< prev index next >

src/hotspot/cpu/x86/frame_x86.inline.hpp

Print this page
@@ -30,10 +30,13 @@
  #include "code/vmreg.inline.hpp"
  #include "compiler/oopMap.inline.hpp"
  #include "interpreter/interpreter.hpp"
  #include "runtime/sharedRuntime.hpp"
  #include "runtime/registerMap.hpp"
+ #ifdef COMPILER1
+ #include "c1/c1_Runtime1.hpp"
+ #endif
  
  // Inline functions for Intel frames:
  
  #if INCLUDE_JFR
  

@@ -421,30 +424,37 @@
    return frame(sender_sp(), link(), sender_pc());
  }
  
  inline frame frame::sender_for_compiled_frame(RegisterMap* map) const {
    assert(map != nullptr, "map must be set");
- 
-   // frame owned by optimizing compiler
-   assert(_cb->frame_size() > 0, "must have non-zero frame size");
-   intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
-   assert(sender_sp == real_fp(), "");
- 
-   // On Intel the return_address is always the word on the stack
-   address sender_pc = (address) *(sender_sp-1);
- 
-   // This is the saved value of EBP which may or may not really be an FP.
-   // It is only an FP if the sender is an interpreter frame (or C1?).
-   // saved_fp_addr should be correct even for a bottom thawed frame (with a return barrier)
-   intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
+   CompiledFramePointers cfp = compiled_frame_details();
  
    if (map->update_map()) {
      // Tell GC to use argument oopmaps for some runtime stubs that need it.
      // For C1, the runtime stub might not have oop maps, so set this flag
      // outside of update_register_map.
-     if (!_cb->is_nmethod()) { // compiled frames do not use callee-saved registers
-       map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
+     bool c1_buffering = false;
+ #ifdef COMPILER1
+     nmethod* nm = _cb->as_nmethod_or_null();
+     if (nm != nullptr && nm->is_compiled_by_c1() && nm->method()->has_scalarized_args() &&
+         pc() < nm->verified_inline_entry_point()) {
+       // TODO 8284443 Can't we do that by not passing 'dont_gc_arguments' in case 'StubId::c1_buffer_inline_args_id' in 'Runtime1::generate_code_for'?
+       // The VEP and VIEP(RO) of C1-compiled methods call buffer_inline_args_xxx
+       // before doing any argument shuffling, so we need to scan the oops
+       // as the caller passes them.
+       c1_buffering = true;
+ #ifdef ASSERT
+       NativeCall* call = nativeCall_before(pc());
+       address dest = call->destination();
+       assert(dest == Runtime1::entry_for(StubId::c1_buffer_inline_args_no_receiver_id) ||
+              dest == Runtime1::entry_for(StubId::c1_buffer_inline_args_id), "unexpected safepoint in entry point");
+ #endif
+     }
+ #endif
+     if (!_cb->is_nmethod() || c1_buffering) { // compiled frames do not use callee-saved registers
+       bool caller_args = _cb->caller_must_gc_arguments(map->thread()) || c1_buffering;
+       map->set_include_argument_oops(caller_args);
        if (oop_map() != nullptr) {
          _oop_map->update_register_map(this, map);
        }
      } else {
        assert(!_cb->caller_must_gc_arguments(map->thread()), "");

@@ -453,25 +463,25 @@
      }
  
      // Since the prolog does the save and restore of EBP there is no oopmap
      // for it so we must fill in its location as if there was an oopmap entry
      // since if our caller was compiled code there could be live jvm state in it.
-     update_map_with_saved_link(map, saved_fp_addr);
+     update_map_with_saved_link(map, cfp.saved_fp_addr);
    }
  
-   assert(sender_sp != sp(), "must have changed");
+   assert(cfp.sender_sp != sp(), "must have changed");
  
-   if (Continuation::is_return_barrier_entry(sender_pc)) {
+   if (Continuation::is_return_barrier_entry(*cfp.sender_pc_addr)) {
      if (map->walk_cont()) { // about to walk into an h-stack
        return Continuation::top_frame(*this, map);
      } else {
-       return Continuation::continuation_bottom_sender(map->thread(), *this, sender_sp);
+       return Continuation::continuation_bottom_sender(map->thread(), *this, cfp.sender_sp);
      }
    }
  
-   intptr_t* unextended_sp = sender_sp;
-   return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
+   intptr_t* unextended_sp = cfp.sender_sp;
+   return frame(cfp.sender_sp, unextended_sp, *cfp.saved_fp_addr, *cfp.sender_pc_addr);
  }
  
  template <typename RegisterMapT>
  void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr) {
    // The interpreter and compiler(s) always save EBP/RBP in a known
< prev index next >