6709093: Compressed Oops: reduce size of compiled methods
Exclude UEP size from nmethod code size and use narrow klass oop to load prototype header. Reviewed-by: jrose, never
This commit is contained in:
parent
54eeffff83
commit
dbdeade3b7
@ -5975,7 +5975,8 @@ instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
instruct decodeHeapOop(iRegP dst, iRegN 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));
|
match(Set dst (DecodeN src));
|
||||||
format %{ "decode_heap_oop $src, $dst" %}
|
format %{ "decode_heap_oop $src, $dst" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@ -5985,7 +5986,8 @@ instruct decodeHeapOop(iRegP dst, iRegN src) %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
instruct decodeHeapOop_not_null(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));
|
match(Set dst (DecodeN src));
|
||||||
format %{ "decode_heap_oop_not_null $src, $dst" %}
|
format %{ "decode_heap_oop_not_null $src, $dst" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
|
@ -5007,8 +5007,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re
|
|||||||
jcc(Assembler::notEqual, cas_label);
|
jcc(Assembler::notEqual, cas_label);
|
||||||
// The bias pattern is present in the object's header. Need to check
|
// The bias pattern is present in the object's header. Need to check
|
||||||
// whether the bias owner and the epoch are both still current.
|
// whether the bias owner and the epoch are both still current.
|
||||||
load_klass(tmp_reg, obj_reg);
|
load_prototype_header(tmp_reg, obj_reg);
|
||||||
movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
|
|
||||||
orq(tmp_reg, r15_thread);
|
orq(tmp_reg, r15_thread);
|
||||||
xorq(tmp_reg, swap_reg);
|
xorq(tmp_reg, swap_reg);
|
||||||
andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place));
|
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
|
// FIXME: due to a lack of registers we currently blow away the age
|
||||||
// bits in this situation. Should attempt to preserve them.
|
// bits in this situation. Should attempt to preserve them.
|
||||||
load_klass(tmp_reg, obj_reg);
|
load_prototype_header(tmp_reg, obj_reg);
|
||||||
movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
|
|
||||||
orq(tmp_reg, r15_thread);
|
orq(tmp_reg, r15_thread);
|
||||||
if (os::is_MP()) {
|
if (os::is_MP()) {
|
||||||
lock();
|
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
|
// FIXME: due to a lack of registers we currently blow away the age
|
||||||
// bits in this situation. Should attempt to preserve them.
|
// bits in this situation. Should attempt to preserve them.
|
||||||
load_klass(tmp_reg, obj_reg);
|
load_prototype_header(tmp_reg, obj_reg);
|
||||||
movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
|
|
||||||
if (os::is_MP()) {
|
if (os::is_MP()) {
|
||||||
lock();
|
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) {
|
void MacroAssembler::store_klass(Register dst, Register src) {
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
encode_heap_oop_not_null(src);
|
encode_heap_oop_not_null(src);
|
||||||
|
@ -1111,6 +1111,8 @@ class MacroAssembler : public Assembler {
|
|||||||
void store_klass(Register dst, Register src);
|
void store_klass(Register dst, Register src);
|
||||||
void store_klass_gap(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 load_heap_oop(Register dst, Address src);
|
||||||
void store_heap_oop(Address dst, Register src);
|
void store_heap_oop(Address dst, Register src);
|
||||||
void encode_heap_oop(Register r);
|
void encode_heap_oop(Register r);
|
||||||
|
@ -6149,7 +6149,7 @@ instruct loadNKlass(rRegN dst, memory mem)
|
|||||||
match(Set dst (LoadNKlass mem));
|
match(Set dst (LoadNKlass mem));
|
||||||
|
|
||||||
ins_cost(125); // XXX
|
ins_cost(125); // XXX
|
||||||
format %{ "movl $dst, $mem\t# compressed klass ptr\n\t" %}
|
format %{ "movl $dst, $mem\t# compressed klass ptr" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
|
Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
|
||||||
Register dst = as_Register($dst$$reg);
|
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) %{
|
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));
|
match(Set dst (DecodeN src));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
format %{ "decode_heap_oop $dst,$src" %}
|
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) %{
|
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));
|
match(Set dst (DecodeN src));
|
||||||
format %{ "decode_heap_oop_not_null $dst,$src" %}
|
format %{ "decode_heap_oop_not_null $dst,$src" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
|
@ -878,7 +878,7 @@ int ciMethod::instructions_size() {
|
|||||||
(TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
|
(TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return code->code_size();
|
return code->code_end() - code->verified_entry_point();
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1992,11 +1992,49 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Op_AddP: { // Assert sane base pointers
|
case Op_AddP: { // Assert sane base pointers
|
||||||
const Node *addp = n->in(AddPNode::Address);
|
Node *addp = n->in(AddPNode::Address);
|
||||||
assert( !addp->is_AddP() ||
|
assert( !addp->is_AddP() ||
|
||||||
addp->in(AddPNode::Base)->is_top() || // Top OK for allocation
|
addp->in(AddPNode::Base)->is_top() || // Top OK for allocation
|
||||||
addp->in(AddPNode::Base) == n->in(AddPNode::Base),
|
addp->in(AddPNode::Base) == n->in(AddPNode::Base),
|
||||||
"Base pointers must match" );
|
"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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user