src/cpu/x86/vm/templateInterpreter_x86_32.cpp

changeset 2784
92add02409c9
parent 2698
38fea01eb669
parent 2781
e1162778c1c8
child 2901
3d2ab563047a
     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  

mercurial