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

Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
          +++ new/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
↓ open down ↓ 749 lines elided ↑ open up ↑
 750  750      // generate a vanilla interpreter entry as the slow path
 751  751      __ bind(slow_path);
 752  752      (void) generate_normal_entry(false);
 753  753    } else {
 754  754      (void) generate_normal_entry(false);
 755  755    }
 756  756  
 757  757    return entry_point;
 758  758  }
 759  759  
      760 +// Method entry for java.lang.ref.Reference.get.
      761 +address InterpreterGenerator::generate_Reference_get_entry(void) {
      762 +#ifndef SERIALGC
      763 +  // Code: _aload_0, _getfield, _areturn
      764 +  // parameter size = 1
      765 +  //
      766 +  // The code that gets generated by this routine is split into 2 parts:
      767 +  //    1. The "intrinsified" code for G1 (or any SATB based GC),
      768 +  //    2. The slow path - which is an expansion of the regular method entry.
      769 +  //
      770 +  // Notes:-
      771 +  // * In the G1 code we do not check whether we need to block for
      772 +  //   a safepoint. If G1 is enabled then we must execute the specialized
      773 +  //   code for Reference.get (except when the Reference object is null)
      774 +  //   so that we can log the value in the referent field with an SATB
      775 +  //   update buffer.
      776 +  //   If the code for the getfield template is modified so that the
      777 +  //   G1 pre-barrier code is executed when the current method is
      778 +  //   Reference.get() then going through the normal method entry
      779 +  //   will be fine.
      780 +  // * The G1 code can, however, check the receiver object (the instance
      781 +  //   of java.lang.Reference) and jump to the slow path if null. If the
      782 +  //   Reference object is null then we obviously cannot fetch the referent
      783 +  //   and so we don't need to call the G1 pre-barrier. Thus we can use the
      784 +  //   regular method entry code to generate the NPE.
      785 +  //
      786 +  // This code is based on generate_accessor_enty.
      787 +  //
      788 +  // rbx: methodOop
      789 +
      790 +  // r13: senderSP must preserve for slow path, set SP to it on fast path
      791 +
      792 +  address entry = __ pc();
      793 +
      794 +  const int referent_offset = java_lang_ref_Reference::referent_offset;
      795 +  guarantee(referent_offset > 0, "referent offset not initialized");
      796 +
      797 +  if (UseG1GC) {
      798 +    Label slow_path;
      799 +    // rbx: method
      800 +
      801 +    // Check if local 0 != NULL
      802 +    // If the receiver is null then it is OK to jump to the slow path.
      803 +    __ movptr(rax, Address(rsp, wordSize));
      804 +
      805 +    __ testptr(rax, rax);
      806 +    __ jcc(Assembler::zero, slow_path);
      807 +
      808 +    // rax: local 0
      809 +    // rbx: method (but can be used as scratch now)
      810 +    // rdx: scratch
      811 +    // rdi: scratch
      812 +
      813 +    // Generate the G1 pre-barrier code to log the value of
      814 +    // the referent field in an SATB buffer.
      815 +
      816 +    // Load the value of the referent field.
      817 +    const Address field_address(rax, referent_offset);
      818 +    __ load_heap_oop(rax, field_address);
      819 +
      820 +    // Generate the G1 pre-barrier code to log the value of
      821 +    // the referent field in an SATB buffer.
      822 +    __ g1_write_barrier_pre(noreg /* obj */,
      823 +                            rax /* pre_val */,
      824 +                            r15_thread /* thread */,
      825 +                            rbx /* tmp */,
      826 +                            true /* tosca_live */,
      827 +                            true /* expand_call */);
      828 +
      829 +    // _areturn
      830 +    __ pop(rdi);                // get return address
      831 +    __ mov(rsp, r13);           // set sp to sender sp
      832 +    __ jmp(rdi);
      833 +    __ ret(0);
      834 +
      835 +    // generate a vanilla interpreter entry as the slow path
      836 +    __ bind(slow_path);
      837 +    (void) generate_normal_entry(false);
      838 +
      839 +    return entry;
      840 +  }
      841 +#endif // SERIALGC
      842 +
      843 +  // If G1 is not enabled then attempt to go through the accessor entry point
      844 +  // Reference.get is an accessor
      845 +  return generate_accessor_entry();
      846 +}
      847 +
      848 +
 760  849  // Interpreter stub for calling a native method. (asm interpreter)
 761  850  // This sets up a somewhat different looking stack for calling the
 762  851  // native method than the typical interpreter frame setup.
 763  852  address InterpreterGenerator::generate_native_entry(bool synchronized) {
 764  853    // determine code generation flags
 765  854    bool inc_counter  = UseCompiler || CountCompiledCalls;
 766  855  
 767  856    // rbx: methodOop
 768  857    // r13: sender sp
 769  858  
↓ open down ↓ 686 lines elided ↑ open up ↑
1456 1545    case Interpreter::abstract               : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();    break;
1457 1546    case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();break;
1458 1547  
1459 1548    case Interpreter::java_lang_math_sin     : // fall thru
1460 1549    case Interpreter::java_lang_math_cos     : // fall thru
1461 1550    case Interpreter::java_lang_math_tan     : // fall thru
1462 1551    case Interpreter::java_lang_math_abs     : // fall thru
1463 1552    case Interpreter::java_lang_math_log     : // fall thru
1464 1553    case Interpreter::java_lang_math_log10   : // fall thru
1465 1554    case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);    break;
     1555 +  case Interpreter::java_lang_ref_reference_get
     1556 +                                           : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
1466 1557    default                                  : ShouldNotReachHere();                                                       break;
1467 1558    }
1468 1559  
1469 1560    if (entry_point) {
1470 1561      return entry_point;
1471 1562    }
1472 1563  
1473 1564    return ((InterpreterGenerator*) this)->
1474 1565                                  generate_normal_entry(synchronized);
1475 1566  }
↓ open down ↓ 435 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX