< prev index next >

src/hotspot/share/runtime/javaThread.hpp

Print this page
@@ -494,23 +494,36 @@
    // instead of unmounting.
    bool _preemption_cancelled;
    // For Object.wait() we set this field to know if we need to
    // throw IE at the end of thawing before returning to Java.
    bool _pending_interrupted_exception;
+   // We allow preemption on some klass initializion calls.
+   // We use this boolean to mark such calls.
+   bool _at_preemptable_init;
  
   public:
    bool preemption_cancelled()           { return _preemption_cancelled; }
    void set_preemption_cancelled(bool b) { _preemption_cancelled = b; }
  
    bool pending_interrupted_exception()           { return _pending_interrupted_exception; }
    void set_pending_interrupted_exception(bool b) { _pending_interrupted_exception = b; }
  
-   bool preempting()           { return _preempt_alternate_return != nullptr; }
+   bool preempting()                              { return _preempt_alternate_return != nullptr; }
    void set_preempt_alternate_return(address val) { _preempt_alternate_return = val; }
  
- private:
+   bool at_preemptable_init() { return _at_preemptable_init; }
+   void set_at_preemptable_init(bool b) { _at_preemptable_init = b; }
+ 
+ #ifdef ASSERT
+   // Used for extra logging with -Xlog:continuation+preempt
+   InstanceKlass* _preempt_init_klass;
  
+   InstanceKlass* preempt_init_klass() { return _preempt_init_klass; }
+   void set_preempt_init_klass(InstanceKlass* ik) { _preempt_init_klass = ik; }
+ #endif
+ 
+ private:
    friend class VMThread;
    friend class ThreadWaitTransition;
    friend class VM_Exit;
  
    // Stack watermark barriers.

@@ -1347,16 +1360,33 @@
      thread->push_jni_handle_block();
    }
    ~JNIHandleMark() { _thread->pop_jni_handle_block(); }
  };
  
+ class PreemptableInitCall {
+   JavaThread* _thread;
+   bool _previous;
+   DEBUG_ONLY(InstanceKlass* _previous_klass;)
+  public:
+   PreemptableInitCall(JavaThread* thread, InstanceKlass* ik) : _thread(thread) {
+     _previous = thread->at_preemptable_init();
+     _thread->set_at_preemptable_init(true);
+     DEBUG_ONLY(_previous_klass = _thread->preempt_init_klass();)
+     DEBUG_ONLY(_thread->set_preempt_init_klass(ik));
+   }
+   ~PreemptableInitCall() {
+     _thread->set_at_preemptable_init(_previous);
+     DEBUG_ONLY(_thread->set_preempt_init_klass(_previous_klass));
+   }
+ };
+ 
  class NoPreemptMark {
    ContinuationEntry* _ce;
    bool _unpin;
   public:
-   NoPreemptMark(JavaThread* thread) : _ce(thread->last_continuation()), _unpin(false) {
-     if (_ce != nullptr) _unpin = _ce->pin();
+   NoPreemptMark(JavaThread* thread, bool ignore_mark = false) : _ce(thread->last_continuation()), _unpin(false) {
+     if (_ce != nullptr && !ignore_mark) _unpin = _ce->pin();
    }
    ~NoPreemptMark() { if (_unpin) _ce->unpin(); }
  };
  
  class ThreadOnMonitorWaitedEvent {
< prev index next >