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/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/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..0b5dd3cf977b400a38a91876129a733f2042ad9f 100644 --- a/src/share/vm/opto/connode.hpp +++ b/src/share/vm/opto/connode.hpp @@ -282,6 +282,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 +301,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/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/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index 6f2fa5be969b273ba881d73e603fa6d661df4adb..2b18a3e0f066b74084276bc3cafa6eacceaa3f75 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -2176,6 +2176,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;