Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/assembler_x86.cpp @ 6848:8e47bac5643a
7054512: Compress class pointers after perm gen removal
Summary: support of compress class pointers in the compilers.
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 09 Oct 2012 10:11:38 +0200 |
parents | 137868b7aa6f |
children | d804e148cff8 |
comparison
equal
deleted
inserted
replaced
6847:65d07d9ee446 | 6848:8e47bac5643a |
---|---|
6934 assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); | 6934 assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); |
6935 LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); | 6935 LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); |
6936 #ifdef ASSERT | 6936 #ifdef ASSERT |
6937 // TraceBytecodes does not use r12 but saves it over the call, so don't verify | 6937 // TraceBytecodes does not use r12 but saves it over the call, so don't verify |
6938 // r12 is the heapbase. | 6938 // r12 is the heapbase. |
6939 LP64_ONLY(if (UseCompressedOops && !TraceBytecodes) verify_heapbase("call_VM_base");) | 6939 LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) |
6940 #endif // ASSERT | 6940 #endif // ASSERT |
6941 | 6941 |
6942 assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); | 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"); | 6943 assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); |
6944 | 6944 |
10034 | 10034 |
10035 void MacroAssembler::load_klass(Register dst, Register src) { | 10035 void MacroAssembler::load_klass(Register dst, Register src) { |
10036 #ifdef _LP64 | 10036 #ifdef _LP64 |
10037 if (UseCompressedKlassPointers) { | 10037 if (UseCompressedKlassPointers) { |
10038 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 10038 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
10039 decode_heap_oop_not_null(dst); | 10039 decode_klass_not_null(dst); |
10040 } else | 10040 } else |
10041 #endif | 10041 #endif |
10042 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 10042 movptr(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
10043 } | 10043 } |
10044 | 10044 |
10045 void MacroAssembler::load_prototype_header(Register dst, Register src) { | 10045 void MacroAssembler::load_prototype_header(Register dst, Register src) { |
10046 #ifdef _LP64 | 10046 #ifdef _LP64 |
10047 if (UseCompressedKlassPointers) { | 10047 if (UseCompressedKlassPointers) { |
10048 assert (Universe::heap() != NULL, "java heap should be initialized"); | 10048 assert (Universe::heap() != NULL, "java heap should be initialized"); |
10049 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); | 10049 movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); |
10050 if (Universe::narrow_oop_shift() != 0) { | 10050 if (Universe::narrow_klass_shift() != 0) { |
10051 assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong"); | 10051 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong"); |
10052 if (LogMinObjAlignmentInBytes == Address::times_8) { | 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())); | 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 { | 10054 } else { |
10060 movq(dst, Address(dst, Klass::prototype_header_offset())); | 10055 movq(dst, Address(dst, Klass::prototype_header_offset())); |
10061 } | 10056 } |
10062 } else | 10057 } else |
10063 #endif | 10058 #endif |
10068 } | 10063 } |
10069 | 10064 |
10070 void MacroAssembler::store_klass(Register dst, Register src) { | 10065 void MacroAssembler::store_klass(Register dst, Register src) { |
10071 #ifdef _LP64 | 10066 #ifdef _LP64 |
10072 if (UseCompressedKlassPointers) { | 10067 if (UseCompressedKlassPointers) { |
10073 encode_heap_oop_not_null(src); | 10068 encode_klass_not_null(src); |
10074 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); | 10069 movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); |
10075 } else | 10070 } else |
10076 #endif | 10071 #endif |
10077 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); | 10072 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); |
10078 } | 10073 } |
10150 } | 10145 } |
10151 } | 10146 } |
10152 | 10147 |
10153 #ifdef ASSERT | 10148 #ifdef ASSERT |
10154 void MacroAssembler::verify_heapbase(const char* msg) { | 10149 void MacroAssembler::verify_heapbase(const char* msg) { |
10155 assert (UseCompressedOops, "should be compressed"); | 10150 assert (UseCompressedOops || UseCompressedKlassPointers, "should be compressed"); |
10156 assert (Universe::heap() != NULL, "java heap should be initialized"); | 10151 assert (Universe::heap() != NULL, "java heap should be initialized"); |
10157 if (CheckCompressedOops) { | 10152 if (CheckCompressedOops) { |
10158 Label ok; | 10153 Label ok; |
10159 push(rscratch1); // cmpptr trashes rscratch1 | 10154 push(rscratch1); // cmpptr trashes rscratch1 |
10160 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); | 10155 cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr())); |
10161 jcc(Assembler::equal, ok); | 10156 jcc(Assembler::equal, ok); |
10162 STOP(msg); | 10157 STOP(msg); |
10163 bind(ok); | 10158 bind(ok); |
10164 pop(rscratch1); | 10159 pop(rscratch1); |
10165 } | 10160 } |
10293 movq(dst, src); | 10288 movq(dst, src); |
10294 } | 10289 } |
10295 } | 10290 } |
10296 } | 10291 } |
10297 | 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 | |
10298 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { | 10361 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { |
10299 assert (UseCompressedOops, "should only be used for compressed headers"); | 10362 assert (UseCompressedOops, "should only be used for compressed headers"); |
10300 assert (Universe::heap() != NULL, "java heap should be initialized"); | 10363 assert (Universe::heap() != NULL, "java heap should be initialized"); |
10301 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 10364 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
10302 int oop_index = oop_recorder()->find_index(obj); | 10365 int oop_index = oop_recorder()->find_index(obj); |
10311 int oop_index = oop_recorder()->find_index(obj); | 10374 int oop_index = oop_recorder()->find_index(obj); |
10312 RelocationHolder rspec = oop_Relocation::spec(oop_index); | 10375 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
10313 mov_narrow_oop(dst, oop_index, rspec); | 10376 mov_narrow_oop(dst, oop_index, rspec); |
10314 } | 10377 } |
10315 | 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 | |
10316 void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) { | 10395 void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) { |
10317 assert (UseCompressedOops, "should only be used for compressed headers"); | 10396 assert (UseCompressedOops, "should only be used for compressed headers"); |
10318 assert (Universe::heap() != NULL, "java heap should be initialized"); | 10397 assert (Universe::heap() != NULL, "java heap should be initialized"); |
10319 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 10398 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
10320 int oop_index = oop_recorder()->find_index(obj); | 10399 int oop_index = oop_recorder()->find_index(obj); |
10329 int oop_index = oop_recorder()->find_index(obj); | 10408 int oop_index = oop_recorder()->find_index(obj); |
10330 RelocationHolder rspec = oop_Relocation::spec(oop_index); | 10409 RelocationHolder rspec = oop_Relocation::spec(oop_index); |
10331 Assembler::cmp_narrow_oop(dst, oop_index, rspec); | 10410 Assembler::cmp_narrow_oop(dst, oop_index, rspec); |
10332 } | 10411 } |
10333 | 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 | |
10334 void MacroAssembler::reinit_heapbase() { | 10429 void MacroAssembler::reinit_heapbase() { |
10335 if (UseCompressedOops) { | 10430 if (UseCompressedOops || UseCompressedKlassPointers) { |
10336 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); | 10431 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr())); |
10337 } | 10432 } |
10338 } | 10433 } |
10339 #endif // _LP64 | 10434 #endif // _LP64 |
10340 | 10435 |
10341 | 10436 |