Mercurial > hg > truffle
comparison src/cpu/x86/vm/interp_masm_x86_64.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 | e522a00b91aa f34d701e952e |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 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_64.hpp" | 26 #include "interp_masm_x86_64.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" |
219 assert(EnableInvokeDynamic, "giant index used only for JSR 292"); | 219 assert(EnableInvokeDynamic, "giant index used only for JSR 292"); |
220 movl(index, Address(r13, bcp_offset)); | 220 movl(index, Address(r13, bcp_offset)); |
221 // Check if the secondary index definition is still ~x, otherwise | 221 // Check if the secondary index definition is still ~x, otherwise |
222 // we have to change the following assembler code to calculate the | 222 // we have to change the following assembler code to calculate the |
223 // plain index. | 223 // plain index. |
224 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line"); | 224 assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line"); |
225 notl(index); // convert to plain index | 225 notl(index); // convert to plain index |
226 } else if (index_size == sizeof(u1)) { | 226 } else if (index_size == sizeof(u1)) { |
227 assert(EnableInvokeDynamic, "tiny index used only for JSR 292"); | |
228 load_unsigned_byte(index, Address(r13, bcp_offset)); | 227 load_unsigned_byte(index, Address(r13, bcp_offset)); |
229 } else { | 228 } else { |
230 ShouldNotReachHere(); | 229 ShouldNotReachHere(); |
231 } | 230 } |
232 } | 231 } |
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"); |
243 // convert from field index to ConstantPoolCacheEntry index | 242 // convert from field index to ConstantPoolCacheEntry index |
243 assert(exact_log2(in_words(ConstantPoolCacheEntry::size())) == 2, "else change next line"); | |
244 shll(index, 2); | 244 shll(index, 2); |
245 } | 245 } |
246 | 246 |
247 | 247 |
248 void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache, | 248 void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache, |
252 int bcp_offset, | 252 int bcp_offset, |
253 size_t index_size) { | 253 size_t index_size) { |
254 get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size); | 254 get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size); |
255 // We use a 32-bit load here since the layout of 64-bit words on | 255 // We use a 32-bit load here since the layout of 64-bit words on |
256 // little-endian machines allow us that. | 256 // little-endian machines allow us that. |
257 movl(bytecode, Address(cache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); | 257 movl(bytecode, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset())); |
258 const int shift_count = (1 + byte_no) * BitsPerByte; | 258 const int shift_count = (1 + byte_no) * BitsPerByte; |
259 assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) || | 259 assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) || |
260 (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift), | 260 (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift), |
261 "correct shift count"); | 261 "correct shift count"); |
262 shrl(bytecode, shift_count); | 262 shrl(bytecode, shift_count); |
272 assert(cache != tmp, "must use different register"); | 272 assert(cache != tmp, "must use different register"); |
273 get_cache_index_at_bcp(tmp, bcp_offset, index_size); | 273 get_cache_index_at_bcp(tmp, bcp_offset, index_size); |
274 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); | 274 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); |
275 // convert from field index to ConstantPoolCacheEntry index | 275 // convert from field index to ConstantPoolCacheEntry index |
276 // and from word offset to byte offset | 276 // and from word offset to byte offset |
277 assert(exact_log2(in_bytes(ConstantPoolCacheEntry::size_in_bytes())) == 2 + LogBytesPerWord, "else change next line"); | |
277 shll(tmp, 2 + LogBytesPerWord); | 278 shll(tmp, 2 + LogBytesPerWord); |
278 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); | 279 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
279 // skip past the header | 280 // skip past the header |
280 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); | 281 addptr(cache, in_bytes(ConstantPoolCache::base_offset())); |
281 addptr(cache, tmp); // construct pointer to cache entry | 282 addptr(cache, tmp); // construct pointer to cache entry |
282 } | 283 } |
283 | 284 |
285 // Load object from cpool->resolved_references(index) | |
286 void InterpreterMacroAssembler::load_resolved_reference_at_index( | |
287 Register result, Register index) { | |
288 assert_different_registers(result, index); | |
289 // convert from field index to resolved_references() index and from | |
290 // word index to byte offset. Since this is a java object, it can be compressed | |
291 Register tmp = index; // reuse | |
292 shll(tmp, LogBytesPerHeapOop); | |
293 | |
294 get_constant_pool(result); | |
295 // load pointer for resolved_references[] objArray | |
296 movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes())); | |
297 // JNIHandles::resolve(obj); | |
298 movptr(result, Address(result, 0)); | |
299 // Add in the index | |
300 addptr(result, tmp); | |
301 load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); | |
302 } | |
284 | 303 |
285 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a | 304 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a |
286 // subtype of super_klass. | 305 // subtype of super_klass. |
287 // | 306 // |
288 // Args: | 307 // Args: |
424 // interp_only_mode if these events CAN be enabled. | 443 // interp_only_mode if these events CAN be enabled. |
425 // interp_only is an int, on little endian it is sufficient to test the byte only | 444 // interp_only is an int, on little endian it is sufficient to test the byte only |
426 // Is a cmpl faster? | 445 // Is a cmpl faster? |
427 cmpb(Address(r15_thread, JavaThread::interp_only_mode_offset()), 0); | 446 cmpb(Address(r15_thread, JavaThread::interp_only_mode_offset()), 0); |
428 jccb(Assembler::zero, run_compiled_code); | 447 jccb(Assembler::zero, run_compiled_code); |
429 jmp(Address(method, methodOopDesc::interpreter_entry_offset())); | 448 jmp(Address(method, Method::interpreter_entry_offset())); |
430 bind(run_compiled_code); | 449 bind(run_compiled_code); |
431 } | 450 } |
432 | 451 |
433 jmp(Address(method, methodOopDesc::from_interpreted_offset())); | 452 jmp(Address(method, Method::from_interpreted_offset())); |
434 | 453 |
435 } | 454 } |
436 | 455 |
437 | 456 |
438 // The following two routines provide a hook so that an implementation | 457 // The following two routines provide a hook so that an implementation |
524 movbool(rdx, do_not_unlock_if_synchronized); | 543 movbool(rdx, do_not_unlock_if_synchronized); |
525 movbool(do_not_unlock_if_synchronized, false); // reset the flag | 544 movbool(do_not_unlock_if_synchronized, false); // reset the flag |
526 | 545 |
527 // get method access flags | 546 // get method access flags |
528 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); | 547 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); |
529 movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); | 548 movl(rcx, Address(rbx, Method::access_flags_offset())); |
530 testl(rcx, JVM_ACC_SYNCHRONIZED); | 549 testl(rcx, JVM_ACC_SYNCHRONIZED); |
531 jcc(Assembler::zero, unlocked); | 550 jcc(Assembler::zero, unlocked); |
532 | 551 |
533 // Don't unlock anything if the _do_not_unlock_if_synchronized flag | 552 // Don't unlock anything if the _do_not_unlock_if_synchronized flag |
534 // is set. | 553 // is set. |
832 push(rax); | 851 push(rax); |
833 push(rbx); | 852 push(rbx); |
834 | 853 |
835 get_method(rbx); | 854 get_method(rbx); |
836 // Test MDO to avoid the call if it is NULL. | 855 // Test MDO to avoid the call if it is NULL. |
837 movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); | 856 movptr(rax, Address(rbx, in_bytes(Method::method_data_offset()))); |
838 testptr(rax, rax); | 857 testptr(rax, rax); |
839 jcc(Assembler::zero, set_mdp); | 858 jcc(Assembler::zero, set_mdp); |
840 // rbx: method | 859 // rbx: method |
841 // r13: bcp | 860 // r13: bcp |
842 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13); | 861 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13); |
843 // rax: mdi | 862 // rax: mdi |
844 // mdo is guaranteed to be non-zero here, we checked for it before the call. | 863 // mdo is guaranteed to be non-zero here, we checked for it before the call. |
845 movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); | 864 movptr(rbx, Address(rbx, in_bytes(Method::method_data_offset()))); |
846 addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); | 865 addptr(rbx, in_bytes(MethodData::data_offset())); |
847 addptr(rax, rbx); | 866 addptr(rax, rbx); |
848 bind(set_mdp); | 867 bind(set_mdp); |
849 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); | 868 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax); |
850 pop(rbx); | 869 pop(rbx); |
851 pop(rax); | 870 pop(rax); |
864 | 883 |
865 // If the mdp is valid, it will point to a DataLayout header which is | 884 // If the mdp is valid, it will point to a DataLayout header which is |
866 // consistent with the bcp. The converse is highly probable also. | 885 // consistent with the bcp. The converse is highly probable also. |
867 load_unsigned_short(c_rarg2, | 886 load_unsigned_short(c_rarg2, |
868 Address(c_rarg3, in_bytes(DataLayout::bci_offset()))); | 887 Address(c_rarg3, in_bytes(DataLayout::bci_offset()))); |
869 addptr(c_rarg2, Address(rbx, methodOopDesc::const_offset())); | 888 addptr(c_rarg2, Address(rbx, Method::const_offset())); |
870 lea(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); | 889 lea(c_rarg2, Address(c_rarg2, ConstMethod::codes_offset())); |
871 cmpptr(c_rarg2, r13); | 890 cmpptr(c_rarg2, r13); |
872 jcc(Assembler::equal, verify_continue); | 891 jcc(Assembler::equal, verify_continue); |
873 // rbx: method | 892 // rbx: method |
874 // r13: bcp | 893 // r13: bcp |
875 // c_rarg3: mdp | 894 // c_rarg3: mdp |