< prev index next >

src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp

Print this page
@@ -168,48 +168,69 @@
  
  class StubFrame: public StackObj {
   private:
    StubAssembler* _sasm;
    bool _return_state;
+   bool _use_pop_on_epilogue;
  
-  public:
-   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, return_state_t return_state=requires_return);
-   void load_argument(int offset_in_words, Register reg);
+   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments,
+             return_state_t return_state, bool use_pop_on_epilogue);
  
+  public:
+   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, bool use_pop_on_epilogue);
+   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, return_state_t return_state);
+   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
    ~StubFrame();
+ 
+   void load_argument(int offset_in_words, Register reg);
  };;
  
  void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
    set_info(name, must_gc_arguments);
    enter();
  }
  
- void StubAssembler::epilogue() {
-   leave();
+ void StubAssembler::epilogue(bool use_pop) {
+   // use_pop when this frame may have been frozen on one carrier
+   // thread then thawed on another carrier thread, rendering the fp
+   // register invalid. We must restore the previous FP because it is
+   // used as a call-saved scratch register by compiled code.
+   if (use_pop) {
+     ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
+   } else {
+     leave();
+   }
    ret(lr);
  }
  
  #define __ _sasm->
  
- StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments, return_state_t return_state) {
-   _sasm = sasm;
-   _return_state = return_state;
+ StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments,
+                      return_state_t return_state, bool use_pop_on_epilogue)
+   : _sasm(sasm), _return_state(return_state), _use_pop_on_epilogue(use_pop_on_epilogue) {
    __ prologue(name, must_gc_arguments);
  }
  
+ StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments,
+                      bool use_pop_on_epilogue) :
+   StubFrame(sasm, name, must_gc_arguments, requires_return, use_pop_on_epilogue) {}
+ 
+ StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments,
+                      return_state_t return_state) :
+   StubFrame(sasm, name, must_gc_arguments, return_state, /*use_pop_on_epilogue*/false) {}
+ 
+ StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) :
+   StubFrame(sasm, name, must_gc_arguments, requires_return, /*use_pop_on_epilogue*/false) {}
+ 
  // load parameters that were stored with LIR_Assembler::store_parameter
  // Note: offsets for store_parameter and load_argument must match
  void StubFrame::load_argument(int offset_in_words, Register reg) {
    __ load_parameter(offset_in_words, reg);
  }
  
  StubFrame::~StubFrame() {
-   if (_return_state == requires_return) {
-     __ epilogue();
-   } else {
-     __ should_not_reach_here();
-   }
+   __ epilogue(_use_pop_on_epilogue);
  }
  
  #undef __
  
  

@@ -250,11 +271,11 @@
    int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
    OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
  
    for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
      Register r = as_Register(i);
-     if (i <= 18 && i != rscratch1->encoding() && i != rscratch2->encoding()) {
+     if (r == rthread || (i <= 18 && i != rscratch1->encoding() && i != rscratch2->encoding())) {
        int sp_offset = cpu_reg_save_offsets[i];
        oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
                                  r->as_VMReg());
      }
    }

@@ -335,10 +356,19 @@
      cpu_reg_save_offsets[i] = sp_offset;
      sp_offset += 2;   // SP offsets are in halfwords
    }
  }
  
+ // return: offset in 64-bit words.
+ uint Runtime1::runtime_blob_current_thread_offset(frame f) {
+   CodeBlob* cb = f.cb();
+   assert(cb == Runtime1::blob_for(Runtime1::monitorenter_id) ||
+          cb == Runtime1::blob_for(Runtime1::monitorenter_nofpu_id), "must be");
+   assert(cb != nullptr && cb->is_runtime_stub(), "invalid frame");
+   int offset = cpu_reg_save_offsets[rthread->encoding()];
+   return offset / 2;   // SP offsets are in halfwords
+ }
  
  // target: the entry point of the method that creates and posts the exception oop
  // has_argument: true if the exception needs arguments (passed in rscratch1 and rscratch2)
  
  OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {

@@ -860,11 +890,11 @@
      case monitorenter_nofpu_id:
        save_fpu_registers = false;
        // fall through
      case monitorenter_id:
        {
-         StubFrame f(sasm, "monitorenter", dont_gc_arguments);
+         StubFrame f(sasm, "monitorenter", dont_gc_arguments, /*use_pop_on_epilogue*/true);
          OopMap* map = save_live_registers(sasm, save_fpu_registers);
  
          // Called with store_parameter and not C abi
  
          f.load_argument(1, r0); // r0,: object
< prev index next >