sssssssss73

  void initialize() {
    _value       = &_value_buffer[1];
    _value_state = &_value_state_buffer[1];
    _max_size = _default_size;
    _size = 0;
    _start_at_zero = false;
  }
  template<typename T>
  inline int push_oop_impl(T handle, int size) {
    JNITypes::put_obj((oop)handle, _value, size); // Updates size.
    return size;                // Return the updated size.
  }
 public:
  JavaCallArguments() { initialize(); }
  JavaCallArguments(Handle receiver) {
    initialize();
    push_oop(receiver);
  }
  JavaCallArguments(int max_size) {
    if (max_size > _default_size) {
      _value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
      _value_state = NEW_RESOURCE_ARRAY(u_char, max_size + 1);
      _value++;
      _value_state++;
      _max_size = max_size;
      _size = 0;
      _start_at_zero = false;
    } else {
      initialize();
    }
  }
  enum {
    value_state_primitive,
    value_state_oop,
    value_state_handle,
    value_state_jobject,
    value_state_limit
  };
  inline void push_oop(Handle h) {
    _value_state[_size] = value_state_handle;
    _size = push_oop_impl(h.raw_value(), _size);
  }
  inline void push_jobject(jobject h) {
    _value_state[_size] = value_state_jobject;
    _size = push_oop_impl(h, _size);
  }
  inline void push_int(int i) {
    _value_state[_size] = value_state_primitive;
    JNITypes::put_int(i, _value, _size);
  }
  inline void push_double(double d) {
    _value_state[_size] = value_state_primitive;
    _value_state[_size + 1] = value_state_primitive;
    JNITypes::put_double(d, _value, _size);
  }
  inline void push_long(jlong l) {
    _value_state[_size] = value_state_primitive;
    _value_state[_size + 1] = value_state_primitive;
    JNITypes::put_long(l, _value, _size);
  }
  inline void push_float(float f) {
    _value_state[_size] = value_state_primitive;
    JNITypes::put_float(f, _value, _size);
  }
  Handle receiver() {
    assert(_size > 0, "must at least be one argument");
    assert(_value_state[0] == value_state_handle,
           "first argument must be an oop");
    assert(_value[0] != 0, "receiver must be not-null");
    return Handle((oop*)_value[0], false);
  }
  void set_receiver(Handle h) {
    assert(_start_at_zero == false, "can only be called once");
    _start_at_zero = true;
    _value_state--;
    _value--;
    _size++;
    _value_state[0] = value_state_handle;
    push_oop_impl(h.raw_value(), 0);
  }
  intptr_t* parameters() ;
  int   size_of_parameters() const { return _size; }
  void verify(methodHandle method, BasicType return_type);
};
class JavaCalls: AllStatic {
  static void call_helper(JavaValue* result, methodHandle* method, JavaCallArguments* args, TRAPS);
 public:
  static void call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS);
  static void call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS);
  static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); // No args
  static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS);
  static void call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS);
  static void call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS);
  static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS); // No args
  static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS);
  static void call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS);
  static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS);
  static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
  static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS);
  static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS);
  static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS);
};
#endif // SHARE_VM_RUNTIME_JAVACALLS_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/javaFrameAnchor.hpp
#ifndef SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
#define SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
#include "utilities/globalDefinitions.hpp"
#include "runtime/orderAccess.inline.hpp"
class JavaThread;
class JavaFrameAnchor VALUE_OBJ_CLASS_SPEC {
friend class CallNativeDirectNode;
friend class OptoRuntime;
friend class Runtime1;
friend class StubAssembler;
friend class CallRuntimeDirectNode;
friend class MacroAssembler;
friend class InterpreterGenerator;
friend class LIR_Assembler;
friend class GraphKit;
friend class StubGenerator;
friend class JavaThread;
friend class frame;
friend class VMStructs;
friend class BytecodeInterpreter;
friend class JavaCallWrapper;
 private:
  intptr_t* volatile _last_Java_sp;
  volatile  address _last_Java_pc;
  bool has_last_Java_frame() const                   { return _last_Java_sp != NULL; }
  void zap(void)                                     { _last_Java_sp = NULL; }
#ifdef TARGET_ARCH_x86
# include "javaFrameAnchor_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "javaFrameAnchor_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "javaFrameAnchor_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "javaFrameAnchor_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "javaFrameAnchor_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "javaFrameAnchor_ppc.hpp"
#endif
public:
  JavaFrameAnchor()                              { clear(); }
  JavaFrameAnchor(JavaFrameAnchor *src)          { copy(src); }
  void set_last_Java_pc(address pc)              { _last_Java_pc = pc; }
  static ByteSize last_Java_sp_offset()          { return byte_offset_of(JavaFrameAnchor, _last_Java_sp); }
  static ByteSize last_Java_pc_offset()          { return byte_offset_of(JavaFrameAnchor, _last_Java_pc); }
};
#endif // SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/jfieldIDWorkaround.hpp
#ifndef SHARE_VM_RUNTIME_JFIELDIDWORKAROUND_HPP
#define SHARE_VM_RUNTIME_JFIELDIDWORKAROUND_HPP
class jfieldIDWorkaround: AllStatic {
 private:
  enum {
    checked_bits           = 1,
    instance_bits          = 1,
    address_bits           = BitsPerWord - checked_bits - instance_bits,
    large_offset_bits      = address_bits,  // unioned with address
    small_offset_bits      = 7,
    klass_bits             = address_bits - small_offset_bits,
    checked_shift          = 0,
    instance_shift         = checked_shift  + checked_bits,
    address_shift          = instance_shift + instance_bits,
    offset_shift           = address_shift,  // unioned with address
    klass_shift            = offset_shift + small_offset_bits,
    checked_mask_in_place  = right_n_bits(checked_bits)  << checked_shift,
    instance_mask_in_place = right_n_bits(instance_bits) << instance_shift,
#ifndef _WIN64
    large_offset_mask      = right_n_bits(large_offset_bits),
    small_offset_mask      = right_n_bits(small_offset_bits),
    klass_mask             = right_n_bits(klass_bits)
#endif
    };
#ifdef _WIN64
    const static uintptr_t large_offset_mask = right_n_bits(large_offset_bits);
    const static uintptr_t small_offset_mask = right_n_bits(small_offset_bits);
    const static uintptr_t klass_mask        = right_n_bits(klass_bits);
#endif
  static bool is_checked_jfieldID(jfieldID id) {
    uintptr_t as_uint = (uintptr_t) id;
    return ((as_uint & checked_mask_in_place) != 0);
  }
  static intptr_t raw_instance_offset(jfieldID id) {
    uintptr_t result = (uintptr_t) id >> address_shift;
    if (VerifyJNIFields && is_checked_jfieldID(id)) {
      result &= small_offset_mask;  // cut off the hash bits
    }
    return (intptr_t)result;
  }
  static intptr_t encode_klass_hash(Klass* k, intptr_t offset);
  static bool             klass_hash_ok(Klass* k, jfieldID id);
  static void  verify_instance_jfieldID(Klass* k, jfieldID id);
 public:
  static bool is_valid_jfieldID(Klass* k, jfieldID id);
  static bool is_instance_jfieldID(Klass* k, jfieldID id) {
    uintptr_t as_uint = (uintptr_t) id;
    return ((as_uint & instance_mask_in_place) != 0);
  }
  static bool is_static_jfieldID(jfieldID id) {
    uintptr_t as_uint = (uintptr_t) id;
    return ((as_uint & instance_mask_in_place) == 0);
  }
  static jfieldID to_instance_jfieldID(Klass* k, int offset) {
    intptr_t as_uint = ((offset & large_offset_mask) << offset_shift) | instance_mask_in_place;
    if (VerifyJNIFields) {
      as_uint |= encode_klass_hash(k, offset);
    }
    jfieldID result = (jfieldID) as_uint;
#ifndef ASSERT
    if (VerifyJNIFields)
#endif // ASSERT
    {
      verify_instance_jfieldID(k, result);
    }
    assert(raw_instance_offset(result) == (offset & large_offset_mask), "extract right offset");
    return result;
  }
  static intptr_t from_instance_jfieldID(Klass* k, jfieldID id) {
#ifndef ASSERT
    if (VerifyJNIFields)
#endif // ASSERT
    {
      verify_instance_jfieldID(k, id);
    }
    return raw_instance_offset(id);
  }
  static jfieldID to_static_jfieldID(JNIid* id) {
    assert(id->is_static_field_id(), "from_JNIid, but not static field id");
    jfieldID result = (jfieldID) id;
    assert(from_static_jfieldID(result) == id, "must produce the same static id");
    return result;
  }
  static JNIid* from_static_jfieldID(jfieldID id) {
    assert(jfieldIDWorkaround::is_static_jfieldID(id),
           "to_JNIid, but not static jfieldID");
    JNIid* result = (JNIid*) id;
    assert(result->is_static_field_id(), "to_JNIid, but not static field id");
    return result;
  }
  static jfieldID to_jfieldID(instanceKlassHandle k, int offset, bool is_static) {
    if (is_static) {
      JNIid *id = k->jni_id_for(offset);
      debug_only(id->set_is_static_field_id());
      return jfieldIDWorkaround::to_static_jfieldID(id);
    } else {
      return jfieldIDWorkaround::to_instance_jfieldID(k(), offset);
    }
  }
};
#endif // SHARE_VM_RUNTIME_JFIELDIDWORKAROUND_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/jniHandles.cpp
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "memory/iterator.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
JNIHandleBlock* JNIHandles::_global_handles       = NULL;
JNIHandleBlock* JNIHandles::_weak_global_handles  = NULL;
oop             JNIHandles::_deleted_handle       = NULL;
jobject JNIHandles::make_local(oop obj) {
  if (obj == NULL) {
    return NULL;                // ignore null handles
  } else {
    Thread* thread = Thread::current();
    assert(Universe::heap()->is_in_reserved(obj), "sanity check");
    return thread->active_handles()->allocate_handle(obj);
  }
}
jobject JNIHandles::make_local(Thread* thread, oop obj) {
  if (obj == NULL) {
    return NULL;                // ignore null handles
  } else {
    assert(Universe::heap()->is_in_reserved(obj), "sanity check");
    return thread->active_handles()->allocate_handle(obj);
  }
}
jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
  if (obj == NULL) {
    return NULL;                // ignore null handles
  } else {
    JavaThread* thread = JavaThread::thread_from_jni_environment(env);
    assert(Universe::heap()->is_in_reserved(obj), "sanity check");
    return thread->active_handles()->allocate_handle(obj);
  }
}
jobject JNIHandles::make_global(Handle obj) {
  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
  jobject res = NULL;
  if (!obj.is_null()) {
    MutexLocker ml(JNIGlobalHandle_lock);
    assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
    res = _global_handles->allocate_handle(obj());
  } else {
    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
  }
  return res;
}
jobject JNIHandles::make_weak_global(Handle obj) {
  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
  jobject res = NULL;
  if (!obj.is_null()) {
    {
      MutexLocker ml(JNIGlobalHandle_lock);
      assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
      res = _weak_global_handles->allocate_handle(obj());
    }
    assert(is_ptr_aligned(res, weak_tag_alignment), "invariant");
    char* tptr = reinterpret_cast<char*>(res) + weak_tag_value;
    res = reinterpret_cast<jobject>(tptr);
  } else {
    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
  }
  return res;
}
template<bool external_guard>
oop JNIHandles::resolve_jweak(jweak handle) {
  assert(is_jweak(handle), "precondition");
  oop result = jweak_ref(handle);
  result = guard_value<external_guard>(result);
#if INCLUDE_ALL_GCS
  if (result != NULL && UseG1GC) {
    G1SATBCardTableModRefBS::enqueue(result);
  }
#endif // INCLUDE_ALL_GCS
  return result;
}
template oop JNIHandles::resolve_jweak<true>(jweak);
template oop JNIHandles::resolve_jweak<false>(jweak);
void JNIHandles::destroy_global(jobject handle) {
  if (handle != NULL) {
    assert(is_global_handle(handle), "Invalid delete of global JNI handle");
    jobject_ref(handle) = deleted_handle();
  }
}
void JNIHandles::destroy_weak_global(jobject handle) {
  if (handle != NULL) {
    jweak_ref(handle) = deleted_handle();
  }
}
void JNIHandles::oops_do(OopClosure* f) {
  f->do_oop(&_deleted_handle);
  _global_handles->oops_do(f);
}
void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
  _weak_global_handles->weak_oops_do(is_alive, f);
}
void JNIHandles::weak_oops_do(OopClosure* f) {
  AlwaysTrueClosure always_true;
  weak_oops_do(&always_true, f);
}
void JNIHandles::initialize() {
  _global_handles      = JNIHandleBlock::allocate_block();
  _weak_global_handles = JNIHandleBlock::allocate_block();
  EXCEPTION_MARK;
  Klass* k      = SystemDictionary::Object_klass();
  _deleted_handle = InstanceKlass::cast(k)->allocate_instance(CATCH);
}
bool JNIHandles::is_local_handle(Thread* thread, jobject handle) {
  JNIHandleBlock* block = thread->active_handles();
  while (block != NULL) {
    if (block->chain_contains(handle)) {
      return true;
    }
    block = block->pop_frame_link();
  }
  return false;
}
bool JNIHandles::is_frame_handle(JavaThread* thr, jobject obj) {
  return (thr->has_last_Java_frame() &&
         (void*)obj < (void*)thr->stack_base() &&
         (void*)obj >= (void*)thr->last_Java_sp());
}
bool JNIHandles::is_global_handle(jobject handle) {
  return _global_handles->chain_contains(handle);
}
bool JNIHandles::is_weak_global_handle(jobject handle) {
  return _weak_global_handles->chain_contains(handle);
}
long JNIHandles::global_handle_memory_usage() {
  return _global_handles->memory_usage();
}
long JNIHandles::weak_global_handle_memory_usage() {
  return _weak_global_handles->memory_usage();
}
class CountHandleClosure: public OopClosure {
private:
  int _count;
public:
  CountHandleClosure(): _count(0) {}
  virtual void do_oop(oop* ooph) {
    if (*ooph != JNIHandles::deleted_handle()) {
      _count++;
    }
  }
  virtual void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
  int count() { return _count; }
};
void JNIHandles::print_on(outputStream* st) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  assert(_global_handles != NULL && _weak_global_handles != NULL,
         "JNIHandles not initialized");
  CountHandleClosure global_handle_count;
  oops_do(&global_handle_count);
  weak_oops_do(&global_handle_count);
  st->print_cr("JNI global references: %d", global_handle_count.count());
  st->cr();
  st->flush();
}
class VerifyHandleClosure: public OopClosure {
public:
  virtual void do_oop(oop* root) {
    (*root)->verify();
  }
  virtual void do_oop(narrowOop* root) { ShouldNotReachHere(); }
};
void JNIHandles::verify() {
  VerifyHandleClosure verify_handle;
  oops_do(&verify_handle);
  weak_oops_do(&verify_handle);
}
void jni_handles_init() {
  JNIHandles::initialize();
}
int             JNIHandleBlock::_blocks_allocated     = 0;
JNIHandleBlock* JNIHandleBlock::_block_free_list      = NULL;
#ifndef PRODUCT
JNIHandleBlock* JNIHandleBlock::_block_list           = NULL;
#endif
void JNIHandleBlock::zap() {
  _top  = 0;
  for (int index = 0; index < block_size_in_oops; index++) {
    _handles[index] = badJNIHandle;
  }
}
JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread)  {
  assert(thread == NULL || thread == Thread::current(), "sanity check");
  JNIHandleBlock* block;
  if (thread != NULL && thread->free_handle_block() != NULL) {
    block = thread->free_handle_block();
    thread->set_free_handle_block(block->_next);
  }
  else {
    MutexLockerEx ml(JNIHandleBlockFreeList_lock,
                     Mutex::_no_safepoint_check_flag);
    if (_block_free_list == NULL) {
      block = new JNIHandleBlock();
      _blocks_allocated++;
      if (TraceJNIHandleAllocation) {
        tty->print_cr("JNIHandleBlock " INTPTR_FORMAT " allocated (%d total blocks)",
                      block, _blocks_allocated);
      }
      if (ZapJNIHandleArea) block->zap();
      #ifndef PRODUCT
      block->_block_list_link = _block_list;
      _block_list = block;
      #endif
    } else {
      block = _block_free_list;
      _block_free_list = _block_free_list->_next;
    }
  }
  block->_top  = 0;
  block->_next = NULL;
  block->_pop_frame_link = NULL;
  block->_planned_capacity = block_size_in_oops;
  debug_only(block->_last = NULL);
  debug_only(block->_free_list = NULL);
  debug_only(block->_allocate_before_rebuild = -1);
  return block;
}
void JNIHandleBlock::release_block(JNIHandleBlock* block, Thread* thread) {
  assert(thread == NULL || thread == Thread::current(), "sanity check");
  JNIHandleBlock* pop_frame_link = block->pop_frame_link();
  if (thread != NULL ) {
    if (ZapJNIHandleArea) block->zap();
    JNIHandleBlock* freelist = thread->free_handle_block();
    block->_pop_frame_link = NULL;
    thread->set_free_handle_block(block);
    if ( freelist != NULL ) {
      while ( block->_next != NULL ) block = block->_next;
      block->_next = freelist;
    }
    block = NULL;
  }
  if (block != NULL) {
    MutexLockerEx ml(JNIHandleBlockFreeList_lock,
                     Mutex::_no_safepoint_check_flag);
    while (block != NULL) {
      if (ZapJNIHandleArea) block->zap();
      JNIHandleBlock* next = block->_next;
      block->_next = _block_free_list;
      _block_free_list = block;
      block = next;
    }
  }
  if (pop_frame_link != NULL) {
    release_block(pop_frame_link, thread);
  }
}
void JNIHandleBlock::oops_do(OopClosure* f) {
  JNIHandleBlock* current_chain = this;
  while (current_chain != NULL) {
    for (JNIHandleBlock* current = current_chain; current != NULL;
         current = current->_next) {
      assert(current == current_chain || current->pop_frame_link() == NULL,
        "only blocks first in chain should have pop frame link set");
      for (int index = 0; index < current->_top; index++) {
        oop* root = &(current->_handles)[index];
        oop value = *root;
        if (value != NULL && Universe::heap()->is_in_reserved(value)) {
          f->do_oop(root);
        }
      }
      if (current->_top < block_size_in_oops) {
        break;
      }
    }
    current_chain = current_chain->pop_frame_link();
  }
}
void JNIHandleBlock::weak_oops_do(BoolObjectClosure* is_alive,
                                  OopClosure* f) {
  for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
    assert(current->pop_frame_link() == NULL,
      "blocks holding weak global JNI handles should not have pop frame link set");
    for (int index = 0; index < current->_top; index++) {
      oop* root = &(current->_handles)[index];
      oop value = *root;
      if (value != NULL && Universe::heap()->is_in_reserved(value)) {
        if (is_alive->do_object_b(value)) {
          f->do_oop(root);
        } else {
          if (TraceReferenceGC) {
            tty->print_cr("Clearing JNI weak reference (" INTPTR_FORMAT ")", root);
          }
        }
      }
    }
    if (current->_top < block_size_in_oops) {
      break;
    }
  }
  JvmtiExport::weak_oops_do(is_alive, f);
}
jobject JNIHandleBlock::allocate_handle(oop obj) {
  assert(Universe::heap()->is_in_reserved(obj), "sanity check");
  if (_top == 0) {
    for (JNIHandleBlock* current = _next; current != NULL;
         current = current->_next) {
      assert(current->_last == NULL, "only first block should have _last set");
      assert(current->_free_list == NULL,
             "only first block should have _free_list set");
      current->_top = 0;
      if (ZapJNIHandleArea) current->zap();
    }
    _free_list = NULL;
    _allocate_before_rebuild = 0;
    _last = this;
    if (ZapJNIHandleArea) zap();
  }
  if (_last->_top < block_size_in_oops) {
    oop* handle = &(_last->_handles)[_last->_top++];
    return (jobject) handle;
  }
  if (_free_list != NULL) {
    oop* handle = _free_list;
    _free_list = (oop*) *_free_list;
    return (jobject) handle;
  }
  if (_last->_next != NULL) {
    _last = _last->_next;
    return allocate_handle(obj);
  }
  if (_allocate_before_rebuild == 0) {
      rebuild_free_list();        // updates _allocate_before_rebuild counter
  } else {
    Thread* thread = Thread::current();
    Handle obj_handle(thread, obj);
    _last->_next = JNIHandleBlock::allocate_block(thread);
    _last = _last->_next;
    _allocate_before_rebuild--;
    obj = obj_handle();
  }
  return allocate_handle(obj);  // retry
}
void JNIHandleBlock::rebuild_free_list() {
  assert(_allocate_before_rebuild == 0 && _free_list == NULL, "just checking");
  int free = 0;
  int blocks = 0;
  for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
    for (int index = 0; index < current->_top; index++) {
      oop* handle = &(current->_handles)[index];
      if (*handle ==  JNIHandles::deleted_handle()) {
        _free_list = handle;
        free++;
      }
    }
    assert(current->_top == block_size_in_oops, "just checking");
    blocks++;
  }
  int total = blocks * block_size_in_oops;
  int extra = total - 2*free;
  if (extra > 0) {
    _allocate_before_rebuild = (extra + block_size_in_oops - 1) / block_size_in_oops;
  }
  if (TraceJNIHandleAllocation) {
    tty->print_cr("Rebuild free list JNIHandleBlock " INTPTR_FORMAT " blocks=%d used=%d free=%d add=%d",
      this, blocks, total-free, free, _allocate_before_rebuild);
  }
}
bool JNIHandleBlock::contains(jobject handle) const {
  return ((jobject)&_handles[0] <= handle && handle<(jobject)&_handles[_top]);
}
bool JNIHandleBlock::chain_contains(jobject handle) const {
  for (JNIHandleBlock* current = (JNIHandleBlock*) this; current != NULL; current = current->_next) {
    if (current->contains(handle)) {
      return true;
    }
  }
  return false;
}
int JNIHandleBlock::length() const {
  int result = 1;
  for (JNIHandleBlock* current = _next; current != NULL; current = current->_next) {
    result++;
  }
  return result;
}
const size_t JNIHandleBlock::get_number_of_live_handles() {
  CountHandleClosure counter;
  oops_do(&counter);
  return counter.count();
}
long JNIHandleBlock::memory_usage() const {
  return length() * sizeof(JNIHandleBlock);
}
#ifndef PRODUCT
bool JNIHandleBlock::any_contains(jobject handle) {
  for (JNIHandleBlock* current = _block_list; current != NULL; current = current->_block_list_link) {
    if (current->contains(handle)) {
      return true;
    }
  }
  return false;
}
void JNIHandleBlock::print_statistics() {
  int used_blocks = 0;
  int free_blocks = 0;
  int used_handles = 0;
  int free_handles = 0;
  JNIHandleBlock* block = _block_list;
  while (block != NULL) {
    if (block->_top > 0) {
      used_blocks++;
    } else {
      free_blocks++;
    }
    used_handles += block->_top;
    free_handles += (block_size_in_oops - block->_top);
    block = block->_block_list_link;
  }
  tty->print_cr("JNIHandleBlocks statistics");
  tty->print_cr("- blocks allocated: %d", used_blocks + free_blocks);
  tty->print_cr("- blocks in use:    %d", used_blocks);
  tty->print_cr("- blocks free:      %d", free_blocks);
  tty->print_cr("- handles in use:   %d", used_handles);
  tty->print_cr("- handles free:     %d", free_handles);
}
#endif
C:\hotspot-69087d08d473\src\share\vm/runtime/jniHandles.hpp
#ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP
#define SHARE_VM_RUNTIME_JNIHANDLES_HPP
#include "runtime/handles.hpp"
#include "utilities/top.hpp"
class JNIHandleBlock;
class JNIHandles : AllStatic {
  friend class VMStructs;
 private:
  static JNIHandleBlock* _global_handles;             // First global handle block
  static JNIHandleBlock* _weak_global_handles;        // First weak global handle block
  static oop _deleted_handle;                         // Sentinel marking deleted handles
  inline static bool is_jweak(jobject handle);
  inline static oop& jobject_ref(jobject handle); // NOT jweak!
  inline static oop& jweak_ref(jobject handle);
  template<bool external_guard> inline static oop guard_value(oop value);
  template<bool external_guard> inline static oop resolve_impl(jobject handle);
  template<bool external_guard> static oop resolve_jweak(jweak handle);
 public:
  static const uintptr_t weak_tag_size = 1;
  static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
  static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
  static const int weak_tag_value = 1;
  inline static oop resolve(jobject handle);
  inline static oop resolve_external_guard(jobject handle);
  inline static oop resolve_non_null(jobject handle);
  static jobject make_local(oop obj);
  static jobject make_local(JNIEnv* env, oop obj);    // Fast version when env is known
  static jobject make_local(Thread* thread, oop obj); // Even faster version when current thread is known
  inline static void destroy_local(jobject handle);
  static jobject make_global(Handle  obj);
  static void destroy_global(jobject handle);
  static jobject make_weak_global(Handle obj);
  static void destroy_weak_global(jobject handle);
  static oop deleted_handle()   { return _deleted_handle; }
  static void initialize();
  static void print_on(outputStream* st);
  static void print()           { print_on(tty); }
  static void verify();
  static bool is_local_handle(Thread* thread, jobject handle);
  static bool is_frame_handle(JavaThread* thr, jobject obj);
  static bool is_global_handle(jobject handle);
  static bool is_weak_global_handle(jobject handle);
  static long global_handle_memory_usage();
  static long weak_global_handle_memory_usage();
  static void oops_do(OopClosure* f);
  static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
  static void weak_oops_do(OopClosure* f);
};

class JNIHandleBlock : public CHeapObj<mtInternal> {
  friend class VMStructs;
  friend class CppInterpreter;
 private:
  enum SomeConstants {
    block_size_in_oops  = 32                    // Number of handles per handle block
  };
  oop             _handles[block_size_in_oops]; // The handles
  int             _top;                         // Index of next unused handle
  JNIHandleBlock* _next;                        // Link to next block
  JNIHandleBlock* _last;                        // Last block in use
  JNIHandleBlock* _pop_frame_link;              // Block to restore on PopLocalFrame call
  oop*            _free_list;                   // Handle free list
  int             _allocate_before_rebuild;     // Number of blocks to allocate before rebuilding free list
  size_t          _planned_capacity;
  #ifndef PRODUCT
  JNIHandleBlock* _block_list_link;             // Link for list below
  static JNIHandleBlock* _block_list;           // List of all allocated blocks (for debugging only)
  #endif
  static JNIHandleBlock* _block_free_list;      // Free list of currently unused blocks
  static int      _blocks_allocated;            // For debugging/printing
  void zap();
 protected:
  void clear() { _top = 0; }
 private:
  void rebuild_free_list();
 public:
  jobject allocate_handle(oop obj);
  static JNIHandleBlock* allocate_block(Thread* thread = NULL);
  static void release_block(JNIHandleBlock* block, Thread* thread = NULL);
  JNIHandleBlock* pop_frame_link() const          { return _pop_frame_link; }
  void set_pop_frame_link(JNIHandleBlock* block)  { _pop_frame_link = block; }
  static int top_offset_in_bytes()                { return offset_of(JNIHandleBlock, _top); }
  void oops_do(OopClosure* f);
  void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
  void set_planned_capacity(size_t planned_capacity) { _planned_capacity = planned_capacity; }
  const size_t get_planned_capacity() { return _planned_capacity; }
  const size_t get_number_of_live_handles();
  bool chain_contains(jobject handle) const;    // Does this block or following blocks contain handle
  bool contains(jobject handle) const;          // Does this block contain handle
  int length() const;                           // Length of chain starting with this block
  long memory_usage() const;
  #ifndef PRODUCT
  static bool any_contains(jobject handle);     // Does any block currently in use contain handle
  static void print_statistics();
  #endif
};
inline bool JNIHandles::is_jweak(jobject handle) {
  STATIC_ASSERT(weak_tag_size == 1);
  STATIC_ASSERT(weak_tag_value == 1);
  return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0;
}
inline oop& JNIHandles::jobject_ref(jobject handle) {
  assert(!is_jweak(handle), "precondition");
  return *reinterpret_cast<oop*>(handle);
}
inline oop& JNIHandles::jweak_ref(jobject handle) {
  assert(is_jweak(handle), "precondition");
  char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value;
  return *reinterpret_cast<oop*>(ptr);
}
template<bool external_guard>
inline oop JNIHandles::guard_value(oop value) {
  if (!external_guard) {
    assert(value != badJNIHandle, "Pointing to zapped jni handle area");
    assert(value != deleted_handle(), "Used a deleted global handle");
  } else if ((value == badJNIHandle) || (value == deleted_handle())) {
    value = NULL;
  }
  return value;
}
template<bool external_guard>
inline oop JNIHandles::resolve_impl(jobject handle) {
  assert(handle != NULL, "precondition");
  oop result;
  if (is_jweak(handle)) {       // Unlikely
    result = resolve_jweak<external_guard>(handle);
  } else {
    result = jobject_ref(handle);
    assert(external_guard || result != NULL,
           "Invalid value read from jni handle");
    result = guard_value<external_guard>(result);
  }
  return result;
}
inline oop JNIHandles::resolve(jobject handle) {
  oop result = NULL;
  if (handle != NULL) {
    result = resolve_impl<false /* external_guard */ >(handle);
  }
  return result;
}
inline oop JNIHandles::resolve_external_guard(jobject handle) {
  oop result = NULL;
  if (handle != NULL) {
    result = resolve_impl<true /* external_guard */ >(handle);
  }
  return result;
}
inline oop JNIHandles::resolve_non_null(jobject handle) {
  assert(handle != NULL, "JNI handle should not be null");
  oop result = resolve_impl<false /* external_guard */ >(handle);
  assert(result != NULL, "NULL read from jni handle");
  return result;
}
inline void JNIHandles::destroy_local(jobject handle) {
  if (handle != NULL) {
    jobject_ref(handle) = deleted_handle();
  }
}
#endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/jniPeriodicChecker.cpp
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/jniPeriodicChecker.hpp"
#include "runtime/task.hpp"
class JniPeriodicCheckerTask : public PeriodicTask {
  public:
     JniPeriodicCheckerTask(int interval_time) : PeriodicTask(interval_time) {}
     void task() { os::run_periodic_checks(); }
     static void engage();
     static void disengage();
};
JniPeriodicCheckerTask*              JniPeriodicChecker::_task   = NULL;
void JniPeriodicChecker::engage() {
  if (CheckJNICalls && !is_active()) {
    _task = new JniPeriodicCheckerTask(10);
    _task->enroll();
  }
}
void JniPeriodicChecker::disengage() {
  if (CheckJNICalls && is_active()) {
    _task->disenroll();
    delete _task;
    _task = NULL;
  }
}
void jniPeriodicChecker_exit() {
  if (!CheckJNICalls) return;
}
C:\hotspot-69087d08d473\src\share\vm/runtime/jniPeriodicChecker.hpp
#ifndef SHARE_VM_RUNTIME_JNIPERIODICCHECKER_HPP
#define SHARE_VM_RUNTIME_JNIPERIODICCHECKER_HPP
class JniPeriodicCheckerTask;
class JniPeriodicChecker : AllStatic {
  friend class JniPeriodicCheckerTask;
  private:
    static JniPeriodicCheckerTask* _task;
  public:
    static void engage();
    static void disengage();
    static bool is_active() { return _task != NULL; }
    static void initialize();
    static void destroy();
};
void jniPeriodicChecker_exit();
#endif // SHARE_VM_RUNTIME_JNIPERIODICCHECKER_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/memprofiler.cpp
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/oopMapCache.hpp"
#include "memory/generation.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/memprofiler.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/task.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#ifndef PRODUCT
class MemProfilerTask : public PeriodicTask {
 public:
  MemProfilerTask(int interval_time) : PeriodicTask(interval_time) {}
  void task();
};
void MemProfilerTask::task() {
  MutexLocker mu(Threads_lock);
  MemProfiler::do_trace();
}
MemProfilerTask* MemProfiler::_task   = NULL;
FILE*            MemProfiler::_log_fp = NULL;
bool MemProfiler::is_active() {
  return _task != NULL;
}
void MemProfiler::engage() {
  const char *log_name = "mprofile.log";
  if (!is_active()) {
    _log_fp = fopen(log_name , "w+");
    if (_log_fp == NULL) {
      fatal(err_msg("MemProfiler: Cannot create log file: %s", log_name));
    }
    fprintf(_log_fp, "MemProfiler: sizes are in Kb, time is in seconds since startup\n\n");
    fprintf(_log_fp, "  time, #thr, #cls,  heap,  heap,  perm,  perm,  code, hndls, rescs, oopmp\n");
    fprintf(_log_fp, "                     used, total,  used, total, total, total, total, total\n");
    fprintf(_log_fp, "--------------------------------------------------------------------------\n");
    _task = new MemProfilerTask(MemProfilingInterval);
    _task->enroll();
  }
}
void MemProfiler::disengage() {
  if (!is_active()) return;
  do_trace();
  fprintf(_log_fp, "MemProfiler detached\n");
  fclose(_log_fp);
  assert(_task != NULL, "sanity check");
  _task->disenroll();
  delete _task;
  _task = NULL;
}
void MemProfiler::do_trace() {
  size_t handles_memory_usage    = VMThread::vm_thread()->handle_area()->size_in_bytes();
  size_t resource_memory_usage   = VMThread::vm_thread()->resource_area()->size_in_bytes();
  JavaThread *cur = Threads::first();
  while (cur != NULL) {
    handles_memory_usage  += cur->handle_area()->size_in_bytes();
    resource_memory_usage += cur->resource_area()->size_in_bytes();
    cur = cur->next();
  }
  fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
          os::elapsedTime(),
          Threads::number_of_threads(),
          SystemDictionary::number_of_classes(),
          Universe::heap()->used() / K,
          Universe::heap()->capacity() / K);
  fprintf(_log_fp, UINTX_FORMAT_W(6) ",", CodeCache::capacity() / K);
  fprintf(_log_fp, UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) "\n",
          handles_memory_usage / K,
          resource_memory_usage / K,
          OopMapCache::memory_usage() / K);
  fflush(_log_fp);
}
#endif
C:\hotspot-69087d08d473\src\share\vm/runtime/memprofiler.hpp
#ifndef SHARE_VM_RUNTIME_MEMPROFILER_HPP
#define SHARE_VM_RUNTIME_MEMPROFILER_HPP
class MemProfilerTask;
class MemProfiler : AllStatic {
 friend class MemProfilerTask;
 private:
  static MemProfilerTask* _task;
  static FILE* _log_fp;
  static void do_trace()      PRODUCT_RETURN;
 public:
  static void engage()        PRODUCT_RETURN;
  static void disengage()     PRODUCT_RETURN;
  static bool is_active()     PRODUCT_RETURN0;
};
#endif // SHARE_VM_RUNTIME_MEMPROFILER_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/monitorChunk.cpp
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/monitorChunk.hpp"
MonitorChunk::MonitorChunk(int number_on_monitors) {
  _number_of_monitors = number_on_monitors;
  _monitors           = NEW_C_HEAP_ARRAY(BasicObjectLock, number_on_monitors, mtInternal);
  _next               = NULL;
}
MonitorChunk::~MonitorChunk() {
  FreeHeap(monitors());
}
void MonitorChunk::oops_do(OopClosure* f) {
  for (int index = 0; index < number_of_monitors(); index++) {
    at(index)->oops_do(f);
  }
}
C:\hotspot-69087d08d473\src\share\vm/runtime/monitorChunk.hpp
#ifndef SHARE_VM_RUNTIME_MONITORCHUNK_HPP
#define SHARE_VM_RUNTIME_MONITORCHUNK_HPP
#include "runtime/synchronizer.hpp"
class MonitorChunk: public CHeapObj<mtInternal> {
 private:
  int              _number_of_monitors;
  BasicObjectLock* _monitors;
  BasicObjectLock* monitors() const { return _monitors; }
  MonitorChunk*    _next;
 public:
  MonitorChunk(int number_on_monitors);
  ~MonitorChunk();
  MonitorChunk* next() const                { return _next; }
  void set_next(MonitorChunk* next)         { _next = next; }
  bool is_linked() const                    { return next() != NULL; }
  int number_of_monitors() const { return _number_of_monitors; }
  BasicObjectLock* at(int index)            { assert(index >= 0 && index < number_of_monitors(), "out of bounds check"); return &monitors()[index]; }
  void oops_do(OopClosure* f);
  bool contains(void* addr) const           { return (addr >= (void*) monitors()) && (addr <  (void*) (monitors() + number_of_monitors())); }
};
#endif // SHARE_VM_RUNTIME_MONITORCHUNK_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/mutex.cpp
#include "precompiled.hpp"
#include "runtime/mutex.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/thread.inline.hpp"
#include "utilities/events.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "mutex_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "mutex_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "mutex_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "mutex_bsd.inline.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
#define CASPTR(a,c,s) intptr_t(Atomic::cmpxchg_ptr ((void *)(s),(void *)(a),(void *)(c)))
#define UNS(x) (uintptr_t(x))
#define TRACE(m) { static volatile int ctr = 0 ; int x = ++ctr ; if ((x & (x-1))==0) { ::printf ("%d:%s\n", x, #m); ::fflush(stdout); }}
static inline jint MarsagliaXORV (jint x) {
  if (x == 0) x = 1|os::random() ;
  x ^= x << 6;
  x ^= ((unsigned)x) >> 21;
  x ^= x << 7 ;
  return x & 0x7FFFFFFF ;
}
static int Stall (int its) {
  static volatile jint rv = 1 ;
  volatile int OnFrame = 0 ;
  jint v = rv ^ UNS(OnFrame) ;
  while (--its >= 0) {
    v = MarsagliaXORV (v) ;
  }
  if (v == 0x12345) rv = v ;
  return v ;
}
int Monitor::TryLock () {
  intptr_t v = _LockWord.FullWord ;
  for (;;) {
    if ((v & _LBIT) != 0) return 0 ;
    const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ;
    if (v == u) return 1 ;
    v = u ;
  }
}
int Monitor::TryFast () {
  intptr_t v = CASPTR (&_LockWord, 0, _LBIT) ;  // agro ...
  if (v == 0) return 1 ;
  for (;;) {
    if ((v & _LBIT) != 0) return 0 ;
    const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ;
    if (v == u) return 1 ;
    v = u ;
  }
}
int Monitor::ILocked () {
  const intptr_t w = _LockWord.FullWord & 0xFF ;
  assert (w == 0 || w == _LBIT, "invariant") ;
  return w == _LBIT ;
}
int Monitor::TrySpin (Thread * const Self) {
  if (TryLock())    return 1 ;
  if (!os::is_MP()) return 0 ;
  int Probes  = 0 ;
  int Delay   = 0 ;
  int Steps   = 0 ;
  int SpinMax = NativeMonitorSpinLimit ;
  int flgs    = NativeMonitorFlags ;
  for (;;) {
    intptr_t v = _LockWord.FullWord;
    if ((v & _LBIT) == 0) {
      if (CASPTR (&_LockWord, v, v|_LBIT) == v) {
        return 1 ;
      }
      continue ;
    }
    if ((flgs & 8) == 0) {
      SpinPause () ;
    }
    ++ Probes;
    if (Probes > SpinMax) return 0 ;
    if ((Probes & 0x7) == 0) {
      Delay = ((Delay << 1)|1) & 0x7FF ;
    }
    if (flgs & 2) continue ;
    Steps += Delay ;
    if (Self != NULL) {
      jint rv = Self->rng[0] ;
      for (int k = Delay ; --k >= 0; ) {
        rv = MarsagliaXORV (rv) ;
        if ((flgs & 4) == 0 && SafepointSynchronize::do_call_back()) return 0 ;
      }
      Self->rng[0] = rv ;
    } else {
      Stall (Delay) ;
    }
  }
}
static int ParkCommon (ParkEvent * ev, jlong timo) {
  intx nmt = NativeMonitorTimeout ;
  if (nmt > 0 && (nmt < timo || timo <= 0)) {
     timo = nmt ;
  }
  int err = OS_OK ;
  if (0 == timo) {
    ev->park() ;
  } else {
    err = ev->park(timo) ;
  }
  return err ;
}
inline int Monitor::AcquireOrPush (ParkEvent * ESelf) {
  intptr_t v = _LockWord.FullWord ;
  for (;;) {
    if ((v & _LBIT) == 0) {
      const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ;
      if (u == v) return 1 ;        // indicate acquired
      v = u ;
    } else {
      ESelf->ListNext = (ParkEvent *) (v & ~_LBIT) ;
      const intptr_t u = CASPTR (&_LockWord, v, intptr_t(ESelf)|_LBIT) ;
      if (u == v) return 0 ;        // indicate pushed onto cxq
      v = u ;
    }
  }
}
void Monitor::ILock (Thread * Self) {
  assert (_OnDeck != Self->_MutexEvent, "invariant") ;
  if (TryFast()) {
 Exeunt:
    assert (ILocked(), "invariant") ;
    return ;
  }
  ParkEvent * const ESelf = Self->_MutexEvent ;
  assert (_OnDeck != ESelf, "invariant") ;
  if (TrySpin (Self)) goto Exeunt ;
  ESelf->reset() ;
  OrderAccess::fence() ;
  if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(Self)) == 0) {
    goto OnDeck_LOOP ;
  }
  if (AcquireOrPush (ESelf)) goto Exeunt ;
  while (_OnDeck != ESelf) {
    ParkCommon (ESelf, 0) ;
  }
 OnDeck_LOOP:
  for (;;) {
    assert (_OnDeck == ESelf, "invariant") ;
    if (TrySpin (Self)) break ;
    ParkCommon (ESelf, 0) ;
  }
  assert (_OnDeck == ESelf, "invariant") ;
  _OnDeck = NULL ;
  goto Exeunt ;
}
void Monitor::IUnlock (bool RelaxAssert) {
  assert (ILocked(), "invariant") ;
  OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock
  OrderAccess::storeload ();
  ParkEvent * const w = _OnDeck ;
  assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ;
  if (w != NULL) {
    if ((UNS(w) & _LBIT) == 0) w->unpark() ;
    return ;
  }
  intptr_t cxq = _LockWord.FullWord ;
  if (((cxq & ~_LBIT)|UNS(_EntryList)) == 0) {
    return ;      // normal fast-path exit - cxq and EntryList both empty
  }
  if (cxq & _LBIT) {
    return ;
  }
 Succession:
  if (CASPTR (&_OnDeck, NULL, _LBIT) != UNS(NULL)) {
    return ;
  }
  ParkEvent * List = _EntryList ;
  if (List != NULL) {
   WakeOne:
    assert (List == _EntryList, "invariant") ;
    ParkEvent * const w = List ;
    assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ;
    _EntryList = w->ListNext ;
    assert (UNS(_OnDeck) == _LBIT, "invariant") ;
    _OnDeck = w ;           // pass OnDeck to w.
    OrderAccess::storeload() ;
    cxq = _LockWord.FullWord ;
    if (cxq & _LBIT) return ;
    w->unpark() ;
    return ;
  }
  cxq = _LockWord.FullWord ;
  if ((cxq & ~_LBIT) != 0) {
    for (;;) {
      if (cxq & _LBIT) goto Punt ;
      const intptr_t vfy = CASPTR (&_LockWord, cxq, cxq & _LBIT) ;
      if (vfy == cxq) break ;
      cxq = vfy ;
    }
    assert (_EntryList == NULL, "invariant") ;
    _EntryList = List = (ParkEvent *)(cxq & ~_LBIT) ;
    assert (List != NULL, "invariant") ;
    goto WakeOne ;
  }
 Punt:
  assert (UNS(_OnDeck) == _LBIT, "invariant") ;
  _OnDeck = NULL ;            // Release inner lock.
  OrderAccess::storeload();   // Dekker duality - pivot point
  cxq = _LockWord.FullWord ;
  if ((cxq & ~_LBIT) != 0 && (cxq & _LBIT) == 0) {
    goto Succession ;         // potential race -- re-run succession
  }
  return ;
}
bool Monitor::notify() {
  assert (_owner == Thread::current(), "invariant") ;
  assert (ILocked(), "invariant") ;
  if (_WaitSet == NULL) return true ;
  NotifyCount ++ ;
  Thread::muxAcquire (_WaitLock, "notify:WaitLock") ;
  ParkEvent * nfy = _WaitSet ;
  if (nfy != NULL) {                  // DCL idiom
    _WaitSet = nfy->ListNext ;
    assert (nfy->Notified == 0, "invariant") ;
    for (;;) {
      const intptr_t v = _LockWord.FullWord ;
      assert ((v & 0xFF) == _LBIT, "invariant") ;
      nfy->ListNext = (ParkEvent *)(v & ~_LBIT);
      if (CASPTR (&_LockWord, v, UNS(nfy)|_LBIT) == v) break;
    }
    OrderAccess::fence() ;
    nfy->Notified = 1;
  }
  Thread::muxRelease (_WaitLock) ;
  if (nfy != NULL && (NativeMonitorFlags & 16)) {
    nfy->unpark() ;
  }
  assert (ILocked(), "invariant") ;
  return true ;
}
bool Monitor::notify_all() {
  assert (_owner == Thread::current(), "invariant") ;
  assert (ILocked(), "invariant") ;
  while (_WaitSet != NULL) notify() ;
  return true ;
}
int Monitor::IWait (Thread * Self, jlong timo) {
  assert (ILocked(), "invariant") ;
  ParkEvent * const ESelf = Self->_MutexEvent ;
  ESelf->Notified = 0 ;
  ESelf->reset() ;
  OrderAccess::fence() ;
  Thread::muxAcquire (_WaitLock, "wait:WaitLock:Add") ;
  ESelf->ListNext = _WaitSet ;
  _WaitSet = ESelf ;
  Thread::muxRelease (_WaitLock) ;
  IUnlock (true) ;
  for (;;) {
    if (ESelf->Notified) break ;
    int err = ParkCommon (ESelf, timo) ;
    if (err == OS_TIMEOUT || (NativeMonitorFlags & 1)) break ;
  }
  OrderAccess::fence() ;
  int WasOnWaitSet = 0 ;
  if (ESelf->Notified == 0) {
    Thread::muxAcquire (_WaitLock, "wait:WaitLock:remove") ;
    if (ESelf->Notified == 0) {     // DCL idiom
      assert (_OnDeck != ESelf, "invariant") ;   // can't be both OnDeck and on WaitSet
      ParkEvent * p = _WaitSet ;
      ParkEvent * q = NULL ;            // classic q chases p
      while (p != NULL && p != ESelf) {
        q = p ;
        p = p->ListNext ;
      }
      assert (p == ESelf, "invariant") ;
      if (p == _WaitSet) {      // found at head
        assert (q == NULL, "invariant") ;
        _WaitSet = p->ListNext ;
      } else {                  // found in interior
        assert (q->ListNext == p, "invariant") ;
        q->ListNext = p->ListNext ;
      }
      WasOnWaitSet = 1 ;        // We were *not* notified but instead encountered timeout
    }
    Thread::muxRelease (_WaitLock) ;
  }
  if (WasOnWaitSet) {
    assert (_OnDeck != ESelf, "invariant") ;
    ILock (Self) ;
  } else {
    for (;;) {
      if (_OnDeck == ESelf && TrySpin(Self)) break ;
      ParkCommon (ESelf, 0) ;
    }
    assert (_OnDeck == ESelf, "invariant") ;
    _OnDeck = NULL ;
  }
  assert (ILocked(), "invariant") ;
  return WasOnWaitSet != 0 ;        // return true IFF timeout
}
void Monitor::lock (Thread * Self) {
#ifdef CHECK_UNHANDLED_OOPS
  if (Self->is_Java_thread()) {
    Self->clear_unhandled_oops();
  }
#endif // CHECK_UNHANDLED_OOPS
  debug_only(check_prelock_state(Self));
  assert (_owner != Self              , "invariant") ;
  assert (_OnDeck != Self->_MutexEvent, "invariant") ;
  if (TryFast()) {
 Exeunt:
    assert (ILocked(), "invariant") ;
    assert (owner() == NULL, "invariant");
    set_owner (Self);
    return ;
  }
  bool can_sneak = Self->is_VM_thread() && SafepointSynchronize::is_at_safepoint();
  if (can_sneak && _owner == NULL) {
    _snuck = true;
    goto Exeunt ;
  }
  if (TrySpin (Self)) goto Exeunt ;
  check_block_state(Self);
  if (Self->is_Java_thread()) {
    assert(rank() > Mutex::special, "Potential deadlock with special or lesser rank mutex");
    ThreadBlockInVM tbivm ((JavaThread *) Self) ;
    ILock (Self) ;
  } else {
    ILock (Self) ;
  }
  goto Exeunt ;
}
void Monitor::lock() {
  this->lock(Thread::current());
}
void Monitor::lock_without_safepoint_check (Thread * Self) {
  assert (_owner != Self, "invariant") ;
  ILock (Self) ;
  assert (_owner == NULL, "invariant");
  set_owner (Self);
}
void Monitor::lock_without_safepoint_check () {
  lock_without_safepoint_check (Thread::current()) ;
}
bool Monitor::try_lock() {
  Thread * const Self = Thread::current();
  debug_only(check_prelock_state(Self));
  bool can_sneak = Self->is_VM_thread() && SafepointSynchronize::is_at_safepoint();
  if (can_sneak && _owner == NULL) {
    set_owner(Self); // Do not need to be atomic, since we are at a safepoint
    _snuck = true;
    return true;
  }
  if (TryLock()) {
    assert (_owner == NULL, "invariant");
    set_owner (Self);
    return true;
  }
  return false;
}
void Monitor::unlock() {
  assert (_owner  == Thread::current(), "invariant") ;
  assert (_OnDeck != Thread::current()->_MutexEvent , "invariant") ;
  set_owner (NULL) ;
  if (_snuck) {
    assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), "sneak");
    _snuck = false;
    return ;
  }
  IUnlock (false) ;
}
void Monitor::jvm_raw_lock() {
  assert(rank() == native, "invariant");
  if (TryLock()) {
 Exeunt:
    assert (ILocked(), "invariant") ;
    assert (_owner == NULL, "invariant");
    _owner = ThreadLocalStorage::thread();
    return ;
  }
  if (TrySpin(NULL)) goto Exeunt ;
  ParkEvent * const ESelf = ParkEvent::Allocate(NULL) ;
  ESelf->reset() ;
  OrderAccess::storeload() ;
  if (AcquireOrPush (ESelf)) {
    ParkEvent::Release (ESelf) ;      // surrender the ParkEvent
    goto Exeunt ;
  }
  for (;;) {
    if (_OnDeck == ESelf && TrySpin(NULL)) break ;
    ParkCommon (ESelf, 0) ;
  }
  assert (_OnDeck == ESelf, "invariant") ;
  _OnDeck = NULL ;
  ParkEvent::Release (ESelf) ;      // surrender the ParkEvent
  goto Exeunt ;
}
void Monitor::jvm_raw_unlock() {
  _owner = NULL ;
  if (_snuck) {         // ???
    assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), "sneak");
    _snuck = false;
    return ;
  }
  IUnlock(false) ;
}
bool Monitor::wait(bool no_safepoint_check, long timeout, bool as_suspend_equivalent) {
  Thread * const Self = Thread::current() ;
  assert (_owner == Self, "invariant") ;
  assert (ILocked(), "invariant") ;
  guarantee (!as_suspend_equivalent || !no_safepoint_check, "invariant") ;
  guarantee (no_safepoint_check || Self->is_Java_thread(), "invariant") ;
  #ifdef ASSERT
    Monitor * least = get_least_ranked_lock_besides_this(Self->owned_locks());
    assert(least != this, "Specification of get_least_... call above");
    if (least != NULL && least->rank() <= special) {
      tty->print("Attempting to wait on monitor %s/%d while holding"
                 " lock %s/%d -- possible deadlock",
                 name(), rank(), least->name(), least->rank());
      assert(false, "Shouldn't block(wait) while holding a lock of rank special");
    }
  #endif // ASSERT
  int wait_status ;
  set_owner(NULL);
  if (no_safepoint_check) {
    wait_status = IWait (Self, timeout) ;
  } else {
    assert (Self->is_Java_thread(), "invariant") ;
    JavaThread *jt = (JavaThread *)Self;
    ThreadBlockInVM tbivm(jt);
    OSThreadWaitState osts(Self->osthread(), false /* not Object.wait() */);
    if (as_suspend_equivalent) {
      jt->set_suspend_equivalent();
    }
    wait_status = IWait (Self, timeout) ;
    if (as_suspend_equivalent && jt->handle_special_suspend_equivalent_condition()) {
      assert (ILocked(), "invariant") ;
      IUnlock (true) ;
      jt->java_suspend_self();
      ILock (Self) ;
      assert (ILocked(), "invariant") ;
    }
  }
  assert (ILocked(), "invariant") ;
  assert (_owner == NULL, "invariant") ;
  set_owner (Self) ;
  return wait_status != 0 ;          // return true IFF timeout
}
Monitor::~Monitor() {
  assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
}
void Monitor::ClearMonitor (Monitor * m, const char *name) {
  m->_owner             = NULL ;
  m->_snuck             = false ;
  if (name == NULL) {
    strcpy(m->_name, "UNKNOWN") ;
  } else {
    strncpy(m->_name, name, MONITOR_NAME_LEN - 1);
    m->_name[MONITOR_NAME_LEN - 1] = '\0';
  }
  m->_LockWord.FullWord = 0 ;
  m->_EntryList         = NULL ;
  m->_OnDeck            = NULL ;
  m->_WaitSet           = NULL ;
  m->_WaitLock[0]       = 0 ;
}
Monitor::Monitor() { ClearMonitor(this); }
Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) {
  ClearMonitor (this, name) ;
#ifdef ASSERT
  _allow_vm_block  = allow_vm_block;
  _rank            = Rank ;
#endif
}
Mutex::~Mutex() {
  assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
}
Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) {
  ClearMonitor ((Monitor *) this, name) ;
#ifdef ASSERT
 _allow_vm_block   = allow_vm_block;
 _rank             = Rank ;
#endif
}
bool Monitor::owned_by_self() const {
  bool ret = _owner == Thread::current();
  assert (!ret || _LockWord.Bytes[_LSBINDEX] != 0, "invariant") ;
  return ret;
}
void Monitor::print_on_error(outputStream* st) const {
  st->print("[" PTR_FORMAT, this);
  st->print("] %s", _name);
  st->print(" - owner thread: " PTR_FORMAT, _owner);
}
#ifndef PRODUCT
void Monitor::print_on(outputStream* st) const {
  st->print_cr("Mutex: [0x%lx/0x%lx] %s - owner: 0x%lx", this, _LockWord.FullWord, _name, _owner);
}
#endif
#ifndef PRODUCT
#ifdef ASSERT
Monitor * Monitor::get_least_ranked_lock(Monitor * locks) {
  Monitor *res, *tmp;
  for (res = tmp = locks; tmp != NULL; tmp = tmp->next()) {
    if (tmp->rank() < res->rank()) {
      res = tmp;
    }
  }
  if (!SafepointSynchronize::is_at_safepoint()) {
    for (tmp = locks; tmp != NULL; tmp = tmp->next()) {
      if (tmp->next() != NULL) {
        assert(tmp->rank() == Mutex::native ||
               tmp->rank() <= tmp->next()->rank(), "mutex rank anomaly?");
      }
    }
  }
  return res;
}
Monitor* Monitor::get_least_ranked_lock_besides_this(Monitor* locks) {
  Monitor *res, *tmp;
  for (res = NULL, tmp = locks; tmp != NULL; tmp = tmp->next()) {
    if (tmp != this && (res == NULL || tmp->rank() < res->rank())) {
      res = tmp;
    }
  }
  if (!SafepointSynchronize::is_at_safepoint()) {
    for (tmp = locks; tmp != NULL; tmp = tmp->next()) {
      if (tmp->next() != NULL) {
        assert(tmp->rank() == Mutex::native ||
               tmp->rank() <= tmp->next()->rank(), "mutex rank anomaly?");
      }
    }
  }
  return res;
}
bool Monitor::contains(Monitor* locks, Monitor * lock) {
  for (; locks != NULL; locks = locks->next()) {
    if (locks == lock)
      return true;
  }
  return false;
}
#endif
void Monitor::set_owner_implementation(Thread *new_owner) {
  if (new_owner != NULL) {
    assert(new_owner == Thread::current(), "Should I be doing this?");
    assert(_owner == NULL, "setting the owner thread of an already owned mutex");
    _owner = new_owner; // set the owner
    #ifdef ASSERT  // Thread::_owned_locks is under the same ifdef
      Monitor* locks = get_least_ranked_lock(new_owner->owned_locks());
      assert(this->rank() >= 0, "bad lock rank");
      if (this->rank() != Mutex::native &&
          this->rank() != Mutex::suspend_resume &&
          locks != NULL && locks->rank() <= this->rank() &&
          !SafepointSynchronize::is_at_safepoint() &&
          this != Interrupt_lock && this != ProfileVM_lock &&
          !(this == Safepoint_lock && contains(locks, Terminator_lock) &&
            SafepointSynchronize::is_synchronizing())) {
        new_owner->print_owned_locks();
        fatal(err_msg("acquiring lock %s/%d out of order with lock %s/%d -- "
                      "possible deadlock", this->name(), this->rank(),
                      locks->name(), locks->rank()));
      }
      this->_next = new_owner->_owned_locks;
      new_owner->_owned_locks = this;
    #endif
  } else {
    Thread* old_owner = _owner;
    debug_only(_last_owner = old_owner);
    assert(old_owner != NULL, "removing the owner thread of an unowned mutex");
    assert(old_owner == Thread::current(), "removing the owner thread of an unowned mutex");
    _owner = NULL; // set the owner
    #ifdef ASSERT
      Monitor *locks = old_owner->owned_locks();
      Monitor *prev = NULL;
      bool found = false;
      for (; locks != NULL; prev = locks, locks = locks->next()) {
        if (locks == this) {
          found = true;
          break;
        }
      }
      assert(found, "Removing a lock not owned");
      if (prev == NULL) {
        old_owner->_owned_locks = _next;
      } else {
        prev->_next = _next;
      }
      _next = NULL;
    #endif
  }
}
void Monitor::check_prelock_state(Thread *thread) {
  assert((!thread->is_Java_thread() || ((JavaThread *)thread)->thread_state() == _thread_in_vm)
         || rank() == Mutex::special, "wrong thread state for using locks");
  if (StrictSafepointChecks) {
    if (thread->is_VM_thread() && !allow_vm_block()) {
      fatal(err_msg("VM thread using lock %s (not allowed to block on)",
                    name()));
    }
    debug_only(if (rank() != Mutex::special) \
      thread->check_for_valid_safepoint_state(false);)
  }
  assert(!os::ThreadCrashProtection::is_crash_protected(thread),
         "locking not allowed when crash protection is set");
}
void Monitor::check_block_state(Thread *thread) {
  if (!_allow_vm_block && thread->is_VM_thread()) {
    warning("VM thread blocked on lock");
    print();
    BREAKPOINT;
  }
  assert(_owner != thread, "deadlock: blocking on monitor owned by current thread");
}
#endif // PRODUCT
C:\hotspot-69087d08d473\src\share\vm/runtime/mutex.hpp
#ifndef SHARE_VM_RUNTIME_MUTEX_HPP
#define SHARE_VM_RUNTIME_MUTEX_HPP
#include "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "utilities/histogram.hpp"
union SplitWord {   // full-word with separately addressable LSB
  volatile intptr_t FullWord ;
  volatile void * Address ;
  volatile jbyte Bytes [sizeof(intptr_t)] ;
} ;
#ifdef VM_LITTLE_ENDIAN
 #define _LSBINDEX 0
#else
 #define _LSBINDEX (sizeof(intptr_t)-1)
#endif
class ParkEvent ;
static const int MONITOR_NAME_LEN = 64;
class Monitor : public CHeapObj<mtInternal> {
 public:
  enum lock_types {
       event,
       special,
       suspend_resume,
       leaf        = suspend_resume +   2,
       safepoint   = leaf           +  10,
       barrier     = safepoint      +   1,
       nonleaf     = barrier        +   1,
       max_nonleaf = nonleaf        + 900,
       native      = max_nonleaf    +   1
  };
 protected:                              // Monitor-Mutex metadata
  SplitWord _LockWord ;                  // Contention queue (cxq) colocated with Lock-byte
  enum LockWordBits { _LBIT=1 } ;
  Thread * volatile _owner;              // The owner of the lock
  ParkEvent * volatile _EntryList ;      // List of threads waiting for entry
  ParkEvent * volatile _OnDeck ;         // heir-presumptive
  volatile intptr_t _WaitLock [1] ;      // Protects _WaitSet
  ParkEvent * volatile  _WaitSet ;       // LL of ParkEvents
  volatile bool     _snuck;              // Used for sneaky locking (evil).
  int NotifyCount ;                      // diagnostic assist
  char _name[MONITOR_NAME_LEN];          // Name of mutex
#ifndef PRODUCT
  bool      _allow_vm_block;
  debug_only(int _rank;)                 // rank (to avoid/detect potential deadlocks)
  debug_only(Monitor * _next;)           // Used by a Thread to link up owned locks
  debug_only(Thread* _last_owner;)       // the last thread to own the lock
  debug_only(static bool contains(Monitor * locks, Monitor * lock);)
  debug_only(static Monitor * get_least_ranked_lock(Monitor * locks);)
  debug_only(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);)
#endif
  void set_owner_implementation(Thread* owner)                        PRODUCT_RETURN;
  void check_prelock_state     (Thread* thread)                       PRODUCT_RETURN;
  void check_block_state       (Thread* thread)                       PRODUCT_RETURN;
 public:
  enum {
    _no_safepoint_check_flag    = true,
    _allow_vm_block_flag        = true,
    _as_suspend_equivalent_flag = true
  };
  enum WaitResults {
    CONDVAR_EVENT,         // Wait returned because of condition variable notification
    INTERRUPT_EVENT,       // Wait returned because waiting thread was interrupted
    NUMBER_WAIT_RESULTS
  };
 private:
   int  TrySpin (Thread * Self) ;
   int  TryLock () ;
   int  TryFast () ;
   int  AcquireOrPush (ParkEvent * ev) ;
   void IUnlock (bool RelaxAssert) ;
   void ILock (Thread * Self) ;
   int  IWait (Thread * Self, jlong timo);
   int  ILocked () ;
 protected:
   static void ClearMonitor (Monitor * m, const char* name = NULL) ;
   Monitor() ;
 public:
  Monitor(int rank, const char *name, bool allow_vm_block=false);
  ~Monitor();
  bool wait(bool no_safepoint_check = !_no_safepoint_check_flag,
            long timeout = 0,
            bool as_suspend_equivalent = !_as_suspend_equivalent_flag);
  bool notify();
  bool notify_all();
  void lock(); // prints out warning if VM thread blocks
  void lock(Thread *thread); // overloaded with current thread
  void unlock();
  bool is_locked() const                     { return _owner != NULL; }
  bool try_lock(); // Like lock(), but unblocking. It returns false instead
  void lock_without_safepoint_check();
  void lock_without_safepoint_check (Thread * Self) ;
  Thread* owner() const         { return _owner; }
  bool owned_by_self() const;
  void jvm_raw_lock();
  void jvm_raw_unlock();
  const char *name() const                  { return _name; }
  void print_on_error(outputStream* st) const;
  #ifndef PRODUCT
    void print_on(outputStream* st) const;
    void print() const                      { print_on(tty); }
    debug_only(int    rank() const          { return _rank; })
    bool   allow_vm_block()                 { return _allow_vm_block; }
    debug_only(Monitor *next()  const         { return _next; })
    debug_only(void   set_next(Monitor *next) { _next = next; })
  #endif
  void set_owner(Thread* owner) {
  #ifndef PRODUCT
    set_owner_implementation(owner);
    debug_only(void verify_Monitor(Thread* thr));
  #else
    _owner = owner;
  #endif
  }
};
class Mutex : public Monitor {      // degenerate Monitor
 public:
   Mutex (int rank, const char *name, bool allow_vm_block=false);
   ~Mutex () ;
 private:
   bool notify ()    { ShouldNotReachHere(); return false; }
   bool notify_all() { ShouldNotReachHere(); return false; }
   bool wait (bool no_safepoint_check, long timeout, bool as_suspend_equivalent) {
     ShouldNotReachHere() ;
     return false ;
   }
};
#endif // SHARE_VM_RUNTIME_MUTEX_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/mutexLocker.cpp
#include "precompiled.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/vmThread.hpp"
Mutex*   Patching_lock                = NULL;
Monitor* SystemDictionary_lock        = NULL;
Mutex*   PackageTable_lock            = NULL;
Mutex*   CompiledIC_lock              = NULL;
Mutex*   InlineCacheBuffer_lock       = NULL;
Mutex*   VMStatistic_lock             = NULL;
Mutex*   JNIGlobalHandle_lock         = NULL;
Mutex*   JNIHandleBlockFreeList_lock  = NULL;
Mutex*   MemberNameTable_lock         = NULL;
Mutex*   JmethodIdCreation_lock       = NULL;
Mutex*   JfieldIdCreation_lock        = NULL;
Monitor* JNICritical_lock             = NULL;
Mutex*   JvmtiThreadState_lock        = NULL;
Monitor* JvmtiPendingEvent_lock       = NULL;
Monitor* Heap_lock                    = NULL;
Mutex*   ExpandHeap_lock              = NULL;
Mutex*   AdapterHandlerLibrary_lock   = NULL;
Mutex*   SignatureHandlerLibrary_lock = NULL;
Mutex*   VtableStubs_lock             = NULL;
Mutex*   SymbolTable_lock             = NULL;
Mutex*   StringTable_lock             = NULL;
Monitor* StringDedupQueue_lock        = NULL;
Mutex*   StringDedupTable_lock        = NULL;
Mutex*   CodeCache_lock               = NULL;
Mutex*   MethodData_lock              = NULL;
Mutex*   RetData_lock                 = NULL;
Monitor* VMOperationQueue_lock        = NULL;
Monitor* VMOperationRequest_lock      = NULL;
Monitor* Safepoint_lock               = NULL;
Monitor* SerializePage_lock           = NULL;
Monitor* Threads_lock                 = NULL;
Monitor* CGC_lock                     = NULL;
Monitor* STS_lock                     = NULL;
Monitor* SLT_lock                     = NULL;
Monitor* iCMS_lock                    = NULL;
Monitor* FullGCCount_lock             = NULL;
Monitor* CMark_lock                   = NULL;
Mutex*   CMRegionStack_lock           = NULL;
Mutex*   SATB_Q_FL_lock               = NULL;
Monitor* SATB_Q_CBL_mon               = NULL;
Mutex*   Shared_SATB_Q_lock           = NULL;
Mutex*   DirtyCardQ_FL_lock           = NULL;
Monitor* DirtyCardQ_CBL_mon           = NULL;
Mutex*   Shared_DirtyCardQ_lock       = NULL;
Mutex*   ParGCRareEvent_lock          = NULL;
Mutex*   EvacFailureStack_lock        = NULL;
Mutex*   DerivedPointerTableGC_lock   = NULL;
Mutex*   Compile_lock                 = NULL;
Monitor* MethodCompileQueue_lock      = NULL;
Monitor* CompileThread_lock           = NULL;
Mutex*   CompileTaskAlloc_lock        = NULL;
Mutex*   CompileStatistics_lock       = NULL;
Mutex*   MultiArray_lock              = NULL;
Monitor* Terminator_lock              = NULL;
Monitor* BeforeExit_lock              = NULL;
Monitor* Notify_lock                  = NULL;
Monitor* Interrupt_lock               = NULL;
Monitor* ProfileVM_lock               = NULL;
Mutex*   ProfilePrint_lock            = NULL;
Mutex*   ExceptionCache_lock          = NULL;
Monitor* ObjAllocPost_lock            = NULL;
Mutex*   OsrList_lock                 = NULL;
#ifndef PRODUCT
Mutex*   FullGCALot_lock              = NULL;
#endif
Mutex*   Debug1_lock                  = NULL;
Mutex*   Debug2_lock                  = NULL;
Mutex*   Debug3_lock                  = NULL;
Mutex*   tty_lock                     = NULL;
Mutex*   RawMonitor_lock              = NULL;
Mutex*   PerfDataMemAlloc_lock        = NULL;
Mutex*   PerfDataManager_lock         = NULL;
Mutex*   OopMapCacheAlloc_lock        = NULL;
Mutex*   FreeList_lock                = NULL;
Monitor* SecondaryFreeList_lock       = NULL;
Mutex*   OldSets_lock                 = NULL;
Monitor* RootRegionScan_lock          = NULL;
Mutex*   MMUTracker_lock              = NULL;
Monitor* GCTaskManager_lock           = NULL;
Mutex*   Management_lock              = NULL;
Monitor* Service_lock                 = NULL;
Monitor* PeriodicTask_lock            = NULL;
Monitor* RedefineClasses_lock         = NULL;
#ifdef INCLUDE_JFR
Mutex*   JfrStacktrace_lock           = NULL;
Monitor* JfrMsg_lock                  = NULL;
Mutex*   JfrBuffer_lock               = NULL;
Mutex*   JfrStream_lock               = NULL;
Mutex*   JfrThreadGroups_lock         = NULL;
#ifndef SUPPORTS_NATIVE_CX8
Mutex*   JfrCounters_lock             = NULL;
#endif
#endif
#ifndef SUPPORTS_NATIVE_CX8
Mutex*   UnsafeJlong_lock             = NULL;
#endif
#define MAX_NUM_MUTEX 128
static Monitor * _mutex_array[MAX_NUM_MUTEX];
static int _num_mutex;
#ifdef ASSERT
void assert_locked_or_safepoint(const Monitor * lock) {
  if (IgnoreLockingAssertions) return;
  assert(lock != NULL, "Need non-NULL lock");
  if (lock->owned_by_self()) return;
  if (SafepointSynchronize::is_at_safepoint()) return;
  if (!Universe::is_fully_initialized()) return;
  VM_Operation* op = VMThread::vm_operation();
  if (op != NULL && op->calling_thread() == lock->owner()) return;
  fatal(err_msg("must own lock %s", lock->name()));
}
void assert_lock_strong(const Monitor * lock) {
  if (IgnoreLockingAssertions) return;
  assert(lock != NULL, "Need non-NULL lock");
  if (lock->owned_by_self()) return;
  fatal(err_msg("must own lock %s", lock->name()));
}
#endif
#define def(var, type, pri, vm_block) {                           \
  var = new type(Mutex::pri, #var, vm_block);                     \
  assert(_num_mutex < MAX_NUM_MUTEX,                              \
                    "increase MAX_NUM_MUTEX");                    \
  _mutex_array[_num_mutex++] = var;                               \
}
void mutex_init() {
  def(tty_lock                     , Mutex  , event,       true ); // allow to lock in VM
  def(CGC_lock                   , Monitor, special,     true ); // coordinate between fore- and background GC
  def(STS_lock                   , Monitor, leaf,        true );
  if (UseConcMarkSweepGC) {
    def(iCMS_lock                  , Monitor, special,     true ); // CMS incremental mode start/stop notification
  }
  if (UseConcMarkSweepGC || UseG1GC) {
    def(FullGCCount_lock           , Monitor, leaf,        true ); // in support of ExplicitGCInvokesConcurrent
  }
  if (UseG1GC) {
    def(CMark_lock                 , Monitor, nonleaf,     true ); // coordinate concurrent mark thread
    def(CMRegionStack_lock         , Mutex,   leaf,        true );
    def(SATB_Q_FL_lock             , Mutex  , special,     true );
    def(SATB_Q_CBL_mon             , Monitor, nonleaf,     true );
    def(Shared_SATB_Q_lock         , Mutex,   nonleaf,     true );
    def(DirtyCardQ_FL_lock         , Mutex  , special,     true );
    def(DirtyCardQ_CBL_mon         , Monitor, nonleaf,     true );
    def(Shared_DirtyCardQ_lock     , Mutex,   nonleaf,     true );
    def(FreeList_lock              , Mutex,   leaf     ,   true );
    def(SecondaryFreeList_lock     , Monitor, leaf     ,   true );
    def(OldSets_lock               , Mutex  , leaf     ,   true );
    def(RootRegionScan_lock        , Monitor, leaf     ,   true );
    def(MMUTracker_lock            , Mutex  , leaf     ,   true );
    def(EvacFailureStack_lock      , Mutex  , nonleaf  ,   true );
    def(StringDedupQueue_lock      , Monitor, leaf,        true );
    def(StringDedupTable_lock      , Mutex  , leaf,        true );
  }
  def(ParGCRareEvent_lock          , Mutex  , leaf     ,   true );
  def(DerivedPointerTableGC_lock   , Mutex,   leaf,        true );
  def(CodeCache_lock               , Mutex  , special,     true );
  def(Interrupt_lock               , Monitor, special,     true ); // used for interrupt processing
  def(RawMonitor_lock              , Mutex,   special,     true );
  def(OopMapCacheAlloc_lock        , Mutex,   leaf,        true ); // used for oop_map_cache allocation.
  def(Patching_lock                , Mutex  , special,     true ); // used for safepointing and code patching.
  def(ObjAllocPost_lock            , Monitor, special,     false);
  def(Service_lock                 , Monitor, special,     true ); // used for service thread operations
  def(JmethodIdCreation_lock       , Mutex  , leaf,        true ); // used for creating jmethodIDs.
  def(SystemDictionary_lock        , Monitor, leaf,        true ); // lookups done by VM thread
  def(PackageTable_lock            , Mutex  , leaf,        false);
  def(InlineCacheBuffer_lock       , Mutex  , leaf,        true );
  def(VMStatistic_lock             , Mutex  , leaf,        false);
  def(ExpandHeap_lock              , Mutex  , leaf,        true ); // Used during compilation by VM thread
  def(JNIHandleBlockFreeList_lock  , Mutex  , leaf,        true ); // handles are used by VM thread
  def(SignatureHandlerLibrary_lock , Mutex  , leaf,        false);
  def(SymbolTable_lock             , Mutex  , leaf+2,      true );
  def(StringTable_lock             , Mutex  , leaf,        true );
  def(ProfilePrint_lock            , Mutex  , leaf,        false); // serial profile printing
  def(ExceptionCache_lock          , Mutex  , leaf,        false); // serial profile printing
  def(OsrList_lock                 , Mutex  , leaf,        true );
  def(Debug1_lock                  , Mutex  , leaf,        true );
#ifndef PRODUCT
  def(FullGCALot_lock              , Mutex  , leaf,        false); // a lock to make FullGCALot MT safe
#endif
  def(BeforeExit_lock              , Monitor, leaf,        true );
  def(PerfDataMemAlloc_lock        , Mutex  , leaf,        true ); // used for allocating PerfData memory for performance data
  def(PerfDataManager_lock         , Mutex  , leaf,        true ); // used for synchronized access to PerfDataManager resources
  def(Safepoint_lock               , Monitor, safepoint,   true ); // locks SnippetCache_lock/Threads_lock
  def(Threads_lock                 , Monitor, barrier,     true );
  def(VMOperationQueue_lock        , Monitor, nonleaf,     true ); // VM_thread allowed to block on these
  def(VMOperationRequest_lock      , Monitor, nonleaf,     true );
  def(RetData_lock                 , Mutex  , nonleaf,     false);
  def(Terminator_lock              , Monitor, nonleaf,     true );
  def(VtableStubs_lock             , Mutex  , nonleaf,     true );
  def(Notify_lock                  , Monitor, nonleaf,     true );
  def(JNIGlobalHandle_lock         , Mutex  , nonleaf,     true ); // locks JNIHandleBlockFreeList_lock
  def(JNICritical_lock             , Monitor, nonleaf,     true ); // used for JNI critical regions
  def(AdapterHandlerLibrary_lock   , Mutex  , nonleaf,     true);
  if (UseConcMarkSweepGC) {
    def(SLT_lock                   , Monitor, nonleaf,     false );
  }
  def(Heap_lock                    , Monitor, nonleaf+1,   false);
  def(JfieldIdCreation_lock        , Mutex  , nonleaf+1,   true ); // jfieldID, Used in VM_Operation
  def(MemberNameTable_lock         , Mutex  , nonleaf+1,   false); // Used to protect MemberNameTable
  def(CompiledIC_lock              , Mutex  , nonleaf+2,   false); // locks VtableStubs_lock, InlineCacheBuffer_lock
  def(CompileTaskAlloc_lock        , Mutex  , nonleaf+2,   true );
  def(CompileStatistics_lock       , Mutex  , nonleaf+2,   false);
  def(MultiArray_lock              , Mutex  , nonleaf+2,   false); // locks SymbolTable_lock
  def(JvmtiThreadState_lock        , Mutex  , nonleaf+2,   false); // Used by JvmtiThreadState/JvmtiEventController
  def(JvmtiPendingEvent_lock       , Monitor, nonleaf,     false); // Used by JvmtiCodeBlobEvents
  def(Management_lock              , Mutex  , nonleaf+2,   false); // used for JVM management
  def(Compile_lock                 , Mutex  , nonleaf+3,   true );
  def(MethodData_lock              , Mutex  , nonleaf+3,   false);
  def(MethodCompileQueue_lock      , Monitor, nonleaf+4,   true );
  def(Debug2_lock                  , Mutex  , nonleaf+4,   true );
  def(Debug3_lock                  , Mutex  , nonleaf+4,   true );
  def(ProfileVM_lock               , Monitor, special,   false); // used for profiling of the VMThread
  def(CompileThread_lock           , Monitor, nonleaf+5,   false );
  def(PeriodicTask_lock            , Monitor, nonleaf+5,   true);
  def(RedefineClasses_lock         , Monitor, nonleaf+5,   true);
#if INCLUDE_JFR
  def(JfrMsg_lock                  , Monitor, leaf,        true);
  def(JfrBuffer_lock               , Mutex,   leaf,        true);
  def(JfrThreadGroups_lock         , Mutex,   leaf,        true);
  def(JfrStream_lock               , Mutex,   nonleaf,     true);
  def(JfrStacktrace_lock           , Mutex,   special,     true);
#ifndef SUPPORTS_NATIVE_CX8
  def(JfrCounters_lock             , Mutex,   special,     false);
#endif
#endif
#ifndef SUPPORTS_NATIVE_CX8
  def(UnsafeJlong_lock             , Mutex,   special,     false);
#endif
}
GCMutexLocker::GCMutexLocker(Monitor * mutex) {
  if (SafepointSynchronize::is_at_safepoint()) {
    _locked = false;
  } else {
    _mutex = mutex;
    _locked = true;
    _mutex->lock();
  }
}
void print_owned_locks_on_error(outputStream* st) {
  st->print("VM Mutex/Monitor currently owned by a thread: ");
  bool none = true;
  for (int i = 0; i < _num_mutex; i++) {
     if (_mutex_array[i]->owner() != NULL) {
       if (none) {
          st->print_cr(" ([mutex/lock_event])");
          none = false;
       }
       _mutex_array[i]->print_on_error(st);
       st->cr();
     }
  }
  if (none) st->print_cr("None");
}
C:\hotspot-69087d08d473\src\share\vm/runtime/mutexLocker.hpp
#ifndef SHARE_VM_RUNTIME_MUTEXLOCKER_HPP
#define SHARE_VM_RUNTIME_MUTEXLOCKER_HPP
#include "memory/allocation.hpp"
#include "runtime/mutex.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "os_aix.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
extern Mutex*   Patching_lock;                   // a lock used to guard code patching of compiled code
extern Monitor* SystemDictionary_lock;           // a lock on the system dictonary
extern Mutex*   PackageTable_lock;               // a lock on the class loader package table
extern Mutex*   CompiledIC_lock;                 // a lock used to guard compiled IC patching and access
extern Mutex*   InlineCacheBuffer_lock;          // a lock used to guard the InlineCacheBuffer
extern Mutex*   VMStatistic_lock;                // a lock used to guard statistics count increment
extern Mutex*   JNIGlobalHandle_lock;            // a lock on creating JNI global handles
extern Mutex*   JNIHandleBlockFreeList_lock;     // a lock on the JNI handle block free list
extern Mutex*   MemberNameTable_lock;            // a lock on the MemberNameTable updates
extern Mutex*   JmethodIdCreation_lock;          // a lock on creating JNI method identifiers
extern Mutex*   JfieldIdCreation_lock;           // a lock on creating JNI static field identifiers
extern Monitor* JNICritical_lock;                // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
extern Mutex*   JvmtiThreadState_lock;           // a lock on modification of JVMTI thread data
extern Monitor* JvmtiPendingEvent_lock;          // a lock on the JVMTI pending events list
extern Monitor* Heap_lock;                       // a lock on the heap
extern Mutex*   ExpandHeap_lock;                 // a lock on expanding the heap
extern Mutex*   AdapterHandlerLibrary_lock;      // a lock on the AdapterHandlerLibrary
extern Mutex*   SignatureHandlerLibrary_lock;    // a lock on the SignatureHandlerLibrary
extern Mutex*   VtableStubs_lock;                // a lock on the VtableStubs
extern Mutex*   SymbolTable_lock;                // a lock on the symbol table
extern Mutex*   StringTable_lock;                // a lock on the interned string table
extern Monitor* StringDedupQueue_lock;           // a lock on the string deduplication queue
extern Mutex*   StringDedupTable_lock;           // a lock on the string deduplication table
extern Mutex*   CodeCache_lock;                  // a lock on the CodeCache, rank is special, use MutexLockerEx
extern Mutex*   MethodData_lock;                 // a lock on installation of method data
extern Mutex*   RetData_lock;                    // a lock on installation of RetData inside method data
extern Mutex*   DerivedPointerTableGC_lock;      // a lock to protect the derived pointer table
extern Monitor* VMOperationQueue_lock;           // a lock on queue of vm_operations waiting to execute
extern Monitor* VMOperationRequest_lock;         // a lock on Threads waiting for a vm_operation to terminate
extern Monitor* Safepoint_lock;                  // a lock used by the safepoint abstraction
extern Monitor* Threads_lock;                    // a lock on the Threads table of active Java threads
extern Monitor* CGC_lock;                        // used for coordination between
extern Monitor* STS_lock;                        // used for joining/leaving SuspendibleThreadSet.
extern Monitor* SLT_lock;                        // used in CMS GC for acquiring PLL
extern Monitor* iCMS_lock;                       // CMS incremental mode start/stop notification
extern Monitor* FullGCCount_lock;                // in support of "concurrent" full gc
extern Monitor* CMark_lock;                      // used for concurrent mark thread coordination
extern Mutex*   CMRegionStack_lock;              // used for protecting accesses to the CM region stack
extern Mutex*   SATB_Q_FL_lock;                  // Protects SATB Q
extern Monitor* SATB_Q_CBL_mon;                  // Protects SATB Q
extern Mutex*   Shared_SATB_Q_lock;              // Lock protecting SATB
extern Mutex*   DirtyCardQ_FL_lock;              // Protects dirty card Q
extern Monitor* DirtyCardQ_CBL_mon;              // Protects dirty card Q
extern Mutex*   Shared_DirtyCardQ_lock;          // Lock protecting dirty card
extern Mutex*   ParGCRareEvent_lock;             // Synchronizes various (rare) parallel GC ops.
extern Mutex*   EvacFailureStack_lock;           // guards the evac failure scan stack
extern Mutex*   Compile_lock;                    // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
extern Monitor* MethodCompileQueue_lock;         // a lock held when method compilations are enqueued, dequeued
extern Monitor* CompileThread_lock;              // a lock held by compile threads during compilation system initialization
extern Mutex*   CompileTaskAlloc_lock;           // a lock held when CompileTasks are allocated
extern Mutex*   CompileStatistics_lock;          // a lock held when updating compilation statistics
extern Mutex*   MultiArray_lock;                 // a lock used to guard allocation of multi-dim arrays
extern Monitor* Terminator_lock;                 // a lock used to guard termination of the vm
extern Monitor* BeforeExit_lock;                 // a lock used to guard cleanups and shutdown hooks
extern Monitor* Notify_lock;                     // a lock used to synchronize the start-up of the vm
extern Monitor* Interrupt_lock;                  // a lock used for condition variable mediated interrupt processing
extern Monitor* ProfileVM_lock;                  // a lock used for profiling the VMThread
extern Mutex*   ProfilePrint_lock;               // a lock used to serialize the printing of profiles
extern Mutex*   ExceptionCache_lock;             // a lock used to synchronize exception cache updates
extern Mutex*   OsrList_lock;                    // a lock used to serialize access to OSR queues
#ifndef PRODUCT
extern Mutex*   FullGCALot_lock;                 // a lock to make FullGCALot MT safe
#endif // PRODUCT
extern Mutex*   Debug1_lock;                     // A bunch of pre-allocated locks that can be used for tracing
extern Mutex*   Debug2_lock;                     // down synchronization related bugs!
extern Mutex*   Debug3_lock;
extern Mutex*   RawMonitor_lock;
extern Mutex*   PerfDataMemAlloc_lock;           // a lock on the allocator for PerfData memory for performance data
extern Mutex*   PerfDataManager_lock;            // a long on access to PerfDataManager resources
extern Mutex*   ParkerFreeList_lock;
extern Mutex*   OopMapCacheAlloc_lock;           // protects allocation of oop_map caches
extern Mutex*   FreeList_lock;                   // protects the free region list during safepoints
extern Monitor* SecondaryFreeList_lock;          // protects the secondary free region list
extern Mutex*   OldSets_lock;                    // protects the old region sets
extern Monitor* RootRegionScan_lock;             // used to notify that the CM threads have finished scanning the IM snapshot regions
extern Mutex*   MMUTracker_lock;                 // protects the MMU
extern Mutex*   Management_lock;                 // a lock used to serialize JVM management
extern Monitor* Service_lock;                    // a lock used for service thread operation
extern Monitor* PeriodicTask_lock;               // protects the periodic task structure
extern Monitor* RedefineClasses_lock;            // locks classes from parallel redefinition
#if INCLUDE_JFR
extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
extern Monitor* JfrMsg_lock;                     // protects JFR messaging
extern Mutex*   JfrBuffer_lock;                  // protects JFR buffer operations
extern Mutex*   JfrStream_lock;                  // protects JFR stream access
extern Mutex*   JfrThreadGroups_lock;            // protects JFR access to Thread Groups
#ifndef SUPPORTS_NATIVE_CX8
extern Mutex*   JfrCounters_lock;                // provides atomic updates of JFR counters
#endif
#endif
#ifndef SUPPORTS_NATIVE_CX8
extern Mutex*   UnsafeJlong_lock;                // provides Unsafe atomic updates to jlongs on platforms that don't support cx8
#endif
void print_owned_locks_on_error(outputStream* st);
char *lock_name(Mutex *mutex);
class MutexLocker: StackObj {
 private:
  Monitor * _mutex;
 public:
  MutexLocker(Monitor * mutex) {
    assert(mutex->rank() != Mutex::special,
      "Special ranked mutex should only use MutexLockerEx");
    _mutex = mutex;
    _mutex->lock();
  }
  MutexLocker(Monitor * mutex, Thread *thread) {
    assert(mutex->rank() != Mutex::special,
      "Special ranked mutex should only use MutexLockerEx");
    _mutex = mutex;
    _mutex->lock(thread);
  }
  ~MutexLocker() {
    _mutex->unlock();
  }
};
#ifdef ASSERT
void assert_locked_or_safepoint(const Monitor * lock);
void assert_lock_strong(const Monitor * lock);
#else
#define assert_locked_or_safepoint(lock)
#define assert_lock_strong(lock)
#endif
class MutexLockerEx: public StackObj {
 private:
  Monitor * _mutex;
 public:
  MutexLockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) {
    _mutex = mutex;
    if (_mutex != NULL) {
      assert(mutex->rank() > Mutex::special || no_safepoint_check,
        "Mutexes with rank special or lower should not do safepoint checks");
      if (no_safepoint_check)
        _mutex->lock_without_safepoint_check();
      else
        _mutex->lock();
    }
  }
  ~MutexLockerEx() {
    if (_mutex != NULL) {
      _mutex->unlock();
    }
  }
};
class MonitorLockerEx: public MutexLockerEx {
 private:
  Monitor * _monitor;
 public:
  MonitorLockerEx(Monitor* monitor,
                  bool no_safepoint_check = !Mutex::_no_safepoint_check_flag):
    MutexLockerEx(monitor, no_safepoint_check),
    _monitor(monitor) {
  }
  ~MonitorLockerEx() {
    #ifdef ASSERT
      if (_monitor != NULL) {
        assert_lock_strong(_monitor);
      }
    #endif  // ASSERT
  }
  bool wait(bool no_safepoint_check = !Mutex::_no_safepoint_check_flag,
            long timeout = 0,
            bool as_suspend_equivalent = !Mutex::_as_suspend_equivalent_flag) {
    if (_monitor != NULL) {
      return _monitor->wait(no_safepoint_check, timeout, as_suspend_equivalent);
    }
    return false;
  }
  bool notify_all() {
    if (_monitor != NULL) {
      return _monitor->notify_all();
    }
    return true;
  }
  bool notify() {
    if (_monitor != NULL) {
      return _monitor->notify();
    }
    return true;
  }
};
class GCMutexLocker: public StackObj {
private:
  Monitor * _mutex;
  bool _locked;
public:
  GCMutexLocker(Monitor * mutex);
  ~GCMutexLocker() { if (_locked) _mutex->unlock(); }
};
class MutexUnlocker: StackObj {
 private:
  Monitor * _mutex;
 public:
  MutexUnlocker(Monitor * mutex) {
    _mutex = mutex;
    _mutex->unlock();
  }
  ~MutexUnlocker() {
    _mutex->lock();
  }
};
class MutexUnlockerEx: StackObj {
 private:
  Monitor * _mutex;
  bool _no_safepoint_check;
 public:
  MutexUnlockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) {
    _mutex = mutex;
    _no_safepoint_check = no_safepoint_check;
    _mutex->unlock();
  }
  ~MutexUnlockerEx() {
    if (_no_safepoint_check == Mutex::_no_safepoint_check_flag) {
      _mutex->lock_without_safepoint_check();
    } else {
      _mutex->lock();
    }
  }
};
#ifndef PRODUCT
class VerifyMutexLocker: StackObj {
 private:
  Monitor * _mutex;
  bool   _reentrant;
 public:
  VerifyMutexLocker(Monitor * mutex) {
    _mutex     = mutex;
    _reentrant = mutex->owned_by_self();
    if (!_reentrant) {
      FlagSetting fs(StrictSafepointChecks, false);
      _mutex->lock();
    }
  }
  ~VerifyMutexLocker() {
    if (!_reentrant) {
      _mutex->unlock();
    }
  }
};
#endif
#endif // SHARE_VM_RUNTIME_MUTEXLOCKER_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/objectMonitor.cpp
#include "precompiled.hpp"
#include "classfile/vmSymbols.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/support/jfrThreadId.hpp"
#include "memory/resourceArea.hpp"
#include "oops/markOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "services/threadService.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/macros.hpp"
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/support/jfrFlush.hpp"
#endif
#if defined(__GNUC__) && !defined(IA64) && !defined(PPC64)
  #define ATTR __attribute__((noinline))
#else
  #define ATTR
#endif
#ifdef DTRACE_ENABLED
#define DTRACE_MONITOR_PROBE_COMMON(obj, thread)                           \
  char* bytes = NULL;                                                      \
  int len = 0;                                                             \
  jlong jtid = SharedRuntime::get_java_tid(thread);                        \
  Symbol* klassname = ((oop)obj)->klass()->name();                         \
  if (klassname != NULL) {                                                 \
    bytes = (char*)klassname->bytes();                                     \
    len = klassname->utf8_length();                                        \
  }
#ifndef USDT2
HS_DTRACE_PROBE_DECL4(hotspot, monitor__notify,
  jlong, uintptr_t, char*, int);
HS_DTRACE_PROBE_DECL4(hotspot, monitor__notifyAll,
  jlong, uintptr_t, char*, int);
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__enter,
  jlong, uintptr_t, char*, int);
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__entered,
  jlong, uintptr_t, char*, int);
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__exit,
  jlong, uintptr_t, char*, int);
#define DTRACE_MONITOR_WAIT_PROBE(monitor, obj, thread, millis)       \
  {                                                                        \
    if (DTraceMonitorProbes) {                                            \
      DTRACE_MONITOR_PROBE_COMMON(obj, thread);                       \
      HS_DTRACE_PROBE5(hotspot, monitor__wait, jtid,                       \
                       (monitor), bytes, len, (millis));                   \
    }                                                                      \
  }
#define DTRACE_MONITOR_PROBE(probe, monitor, obj, thread)             \
  {                                                                        \
    if (DTraceMonitorProbes) {                                            \
      DTRACE_MONITOR_PROBE_COMMON(obj, thread);                       \
      HS_DTRACE_PROBE4(hotspot, monitor__##probe, jtid,                    \
                       (uintptr_t)(monitor), bytes, len);                  \
    }                                                                      \
  }
#else /* USDT2 */
#define DTRACE_MONITOR_WAIT_PROBE(monitor, obj, thread, millis)            \
  {                                                                        \
    if (DTraceMonitorProbes) {                                            \
      DTRACE_MONITOR_PROBE_COMMON(obj, thread);                            \
      HOTSPOT_MONITOR_WAIT(jtid,                                           \
                       (monitor), bytes, len, (millis));                   \
    }                                                                      \
  }
#define HOTSPOT_MONITOR_contended__enter HOTSPOT_MONITOR_CONTENDED_ENTER
#define HOTSPOT_MONITOR_contended__entered HOTSPOT_MONITOR_CONTENDED_ENTERED
#define HOTSPOT_MONITOR_contended__exit HOTSPOT_MONITOR_CONTENDED_EXIT
#define HOTSPOT_MONITOR_notify HOTSPOT_MONITOR_NOTIFY
#define HOTSPOT_MONITOR_notifyAll HOTSPOT_MONITOR_NOTIFYALL
#define DTRACE_MONITOR_PROBE(probe, monitor, obj, thread)                  \
  {                                                                        \
    if (DTraceMonitorProbes) {                                            \
      DTRACE_MONITOR_PROBE_COMMON(obj, thread);                            \
      HOTSPOT_MONITOR_##probe(jtid,                                               \
                       (uintptr_t)(monitor), bytes, len);                  \
    }                                                                      \
  }
#endif /* USDT2 */
#else //  ndef DTRACE_ENABLED
#define DTRACE_MONITOR_WAIT_PROBE(obj, thread, millis, mon)    {;}
#define DTRACE_MONITOR_PROBE(probe, obj, thread, mon)          {;}
#endif // ndef DTRACE_ENABLED
int ObjectMonitor::Knob_Verbose    = 0 ;
int ObjectMonitor::Knob_SpinLimit  = 5000 ;    // derived by an external tool -
static int Knob_LogSpins           = 0 ;       // enable jvmstat tally for spins
static int Knob_HandOff            = 0 ;
static int Knob_ReportSettings     = 0 ;
static int Knob_SpinBase           = 0 ;       // Floor AKA SpinMin
static int Knob_SpinBackOff        = 0 ;       // spin-loop backoff
static int Knob_CASPenalty         = -1 ;      // Penalty for failed CAS
static int Knob_OXPenalty          = -1 ;      // Penalty for observed _owner change
static int Knob_SpinSetSucc        = 1 ;       // spinners set the _succ field
static int Knob_SpinEarly          = 1 ;
static int Knob_SuccEnabled        = 1 ;       // futile wake throttling
static int Knob_SuccRestrict       = 0 ;       // Limit successors + spinners to at-most-one
static int Knob_MaxSpinners        = -1 ;      // Should be a function of # CPUs
static int Knob_Bonus              = 100 ;     // spin success bonus
static int Knob_BonusB             = 100 ;     // spin success bonus
static int Knob_Penalty            = 200 ;     // spin failure penalty
static int Knob_Poverty            = 1000 ;
static int Knob_SpinAfterFutile    = 1 ;       // Spin after returning from park()
static int Knob_FixedSpin          = 0 ;
static int Knob_OState             = 3 ;       // Spinner checks thread state of _owner
static int Knob_UsePause           = 1 ;
static int Knob_ExitPolicy         = 0 ;
static int Knob_PreSpin            = 10 ;      // 20-100 likely better
static int Knob_ResetEvent         = 0 ;
static int BackOffMask             = 0 ;
static int Knob_FastHSSEC          = 0 ;
static int Knob_MoveNotifyee       = 2 ;       // notify() - disposition of notifyee
static int Knob_QMode              = 0 ;       // EntryList-cxq policy - queue discipline
static volatile int InitDone       = 0 ;
#define TrySpin TrySpin_VaryDuration
bool ObjectMonitor::try_enter(Thread* THREAD) {
  if (THREAD != _owner) {
    if (THREAD->is_lock_owned ((address)_owner)) {
       assert(_recursions == 0, "internal state error");
       _owner = THREAD ;
       _recursions = 1 ;
       OwnerIsThread = 1 ;
       return true;
    }
    if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
      return false;
    }
    return true;
  } else {
    _recursions++;
    return true;
  }
}
void ATTR ObjectMonitor::enter(TRAPS) {
  Thread * const Self = THREAD ;
  void * cur ;
  cur = Atomic::cmpxchg_ptr (Self, &_owner, NULL) ;
  if (cur == NULL) {
     assert (_recursions == 0   , "invariant") ;
     assert (_owner      == Self, "invariant") ;
     return ;
  }
  if (cur == Self) {
     _recursions ++ ;
     return ;
  }
  if (Self->is_lock_owned ((address)cur)) {
    assert (_recursions == 0, "internal state error");
    _recursions = 1 ;
    _owner = Self ;
    OwnerIsThread = 1 ;
    return ;
  }
  assert (Self->_Stalled == 0, "invariant") ;
  Self->_Stalled = intptr_t(this) ;
  if (Knob_SpinEarly && TrySpin (Self) > 0) {
     assert (_owner == Self      , "invariant") ;
     assert (_recursions == 0    , "invariant") ;
     assert (((oop)(object()))->mark() == markOopDesc::encode(this), "invariant") ;
     Self->_Stalled = 0 ;
     return ;
  }
  assert (_owner != Self          , "invariant") ;
  assert (_succ  != Self          , "invariant") ;
  assert (Self->is_Java_thread()  , "invariant") ;
  JavaThread * jt = (JavaThread *) Self ;
  assert (!SafepointSynchronize::is_at_safepoint(), "invariant") ;
  assert (jt->thread_state() != _thread_blocked   , "invariant") ;
  assert (this->object() != NULL  , "invariant") ;
  assert (_count >= 0, "invariant") ;
  Atomic::inc_ptr(&_count);
  JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);)
  EventJavaMonitorEnter event;
  if (event.should_commit()) {
    event.set_monitorClass(((oop)this->object())->klass());
    event.set_address((uintptr_t)(this->object_addr()));
  }
  { // Change java thread status to indicate blocked on monitor enter.
    JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this);
    Self->set_current_pending_monitor(this);
    DTRACE_MONITOR_PROBE(contended__enter, this, object(), jt);
    if (JvmtiExport::should_post_monitor_contended_enter()) {
      JvmtiExport::post_monitor_contended_enter(jt, this);
    }
    OSThreadContendState osts(Self->osthread());
    ThreadBlockInVM tbivm(jt);
    for (;;) {
      jt->set_suspend_equivalent();
      EnterI (THREAD) ;
      if (!ExitSuspendEquivalent(jt)) break ;
          _recursions = 0 ;
      _succ = NULL ;
      exit (false, Self) ;
      jt->java_suspend_self();
    }
    Self->set_current_pending_monitor(NULL);
  }
  Atomic::dec_ptr(&_count);
  assert (_count >= 0, "invariant") ;
  Self->_Stalled = 0 ;
  assert (_recursions == 0     , "invariant") ;
  assert (_owner == Self       , "invariant") ;
  assert (_succ  != Self       , "invariant") ;
  assert (((oop)(object()))->mark() == markOopDesc::encode(this), "invariant") ;
  DTRACE_MONITOR_PROBE(contended__entered, this, object(), jt);
  if (JvmtiExport::should_post_monitor_contended_entered()) {
    JvmtiExport::post_monitor_contended_entered(jt, this);
  }
  if (event.should_commit()) {
    event.set_previousOwner((uintptr_t)_previous_owner_tid);
    event.commit();
  }
  if (ObjectMonitor::_sync_ContendedLockAttempts != NULL) {
     ObjectMonitor::_sync_ContendedLockAttempts->inc() ;
  }
}
int ObjectMonitor::TryLock (Thread * Self) {
   for (;;) {
      void * own = _owner ;
      if (own != NULL) return 0 ;
      if (Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) {
         assert (_recursions == 0, "invariant") ;
         assert (_owner == Self, "invariant") ;
         return 1 ;
      }
      if (true) return -1 ;
   }
}
void ATTR ObjectMonitor::EnterI (TRAPS) {
    Thread * Self = THREAD ;
    assert (Self->is_Java_thread(), "invariant") ;
    assert (((JavaThread *) Self)->thread_state() == _thread_blocked   , "invariant") ;
    if (TryLock (Self) > 0) {
        assert (_succ != Self              , "invariant") ;
        assert (_owner == Self             , "invariant") ;
        assert (_Responsible != Self       , "invariant") ;
        return ;
    }
    DeferredInitialize () ;
    if (TrySpin (Self) > 0) {
        assert (_owner == Self        , "invariant") ;
        assert (_succ != Self         , "invariant") ;
        assert (_Responsible != Self  , "invariant") ;
        return ;
    }
    assert (_succ  != Self            , "invariant") ;
    assert (_owner != Self            , "invariant") ;
    assert (_Responsible != Self      , "invariant") ;
    ObjectWaiter node(Self) ;
    Self->_ParkEvent->reset() ;
    node._prev   = (ObjectWaiter *) 0xBAD ;
    node.TState  = ObjectWaiter::TS_CXQ ;
    ObjectWaiter * nxt ;
    for (;;) {
        node._next = nxt = _cxq ;
        if (Atomic::cmpxchg_ptr (&node, &_cxq, nxt) == nxt) break ;
        if (TryLock (Self) > 0) {
            assert (_succ != Self         , "invariant") ;
            assert (_owner == Self        , "invariant") ;
            assert (_Responsible != Self  , "invariant") ;
            return ;
        }
    }
    if ((SyncFlags & 16) == 0 && nxt == NULL && _EntryList == NULL) {
        Atomic::cmpxchg_ptr (Self, &_Responsible, NULL) ;
    }
    TEVENT (Inflated enter - Contention) ;
    int nWakeups = 0 ;
    int RecheckInterval = 1 ;
    for (;;) {
        if (TryLock (Self) > 0) break ;
        assert (_owner != Self, "invariant") ;
        if ((SyncFlags & 2) && _Responsible == NULL) {
           Atomic::cmpxchg_ptr (Self, &_Responsible, NULL) ;
        }
        if (_Responsible == Self || (SyncFlags & 1)) {
            TEVENT (Inflated enter - park TIMED) ;
            Self->_ParkEvent->park ((jlong) RecheckInterval) ;
            RecheckInterval *= 8 ;
            if (RecheckInterval > 1000) RecheckInterval = 1000 ;
        } else {
            TEVENT (Inflated enter - park UNTIMED) ;
            Self->_ParkEvent->park() ;
        }
        if (TryLock(Self) > 0) break ;
        TEVENT (Inflated enter - Futile wakeup) ;
        if (ObjectMonitor::_sync_FutileWakeups != NULL) {
           ObjectMonitor::_sync_FutileWakeups->inc() ;
        }
        ++ nWakeups ;
        if ((Knob_SpinAfterFutile & 1) && TrySpin (Self) > 0) break ;
        if ((Knob_ResetEvent & 1) && Self->_ParkEvent->fired()) {
           Self->_ParkEvent->reset() ;
           OrderAccess::fence() ;
        }
        if (_succ == Self) _succ = NULL ;
        OrderAccess::fence() ;
    }
    assert (_owner == Self      , "invariant") ;
    assert (object() != NULL    , "invariant") ;
    UnlinkAfterAcquire (Self, &node) ;
    if (_succ == Self) _succ = NULL ;
    assert (_succ != Self, "invariant") ;
    if (_Responsible == Self) {
        _Responsible = NULL ;
        OrderAccess::fence(); // Dekker pivot-point
    }
    if (SyncFlags & 8) {
       OrderAccess::fence() ;
    }
    return ;
}
void ATTR ObjectMonitor::ReenterI (Thread * Self, ObjectWaiter * SelfNode) {
    assert (Self != NULL                , "invariant") ;
    assert (SelfNode != NULL            , "invariant") ;
    assert (SelfNode->_thread == Self   , "invariant") ;
    assert (_waiters > 0                , "invariant") ;
    assert (((oop)(object()))->mark() == markOopDesc::encode(this) , "invariant") ;
    assert (((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant") ;
    JavaThread * jt = (JavaThread *) Self ;
    int nWakeups = 0 ;
    for (;;) {
        ObjectWaiter::TStates v = SelfNode->TState ;
        guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ;
        assert    (_owner != Self, "invariant") ;
        if (TryLock (Self) > 0) break ;
        if (TrySpin (Self) > 0) break ;
        TEVENT (Wait Reentry - parking) ;
        {
           OSThreadContendState osts(Self->osthread());
           ThreadBlockInVM tbivm(jt);
           jt->set_suspend_equivalent();
           if (SyncFlags & 1) {
              Self->_ParkEvent->park ((jlong)1000) ;
           } else {
              Self->_ParkEvent->park () ;
           }
           for (;;) {
              if (!ExitSuspendEquivalent (jt)) break ;
              if (_succ == Self) { _succ = NULL; OrderAccess::fence(); }
              jt->java_suspend_self();
              jt->set_suspend_equivalent();
           }
        }
        if (TryLock(Self) > 0) break ;
        TEVENT (Wait Reentry - futile wakeup) ;
        ++ nWakeups ;
        if (_succ == Self) _succ = NULL ;
        OrderAccess::fence() ;
        if (ObjectMonitor::_sync_FutileWakeups != NULL) {
          ObjectMonitor::_sync_FutileWakeups->inc() ;
        }
    }
    assert (_owner == Self, "invariant") ;
    assert (((oop)(object()))->mark() == markOopDesc::encode(this), "invariant") ;
    UnlinkAfterAcquire (Self, SelfNode) ;
    if (_succ == Self) _succ = NULL ;
    assert (_succ != Self, "invariant") ;
    SelfNode->TState = ObjectWaiter::TS_RUN ;
    OrderAccess::fence() ;      // see comments at the end of EnterI()
}
void ObjectMonitor::UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode)
{
    assert (_owner == Self, "invariant") ;
    assert (SelfNode->_thread == Self, "invariant") ;
    if (SelfNode->TState == ObjectWaiter::TS_ENTER) {
        ObjectWaiter * nxt = SelfNode->_next ;
        ObjectWaiter * prv = SelfNode->_prev ;
        if (nxt != NULL) nxt->_prev = prv ;
        if (prv != NULL) prv->_next = nxt ;
        if (SelfNode == _EntryList ) _EntryList = nxt ;
        assert (nxt == NULL || nxt->TState == ObjectWaiter::TS_ENTER, "invariant") ;
        assert (prv == NULL || prv->TState == ObjectWaiter::TS_ENTER, "invariant") ;
        TEVENT (Unlink from EntryList) ;
    } else {
        guarantee (SelfNode->TState == ObjectWaiter::TS_CXQ, "invariant") ;
        ObjectWaiter * v = _cxq ;
        assert (v != NULL, "invariant") ;
        if (v != SelfNode || Atomic::cmpxchg_ptr (SelfNode->_next, &_cxq, v) != v) {
            if (v == SelfNode) {
                assert (_cxq != v, "invariant") ;
                v = _cxq ;          // CAS above failed - start scan at head of list
            }
            ObjectWaiter * p ;
            ObjectWaiter * q = NULL ;
            for (p = v ; p != NULL && p != SelfNode; p = p->_next) {
                q = p ;
                assert (p->TState == ObjectWaiter::TS_CXQ, "invariant") ;
            }
            assert (v != SelfNode,  "invariant") ;
            assert (p == SelfNode,  "Node not found on cxq") ;
            assert (p != _cxq,      "invariant") ;
            assert (q != NULL,      "invariant") ;
            assert (q->_next == p,  "invariant") ;
            q->_next = p->_next ;
        }
        TEVENT (Unlink from cxq) ;
    }
    SelfNode->_prev  = (ObjectWaiter *) 0xBAD ;
    SelfNode->_next  = (ObjectWaiter *) 0xBAD ;
    SelfNode->TState = ObjectWaiter::TS_RUN ;
}
void ATTR ObjectMonitor::exit(bool not_suspended, TRAPS) {
   Thread * Self = THREAD ;
   if (THREAD != _owner) {
     if (THREAD->is_lock_owned((address) _owner)) {
       assert (_recursions == 0, "invariant") ;
       _owner = THREAD ;
       _recursions = 0 ;
       OwnerIsThread = 1 ;
     } else {
       TEVENT (Exit - Throw IMSX) ;
       assert(false, "Non-balanced monitor enter/exit!");
       if (false) {
          THROW(vmSymbols::java_lang_IllegalMonitorStateException());
       }
       return;
     }
   }
   if (_recursions != 0) {
     _recursions--;        // this is simple recursive enter
     TEVENT (Inflated exit - recursive) ;
     return ;
   }
   if ((SyncFlags & 4) == 0) {
      _Responsible = NULL ;
   }
#if INCLUDE_JFR
   if (not_suspended && EventJavaMonitorEnter::is_enabled()) {
    _previous_owner_tid = JFR_THREAD_ID(Self);
   }
#endif
   for (;;) {
      assert (THREAD == _owner, "invariant") ;
      if (Knob_ExitPolicy == 0) {
         OrderAccess::release_store_ptr (&_owner, NULL) ;   // drop the lock
         OrderAccess::storeload() ;                         // See if we need to wake a successor
         if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
            TEVENT (Inflated exit - simple egress) ;
            return ;
         }
         TEVENT (Inflated exit - complex egress) ;
         if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
            return ;
         }
         TEVENT (Exit - Reacquired) ;
      } else {
         if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
            OrderAccess::release_store_ptr (&_owner, NULL) ;   // drop the lock
            OrderAccess::storeload() ;
            if (_cxq == NULL || _succ != NULL) {
                TEVENT (Inflated exit - simple egress) ;
                return ;
            }
            if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
               TEVENT (Inflated exit - reacquired succeeded) ;
               return ;
            }
            TEVENT (Inflated exit - reacquired failed) ;
         } else {
            TEVENT (Inflated exit - complex egress) ;
         }
      }
      guarantee (_owner == THREAD, "invariant") ;
      ObjectWaiter * w = NULL ;
      int QMode = Knob_QMode ;
      if (QMode == 2 && _cxq != NULL) {
          w = _cxq ;
          assert (w != NULL, "invariant") ;
          assert (w->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
          ExitEpilog (Self, w) ;
          return ;
      }
      if (QMode == 3 && _cxq != NULL) {
          w = _cxq ;
          for (;;) {
             assert (w != NULL, "Invariant") ;
             ObjectWaiter * u = (ObjectWaiter *) Atomic::cmpxchg_ptr (NULL, &_cxq, w) ;
             if (u == w) break ;
             w = u ;
          }
          assert (w != NULL              , "invariant") ;
          ObjectWaiter * q = NULL ;
          ObjectWaiter * p ;
          for (p = w ; p != NULL ; p = p->_next) {
              guarantee (p->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
              p->TState = ObjectWaiter::TS_ENTER ;
              p->_prev = q ;
              q = p ;
          }
          ObjectWaiter * Tail ;
          for (Tail = _EntryList ; Tail != NULL && Tail->_next != NULL ; Tail = Tail->_next) ;
          if (Tail == NULL) {
              _EntryList = w ;
          } else {
              Tail->_next = w ;
              w->_prev = Tail ;
          }
      }
      if (QMode == 4 && _cxq != NULL) {
          w = _cxq ;
          for (;;) {
             assert (w != NULL, "Invariant") ;
             ObjectWaiter * u = (ObjectWaiter *) Atomic::cmpxchg_ptr (NULL, &_cxq, w) ;
             if (u == w) break ;
             w = u ;
          }
          assert (w != NULL              , "invariant") ;
          ObjectWaiter * q = NULL ;
          ObjectWaiter * p ;
          for (p = w ; p != NULL ; p = p->_next) {
              guarantee (p->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
              p->TState = ObjectWaiter::TS_ENTER ;
              p->_prev = q ;
              q = p ;
          }
          if (_EntryList != NULL) {
              q->_next = _EntryList ;
              _EntryList->_prev = q ;
          }
          _EntryList = w ;
      }
      w = _EntryList  ;
      if (w != NULL) {
          assert (w->TState == ObjectWaiter::TS_ENTER, "invariant") ;
          ExitEpilog (Self, w) ;
          return ;
      }
      w = _cxq ;
      if (w == NULL) continue ;
      for (;;) {
          assert (w != NULL, "Invariant") ;
          ObjectWaiter * u = (ObjectWaiter *) Atomic::cmpxchg_ptr (NULL, &_cxq, w) ;
          if (u == w) break ;
          w = u ;
      }
      TEVENT (Inflated exit - drain cxq into EntryList) ;
      assert (w != NULL              , "invariant") ;
      assert (_EntryList  == NULL    , "invariant") ;
      if (QMode == 1) {
         ObjectWaiter * s = NULL ;
         ObjectWaiter * t = w ;
         ObjectWaiter * u = NULL ;
         while (t != NULL) {
             guarantee (t->TState == ObjectWaiter::TS_CXQ, "invariant") ;
             t->TState = ObjectWaiter::TS_ENTER ;
             u = t->_next ;
             t->_prev = u ;
             t->_next = s ;
             s = t;
             t = u ;
         }
         _EntryList  = s ;
         assert (s != NULL, "invariant") ;
      } else {
         _EntryList = w ;
         ObjectWaiter * q = NULL ;
         ObjectWaiter * p ;
         for (p = w ; p != NULL ; p = p->_next) {
             guarantee (p->TState == ObjectWaiter::TS_CXQ, "Invariant") ;
             p->TState = ObjectWaiter::TS_ENTER ;
             p->_prev = q ;
             q = p ;
         }
      }
      if (_succ != NULL) continue;
      w = _EntryList  ;
      if (w != NULL) {
          guarantee (w->TState == ObjectWaiter::TS_ENTER, "invariant") ;
          ExitEpilog (Self, w) ;
          return ;
      }
   }
}
bool ObjectMonitor::ExitSuspendEquivalent (JavaThread * jSelf) {
   int Mode = Knob_FastHSSEC ;
   if (Mode && !jSelf->is_external_suspend()) {
      assert (jSelf->is_suspend_equivalent(), "invariant") ;
      jSelf->clear_suspend_equivalent() ;
      if (2 == Mode) OrderAccess::storeload() ;
      if (!jSelf->is_external_suspend()) return false ;
      TEVENT (ExitSuspendEquivalent - raced) ;
      jSelf->set_suspend_equivalent() ;
   }
   return jSelf->handle_special_suspend_equivalent_condition() ;
}
void ObjectMonitor::ExitEpilog (Thread * Self, ObjectWaiter * Wakee) {
   assert (_owner == Self, "invariant") ;
   _succ = Knob_SuccEnabled ? Wakee->_thread : NULL ;
   ParkEvent * Trigger = Wakee->_event ;
   Wakee  = NULL ;
   OrderAccess::release_store_ptr (&_owner, NULL) ;
   OrderAccess::fence() ;                               // ST _owner vs LD in unpark()
   if (SafepointSynchronize::do_call_back()) {
      TEVENT (unpark before SAFEPOINT) ;
   }
   DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self);
   Trigger->unpark() ;
   if (ObjectMonitor::_sync_Parks != NULL) {
      ObjectMonitor::_sync_Parks->inc() ;
   }
}
intptr_t ObjectMonitor::complete_exit(TRAPS) {
   Thread * const Self = THREAD;
   assert(Self->is_Java_thread(), "Must be Java thread!");
   JavaThread *jt = (JavaThread *)THREAD;
   DeferredInitialize();
   if (THREAD != _owner) {
    if (THREAD->is_lock_owned ((address)_owner)) {
       assert(_recursions == 0, "internal state error");
       _owner = THREAD ;   /* Convert from basiclock addr to Thread addr */
       _recursions = 0 ;
       OwnerIsThread = 1 ;
    }
   }
   guarantee(Self == _owner, "complete_exit not owner");
   intptr_t save = _recursions; // record the old recursion count
   _recursions = 0;        // set the recursion level to be 0
   exit (true, Self) ;           // exit the monitor
   guarantee (_owner != Self, "invariant");
   return save;
}
void ObjectMonitor::reenter(intptr_t recursions, TRAPS) {
   Thread * const Self = THREAD;
   assert(Self->is_Java_thread(), "Must be Java thread!");
   JavaThread *jt = (JavaThread *)THREAD;
   guarantee(_owner != Self, "reenter already owner");
   enter (THREAD);       // enter the monitor
   guarantee (_recursions == 0, "reenter recursion");
   _recursions = recursions;
   return;
}
#define CHECK_OWNER()                                                             \
  do {                                                                            \
    if (THREAD != _owner) {                                                       \
      if (THREAD->is_lock_owned((address) _owner)) {                              \
        _owner = THREAD ;  /* Convert from basiclock addr to Thread addr */       \
        _recursions = 0;                                                          \
        OwnerIsThread = 1 ;                                                       \
      } else {                                                                    \
        TEVENT (Throw IMSX) ;                                                     \
        THROW(vmSymbols::java_lang_IllegalMonitorStateException());               \
      }                                                                           \
    }                                                                             \
  } while (false)
void ObjectMonitor::check_slow(TRAPS) {
  TEVENT (check_slow - throw IMSX) ;
  assert(THREAD != _owner && !THREAD->is_lock_owned((address) _owner), "must not be owner");
  THROW_MSG(vmSymbols::java_lang_IllegalMonitorStateException(), "current thread not owner");
}
static int Adjust (volatile int * adr, int dx) {
  int v ;
  for (v = *adr ; Atomic::cmpxchg (v + dx, adr, v) != v; v = *adr) ;
  return v ;
}
static void post_monitor_wait_event(EventJavaMonitorWait* event,
                                    ObjectMonitor* monitor,
                                    jlong notifier_tid,
                                    jlong timeout,
                                    bool timedout) {
  assert(monitor != NULL, "invariant");
  event->set_monitorClass(((oop)monitor->object())->klass());
  event->set_timeout(timeout);
  event->set_address((uintptr_t)monitor->object_addr());
  event->set_notifier((u8)notifier_tid);
  event->set_timedOut(timedout);
  event->commit();
}
void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
   Thread * const Self = THREAD ;
   assert(Self->is_Java_thread(), "Must be Java thread!");
   JavaThread *jt = (JavaThread *)THREAD;
   DeferredInitialize () ;
   CHECK_OWNER();
   EventJavaMonitorWait event;
   if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
     if (JvmtiExport::should_post_monitor_waited()) {
        JvmtiExport::post_monitor_waited(jt, this, false);
     }
     if (event.should_commit()) {
       post_monitor_wait_event(&event, this, 0, millis, false);
     }
     TEVENT (Wait - Throw IEX) ;
     THROW(vmSymbols::java_lang_InterruptedException());
     return ;
   }
   TEVENT (Wait) ;
   assert (Self->_Stalled == 0, "invariant") ;
   Self->_Stalled = intptr_t(this) ;
   jt->set_current_waiting_monitor(this);
   ObjectWaiter node(Self);
   node.TState = ObjectWaiter::TS_WAIT ;
   Self->_ParkEvent->reset() ;
   OrderAccess::fence();          // ST into Event; membar ; LD interrupted-flag
   Thread::SpinAcquire (&_WaitSetLock, "WaitSet - add") ;
   AddWaiter (&node) ;
   Thread::SpinRelease (&_WaitSetLock) ;
   if ((SyncFlags & 4) == 0) {
      _Responsible = NULL ;
   }
   intptr_t save = _recursions; // record the old recursion count
   _waiters++;                  // increment the number of waiters
   _recursions = 0;             // set the recursion level to be 1
   exit (true, Self) ;                    // exit the monitor
   guarantee (_owner != Self, "invariant") ;
   int ret = OS_OK ;
   int WasNotified = 0 ;
   { // State transition wrappers
     OSThread* osthread = Self->osthread();
     OSThreadWaitState osts(osthread, true);
     {
       ThreadBlockInVM tbivm(jt);
       jt->set_suspend_equivalent();
       if (interruptible && (Thread::is_interrupted(THREAD, false) || HAS_PENDING_EXCEPTION)) {
       } else
       if (node._notified == 0) {
         if (millis <= 0) {
            Self->_ParkEvent->park () ;
         } else {
            ret = Self->_ParkEvent->park (millis) ;
         }
       }
       if (ExitSuspendEquivalent (jt)) {
          jt->java_suspend_self();
       }
     } // Exit thread safepoint: transition _thread_blocked -> _thread_in_vm
     if (node.TState == ObjectWaiter::TS_WAIT) {
         Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ;
         if (node.TState == ObjectWaiter::TS_WAIT) {
            DequeueSpecificWaiter (&node) ;       // unlink from WaitSet
            assert(node._notified == 0, "invariant");
            node.TState = ObjectWaiter::TS_RUN ;
         }
         Thread::SpinRelease (&_WaitSetLock) ;
     }
     guarantee (node.TState != ObjectWaiter::TS_WAIT, "invariant") ;
     OrderAccess::loadload() ;
     if (_succ == Self) _succ = NULL ;
     WasNotified = node._notified ;
     if (JvmtiExport::should_post_monitor_waited()) {
       JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
       if (node._notified != 0 && _succ == Self) {
         node._event->unpark();
       }
     }
     if (event.should_commit()) {
       post_monitor_wait_event(&event, this, node._notifier_tid, millis, ret == OS_TIMEOUT);
     }
     OrderAccess::fence() ;
     assert (Self->_Stalled != 0, "invariant") ;
     Self->_Stalled = 0 ;
     assert (_owner != Self, "invariant") ;
     ObjectWaiter::TStates v = node.TState ;
     if (v == ObjectWaiter::TS_RUN) {
         enter (Self) ;
     } else {
         guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ;
         ReenterI (Self, &node) ;
         node.wait_reenter_end(this);
     }
     guarantee (node.TState == ObjectWaiter::TS_RUN, "invariant") ;
     assert    (_owner == Self, "invariant") ;
     assert    (_succ != Self , "invariant") ;
   } // OSThreadWaitState()
   jt->set_current_waiting_monitor(NULL);
   guarantee (_recursions == 0, "invariant") ;
   _recursions = save;     // restore the old recursion count
   _waiters--;             // decrement the number of waiters
   assert (_owner == Self       , "invariant") ;
   assert (_succ  != Self       , "invariant") ;
   assert (((oop)(object()))->mark() == markOopDesc::encode(this), "invariant") ;
   if (SyncFlags & 32) {
      OrderAccess::fence() ;
   }
   if (!WasNotified) {
     if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
       TEVENT (Wait - throw IEX from epilog) ;
       THROW(vmSymbols::java_lang_InterruptedException());
     }
   }
}
void ObjectMonitor::notify(TRAPS) {
  CHECK_OWNER();
  if (_WaitSet == NULL) {
     TEVENT (Empty-Notify) ;
     return ;
  }
  DTRACE_MONITOR_PROBE(notify, this, object(), THREAD);
  int Policy = Knob_MoveNotifyee ;
  Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notify") ;
  ObjectWaiter * iterator = DequeueWaiter() ;
  if (iterator != NULL) {
     TEVENT (Notify1 - Transfer) ;
     guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ;
     guarantee (iterator->_notified == 0, "invariant") ;
     if (Policy != 4) {
        iterator->TState = ObjectWaiter::TS_ENTER ;
     }
     iterator->_notified = 1 ;
     Thread * Self = THREAD;
     iterator->_notifier_tid = JFR_THREAD_ID(Self);
     ObjectWaiter * List = _EntryList ;
     if (List != NULL) {
        assert (List->_prev == NULL, "invariant") ;
        assert (List->TState == ObjectWaiter::TS_ENTER, "invariant") ;
        assert (List != iterator, "invariant") ;
     }
     if (Policy == 0) {       // prepend to EntryList
         if (List == NULL) {
             iterator->_next = iterator->_prev = NULL ;
             _EntryList = iterator ;
         } else {
             List->_prev = iterator ;
             iterator->_next = List ;
             iterator->_prev = NULL ;
             _EntryList = iterator ;
        }
     } else
     if (Policy == 1) {      // append to EntryList
         if (List == NULL) {
             iterator->_next = iterator->_prev = NULL ;
             _EntryList = iterator ;
         } else {
            ObjectWaiter * Tail ;
            for (Tail = List ; Tail->_next != NULL ; Tail = Tail->_next) ;
            assert (Tail != NULL && Tail->_next == NULL, "invariant") ;
            Tail->_next = iterator ;
            iterator->_prev = Tail ;
            iterator->_next = NULL ;
        }
     } else
     if (Policy == 2) {      // prepend to cxq
         if (List == NULL) {
             iterator->_next = iterator->_prev = NULL ;
             _EntryList = iterator ;
         } else {
            iterator->TState = ObjectWaiter::TS_CXQ ;
            for (;;) {
                ObjectWaiter * Front = _cxq ;
                iterator->_next = Front ;
                if (Atomic::cmpxchg_ptr (iterator, &_cxq, Front) == Front) {
                    break ;
                }
            }
         }
     } else
     if (Policy == 3) {      // append to cxq
        iterator->TState = ObjectWaiter::TS_CXQ ;
        for (;;) {
            ObjectWaiter * Tail ;
            Tail = _cxq ;
            if (Tail == NULL) {
                iterator->_next = NULL ;
                if (Atomic::cmpxchg_ptr (iterator, &_cxq, NULL) == NULL) {
                   break ;
                }
            } else {
                while (Tail->_next != NULL) Tail = Tail->_next ;
                Tail->_next = iterator ;
                iterator->_prev = Tail ;
                iterator->_next = NULL ;
                break ;
            }
        }
     } else {
        ParkEvent * ev = iterator->_event ;
        iterator->TState = ObjectWaiter::TS_RUN ;
        OrderAccess::fence() ;
        ev->unpark() ;
     }
     if (Policy < 4) {
       iterator->wait_reenter_begin(this);
     }
  }
  Thread::SpinRelease (&_WaitSetLock) ;
  if (iterator != NULL && ObjectMonitor::_sync_Notifications != NULL) {
     ObjectMonitor::_sync_Notifications->inc() ;
  }
}
void ObjectMonitor::notifyAll(TRAPS) {
  CHECK_OWNER();
  ObjectWaiter* iterator;
  if (_WaitSet == NULL) {
      TEVENT (Empty-NotifyAll) ;
      return ;
  }
  DTRACE_MONITOR_PROBE(notifyAll, this, object(), THREAD);
  int Policy = Knob_MoveNotifyee ;
  int Tally = 0 ;
  Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notifyall") ;
  for (;;) {
     iterator = DequeueWaiter () ;
     if (iterator == NULL) break ;
     TEVENT (NotifyAll - Transfer1) ;
     ++Tally ;
     guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ;
     guarantee (iterator->_notified == 0, "invariant") ;
     iterator->_notified = 1 ;
     Thread * Self = THREAD;
     iterator->_notifier_tid = JFR_THREAD_ID(Self);
     if (Policy != 4) {
        iterator->TState = ObjectWaiter::TS_ENTER ;
     }
     ObjectWaiter * List = _EntryList ;
     if (List != NULL) {
        assert (List->_prev == NULL, "invariant") ;
        assert (List->TState == ObjectWaiter::TS_ENTER, "invariant") ;
        assert (List != iterator, "invariant") ;
     }
     if (Policy == 0) {       // prepend to EntryList
         if (List == NULL) {
             iterator->_next = iterator->_prev = NULL ;
             _EntryList = iterator ;
         } else {
             List->_prev = iterator ;
             iterator->_next = List ;
             iterator->_prev = NULL ;
             _EntryList = iterator ;
        }
     } else
     if (Policy == 1) {      // append to EntryList
         if (List == NULL) {
             iterator->_next = iterator->_prev = NULL ;
             _EntryList = iterator ;
         } else {
            ObjectWaiter * Tail ;
            for (Tail = List ; Tail->_next != NULL ; Tail = Tail->_next) ;
            assert (Tail != NULL && Tail->_next == NULL, "invariant") ;
            Tail->_next = iterator ;
            iterator->_prev = Tail ;
            iterator->_next = NULL ;
        }
     } else
     if (Policy == 2) {      // prepend to cxq
         iterator->TState = ObjectWaiter::TS_CXQ ;
         for (;;) {
             ObjectWaiter * Front = _cxq ;
             iterator->_next = Front ;
             if (Atomic::cmpxchg_ptr (iterator, &_cxq, Front) == Front) {
                 break ;
             }
         }
     } else
     if (Policy == 3) {      // append to cxq
        iterator->TState = ObjectWaiter::TS_CXQ ;
        for (;;) {
            ObjectWaiter * Tail ;
            Tail = _cxq ;
            if (Tail == NULL) {
                iterator->_next = NULL ;
                if (Atomic::cmpxchg_ptr (iterator, &_cxq, NULL) == NULL) {
                   break ;
                }
            } else {
                while (Tail->_next != NULL) Tail = Tail->_next ;
                Tail->_next = iterator ;
                iterator->_prev = Tail ;
                iterator->_next = NULL ;
                break ;
            }
        }
     } else {
        ParkEvent * ev = iterator->_event ;
        iterator->TState = ObjectWaiter::TS_RUN ;
        OrderAccess::fence() ;
        ev->unpark() ;
     }
     if (Policy < 4) {
       iterator->wait_reenter_begin(this);
     }
  }
  Thread::SpinRelease (&_WaitSetLock) ;
  if (Tally != 0 && ObjectMonitor::_sync_Notifications != NULL) {
     ObjectMonitor::_sync_Notifications->inc(Tally) ;
  }
}
intptr_t ObjectMonitor::SpinCallbackArgument = 0 ;
int (*ObjectMonitor::SpinCallbackFunction)(intptr_t, int) = NULL ;
int ObjectMonitor::TrySpin_VaryDuration (Thread * Self) {
    int ctr = Knob_FixedSpin ;
    if (ctr != 0) {
        while (--ctr >= 0) {
            if (TryLock (Self) > 0) return 1 ;
            SpinPause () ;
        }
        return 0 ;
    }
    for (ctr = Knob_PreSpin + 1; --ctr >= 0 ; ) {
      if (TryLock(Self) > 0) {
        int x = _SpinDuration ;
        if (x < Knob_SpinLimit) {
           if (x < Knob_Poverty) x = Knob_Poverty ;
           _SpinDuration = x + Knob_BonusB ;
        }
        return 1 ;
      }
      SpinPause () ;
    }
    ctr = _SpinDuration  ;
    if (ctr < Knob_SpinBase) ctr = Knob_SpinBase ;
    if (ctr <= 0) return 0 ;
    if (Knob_SuccRestrict && _succ != NULL) return 0 ;
    if (Knob_OState && NotRunnable (Self, (Thread *) _owner)) {
       TEVENT (Spin abort - notrunnable [TOP]);
       return 0 ;
    }
    int MaxSpin = Knob_MaxSpinners ;
    if (MaxSpin >= 0) {
       if (_Spinner > MaxSpin) {
          TEVENT (Spin abort -- too many spinners) ;
          return 0 ;
       }
       Adjust (&_Spinner, 1) ;
    }
    int hits    = 0 ;
    int msk     = 0 ;
    int caspty  = Knob_CASPenalty ;
    int oxpty   = Knob_OXPenalty ;
    int sss     = Knob_SpinSetSucc ;
    if (sss && _succ == NULL ) _succ = Self ;
    Thread * prv = NULL ;
    while (--ctr >= 0) {
      if ((ctr & 0xFF) == 0) {
         if (SafepointSynchronize::do_call_back()) {
            TEVENT (Spin: safepoint) ;
            goto Abort ;           // abrupt spin egress
         }
         if (Knob_UsePause & 1) SpinPause () ;
         int (*scb)(intptr_t,int) = SpinCallbackFunction ;
         if (hits > 50 && scb != NULL) {
            int abend = (*scb)(SpinCallbackArgument, 0) ;
         }
      }
      if (Knob_UsePause & 2) SpinPause() ;
      if (ctr & msk) continue ;
      ++hits ;
      if ((hits & 0xF) == 0) {
        msk = ((msk << 2)|3) & BackOffMask ;
      }
      Thread * ox = (Thread *) _owner ;
      if (ox == NULL) {
         ox = (Thread *) Atomic::cmpxchg_ptr (Self, &_owner, NULL) ;
         if (ox == NULL) {
            if (sss && _succ == Self) {
               _succ = NULL ;
            }
            if (MaxSpin > 0) Adjust (&_Spinner, -1) ;
            int x = _SpinDuration ;
            if (x < Knob_SpinLimit) {
                if (x < Knob_Poverty) x = Knob_Poverty ;
                _SpinDuration = x + Knob_Bonus ;
            }
            return 1 ;
         }
         prv = ox ;
         TEVENT (Spin: cas failed) ;
         if (caspty == -2) break ;
         if (caspty == -1) goto Abort ;
         ctr -= caspty ;
         continue ;
      }
      if (ox != prv && prv != NULL ) {
          TEVENT (spin: Owner changed)
          if (oxpty == -2) break ;
          if (oxpty == -1) goto Abort ;
          ctr -= oxpty ;
      }
      prv = ox ;
      if (Knob_OState && NotRunnable (Self, ox)) {
         TEVENT (Spin abort - notrunnable);
         goto Abort ;
      }
      if (sss && _succ == NULL ) _succ = Self ;
   }
   TEVENT (Spin failure) ;
   {
     int x = _SpinDuration ;
     if (x > 0) {
        x -= Knob_Penalty ;
        if (x < 0) x = 0 ;
        _SpinDuration = x ;
     }
   }
 Abort:
   if (MaxSpin >= 0) Adjust (&_Spinner, -1) ;
   if (sss && _succ == Self) {
      _succ = NULL ;
      OrderAccess::fence() ;
      if (TryLock(Self) > 0) return 1 ;
   }
   return 0 ;
}
int ObjectMonitor::NotRunnable (Thread * Self, Thread * ox) {
    if (!OwnerIsThread) return 0 ;
    if (ox == NULL) return 0 ;
    intptr_t BlockedOn = SafeFetchN ((intptr_t *) &ox->_Stalled, intptr_t(1)) ;
    if (BlockedOn == 1) return 1 ;
    if (BlockedOn != 0) {
      return BlockedOn != intptr_t(this) && _owner == ox ;
    }
    assert (sizeof(((JavaThread *)ox)->_thread_state == sizeof(int)), "invariant") ;
    int jst = SafeFetch32 ((int *) &((JavaThread *) ox)->_thread_state, -1) ; ;
    return jst == _thread_blocked || jst == _thread_in_native ;
}
ObjectWaiter::ObjectWaiter(Thread* thread) {
  _next     = NULL;
  _prev     = NULL;
  _notified = 0;
  _notifier_tid = 0;
  TState    = TS_RUN ;
  _thread   = thread;
  _event    = thread->_ParkEvent ;
  _active   = false;
  assert (_event != NULL, "invariant") ;
}
void ObjectWaiter::wait_reenter_begin(ObjectMonitor *mon) {
  JavaThread *jt = (JavaThread *)this->_thread;
  _active = JavaThreadBlockedOnMonitorEnterState::wait_reenter_begin(jt, mon);
}
void ObjectWaiter::wait_reenter_end(ObjectMonitor *mon) {
  JavaThread *jt = (JavaThread *)this->_thread;
  JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active);
}
inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) {
  assert(node != NULL, "should not dequeue NULL node");
  assert(node->_prev == NULL, "node already in list");
  assert(node->_next == NULL, "node already in list");
  if (_WaitSet == NULL) {
    _WaitSet = node;
    node->_prev = node;
    node->_next = node;
  } else {
    ObjectWaiter* head = _WaitSet ;
    ObjectWaiter* tail = head->_prev;
    assert(tail->_next == head, "invariant check");
    tail->_next = node;
    head->_prev = node;
    node->_next = head;
    node->_prev = tail;
  }
}
inline ObjectWaiter* ObjectMonitor::DequeueWaiter() {
  ObjectWaiter* waiter = _WaitSet;
  if (waiter) {
    DequeueSpecificWaiter(waiter);
  }
  return waiter;
}
inline void ObjectMonitor::DequeueSpecificWaiter(ObjectWaiter* node) {
  assert(node != NULL, "should not dequeue NULL node");
  assert(node->_prev != NULL, "node already removed from list");
  assert(node->_next != NULL, "node already removed from list");
  ObjectWaiter* next = node->_next;
  if (next == node) {
    assert(node->_prev == node, "invariant check");
    _WaitSet = NULL;
  } else {
    ObjectWaiter* prev = node->_prev;
    assert(prev->_next == node, "invariant check");
    assert(next->_prev == node, "invariant check");
    next->_prev = prev;
    prev->_next = next;
    if (_WaitSet == node) {
      _WaitSet = next;
    }
  }
  node->_next = NULL;
  node->_prev = NULL;
}
PerfCounter * ObjectMonitor::_sync_ContendedLockAttempts       = NULL ;
PerfCounter * ObjectMonitor::_sync_FutileWakeups               = NULL ;
PerfCounter * ObjectMonitor::_sync_Parks                       = NULL ;
PerfCounter * ObjectMonitor::_sync_EmptyNotifications          = NULL ;
PerfCounter * ObjectMonitor::_sync_Notifications               = NULL ;
PerfCounter * ObjectMonitor::_sync_PrivateA                    = NULL ;
PerfCounter * ObjectMonitor::_sync_PrivateB                    = NULL ;
PerfCounter * ObjectMonitor::_sync_SlowExit                    = NULL ;
PerfCounter * ObjectMonitor::_sync_SlowEnter                   = NULL ;
PerfCounter * ObjectMonitor::_sync_SlowNotify                  = NULL ;
PerfCounter * ObjectMonitor::_sync_SlowNotifyAll               = NULL ;
PerfCounter * ObjectMonitor::_sync_FailedSpins                 = NULL ;
PerfCounter * ObjectMonitor::_sync_SuccessfulSpins             = NULL ;
PerfCounter * ObjectMonitor::_sync_MonInCirculation            = NULL ;
PerfCounter * ObjectMonitor::_sync_MonScavenged                = NULL ;
PerfCounter * ObjectMonitor::_sync_Inflations                  = NULL ;
PerfCounter * ObjectMonitor::_sync_Deflations                  = NULL ;
PerfLongVariable * ObjectMonitor::_sync_MonExtant              = NULL ;
void ObjectMonitor::Initialize () {
  static int InitializationCompleted = 0 ;
  assert (InitializationCompleted == 0, "invariant") ;
  InitializationCompleted = 1 ;
  if (UsePerfData) {
      EXCEPTION_MARK ;
      #define NEWPERFCOUNTER(n)   {n = PerfDataManager::create_counter(SUN_RT, #n, PerfData::U_Events,CHECK); }
      #define NEWPERFVARIABLE(n)  {n = PerfDataManager::create_variable(SUN_RT, #n, PerfData::U_Events,CHECK); }
      NEWPERFCOUNTER(_sync_Inflations) ;
      NEWPERFCOUNTER(_sync_Deflations) ;
      NEWPERFCOUNTER(_sync_ContendedLockAttempts) ;
      NEWPERFCOUNTER(_sync_FutileWakeups) ;
      NEWPERFCOUNTER(_sync_Parks) ;
      NEWPERFCOUNTER(_sync_EmptyNotifications) ;
      NEWPERFCOUNTER(_sync_Notifications) ;
      NEWPERFCOUNTER(_sync_SlowEnter) ;
      NEWPERFCOUNTER(_sync_SlowExit) ;
      NEWPERFCOUNTER(_sync_SlowNotify) ;
      NEWPERFCOUNTER(_sync_SlowNotifyAll) ;
      NEWPERFCOUNTER(_sync_FailedSpins) ;
      NEWPERFCOUNTER(_sync_SuccessfulSpins) ;
      NEWPERFCOUNTER(_sync_PrivateA) ;
      NEWPERFCOUNTER(_sync_PrivateB) ;
      NEWPERFCOUNTER(_sync_MonInCirculation) ;
      NEWPERFCOUNTER(_sync_MonScavenged) ;
      NEWPERFVARIABLE(_sync_MonExtant) ;
      #undef NEWPERFCOUNTER
  }
}
#define CTASSERT(x) { int tag[1-(2*!(x))]; printf ("Tag @" INTPTR_FORMAT "\n", (intptr_t)tag); }
void ObjectMonitor::ctAsserts() {
  CTASSERT(offset_of (ObjectMonitor, _header) == 0);
}
static char * kvGet (char * kvList, const char * Key) {
    if (kvList == NULL) return NULL ;
    size_t n = strlen (Key) ;
    char * Search ;
    for (Search = kvList ; *Search ; Search += strlen(Search) + 1) {
        if (strncmp (Search, Key, n) == 0) {
            if (Search[n] == '=') return Search + n + 1 ;
            if (Search[n] == 0)   return (char *) "1" ;
        }
    }
    return NULL ;
}
static int kvGetInt (char * kvList, const char * Key, int Default) {
    char * v = kvGet (kvList, Key) ;
    int rslt = v ? ::strtol (v, NULL, 0) : Default ;
    if (Knob_ReportSettings && v != NULL) {
        ::printf ("  SyncKnob: %s %d(%d)\n", Key, rslt, Default) ;
        ::fflush (stdout) ;
    }
    return rslt ;
}
void ObjectMonitor::DeferredInitialize () {
  if (InitDone > 0) return ;
  if (Atomic::cmpxchg (-1, &InitDone, 0) != 0) {
      while (InitDone != 1) ;
      return ;
  }
  if (SyncKnobs == NULL) SyncKnobs = "" ;
  size_t sz = strlen (SyncKnobs) ;
  char * knobs = (char *) malloc (sz + 2) ;
  if (knobs == NULL) {
     vm_exit_out_of_memory (sz + 2, OOM_MALLOC_ERROR, "Parse SyncKnobs") ;
     guarantee (0, "invariant") ;
  }
  strcpy (knobs, SyncKnobs) ;
  knobs[sz+1] = 0 ;
  for (char * p = knobs ; *p ; p++) {
     if (*p == ':') *p = 0 ;
  }
  #define SETKNOB(x) { Knob_##x = kvGetInt (knobs, #x, Knob_##x); }
  SETKNOB(ReportSettings) ;
  SETKNOB(Verbose) ;
  SETKNOB(FixedSpin) ;
  SETKNOB(SpinLimit) ;
  SETKNOB(SpinBase) ;
  SETKNOB(SpinBackOff);
  SETKNOB(CASPenalty) ;
  SETKNOB(OXPenalty) ;
  SETKNOB(LogSpins) ;
  SETKNOB(SpinSetSucc) ;
  SETKNOB(SuccEnabled) ;
  SETKNOB(SuccRestrict) ;
  SETKNOB(Penalty) ;
  SETKNOB(Bonus) ;
  SETKNOB(BonusB) ;
  SETKNOB(Poverty) ;
  SETKNOB(SpinAfterFutile) ;
  SETKNOB(UsePause) ;
  SETKNOB(SpinEarly) ;
  SETKNOB(OState) ;
  SETKNOB(MaxSpinners) ;
  SETKNOB(PreSpin) ;
  SETKNOB(ExitPolicy) ;
  SETKNOB(QMode);
  SETKNOB(ResetEvent) ;
  SETKNOB(MoveNotifyee) ;
  SETKNOB(FastHSSEC) ;
  #undef SETKNOB
  if (Knob_Verbose) {
    sanity_checks();
  }
  if (os::is_MP()) {
     BackOffMask = (1 << Knob_SpinBackOff) - 1 ;
     if (Knob_ReportSettings) ::printf ("BackOffMask=%X\n", BackOffMask) ;
  } else {
     Knob_SpinLimit = 0 ;
     Knob_SpinBase  = 0 ;
     Knob_PreSpin   = 0 ;
     Knob_FixedSpin = -1 ;
  }
  if (Knob_LogSpins == 0) {
     ObjectMonitor::_sync_FailedSpins = NULL ;
  }
  free (knobs) ;
  OrderAccess::fence() ;
  InitDone = 1 ;
}
void ObjectMonitor::sanity_checks() {
  int error_cnt = 0;
  int warning_cnt = 0;
  bool verbose = Knob_Verbose != 0 NOT_PRODUCT(|| VerboseInternalVMTests);
  if (verbose) {
    tty->print_cr("INFO: sizeof(ObjectMonitor)=" SIZE_FORMAT,
                  sizeof(ObjectMonitor));
  }
  uint cache_line_size = VM_Version::L1_data_cache_line_size();
  if (verbose) {
    tty->print_cr("INFO: L1_data_cache_line_size=%u", cache_line_size);
  }
  ObjectMonitor dummy;
  u_char *addr_begin  = (u_char*)&dummy;
  u_char *addr_header = (u_char*)&dummy._header;
  u_char *addr_owner  = (u_char*)&dummy._owner;
  uint offset_header = (uint)(addr_header - addr_begin);
  if (verbose) tty->print_cr("INFO: offset(_header)=%u", offset_header);
  uint offset_owner = (uint)(addr_owner - addr_begin);
  if (verbose) tty->print_cr("INFO: offset(_owner)=%u", offset_owner);
  if ((uint)(addr_header - addr_begin) != 0) {
    tty->print_cr("ERROR: offset(_header) must be zero (0).");
    error_cnt++;
  }
  if (cache_line_size != 0) {
    if ((offset_owner - offset_header) < cache_line_size) {
      tty->print_cr("WARNING: the _header and _owner fields are closer "
                    "than a cache line which permits false sharing.");
      warning_cnt++;
    }
    if ((sizeof(ObjectMonitor) % cache_line_size) != 0) {
      tty->print_cr("WARNING: ObjectMonitor size is not a multiple of "
                    "a cache line which permits false sharing.");
      warning_cnt++;
    }
  }
  ObjectSynchronizer::sanity_checks(verbose, cache_line_size, &error_cnt,
                                    &warning_cnt);
  if (verbose || error_cnt != 0 || warning_cnt != 0) {
    tty->print_cr("INFO: error_cnt=%d", error_cnt);
    tty->print_cr("INFO: warning_cnt=%d", warning_cnt);
  }
  guarantee(error_cnt == 0,
            "Fatal error(s) found in ObjectMonitor::sanity_checks()");
}
#ifndef PRODUCT
void ObjectMonitor::verify() {
}
void ObjectMonitor::print() {
}
#endif
C:\hotspot-69087d08d473\src\share\vm/runtime/objectMonitor.hpp
#ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
#define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
#include "runtime/os.hpp"
#include "runtime/park.hpp"
#include "runtime/perfData.hpp"
class ObjectWaiter : public StackObj {
 public:
  enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;
  enum Sorted  { PREPEND, APPEND, SORTED } ;
  ObjectWaiter * volatile _next;
  ObjectWaiter * volatile _prev;
  Thread*       _thread;
  jlong         _notifier_tid;
  ParkEvent *   _event;
  volatile int  _notified ;
  volatile TStates TState ;
  Sorted        _Sorted ;           // List placement disposition
  bool          _active ;           // Contention monitoring is enabled
 public:
  ObjectWaiter(Thread* thread);
  void wait_reenter_begin(ObjectMonitor *mon);
  void wait_reenter_end(ObjectMonitor *mon);
};
class ObjectMonitor {
 public:
  enum {
    OM_OK,                    // no error
    OM_SYSTEM_ERROR,          // operating system error
    OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
    OM_INTERRUPTED,           // Thread.interrupt()
    OM_TIMED_OUT              // Object.wait() timed out
  };
 public:
  static int header_offset_in_bytes()      { return offset_of(ObjectMonitor, _header);     }
  static int object_offset_in_bytes()      { return offset_of(ObjectMonitor, _object);     }
  static int owner_offset_in_bytes()       { return offset_of(ObjectMonitor, _owner);      }
  static int count_offset_in_bytes()       { return offset_of(ObjectMonitor, _count);      }
  static int recursions_offset_in_bytes()  { return offset_of(ObjectMonitor, _recursions); }
  static int cxq_offset_in_bytes()         { return offset_of(ObjectMonitor, _cxq) ;       }
  static int succ_offset_in_bytes()        { return offset_of(ObjectMonitor, _succ) ;      }
  static int EntryList_offset_in_bytes()   { return offset_of(ObjectMonitor, _EntryList);  }
  static int FreeNext_offset_in_bytes()    { return offset_of(ObjectMonitor, FreeNext);    }
  static int WaitSet_offset_in_bytes()     { return offset_of(ObjectMonitor, _WaitSet) ;   }
  static int Responsible_offset_in_bytes() { return offset_of(ObjectMonitor, _Responsible);}
  static int Spinner_offset_in_bytes()     { return offset_of(ObjectMonitor, _Spinner);    }
 public:
  static int (*SpinCallbackFunction)(intptr_t, int) ;
  static intptr_t SpinCallbackArgument ;
 public:
  markOop   header() const;
  void      set_header(markOop hdr);
  intptr_t is_busy() const {
    return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList ) ;
  }
  intptr_t  is_entered(Thread* current) const;
  void*     owner() const;
  void      set_owner(void* owner);
  intptr_t  waiters() const;
  intptr_t  count() const;
  void      set_count(intptr_t count);
  intptr_t  contentions() const ;
  intptr_t  recursions() const                                         { return _recursions; }
  ObjectWaiter* first_waiter()                                         { return _WaitSet; }
  ObjectWaiter* next_waiter(ObjectWaiter* o)                           { return o->_next; }
  Thread* thread_of_waiter(ObjectWaiter* o)                            { return o->_thread; }
  ObjectMonitor() {
    _header       = NULL;
    _count        = 0;
    _waiters      = 0,
    _recursions   = 0;
    _object       = NULL;
    _owner        = NULL;
    _WaitSet      = NULL;
    _WaitSetLock  = 0 ;
    _Responsible  = NULL ;
    _succ         = NULL ;
    _cxq          = NULL ;
    FreeNext      = NULL ;
    _EntryList    = NULL ;
    _SpinFreq     = 0 ;
    _SpinClock    = 0 ;
    OwnerIsThread = 0 ;
    _previous_owner_tid = 0;
  }
  ~ObjectMonitor() {
  }
private:
  void Recycle () {
    _succ          = NULL ;
    _EntryList     = NULL ;
    _cxq           = NULL ;
    _WaitSet       = NULL ;
    _recursions    = 0 ;
    _SpinFreq      = 0 ;
    _SpinClock     = 0 ;
    OwnerIsThread  = 0 ;
  }
public:
  void*     object() const;
  void*     object_addr();
  void      set_object(void* obj);
  bool      check(TRAPS);       // true if the thread owns the monitor.
  void      check_slow(TRAPS);
  void      clear();
  static void sanity_checks();  // public for -XX:+ExecuteInternalVMTests
#ifndef PRODUCT
  void      verify();
  void      print();
#endif
  bool      try_enter (TRAPS) ;
  void      enter(TRAPS);
  void      exit(bool not_suspended, TRAPS);
  void      wait(jlong millis, bool interruptable, TRAPS);
  void      notify(TRAPS);
  void      notifyAll(TRAPS);
  intptr_t  complete_exit(TRAPS);
  void      reenter(intptr_t recursions, TRAPS);
 private:
  void      AddWaiter (ObjectWaiter * waiter) ;
  static    void DeferredInitialize();
  ObjectWaiter * DequeueWaiter () ;
  void      DequeueSpecificWaiter (ObjectWaiter * waiter) ;
  void      EnterI (TRAPS) ;
  void      ReenterI (Thread * Self, ObjectWaiter * SelfNode) ;
  void      UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode) ;
  int       TryLock (Thread * Self) ;
  int       NotRunnable (Thread * Self, Thread * Owner) ;
  int       TrySpin_Fixed (Thread * Self) ;
  int       TrySpin_VaryFrequency (Thread * Self) ;
  int       TrySpin_VaryDuration  (Thread * Self) ;
  void      ctAsserts () ;
  void      ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
  bool      ExitSuspendEquivalent (JavaThread * Self) ;
 private:
  friend class ObjectSynchronizer;
  friend class ObjectWaiter;
  friend class VMStructs;
  volatile markOop   _header;       // displaced object header word - mark
  void*     volatile _object;       // backward object pointer - strong root
  double SharingPad [1] ;           // temp to reduce false sharing
 protected:                         // protected for jvmtiRawMonitor
  void *  volatile _owner;          // pointer to owning thread OR BasicLock
  volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
  volatile intptr_t  _recursions;   // recursion count, 0 for first entry
 private:
  int OwnerIsThread ;               // _owner is (Thread *) vs SP/BasicLock
  ObjectWaiter * volatile _cxq ;    // LL of recently-arrived threads blocked on entry.
 protected:
  ObjectWaiter * volatile _EntryList ;     // Threads blocked on entry or reentry.
 private:
  Thread * volatile _succ ;          // Heir presumptive thread - used for futile wakeup throttling
  Thread * volatile _Responsible ;
  int _PromptDrain ;                // rqst to drain cxq into EntryList ASAP
  volatile int _Spinner ;           // for exit->spinner handoff optimization
  volatile int _SpinFreq ;          // Spin 1-out-of-N attempts: success rate
  volatile int _SpinClock ;
  volatile int _SpinDuration ;
  volatile intptr_t _SpinState ;    // MCS/CLH list of spinners
  volatile intptr_t  _count;        // reference count to prevent reclaimation/deflation
 protected:
  volatile intptr_t  _waiters;      // number of waiting threads
 private:
 protected:
  ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
 private:
  volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
 public:
  int _QMix ;                       // Mixed prepend queue discipline
  ObjectMonitor * FreeNext ;        // Free list linkage
  intptr_t StatA, StatsB ;
 public:
  static void Initialize () ;
  static PerfCounter * _sync_ContendedLockAttempts ;
  static PerfCounter * _sync_FutileWakeups ;
  static PerfCounter * _sync_Parks ;
  static PerfCounter * _sync_EmptyNotifications ;
  static PerfCounter * _sync_Notifications ;
  static PerfCounter * _sync_SlowEnter ;
  static PerfCounter * _sync_SlowExit ;
  static PerfCounter * _sync_SlowNotify ;
  static PerfCounter * _sync_SlowNotifyAll ;
  static PerfCounter * _sync_FailedSpins ;
  static PerfCounter * _sync_SuccessfulSpins ;
  static PerfCounter * _sync_PrivateA ;
  static PerfCounter * _sync_PrivateB ;
  static PerfCounter * _sync_MonInCirculation ;
  static PerfCounter * _sync_MonScavenged ;
  static PerfCounter * _sync_Inflations ;
  static PerfCounter * _sync_Deflations ;
  static PerfLongVariable * _sync_MonExtant ;
 public:
  static int Knob_Verbose;
  static int Knob_SpinLimit;
  void* operator new (size_t size) throw() {
    return AllocateHeap(size, mtInternal);
  }
  void* operator new[] (size_t size) throw() {
    return operator new (size);
  }
  void operator delete(void* p) {
    FreeHeap(p, mtInternal);
  }
  void operator delete[] (void *p) {
    operator delete(p);
  }
};
#undef TEVENT
#define TEVENT(nom) {if (SyncVerbose) FEVENT(nom); }
#define FEVENT(nom) { static volatile int ctr = 0 ; int v = ++ctr ; if ((v & (v-1)) == 0) { ::printf (#nom " : %d \n", v); ::fflush(stdout); }}
#undef  TEVENT
#define TEVENT(nom) {;}
#endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/objectMonitor.inline.hpp
#ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_INLINE_HPP
#define SHARE_VM_RUNTIME_OBJECTMONITOR_INLINE_HPP
inline intptr_t ObjectMonitor::is_entered(TRAPS) const {
  if (THREAD == _owner || THREAD->is_lock_owned((address) _owner)) {
    return 1;
  }
  return 0;
}
inline markOop ObjectMonitor::header() const {
  return _header;
}
inline void ObjectMonitor::set_header(markOop hdr) {
  _header = hdr;
}
inline intptr_t ObjectMonitor::count() const {
  return _count;
}
inline void ObjectMonitor::set_count(intptr_t count) {
  _count= count;
}
inline intptr_t ObjectMonitor::waiters() const {
  return _waiters;
}
inline void* ObjectMonitor::owner() const {
  return _owner;
}
inline void ObjectMonitor::clear() {
  assert(_header, "Fatal logic error in ObjectMonitor header!");
  assert(_count == 0, "Fatal logic error in ObjectMonitor count!");
  assert(_waiters == 0, "Fatal logic error in ObjectMonitor waiters!");
  assert(_recursions == 0, "Fatal logic error in ObjectMonitor recursions!");
  assert(_object, "Fatal logic error in ObjectMonitor object!");
  assert(_owner == 0, "Fatal logic error in ObjectMonitor owner!");
  _header = NULL;
  _object = NULL;
}
inline void* ObjectMonitor::object() const {
  return _object;
}
inline void* ObjectMonitor::object_addr() {
  return (void *)(&_object);
}
inline void ObjectMonitor::set_object(void* obj) {
  _object = obj;
}
inline bool ObjectMonitor::check(TRAPS) {
  if (THREAD != _owner) {
    if (THREAD->is_lock_owned((address) _owner)) {
      _owner = THREAD;  // regain ownership of inflated monitor
      OwnerIsThread = 1 ;
      assert (_recursions == 0, "invariant") ;
    } else {
      check_slow(THREAD);
      return false;
    }
  }
  return true;
}
inline intptr_t ObjectMonitor::contentions() const {
  return _count;
}
inline void ObjectMonitor::set_owner(void* owner) {
  _owner = owner;
  _recursions = 0;
}
#endif // SHARE_VM_RUNTIME_OBJECTMONITOR_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/orderAccess.cpp
#include "precompiled.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.hpp"
void OrderAccess::StubRoutines_fence() {
  void (*func)() = CAST_TO_FN_PTR(void (*)(), StubRoutines::fence_entry());
  if (func != NULL) {
    (*func)();
    return;
  }
  assert(Threads::number_of_threads() == 0, "for bootstrap only");
}
C:\hotspot-69087d08d473\src\share\vm/runtime/orderAccess.hpp
#ifndef SHARE_VM_RUNTIME_ORDERACCESS_HPP
#define SHARE_VM_RUNTIME_ORDERACCESS_HPP
#include "memory/allocation.hpp"
class OrderAccess : AllStatic {
 public:
  static void     loadload();
  static void     storestore();
  static void     loadstore();
  static void     storeload();
  static void     acquire();
  static void     release();
  static void     fence();
  static jbyte    load_acquire(volatile jbyte*   p);
  static jshort   load_acquire(volatile jshort*  p);
  static jint     load_acquire(volatile jint*    p);
  static jlong    load_acquire(volatile jlong*   p);
  static jubyte   load_acquire(volatile jubyte*  p);
  static jushort  load_acquire(volatile jushort* p);
  static juint    load_acquire(volatile juint*   p);
  static julong   load_acquire(volatile julong*  p);
  static jfloat   load_acquire(volatile jfloat*  p);
  static jdouble  load_acquire(volatile jdouble* p);
  static intptr_t load_ptr_acquire(volatile intptr_t*   p);
  static void*    load_ptr_acquire(volatile void*       p);
  static void*    load_ptr_acquire(const volatile void* p);
  static void     release_store(volatile jbyte*   p, jbyte   v);
  static void     release_store(volatile jshort*  p, jshort  v);
  static void     release_store(volatile jint*    p, jint    v);
  static void     release_store(volatile jlong*   p, jlong   v);
  static void     release_store(volatile jubyte*  p, jubyte  v);
  static void     release_store(volatile jushort* p, jushort v);
  static void     release_store(volatile juint*   p, juint   v);
  static void     release_store(volatile julong*  p, julong  v);
  static void     release_store(volatile jfloat*  p, jfloat  v);
  static void     release_store(volatile jdouble* p, jdouble v);
  static void     release_store_ptr(volatile intptr_t* p, intptr_t v);
  static void     release_store_ptr(volatile void*     p, void*    v);
  static void     store_fence(jbyte*   p, jbyte   v);
  static void     store_fence(jshort*  p, jshort  v);
  static void     store_fence(jint*    p, jint    v);
  static void     store_fence(jlong*   p, jlong   v);
  static void     store_fence(jubyte*  p, jubyte  v);
  static void     store_fence(jushort* p, jushort v);
  static void     store_fence(juint*   p, juint   v);
  static void     store_fence(julong*  p, julong  v);
  static void     store_fence(jfloat*  p, jfloat  v);
  static void     store_fence(jdouble* p, jdouble v);
  static void     store_ptr_fence(intptr_t* p, intptr_t v);
  static void     store_ptr_fence(void**    p, void*    v);
  static void     release_store_fence(volatile jbyte*   p, jbyte   v);
  static void     release_store_fence(volatile jshort*  p, jshort  v);
  static void     release_store_fence(volatile jint*    p, jint    v);
  static void     release_store_fence(volatile jlong*   p, jlong   v);
  static void     release_store_fence(volatile jubyte*  p, jubyte  v);
  static void     release_store_fence(volatile jushort* p, jushort v);
  static void     release_store_fence(volatile juint*   p, juint   v);
  static void     release_store_fence(volatile julong*  p, julong  v);
  static void     release_store_fence(volatile jfloat*  p, jfloat  v);
  static void     release_store_fence(volatile jdouble* p, jdouble v);
  static void     release_store_ptr_fence(volatile intptr_t* p, intptr_t v);
  static void     release_store_ptr_fence(volatile void*     p, void*    v);
 private:
  static void StubRoutines_fence();
};
#endif // SHARE_VM_RUNTIME_ORDERACCESS_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/orderAccess.inline.hpp
#ifndef SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP
#define SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP
#include "runtime/orderAccess.hpp"
#ifdef TARGET_OS_ARCH_linux_x86
# include "orderAccess_linux_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_sparc
# include "orderAccess_linux_sparc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_zero
# include "orderAccess_linux_zero.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_arm
# include "orderAccess_linux_arm.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_aarch64
# include "orderAccess_linux_aarch64.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_ppc
# include "orderAccess_linux_ppc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_x86
# include "orderAccess_solaris_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_sparc
# include "orderAccess_solaris_sparc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_windows_x86
# include "orderAccess_windows_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_aix_ppc
# include "orderAccess_aix_ppc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_x86
# include "orderAccess_bsd_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_zero
# include "orderAccess_bsd_zero.inline.hpp"
#endif
#endif // SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/os.cpp
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/allocation.inline.hpp"
#ifdef ASSERT
#include "memory/guardedMemory.hpp"
#endif
#include "oops/oop.inline.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
#include "prims/privilegedStack.hpp"
#include "runtime/arguments.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "services/attachListener.hpp"
#include "services/nmtCommon.hpp"
#include "services/mallocTracker.hpp"
#include "services/memTracker.hpp"
#include "services/threadService.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
# include <signal.h>
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
OSThread*         os::_starting_thread    = NULL;
address           os::_polling_page       = NULL;
volatile int32_t* os::_mem_serialize_page = NULL;
uintptr_t         os::_serialize_page_mask = 0;
long              os::_rand_seed          = 1;
int               os::_processor_count    = 0;
int               os::_initial_active_processor_count = 0;
size_t            os::_page_sizes[os::page_sizes_max];
#ifndef PRODUCT
julong os::num_mallocs = 0;         // # of calls to malloc/realloc
julong os::alloc_bytes = 0;         // # of bytes allocated
julong os::num_frees = 0;           // # of calls to free
julong os::free_bytes = 0;          // # of bytes freed
#endif
static juint cur_malloc_words = 0;  // current size for MallocMaxTestWords
void os_init_globals() {
  os::init_globals();
}
int os::snprintf(char* buf, size_t len, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  int result = os::vsnprintf(buf, len, fmt, args);
  va_end(args);
  return result;
}
char* os::iso8601_time(char* buffer, size_t buffer_length) {
  static const char* iso8601_format =
    "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d";
  static const size_t needed_buffer = 29;
  if (buffer == NULL) {
    assert(false, "NULL buffer");
    return NULL;
  }
  if (buffer_length < needed_buffer) {
    assert(false, "buffer_length too small");
    return NULL;
  }
  jlong milliseconds_since_19700101 = javaTimeMillis();
  const int milliseconds_per_microsecond = 1000;
  const time_t seconds_since_19700101 =
    milliseconds_since_19700101 / milliseconds_per_microsecond;
  const int milliseconds_after_second =
    milliseconds_since_19700101 % milliseconds_per_microsecond;
  struct tm time_struct;
  if (localtime_pd(&seconds_since_19700101, &time_struct) == NULL) {
    assert(false, "Failed localtime_pd");
    return NULL;
  }
  const time_t seconds_per_minute = 60;
  const time_t minutes_per_hour = 60;
  const time_t seconds_per_hour = seconds_per_minute * minutes_per_hour;
  time_t UTC_to_local = 0;
#if defined(_ALLBSD_SOURCE) || defined(_GNU_SOURCE)
    UTC_to_local = -(time_struct.tm_gmtoff);
#elif defined(_WINDOWS)
  long zone;
  _get_timezone(&zone);
  UTC_to_local = static_cast<time_t>(zone);
#else
  UTC_to_local = timezone;
#endif
#if !defined(_ALLBSD_SOURCE) && !defined(_GNU_SOURCE)
  if (time_struct.tm_isdst > 0) {
    UTC_to_local = UTC_to_local - seconds_per_hour;
  }
#endif
  const time_t local_to_UTC = -(UTC_to_local);
  char sign_local_to_UTC = '+';
  time_t abs_local_to_UTC = local_to_UTC;
  if (local_to_UTC < 0) {
    sign_local_to_UTC = '-';
    abs_local_to_UTC = -(abs_local_to_UTC);
  }
  const time_t zone_hours = (abs_local_to_UTC / seconds_per_hour);
  const time_t zone_min =
    ((abs_local_to_UTC % seconds_per_hour) / seconds_per_minute);
  const int year = 1900 + time_struct.tm_year;
  const int month = 1 + time_struct.tm_mon;
  const int printed = jio_snprintf(buffer, buffer_length, iso8601_format,
                                   year,
                                   month,
                                   time_struct.tm_mday,
                                   time_struct.tm_hour,
                                   time_struct.tm_min,
                                   time_struct.tm_sec,
                                   milliseconds_after_second,
                                   sign_local_to_UTC,
                                   zone_hours,
                                   zone_min);
  if (printed == 0) {
    assert(false, "Failed jio_printf");
    return NULL;
  }
  return buffer;
}
OSReturn os::set_priority(Thread* thread, ThreadPriority p) {
#ifdef ASSERT
  if (!(!thread->is_Java_thread() ||
         Thread::current() == thread  ||
         Threads_lock->owned_by_self()
         || thread->is_Compiler_thread()
        )) {
    assert(false, "possibility of dangling Thread pointer");
  }
#endif
  if (p >= MinPriority && p <= MaxPriority) {
    int priority = java_to_os_priority[p];
    return set_native_priority(thread, priority);
  } else {
    assert(false, "Should not happen");
    return OS_ERR;
  }
}
OSReturn os::get_priority(const Thread* const thread, ThreadPriority& priority) {
  int p;
  int os_prio;
  OSReturn ret = get_native_priority(thread, &os_prio);
  if (ret != OS_OK) return ret;
  if (java_to_os_priority[MaxPriority] > java_to_os_priority[MinPriority]) {
    for (p = MaxPriority; p > MinPriority && java_to_os_priority[p] > os_prio; p--) ;
  } else {
    for (p = MaxPriority; p > MinPriority && java_to_os_priority[p] < os_prio; p--) ;
  }
  priority = (ThreadPriority)p;
  return OS_OK;
}
#ifndef SIGBREAK
#define SIGBREAK SIGQUIT
#endif
static void signal_thread_entry(JavaThread* thread, TRAPS) {
  os::set_priority(thread, NearMaxPriority);
  while (true) {
    int sig;
    {
      sig = os::signal_wait();
    }
    if (sig == os::sigexitnum_pd()) {
       return;
    }
    switch (sig) {
      case SIGBREAK: {
        if (!DisableAttachMechanism && AttachListener::is_init_trigger()) {
          continue;
        }
        VM_PrintThreads op;
        VMThread::execute(&op);
        VM_PrintJNI jni_op;
        VMThread::execute(&jni_op);
        VM_FindDeadlocks op1(tty);
        VMThread::execute(&op1);
        Universe::print_heap_at_SIGBREAK();
        if (PrintClassHistogram) {
          VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */);
          VMThread::execute(&op1);
        }
        if (JvmtiExport::should_post_data_dump()) {
          JvmtiExport::post_data_dump();
        }
        break;
      }
      default: {
        HandleMark hm(THREAD);
        Klass* k = SystemDictionary::resolve_or_null(vmSymbols::sun_misc_Signal(), THREAD);
        KlassHandle klass (THREAD, k);
        if (klass.not_null()) {
          JavaValue result(T_VOID);
          JavaCallArguments args;
          args.push_int(sig);
          JavaCalls::call_static(
            &result,
            klass,
            vmSymbols::dispatch_name(),
            vmSymbols::int_void_signature(),
            &args,
            THREAD
          );
        }
        if (HAS_PENDING_EXCEPTION) {
          if (tty != NULL) {
            char klass_name[256];
            char tmp_sig_name[16];
            const char* sig_name = "UNKNOWN";
            InstanceKlass::cast(PENDING_EXCEPTION->klass())->
              name()->as_klass_external_name(klass_name, 256);
            if (os::exception_name(sig, tmp_sig_name, 16) != NULL)
              sig_name = tmp_sig_name;
            warning("Exception %s occurred dispatching signal %s to handler"
                    "- the VM may need to be forcibly terminated",
                    klass_name, sig_name );
          }
          CLEAR_PENDING_EXCEPTION;
        }
      }
    }
  }
}
void os::init_before_ergo() {
  initialize_initial_active_processor_count();
  large_page_init();
  VM_Version::init_before_ergo();
}
void os::signal_init() {
  if (!ReduceSignalUsage) {
    EXCEPTION_MARK;
    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK);
    instanceKlassHandle klass (THREAD, k);
    instanceHandle thread_oop = klass->allocate_instance_handle(CHECK);
    const char thread_name[] = "Signal Dispatcher";
    Handle string = java_lang_String::create_from_str(thread_name, CHECK);
    Handle thread_group (THREAD, Universe::system_thread_group());
    JavaValue result(T_VOID);
    JavaCalls::call_special(&result, thread_oop,
                           klass,
                           vmSymbols::object_initializer_name(),
                           vmSymbols::threadgroup_string_void_signature(),
                           thread_group,
                           string,
                           CHECK);
    KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass());
    JavaCalls::call_special(&result,
                            thread_group,
                            group,
                            vmSymbols::add_method_name(),
                            vmSymbols::thread_void_signature(),
                            thread_oop,         // ARG 1
                            CHECK);
    os::signal_init_pd();
    { MutexLocker mu(Threads_lock);
      JavaThread* signal_thread = new JavaThread(&signal_thread_entry);
      if (signal_thread == NULL || signal_thread->osthread() == NULL) {
        vm_exit_during_initialization("java.lang.OutOfMemoryError",
                                      "unable to create new native thread");
      }
      java_lang_Thread::set_thread(thread_oop(), signal_thread);
      java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
      java_lang_Thread::set_daemon(thread_oop());
      signal_thread->set_threadObj(thread_oop());
      Threads::add(signal_thread);
      Thread::start(signal_thread);
    }
    os::signal(SIGBREAK, os::user_handler());
  }
}
void os::terminate_signal_thread() {
  if (!ReduceSignalUsage)
    signal_notify(sigexitnum_pd());
}
typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *);
extern struct JavaVM_ main_vm;
static void* _native_java_library = NULL;
void* os::native_java_library() {
  if (_native_java_library == NULL) {
    char buffer[JVM_MAXPATHLEN];
    char ebuf[1024];
    if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
                       "verify")) {
      dll_load(buffer, ebuf, sizeof(ebuf));
    }
    if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
                       "java")) {
      _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
    }
    if (_native_java_library == NULL) {
      vm_exit_during_initialization("Unable to load native library", ebuf);
    }
#if defined(__OpenBSD__)
    if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
                       "net")) {
      dll_load(buffer, ebuf, sizeof(ebuf));
    }
#endif
  }
  static jboolean onLoaded = JNI_FALSE;
  if (onLoaded) {
    if (ThreadLocalStorage::is_initialized()) {
      const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
      JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(
          JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0]));
      if (JNI_OnLoad != NULL) {
        JavaThread* thread = JavaThread::current();
        ThreadToNativeFromVM ttn(thread);
        HandleMark hm(thread);
        jint ver = (*JNI_OnLoad)(&main_vm, NULL);
        onLoaded = JNI_TRUE;
        if (!Threads::is_supported_jni_version_including_1_1(ver)) {
          vm_exit_during_initialization("Unsupported JNI version");
        }
      }
    }
  }
  return _native_java_library;
}
void* os::find_agent_function(AgentLibrary *agent_lib, bool check_lib,
                              const char *syms[], size_t syms_len) {
  assert(agent_lib != NULL, "sanity check");
  const char *lib_name;
  void *handle = agent_lib->os_lib();
  void *entryName = NULL;
  char *agent_function_name;
  size_t i;
  lib_name = ((check_lib || agent_lib->is_static_lib()) ? agent_lib->name() : NULL);
  for (i = 0; i < syms_len; i++) {
    agent_function_name = build_agent_function_name(syms[i], lib_name, agent_lib->is_absolute_path());
    if (agent_function_name == NULL) {
      break;
    }
    entryName = dll_lookup(handle, agent_function_name);
    FREE_C_HEAP_ARRAY(char, agent_function_name, mtThread);
    if (entryName != NULL) {
      break;
    }
  }
  return entryName;
}
bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[],
                            size_t syms_len) {
  void *ret;
  void *proc_handle;
  void *save_handle;
  assert(agent_lib != NULL, "sanity check");
  if (agent_lib->name() == NULL) {
    return false;
  }
  proc_handle = get_default_process_handle();
  save_handle = agent_lib->os_lib();
  agent_lib->set_os_lib(proc_handle);
  ret = find_agent_function(agent_lib, true, syms, syms_len);
  if (ret != NULL) {
    agent_lib->set_valid();
    agent_lib->set_static_lib(true);
    return true;
  }
  agent_lib->set_os_lib(save_handle);
  return false;
}
char *os::strdup(const char *str, MEMFLAGS flags) {
  size_t size = strlen(str);
  char *dup_str = (char *)malloc(size + 1, flags);
  if (dup_str == NULL) return NULL;
  strcpy(dup_str, str);
  return dup_str;
}
#define paranoid                 0  /* only set to 1 if you suspect checking code has bug */
#ifdef ASSERT
static void verify_memory(void* ptr) {
  GuardedMemory guarded(ptr);
  if (!guarded.verify_guards()) {
    tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
    tty->print_cr("## memory stomp:");
    guarded.print_on(tty);
    fatal("memory stomping error");
  }
}
#endif
static u_char* testMalloc(size_t alloc_size) {
  assert(MallocMaxTestWords > 0, "sanity check");
  if ((cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) {
    return NULL;
  }
  u_char* ptr = (u_char*)::malloc(alloc_size);
  if (ptr != NULL) {
    Atomic::add(((jint) (alloc_size / BytesPerWord)),
                (volatile jint *) &cur_malloc_words);
  }
  return ptr;
}
void* os::malloc(size_t size, MEMFLAGS flags) {
  return os::malloc(size, flags, CALLER_PC);
}
void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
  NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
  NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
  assert(!os::ThreadCrashProtection::is_crash_protected(ThreadLocalStorage::thread()),
         "malloc() not allowed when crash protection is set");
  if (size == 0) {
    size = 1;
  }
  NMT_TrackingLevel level = MemTracker::tracking_level();
  size_t            nmt_header_size = MemTracker::malloc_header_size(level);
#ifndef ASSERT
  const size_t alloc_size = size + nmt_header_size;
#else
  const size_t alloc_size = GuardedMemory::get_total_size(size + nmt_header_size);
  if (size + nmt_header_size > alloc_size) { // Check for rollover.
    return NULL;
  }
#endif
  NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
  u_char* ptr;
  if (MallocMaxTestWords > 0) {
    ptr = testMalloc(alloc_size);
  } else {
    ptr = (u_char*)::malloc(alloc_size);
  }
#ifdef ASSERT
  if (ptr == NULL) {
    return NULL;
  }
  GuardedMemory guarded(ptr, size + nmt_header_size);
  ptr = guarded.get_user_ptr();
#endif
  if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
    tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
    breakpoint();
  }
  debug_only(if (paranoid) verify_memory(ptr));
  if (PrintMalloc && tty != NULL) {
    tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
  }
  return MemTracker::record_malloc((address)ptr, size, memflags, stack, level);
}
void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) {
  return os::realloc(memblock, size, flags, CALLER_PC);
}
void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
#ifndef ASSERT
  NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
  NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
  void* membase = MemTracker::record_free(memblock);
  NMT_TrackingLevel level = MemTracker::tracking_level();
  size_t  nmt_header_size = MemTracker::malloc_header_size(level);
  void* ptr = ::realloc(membase, size + nmt_header_size);
  return MemTracker::record_malloc(ptr, size, memflags, stack, level);
#else
  if (memblock == NULL) {
    return os::malloc(size, memflags, stack);
  }
  if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
    tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
    breakpoint();
  }
  void* membase = MemTracker::malloc_base(memblock);
  verify_memory(membase);
  NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
  if (size == 0) {
    return NULL;
  }
  void* ptr = os::malloc(size, memflags, stack);
  if (PrintMalloc) {
    tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
  }
  if ( ptr != NULL ) {
    GuardedMemory guarded(MemTracker::malloc_base(memblock));
    size_t memblock_size = guarded.get_user_size() - MemTracker::malloc_header_size(memblock);
    memcpy(ptr, memblock, MIN2(size, memblock_size));
    if (paranoid) verify_memory(MemTracker::malloc_base(ptr));
    if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
      tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
      breakpoint();
    }
    os::free(memblock);
  }
  return ptr;
#endif
}
void  os::free(void *memblock, MEMFLAGS memflags) {
  NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
#ifdef ASSERT
  if (memblock == NULL) return;
  if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
    if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
    breakpoint();
  }
  void* membase = MemTracker::record_free(memblock);
  verify_memory(membase);
  NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
  GuardedMemory guarded(membase);
  size_t size = guarded.get_user_size();
  inc_stat_counter(&free_bytes, size);
  membase = guarded.release_for_freeing();
  if (PrintMalloc && tty != NULL) {
      fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)membase);
  }
  ::free(membase);
#else
  void* membase = MemTracker::record_free(memblock);
  ::free(membase);
#endif
}
void os::init_random(long initval) {
  _rand_seed = initval;
}
long os::random() {
  const long a = 16807;
  const unsigned long m = 2147483647;
  const long q = m / a;        assert(q == 127773, "weird math");
  const long r = m % a;        assert(r == 2836, "weird math");
  unsigned long lo = a * (long)(_rand_seed & 0xFFFF);
  unsigned long hi = a * (long)((unsigned long)_rand_seed >> 16);
  lo += (hi & 0x7FFF) << 16;
  if (lo > m) {
    lo &= m;
    ++lo;
  }
  lo += hi >> 15;
  if (lo > m) {
    lo &= m;
    ++lo;
  }
  return (_rand_seed = lo);
}
void os::start_thread(Thread* thread) {
  MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);
  OSThread* osthread = thread->osthread();
  osthread->set_state(RUNNABLE);
  pd_start_thread(thread);
}
void os::print_hex_dump(outputStream* st, address start, address end, int unitsize) {
  assert(unitsize == 1 || unitsize == 2 || unitsize == 4 || unitsize == 8, "just checking");
  int cols = 0;
  int cols_per_line = 0;
  switch (unitsize) {
    case 1: cols_per_line = 16; break;
    case 2: cols_per_line = 8;  break;
    case 4: cols_per_line = 4;  break;
    case 8: cols_per_line = 2;  break;
    default: return;
  }
  address p = start;
  st->print(PTR_FORMAT ":   ", start);
  while (p < end) {
    switch (unitsize) {
      case 1: st->print("%02x", *(u1*)p); break;
      case 2: st->print("%04x", *(u2*)p); break;
      case 4: st->print("%08x", *(u4*)p); break;
      case 8: st->print("%016" FORMAT64_MODIFIER "x", *(u8*)p); break;
    }
    p += unitsize;
    cols++;
    if (cols >= cols_per_line && p < end) {
       cols = 0;
       st->cr();
       st->print(PTR_FORMAT ":   ", p);
    } else {
       st->print(" ");
    }
  }
  st->cr();
}
void os::print_environment_variables(outputStream* st, const char** env_list,
                                     char* buffer, int len) {
  if (env_list) {
    st->print_cr("Environment Variables:");
    for (int i = 0; env_list[i] != NULL; i++) {
      if (getenv(env_list[i], buffer, len)) {
        st->print("%s", env_list[i]);
        st->print("=");
        st->print_cr("%s", buffer);
      }
    }
  }
}
void os::print_cpu_info(outputStream* st) {
  st->print("CPU:");
  st->print("total %d", os::processor_count());
  st->print(" (initial active %d)", _initial_active_processor_count);
  st->print(" %s", VM_Version::cpu_features());
  st->cr();
  pd_print_cpu_info(st);
}
void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
  const int secs_per_day  = 86400;
  const int secs_per_hour = 3600;
  const int secs_per_min  = 60;
  time_t tloc;
  (void)time(&tloc);
  st->print("time: %s", ctime(&tloc));  // ctime adds newline.
  struct tm tz;
  if (localtime_pd(&tloc, &tz) != NULL) {
    ::strftime(buf, buflen, "%Z", &tz);
    st->print_cr("timezone: %s", buf);
  }
  double t = os::elapsedTime();
  int eltime = (int)t;  // elapsed time in seconds
  int eltimeFraction = (int) ((t - eltime) * 1000000);
  int eldays = eltime / secs_per_day;
  int day_secs = eldays * secs_per_day;
  int elhours = (eltime - day_secs) / secs_per_hour;
  int hour_secs = elhours * secs_per_hour;
  int elmins = (eltime - day_secs - hour_secs) / secs_per_min;
  int minute_secs = elmins * secs_per_min;
  int elsecs = (eltime - day_secs - hour_secs - minute_secs);
  st->print_cr("elapsed time: %d.%06d seconds (%dd %dh %dm %ds)", eltime, eltimeFraction, eldays, elhours, elmins, elsecs);
}
void os::print_location(outputStream* st, intptr_t x, bool verbose) {
  address addr = (address)x;
  CodeBlob* b = CodeCache::find_blob_unsafe(addr);
  if (b != NULL) {
    if (b->is_buffer_blob()) {
      InterpreterCodelet* i = Interpreter::codelet_containing(addr);
      if (i != NULL) {
        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an Interpreter codelet", addr, (int)(addr - i->code_begin()));
        i->print_on(st);
        return;
      }
      if (Interpreter::contains(addr)) {
        st->print_cr(INTPTR_FORMAT " is pointing into interpreter code"
                     " (not bytecode specific)", addr);
        return;
      }
      if (AdapterHandlerLibrary::contains(b)) {
        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an AdapterHandler", addr, (int)(addr - b->code_begin()));
        AdapterHandlerLibrary::print_handler_on(st, b);
      }
      StubCodeDesc* d = StubCodeDesc::desc_for(addr);
      if (d != NULL) {
        st->print_cr(INTPTR_FORMAT " is at begin+%d in a stub", addr, (int)(addr - d->begin()));
        d->print_on(st);
        st->cr();
        return;
      }
      if (StubRoutines::contains(addr)) {
        st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) "
                     "stub routine", addr);
        return;
      }
      if (InlineCacheBuffer::contains(addr)) {
        st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
        return;
      }
      VtableStub* v = VtableStubs::stub_containing(addr);
      if (v != NULL) {
        st->print_cr(INTPTR_FORMAT " is at entry_point+%d in a vtable stub", addr, (int)(addr - v->entry_point()));
        v->print_on(st);
        st->cr();
        return;
      }
    }
    nmethod* nm = b->as_nmethod_or_null();
    if (nm != NULL) {
      ResourceMark rm;
      st->print(INTPTR_FORMAT " is at entry_point+%d in (nmethod*)" INTPTR_FORMAT,
                addr, (int)(addr - nm->entry_point()), nm);
      if (verbose) {
        st->print(" for ");
        nm->method()->print_value_on(st);
      }
      st->cr();
      nm->print_nmethod(verbose);
      return;
    }
    st->print_cr(INTPTR_FORMAT " is at code_begin+%d in ", addr, (int)(addr - b->code_begin()));
    b->print_on(st);
    return;
  }
  if (Universe::heap()->is_in(addr)) {
    HeapWord* p = Universe::heap()->block_start(addr);
    bool print = false;
    if (p != NULL && Universe::heap()->block_is_obj(p)) {
      print = true;
    } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
      p = (HeapWord*) addr;
      print = true;
    }
    if (print) {
      if (p == (HeapWord*) addr) {
        st->print_cr(INTPTR_FORMAT " is an oop", addr);
      } else {
        st->print_cr(INTPTR_FORMAT " is pointing into object: " INTPTR_FORMAT, addr, p);
      }
      oop(p)->print_on(st);
      return;
    }
  } else {
    if (Universe::heap()->is_in_reserved(addr)) {
      st->print_cr(INTPTR_FORMAT " is an unallocated location "
                   "in the heap", addr);
      return;
    }
  }
  if (JNIHandles::is_global_handle((jobject) addr)) {
    st->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
    return;
  }
  if (JNIHandles::is_weak_global_handle((jobject) addr)) {
    st->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
    return;
  }
#ifndef PRODUCT
  if (JNIHandleBlock::any_contains((jobject) addr)) {
    st->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
    return;
  }
#endif
  for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
    if (thread->privileged_stack_top() != NULL &&
        thread->privileged_stack_top()->contains(addr)) {
      st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack "
                   "for thread: " INTPTR_FORMAT, addr, thread);
      if (verbose) thread->print_on(st);
      return;
    }
    if (addr == (address)thread) {
      if (verbose) {
        thread->print_on(st);
      } else {
        st->print_cr(INTPTR_FORMAT " is a thread", addr);
      }
      return;
    }
    if (thread->stack_base() >= addr &&
        addr > (thread->stack_base() - thread->stack_size())) {
      st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
                   INTPTR_FORMAT, addr, thread);
      if (verbose) thread->print_on(st);
      return;
    }
  }
  if (Metaspace::contains(addr)) {
    if (Method::has_method_vptr((const void*)addr)) {
      ((Method*)addr)->print_value_on(st);
      st->cr();
    } else {
      st->print_cr(INTPTR_FORMAT " is pointing into metadata", addr);
    }
    return;
  }
  if (os::find(addr, st)) {
    return;
  }
  st->print_cr(INTPTR_FORMAT " is an unknown value", addr);
}
bool os::is_first_C_frame(frame* fr) {
#if (defined(IA64) && !defined(AIX)) && !defined(_WIN32)
  Thread *thread = Thread::current();
  if ((address)fr->fp() <=
      thread->register_stack_base() HPUX_ONLY(+ 0x0) LINUX_ONLY(+ 0x50)) {
    return true;
  } else {
    return false;
  }
#elif defined(IA64) && defined(_WIN32)
  return true;
#else
  uintptr_t fp_align_mask = (uintptr_t)(sizeof(address)-1);
  uintptr_t sp_align_mask = (uintptr_t)(sizeof(int)-1);
  uintptr_t usp    = (uintptr_t)fr->sp();
  if ((usp & sp_align_mask) != 0) return true;
  uintptr_t ufp    = (uintptr_t)fr->fp();
  if ((ufp & fp_align_mask) != 0) return true;
  uintptr_t old_sp = (uintptr_t)fr->sender_sp();
  if ((old_sp & sp_align_mask) != 0) return true;
  if (old_sp == 0 || old_sp == (uintptr_t)-1) return true;
  uintptr_t old_fp = (uintptr_t)fr->link();
  if ((old_fp & fp_align_mask) != 0) return true;
  if (old_fp == 0 || old_fp == (uintptr_t)-1 || old_fp == ufp) return true;
  if (old_fp < ufp) return true;
  if (old_fp - ufp > 64 * K) return true;
  return false;
#endif
}
#ifdef ASSERT
extern "C" void test_random() {
  const double m = 2147483647;
  double mean = 0.0, variance = 0.0, t;
  long reps = 10000;
  unsigned long seed = 1;
  tty->print_cr("seed %ld for %ld repeats...", seed, reps);
  os::init_random(seed);
  long num;
  for (int k = 0; k < reps; k++) {
    num = os::random();
    double u = (double)num / m;
    assert(u >= 0.0 && u <= 1.0, "bad random number!");
    mean += u;
    variance += (u*u);
  }
  mean /= reps;
  variance /= (reps - 1);
  assert(num == 1043618065, "bad seed");
  tty->print_cr("mean of the 1st 10000 numbers: %f", mean);
  tty->print_cr("variance of the 1st 10000 numbers: %f", variance);
  const double eps = 0.0001;
  t = fabsd(mean - 0.5018);
  assert(t < eps, "bad mean");
  t = (variance - 0.3355) < 0.0 ? -(variance - 0.3355) : variance - 0.3355;
  assert(t < eps, "bad variance");
}
#endif
char* os::format_boot_path(const char* format_string,
                           const char* home,
                           int home_len,
                           char fileSep,
                           char pathSep) {
    assert((fileSep == '/' && pathSep == ':') ||
           (fileSep == '\\' && pathSep == ';'), "unexpected seperator chars");
    int formatted_path_len = 0;
    const char* p;
    for (p = format_string; *p != 0; ++p) {
        if (*p == '%') formatted_path_len += home_len - 1;
        ++formatted_path_len;
    }
    char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1, mtInternal);
    if (formatted_path == NULL) {
        return NULL;
    }
    char* q = formatted_path;
    for (p = format_string; *p != 0; ++p) {
        switch (*p) {
        case '%':
            strcpy(q, home);
            q += home_len;
            break;
        case '/':
            break;
        case ':':
            break;
        default:
        }
    }
    assert((q - formatted_path) == formatted_path_len, "formatted_path size botched");
    return formatted_path;
}
bool os::set_boot_path(char fileSep, char pathSep) {
    const char* home = Arguments::get_java_home();
    int home_len = (int)strlen(home);
    static const char* meta_index_dir_format = "%/lib/";
    static const char* meta_index_format = "%/lib/meta-index";
    char* meta_index = format_boot_path(meta_index_format, home, home_len, fileSep, pathSep);
    if (meta_index == NULL) return false;
    char* meta_index_dir = format_boot_path(meta_index_dir_format, home, home_len, fileSep, pathSep);
    if (meta_index_dir == NULL) return false;
    Arguments::set_meta_index_path(meta_index, meta_index_dir);
    static const char classpath_format[] =
        "%/lib/resources.jar:"
        "%/lib/rt.jar:"
        "%/lib/sunrsasign.jar:"
        "%/lib/jsse.jar:"
        "%/lib/jce.jar:"
        "%/lib/charsets.jar:"
        "%/lib/jfr.jar:"
        "%/classes";
    char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);
    if (sysclasspath == NULL) return false;
    Arguments::set_sysclasspath(sysclasspath);
    return true;
}
char** os::split_path(const char* path, int* n) {
  if (path == NULL || strlen(path) == 0) {
    return NULL;
  }
  const char psepchar = *os::path_separator();
  char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal);
  if (inpath == NULL) {
    return NULL;
  }
  strcpy(inpath, path);
  int count = 1;
  char* p = strchr(inpath, psepchar);
  while (p != NULL) {
    count++;
    p++;
    p = strchr(p, psepchar);
  }
  char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal);
  if (opath == NULL) {
    return NULL;
  }
  p = inpath;
  for (int i = 0 ; i < count ; i++) {
    size_t len = strcspn(p, os::path_separator());
    if (len > JVM_MAXPATHLEN) {
      return NULL;
    }
    char* s  = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
    if (s == NULL) {
      return NULL;
    }
    strncpy(s, p, len);
    s[len] = '\0';
    opath[i] = s;
    p += len + 1;
  }
  FREE_C_HEAP_ARRAY(char, inpath, mtInternal);
  return opath;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值