src/cpu/x86/vm/assembler_x86.cpp

Print this page
rev 3688 : 7054512: Compress class pointers after perm gen removal
Summary: support of compress class pointers in the compilers.
Reviewed-by:


6919                                   bool     check_exceptions) {
6920   // determine java_thread register
6921   if (!java_thread->is_valid()) {
6922 #ifdef _LP64
6923     java_thread = r15_thread;
6924 #else
6925     java_thread = rdi;
6926     get_thread(java_thread);
6927 #endif // LP64
6928   }
6929   // determine last_java_sp register
6930   if (!last_java_sp->is_valid()) {
6931     last_java_sp = rsp;
6932   }
6933   // debugging support
6934   assert(number_of_arguments >= 0   , "cannot have negative number of arguments");
6935   LP64_ONLY(assert(java_thread == r15_thread, "unexpected register"));
6936 #ifdef ASSERT
6937   // TraceBytecodes does not use r12 but saves it over the call, so don't verify
6938   // r12 is the heapbase.
6939   LP64_ONLY(if (UseCompressedOops && !TraceBytecodes) verify_heapbase("call_VM_base");)
6940 #endif // ASSERT
6941 
6942   assert(java_thread != oop_result  , "cannot use the same register for java_thread & oop_result");
6943   assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp");
6944 
6945   // push java thread (becomes first argument of C function)
6946 
6947   NOT_LP64(push(java_thread); number_of_arguments++);
6948   LP64_ONLY(mov(c_rarg0, r15_thread));
6949 
6950   // set last Java frame before call
6951   assert(last_java_sp != rbp, "can't use ebp/rbp");
6952 
6953   // Only interpreter should have to set fp
6954   set_last_Java_frame(java_thread, last_java_sp, rbp, NULL);
6955 
6956   // do the call, remove parameters
6957   MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments);
6958 
6959   // restore the thread (cannot use the pushed argument since arguments


10019   ExternalAddress msg((address) s);
10020   // pass message string s
10021   pushptr(msg.addr());
10022   push(stack_depth);        // pass stack depth
10023   call(RuntimeAddress(CAST_FROM_FN_PTR(address, _verify_FPU)));
10024   addptr(rsp, 3 * wordSize);   // discard arguments
10025   // check for error
10026   { Label L;
10027     testl(rax, rax);
10028     jcc(Assembler::notZero, L);
10029     int3();                  // break if error condition
10030     bind(L);
10031   }
10032   pop_CPU_state();
10033 }
10034 
10035 void MacroAssembler::load_klass(Register dst, Register src) {
10036 #ifdef _LP64
10037   if (UseCompressedKlassPointers) {
10038     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10039     decode_heap_oop_not_null(dst);
10040   } else
10041 #endif
10042     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10043 }
10044 
10045 void MacroAssembler::load_prototype_header(Register dst, Register src) {
10046 #ifdef _LP64
10047   if (UseCompressedKlassPointers) {
10048     assert (Universe::heap() != NULL, "java heap should be initialized");
10049     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10050     if (Universe::narrow_oop_shift() != 0) {
10051       assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
10052       if (LogMinObjAlignmentInBytes == Address::times_8) {
10053         movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset()));
10054       } else {
10055         // OK to use shift since we don't need to preserve flags.
10056         shlq(dst, LogMinObjAlignmentInBytes);
10057         movq(dst, Address(r12_heapbase, dst, Address::times_1, Klass::prototype_header_offset()));
10058       }
10059     } else {
10060       movq(dst, Address(dst, Klass::prototype_header_offset()));
10061     }
10062   } else
10063 #endif
10064   {
10065     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10066     movptr(dst, Address(dst, Klass::prototype_header_offset()));
10067   }
10068 }
10069 
10070 void MacroAssembler::store_klass(Register dst, Register src) {
10071 #ifdef _LP64
10072   if (UseCompressedKlassPointers) {
10073     encode_heap_oop_not_null(src);
10074     movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
10075   } else
10076 #endif
10077     movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src);
10078 }
10079 
10080 void MacroAssembler::load_heap_oop(Register dst, Address src) {
10081 #ifdef _LP64
10082   // FIXME: Must change all places where we try to load the klass.
10083   if (UseCompressedOops) {
10084     movl(dst, src);
10085     decode_heap_oop(dst);
10086   } else
10087 #endif
10088     movptr(dst, src);
10089 }
10090 
10091 // Doesn't do verfication, generates fixed size code
10092 void MacroAssembler::load_heap_oop_not_null(Register dst, Address src) {
10093 #ifdef _LP64


10135   if (UseCompressedOops) {
10136     movl(dst, (int32_t)NULL_WORD);
10137   } else {
10138     movslq(dst, (int32_t)NULL_WORD);
10139   }
10140 #else
10141   movl(dst, (int32_t)NULL_WORD);
10142 #endif
10143 }
10144 
10145 #ifdef _LP64
10146 void MacroAssembler::store_klass_gap(Register dst, Register src) {
10147   if (UseCompressedKlassPointers) {
10148     // Store to klass gap in destination
10149     movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
10150   }
10151 }
10152 
10153 #ifdef ASSERT
10154 void MacroAssembler::verify_heapbase(const char* msg) {
10155   assert (UseCompressedOops, "should be compressed");
10156   assert (Universe::heap() != NULL, "java heap should be initialized");
10157   if (CheckCompressedOops) {
10158     Label ok;
10159     push(rscratch1); // cmpptr trashes rscratch1
10160     cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
10161     jcc(Assembler::equal, ok);
10162     STOP(msg);
10163     bind(ok);
10164     pop(rscratch1);
10165   }
10166 }
10167 #endif
10168 
10169 // Algorithm must match oop.inline.hpp encode_heap_oop.
10170 void MacroAssembler::encode_heap_oop(Register r) {
10171 #ifdef ASSERT
10172   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
10173 #endif
10174   verify_oop(r, "broken oop in encode_heap_oop");
10175   if (Universe::narrow_oop_base() == NULL) {
10176     if (Universe::narrow_oop_shift() != 0) {
10177       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
10178       shrq(r, LogMinObjAlignmentInBytes);
10179     }
10180     return;


10278     assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
10279     if (LogMinObjAlignmentInBytes == Address::times_8) {
10280       leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
10281     } else {
10282       if (dst != src) {
10283         movq(dst, src);
10284       }
10285       shlq(dst, LogMinObjAlignmentInBytes);
10286       if (Universe::narrow_oop_base() != NULL) {
10287         addq(dst, r12_heapbase);
10288       }
10289     }
10290   } else {
10291     assert (Universe::narrow_oop_base() == NULL, "sanity");
10292     if (dst != src) {
10293       movq(dst, src);
10294     }
10295   }
10296 }
10297 




































































10298 void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
10299   assert (UseCompressedOops, "should only be used for compressed headers");
10300   assert (Universe::heap() != NULL, "java heap should be initialized");
10301   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10302   int oop_index = oop_recorder()->find_index(obj);
10303   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10304   mov_narrow_oop(dst, oop_index, rspec);
10305 }
10306 
10307 void  MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
10308   assert (UseCompressedOops, "should only be used for compressed headers");
10309   assert (Universe::heap() != NULL, "java heap should be initialized");
10310   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10311   int oop_index = oop_recorder()->find_index(obj);
10312   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10313   mov_narrow_oop(dst, oop_index, rspec);
10314 }
10315 
















10316 void  MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) {
10317   assert (UseCompressedOops, "should only be used for compressed headers");
10318   assert (Universe::heap() != NULL, "java heap should be initialized");
10319   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10320   int oop_index = oop_recorder()->find_index(obj);
10321   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10322   Assembler::cmp_narrow_oop(dst, oop_index, rspec);
10323 }
10324 
10325 void  MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) {
10326   assert (UseCompressedOops, "should only be used for compressed headers");
10327   assert (Universe::heap() != NULL, "java heap should be initialized");
10328   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10329   int oop_index = oop_recorder()->find_index(obj);
10330   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10331   Assembler::cmp_narrow_oop(dst, oop_index, rspec);
10332 }
10333 
















10334 void MacroAssembler::reinit_heapbase() {
10335   if (UseCompressedOops) {
10336     movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
10337   }
10338 }
10339 #endif // _LP64
10340 
10341 
10342 // C2 compiled method's prolog code.
10343 void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) {
10344 
10345   // WARNING: Initial instruction MUST be 5 bytes or longer so that
10346   // NativeJump::patch_verified_entry will be able to patch out the entry
10347   // code safely. The push to verify stack depth is ok at 5 bytes,
10348   // the frame allocation can be either 3 or 6 bytes. So if we don't do
10349   // stack bang then we must use the 6 byte frame allocation even if
10350   // we have no frame. :-(
10351 
10352   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
10353   // Remove word for return addr
10354   framesize -= wordSize;
10355 
10356   // Calls to C2R adapters often do not accept exceptional returns.




6919                                   bool     check_exceptions) {
6920   // determine java_thread register
6921   if (!java_thread->is_valid()) {
6922 #ifdef _LP64
6923     java_thread = r15_thread;
6924 #else
6925     java_thread = rdi;
6926     get_thread(java_thread);
6927 #endif // LP64
6928   }
6929   // determine last_java_sp register
6930   if (!last_java_sp->is_valid()) {
6931     last_java_sp = rsp;
6932   }
6933   // debugging support
6934   assert(number_of_arguments >= 0   , "cannot have negative number of arguments");
6935   LP64_ONLY(assert(java_thread == r15_thread, "unexpected register"));
6936 #ifdef ASSERT
6937   // TraceBytecodes does not use r12 but saves it over the call, so don't verify
6938   // r12 is the heapbase.
6939   LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
6940 #endif // ASSERT
6941 
6942   assert(java_thread != oop_result  , "cannot use the same register for java_thread & oop_result");
6943   assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp");
6944 
6945   // push java thread (becomes first argument of C function)
6946 
6947   NOT_LP64(push(java_thread); number_of_arguments++);
6948   LP64_ONLY(mov(c_rarg0, r15_thread));
6949 
6950   // set last Java frame before call
6951   assert(last_java_sp != rbp, "can't use ebp/rbp");
6952 
6953   // Only interpreter should have to set fp
6954   set_last_Java_frame(java_thread, last_java_sp, rbp, NULL);
6955 
6956   // do the call, remove parameters
6957   MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments);
6958 
6959   // restore the thread (cannot use the pushed argument since arguments


10019   ExternalAddress msg((address) s);
10020   // pass message string s
10021   pushptr(msg.addr());
10022   push(stack_depth);        // pass stack depth
10023   call(RuntimeAddress(CAST_FROM_FN_PTR(address, _verify_FPU)));
10024   addptr(rsp, 3 * wordSize);   // discard arguments
10025   // check for error
10026   { Label L;
10027     testl(rax, rax);
10028     jcc(Assembler::notZero, L);
10029     int3();                  // break if error condition
10030     bind(L);
10031   }
10032   pop_CPU_state();
10033 }
10034 
10035 void MacroAssembler::load_klass(Register dst, Register src) {
10036 #ifdef _LP64
10037   if (UseCompressedKlassPointers) {
10038     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10039     decode_klass_not_null(dst);
10040   } else
10041 #endif
10042     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10043 }
10044 
10045 void MacroAssembler::load_prototype_header(Register dst, Register src) {
10046 #ifdef _LP64
10047   if (UseCompressedKlassPointers) {
10048     assert (Universe::heap() != NULL, "java heap should be initialized");
10049     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10050     if (Universe::narrow_klass_shift() != 0) {
10051       assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
10052       assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
10053       movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset()));
10054     } else {





10055       movq(dst, Address(dst, Klass::prototype_header_offset()));
10056     }
10057   } else
10058 #endif
10059   {
10060     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
10061     movptr(dst, Address(dst, Klass::prototype_header_offset()));
10062   }
10063 }
10064 
10065 void MacroAssembler::store_klass(Register dst, Register src) {
10066 #ifdef _LP64
10067   if (UseCompressedKlassPointers) {
10068     encode_klass_not_null(src);
10069     movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
10070   } else
10071 #endif
10072     movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src);
10073 }
10074 
10075 void MacroAssembler::load_heap_oop(Register dst, Address src) {
10076 #ifdef _LP64
10077   // FIXME: Must change all places where we try to load the klass.
10078   if (UseCompressedOops) {
10079     movl(dst, src);
10080     decode_heap_oop(dst);
10081   } else
10082 #endif
10083     movptr(dst, src);
10084 }
10085 
10086 // Doesn't do verfication, generates fixed size code
10087 void MacroAssembler::load_heap_oop_not_null(Register dst, Address src) {
10088 #ifdef _LP64


10130   if (UseCompressedOops) {
10131     movl(dst, (int32_t)NULL_WORD);
10132   } else {
10133     movslq(dst, (int32_t)NULL_WORD);
10134   }
10135 #else
10136   movl(dst, (int32_t)NULL_WORD);
10137 #endif
10138 }
10139 
10140 #ifdef _LP64
10141 void MacroAssembler::store_klass_gap(Register dst, Register src) {
10142   if (UseCompressedKlassPointers) {
10143     // Store to klass gap in destination
10144     movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
10145   }
10146 }
10147 
10148 #ifdef ASSERT
10149 void MacroAssembler::verify_heapbase(const char* msg) {
10150   assert (UseCompressedOops || UseCompressedKlassPointers, "should be compressed");
10151   assert (Universe::heap() != NULL, "java heap should be initialized");
10152   if (CheckCompressedOops) {
10153     Label ok;
10154     push(rscratch1); // cmpptr trashes rscratch1
10155     cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
10156     jcc(Assembler::equal, ok);
10157     STOP(msg);
10158     bind(ok);
10159     pop(rscratch1);
10160   }
10161 }
10162 #endif
10163 
10164 // Algorithm must match oop.inline.hpp encode_heap_oop.
10165 void MacroAssembler::encode_heap_oop(Register r) {
10166 #ifdef ASSERT
10167   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
10168 #endif
10169   verify_oop(r, "broken oop in encode_heap_oop");
10170   if (Universe::narrow_oop_base() == NULL) {
10171     if (Universe::narrow_oop_shift() != 0) {
10172       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
10173       shrq(r, LogMinObjAlignmentInBytes);
10174     }
10175     return;


10273     assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
10274     if (LogMinObjAlignmentInBytes == Address::times_8) {
10275       leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
10276     } else {
10277       if (dst != src) {
10278         movq(dst, src);
10279       }
10280       shlq(dst, LogMinObjAlignmentInBytes);
10281       if (Universe::narrow_oop_base() != NULL) {
10282         addq(dst, r12_heapbase);
10283       }
10284     }
10285   } else {
10286     assert (Universe::narrow_oop_base() == NULL, "sanity");
10287     if (dst != src) {
10288       movq(dst, src);
10289     }
10290   }
10291 }
10292 
10293 void MacroAssembler::encode_klass_not_null(Register r) {
10294   assert(Metaspace::is_initialized(), "metaspace should be initialized");
10295 #ifdef ASSERT
10296   verify_heapbase("MacroAssembler::encode_klass_not_null: heap base corrupted?");
10297 #endif
10298   if (Universe::narrow_klass_base() != NULL) {
10299     subq(r, r12_heapbase);
10300   }
10301   if (Universe::narrow_klass_shift() != 0) {
10302     assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
10303     shrq(r, LogKlassAlignmentInBytes);
10304   }
10305 }
10306 
10307 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
10308   assert(Metaspace::is_initialized(), "metaspace should be initialized");
10309 #ifdef ASSERT
10310   verify_heapbase("MacroAssembler::encode_klass_not_null2: heap base corrupted?");
10311 #endif
10312   if (dst != src) {
10313     movq(dst, src);
10314   }
10315   if (Universe::narrow_klass_base() != NULL) {
10316     subq(dst, r12_heapbase);
10317   }
10318   if (Universe::narrow_klass_shift() != 0) {
10319     assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
10320     shrq(dst, LogKlassAlignmentInBytes);
10321   }
10322 }
10323 
10324 void  MacroAssembler::decode_klass_not_null(Register r) {
10325   assert(Metaspace::is_initialized(), "metaspace should be initialized");
10326   // Note: it will change flags
10327   assert (UseCompressedKlassPointers, "should only be used for compressed headers");
10328   // Cannot assert, unverified entry point counts instructions (see .ad file)
10329   // vtableStubs also counts instructions in pd_code_size_limit.
10330   // Also do not verify_oop as this is called by verify_oop.
10331   if (Universe::narrow_klass_shift() != 0) {
10332     assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
10333     shlq(r, LogKlassAlignmentInBytes);
10334     if (Universe::narrow_klass_base() != NULL) {
10335       addq(r, r12_heapbase);
10336     }
10337   } else {
10338     assert (Universe::narrow_klass_base() == NULL, "sanity");
10339   }
10340 }
10341 
10342 void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
10343   assert(Metaspace::is_initialized(), "metaspace should be initialized");
10344   // Note: it will change flags
10345   assert (UseCompressedKlassPointers, "should only be used for compressed headers");
10346   // Cannot assert, unverified entry point counts instructions (see .ad file)
10347   // vtableStubs also counts instructions in pd_code_size_limit.
10348   // Also do not verify_oop as this is called by verify_oop.
10349   if (Universe::narrow_klass_shift() != 0) {
10350     assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
10351     assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
10352     leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
10353   } else {
10354     assert (Universe::narrow_klass_base() == NULL, "sanity");
10355     if (dst != src) {
10356       movq(dst, src);
10357     }
10358   }
10359 }
10360 
10361 void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
10362   assert (UseCompressedOops, "should only be used for compressed headers");
10363   assert (Universe::heap() != NULL, "java heap should be initialized");
10364   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10365   int oop_index = oop_recorder()->find_index(obj);
10366   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10367   mov_narrow_oop(dst, oop_index, rspec);
10368 }
10369 
10370 void  MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
10371   assert (UseCompressedOops, "should only be used for compressed headers");
10372   assert (Universe::heap() != NULL, "java heap should be initialized");
10373   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10374   int oop_index = oop_recorder()->find_index(obj);
10375   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10376   mov_narrow_oop(dst, oop_index, rspec);
10377 }
10378 
10379 void  MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
10380   assert (UseCompressedKlassPointers, "should only be used for compressed headers");
10381   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10382   int klass_index = oop_recorder()->find_index(k);
10383   RelocationHolder rspec = metadata_Relocation::spec(klass_index);
10384   mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
10385 }
10386 
10387 void  MacroAssembler::set_narrow_klass(Address dst, Klass* k) {
10388   assert (UseCompressedKlassPointers, "should only be used for compressed headers");
10389   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10390   int klass_index = oop_recorder()->find_index(k);
10391   RelocationHolder rspec = metadata_Relocation::spec(klass_index);
10392   mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
10393 }
10394 
10395 void  MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) {
10396   assert (UseCompressedOops, "should only be used for compressed headers");
10397   assert (Universe::heap() != NULL, "java heap should be initialized");
10398   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10399   int oop_index = oop_recorder()->find_index(obj);
10400   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10401   Assembler::cmp_narrow_oop(dst, oop_index, rspec);
10402 }
10403 
10404 void  MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) {
10405   assert (UseCompressedOops, "should only be used for compressed headers");
10406   assert (Universe::heap() != NULL, "java heap should be initialized");
10407   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10408   int oop_index = oop_recorder()->find_index(obj);
10409   RelocationHolder rspec = oop_Relocation::spec(oop_index);
10410   Assembler::cmp_narrow_oop(dst, oop_index, rspec);
10411 }
10412 
10413 void  MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) {
10414   assert (UseCompressedKlassPointers, "should only be used for compressed headers");
10415   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10416   int klass_index = oop_recorder()->find_index(k);
10417   RelocationHolder rspec = metadata_Relocation::spec(klass_index);
10418   Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
10419 }
10420 
10421 void  MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
10422   assert (UseCompressedKlassPointers, "should only be used for compressed headers");
10423   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
10424   int klass_index = oop_recorder()->find_index(k);
10425   RelocationHolder rspec = metadata_Relocation::spec(klass_index);
10426   Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
10427 }
10428 
10429 void MacroAssembler::reinit_heapbase() {
10430   if (UseCompressedOops || UseCompressedKlassPointers) {
10431     movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
10432   }
10433 }
10434 #endif // _LP64
10435 
10436 
10437 // C2 compiled method's prolog code.
10438 void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) {
10439 
10440   // WARNING: Initial instruction MUST be 5 bytes or longer so that
10441   // NativeJump::patch_verified_entry will be able to patch out the entry
10442   // code safely. The push to verify stack depth is ok at 5 bytes,
10443   // the frame allocation can be either 3 or 6 bytes. So if we don't do
10444   // stack bang then we must use the 6 byte frame allocation even if
10445   // we have no frame. :-(
10446 
10447   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
10448   // Remove word for return addr
10449   framesize -= wordSize;
10450 
10451   // Calls to C2R adapters often do not accept exceptional returns.