diff --git a/src/cpu/sparc/vm/sparc.ad b/src/cpu/sparc/vm/sparc.ad index 41ba26e239ad3b7d95d98f4ddcde7daf15118f1f..39e854ee5864d020b43e83d075900230e5dfed13 100644 --- a/src/cpu/sparc/vm/sparc.ad +++ b/src/cpu/sparc/vm/sparc.ad @@ -5975,7 +5975,8 @@ instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{ %} instruct decodeHeapOop(iRegP dst, iRegN src) %{ - predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); + predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && + n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); match(Set dst (DecodeN src)); format %{ "decode_heap_oop $src, $dst" %} ins_encode %{ @@ -5985,7 +5986,8 @@ instruct decodeHeapOop(iRegP dst, iRegN src) %{ %} instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{ - predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); + predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || + n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); match(Set dst (DecodeN src)); format %{ "decode_heap_oop_not_null $src, $dst" %} ins_encode %{ diff --git a/src/cpu/x86/vm/assembler_x86_64.cpp b/src/cpu/x86/vm/assembler_x86_64.cpp index a165cd6dd3d6dbf92c0c878e17f134da6289afda..7ea32612190d5bbbd2d81821c2aab37b3ac3a7e6 100644 --- a/src/cpu/x86/vm/assembler_x86_64.cpp +++ b/src/cpu/x86/vm/assembler_x86_64.cpp @@ -5007,8 +5007,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re jcc(Assembler::notEqual, cas_label); // The bias pattern is present in the object's header. Need to check // whether the bias owner and the epoch are both still current. - load_klass(tmp_reg, obj_reg); - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + load_prototype_header(tmp_reg, obj_reg); orq(tmp_reg, r15_thread); xorq(tmp_reg, swap_reg); andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place)); @@ -5082,8 +5081,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re // // FIXME: due to a lack of registers we currently blow away the age // bits in this situation. Should attempt to preserve them. - load_klass(tmp_reg, obj_reg); - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + load_prototype_header(tmp_reg, obj_reg); orq(tmp_reg, r15_thread); if (os::is_MP()) { lock(); @@ -5113,8 +5111,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re // // FIXME: due to a lack of registers we currently blow away the age // bits in this situation. Should attempt to preserve them. - load_klass(tmp_reg, obj_reg); - movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + load_prototype_header(tmp_reg, obj_reg); if (os::is_MP()) { lock(); } @@ -5158,6 +5155,16 @@ void MacroAssembler::load_klass(Register dst, Register src) { } } +void MacroAssembler::load_prototype_header(Register dst, Register src) { + if (UseCompressedOops) { + movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } else { + movq(dst, Address(src, oopDesc::klass_offset_in_bytes())); + movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes())); + } +} + void MacroAssembler::store_klass(Register dst, Register src) { if (UseCompressedOops) { encode_heap_oop_not_null(src); diff --git a/src/cpu/x86/vm/assembler_x86_64.hpp b/src/cpu/x86/vm/assembler_x86_64.hpp index e8241139c6266e3d18d0c3e74a0e529b20986dda..2b90204891a6e3cd4ec830322c25814b80918829 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 store_klass(Register dst, Register src); void store_klass_gap(Register dst, Register src); + void load_prototype_header(Register dst, Register src); + void load_heap_oop(Register dst, Address src); void store_heap_oop(Address dst, Register src); void encode_heap_oop(Register r); diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad index dd168e4c528837502eebd0e1c23f63c0131d5b29..41d1abfece6ac149f8731a5efccd25d259361452 100644 --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -6149,7 +6149,7 @@ instruct loadNKlass(rRegN dst, memory mem) match(Set dst (LoadNKlass mem)); ins_cost(125); // XXX - format %{ "movl $dst, $mem\t# compressed klass ptr\n\t" %} + format %{ "movl $dst, $mem\t# compressed klass ptr" %} ins_encode %{ Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); Register dst = as_Register($dst$$reg); @@ -7089,7 +7089,8 @@ instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ %} instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ - predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); + predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && + n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); match(Set dst (DecodeN src)); effect(KILL cr); format %{ "decode_heap_oop $dst,$src" %} @@ -7105,7 +7106,8 @@ instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ %} instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{ - predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); + predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || + n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); match(Set dst (DecodeN src)); format %{ "decode_heap_oop_not_null $dst,$src" %} ins_encode %{ diff --git a/src/share/vm/ci/ciMethod.cpp b/src/share/vm/ci/ciMethod.cpp index 2c6c5aa272d876ad4acba05348c0d7ffc1b31255..ef890bd86a51007d2d3979e53c9469212107d451 100644 --- a/src/share/vm/ci/ciMethod.cpp +++ b/src/share/vm/ci/ciMethod.cpp @@ -878,7 +878,7 @@ int ciMethod::instructions_size() { (TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) { return 0; } - return code->code_size(); + return code->code_end() - code->verified_entry_point(); ) } diff --git a/src/share/vm/opto/compile.cpp b/src/share/vm/opto/compile.cpp index d0378175008d939300d380e4d51e489dda968a41..29484546de56796301ee9bc3611a83dc7035f2dc 100644 --- a/src/share/vm/opto/compile.cpp +++ b/src/share/vm/opto/compile.cpp @@ -1992,11 +1992,49 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) { } case Op_AddP: { // Assert sane base pointers - const Node *addp = n->in(AddPNode::Address); + Node *addp = n->in(AddPNode::Address); assert( !addp->is_AddP() || addp->in(AddPNode::Base)->is_top() || // Top OK for allocation addp->in(AddPNode::Base) == n->in(AddPNode::Base), "Base pointers must match" ); +#ifdef _LP64 + if (UseCompressedOops && + addp->Opcode() == Op_ConP && + addp == n->in(AddPNode::Base) && + n->in(AddPNode::Offset)->is_Con()) { + // Use addressing with narrow klass to load with offset on x86. + // On sparc loading 32-bits constant and decoding it have less + // instructions (4) then load 64-bits constant (7). + // Do this transformation here since IGVN will convert ConN back to ConP. + const Type* t = addp->bottom_type(); + if (t->isa_oopptr()) { + Node* nn = NULL; + + // Look for existing ConN node of the same exact type. + Compile* C = Compile::current(); + Node* r = C->root(); + uint cnt = r->outcnt(); + for (uint i = 0; i < cnt; i++) { + Node* m = r->raw_out(i); + if (m!= NULL && m->Opcode() == Op_ConN && + m->bottom_type()->is_narrowoop()->make_oopptr() == t) { + nn = m; + break; + } + } + if (nn != NULL) { + // Decode a narrow oop to match address + // [R12 + narrow_oop_reg<<3 + offset] + nn = new (C, 2) DecodeNNode(nn, t); + n->set_req(AddPNode::Base, nn); + n->set_req(AddPNode::Address, nn); + if (addp->outcnt() == 0) { + addp->disconnect_inputs(NULL); + } + } + } + } +#endif break; }