1849 //============================================================================= |
1849 //============================================================================= |
1850 #ifndef PRODUCT |
1850 #ifndef PRODUCT |
1851 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
1851 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
1852 { |
1852 { |
1853 if (UseCompressedOops) { |
1853 if (UseCompressedOops) { |
1854 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes()); |
1854 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); |
1855 if (Universe::narrow_oop_shift() != 0) { |
1855 if (Universe::narrow_oop_shift() != 0) { |
1856 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]"); |
1856 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); |
1857 } |
1857 } |
1858 st->print_cr("cmpq rax, rscratch1\t # Inline cache check"); |
1858 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); |
1859 } else { |
1859 } else { |
1860 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" |
1860 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" |
1861 "# Inline cache check", oopDesc::klass_offset_in_bytes()); |
1861 "# Inline cache check"); |
1862 } |
1862 } |
1863 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); |
1863 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); |
1864 st->print_cr("\tnop"); |
1864 st->print_cr("\tnop\t# nops to align entry point"); |
1865 if (!OptoBreakpoint) { |
|
1866 st->print_cr("\tnop"); |
|
1867 } |
|
1868 } |
1865 } |
1869 #endif |
1866 #endif |
1870 |
1867 |
1871 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const |
1868 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const |
1872 { |
1869 { |
1873 MacroAssembler masm(&cbuf); |
1870 MacroAssembler masm(&cbuf); |
1874 #ifdef ASSERT |
|
1875 uint code_size = cbuf.code_size(); |
1871 uint code_size = cbuf.code_size(); |
1876 #endif |
|
1877 if (UseCompressedOops) { |
1872 if (UseCompressedOops) { |
1878 masm.load_klass(rscratch1, j_rarg0); |
1873 masm.load_klass(rscratch1, j_rarg0); |
1879 masm.cmpptr(rax, rscratch1); |
1874 masm.cmpptr(rax, rscratch1); |
1880 } else { |
1875 } else { |
1881 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); |
1876 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); |
1882 } |
1877 } |
1883 |
1878 |
1884 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
1879 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
1885 |
1880 |
1886 /* WARNING these NOPs are critical so that verified entry point is properly |
1881 /* WARNING these NOPs are critical so that verified entry point is properly |
1887 aligned for patching by NativeJump::patch_verified_entry() */ |
1882 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ |
1888 int nops_cnt = 1; |
1883 int nops_cnt = 4 - ((cbuf.code_size() - code_size) & 0x3); |
1889 if (!OptoBreakpoint) { |
1884 if (OptoBreakpoint) { |
1890 // Leave space for int3 |
1885 // Leave space for int3 |
1891 nops_cnt += 1; |
1886 nops_cnt -= 1; |
1892 } |
1887 } |
1893 if (UseCompressedOops) { |
1888 nops_cnt &= 0x3; // Do not add nops if code is aligned. |
1894 // ??? divisible by 4 is aligned? |
1889 if (nops_cnt > 0) |
1895 nops_cnt += 1; |
1890 masm.nop(nops_cnt); |
1896 } |
|
1897 masm.nop(nops_cnt); |
|
1898 |
|
1899 assert(cbuf.code_size() - code_size == size(ra_), |
|
1900 "checking code size of inline cache node"); |
|
1901 } |
1891 } |
1902 |
1892 |
1903 uint MachUEPNode::size(PhaseRegAlloc* ra_) const |
1893 uint MachUEPNode::size(PhaseRegAlloc* ra_) const |
1904 { |
1894 { |
1905 if (UseCompressedOops) { |
1895 return MachNode::size(ra_); // too many variables; just compute it |
1906 if (Universe::narrow_oop_shift() == 0) { |
1896 // the hard way |
1907 return OptoBreakpoint ? 15 : 16; |
|
1908 } else { |
|
1909 return OptoBreakpoint ? 19 : 20; |
|
1910 } |
|
1911 } else { |
|
1912 return OptoBreakpoint ? 11 : 12; |
|
1913 } |
|
1914 } |
1897 } |
1915 |
1898 |
1916 |
1899 |
1917 //============================================================================= |
1900 //============================================================================= |
1918 uint size_exception_handler() |
1901 uint size_exception_handler() |
5125 |
5108 |
5126 // Indirect Narrow Oop Plus Offset Operand |
5109 // Indirect Narrow Oop Plus Offset Operand |
5127 // Note: x86 architecture doesn't support "scale * index + offset" without a base |
5110 // Note: x86 architecture doesn't support "scale * index + offset" without a base |
5128 // we can't free r12 even with Universe::narrow_oop_base() == NULL. |
5111 // we can't free r12 even with Universe::narrow_oop_base() == NULL. |
5129 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ |
5112 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ |
5130 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); |
5113 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); |
5131 constraint(ALLOC_IN_RC(ptr_reg)); |
5114 constraint(ALLOC_IN_RC(ptr_reg)); |
5132 match(AddP (DecodeN reg) off); |
5115 match(AddP (DecodeN reg) off); |
5133 |
5116 |
5134 op_cost(10); |
5117 op_cost(10); |
5135 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} |
5118 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} |
7740 __ decode_heap_oop(d); |
7723 __ decode_heap_oop(d); |
7741 %} |
7724 %} |
7742 ins_pipe(ialu_reg_long); |
7725 ins_pipe(ialu_reg_long); |
7743 %} |
7726 %} |
7744 |
7727 |
7745 instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{ |
7728 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ |
7746 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || |
7729 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || |
7747 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); |
7730 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); |
7748 match(Set dst (DecodeN src)); |
7731 match(Set dst (DecodeN src)); |
|
7732 effect(KILL cr); |
7749 format %{ "decode_heap_oop_not_null $dst,$src" %} |
7733 format %{ "decode_heap_oop_not_null $dst,$src" %} |
7750 ins_encode %{ |
7734 ins_encode %{ |
7751 Register s = $src$$Register; |
7735 Register s = $src$$Register; |
7752 Register d = $dst$$Register; |
7736 Register d = $dst$$Register; |
7753 if (s != d) { |
7737 if (s != d) { |