src/cpu/x86/vm/x86_64.ad
Print this page
rev 3688 : 7054512: Compress class pointers after perm gen removal
Summary: support of compress class pointers in the compilers.
Reviewed-by:
*** 1407,1420 ****
//=============================================================================
#ifndef PRODUCT
void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
{
! if (UseCompressedOops) {
st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
! if (Universe::narrow_oop_shift() != 0) {
! st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1");
}
st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
} else {
st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
"# Inline cache check");
--- 1407,1420 ----
//=============================================================================
#ifndef PRODUCT
void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
{
! if (UseCompressedKlassPointers) {
st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
! if (Universe::narrow_klass_shift() != 0) {
! st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
}
st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
} else {
st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
"# Inline cache check");
*** 1426,1436 ****
void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
{
MacroAssembler masm(&cbuf);
uint insts_size = cbuf.insts_size();
! if (UseCompressedOops) {
masm.load_klass(rscratch1, j_rarg0);
masm.cmpptr(rax, rscratch1);
} else {
masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
}
--- 1426,1436 ----
void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
{
MacroAssembler masm(&cbuf);
uint insts_size = cbuf.insts_size();
! if (UseCompressedKlassPointers) {
masm.load_klass(rscratch1, j_rarg0);
masm.cmpptr(rax, rscratch1);
} else {
masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
}
*** 1574,1583 ****
--- 1574,1588 ----
bool Matcher::narrow_oop_use_complex_address() {
assert(UseCompressedOops, "only for compressed oops code");
return (LogMinObjAlignmentInBytes <= 3);
}
+ bool Matcher::narrow_klass_use_complex_address() {
+ assert(UseCompressedKlassPointers, "only for compressed klass code");
+ return (LogKlassAlignmentInBytes <= 3);
+ }
+
// Is it better to copy float constants, or load them directly from
// memory? Intel can load a float constant from a direct address,
// requiring no extra registers. Most RISCs will have to materialize
// an address into a register first, so they would do better to copy
// the constant from stack.
*** 3137,3146 ****
--- 3142,3159 ----
op_cost(10);
format %{ %}
interface(CONST_INTER);
%}
+ operand immNKlass() %{
+ match(ConNKlass);
+
+ op_cost(10);
+ format %{ %}
+ interface(CONST_INTER);
+ %}
+
// NULL Pointer Immediate
operand immN0() %{
predicate(n->get_narrowcon() == 0);
match(ConN);
*** 4036,4045 ****
--- 4049,4197 ----
scale($scale);
disp($off);
%}
%}
+ operand indirectNarrowKlass(rRegN reg)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(DecodeNKlass reg);
+
+ format %{ "[$reg]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index(0x4);
+ scale(0x0);
+ disp(0x0);
+ %}
+ %}
+
+ operand indOffset8NarrowKlass(rRegN reg, immL8 off)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (DecodeNKlass reg) off);
+
+ format %{ "[$reg + $off (8-bit)]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index(0x4);
+ scale(0x0);
+ disp($off);
+ %}
+ %}
+
+ operand indOffset32NarrowKlass(rRegN reg, immL32 off)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (DecodeNKlass reg) off);
+
+ format %{ "[$reg + $off (32-bit)]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index(0x4);
+ scale(0x0);
+ disp($off);
+ %}
+ %}
+
+ operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (AddP (DecodeNKlass reg) lreg) off);
+
+ op_cost(10);
+ format %{"[$reg + $off + $lreg]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index($lreg);
+ scale(0x0);
+ disp($off);
+ %}
+ %}
+
+ operand indIndexNarrowKlass(rRegN reg, rRegL lreg)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (DecodeNKlass reg) lreg);
+
+ op_cost(10);
+ format %{"[$reg + $lreg]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index($lreg);
+ scale(0x0);
+ disp(0x0);
+ %}
+ %}
+
+ operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (DecodeNKlass reg) (LShiftL lreg scale));
+
+ op_cost(10);
+ format %{"[$reg + $lreg << $scale]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index($lreg);
+ scale($scale);
+ disp(0x0);
+ %}
+ %}
+
+ operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
+ %{
+ predicate(Universe::narrow_klass_shift() == 0);
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off);
+
+ op_cost(10);
+ format %{"[$reg + $off + $lreg << $scale]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index($lreg);
+ scale($scale);
+ disp($off);
+ %}
+ %}
+
+ operand indCompressedKlassOffset(rRegN reg, immL32 off) %{
+ predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8));
+ constraint(ALLOC_IN_RC(ptr_reg));
+ match(AddP (DecodeNKlass reg) off);
+
+ op_cost(10);
+ format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %}
+ interface(MEMORY_INTER) %{
+ base(0xc); // R12
+ index($reg);
+ scale(0x3);
+ disp($off);
+ %}
+ %}
+
+ operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale)
+ %{
+ constraint(ALLOC_IN_RC(ptr_reg));
+ predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
+ match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off);
+
+ op_cost(10);
+ format %{"[$reg + $off + $idx << $scale]" %}
+ interface(MEMORY_INTER) %{
+ base($reg);
+ index($idx);
+ scale($scale);
+ disp($off);
+ %}
+ %}
//----------Special Memory Operands--------------------------------------------
// Stack Slot Operand - This operand is used for loading and storing temporary
// values on the stack where a match requires a value to
// flow through memory.
*** 4207,4217 ****
opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
indCompressedOopOffset,
indirectNarrow, indOffset8Narrow, indOffset32Narrow,
indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
! indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
//----------PIPELINE-----------------------------------------------------------
// Rules which define the behavior of the target architectures pipeline.
pipeline %{
--- 4359,4373 ----
opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
indCompressedOopOffset,
indirectNarrow, indOffset8Narrow, indOffset32Narrow,
indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
! indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow,
! indCompressedKlassOffset,
! indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass,
! indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass,
! indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass);
//----------PIPELINE-----------------------------------------------------------
// Rules which define the behavior of the target architectures pipeline.
pipeline %{
*** 5467,5476 ****
--- 5623,5648 ----
}
%}
ins_pipe(ialu_reg_fat); // XXX
%}
+ instruct loadConNKlass(rRegN dst, immNKlass src) %{
+ match(Set dst src);
+
+ ins_cost(125);
+ format %{ "movl $dst, $src\t# compressed klass ptr" %}
+ ins_encode %{
+ address con = (address)$src$$constant;
+ if (con == NULL) {
+ ShouldNotReachHere();
+ } else {
+ __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
+ }
+ %}
+ ins_pipe(ialu_reg_fat); // XXX
+ %}
+
instruct loadConF0(regF dst, immF0 src)
%{
match(Set dst src);
ins_cost(100);
*** 5736,5746 ****
ins_pipe(ialu_mem_reg);
%}
instruct storeImmP0(memory mem, immP0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreP mem zero));
ins_cost(125); // XXX
format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
ins_encode %{
--- 5908,5918 ----
ins_pipe(ialu_mem_reg);
%}
instruct storeImmP0(memory mem, immP0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreP mem zero));
ins_cost(125); // XXX
format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
ins_encode %{
*** 5772,5784 ****
__ movl($mem$$Address, $src$$Register);
%}
ins_pipe(ialu_mem_reg);
%}
instruct storeImmN0(memory mem, immN0 zero)
%{
! predicate(Universe::narrow_oop_base() == NULL);
match(Set mem (StoreN mem zero));
ins_cost(125); // XXX
format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
ins_encode %{
--- 5944,5968 ----
__ movl($mem$$Address, $src$$Register);
%}
ins_pipe(ialu_mem_reg);
%}
+ instruct storeNKlass(memory mem, rRegN src)
+ %{
+ match(Set mem (StoreNKlass mem src));
+
+ ins_cost(125); // XXX
+ format %{ "movl $mem, $src\t# compressed klass ptr" %}
+ ins_encode %{
+ __ movl($mem$$Address, $src$$Register);
+ %}
+ ins_pipe(ialu_mem_reg);
+ %}
+
instruct storeImmN0(memory mem, immN0 zero)
%{
! predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL);
match(Set mem (StoreN mem zero));
ins_cost(125); // XXX
format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
ins_encode %{
*** 5802,5815 ****
}
%}
ins_pipe(ialu_mem_imm);
%}
// Store Integer Immediate
instruct storeImmI0(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreI mem zero));
ins_cost(125); // XXX
format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
ins_encode %{
--- 5986,6011 ----
}
%}
ins_pipe(ialu_mem_imm);
%}
+ instruct storeImmNKlass(memory mem, immNKlass src)
+ %{
+ match(Set mem (StoreNKlass mem src));
+
+ ins_cost(150); // XXX
+ format %{ "movl $mem, $src\t# compressed klass ptr" %}
+ ins_encode %{
+ __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
+ %}
+ ins_pipe(ialu_mem_imm);
+ %}
+
// Store Integer Immediate
instruct storeImmI0(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreI mem zero));
ins_cost(125); // XXX
format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
ins_encode %{
*** 5830,5840 ****
%}
// Store Long Immediate
instruct storeImmL0(memory mem, immL0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreL mem zero));
ins_cost(125); // XXX
format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
ins_encode %{
--- 6026,6036 ----
%}
// Store Long Immediate
instruct storeImmL0(memory mem, immL0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreL mem zero));
ins_cost(125); // XXX
format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
ins_encode %{
*** 5855,5865 ****
%}
// Store Short/Char Immediate
instruct storeImmC0(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreC mem zero));
ins_cost(125); // XXX
format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
ins_encode %{
--- 6051,6061 ----
%}
// Store Short/Char Immediate
instruct storeImmC0(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreC mem zero));
ins_cost(125); // XXX
format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
ins_encode %{
*** 5881,5891 ****
%}
// Store Byte Immediate
instruct storeImmB0(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreB mem zero));
ins_cost(125); // XXX
format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
ins_encode %{
--- 6077,6087 ----
%}
// Store Byte Immediate
instruct storeImmB0(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreB mem zero));
ins_cost(125); // XXX
format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
ins_encode %{
*** 5906,5916 ****
%}
// Store CMS card-mark Immediate
instruct storeImmCM0_reg(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreCM mem zero));
ins_cost(125); // XXX
format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
ins_encode %{
--- 6102,6112 ----
%}
// Store CMS card-mark Immediate
instruct storeImmCM0_reg(memory mem, immI0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreCM mem zero));
ins_cost(125); // XXX
format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
ins_encode %{
*** 5944,5954 ****
%}
// Store immediate Float value (it is faster than store from XMM register)
instruct storeF0(memory mem, immF0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreF mem zero));
ins_cost(25); // XXX
format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
ins_encode %{
--- 6140,6150 ----
%}
// Store immediate Float value (it is faster than store from XMM register)
instruct storeF0(memory mem, immF0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreF mem zero));
ins_cost(25); // XXX
format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
ins_encode %{
*** 5994,6004 ****
ins_pipe(ialu_mem_imm);
%}
instruct storeD0(memory mem, immD0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set mem (StoreD mem zero));
ins_cost(25); // XXX
format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
ins_encode %{
--- 6190,6200 ----
ins_pipe(ialu_mem_imm);
%}
instruct storeD0(memory mem, immD0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set mem (StoreD mem zero));
ins_cost(25); // XXX
format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
ins_encode %{
*** 6480,6489 ****
--- 6676,6711 ----
}
%}
ins_pipe(ialu_reg_long);
%}
+ instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
+ match(Set dst (EncodePKlass src));
+ effect(KILL cr);
+ format %{ "encode_heap_oop_not_null $dst,$src" %}
+ ins_encode %{
+ __ encode_klass_not_null($dst$$Register, $src$$Register);
+ %}
+ ins_pipe(ialu_reg_long);
+ %}
+
+ instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
+ match(Set dst (DecodeNKlass src));
+ effect(KILL cr);
+ format %{ "decode_heap_oop_not_null $dst,$src" %}
+ ins_encode %{
+ Register s = $src$$Register;
+ Register d = $dst$$Register;
+ if (s != d) {
+ __ decode_klass_not_null(d, s);
+ } else {
+ __ decode_klass_not_null(d);
+ }
+ %}
+ ins_pipe(ialu_reg_long);
+ %}
+
//----------Conditional Move---------------------------------------------------
// Jump
// dummy instruction for generating temp registers
instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
*** 10450,10460 ****
ins_pipe(ialu_cr_reg_imm);
%}
instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
match(Set cr (CmpP (LoadP mem) zero));
format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
ins_encode %{
__ cmpq(r12, $mem$$Address);
--- 10672,10682 ----
ins_pipe(ialu_cr_reg_imm);
%}
instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
%{
! predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
match(Set cr (CmpP (LoadP mem) zero));
format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
ins_encode %{
__ cmpq(r12, $mem$$Address);
*** 10501,10510 ****
--- 10723,10753 ----
__ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
%}
ins_pipe(ialu_cr_reg_mem);
%}
+ instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
+ match(Set cr (CmpN op1 op2));
+
+ format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
+ ins_encode %{
+ __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
+ %}
+ ins_pipe(ialu_cr_reg_imm);
+ %}
+
+ instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
+ %{
+ match(Set cr (CmpN src (LoadNKlass mem)));
+
+ format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
+ ins_encode %{
+ __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
+ %}
+ ins_pipe(ialu_cr_reg_mem);
+ %}
+
instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
match(Set cr (CmpN src zero));
format %{ "testl $src, $src\t# compressed ptr" %}
ins_encode %{ __ testl($src$$Register, $src$$Register); %}
*** 10524,10534 ****
ins_pipe(ialu_cr_reg_mem);
%}
instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
%{
! predicate(Universe::narrow_oop_base() == NULL);
match(Set cr (CmpN (LoadN mem) zero));
format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
ins_encode %{
__ cmpl(r12, $mem$$Address);
--- 10767,10777 ----
ins_pipe(ialu_cr_reg_mem);
%}
instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
%{
! predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL));
match(Set cr (CmpN (LoadN mem) zero));
format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
ins_encode %{
__ cmpl(r12, $mem$$Address);