1.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Wed Apr 06 16:02:53 2011 -0700 1.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Apr 08 14:19:50 2011 -0700 1.3 @@ -776,6 +776,98 @@ 1.4 1.5 } 1.6 1.7 +// Method entry for java.lang.ref.Reference.get. 1.8 +address InterpreterGenerator::generate_Reference_get_entry(void) { 1.9 +#ifndef SERIALGC 1.10 + // Code: _aload_0, _getfield, _areturn 1.11 + // parameter size = 1 1.12 + // 1.13 + // The code that gets generated by this routine is split into 2 parts: 1.14 + // 1. The "intrinsified" code for G1 (or any SATB based GC), 1.15 + // 2. The slow path - which is an expansion of the regular method entry. 1.16 + // 1.17 + // Notes:- 1.18 + // * In the G1 code we do not check whether we need to block for 1.19 + // a safepoint. If G1 is enabled then we must execute the specialized 1.20 + // code for Reference.get (except when the Reference object is null) 1.21 + // so that we can log the value in the referent field with an SATB 1.22 + // update buffer. 1.23 + // If the code for the getfield template is modified so that the 1.24 + // G1 pre-barrier code is executed when the current method is 1.25 + // Reference.get() then going through the normal method entry 1.26 + // will be fine. 1.27 + // * The G1 code below can, however, check the receiver object (the instance 1.28 + // of java.lang.Reference) and jump to the slow path if null. If the 1.29 + // Reference object is null then we obviously cannot fetch the referent 1.30 + // and so we don't need to call the G1 pre-barrier. Thus we can use the 1.31 + // regular method entry code to generate the NPE. 1.32 + // 1.33 + // This code is based on generate_accessor_enty. 1.34 + 1.35 + // rbx,: methodOop 1.36 + // rcx: receiver (preserve for slow entry into asm interpreter) 1.37 + 1.38 + // rsi: senderSP must preserved for slow path, set SP to it on fast path 1.39 + 1.40 + address entry = __ pc(); 1.41 + 1.42 + const int referent_offset = java_lang_ref_Reference::referent_offset; 1.43 + guarantee(referent_offset > 0, "referent offset not initialized"); 1.44 + 1.45 + if (UseG1GC) { 1.46 + Label slow_path; 1.47 + 1.48 + // Check if local 0 != NULL 1.49 + // If the receiver is null then it is OK to jump to the slow path. 1.50 + __ movptr(rax, Address(rsp, wordSize)); 1.51 + __ testptr(rax, rax); 1.52 + __ jcc(Assembler::zero, slow_path); 1.53 + 1.54 + // rax: local 0 (must be preserved across the G1 barrier call) 1.55 + // 1.56 + // rbx: method (at this point it's scratch) 1.57 + // rcx: receiver (at this point it's scratch) 1.58 + // rdx: scratch 1.59 + // rdi: scratch 1.60 + // 1.61 + // rsi: sender sp 1.62 + 1.63 + // Preserve the sender sp in case the pre-barrier 1.64 + // calls the runtime 1.65 + __ push(rsi); 1.66 + 1.67 + // Load the value of the referent field. 1.68 + const Address field_address(rax, referent_offset); 1.69 + __ movptr(rax, field_address); 1.70 + 1.71 + // Generate the G1 pre-barrier code to log the value of 1.72 + // the referent field in an SATB buffer. 1.73 + __ get_thread(rcx); 1.74 + __ g1_write_barrier_pre(noreg /* obj */, 1.75 + rax /* pre_val */, 1.76 + rcx /* thread */, 1.77 + rbx /* tmp */, 1.78 + true /* tosca_save */, 1.79 + true /* expand_call */); 1.80 + 1.81 + // _areturn 1.82 + __ pop(rsi); // get sender sp 1.83 + __ pop(rdi); // get return address 1.84 + __ mov(rsp, rsi); // set sp to sender sp 1.85 + __ jmp(rdi); 1.86 + 1.87 + __ bind(slow_path); 1.88 + (void) generate_normal_entry(false); 1.89 + 1.90 + return entry; 1.91 + } 1.92 +#endif // SERIALGC 1.93 + 1.94 + // If G1 is not enabled then attempt to go through the accessor entry point 1.95 + // Reference.get is an accessor 1.96 + return generate_accessor_entry(); 1.97 +} 1.98 + 1.99 // 1.100 // Interpreter stub for calling a native method. (asm interpreter) 1.101 // This sets up a somewhat different looking stack for calling the native method 1.102 @@ -1444,6 +1536,8 @@ 1.103 case Interpreter::java_lang_math_log : // fall thru 1.104 case Interpreter::java_lang_math_log10 : // fall thru 1.105 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; 1.106 + case Interpreter::java_lang_ref_reference_get 1.107 + : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; 1.108 default : ShouldNotReachHere(); break; 1.109 } 1.110