hotspot/src/cpu/arm/vm/interp_masm_arm.cpp
changeset 46300 b8c77e61e99e
parent 42664 29142a56c193
child 46327 91576389a517
--- a/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp	Wed Mar 01 13:47:11 2017 +0000
+++ b/hotspot/src/cpu/arm/vm/interp_masm_arm.cpp	Wed Mar 01 14:59:36 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2195,75 +2195,42 @@
 
 void InterpreterMacroAssembler::get_method_counters(Register method,
                                                     Register Rcounters,
-                                                    Label& skip) {
+                                                    Label& skip,
+                                                    bool saveRegs,
+                                                    Register reg1,
+                                                    Register reg2,
+                                                    Register reg3) {
   const Address method_counters(method, Method::method_counters_offset());
   Label has_counters;
 
   ldr(Rcounters, method_counters);
   cbnz(Rcounters, has_counters);
 
+  if (saveRegs) {
+    // Save and restore in use caller-saved registers since they will be trashed by call_VM
+    assert(reg1 != noreg, "must specify reg1");
+    assert(reg2 != noreg, "must specify reg2");
 #ifdef AARCH64
-  const Register tmp = Rcounters;
-  const int saved_regs_size = 20*wordSize;
-
-  // Note: call_VM will cut SP according to Rstack_top value before call, and restore SP to
-  // extended_sp value from frame after the call.
-  // So make sure there is enough stack space to save registers and adjust Rstack_top accordingly.
-  {
-    Label enough_stack_space;
-    check_extended_sp(tmp);
-    sub(Rstack_top, Rstack_top, saved_regs_size);
-    cmp(SP, Rstack_top);
-    b(enough_stack_space, ls);
-
-    align_reg(tmp, Rstack_top, StackAlignmentInBytes);
-    mov(SP, tmp);
-    str(tmp, Address(FP, frame::interpreter_frame_extended_sp_offset * wordSize));
-
-    bind(enough_stack_space);
-    check_stack_top();
-
-    int offset = 0;
-    stp(R0,  R1,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R2,  R3,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R4,  R5,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R6,  R7,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R8,  R9,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R10, R11, Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R12, R13, Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R14, R15, Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R16, R17, Address(Rstack_top, offset)); offset += 2*wordSize;
-    stp(R18, LR,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    assert (offset == saved_regs_size, "should be");
+    assert(reg3 != noreg, "must specify reg3");
+    stp(reg1, reg2, Address(Rstack_top, -2*wordSize, pre_indexed));
+    stp(reg3, ZR, Address(Rstack_top, -2*wordSize, pre_indexed));
+#else
+    assert(reg3 == noreg, "must not specify reg3");
+    push(RegisterSet(reg1) | RegisterSet(reg2));
+#endif
   }
-#else
-  push(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(R14));
-#endif // AARCH64
 
   mov(R1, method);
-  call_VM(noreg, CAST_FROM_FN_PTR(address,
-          InterpreterRuntime::build_method_counters), R1);
-
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), R1);
+
+  if (saveRegs) {
 #ifdef AARCH64
-  {
-    int offset = 0;
-    ldp(R0,  R1,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R2,  R3,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R4,  R5,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R6,  R7,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R8,  R9,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R10, R11, Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R12, R13, Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R14, R15, Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R16, R17, Address(Rstack_top, offset)); offset += 2*wordSize;
-    ldp(R18, LR,  Address(Rstack_top, offset)); offset += 2*wordSize;
-    assert (offset == saved_regs_size, "should be");
-
-    add(Rstack_top, Rstack_top, saved_regs_size);
+    ldp(reg3, ZR, Address(Rstack_top, 2*wordSize, post_indexed));
+    ldp(reg1, reg2, Address(Rstack_top, 2*wordSize, post_indexed));
+#else
+    pop(RegisterSet(reg1) | RegisterSet(reg2));
+#endif
   }
-#else
-  pop(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(R14));
-#endif // AARCH64
 
   ldr(Rcounters, method_counters);
   cbz(Rcounters, skip); // No MethodCounters created, OutOfMemory