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);