Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/interp_masm_x86_32.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 1d7922586cf6 |
children | f34d701e952e |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
26 #include "interp_masm_x86_32.hpp" | 26 #include "interp_masm_x86_32.hpp" |
27 #include "interpreter/interpreter.hpp" | 27 #include "interpreter/interpreter.hpp" |
28 #include "interpreter/interpreterRuntime.hpp" | 28 #include "interpreter/interpreterRuntime.hpp" |
29 #include "oops/arrayOop.hpp" | 29 #include "oops/arrayOop.hpp" |
30 #include "oops/markOop.hpp" | 30 #include "oops/markOop.hpp" |
31 #include "oops/methodDataOop.hpp" | 31 #include "oops/methodData.hpp" |
32 #include "oops/methodOop.hpp" | 32 #include "oops/method.hpp" |
33 #include "prims/jvmtiExport.hpp" | 33 #include "prims/jvmtiExport.hpp" |
34 #include "prims/jvmtiRedefineClassesTrace.hpp" | 34 #include "prims/jvmtiRedefineClassesTrace.hpp" |
35 #include "prims/jvmtiThreadState.hpp" | 35 #include "prims/jvmtiThreadState.hpp" |
36 #include "runtime/basicLock.hpp" | 36 #include "runtime/basicLock.hpp" |
37 #include "runtime/biasedLocking.hpp" | 37 #include "runtime/biasedLocking.hpp" |
221 assert(EnableInvokeDynamic, "giant index used only for JSR 292"); | 221 assert(EnableInvokeDynamic, "giant index used only for JSR 292"); |
222 movl(reg, Address(rsi, bcp_offset)); | 222 movl(reg, Address(rsi, bcp_offset)); |
223 // Check if the secondary index definition is still ~x, otherwise | 223 // Check if the secondary index definition is still ~x, otherwise |
224 // we have to change the following assembler code to calculate the | 224 // we have to change the following assembler code to calculate the |
225 // plain index. | 225 // plain index. |
226 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line"); | 226 assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line"); |
227 notl(reg); // convert to plain index | 227 notl(reg); // convert to plain index |
228 } else if (index_size == sizeof(u1)) { | 228 } else if (index_size == sizeof(u1)) { |
229 assert(EnableInvokeDynamic, "tiny index used only for JSR 292"); | |
230 load_unsigned_byte(reg, Address(rsi, bcp_offset)); | 229 load_unsigned_byte(reg, Address(rsi, bcp_offset)); |
231 } else { | 230 } else { |
232 ShouldNotReachHere(); | 231 ShouldNotReachHere(); |
233 } | 232 } |
234 } | 233 } |
238 int bcp_offset, size_t index_size) { | 237 int bcp_offset, size_t index_size) { |
239 assert_different_registers(cache, index); | 238 assert_different_registers(cache, index); |
240 get_cache_index_at_bcp(index, bcp_offset, index_size); | 239 get_cache_index_at_bcp(index, bcp_offset, index_size); |
241 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); | 240 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
242 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); | 241 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
242 assert(exact_log2(in_words(ConstantPoolCacheEntry::size())) == 2, "else change next line"); | |
243 shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index | 243 shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index |
244 } | 244 } |
245 | 245 |
246 | 246 |
247 void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache, | 247 void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache, |
249 Register bytecode, | 249 Register bytecode, |
250 int byte_no, | 250 int byte_no, |
251 int bcp_offset, | 251 int bcp_offset, |
252 size_t index_size) { | 252 size_t index_size) { |
253 get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size); | 253 get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size); |
254 movptr(bytecode, Address(cache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); | 254 movptr(bytecode, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset())); |
255 const int shift_count = (1 + byte_no) * BitsPerByte; | 255 const int shift_count = (1 + byte_no) * BitsPerByte; |
256 assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) || | 256 assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) || |
257 (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift), | 257 (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift), |
258 "correct shift count"); | 258 "correct shift count"); |
259 shrptr(bytecode, shift_count); | 259 shrptr(bytecode, shift_count); |
267 assert(cache != tmp, "must use different register"); | 267 assert(cache != tmp, "must use different register"); |
268 get_cache_index_at_bcp(tmp, bcp_offset, index_size); | 268 get_cache_index_at_bcp(tmp, bcp_offset, index_size); |
269 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); | 269 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
270 // convert from field index to ConstantPoolCacheEntry index | 270 // convert from field index to ConstantPoolCacheEntry index |
271 // and from word offset to byte offset | 271 // and from word offset to byte offset |
272 assert(exact_log2(in_bytes(ConstantPoolCacheEntry::size_in_bytes())) == 2 + LogBytesPerWord, "else change next line"); | |
272 shll(tmp, 2 + LogBytesPerWord); | 273 shll(tmp, 2 + LogBytesPerWord); |
273 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); | 274 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
274 // skip past the header | 275 // skip past the header |
275 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); | 276 addptr(cache, in_bytes(ConstantPoolCache::base_offset())); |
276 addptr(cache, tmp); // construct pointer to cache entry | 277 addptr(cache, tmp); // construct pointer to cache entry |
277 } | 278 } |
278 | 279 |
280 // Load object from cpool->resolved_references(index) | |
281 void InterpreterMacroAssembler::load_resolved_reference_at_index( | |
282 Register result, Register index) { | |
283 assert_different_registers(result, index); | |
284 // convert from field index to resolved_references() index and from | |
285 // word index to byte offset. Since this is a java object, it can be compressed | |
286 Register tmp = index; // reuse | |
287 shll(tmp, LogBytesPerHeapOop); | |
288 | |
289 get_constant_pool(result); | |
290 // load pointer for resolved_references[] objArray | |
291 movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes())); | |
292 // JNIHandles::resolve(obj); | |
293 movptr(result, Address(result, 0)); | |
294 // Add in the index | |
295 addptr(result, tmp); | |
296 load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); | |
297 } | |
279 | 298 |
280 // Generate a subtype check: branch to ok_is_subtype if sub_klass is | 299 // Generate a subtype check: branch to ok_is_subtype if sub_klass is |
281 // a subtype of super_klass. EAX holds the super_klass. Blows ECX. | 300 // a subtype of super_klass. EAX holds the super_klass. Blows ECX. |
282 // Resets EDI to locals. Register sub_klass cannot be any of the above. | 301 // Resets EDI to locals. Register sub_klass cannot be any of the above. |
283 void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) { | 302 void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) { |
425 get_thread(temp); | 444 get_thread(temp); |
426 // interp_only is an int, on little endian it is sufficient to test the byte only | 445 // interp_only is an int, on little endian it is sufficient to test the byte only |
427 // Is a cmpl faster? | 446 // Is a cmpl faster? |
428 cmpb(Address(temp, JavaThread::interp_only_mode_offset()), 0); | 447 cmpb(Address(temp, JavaThread::interp_only_mode_offset()), 0); |
429 jccb(Assembler::zero, run_compiled_code); | 448 jccb(Assembler::zero, run_compiled_code); |
430 jmp(Address(method, methodOopDesc::interpreter_entry_offset())); | 449 jmp(Address(method, Method::interpreter_entry_offset())); |
431 bind(run_compiled_code); | 450 bind(run_compiled_code); |
432 } | 451 } |
433 | 452 |
434 jmp(Address(method, methodOopDesc::from_interpreted_offset())); | 453 jmp(Address(method, Method::from_interpreted_offset())); |
435 | 454 |
436 } | 455 } |
437 | 456 |
438 | 457 |
439 // The following two routines provide a hook so that an implementation | 458 // The following two routines provide a hook so that an implementation |
524 movbool(rbx, do_not_unlock_if_synchronized); | 543 movbool(rbx, do_not_unlock_if_synchronized); |
525 mov(rdi,rbx); | 544 mov(rdi,rbx); |
526 movbool(do_not_unlock_if_synchronized, false); // reset the flag | 545 movbool(do_not_unlock_if_synchronized, false); // reset the flag |
527 | 546 |
528 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags | 547 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags |
529 movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); | 548 movl(rcx, Address(rbx, Method::access_flags_offset())); |
530 | 549 |
531 testl(rcx, JVM_ACC_SYNCHRONIZED); | 550 testl(rcx, JVM_ACC_SYNCHRONIZED); |
532 jcc(Assembler::zero, unlocked); | 551 jcc(Assembler::zero, unlocked); |
533 | 552 |
534 // Don't unlock anything if the _do_not_unlock_if_synchronized flag | 553 // Don't unlock anything if the _do_not_unlock_if_synchronized flag |
818 push(rax); | 837 push(rax); |
819 push(rbx); | 838 push(rbx); |
820 | 839 |
821 get_method(rbx); | 840 get_method(rbx); |
822 // Test MDO to avoid the call if it is NULL. | 841 // Test MDO to avoid the call if it is NULL. |
823 movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); | 842 movptr(rax, Address(rbx, in_bytes(Method::method_data_offset()))); |
824 testptr(rax, rax); | 843 testptr(rax, rax); |
825 jcc(Assembler::zero, set_mdp); | 844 jcc(Assembler::zero, set_mdp); |
826 // rbx,: method | 845 // rbx,: method |
827 // rsi: bcp | 846 // rsi: bcp |
828 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi); | 847 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi); |
829 // rax,: mdi | 848 // rax,: mdi |
830 // mdo is guaranteed to be non-zero here, we checked for it before the call. | 849 // mdo is guaranteed to be non-zero here, we checked for it before the call. |
831 movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); | 850 movptr(rbx, Address(rbx, in_bytes(Method::method_data_offset()))); |
832 addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); | 851 addptr(rbx, in_bytes(MethodData::data_offset())); |
833 addptr(rax, rbx); | 852 addptr(rax, rbx); |
834 bind(set_mdp); | 853 bind(set_mdp); |
835 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); | 854 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); |
836 pop(rbx); | 855 pop(rbx); |
837 pop(rax); | 856 pop(rax); |
849 get_method(rbx); | 868 get_method(rbx); |
850 | 869 |
851 // If the mdp is valid, it will point to a DataLayout header which is | 870 // If the mdp is valid, it will point to a DataLayout header which is |
852 // consistent with the bcp. The converse is highly probable also. | 871 // consistent with the bcp. The converse is highly probable also. |
853 load_unsigned_short(rdx, Address(rcx, in_bytes(DataLayout::bci_offset()))); | 872 load_unsigned_short(rdx, Address(rcx, in_bytes(DataLayout::bci_offset()))); |
854 addptr(rdx, Address(rbx, methodOopDesc::const_offset())); | 873 addptr(rdx, Address(rbx, Method::const_offset())); |
855 lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); | 874 lea(rdx, Address(rdx, ConstMethod::codes_offset())); |
856 cmpptr(rdx, rsi); | 875 cmpptr(rdx, rsi); |
857 jcc(Assembler::equal, verify_continue); | 876 jcc(Assembler::equal, verify_continue); |
858 // rbx,: method | 877 // rbx,: method |
859 // rsi: bcp | 878 // rsi: bcp |
860 // rcx: mdp | 879 // rcx: mdp |