< prev index next >

src/hotspot/share/runtime/continuationFreezeThaw.cpp

Print this page
*** 1739,11 ***
    inline bool seen_by_gc();
  
    inline void before_thaw_java_frame(const frame& hf, const frame& caller, bool bottom, int num_frame);
    inline void after_thaw_java_frame(const frame& f, bool bottom);
    inline void patch(frame& f, const frame& caller, bool bottom);
!   void clear_bitmap_bits(intptr_t* start, int range);
  
    NOINLINE void recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames);
    void recurse_thaw_compiled_frame(const frame& hf, frame& caller, int num_frames, bool stub_caller);
    void recurse_thaw_stub_frame(const frame& hf, frame& caller, int num_frames);
    void finish_thaw(frame& f);
--- 1739,11 ---
    inline bool seen_by_gc();
  
    inline void before_thaw_java_frame(const frame& hf, const frame& caller, bool bottom, int num_frame);
    inline void after_thaw_java_frame(const frame& f, bool bottom);
    inline void patch(frame& f, const frame& caller, bool bottom);
!   void clear_bitmap_bits(address start, address end);
  
    NOINLINE void recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames);
    void recurse_thaw_compiled_frame(const frame& hf, frame& caller, int num_frames, bool stub_caller);
    void recurse_thaw_stub_frame(const frame& hf, frame& caller, int num_frames);
    void finish_thaw(frame& f);

*** 2120,17 ***
  
    assert(!bottom || !_cont.is_empty() || Continuation::is_continuation_entry_frame(f, nullptr), "");
    assert(!bottom || (_cont.is_empty() != Continuation::is_cont_barrier_frame(f)), "");
  }
  
! void ThawBase::clear_bitmap_bits(intptr_t* start, int range) {
    // we need to clear the bits that correspond to arguments as they reside in the caller frame
!   // or they will keep objects that are otherwise unreachable alive
!   log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(start+range));
    stackChunkOop chunk = _cont.tail();
!   chunk->bitmap().clear_range(chunk->bit_index_for(start),
!                               chunk->bit_index_for(start+range));
  }
  
  NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames) {
    assert(hf.is_interpreted_frame(), "");
  
--- 2120,26 ---
  
    assert(!bottom || !_cont.is_empty() || Continuation::is_continuation_entry_frame(f, nullptr), "");
    assert(!bottom || (_cont.is_empty() != Continuation::is_cont_barrier_frame(f)), "");
  }
  
! void ThawBase::clear_bitmap_bits(address start, address end) {
+   assert(is_aligned(start, wordSize), "should be aligned: " PTR_FORMAT, p2i(start));
+   assert(is_aligned(end, VMRegImpl::stack_slot_size), "should be aligned: " PTR_FORMAT, p2i(end));
+ 
    // we need to clear the bits that correspond to arguments as they reside in the caller frame
!   // or they will keep objects that are otherwise unreachable alive.
! 
+   // Align `end` if UseCompressedOops is not set to avoid UB when calculating the bit index, since
+   // `end` could be at an odd number of stack slots from `start`, i.e might not be oop aligned.
+   // If that's the case the bit range corresponding to the last stack slot should not have bits set
+   // anyways and we assert that before returning.
+   address effective_end = UseCompressedOops ? end : align_down(end, wordSize);
+   log_develop_trace(continuations)("clearing bitmap for " INTPTR_FORMAT " - " INTPTR_FORMAT, p2i(start), p2i(effective_end));
    stackChunkOop chunk = _cont.tail();
!   chunk->bitmap().clear_range(chunk->bit_index_for(start), chunk->bit_index_for(effective_end));
!   assert(effective_end == end || !chunk->bitmap().at(chunk->bit_index_for(effective_end)), "bit should not be set");
  }
  
  NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& caller, int num_frames) {
    assert(hf.is_interpreted_frame(), "");
  

*** 2179,11 ***
    if (!is_bottom_frame) {
      // can only fix caller once this frame is thawed (due to callee saved regs)
      _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
    } else if (_cont.tail()->has_bitmap() && locals > 0) {
      assert(hf.is_heap_frame(), "should be");
!     clear_bitmap_bits(heap_frame_bottom - locals, locals);
    }
  
    DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
    caller = f;
  }
--- 2188,13 ---
    if (!is_bottom_frame) {
      // can only fix caller once this frame is thawed (due to callee saved regs)
      _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
    } else if (_cont.tail()->has_bitmap() && locals > 0) {
      assert(hf.is_heap_frame(), "should be");
!     address start = (address)(heap_frame_bottom - locals);
+     address end = (address)heap_frame_bottom;
+     clear_bitmap_bits(start, end);
    }
  
    DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
    caller = f;
  }

*** 2252,11 ***
  
    if (!is_bottom_frame) {
      // can only fix caller once this frame is thawed (due to callee saved regs); this happens on the stack
      _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
    } else if (_cont.tail()->has_bitmap() && added_argsize > 0) {
!     clear_bitmap_bits(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top, added_argsize);
    }
  
    DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
    caller = f;
  }
--- 2263,14 ---
  
    if (!is_bottom_frame) {
      // can only fix caller once this frame is thawed (due to callee saved regs); this happens on the stack
      _cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
    } else if (_cont.tail()->has_bitmap() && added_argsize > 0) {
!     address start = (address)(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top);
+     int stack_args_slots = f.cb()->as_compiled_method()->method()->num_stack_arg_slots(false /* rounded */);
+     int argsize_in_bytes = stack_args_slots * VMRegImpl::stack_slot_size;
+     clear_bitmap_bits(start, start + argsize_in_bytes);
    }
  
    DEBUG_ONLY(after_thaw_java_frame(f, is_bottom_frame);)
    caller = f;
  }
< prev index next >