[aarch64-port-dev ] Template interpreter intrinsics.

Andrew Haley aph at redhat.com
Thu Dec 19 09:29:33 PST 2013


A few methods that were missing.

Andrew.


# HG changeset patch
# User aph
# Date 1387469644 0
# Node ID d51634dc964cc80727bf782291f83986818c44e4
# Parent  92c7300156fe53cc71b5154b94515d75c36cb9c6
Template interpreter intrinsics.

diff -r 92c7300156fe -r d51634dc964c src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp
--- a/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp	Wed Dec 18 16:36:20 2013 +0000
+++ b/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp	Thu Dec 19 16:14:04 2013 +0000
@@ -41,8 +41,8 @@
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
   address generate_abstract_entry(void);
-  address generate_method_handle_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
+void generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpargs);
   address generate_empty_entry(void);
   address generate_accessor_entry(void);
   address generate_Reference_get_entry();
diff -r 92c7300156fe -r d51634dc964c src/cpu/aarch64/vm/interpreter_aarch64.cpp
--- a/src/cpu/aarch64/vm/interpreter_aarch64.cpp	Wed Dec 18 16:36:20 2013 +0000
+++ b/src/cpu/aarch64/vm/interpreter_aarch64.cpp	Thu Dec 19 16:14:04 2013 +0000
@@ -125,34 +125,171 @@
 //

 address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
-  return NULL;
+  // rmethod: Method*
+  // r13: sender sp
+  // esp: args
+
+  if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
+
+  // These don't need a safepoint check because they aren't virtually
+  // callable. We won't enter these intrinsics from compiled code.
+  // If in the future we added an intrinsic which was virtually callable
+  // we'd have to worry about how to safepoint so that this code is used.
+
+  // mathematical functions inlined by compiler
+  // (interpreter must provide identical implementation
+  // in order to avoid monotonicity bugs when switching
+  // from interpreter to compiler in the middle of some
+  // computation)
+  //
+  // stack:
+  //        [ arg ] <-- esp
+  //        [ arg ]
+  // retaddr in lr
+
+  address entry_point = NULL;
+  Register continuation = lr;
+  switch (kind) {
+  case Interpreter::java_lang_math_abs:
+    entry_point = __ pc();
+    __ ldrd(v0, Address(esp));
+    __ fabsd(v0, v0);
+    break;
+  case Interpreter::java_lang_math_sqrt:
+    entry_point = __ pc();
+    __ ldrd(v0, Address(esp));
+    __ fsqrtd(v0, v0);
+    break;
+  case Interpreter::java_lang_math_sin :
+  case Interpreter::java_lang_math_cos :
+  case Interpreter::java_lang_math_tan :
+  case Interpreter::java_lang_math_log :
+  case Interpreter::java_lang_math_log10 :
+  case Interpreter::java_lang_math_exp :
+    entry_point = __ pc();
+    __ ldrd(v0, Address(esp));
+    __ mov(r19, lr);
+    continuation = r19;  // The first callee-saved register
+    generate_transcendental_entry(kind, 1);
+    break;
+  case Interpreter::java_lang_math_pow :
+    entry_point = __ pc();
+    __ mov(r19, lr);
+    continuation = r19;
+    __ ldrd(v0, Address(esp, 2 * Interpreter::stackElementSize));
+    __ ldrd(v1, Address(esp));
+    generate_transcendental_entry(kind, 2);
+    break;
+  default:
+    ;
+  }
+  if (entry_point) {
+    __ br(continuation);
+  }
+
+  return entry_point;
 }

+  // double trigonometrics and transcendentals
+  // static jdouble dsin(jdouble x);
+  // static jdouble dcos(jdouble x);
+  // static jdouble dtan(jdouble x);
+  // static jdouble dlog(jdouble x);
+  // static jdouble dlog10(jdouble x);
+  // static jdouble dexp(jdouble x);
+  // static jdouble dpow(jdouble x, jdouble y);
+
+void InterpreterGenerator::generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpargs) {
+  address fn;
+  switch (kind) {
+  case Interpreter::java_lang_math_sin :
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
+    break;
+  case Interpreter::java_lang_math_cos :
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
+    break;
+  case Interpreter::java_lang_math_tan :
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
+    break;
+  case Interpreter::java_lang_math_log :
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
+    break;
+  case Interpreter::java_lang_math_log10 :
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
+    break;
+  case Interpreter::java_lang_math_exp :
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
+    break;
+  case Interpreter::java_lang_math_pow :
+    fpargs = 2;
+    fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+  const int gpargs = 0, rtype = 3;
+  __ mov(rscratch1, fn);
+  __ blrt(rscratch1, gpargs, fpargs, rtype);
+}

 // Abstract method entry
 // Attempt to execute abstract method. Throw exception
 address InterpreterGenerator::generate_abstract_entry(void) {
+  // rmethod: Method*
+  // r13: sender SP
+
   address entry_point = __ pc();

-  __ call_Unimplemented();
+  // abstract method entry
+
+  //  pop return address, reset last_sp to NULL
+  __ empty_expression_stack();
+  __ restore_bcp();      // bcp must be correct for exception handler   (was destroyed)
+  __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
+
+  // throw exception
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address,
+                             InterpreterRuntime::throw_AbstractMethodError));
+  // the call_VM checks for exception, so we should never return here.
+  __ should_not_reach_here();

   return entry_point;
 }

-// Method handle invoker
-// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
-address InterpreterGenerator::generate_method_handle_entry(void) {
-  address entry_point = __ pc();
-
-  __ call_Unimplemented();
-
-  return entry_point;
-}

 // Empty method, generate a very fast return.

 address InterpreterGenerator::generate_empty_entry(void) {
-  return NULL;
+  // rmethod: Method*
+  // r13: sender sp must set sp to this value on return
+
+  if (!UseFastEmptyMethods) {
+    return NULL;
+  }
+
+  address entry_point = __ pc();
+
+  // If we need a safepoint check, generate full interpreter entry.
+  Label slow_path;
+  {
+    unsigned long offset;
+    assert(SafepointSynchronize::_not_synchronized == 0,
+	   "SafepointSynchronize::_not_synchronized");
+    __ adrp(rscratch2, SafepointSynchronize::address_of_state(), offset);
+    __ ldrw(rscratch2, Address(rscratch2, offset));
+    __ cbnz(rscratch2, slow_path);
+  }
+
+  // do nothing for empty methods (do not even increment invocation counter)
+  // Code: _return
+  // _return
+  // return w/o popping parameters
+  __ br(lr);
+
+  __ bind(slow_path);
+  (void) generate_normal_entry(false);
+  return entry_point;
+
 }

 void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
diff -r 92c7300156fe -r d51634dc964c src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Dec 18 16:36:20 2013 +0000
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Dec 19 16:14:04 2013 +0000
@@ -1756,18 +1756,6 @@
   hlt(0);
 }

-void MacroAssembler::enter()
-{
-  stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
-  mov(rfp, sp);
-}
-
-void MacroAssembler::leave()
-{
-  mov(sp, rfp);
-  ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
-}
-
 // If a constant does not fit in an immediate field, generate some
 // number of MOV instructions and then perform the operation.
 void MacroAssembler::wrap_add_sub_imm_insn(Register Rd, Register Rn, unsigned imm,
diff -r 92c7300156fe -r d51634dc964c src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Dec 18 16:36:20 2013 +0000
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Dec 19 16:14:04 2013 +0000
@@ -547,12 +547,17 @@
   // Alignment
   void align(int modulus);

-  // A 5 byte nop that is safe for patching (see patch_verified_entry)
-  void fat_nop();
-
   // Stack frame creation/removal
-  void enter();
-  void leave();
+  void enter()
+  {
+    stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
+    mov(rfp, sp);
+  }
+  void leave()
+  {
+    mov(sp, rfp);
+    ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
+  }

   // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information)
   // The pointer will be loaded into the thread register.



More information about the aarch64-port-dev mailing list