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