Print this page
rev 2161 : [mq]: initial-intrinsification-changes
rev 2162 : [mq]: code-review-comments-vladimir

Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
          +++ new/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
↓ open down ↓ 768 lines elided ↑ open up ↑
 769  769      // generate a vanilla interpreter entry as the slow path
 770  770      __ bind(slow_path);
 771  771  
 772  772      (void) generate_normal_entry(false);
 773  773      return entry_point;
 774  774    }
 775  775    return NULL;
 776  776  
 777  777  }
 778  778  
      779 +// Method entry for java.lang.ref.Reference.get.
      780 +address InterpreterGenerator::generate_Reference_get_entry(void) {
      781 +#ifndef SERIALGC
      782 +  // Code: _aload_0, _getfield, _areturn
      783 +  // parameter size = 1
      784 +  //
      785 +  // The code that gets generated by this routine is split into 2 parts:
      786 +  //    1. The "intrinsified" code for G1 (or any SATB based GC),
      787 +  //    2. The slow path - which is an expansion of the regular method entry.
      788 +  //
      789 +  // Notes:-
      790 +  // * In the G1 code we do not check whether we need to block for
      791 +  //   a safepoint. If G1 is enabled then we must execute the specialized
      792 +  //   code for Reference.get (except when the Reference object is null)
      793 +  //   so that we can log the value in the referent field with an SATB
      794 +  //   update buffer.
      795 +  //   If the code for the getfield template is modified so that the
      796 +  //   G1 pre-barrier code is executed when the current method is
      797 +  //   Reference.get() then going through the normal method entry
      798 +  //   will be fine.
      799 +  // * The G1 code below can, however, check the receiver object (the instance
      800 +  //   of java.lang.Reference) and jump to the slow path if null. If the
      801 +  //   Reference object is null then we obviously cannot fetch the referent
      802 +  //   and so we don't need to call the G1 pre-barrier. Thus we can use the
      803 +  //   regular method entry code to generate the NPE.
      804 +  //
      805 +  // This code is based on generate_accessor_enty.
      806 +
      807 +  // rbx,: methodOop
      808 +  // rcx: receiver (preserve for slow entry into asm interpreter)
      809 +
      810 +  // rsi: senderSP must preserved for slow path, set SP to it on fast path
      811 +
      812 +  address entry = __ pc();
      813 +
      814 +  const int referent_offset = java_lang_ref_Reference::referent_offset;
      815 +  guarantee(referent_offset > 0, "referent offset not initialized");
      816 +
      817 +  if (UseG1GC) {
      818 +    Label slow_path;
      819 +
      820 +    // Check if local 0 != NULL
      821 +    // If the receiver is null then it is OK to jump to the slow path.
      822 +    __ movptr(rax, Address(rsp, wordSize));
      823 +    __ testptr(rax, rax);
      824 +    __ jcc(Assembler::zero, slow_path);
      825 +
      826 +    // rax: local 0 (must be preserved across the G1 barrier call)
      827 +    //
      828 +    // rbx: method (at this point it's scratch)
      829 +    // rcx: receiver (at this point it's scratch)
      830 +    // rdx: scratch
      831 +    // rdi: scratch
      832 +    //
      833 +    // rsi: sender sp
      834 +
      835 +    // Preserve the sender sp in case the pre-barrier
      836 +    // calls the runtime
      837 +    __ push(rsi);
      838 +
      839 +    // Load the value of the referent field.
      840 +    const Address field_address(rax, referent_offset);
      841 +    __ movptr(rax, field_address);
      842 +
      843 +    // Generate the G1 pre-barrier code to log the value of
      844 +    // the referent field in an SATB buffer.
      845 +    __ get_thread(rcx);
      846 +    __ g1_write_barrier_pre(noreg /* obj */,
      847 +                            rax /* pre_val */,
      848 +                            rcx /* thread */,
      849 +                            rbx /* tmp */,
      850 +                            true /* tosca_save */,
      851 +                            true /* expand_call */);
      852 +
      853 +    // _areturn
      854 +    __ pop(rsi);                // get sender sp 
      855 +    __ pop(rdi);                // get return address
      856 +    __ mov(rsp, rsi);           // set sp to sender sp
      857 +    __ jmp(rdi);
      858 +    
      859 +    __ bind(slow_path);
      860 +    (void) generate_normal_entry(false);
      861 +
      862 +    return entry;
      863 +  }
      864 +#endif // SERIALGC
      865 +
      866 +  // If G1 is not enabled then attempt to go through the accessor entry point
      867 +  // Reference.get is an accessor
      868 +  return generate_accessor_entry();
      869 +}
      870 +
 779  871  //
 780  872  // Interpreter stub for calling a native method. (asm interpreter)
 781  873  // This sets up a somewhat different looking stack for calling the native method
 782  874  // than the typical interpreter frame setup.
 783  875  //
 784  876  
 785  877  address InterpreterGenerator::generate_native_entry(bool synchronized) {
 786  878    // determine code generation flags
 787  879    bool inc_counter  = UseCompiler || CountCompiledCalls;
 788  880  
↓ open down ↓ 648 lines elided ↑ open up ↑
1437 1529      case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();     break;
1438 1530      case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
1439 1531  
1440 1532      case Interpreter::java_lang_math_sin     : // fall thru
1441 1533      case Interpreter::java_lang_math_cos     : // fall thru
1442 1534      case Interpreter::java_lang_math_tan     : // fall thru
1443 1535      case Interpreter::java_lang_math_abs     : // fall thru
1444 1536      case Interpreter::java_lang_math_log     : // fall thru
1445 1537      case Interpreter::java_lang_math_log10   : // fall thru
1446 1538      case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
     1539 +    case Interpreter::java_lang_ref_reference_get
     1540 +                                             : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
1447 1541      default                                  : ShouldNotReachHere();                                                       break;
1448 1542    }
1449 1543  
1450 1544    if (entry_point) return entry_point;
1451 1545  
1452 1546    return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized);
1453 1547  
1454 1548  }
1455 1549  
1456 1550  // These should never be compiled since the interpreter will prefer
↓ open down ↓ 412 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX