diff --git a/src/cpu/sparc/vm/assembler_sparc.cpp b/src/cpu/sparc/vm/assembler_sparc.cpp index 2b8139ea39fcb40f7f51e6e79368aca2e4244732..a4963c650782efdcb7ee268931836f01710155ce 100644 --- a/src/cpu/sparc/vm/assembler_sparc.cpp +++ b/src/cpu/sparc/vm/assembler_sparc.cpp @@ -3647,6 +3647,12 @@ void MacroAssembler::encode_heap_oop_not_null(Register r) { srlx(r, LogMinObjAlignmentInBytes, r); } +void MacroAssembler::encode_heap_oop_not_null(Register src, Register dst) { + assert (UseCompressedOops, "must be compressed"); + sub(src, G6_heapbase, dst); + srlx(dst, LogMinObjAlignmentInBytes, dst); +} + // Same algorithm as oops.inline.hpp decode_heap_oop. void MacroAssembler::decode_heap_oop(Register src, Register dst) { assert (UseCompressedOops, "must be compressed"); @@ -3665,6 +3671,14 @@ void MacroAssembler::decode_heap_oop_not_null(Register r) { add(r, G6_heapbase, r); } +void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) { + // Do not add assert code to this unless you change vtableStubs_sparc.cpp + // pd_code_size_limit. + assert (UseCompressedOops, "must be compressed"); + sllx(src, LogMinObjAlignmentInBytes, dst); + add(dst, G6_heapbase, dst); +} + void MacroAssembler::reinit_heapbase() { if (UseCompressedOops) { // call indirectly to solve generation ordering problem diff --git a/src/cpu/sparc/vm/assembler_sparc.hpp b/src/cpu/sparc/vm/assembler_sparc.hpp index a0a6af4717de6a7bdc209066980e7d8cde7db66c..c1aae2e66202fe9d9576b289394c27dff7853617 100644 --- a/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/src/cpu/sparc/vm/assembler_sparc.hpp @@ -1998,6 +1998,8 @@ class MacroAssembler: public Assembler { } void encode_heap_oop_not_null(Register r); void decode_heap_oop_not_null(Register r); + void encode_heap_oop_not_null(Register src, Register dst); + void decode_heap_oop_not_null(Register src, Register dst); // Support for managing the JavaThread pointer (i.e.; the reference to // thread-local information). diff --git a/src/cpu/sparc/vm/bytecodeInterpreter_sparc.hpp b/src/cpu/sparc/vm/bytecodeInterpreter_sparc.hpp index 3cf99c6d4ec130d76e63b60f514f0feecb98cb6b..dafab4bdcfd725a41f9beb3fa20787badf808c0a 100644 --- a/src/cpu/sparc/vm/bytecodeInterpreter_sparc.hpp +++ b/src/cpu/sparc/vm/bytecodeInterpreter_sparc.hpp @@ -78,7 +78,7 @@ public: #define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)]) #define LOCALS_ADDR(offset) ((address)locals[-(offset)]) -#define LOCALS_INT(offset) ((jint)(locals[-(offset)])) +#define LOCALS_INT(offset) (*((jint*)&locals[-(offset)])) #define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)])) #define LOCALS_OBJECT(offset) ((oop)locals[-(offset)]) #define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d) diff --git a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp index b94b82f59a3f4dbaca57d77f98068eb2f949671a..8bd53e47a510b081052ca9319083181dfbd11ab1 100644 --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp @@ -159,7 +159,7 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ break; case T_LONG : #ifndef _LP64 -#if !defined(_LP64) && defined(COMPILER2) +#if defined(COMPILER2) // All return values are where we want them, except for Longs. C2 returns // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. // Since the interpreter will return longs in G1 and O0/O1 in the 32bit @@ -173,10 +173,9 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ // native result is in O0, O1 __ st(O1, L1_scratch, 0); // Low order __ st(O0, L1_scratch, -wordSize); // High order -#endif /* !_LP64 && COMPILER2 */ +#endif /* COMPILER2 */ #else - __ stx(O0, L1_scratch, 0); -__ breakpoint_trap(); + __ stx(O0, L1_scratch, -wordSize); #endif __ sub(L1_scratch, 2*wordSize, L1_scratch); break; @@ -237,7 +236,6 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ case T_VOID: break; break; case T_FLOAT : - __ breakpoint_trap(Assembler::zero); case T_BOOLEAN: case T_CHAR : case T_BYTE : @@ -255,11 +253,7 @@ address CppInterpreterGenerator::generate_stack_to_stack_converter(BasicType typ // except we allocated one extra word for this intepretState so we won't overwrite it // when we return a two word result. #ifdef _LP64 -__ breakpoint_trap(); - // Hmm now that longs are in one entry should "_ptr" really be "x"? __ ld_ptr(O0, 0, O2); - __ ld_ptr(O0, wordSize, O3); - __ st_ptr(O3, O1, 0); __ st_ptr(O2, O1, -wordSize); #else __ ld(O0, 0, O2); @@ -319,10 +313,7 @@ address CppInterpreterGenerator::generate_stack_to_native_abi_converter(BasicTyp // except we allocated one extra word for this intepretState so we won't overwrite it // when we return a two word result. #ifdef _LP64 -__ breakpoint_trap(); - // Hmm now that longs are in one entry should "_ptr" really be "x"? __ ld_ptr(O0, 0, O0->after_save()); - __ ld_ptr(O0, wordSize, O1->after_save()); #else __ ld(O0, wordSize, O1->after_save()); __ ld(O0, 0, O0->after_save()); @@ -1373,7 +1364,7 @@ void CppInterpreterGenerator::generate_more_monitors() { __ delayed()->ld_ptr(L1_scratch, entry_size, L3_scratch); // now zero the slot so we can find it. - __ st(G0, L4_scratch, BasicObjectLock::obj_offset_in_bytes()); + __ st_ptr(G0, L4_scratch, BasicObjectLock::obj_offset_in_bytes()); } @@ -1713,7 +1704,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ lduh(L4_scratch, in_bytes(methodOopDesc::size_of_parameters_offset()), L2_scratch); // get parameter size __ sll(L2_scratch, LogBytesPerWord, L2_scratch ); // parameter size in bytes __ add(L1_scratch, L2_scratch, L1_scratch); // stack destination for result - __ ld_ptr(L4_scratch, in_bytes(methodOopDesc::result_index_offset()), L3_scratch); // called method result type index + __ ld(L4_scratch, in_bytes(methodOopDesc::result_index_offset()), L3_scratch); // called method result type index // tosca is really just native abi __ set((intptr_t)CppInterpreter::_tosca_to_stack, L4_scratch); @@ -1757,7 +1748,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { __ ld_ptr(STATE(_prev_link), L1_scratch); __ ld_ptr(STATE(_method), L2_scratch); // get method just executed - __ ld_ptr(L2_scratch, in_bytes(methodOopDesc::result_index_offset()), L2_scratch); + __ ld(L2_scratch, in_bytes(methodOopDesc::result_index_offset()), L2_scratch); __ tst(L1_scratch); __ brx(Assembler::zero, false, Assembler::pt, return_to_initial_caller); __ delayed()->sll(L2_scratch, LogBytesPerWord, L2_scratch); @@ -1923,10 +1914,10 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) { // compute the unused java stack size __ sub(Gargs, L1_scratch, L2_scratch); // compute unused space - // Round down the unused space to that stack is always aligned - // by making the unused space a multiple of the size of a long. + // Round down the unused space to that stack is always 16-byte aligned + // by making the unused space a multiple of the size of two longs. - __ and3(L2_scratch, -BytesPerLong, L2_scratch); + __ and3(L2_scratch, -2*BytesPerLong, L2_scratch); // Now trim the stack __ add(SP, L2_scratch, SP); @@ -2176,6 +2167,9 @@ int AbstractInterpreter::layout_activation(methodOop method, // MUCHO HACK intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words); + // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode. + assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation"); + frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS); /* Now fillin the interpreterState object */ diff --git a/src/cpu/sparc/vm/sparc.ad b/src/cpu/sparc/vm/sparc.ad index 7e9df441515985359656601bb14b474a36633efc..73458015efed68175536c4b923a804036e9959bd 100644 --- a/src/cpu/sparc/vm/sparc.ad +++ b/src/cpu/sparc/vm/sparc.ad @@ -5957,15 +5957,27 @@ instruct storeA8B(memory mem, regD src) %{ // Convert oop pointer into compressed form instruct encodeHeapOop(iRegN dst, iRegP src) %{ + predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() != TypePtr::NotNull); match(Set dst (EncodeP src)); - format %{ "SRL $src,3,$dst\t encodeHeapOop" %} + format %{ "encode_heap_oop $src, $dst" %} ins_encode %{ __ encode_heap_oop($src$$Register, $dst$$Register); %} ins_pipe(ialu_reg); %} +instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{ + predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() == TypePtr::NotNull); + match(Set dst (EncodeP src)); + format %{ "encode_heap_oop_not_null $src, $dst" %} + ins_encode %{ + __ encode_heap_oop_not_null($src$$Register, $dst$$Register); + %} + ins_pipe(ialu_reg); +%} + instruct decodeHeapOop(iRegP dst, iRegN src) %{ + predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); match(Set dst (DecodeN src)); format %{ "decode_heap_oop $src, $dst" %} ins_encode %{ @@ -5974,6 +5986,16 @@ instruct decodeHeapOop(iRegP dst, iRegN src) %{ ins_pipe(ialu_reg); %} +instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{ + predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); + match(Set dst (DecodeN src)); + format %{ "decode_heap_oop_not_null $src, $dst" %} + ins_encode %{ + __ decode_heap_oop_not_null($src$$Register, $dst$$Register); + %} + ins_pipe(ialu_reg); +%} + // Store Zero into Aligned Packed Bytes instruct storeA8B0(memory mem, immI0 zero) %{ diff --git a/src/cpu/x86/vm/assembler_x86_64.cpp b/src/cpu/x86/vm/assembler_x86_64.cpp index 35affddc94ee1cfd1397c3e9eac05d31a3a6509e..f700fd71b5ec00dd400de0e2d971f6be7e0787d2 100644 --- a/src/cpu/x86/vm/assembler_x86_64.cpp +++ b/src/cpu/x86/vm/assembler_x86_64.cpp @@ -4150,7 +4150,7 @@ void MacroAssembler::call_VM_base(Register oop_result, if (oop_result->is_valid()) { movq(oop_result, Address(r15_thread, JavaThread::vm_result_offset())); movptr(Address(r15_thread, JavaThread::vm_result_offset()), NULL_WORD); - verify_oop(oop_result); + verify_oop(oop_result, "broken oop in call_VM_base"); } } @@ -4689,6 +4689,10 @@ void MacroAssembler::warn(const char* msg) { popq(r12); } +#ifndef PRODUCT +extern "C" void findpc(intptr_t x); +#endif + void MacroAssembler::debug(char* msg, int64_t pc, int64_t regs[]) { // In order to get locks to work, we need to fake a in_VM state if (ShowMessageBoxOnError ) { @@ -4707,6 +4711,11 @@ void MacroAssembler::debug(char* msg, int64_t pc, int64_t regs[]) { if (os::message_box(msg, "Execution stopped, print registers?")) { ttyLocker ttyl; tty->print_cr("rip = 0x%016lx", pc); +#ifndef PRODUCT + tty->cr(); + findpc(pc); + tty->cr(); +#endif tty->print_cr("rax = 0x%016lx", regs[15]); tty->print_cr("rbx = 0x%016lx", regs[12]); tty->print_cr("rcx = 0x%016lx", regs[14]); @@ -5187,7 +5196,7 @@ void MacroAssembler::encode_heap_oop(Register r) { bind(ok); popq(rscratch1); #endif - verify_oop(r); + verify_oop(r, "broken oop in encode_heap_oop"); testq(r, r); cmovq(Assembler::equal, r, r12_heapbase); subq(r, r12_heapbase); @@ -5203,11 +5212,28 @@ void MacroAssembler::encode_heap_oop_not_null(Register r) { stop("null oop passed to encode_heap_oop_not_null"); bind(ok); #endif - verify_oop(r); + verify_oop(r, "broken oop in encode_heap_oop_not_null"); subq(r, r12_heapbase); shrq(r, LogMinObjAlignmentInBytes); } +void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { + assert (UseCompressedOops, "should be compressed"); +#ifdef ASSERT + Label ok; + testq(src, src); + jcc(Assembler::notEqual, ok); + stop("null oop passed to encode_heap_oop_not_null2"); + bind(ok); +#endif + verify_oop(src, "broken oop in encode_heap_oop_not_null2"); + if (dst != src) { + movq(dst, src); + } + subq(dst, r12_heapbase); + shrq(dst, LogMinObjAlignmentInBytes); +} + void MacroAssembler::decode_heap_oop(Register r) { assert (UseCompressedOops, "should be compressed"); #ifdef ASSERT @@ -5232,7 +5258,7 @@ void MacroAssembler::decode_heap_oop(Register r) { leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); #endif bind(done); - verify_oop(r); + verify_oop(r, "broken oop in decode_heap_oop"); } void MacroAssembler::decode_heap_oop_not_null(Register r) { @@ -5243,6 +5269,14 @@ void MacroAssembler::decode_heap_oop_not_null(Register r) { leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); } +void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { + assert (UseCompressedOops, "should only be used for compressed headers"); + // Cannot assert, unverified entry point counts instructions (see .ad file) + // vtableStubs also counts instructions in pd_code_size_limit. + assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); + leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); +} + Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { switch (cond) { // Note some conditions are synonyms for others diff --git a/src/cpu/x86/vm/assembler_x86_64.hpp b/src/cpu/x86/vm/assembler_x86_64.hpp index 8fc04e9e82aea04069f6aa10f521b7960c091a6e..9e1ccbfe59df9eb533702f8e8a70dba0daf2bddb 100644 --- a/src/cpu/x86/vm/assembler_x86_64.hpp +++ b/src/cpu/x86/vm/assembler_x86_64.hpp @@ -1111,6 +1111,8 @@ class MacroAssembler : public Assembler { void decode_heap_oop(Register r); void encode_heap_oop_not_null(Register r); void decode_heap_oop_not_null(Register r); + void encode_heap_oop_not_null(Register dst, Register src); + void decode_heap_oop_not_null(Register dst, Register src); // Stack frame creation/removal void enter(); diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 7ee3ca134de57da96e1394239a07fa24faad9791..5cfbc09fe741e110cc3eeb3493982f89eb9aaf82 100644 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -913,11 +913,12 @@ class StubGenerator: public StubCodeGenerator { // Stack after saving c_rarg3: // [tos + 0]: saved c_rarg3 // [tos + 1]: saved c_rarg2 - // [tos + 2]: saved flags - // [tos + 3]: return address - // * [tos + 4]: error message (char*) - // * [tos + 5]: object to verify (oop) - // * [tos + 6]: saved rax - saved by caller and bashed + // [tos + 2]: saved r12 (several TemplateTable methods use it) + // [tos + 3]: saved flags + // [tos + 4]: return address + // * [tos + 5]: error message (char*) + // * [tos + 6]: object to verify (oop) + // * [tos + 7]: saved rax - saved by caller and bashed // * = popped on exit address generate_verify_oop() { StubCodeMark mark(this, "StubRoutines", "verify_oop"); @@ -928,12 +929,24 @@ class StubGenerator: public StubCodeGenerator { __ pushfq(); __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr())); + __ pushq(r12); + // save c_rarg2 and c_rarg3 __ pushq(c_rarg2); __ pushq(c_rarg3); + enum { + // After previous pushes. + oop_to_verify = 6 * wordSize, + saved_rax = 7 * wordSize, + + // Before the call to MacroAssembler::debug(), see below. + return_addr = 16 * wordSize, + error_msg = 17 * wordSize + }; + // get object - __ movq(rax, Address(rsp, 5 * wordSize)); + __ movq(rax, Address(rsp, oop_to_verify)); // make sure object is 'reasonable' __ testq(rax, rax); @@ -946,6 +959,9 @@ class StubGenerator: public StubCodeGenerator { __ cmpq(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error); + // set r12 to heapbase for load_klass() + __ reinit_heapbase(); + // make sure klass is 'reasonable' __ load_klass(rax, rax); // get klass __ testq(rax, rax); @@ -971,40 +987,45 @@ class StubGenerator: public StubCodeGenerator { // return if everything seems ok __ bind(exit); - __ movq(rax, Address(rsp, 6 * wordSize)); // get saved rax back - __ popq(c_rarg3); // restore c_rarg3 - __ popq(c_rarg2); // restore c_rarg2 + __ movq(rax, Address(rsp, saved_rax)); // get saved rax back + __ popq(c_rarg3); // restore c_rarg3 + __ popq(c_rarg2); // restore c_rarg2 + __ popq(r12); // restore r12 __ popfq(); // restore flags __ ret(3 * wordSize); // pop caller saved stuff // handle errors __ bind(error); - __ movq(rax, Address(rsp, 6 * wordSize)); // get saved rax back - __ popq(c_rarg3); // get saved c_rarg3 back - __ popq(c_rarg2); // get saved c_rarg2 back + __ movq(rax, Address(rsp, saved_rax)); // get saved rax back + __ popq(c_rarg3); // get saved c_rarg3 back + __ popq(c_rarg2); // get saved c_rarg2 back + __ popq(r12); // get saved r12 back __ popfq(); // get saved flags off stack -- // will be ignored __ pushaq(); // push registers // (rip is already // already pushed) - // debug(char* msg, int64_t regs[]) + // debug(char* msg, int64_t pc, int64_t regs[]) // We've popped the registers we'd saved (c_rarg3, c_rarg2 and flags), and // pushed all the registers, so now the stack looks like: // [tos + 0] 16 saved registers // [tos + 16] return address - // [tos + 17] error message (char*) - - __ movq(c_rarg0, Address(rsp, 17 * wordSize)); // pass address of error message - __ movq(c_rarg1, rsp); // pass address of regs on stack + // * [tos + 17] error message (char*) + // * [tos + 18] object to verify (oop) + // * [tos + 19] saved rax - saved by caller and bashed + // * = popped on exit + + __ movq(c_rarg0, Address(rsp, error_msg)); // pass address of error message + __ movq(c_rarg1, Address(rsp, return_addr)); // pass return address + __ movq(c_rarg2, rsp); // pass address of regs on stack __ movq(r12, rsp); // remember rsp __ subq(rsp, frame::arg_reg_save_area_bytes);// windows __ andq(rsp, -16); // align stack as required by ABI BLOCK_COMMENT("call MacroAssembler::debug"); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug))); __ movq(rsp, r12); // restore rsp - __ reinit_heapbase(); // r12 is heapbase - __ popaq(); // pop registers + __ popaq(); // pop registers (includes r12) __ ret(3 * wordSize); // pop caller saved stuff return start; @@ -1038,7 +1059,7 @@ class StubGenerator: public StubCodeGenerator { assert_different_registers(Rtmp, Rint); __ movslq(Rtmp, Rint); __ cmpq(Rtmp, Rint); - __ jccb(Assembler::equal, L); + __ jcc(Assembler::equal, L); __ stop("high 32-bits of int value are not 0"); __ bind(L); #endif diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad index b4639a20d6c19f2b03a026721a39407b60a0e6ed..029e79bf84b89a7eab1c44e96c3520a3055b3721 100644 --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -6080,7 +6080,8 @@ instruct loadKlassComp(rRegP dst, memory mem) predicate(n->in(MemNode::Address)->bottom_type()->is_narrow()); ins_cost(125); // XXX - format %{ "movl $dst, $mem\t# compressed class" %} + format %{ "movl $dst, $mem\t# compressed class\n\t" + "decode_heap_oop $dst,$dst" %} ins_encode %{ Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); Register dst = as_Register($dst$$reg); @@ -6349,7 +6350,7 @@ instruct loadConF(regF dst, immF src) instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ match(Set dst src); effect(KILL cr); - format %{ "xorq $dst, $src\t# compressed ptr" %} + format %{ "xorq $dst, $src\t# compressed NULL ptr" %} ins_encode %{ Register dst = $dst$$Register; __ xorq(dst, dst); @@ -6361,7 +6362,8 @@ instruct loadConN(rRegN dst, immN src) %{ match(Set dst src); ins_cost(125); - format %{ "movl $dst, $src\t# compressed ptr" %} + format %{ "movq $dst, $src\t# compressed ptr\n\t" + "encode_heap_oop_not_null $dst,$dst" %} ins_encode %{ address con = (address)$src$$constant; Register dst = $dst$$Register; @@ -6996,6 +6998,7 @@ instruct castP2X(rRegL dst, rRegP src) // Convert oop pointer into compressed form instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ + predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() != TypePtr::NotNull); match(Set dst (EncodeP src)); effect(KILL cr); format %{ "encode_heap_oop $dst,$src" %} @@ -7010,7 +7013,21 @@ instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ ins_pipe(ialu_reg_long); %} +instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ + predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() == TypePtr::NotNull); + match(Set dst (EncodeP src)); + effect(KILL cr); + format %{ "encode_heap_oop_not_null $dst,$src" %} + ins_encode %{ + Register s = $src$$Register; + Register d = $dst$$Register; + __ encode_heap_oop_not_null(d, s); + %} + ins_pipe(ialu_reg_long); +%} + instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ + predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); match(Set dst (DecodeN src)); effect(KILL cr); format %{ "decode_heap_oop $dst,$src" %} @@ -7025,6 +7042,18 @@ instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ ins_pipe(ialu_reg_long); %} +instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{ + predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); + match(Set dst (DecodeN src)); + format %{ "decode_heap_oop_not_null $dst,$src" %} + ins_encode %{ + Register s = $src$$Register; + Register d = $dst$$Register; + __ decode_heap_oop_not_null(d, s); + %} + ins_pipe(ialu_reg_long); +%} + //----------Conditional Move--------------------------------------------------- // Jump diff --git a/src/share/vm/interpreter/bytecodeInterpreter.cpp b/src/share/vm/interpreter/bytecodeInterpreter.cpp index 2a03dc2d6d4b2074de8ea8a0547b565b63a9b02d..547b440e1771bae500cd1dd251c16ca734278e61 100644 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp @@ -518,16 +518,16 @@ BytecodeInterpreter::run(interpreterState istate) { /* 0xC0 */ &&opc_checkcast, &&opc_instanceof, &&opc_monitorenter, &&opc_monitorexit, /* 0xC4 */ &&opc_wide, &&opc_multianewarray, &&opc_ifnull, &&opc_ifnonnull, -/* 0xC8 */ &&opc_goto_w, &&opc_jsr_w, &&opc_breakpoint, &&opc_fast_igetfield, -/* 0xCC */ &&opc_fastagetfield,&&opc_fast_aload_0, &&opc_fast_iaccess_0, &&opc__fast_aaccess_0, +/* 0xC8 */ &&opc_goto_w, &&opc_jsr_w, &&opc_breakpoint, &&opc_default, +/* 0xCC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -/* 0xD0 */ &&opc_fast_linearswitch, &&opc_fast_binaryswitch, &&opc_return_register_finalizer, &&opc_default, +/* 0xD0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xD4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xD8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xDC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -/* 0xE4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, +/* 0xE4 */ &&opc_default, &&opc_return_register_finalizer, &&opc_default, &&opc_default, /* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, /* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, diff --git a/src/share/vm/opto/cfgnode.cpp b/src/share/vm/opto/cfgnode.cpp index 48bf400c81d0e30aaa593cfc3a021d6a48a8850f..30ab6a59eed0461d5d5dd8c70c3722eea146bd0f 100644 --- a/src/share/vm/opto/cfgnode.cpp +++ b/src/share/vm/opto/cfgnode.cpp @@ -1419,7 +1419,8 @@ PhiNode::LoopSafety PhiNode::simple_data_loop_check(Node *in) const { // Check inputs of phi's inputs also. // It is much less expensive then full graph walk. uint cnt = in->req(); - for (uint i = 1; i < cnt; ++i) { + uint i = (in->is_Proj() && !in->is_CFG()) ? 0 : 1; + for (; i < cnt; ++i) { Node* m = in->in(i); if (m == (Node*)this) return UnsafeLoop; // Unsafe loop @@ -1467,7 +1468,8 @@ bool PhiNode::is_unsafe_data_reference(Node *in) const { while (nstack.size() != 0) { Node* n = nstack.pop(); uint cnt = n->req(); - for (uint i = 1; i < cnt; i++) { // Only data paths + uint i = (n->is_Proj() && !n->is_CFG()) ? 0 : 1; + for (; i < cnt; i++) { Node* m = n->in(i); if (m == (Node*)this) { return true; // Data loop @@ -2017,6 +2019,28 @@ Node *CreateExNode::Identity( PhaseTransform *phase ) { } //============================================================================= +//------------------------------Value------------------------------------------ +// Check for being unreachable. +const Type *NeverBranchNode::Value( PhaseTransform *phase ) const { + if (!in(0) || in(0)->is_top()) return Type::TOP; + return bottom_type(); +} + +//------------------------------Ideal------------------------------------------ +// Check for no longer being part of a loop +Node *NeverBranchNode::Ideal(PhaseGVN *phase, bool can_reshape) { + if (can_reshape && !in(0)->is_Loop()) { + // Dead code elimination can sometimes delete this projection so + // if it's not there, there's nothing to do. + Node* fallthru = proj_out(0); + if (fallthru != NULL) { + phase->is_IterGVN()->subsume_node(fallthru, in(0)); + } + return phase->C->top(); + } + return NULL; +} + #ifndef PRODUCT void NeverBranchNode::format( PhaseRegAlloc *ra_, outputStream *st) const { st->print("%s", Name()); diff --git a/src/share/vm/opto/cfgnode.hpp b/src/share/vm/opto/cfgnode.hpp index 0c4eedb9b99895cd02726a12f3b8b995a85afa1d..f4c4b0e2faee602c34f189b2fa532fbd2c4a2d08 100644 --- a/src/share/vm/opto/cfgnode.hpp +++ b/src/share/vm/opto/cfgnode.hpp @@ -244,6 +244,8 @@ public: MultiBranchNode( uint required ) : MultiNode(required) { init_class_id(Class_MultiBranch); } + // returns required number of users to be well formed. + virtual int required_outcnt() const = 0; }; //------------------------------IfNode----------------------------------------- @@ -333,6 +335,7 @@ public: virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type *Value( PhaseTransform *phase ) const; + virtual int required_outcnt() const { return 2; } virtual const RegMask &out_RegMask() const; void dominated_by(Node* prev_dom, PhaseIterGVN* igvn); int is_range_check(Node* &range, Node* &index, jint &offset); @@ -391,6 +394,7 @@ public: virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type *bottom_type() const; virtual bool pinned() const { return true; } + virtual int required_outcnt() const { return _size; } }; //------------------------------JumpNode--------------------------------------- @@ -504,7 +508,9 @@ public: virtual int Opcode() const; virtual bool pinned() const { return true; }; virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } - + virtual const Type *Value( PhaseTransform *phase ) const; + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + virtual int required_outcnt() const { return 2; } virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } virtual uint size(PhaseRegAlloc *ra_) const { return 0; } #ifndef PRODUCT diff --git a/src/share/vm/opto/compile.cpp b/src/share/vm/opto/compile.cpp index 1e3c9fb43c44bbe8de325fbbaf99ec481704e85d..6559cb4c6211ee29abd3029efd629e626fcb1b97 100644 --- a/src/share/vm/opto/compile.cpp +++ b/src/share/vm/opto/compile.cpp @@ -1981,10 +1981,6 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { #endif break; } - case Op_If: - case Op_CountedLoopEnd: - fpu._tests.push(n); // Collect CFG split points - break; case Op_AddP: { // Assert sane base pointers const Node *addp = n->in(AddPNode::Address); @@ -2083,10 +2079,12 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" ); - if( n->is_If() || n->is_PCTable() ) - fpu._tests.push(n); // Collect CFG split points break; } + + // Collect CFG split points + if (n->is_MultiBranch()) + fpu._tests.push(n); } //------------------------------final_graph_reshaping_walk--------------------- @@ -2165,19 +2163,18 @@ bool Compile::final_graph_reshaping() { // Check for unreachable (from below) code (i.e., infinite loops). for( uint i = 0; i < fpu._tests.size(); i++ ) { - Node *n = fpu._tests[i]; - assert( n->is_PCTable() || n->is_If(), "either PCTables or IfNodes" ); - // Get number of CFG targets; 2 for IfNodes or _size for PCTables. + MultiBranchNode *n = fpu._tests[i]->as_MultiBranch(); + // Get number of CFG targets. // Note that PCTables include exception targets after calls. - uint expected_kids = n->is_PCTable() ? n->as_PCTable()->_size : 2; - if (n->outcnt() != expected_kids) { + uint required_outcnt = n->required_outcnt(); + if (n->outcnt() != required_outcnt) { // Check for a few special cases. Rethrow Nodes never take the // 'fall-thru' path, so expected kids is 1 less. if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { if (n->in(0)->in(0)->is_Call()) { CallNode *call = n->in(0)->in(0)->as_Call(); if (call->entry_point() == OptoRuntime::rethrow_stub()) { - expected_kids--; // Rethrow always has 1 less kid + required_outcnt--; // Rethrow always has 1 less kid } else if (call->req() > TypeFunc::Parms && call->is_CallDynamicJava()) { // Check for null receiver. In such case, the optimizer has @@ -2187,7 +2184,7 @@ bool Compile::final_graph_reshaping() { Node *arg0 = call->in(TypeFunc::Parms); if (arg0->is_Type() && arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { - expected_kids--; + required_outcnt--; } } else if (call->entry_point() == OptoRuntime::new_array_Java() && call->req() > TypeFunc::Parms+1 && @@ -2198,13 +2195,13 @@ bool Compile::final_graph_reshaping() { Node *arg1 = call->in(TypeFunc::Parms+1); if (arg1->is_Type() && arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { - expected_kids--; + required_outcnt--; } } } } - // Recheck with a better notion of 'expected_kids' - if (n->outcnt() != expected_kids) { + // Recheck with a better notion of 'required_outcnt' + if (n->outcnt() != required_outcnt) { record_method_not_compilable("malformed control flow"); return true; // Not all targets reachable! } diff --git a/src/share/vm/opto/connode.cpp b/src/share/vm/opto/connode.cpp index e0b7286635b848e906654304f60eb3477189722d..c542ce397e498df36b52cce29de051349fa6eac6 100644 --- a/src/share/vm/opto/connode.cpp +++ b/src/share/vm/opto/connode.cpp @@ -563,6 +563,26 @@ Node* DecodeNNode::Identity(PhaseTransform* phase) { return this; } +const Type *DecodeNNode::Value( PhaseTransform *phase ) const { + if (phase->type( in(1) ) == TypeNarrowOop::NULL_PTR) { + return TypePtr::NULL_PTR; + } + return bottom_type(); +} + +Node* DecodeNNode::decode(PhaseGVN* phase, Node* value) { + if (value->Opcode() == Op_EncodeP) { + // (DecodeN (EncodeP p)) -> p + return value->in(1); + } + const Type* newtype = value->bottom_type(); + if (newtype == TypeNarrowOop::NULL_PTR) { + return phase->transform(new (phase->C, 1) ConPNode(TypePtr::NULL_PTR)); + } else { + return phase->transform(new (phase->C, 2) DecodeNNode(value, newtype->is_narrowoop()->make_oopptr())); + } +} + Node* EncodePNode::Identity(PhaseTransform* phase) { const Type *t = phase->type( in(1) ); if( t == Type::TOP ) return in(1); @@ -574,14 +594,26 @@ Node* EncodePNode::Identity(PhaseTransform* phase) { return this; } +const Type *EncodePNode::Value( PhaseTransform *phase ) const { + if (phase->type( in(1) ) == TypePtr::NULL_PTR) { + return TypeNarrowOop::NULL_PTR; + } + return bottom_type(); +} Node* EncodePNode::encode(PhaseGVN* phase, Node* value) { + if (value->Opcode() == Op_DecodeN) { + // (EncodeP (DecodeN p)) -> p + return value->in(1); + } const Type* newtype = value->bottom_type(); if (newtype == TypePtr::NULL_PTR) { return phase->transform(new (phase->C, 1) ConNNode(TypeNarrowOop::NULL_PTR)); + } else if (newtype->isa_oopptr()) { + return phase->transform(new (phase->C, 2) EncodePNode(value, newtype->is_oopptr()->make_narrowoop())); } else { - return phase->transform(new (phase->C, 2) EncodePNode(value, - newtype->is_oopptr()->make_narrowoop())); + ShouldNotReachHere(); + return NULL; // to make C++ compiler happy. } } diff --git a/src/share/vm/opto/connode.hpp b/src/share/vm/opto/connode.hpp index 63204ce6b0de018ac7396ab39f7b7ffaf6af2e0a..247a364c845dc071091ad549ee562dad8430799d 100644 --- a/src/share/vm/opto/connode.hpp +++ b/src/share/vm/opto/connode.hpp @@ -239,10 +239,7 @@ public: // cast pointer to pointer (different type) class CastPPNode: public ConstraintCastNode { public: - CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) { - // Only CastPP is safe. CastII can cause optimizer loops. - init_flags(Flag_is_dead_loop_safe); - } + CastPPNode (Node *n, const Type *t ): ConstraintCastNode(n, t) {} virtual int Opcode() const; virtual uint ideal_reg() const { return Op_RegP; } virtual Node *Ideal_DU_postCCP( PhaseCCP * ); @@ -254,10 +251,10 @@ class CheckCastPPNode: public TypeNode { public: CheckCastPPNode( Node *c, Node *n, const Type *t ) : TypeNode(t,2) { init_class_id(Class_CheckCastPP); - init_flags(Flag_is_dead_loop_safe); init_req(0, c); init_req(1, n); } + virtual Node *Identity( PhaseTransform *phase ); virtual const Type *Value( PhaseTransform *phase ) const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); @@ -282,6 +279,7 @@ class EncodePNode : public TypeNode { } virtual int Opcode() const; virtual Node *Identity( PhaseTransform *phase ); + virtual const Type *Value( PhaseTransform *phase ) const; virtual uint ideal_reg() const { return Op_RegN; } static Node* encode(PhaseGVN* phase, Node* value); @@ -300,7 +298,10 @@ class DecodeNNode : public TypeNode { } virtual int Opcode() const; virtual Node *Identity( PhaseTransform *phase ); + virtual const Type *Value( PhaseTransform *phase ) const; virtual uint ideal_reg() const { return Op_RegP; } + + static Node* decode(PhaseGVN* phase, Node* value); }; //------------------------------Conv2BNode------------------------------------- diff --git a/src/share/vm/opto/escape.cpp b/src/share/vm/opto/escape.cpp index ea5f14f3333771973dd7bbd0d5af5fc751e910b0..93a49b94127716ed39fed014edd00617d5aed28d 100644 --- a/src/share/vm/opto/escape.cpp +++ b/src/share/vm/opto/escape.cpp @@ -215,6 +215,10 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase VectorSet visited(Thread::current()->resource_area()); GrowableArray worklist; +#ifdef ASSERT + Node *orig_n = n; +#endif + n = n->uncast(); PointsToNode npt = _nodes->at_grow(n->_idx); @@ -223,8 +227,14 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase ptset.set(n->_idx); return; } - assert(npt._node != NULL, "unregistered node"); - +#ifdef ASSERT + if (npt._node == NULL) { + if (orig_n != n) + orig_n->dump(); + n->dump(); + assert(npt._node != NULL, "unregistered node"); + } +#endif worklist.push(n->_idx); while(worklist.length() > 0) { int ni = worklist.pop(); @@ -266,7 +276,7 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg PointsToNode *ptn = ptnode_adr(ni); // Mark current edges as visited and move deferred edges to separate array. - for (; i < ptn->edge_count(); i++) { + while (i < ptn->edge_count()) { uint t = ptn->edge_target(i); #ifdef ASSERT assert(!visited->test_set(t), "expecting no duplications"); @@ -276,6 +286,8 @@ void ConnectionGraph::remove_deferred(uint ni, GrowableArray* deferred_edg if (ptn->edge_type(i) == PointsToNode::DeferredEdge) { ptn->remove_edge(t, PointsToNode::DeferredEdge); deferred_edges->append(t); + } else { + i++; } } for (int next = 0; next < deferred_edges->length(); ++next) { @@ -1716,6 +1728,8 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) } case Op_CastPP: case Op_CheckCastPP: + case Op_EncodeP: + case Op_DecodeN: { add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); int ti = n->in(1)->_idx; @@ -1743,12 +1757,6 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) add_node(n, PointsToNode::JavaObject, es, true); break; } - case Op_CreateEx: - { - // assume that all exception objects globally escape - add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); - break; - } case Op_ConN: { // assume all narrow oop constants globally escape except for null @@ -1761,6 +1769,12 @@ void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) add_node(n, PointsToNode::JavaObject, es, true); break; } + case Op_CreateEx: + { + // assume that all exception objects globally escape + add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); + break; + } case Op_LoadKlass: { add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); @@ -1976,10 +1990,11 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { break; } case Op_LoadP: + case Op_LoadN: { const Type *t = phase->type(n); #ifdef ASSERT - if (t->isa_ptr() == NULL) + if (!t->isa_narrowoop() && t->isa_ptr() == NULL) assert(false, "Op_LoadP"); #endif @@ -2060,11 +2075,16 @@ void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { break; } case Op_StoreP: + case Op_StoreN: case Op_StorePConditional: case Op_CompareAndSwapP: + case Op_CompareAndSwapN: { Node *adr = n->in(MemNode::Address); const Type *adr_type = phase->type(adr); + if (adr_type->isa_narrowoop()) { + adr_type = adr_type->is_narrowoop()->make_oopptr(); + } #ifdef ASSERT if (!adr_type->isa_oopptr()) assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP"); diff --git a/src/share/vm/opto/lcm.cpp b/src/share/vm/opto/lcm.cpp index 7aa32b5242aa353ce804e9a3f1c267104d545e13..13c3d774cff8e69e3c361b5574b5ce3fec3e2cc5 100644 --- a/src/share/vm/opto/lcm.cpp +++ b/src/share/vm/opto/lcm.cpp @@ -629,6 +629,10 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, Vect // of the phi to be scheduled first. The select() method breaks // ties in scheduling by worklist order. delay.push(m); + } else if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_CreateEx) { + // Force the CreateEx to the top of the list so it's processed + // first and ends up at the start of the block. + worklist.insert(0, m); } else { worklist.push(m); // Then on to worklist! } diff --git a/src/share/vm/opto/macro.cpp b/src/share/vm/opto/macro.cpp index 8c9934f112611321a39aa11ddedef92daad8ccb2..d537c1d6c6ea6b3594cae41d1ed7165bda28768e 100644 --- a/src/share/vm/opto/macro.cpp +++ b/src/share/vm/opto/macro.cpp @@ -584,7 +584,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray is_loaded()) { field_type = TypeInstPtr::BOTTOM; } else if (field != NULL && field->is_constant()) { @@ -597,6 +597,10 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray as_klass()); } + if (UseCompressedOops) { + field_type = field_type->is_oopptr()->make_narrowoop(); + basic_elem_type = T_NARROWOOP; + } } else { field_type = Type::get_const_basic_type(basic_elem_type); } @@ -659,6 +663,13 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray isa_narrowoop()) { + // Enable "DecodeN(EncodeP(Allocate)) --> Allocate" transformation + // to be able scalar replace the allocation. + _igvn.set_delay_transform(false); + field_val = DecodeNNode::decode(&_igvn, field_val); + _igvn.set_delay_transform(true); + } sfpt->add_req(field_val); } JVMState *jvms = sfpt->jvms(); diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp index 91aefe01d87152567fb87819d3b861de57fbc0f9..b28c37b7821aca2cd74b4ba4c3a61f102e94a1d8 100644 --- a/src/share/vm/opto/memnode.cpp +++ b/src/share/vm/opto/memnode.cpp @@ -754,13 +754,12 @@ Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const Type const TypeNarrowOop* narrowtype; if (rt->isa_narrowoop()) { narrowtype = rt->is_narrowoop(); - rt = narrowtype->make_oopptr(); } else { narrowtype = rt->is_oopptr()->make_narrowoop(); } Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, narrowtype)); - return new (C, 2) DecodeNNode(load, rt); + return DecodeNNode::decode(&gvn, load); } else #endif { @@ -1841,15 +1840,7 @@ StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, cons (UseCompressedOops && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { const TypePtr* type = val->bottom_type()->is_ptr(); - Node* cp; - if (type->isa_oopptr()) { - const TypeNarrowOop* etype = type->is_oopptr()->make_narrowoop(); - cp = gvn.transform(new (C, 2) EncodePNode(val, etype)); - } else if (type == TypePtr::NULL_PTR) { - cp = gvn.transform(new (C, 1) ConNNode(TypeNarrowOop::NULL_PTR)); - } else { - ShouldNotReachHere(); - } + Node* cp = EncodePNode::encode(&gvn, val); return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, cp); } else #endif diff --git a/src/share/vm/opto/multnode.hpp b/src/share/vm/opto/multnode.hpp index 34a573ffcd3eb349dd4e9317b4d3d2a65ba78666..8c17f9d45f6b4032cb4ccb35d9e438aa9d848898 100644 --- a/src/share/vm/opto/multnode.hpp +++ b/src/share/vm/opto/multnode.hpp @@ -61,6 +61,9 @@ public: : Node( src ), _con(con), _is_io_use(io_use) { init_class_id(Class_Proj); + // Optimistic setting. Need additional checks in Node::is_dead_loop_safe(). + if (con != TypeFunc::Memory || src->is_Start()) + init_flags(Flag_is_dead_loop_safe); debug_only(check_con()); } const uint _con; // The field in the tuple we are projecting diff --git a/src/share/vm/opto/node.hpp b/src/share/vm/opto/node.hpp index e957887b3edf340de79439230f35123cbf7b5827..dc44aab22c807ab26361233c3ca04315b5d17db8 100644 --- a/src/share/vm/opto/node.hpp +++ b/src/share/vm/opto/node.hpp @@ -741,8 +741,9 @@ public: bool is_Goto() const { return (_flags & Flag_is_Goto) != 0; } // The data node which is safe to leave in dead loop during IGVN optimization. bool is_dead_loop_safe() const { - return is_Phi() || is_Proj() || - (_flags & (Flag_is_dead_loop_safe | Flag_is_Con)) != 0; + return is_Phi() || (is_Proj() && in(0) == NULL) || + ((_flags & (Flag_is_dead_loop_safe | Flag_is_Con)) != 0 && + (!is_Proj() || !in(0)->is_Allocate())); } // is_Copy() returns copied edge index (0 or 1) diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index cb8eeb121495fb20583f4918702da15bedf2a720..59219cda39db0b2274fe874f889299ea976b464e 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -2229,6 +2229,8 @@ JRT_END #ifndef PRODUCT bool AdapterHandlerLibrary::contains(CodeBlob* b) { + if (_handlers == NULL) return false; + for (int i = 0 ; i < _handlers->length() ; i++) { AdapterHandlerEntry* a = get_entry(i); if ( a != NULL && b == CodeCache::find_blob(a->get_i2c_entry()) ) return true; diff --git a/test/compiler/6663848/Tester.java b/test/compiler/6663848/Tester.java new file mode 100644 index 0000000000000000000000000000000000000000..c2e797967a3b592615ee464a119a83c25bbefd94 --- /dev/null +++ b/test/compiler/6663848/Tester.java @@ -0,0 +1,478 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6663848 + * @summary assert(i < Max(),"oob") + */ + +/* Complexity upper bound: 296055 ops */ + +final class Tester_Class_0 { + byte var_1; + static double var_2; + String var_3; + char var_4 = 'n'; + static int var_5; + String var_6; + final long var_7 = 4161100809902398464L; + static String var_8 = "a"; + + + public Tester_Class_0() + { + switch (((false ^ !"n".startsWith("kmmhtohv", 553985525) ? true : false) ? 'k' : (var_4 *= - (var_2 = 3.1182935E38F))) - (~2013121027650726912L >= 2.929692E38F / (var_1 = (byte)4.2723157E37F) ? var_4 | (short)var_7 : ~ ((byte)"".indexOf("yuno", 4922080)))) + { + case 125: + + case ']': + + case 6: + var_5 = (false ? false : 3708707602755734528L >= 1648075631) ? var_4 : (false ? var_4 : ++var_4); + break; + + case 46: + Object var_15; + ++var_4; + float var_16 = 3.1085987E38F; + var_5 = 'h'; + var_1 = true ? (byte)9.482988718680618E307 : (false && false ? (byte)var_7 : (byte)6793807430041920512L); + final byte var_17 = var_1 = (337740577 ^ ~8932537004307666944L) / (short)var_16 - (byte)var_7 << var_7 > ~1539422023641354240L ? (false ? (byte)var_4 : (byte)9.302678E37F) : (byte)(var_5 = (byte)1.3007792E38F); + var_15 = "an"; + break; + + case 29: + var_3 = (var_6 = (var_8 = "kgc")); + break; + + case 60: + + } + char var_18; + ((new Tester_Class_0[var_1 = (byte)(var_2 = 93813743)])[var_1 = (byte)var_4]).var_1 = (var_1 = (var_1 = (byte)5.1405316E37F)); + var_8 = var_8; + float var_19 = 0F; + var_2 = var_4; + do + { + var_4 >>= var_7; + var_19++; + var_4 %= true ? (short)7643330105057892352L : (short)1.1014013E38F; + } while (var_19 < 2 && (! (true & (!true && false)) && true)); + var_4++; + int var_20 = 0; + var_4 = ~var_7 == (var_1 = (byte)var_7) | (float)var_20 <= 'H' ? 'r' : (var_4 |= (byte)var_4); + for (var_6 = (var_8 = "wqmnvxava"); (false ? (short)+ ~3540350558052792320L : + ~ ~3244965056572428288L - (var_4 *= 8.314953959831226E307)) <= +9.34280058703911E307 && var_20 < 6; var_2 = 3.0507823E38F) + { + var_2 = ~ ((byte)844279629935048704L) ^ (var_19 <= (false ? '\\' : 'B') ? (byte)(short)(var_1 = (byte)(short)var_19) : (var_1 = (var_1 = (var_1 = (byte)'T')))); + var_20++; + var_5 = (short)(var_7 >>> (! !true & true ? 'D' : (var_4 -= 1.1444072012663494E308))); + (var_6 = "jnjbrmaus").compareTo(var_3 = false ? "pfmv" : (var_8 = var_8)); + } + var_2 = func_0(1248385981, 'V' != '[' ? (short)1.0082348960424545E308 : (byte)var_4, new double[var_1 = (byte)'p'][(byte)var_19], 1.3646683639847343E308); + var_5 = (var_1 = (var_1 = (true ^ false ? "bfh".startsWith(var_8) : true || !true) | false ? (byte)(var_2 = - ~var_7) : (var_1 = (byte)var_19))); + var_3 = (var_3 = "dn"); + var_2 = false ? (var_1 = (byte)9.136750130102702E307) : var_7; + } + + + + + final short func_0(int arg_0, short arg_1, double[][] arg_2, double arg_3) + { + double[][] var_9 = arg_2; + arg_0 <<= true ? (byte)- +1.1174307E37F : (var_1 = (byte)911334714); + switch ("touoh".endsWith(var_8) ^ ! ! (++var_4 != 1.8567045E38F) ? (var_4 <<= arg_1) : 'E') + { + case 'a': + + case 46: + + case 's': + + case 50: + ((new Tester_Class_0[(byte)arg_0][(byte)- (- + - - + - +1.775205E38F - (arg_1 |= 'Z'))])[var_1 = (var_1 = (byte)4.020531E37F)][var_1 = (var_1 = (byte)883328311549528064L)]).var_4 &= (var_6 = var_8).charAt(arg_0); + var_3 = false ? var_8 : "amfijbpwa"; + var_4 -= -1.4699719646972257E308; + var_2 = (var_1 = (byte)(arg_1 += 1.6757431E38F)); + var_1 = (var_1 = (var_1 = (byte)+1.4416583523884388E308)); + final Object var_10 = (new Object[(byte)(arg_1 += var_4)])[var_1 = (byte)- +1.0281942E38F]; + arg_1 = arg_1; + break; + + case 7: + var_8 = var_8 + var_8; + break; + + case 'N': + + case 'V': + + case 56: + + case 'I': + + } + arg_0 &= arg_1; + var_3 = false ? var_8 : "vpaj"; + var_4 = (var_4 *= arg_1); + arg_3 *= (var_4 = var_4); + final char var_11 = true ? var_4 : (char)(var_4 << (var_1 = (byte)(arg_1 &= arg_0))); + boolean var_12; + var_4 ^= '`'; + "nkj".startsWith(var_6 = "wrcnrdd"); + var_1 = (byte)~var_7; + var_6 = (var_8 = "ul"); + return (var_12 = 3548576322219573248L <= var_4++ & ((var_12 = !true) || (var_12 = !false | false))) ? arg_1-- : (var_1 = (byte)+ (var_2 = 2.7633542E38F)); + } + + protected final void func_1(final String arg_0, Object arg_1, short arg_2) + { + arg_2 *= ~8267766955221100544L; + arg_1 = (var_6 = var_8); + arg_2 <<= false ? (var_1 = (var_1 = (var_1 = (byte)1.6645553629318776E308))) : arg_2; + } + + protected final static float func_2(byte arg_0, final String arg_1) + { + var_8 = arg_1; + char var_13 = ((new Tester_Class_0[arg_0 |= ']'])[arg_0]).var_4--; + var_5 = 907889433; + { + var_13 ^= (var_5 = var_13); + } + var_8 = arg_1; + var_5 = (byte)1759688161; + var_8 = (new String[arg_0 >>>= (short)1072761211])[arg_0]; + return 5.108221E37F; + } + + private static boolean func_3(boolean arg_0, final boolean arg_1) + { + var_2 = ((new Tester_Class_0[(byte)(short)'H'])[(byte)(short)(var_2 = (short)'k')]).var_4; + if (false) + { + var_8 = "cl"; + } + else + { + final byte[] var_14 = new byte[true ? (byte)(- ((byte)9.760296114722793E307) | ~1867374212153383936L) : (byte)(short)'Q']; + var_2 = (float)~3838271533006646272L / (- ~ ~1786841397228277760L ^ ~3695911615719734272L & 'Z'); + } + { + var_8 = var_8; + } + ((new Tester_Class_0[(byte)(var_2 = (short)~ - +4818709334539164672L)])[(byte)'W']).var_1 = true || false & arg_0 ^ (arg_1 ^ arg_0 ? arg_0 : (arg_0 ^= true)) ? (byte)1.5309163701271477E308 : (byte)3.0904342E38F; + ((new Tester_Class_0[(byte)756871578277111808L][(byte)+ + -3.0687752E38F])[(byte)'f'][(byte)1544156315]).var_6 = (var_8 = "vqey"); + return arg_1; + } + + public final char func_4(short arg_0) + { + { + var_6 = (var_3 = "hjtjar"); + var_1 = false ? (byte)4.02486350499973E307 : (byte)1.3222663E38F; + } + var_1 = (new byte[var_1 = (var_1 = (byte)1770517884)])[var_1 = (byte)arg_0]; + var_4++; + --arg_0; + var_5 = true ? 'D' : (var_4 ^= (var_5 = 134858941)); + return (char)~ (7273058621469586432L << (byte)3.1756883E38F ^ (false ? (byte)(var_5 = var_4) : (arg_0 >>= 6165812289376474112L))) < (2046127339 ^ + ((byte)arg_0)) ? (!false ? (var_4 %= 1.8187417377124746E307) : (var_4 *= 445936805)) : var_4; + } + +} + + +class Tester_Class_1 { + Tester_Class_0[][] var_21; + static long var_22 = 6671342492736446464L; + float var_23 = 2.9329673E38F; + final int var_24 = 1834862519; + int var_25 = 69920645; + static char var_26; + static Object var_27; + static int var_28 = Tester_Class_0.var_5 = false ? 'U' : (var_26 = (var_26 = 'R')); + + + public Tester_Class_1() + { + (false ? (Tester_Class_0)(var_27 = Tester_Class_0.var_8) : (Tester_Class_0)(var_27 = "a")).var_1 = (short)(var_23 %= var_23) >= (byte)1217257602 | var_25 == (char)(var_23 += var_23) ? (byte)new Tester_Class_0().var_4-- : ((true | false) ^ !false ? (byte)6.122806E37F : (byte)1.084542872057614E308); + Tester_Class_0.var_2 = new Tester_Class_0().var_7; + --var_22; + boolean var_32 = ! ((new Tester_Class_0().var_1 = (((new Tester_Class_0[(byte)var_22])[(byte)var_23]).var_1 = false ? (byte)(var_23 = var_28) : (byte)1.5858707076311894E308)) != (char)+var_23); + var_25 -= (true ? (byte)5.488240359086226E307 : (((Tester_Class_0)(var_27 = Tester_Class_0.var_8)).var_1 = (byte)'L')) * (Tester_Class_0.var_2 = 7.045106259776882E307); + Object var_33 = (var_32 ^= var_32) ? (var_27 = (Tester_Class_0.var_8 = (Tester_Class_0.var_8 = "gaemnaep"))) : (new Tester_Class_0[(byte)'g'])[(byte)(short)271735827]; + byte var_34 = var_32 ? (byte)((Tester_Class_0)var_33).var_7 : ((var_32 &= true) ? (byte)(Tester_Class_0.var_2 = 1.6975344767401616E307) : (byte)- ((double)var_22)); + Tester_Class_0.var_2 = 1.4644308179397427E308; + var_28 /= (short)1681483575; + Tester_Class_0.var_2 = (var_34 <<= (var_25 ^= ~ (var_22 |= (var_22 = var_22)))); + var_23 *= (char)(var_28 *= var_32 ? var_34 ^ --var_34 : 3220732582528450560L); + if ((((Tester_Class_0)var_33).var_4 &= var_34) != (short)var_28) + { + Tester_Class_0.var_8 = ((false ? (Tester_Class_0)var_33 : (Tester_Class_0)var_33).var_6 = Tester_Class_0.var_8); + } + else + { + var_33 = false | (var_32 ^= true) ? ((new Tester_Class_0[var_34][var_34])[var_34])[var_34] : (Tester_Class_0)var_33; + } + if (false) + { + var_22 = 107656877775594496L; + } + else + { + ((var_32 &= (var_32 |= var_32)) || (var_23 /= var_25) == (Tester_Class_0.var_2 = 7649348100017113088L) ? (new Tester_Class_0[var_34])[var_34] : (Tester_Class_0)var_33).var_4 >>>= (((new Tester_Class_0[var_34])[var_34 <<= 'C']).var_6 = (((Tester_Class_0)(var_33 = (var_33 = var_33))).var_6 = ++var_28 > var_23 ? "qgq" : (Tester_Class_0.var_8 = Tester_Class_0.var_8))).equalsIgnoreCase(Tester_Class_0.var_8) ? var_34++ : ++var_34; + } + String[][] var_35; + Tester_Class_0.var_8 = Tester_Class_0.var_8; + var_27 = (new Tester_Class_0[var_34][var_34 /= 226411329])[false ? --var_34 : (var_34 /= 1.7237614E38F)][var_34]; + var_23 %= var_25; + } + + + + protected Object clone() + { + var_28 >>>= (new Tester_Class_0().var_1 = (byte)new Tester_Class_0().var_4); + ((Tester_Class_0)(var_27 = (Tester_Class_0.var_8 = (Tester_Class_0.var_8 = (Tester_Class_0.var_8 = "ybndugrur"))))).var_3 = Tester_Class_0.var_8; + var_22--; + new Tester_Class_0().var_4 -= (new Tester_Class_0().var_1 = (byte)'O'); + { + short var_29 = 12378; + } + Tester_Class_0.var_8 = "fd"; + "".lastIndexOf("bgsxwmil"); + new Tester_Class_0().var_6 = (Tester_Class_0.var_2 = -1.7590174497347678E308) == (var_26 = 'o') | true && !false ? Tester_Class_0.var_8 : (((Tester_Class_0)(var_27 = "")).var_6 = Tester_Class_0.var_8); + return var_27 = (var_27 = (var_27 = (var_27 = (Tester_Class_0.var_8 = Tester_Class_0.var_8).substring(var_24)))); + } + + public boolean equals(Object obj) + { + --var_28; + var_23 /= +var_23 * -6025098819014877184L / 3.3957492E38F / (short)'i'; + Tester_Class_0.var_2 = 3.0420988E38F * ((short)var_23 <= (var_23 %= 8.761205585617465E307) % + -1.2374670294031777E308 ? (var_23 = 'P') : (float)+ +1.0313120780554142E308); + (7489001532003495936L >= 'C' ? (Tester_Class_0)obj : (Tester_Class_0)(var_27 = obj)).func_4((short)(float)(byte)(float)(Tester_Class_0.var_2 = 1601763635)); + (var_23 * 2.2882572E38F <= (short)var_25 * (true || false ? (short)~ ((byte)1.1382317160718865E307) : (Tester_Class_0.var_2 = 7.909133507918336E307)) ? (Tester_Class_0)obj : (Tester_Class_0)obj).var_4++; + boolean var_30 = true; + var_27 = new Tester_Class_0(); + final String var_31 = "aiqnc"; + return 1.1357028E38F + (var_30 ? (Tester_Class_0)(var_27 = obj) : (Tester_Class_0)obj).var_7 == 3.860172628750592E306; + } + + +} + +public class Tester { + final static long var_36 = (4.4957056E37F < Tester_Class_1.var_22 + 281107777128915968L ? (Tester_Class_1.var_26 = 't') : (char)Tester_Class_1.var_28) - (4654994097042818048L | (byte)(Tester_Class_0.var_2 = (short)(Tester_Class_1.var_26 = ']'))) ^ 349774342780012544L; + + + static long func_0(final Tester_Class_1 arg_0, long arg_1) + { + ((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_0)(Tester_Class_1.var_27 = Tester_Class_0.var_8))).var_4 |= --new Tester_Class_0().var_4; + return Tester_Class_1.var_22 &= new Tester_Class_0().var_4; + } + + protected Tester_Class_1 func_1(final boolean arg_0, Object arg_1) + { + Tester_Class_0.var_2 = (short)Tester_Class_1.var_22; + ((arg_0 ? (byte)8.639448452214698E307 : ((Tester_Class_1)arg_1).var_24) <= ((Tester_Class_1)(Tester_Class_1.var_27 = new float[(byte)Tester_Class_1.var_22])).var_25++ ? (Tester_Class_0)arg_1 : (Tester_Class_0)(arg_1 = (Tester_Class_1.var_27 = (Tester_Class_0)arg_1))).var_3 = (Tester_Class_0.var_8 = "pgfdbinj"); + arg_1 = (new Tester_Class_0[((Tester_Class_0)arg_1).var_1 = (byte)1.0730194668655324E308])[(byte)'l']; + Tester_Class_0.var_8 = Tester_Class_0.var_8; + Tester_Class_1.var_27 = arg_0 & (true | !true) ? (Tester_Class_1)arg_1 : (Tester_Class_1)arg_1; + Tester_Class_1.var_28 += arg_0 ? (byte)(Tester_Class_0.var_8.compareToIgnoreCase(Tester_Class_0.var_8) % (Tester_Class_1.var_28 %= 2.2770412E38F)) : (byte)((byte)(short)Tester_Class_1.var_28 ^ var_36); + Tester_Class_1.var_28 <<= ((Tester_Class_0)arg_1).var_4; + return arg_0 ? (false ^ false ? (Tester_Class_1)arg_1 : (Tester_Class_1)arg_1) : (Tester_Class_1)arg_1; + } + + protected final static String[][] func_2(final double arg_0) + { + Tester_Class_0.var_2 = (((Tester_Class_1.var_22 = ((Tester_Class_1)(Tester_Class_1.var_27 = "")).var_25++) != + ((byte)(Tester_Class_0.var_2 = - ((byte)2.690435E38F))) ? (Tester_Class_1)(Tester_Class_1.var_27 = "twoj") : (new Tester_Class_1[(byte)'n'])[(byte)- ((byte)'p')]).var_25 /= (new short[false ? (byte)arg_0 : (byte)3.1713847E38F])[(byte)(short)((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_1.var_27 = "fi"))).var_7]); + { + ((new Tester_Class_1[(byte)9.709543613377303E307])[((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_0.var_8 = "efwkox"))).var_1 = (byte)7789404846284517376L]).var_23 *= (((new Tester_Class_0[(byte)'J'][(byte)++Tester_Class_1.var_28])[(byte)Tester_Class_1.var_28][(byte)(Tester_Class_1.var_28 = 1677818267)]).var_1 = false || true ? (byte)1.4659824E38F : (byte)(Tester_Class_1.var_26 = 'T')); + } + Tester_Class_0.var_2 = !true | !false | false & ! (!true & (true ^ false)) ? (byte)(Tester_Class_1.var_26 = 'l') : (short)(arg_0 * (char)(byte)Tester_Class_1.var_28); + Tester_Class_1.var_28 <<= false ^ (! ! (!false | ! !true | true) | (Tester_Class_0.var_2 = arg_0) == 245171309) ? (byte)arg_0 : (short)Tester_Class_1.var_22; + { + ((Tester_Class_1)(true ? (Tester_Class_1.var_27 = "axpbpadi") : Tester_Class_0.var_8)).var_23 = ((Tester_Class_1)(Tester_Class_1.var_27 = (new Tester_Class_0[(byte)1.1668668415637981E308][(byte)1.4116134699564312E308])[(byte)-7.4415765E37F][(byte)5156322492367086592L])).var_25; + } + final double var_37 = 1.6970877829548446E308; + --(Tester_Class_1.var_28 == (byte)((byte)arg_0 + (byte)1.1632396E38F) ? (Tester_Class_0)(Tester_Class_1.var_27 = "vluk") : (Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_0.var_8 = "pfki"))).var_4; + Tester_Class_1.var_22--; + return new String[new Tester_Class_0().var_1 = (((Tester_Class_0)(Tester_Class_1.var_27 = "filxvch")).var_1 = (byte)var_36)][new Tester_Class_0().var_1 = (byte)'C']; + } + + final short func_3(byte arg_0, final short arg_1) + { + ((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_0.var_8 = "oenvgqdit"))).var_6 = Tester_Class_0.var_8; + new Tester_Class_0().var_4 >>>= + -var_36; + Tester_Class_0.var_2 = (((new Tester_Class_1[arg_0])[arg_0 %= ++Tester_Class_1.var_28]).var_25 &= Tester_Class_1.var_22); + ((new Tester_Class_1[arg_0])[arg_0 |= 1942533325]).var_23 %= arg_0 < arg_0 ? 'm' : 'N'; + float var_38; + ((new Tester_Class_1[arg_0])[arg_0]).var_23 /= (((new Tester_Class_1[arg_0][arg_0])[arg_0 |= 'N'])[arg_0 <<= - ((byte)- (Tester_Class_0.var_2 = 3.3324301E38F))]).var_23; + return true ? arg_1 : arg_1; + } + + private String func_4() + { + if (true) + { + ((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_1.var_27 = (Tester_Class_1.var_27 = Tester_Class_0.var_8)))).var_1 = (byte)6.4527776E37F; + ((Tester_Class_0)(Tester_Class_1.var_27 = new char[(byte)1.5121402849337185E307])).var_4 >>= - ((byte)3.3631582E37F) + (Tester_Class_1.var_28 /= 2.813947549586372E307); + } + else + { + { + Tester_Class_1.var_22 *= 1.6498653E36F; + } + Tester_Class_0.var_2 = + ((byte)7.750601265069686E307) > (short)(byte)3131520439106527232L ? (short)4699552681135671296L : (short)Tester_Class_1.var_22; + Tester_Class_1.var_22++; + ((Tester_Class_1)(new Object[(byte)6.231994821505742E307])[(byte)Tester_Class_1.var_22]).var_23 %= 30526551; + { + Tester_Class_0.var_2 = ((Tester_Class_1)(Tester_Class_1.var_27 = new short[(byte)9.628297E37F])).var_25; + } + Tester_Class_1.var_28 /= (byte)(false ^ Tester_Class_0.var_8.equalsIgnoreCase(Tester_Class_0.var_8) ? (byte)2.689633745095358E307 : (short)1.2532476E38F); + float var_39; + long[] var_40 = new long[((Tester_Class_0)(Tester_Class_1.var_27 = Tester_Class_0.var_8)).var_1 = (((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_0.var_8 = Tester_Class_0.var_8))).var_1 = (byte)(1.8335008E38F % (true | false ? (short)Tester_Class_1.var_22 : (byte)'P')))]; + } + Tester_Class_0.var_2 = (((new Tester_Class_0[((Tester_Class_0)(Tester_Class_1.var_27 = "inufeoe")).var_1 = (byte)(short)'M'])[(byte)(Tester_Class_0.var_2 = + - -2.274269E38F)]).var_1 = (((Tester_Class_0)(Tester_Class_1.var_27 = "c")).var_1 = (byte)'Z')); + Tester_Class_0.var_8 = (Tester_Class_0.var_8 = Tester_Class_0.var_8); + return "rkvffvlf"; + } + + final char func_5(final char arg_0, final Object[] arg_1, final double arg_2, Object arg_3) + { + arg_3 = true && Tester_Class_1.var_22 < (((Tester_Class_0)arg_3).var_1 = (((Tester_Class_0)(Tester_Class_1.var_27 = arg_3)).var_1 = (byte)arg_2)) ? "dgmwbkv" : Tester_Class_0.var_8; + (true ? (Tester_Class_1)arg_3 : (Tester_Class_1)arg_3).var_23 -= (Tester_Class_0.var_2 = arg_0); + arg_3 = (new String[(byte)arg_2])[(byte)-2.797633529863769E307]; + (false ^ !false ^ (!true && true) ? (Tester_Class_0)arg_3 : (Tester_Class_0)arg_3).var_4 -= (new char[((Tester_Class_0)arg_3).var_1 = (((Tester_Class_0)arg_3).var_1 = (((Tester_Class_0)arg_3).var_1 = (byte)2.433897E38F))])[((Tester_Class_0)arg_3).var_1 = (byte)+7.036923762392132E307]; + Tester_Class_0.var_8 = Tester_Class_0.var_8; + Tester_Class_0.var_2 = true ^ +((Tester_Class_1)(arg_3 = "o")).var_23 <= arg_2 ? (short)Tester_Class_1.var_22 : (((Tester_Class_0)arg_3).var_1 = (byte)1.9730195E38F); + (false ? (Tester_Class_0)arg_3 : (Tester_Class_0)arg_3).var_6 = "bpjqfacys"; + ((new Tester_Class_0[((Tester_Class_0)arg_3).var_1 = (byte)1969581340][((Tester_Class_0)arg_3).var_1 = (byte)(Tester_Class_0.var_2 = arg_0)])[((Tester_Class_0)arg_3).var_1 = (byte)(Tester_Class_0.var_2 = 4044194664687833088L)][((Tester_Class_0)arg_3).var_1 = (byte)((Tester_Class_1)arg_3).var_24]).var_1 = (false ? (byte)+ ((byte)1.2689328633821032E305) == arg_2 : false) ? (byte)arg_2 : (((Tester_Class_0)arg_3).var_1 = (byte)1586517741); + return (func_3(((Tester_Class_0)arg_3).var_1 = (byte)Tester_Class_1.var_28, (short)(byte)- +func_1(true, arg_3).var_23) > 1882532904 ? (short)2.6362656E38F >= (char)2.445034E38F & false : var_36 > Tester_Class_1.var_22) ? ((new Tester_Class_0[(byte)1.2074529E38F][(byte)'N'])[(byte)1.3365433211782782E308][(byte)Tester_Class_1.var_28]).var_4 : 'O'; + } + + private final static Tester_Class_1 func_6(String arg_0, String arg_1) + { + Tester_Class_1.var_22 += ((new Tester_Class_0[(byte)4.1707075152824266E306])[(byte)(short)(((Tester_Class_0)(Tester_Class_1.var_27 = "tmyiha")).var_4 &= 'e')]).var_4; + return (new Tester_Class_1[((Tester_Class_0)(Tester_Class_1.var_27 = arg_1)).var_1 = (byte)2.8419246E38F][(byte)Tester_Class_1.var_22])[((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_1.var_27 = arg_0))).var_1 = (((Tester_Class_0)(Tester_Class_1.var_27 = (Tester_Class_0.var_8 = "nvyfpdyms"))).var_1 = (byte)Tester_Class_1.var_22--)][((Tester_Class_0)(Tester_Class_1.var_27 = "kklsnsnia")).var_1 = (byte)'[']; + } + + double func_7(Object arg_0, final String arg_1) + { + if (false) + { + ((Tester_Class_0)arg_0).var_1 = (byte)'Z'; + } + else + { + ((Tester_Class_0)arg_0).var_3 = Tester_Class_0.var_8; + } + float var_41 = (true ? (new Tester_Class_1[((Tester_Class_0)arg_0).var_1 = (byte)var_36])[((Tester_Class_0)arg_0).var_1 = (byte)Tester_Class_1.var_22] : (Tester_Class_1)arg_0).var_23 /= 'n'; + ++Tester_Class_1.var_22; + return true ^ +func_6(arg_1, Tester_Class_0.var_8).var_23 < ~6945306015697774592L & (Tester_Class_1.var_28 |= var_36) <= var_36 ? + -1.4330949313452472E308 - -6602331706844466176L : Tester_Class_1.var_28; + } + + private final static byte func_8(final Object arg_0, double arg_1, final double arg_2, double arg_3) + { + ((Tester_Class_1)arg_0).var_23 = (short)(!false && (new boolean[(byte)2.2566308E38F])[((Tester_Class_0)arg_0).var_1 = (byte)((Tester_Class_1)arg_0).var_25] ? arg_2 : 3.0315489414155014E307); + short var_42 = (new short[((Tester_Class_0)arg_0).var_1 = (((Tester_Class_0)arg_0).var_1 = (byte)var_36)])[(byte)arg_2]; + Tester_Class_1.var_22 <<= ((new Tester_Class_0[(byte)var_42])[((Tester_Class_0)arg_0).var_1 = (byte)'X']).var_4; + (false ? new Tester_Class_0() : new Tester_Class_0()).var_4 *= 6.636831399350763E307; + (true & false ^ !((Tester_Class_1)arg_0).equals(arg_0) ? (Tester_Class_0)arg_0 : (Tester_Class_0)arg_0).var_4 <<= (Tester_Class_1.var_22 >>>= (Tester_Class_1.var_28 -= Tester_Class_1.var_28)) / 1064434; + int var_43; + final Object var_44 = Tester_Class_1.var_27 = new byte[((Tester_Class_0)arg_0).var_1 = (byte)+arg_2]; + ((Tester_Class_0)var_44).var_1 = (byte)arg_1; + Tester_Class_1 var_45 = (3582921389614857216L != 2.132918E38F / Tester_Class_1.var_22 % (((Tester_Class_1)var_44).var_23 %= var_42--) ? false : false ^ !false) ? func_6(((Tester_Class_0)arg_0).var_6 = Tester_Class_0.var_8, Tester_Class_0.var_8 = Tester_Class_0.var_8) : (Tester_Class_1)arg_0; + arg_1 *= false ? (false ? (byte)var_45.var_23 : (byte)var_45.var_24) : (byte)8158132319185776640L; + Tester_Class_0.var_8 = (new Tester_Class_0().var_6 = "gvxkyj"); + Tester_Class_1.var_27 = "bkfbu"; + arg_1 *= (((Tester_Class_0)arg_0).var_4 += new Tester_Class_0().var_4); + Tester_Class_0 var_46 = (false ? false && - (((Tester_Class_0)arg_0).var_1 = (byte)var_45.var_24) > var_45.var_23 - arg_2 : ("fn".startsWith(Tester_Class_0.var_8) && false) & !true) ? (Tester_Class_0)arg_0 : (Tester_Class_0)arg_0; + return var_46.var_1 = (var_46.var_1 = (var_46.var_1 = (byte)var_45.var_23)); + } + + public static void main(String[] args) + { + for (int i = 0; i < 100000; i++) { + Tester t = new Tester(); + try { + t.test(); + } catch(Throwable e) { + } + if (t.var_36 != -4918908939899620363L) { + throw new InternalError(t.var_36 + " != -4918908939899620363"); + } + } + } + + private void test() + { + ((Tester_Class_0)(Tester_Class_1.var_27 = new Tester_Class_0())).var_4 &= new Tester_Class_0().var_4 >>> (short)new Tester_Class_1().var_25; + Tester_Class_1.var_22 <<= Tester_Class_1.var_22; + Tester_Class_1.var_27 = ((true | ! !false) & false ? ! !true : 6.5017485E37F == (short)(Tester_Class_1.var_22 &= 'h')) ? (Tester_Class_1.var_27 = new Tester_Class_1()) : new Tester_Class_1(); + (1.252611E37F < (((new Tester_Class_0[(byte)'X'])[(byte)6.916916470825763E307]).var_4 /= (byte)Tester_Class_1.var_28 < (new short[(byte)7.626803503643197E307])[(byte)var_36] ? (short)new Tester_Class_0().var_4 : (short)(byte)Tester_Class_1.var_22) ? (true ? new Tester_Class_0() : new Tester_Class_0()) : (true ? new Tester_Class_0() : (Tester_Class_0)(Tester_Class_1.var_27 = Tester_Class_0.var_8))).var_4 ^= Tester_Class_1.var_28++; + (true ? new Tester_Class_1() : func_1(true, Tester_Class_1.var_27 = "jjgccelm")).var_23 -= (- - + + +1.2976166388790213E308 != ((!true ^ ! !true) & (short)(Tester_Class_1.var_28 &= var_36) <= (Tester_Class_1.var_26 = 'C') ? 1163089569715148800L : 8.591879058615699E307) ? (new Tester_Class_0().var_1 = (new Tester_Class_0().var_1 = (byte)2.7209893E38F)) : (!false ^ ! !false ? (short)'x' : (short)'a')) + 7620981797791666176L; + new Tester_Class_0().var_4 ^= 8777687662500669440L; + final String[] var_47 = new String[((1864097118983963648L | (Tester_Class_1.var_26 = '[')) < + (new Tester_Class_1().var_23 += --new Tester_Class_0().var_4) ? ! !true : false) ? (new Tester_Class_0().var_1 = (new Tester_Class_0().var_1 = (byte)2.6448988E38F)) : (byte)Tester_Class_1.var_22]; + long var_48 = 0L; + Tester_Class_0.var_2 = "nwcmc".codePointAt("wgcdlmd".compareTo("jyt")); + do + { + Tester_Class_1.var_22 += new Tester_Class_0().var_4; + var_48++; + Tester_Class_1.var_27 = false ? "dfvpqs" : Tester_Class_0.var_8; + new Tester_Class_0().var_1 = (new Tester_Class_0().var_1 = (new byte[(byte)2.2825838E38F])[(byte)4.2446597794703817E307]); + } while ((true ? !false : false & !false) && (var_48 < 117 && true)); + int var_49 = 0; + Tester_Class_1.var_26 = 'I'; + short var_50; + while (var_49 < 225 && ('U' | ~ ((byte)9.556538701292864E306)) < var_49) + { + var_50 = (var_50 = ((byte)1.2016701369644112E308 != (var_50 = (short)1.2518271E38F) ^ !true ? !true : false) ? (short)6.629572378442352E307 : (byte)'O'); + var_49++; + var_50 = true ? (byte)Tester_Class_1.var_22 : (byte)(Tester_Class_1.var_22 = (byte)var_48); + byte var_51; + short var_52; + } + Tester_Class_1.var_27 = Tester_Class_0.var_8 + "r"; + var_50 = (var_50 = true ^ ! (!false ^ false) ? (byte)573442894 : (byte)2.1479471E38F); + ((var_50 = (short)'w') >= (new Tester_Class_0().var_1 = (byte)5.148172E37F) & true ? new Tester_Class_0() : new Tester_Class_0()).var_4 >>= true ? (new Tester_Class_0().var_4 /= (byte)Tester_Class_1.var_28) : (Tester_Class_1.var_26 = '^'); + float var_53; + (func_6(Tester_Class_0.var_8, Tester_Class_0.var_8).var_24 <= (var_50 = (var_50 = (short)var_48)) ^ !true | true & true | true ^ false ? (Tester_Class_1)(Tester_Class_1.var_27 = Tester_Class_0.var_8) : new Tester_Class_1()).var_23 /= ((new Tester_Class_0[(byte)1.6656795E38F])[new Tester_Class_0().var_1 = (byte)1.212530193895014E308]).var_4; + long var_54 = 0L; + Object var_55; + (true | --new Tester_Class_0().var_4 == 2898909413610959872L & true == true ? func_6(Tester_Class_0.var_8, Tester_Class_0.var_8) : new Tester_Class_1()).var_23 %= 7471272661059674112L; + while (false & (false | 5.7300464E37F != (short)(Tester_Class_0.var_2 = (short)var_36)) && var_54 < 293) + { + func_6(Tester_Class_0.var_8 = "wts", Tester_Class_0.var_8 = (Tester_Class_0.var_8 = Tester_Class_0.var_8)).var_25 |= (Tester_Class_1.var_22 ^= (var_50 = (byte)1.0904691577897794E308)); + var_54++; + (false ? func_6(Tester_Class_0.var_8, "inujn") : func_6(Tester_Class_0.var_8, Tester_Class_0.var_8 = Tester_Class_0.var_8)).var_23 /= (Tester_Class_0.var_2 = (var_50 = (((Tester_Class_0)(var_55 = Tester_Class_0.var_8)).var_1 = (byte)(short)Tester_Class_1.var_28))); + Tester_Class_0.var_8 = Tester_Class_0.var_8; + } + var_50 = func_3(new Tester_Class_0().var_1 = (new Tester_Class_0().var_1 = (byte)var_36), var_50 = (var_50 = (var_50 = (byte)var_36))); + Tester_Class_1.var_22++; + Tester_Class_1.var_28 <<= 'Y'; + } +}