ssssssssss74


void os::set_memory_serialize_page(address page) {
  int count = log2_intptr(sizeof(class JavaThread)) - log2_int(64);
  _mem_serialize_page = (volatile int32_t *)page;
  assert(SerializePageShiftCount == count,
         "thread size changed, fix SerializePageShiftCount constant");
  set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t)));
}
static volatile intptr_t SerializePageLock = 0;
void os::block_on_serialize_page_trap() {
  if (TraceSafepoint) {
    tty->print_cr("Block until the serialize page permission restored");
  }
  Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page");
  Thread::muxRelease(&SerializePageLock);
}
void os::serialize_thread_states() {
  Thread::muxAcquire(&SerializePageLock, "serialize_thread_states");
  os::protect_memory((char *)os::get_memory_serialize_page(),
                     os::vm_page_size(), MEM_PROT_READ);
  os::protect_memory((char *)os::get_memory_serialize_page(),
                     os::vm_page_size(), MEM_PROT_RW);
  Thread::muxRelease(&SerializePageLock);
}
bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
  assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
  address sp = current_stack_pointer();
  const int framesize_in_bytes =
    Interpreter::size_top_interpreter_activation(method()) * wordSize;
  int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
  address stack_limit = thread->stack_base() - thread->stack_size();
  return (sp > (stack_limit + reserved_area));
}
size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
  assert(min_pages > 0, "sanity");
  if (UseLargePages) {
    const size_t max_page_size = region_size / min_pages;
    for (size_t i = 0; _page_sizes[i] != 0; ++i) {
      const size_t page_size = _page_sizes[i];
      if (page_size <= max_page_size) {
        if (!must_be_aligned || is_size_aligned(region_size, page_size)) {
          return page_size;
        }
      }
    }
  }
  return vm_page_size();
}
size_t os::page_size_for_region_aligned(size_t region_size, size_t min_pages) {
  return page_size_for_region(region_size, min_pages, true);
}
size_t os::page_size_for_region_unaligned(size_t region_size, size_t min_pages) {
  return page_size_for_region(region_size, min_pages, false);
}
#ifndef PRODUCT
void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
{
  if (TracePageSizes) {
    tty->print("%s: ", str);
    for (int i = 0; i < count; ++i) {
      tty->print(" " SIZE_FORMAT, page_sizes[i]);
    }
    tty->cr();
  }
}
void os::trace_page_sizes(const char* str, const size_t region_min_size,
                          const size_t region_max_size, const size_t page_size,
                          const char* base, const size_t size)
{
  if (TracePageSizes) {
    tty->print_cr("%s:  min=" SIZE_FORMAT " max=" SIZE_FORMAT
                  " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
                  " size=" SIZE_FORMAT,
                  str, region_min_size, region_max_size,
                  page_size, base, size);
  }
}
#endif  // #ifndef PRODUCT
bool os::is_server_class_machine() {
  if (NeverActAsServerClassMachine) {
    return false;
  }
  if (AlwaysActAsServerClassMachine) {
    return true;
  }
  bool         result            = false;
  const unsigned int    server_processors = 2;
  const julong server_memory     = 2UL * G;
  const julong missing_memory   = 256UL * M;
  if ((os::active_processor_count() >= (int)server_processors) &&
      (os::physical_memory() >= (server_memory - missing_memory))) {
    const unsigned int logical_processors =
      VM_Version::logical_processors_per_package();
    if (logical_processors > 1) {
      const unsigned int physical_packages =
        os::active_processor_count() / logical_processors;
      if (physical_packages > server_processors) {
        result = true;
      }
    } else {
      result = true;
    }
  }
  return result;
}
void os::initialize_initial_active_processor_count() {
  assert(_initial_active_processor_count == 0, "Initial active processor count already set.");
  _initial_active_processor_count = active_processor_count();
}
void os::SuspendedThreadTask::run() {
  assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
  internal_do_task();
  _done = true;
}
bool os::create_stack_guard_pages(char* addr, size_t bytes) {
  return os::pd_create_stack_guard_pages(addr, bytes);
}
char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
  char* result = pd_reserve_memory(bytes, addr, alignment_hint);
  if (result != NULL) {
    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
  }
  return result;
}
char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint,
   MEMFLAGS flags) {
  char* result = pd_reserve_memory(bytes, addr, alignment_hint);
  if (result != NULL) {
    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
    MemTracker::record_virtual_memory_type((address)result, flags);
  }
  return result;
}
char* os::attempt_reserve_memory_at(size_t bytes, char* addr) {
  char* result = pd_attempt_reserve_memory_at(bytes, addr);
  if (result != NULL) {
    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
  }
  return result;
}
void os::split_reserved_memory(char *base, size_t size,
                                 size_t split, bool realloc) {
  pd_split_reserved_memory(base, size, split, realloc);
}
bool os::commit_memory(char* addr, size_t bytes, bool executable) {
  bool res = pd_commit_memory(addr, bytes, executable);
  if (res) {
    MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC);
  }
  return res;
}
bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
                              bool executable) {
  bool res = os::pd_commit_memory(addr, size, alignment_hint, executable);
  if (res) {
    MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC);
  }
  return res;
}
void os::commit_memory_or_exit(char* addr, size_t bytes, bool executable,
                               const char* mesg) {
  pd_commit_memory_or_exit(addr, bytes, executable, mesg);
  MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC);
}
void os::commit_memory_or_exit(char* addr, size_t size, size_t alignment_hint,
                               bool executable, const char* mesg) {
  os::pd_commit_memory_or_exit(addr, size, alignment_hint, executable, mesg);
  MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC);
}
bool os::uncommit_memory(char* addr, size_t bytes) {
  bool res;
  if (MemTracker::tracking_level() > NMT_minimal) {
    Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker();
    res = pd_uncommit_memory(addr, bytes);
    if (res) {
      tkr.record((address)addr, bytes);
    }
  } else {
    res = pd_uncommit_memory(addr, bytes);
  }
  return res;
}
bool os::release_memory(char* addr, size_t bytes) {
  bool res;
  if (MemTracker::tracking_level() > NMT_minimal) {
    Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
    res = pd_release_memory(addr, bytes);
    if (res) {
      tkr.record((address)addr, bytes);
    }
  } else {
    res = pd_release_memory(addr, bytes);
  }
  return res;
}
void os::pretouch_memory(char* start, char* end) {
  for (volatile char *p = start; p < end; p += os::vm_page_size()) {
  }
}
char* os::map_memory(int fd, const char* file_name, size_t file_offset,
                           char *addr, size_t bytes, bool read_only,
                           bool allow_exec) {
  char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec);
  if (result != NULL) {
    MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
  }
  return result;
}
char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
                             char *addr, size_t bytes, bool read_only,
                             bool allow_exec) {
  return pd_remap_memory(fd, file_name, file_offset, addr, bytes,
                    read_only, allow_exec);
}
bool os::unmap_memory(char *addr, size_t bytes) {
  bool result;
  if (MemTracker::tracking_level() > NMT_minimal) {
    Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
    result = pd_unmap_memory(addr, bytes);
    if (result) {
      tkr.record((address)addr, bytes);
    }
  } else {
    result = pd_unmap_memory(addr, bytes);
  }
  return result;
}
void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
  pd_free_memory(addr, bytes, alignment_hint);
}
void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
  pd_realign_memory(addr, bytes, alignment_hint);
}
#ifndef TARGET_OS_FAMILY_windows
os::SuspendResume::State os::SuspendResume::switch_state(os::SuspendResume::State from,
                                                         os::SuspendResume::State to)
{
  os::SuspendResume::State result =
    (os::SuspendResume::State) Atomic::cmpxchg((jint) to, (jint *) &_state, (jint) from);
  if (result == from) {
    return to;
  }
  return result;
}
#endif
#ifndef PRODUCT
#define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
class TestOS : AllStatic {
  static size_t small_page_size() {
    return os::vm_page_size();
  }
  static size_t large_page_size() {
    const size_t large_page_size_example = 4 * M;
    return os::page_size_for_region_aligned(large_page_size_example, 1);
  }
  static void test_page_size_for_region_aligned() {
    if (UseLargePages) {
      const size_t small_page = small_page_size();
      const size_t large_page = large_page_size();
      if (large_page > small_page) {
        size_t num_small_pages_in_large = large_page / small_page;
        size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large);
        assert_eq(page, small_page);
      }
    }
  }
  static void test_page_size_for_region_alignment() {
    if (UseLargePages) {
      const size_t small_page = small_page_size();
      const size_t large_page = large_page_size();
      if (large_page > small_page) {
        const size_t unaligned_region = large_page + 17;
        size_t page = os::page_size_for_region_aligned(unaligned_region, 1);
        assert_eq(page, small_page);
        const size_t num_pages = 5;
        const size_t aligned_region = large_page * num_pages;
        page = os::page_size_for_region_aligned(aligned_region, num_pages);
        assert_eq(page, large_page);
      }
    }
  }
  static void test_page_size_for_region_unaligned() {
    if (UseLargePages) {
      for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
        size_t expected = os::_page_sizes[i];
        size_t actual = os::page_size_for_region_unaligned(expected, 1);
        assert_eq(expected, actual);
      }
      for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
        size_t expected = os::_page_sizes[i];
        size_t actual = os::page_size_for_region_unaligned(expected + 17, 1);
        assert_eq(expected, actual);
      }
      if (os::_page_sizes[1] > os::_page_sizes[0]) {
        size_t expected = os::_page_sizes[0];
        size_t actual = os::page_size_for_region_unaligned(os::_page_sizes[1] - 17, 1);
        assert_eq(actual, expected);
      }
      size_t small_page = small_page_size();
      size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1);
      assert_eq(small_page, actual);
    }
  }
 public:
  static void run_tests() {
    test_page_size_for_region_aligned();
    test_page_size_for_region_alignment();
    test_page_size_for_region_unaligned();
  }
};
void TestOS_test() {
  TestOS::run_tests();
}
#endif // PRODUCT
C:\hotspot-69087d08d473\src\share\vm/runtime/os.hpp
#ifndef SHARE_VM_RUNTIME_OS_HPP
#define SHARE_VM_RUNTIME_OS_HPP
#include "jvmtifiles/jvmti.h"
#include "runtime/atomic.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/handles.hpp"
#include "utilities/top.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "jvm_linux.h"
# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "jvm_solaris.h"
# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "jvm_windows.h"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "jvm_aix.h"
# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "jvm_bsd.h"
# include <setjmp.h>
# ifdef __APPLE__
#  include <mach/mach_time.h>
# endif
#endif
class AgentLibrary;
typedef void (*dll_func)(...);
class Thread;
class JavaThread;
class Event;
class DLL;
class FileHandle;
class NativeCallStack;
template<class E> class GrowableArray;
enum OSReturn {
  OS_OK         =  0,        // Operation was successful
  OS_ERR        = -1,        // Operation failed
  OS_INTRPT     = -2,        // Operation was interrupted
  OS_TIMEOUT    = -3,        // Operation timed out
  OS_NOMEM      = -5,        // Operation failed for lack of memory
  OS_NORESOURCE = -6         // Operation failed for lack of nonmemory resource
};
enum ThreadPriority {        // JLS 20.20.1-3
  NoPriority       = -1,     // Initial non-priority value
  MinPriority      =  1,     // Minimum priority
  NormPriority     =  5,     // Normal (non-daemon) priority
  NearMaxPriority  =  9,     // High priority, used for VMThread
  MaxPriority      = 10,     // Highest priority, used for WatcherThread
  CriticalPriority = 11      // Critical thread priority
};
const bool ExecMem = true;
typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
class MallocTracker;
class os: AllStatic {
  friend class VMStructs;
  friend class MallocTracker;
 public:
  enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)
 private:
  static OSThread*          _starting_thread;
  static address            _polling_page;
  static volatile int32_t * _mem_serialize_page;
  static uintptr_t          _serialize_page_mask;
 public:
  static size_t             _page_sizes[page_sizes_max];
 private:
  static void init_page_sizes(size_t default_page_size) {
    _page_sizes[0] = default_page_size;
    _page_sizes[1] = 0; // sentinel
  }
  static char*  pd_reserve_memory(size_t bytes, char* addr = 0,
                               size_t alignment_hint = 0);
  static char*  pd_attempt_reserve_memory_at(size_t bytes, char* addr);
  static void   pd_split_reserved_memory(char *base, size_t size,
                                      size_t split, bool realloc);
  static bool   pd_commit_memory(char* addr, size_t bytes, bool executable);
  static bool   pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                                 bool executable);
  static void   pd_commit_memory_or_exit(char* addr, size_t bytes,
                                         bool executable, const char* mesg);
  static void   pd_commit_memory_or_exit(char* addr, size_t size,
                                         size_t alignment_hint,
                                         bool executable, const char* mesg);
  static bool   pd_uncommit_memory(char* addr, size_t bytes);
  static bool   pd_release_memory(char* addr, size_t bytes);
  static char*  pd_map_memory(int fd, const char* file_name, size_t file_offset,
                           char *addr, size_t bytes, bool read_only = false,
                           bool allow_exec = false);
  static char*  pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                             char *addr, size_t bytes, bool read_only,
                             bool allow_exec);
  static bool   pd_unmap_memory(char *addr, size_t bytes);
  static void   pd_free_memory(char *addr, size_t bytes, size_t alignment_hint);
  static void   pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint);
  static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned);
  static void initialize_initial_active_processor_count();
  LINUX_ONLY(static void pd_init_container_support();)
 public:
  static void init(void);                      // Called before command line parsing
  static void init_container_support() {       // Called during command line parsing.
     LINUX_ONLY(pd_init_container_support();)
  }
  static void init_before_ergo(void);          // Called after command line parsing
  static jint init_2(void);                    // Called after command line parsing
  static void init_globals(void) {             // Called from init_globals() in init.cpp
    init_globals_ext();
  }
  static int    file_name_strcmp(const char* s1, const char* s2);
  static bool getenv(const char* name, char* buffer, int len);
  static bool unsetenv(const char* name);
  static bool have_special_privileges();
  static jlong  javaTimeMillis();
  static jlong  javaTimeNanos();
  static void   javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
  static void   run_periodic_checks();
  static double elapsedTime();
  static bool getTimesSecs(double* process_real_time,
                           double* process_user_time,
                           double* process_system_time);
  static jlong elapsed_counter();
  static jlong elapsed_frequency();
  static bool supports_vtime();
  static bool enable_vtime();
  static bool vtime_enabled();
  static double elapsedVTime();
  static char*      local_time_string(char *buf, size_t buflen);
  static struct tm* localtime_pd     (const time_t* clock, struct tm*  res);
  static char* iso8601_time(char* buffer, size_t buffer_length);
  static inline bool is_MP() {
    return (_processor_count != 1) || AssumeMP;
  }
  static julong available_memory();
  static julong physical_memory();
  static bool has_allocatable_memory_limit(julong* limit);
  static bool is_server_class_machine();
  static int processor_count() {
    return _processor_count;
  }
  static void set_processor_count(int count) { _processor_count = count; }
  static int active_processor_count();
  static int initial_active_processor_count() {
    assert(_initial_active_processor_count > 0, "Initial active processor count not set yet.");
    return _initial_active_processor_count;
  }
  static bool distribute_processes(uint length, uint* distribution);
  static bool bind_to_processor(uint processor_id);
  static void set_native_thread_name(const char *name);
  static bool uses_stack_guard_pages();
  static bool allocate_stack_guard_pages();
  static void bang_stack_shadow_pages();
  static bool stack_shadow_pages_available(Thread *thread, methodHandle method);
  static int    vm_page_size();
  static size_t page_size_for_region_aligned(size_t region_size, size_t min_pages);
  static size_t page_size_for_region_unaligned(size_t region_size, size_t min_pages);
  static size_t max_page_size() {
    return _page_sizes[0];
  }
  static void trace_page_sizes(const char* str, const size_t* page_sizes,
                               int count) PRODUCT_RETURN;
  static void trace_page_sizes(const char* str, const size_t region_min_size,
                               const size_t region_max_size,
                               const size_t page_size,
                               const char* base = NULL,
                               const size_t size = 0) PRODUCT_RETURN;
  static int    vm_allocation_granularity();
  static char*  reserve_memory(size_t bytes, char* addr = 0,
                               size_t alignment_hint = 0);
  static char*  reserve_memory(size_t bytes, char* addr,
                               size_t alignment_hint, MEMFLAGS flags);
  static char*  reserve_memory_aligned(size_t size, size_t alignment);
  static char*  attempt_reserve_memory_at(size_t bytes, char* addr);
  static void   split_reserved_memory(char *base, size_t size,
                                      size_t split, bool realloc);
  static bool   commit_memory(char* addr, size_t bytes, bool executable);
  static bool   commit_memory(char* addr, size_t size, size_t alignment_hint,
                              bool executable);
  static void   commit_memory_or_exit(char* addr, size_t bytes,
                                      bool executable, const char* mesg);
  static void   commit_memory_or_exit(char* addr, size_t size,
                                      size_t alignment_hint,
                                      bool executable, const char* mesg);
  static bool   uncommit_memory(char* addr, size_t bytes);
  static bool   release_memory(char* addr, size_t bytes);
  static void   pretouch_memory(char* start, char* end);
  enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
  static bool   protect_memory(char* addr, size_t bytes, ProtType prot,
                               bool is_committed = true);
  static bool   guard_memory(char* addr, size_t bytes);
  static bool   unguard_memory(char* addr, size_t bytes);
  static bool   create_stack_guard_pages(char* addr, size_t bytes);
  static bool   pd_create_stack_guard_pages(char* addr, size_t bytes);
  static bool   remove_stack_guard_pages(char* addr, size_t bytes);
  static char*  map_memory(int fd, const char* file_name, size_t file_offset,
                           char *addr, size_t bytes, bool read_only = false,
                           bool allow_exec = false);
  static char*  remap_memory(int fd, const char* file_name, size_t file_offset,
                             char *addr, size_t bytes, bool read_only,
                             bool allow_exec);
  static bool   unmap_memory(char *addr, size_t bytes);
  static void   free_memory(char *addr, size_t bytes, size_t alignment_hint);
  static void   realign_memory(char *addr, size_t bytes, size_t alignment_hint);
  static bool   numa_has_static_binding();
  static bool   numa_has_group_homing();
  static void   numa_make_local(char *addr, size_t bytes, int lgrp_hint);
  static void   numa_make_global(char *addr, size_t bytes);
  static size_t numa_get_groups_num();
  static size_t numa_get_leaf_groups(int *ids, size_t size);
  static bool   numa_topology_changed();
  static int    numa_get_group_id();
  struct page_info {
    size_t size;
    int lgrp_id;
  };
  static bool   get_page_info(char *start, page_info* info);
  static char*  scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found);
  static char*  non_memory_address_word();
  static char*  reserve_memory_special(size_t size, size_t alignment,
                                       char* addr, bool executable);
  static bool   release_memory_special(char* addr, size_t bytes);
  static void   large_page_init();
  static size_t large_page_size();
  static bool   can_commit_large_page_memory();
  static bool   can_execute_large_page_memory();
  static address get_polling_page()             { return _polling_page; }
  static void    set_polling_page(address page) { _polling_page = page; }
  static bool    is_poll_address(address addr)  { return addr >= _polling_page && addr < (_polling_page + os::vm_page_size()); }
  static void    make_polling_page_unreadable();
  static void    make_polling_page_readable();
  static void    serialize_thread_states();
  static int     get_serialize_page_shift_count() {
    return SerializePageShiftCount;
  }
  static void     set_serialize_page_mask(uintptr_t mask) {
    _serialize_page_mask = mask;
  }
  static unsigned int  get_serialize_page_mask() {
    return _serialize_page_mask;
  }
  static void    set_memory_serialize_page(address page);
  static address get_memory_serialize_page() {
    return (address)_mem_serialize_page;
  }
  static inline void write_memory_serialize_page(JavaThread *thread) {
    uintptr_t page_offset = ((uintptr_t)thread >>
                            get_serialize_page_shift_count()) &
                            get_serialize_page_mask();
  }
  static bool    is_memory_serialize_page(JavaThread *thread, address addr) {
    if (UseMembar) return false;
    if (thread == NULL) return false;
    address page = (address) _mem_serialize_page;
    return addr >= page && addr < (page + os::vm_page_size());
  }
  static void block_on_serialize_page_trap();
  enum ThreadType {
    vm_thread,
    cgc_thread,        // Concurrent GC thread
    pgc_thread,        // Parallel GC thread
    java_thread,
    compiler_thread,
    watcher_thread,
    os_thread
  };
  static bool create_thread(Thread* thread,
                            ThreadType thr_type,
                            size_t stack_size = 0);
  static bool create_main_thread(JavaThread* thread);
  static bool is_primordial_thread(void)
#if defined(_WINDOWS) || defined(BSD)
    { return false; }
#else
  ;
#endif
  static bool create_attached_thread(JavaThread* thread);
  static void pd_start_thread(Thread* thread);
  static void start_thread(Thread* thread);
  static void initialize_thread(Thread* thr);
  static void free_thread(OSThread* osthread);
  static intx current_thread_id();
  static int current_process_id();
  static int sleep(Thread* thread, jlong ms, bool interruptable);
  static void naked_short_sleep(jlong ms);
  static void infinite_sleep(); // never returns, use with CAUTION
  static void yield();        // Yields to all threads with same priority
  enum YieldResult {
    YIELD_SWITCHED = 1,         // caller descheduled, other ready threads exist & ran
    YIELD_NONEREADY = 0,        // No other runnable/ready threads.
    YIELD_UNKNOWN = -1          // Unknown: platform doesn't support _SWITCHED or _NONEREADY
  } ;
  static YieldResult NakedYield () ;
  static void yield_all(int attempts = 0); // Yields to all other threads including lower priority
  static void loop_breaker(int attempts);  // called from within tight loops to possibly influence time-sharing
  static OSReturn set_priority(Thread* thread, ThreadPriority priority);
  static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority);
  static void interrupt(Thread* thread);
  static bool is_interrupted(Thread* thread, bool clear_interrupted);
  static int pd_self_suspend_thread(Thread* thread);
  static ExtendedPC fetch_frame_from_context(void* ucVoid, intptr_t** sp, intptr_t** fp);
  static frame      fetch_frame_from_context(void* ucVoid);
  static ExtendedPC get_thread_pc(Thread *thread);
  static void breakpoint();
  static address current_stack_pointer();
  static address current_stack_base();
  static size_t current_stack_size();
  static void verify_stack_alignment() PRODUCT_RETURN;
  static int message_box(const char* title, const char* message);
  static char* do_you_want_to_debug(const char* message);
  static int fork_and_exec(char *cmd, bool use_vfork_if_available = false);
  static void shutdown();
  static void abort(bool dump_core = true);
  static void die();
  static const int default_file_open_flags();
  static int open(const char *path, int oflag, int mode);
  static FILE* open(int fd, const char* mode);
  static int close(int fd);
  static jlong lseek(int fd, jlong offset, int whence);
  static char* native_path(char *path);
  static int ftruncate(int fd, jlong length);
  static int fsync(int fd);
  static int available(int fd, jlong *bytes);
  static size_t read(int fd, void *buf, unsigned int nBytes);
  static size_t read_at(int fd, void *buf, unsigned int nBytes, jlong offset);
  static size_t restartable_read(int fd, void *buf, unsigned int nBytes);
  static size_t write(int fd, const void *buf, unsigned int nBytes);
  static DIR*           opendir(const char* dirname);
  static struct dirent* readdir(DIR* dirp);
  static int            closedir(DIR* dirp);
  static const char*    dll_file_extension();
  static const char*    get_temp_directory();
  static const char*    get_current_directory(char *buf, size_t buflen);
  static bool           dll_build_name(char* buffer, size_t size,
                                       const char* pathname, const char* fname);
  static bool dll_address_to_function_name(address addr, char* buf,
                                           int buflen, int* offset);
  static bool dll_address_to_library_name(address addr, char* buf,
                                          int buflen, int* offset);
  static bool address_is_in_vm(address addr);
  static void* dll_load(const char *name, char *ebuf, int ebuflen);
  static void* dll_lookup(void* handle, const char* name);
  static void  dll_unload(void *lib);
  typedef int (*LoadedModulesCallbackFunc)(const char *, address, address, void *);
  static int get_loaded_modules_info(LoadedModulesCallbackFunc callback, void *param);
  static void* get_default_process_handle();
  static bool find_builtin_agent(AgentLibrary *agent_lib, const char *syms[],
                                 size_t syms_len);
  static void *find_agent_function(AgentLibrary *agent_lib, bool check_lib,
                                   const char *syms[], size_t syms_len);
  static int vsnprintf(char* buf, size_t len, const char* fmt, va_list args) ATTRIBUTE_PRINTF(3, 0);
  static int snprintf(char* buf, size_t len, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4);
  static void print_os_info(outputStream* st);
  static void print_os_info_brief(outputStream* st);
  static void print_cpu_info(outputStream* st);
  static void pd_print_cpu_info(outputStream* st);
  static void print_memory_info(outputStream* st);
  static void print_dll_info(outputStream* st);
  static void print_environment_variables(outputStream* st, const char** env_list, char* buffer, int len);
  static void print_context(outputStream* st, void* context);
  static void print_register_info(outputStream* st, void* context);
  static void print_siginfo(outputStream* st, void* siginfo);
  static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
  static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
  static void print_location(outputStream* st, intptr_t x, bool verbose = false);
  static size_t lasterror(char *buf, size_t len);
  static int get_last_error();
  static bool is_debugger_attached();
  static void wait_for_keypress_at_exit(void);
  static bool is_first_C_frame(frame *fr);
  static frame get_sender_for_C_frame(frame *fr);
  static frame      current_frame();
  static void print_hex_dump(outputStream* st, address start, address end, int unitsize);
  static const char* exception_name(int exception_code, char* buf, size_t buflen);
  static void*    native_java_library();
  static void     jvm_path(char *buf, jint buflen);
  static bool     is_headless_jre();
  static void     print_jni_name_prefix_on(outputStream* st, int args_size);
  static void     print_jni_name_suffix_on(outputStream* st, int args_size);
  static const char* file_separator();
  static const char* line_separator();
  static const char* path_separator();
  static void init_system_properties_values();
  static int stat(const char* path, struct stat* sbuf);
  static bool dir_is_empty(const char* path);
  static int create_binary_file(const char* path, bool rewrite_existing);
  static jlong current_file_offset(int fd);
  static jlong seek_to_file_offset(int fd, jlong offset);
  static int   allocate_thread_local_storage();
  static void  thread_local_storage_at_put(int index, void* value);
  static void* thread_local_storage_at(int index);
  static void  free_thread_local_storage(int index);
  static int get_native_stack(address* stack, int size, int toSkip = 0);
  static void* malloc  (size_t size, MEMFLAGS flags, const NativeCallStack& stack);
  static void* malloc  (size_t size, MEMFLAGS flags);
  static void* realloc (void *memblock, size_t size, MEMFLAGS flag, const NativeCallStack& stack);
  static void* realloc (void *memblock, size_t size, MEMFLAGS flag);
  static void  free    (void *memblock, MEMFLAGS flags = mtNone);
  static bool  check_heap(bool force = false);      // verify C heap integrity
  static char* strdup(const char *, MEMFLAGS flags = mtInternal);  // Like strdup
#ifndef PRODUCT
  static julong num_mallocs;         // # of calls to malloc/realloc
  static julong alloc_bytes;         // # of bytes allocated
  static julong num_frees;           // # of calls to free
  static julong free_bytes;          // # of bytes freed
#endif
  static int socket(int domain, int type, int protocol);
  static int socket_close(int fd);
  static int socket_shutdown(int fd, int howto);
  static int recv(int fd, char* buf, size_t nBytes, uint flags);
  static int send(int fd, char* buf, size_t nBytes, uint flags);
  static int raw_send(int fd, char* buf, size_t nBytes, uint flags);
  static int timeout(int fd, long timeout);
  static int listen(int fd, int count);
  static int connect(int fd, struct sockaddr* him, socklen_t len);
  static int bind(int fd, struct sockaddr* him, socklen_t len);
  static int accept(int fd, struct sockaddr* him, socklen_t* len);
  static int recvfrom(int fd, char* buf, size_t nbytes, uint flags,
                      struct sockaddr* from, socklen_t* fromlen);
  static int get_sock_name(int fd, struct sockaddr* him, socklen_t* len);
  static int sendto(int fd, char* buf, size_t len, uint flags,
                    struct sockaddr* to, socklen_t tolen);
  static int socket_available(int fd, jint* pbytes);
  static int get_sock_opt(int fd, int level, int optname,
                          char* optval, socklen_t* optlen);
  static int set_sock_opt(int fd, int level, int optname,
                          const char* optval, socklen_t optlen);
  static int get_host_name(char* name, int namelen);
  static struct hostent* get_host_by_name(char* name);
  static void  signal_init();
  static void  signal_init_pd();
  static void  signal_notify(int signal_number);
  static void* signal(int signal_number, void* handler);
  static void  signal_raise(int signal_number);
  static int   signal_wait();
  static int   signal_lookup();
  static void* user_handler();
  static void  terminate_signal_thread();
  static int   sigexitnum_pd();
  static long random();                    // return 32bit pseudorandom number
  static void init_random(long initval);   // initialize random sequence
  static void os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
  static void check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize);
  static int get_core_path(char* buffer, size_t bufferSize);
  static jlong current_thread_cpu_time();
  static jlong thread_cpu_time(Thread* t);
  static jlong current_thread_cpu_time(bool user_sys_cpu_time);
  static jlong thread_cpu_time(Thread* t, bool user_sys_cpu_time);
  static void current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr);
  static void thread_cpu_time_info(jvmtiTimerInfo *info_ptr);
  static bool is_thread_cpu_time_supported();
  static int loadavg(double loadavg[], int nelem);
  static bool obsolete_option(const JavaVMOption *option);
#include "runtime/os_ext.hpp"
 public:
  class CrashProtectionCallback : public StackObj {
  public:
    virtual void call() = 0;
  };
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.hpp"
# include "os_posix.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.hpp"
# include "os_posix.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "os_aix.hpp"
# include "os_posix.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_posix.hpp"
# include "os_bsd.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_x86
# include "os_linux_x86.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_aarch64
# include "os_linux_aarch64.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_sparc
# include "os_linux_sparc.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_zero
# include "os_linux_zero.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_x86
# include "os_solaris_x86.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_sparc
# include "os_solaris_sparc.hpp"
#endif
#ifdef TARGET_OS_ARCH_windows_x86
# include "os_windows_x86.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_arm
# include "os_linux_arm.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_ppc
# include "os_linux_ppc.hpp"
#endif
#ifdef TARGET_OS_ARCH_aix_ppc
# include "os_aix_ppc.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_x86
# include "os_bsd_x86.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_zero
# include "os_bsd_zero.hpp"
#endif
 public:
#ifndef PLATFORM_PRINT_NATIVE_STACK
  static bool platform_print_native_stack(outputStream* st, void* context,
                                          char *buf, int buf_size) {
    return false;
  }
#endif
  static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address
  static bool dont_yield();                     // when true, JVM_Yield() is nop
  static void print_statistics();
  static OSReturn set_native_priority(Thread* thread, int native_prio);
  static OSReturn get_native_priority(const Thread* const thread, int* priority_ptr);
  static int java_to_os_priority[CriticalPriority + 1];
  static void hint_no_preempt();
  static void pause();
  static char*  build_agent_function_name(const char *sym, const char *cname,
                                          bool is_absolute_path);
  class SuspendedThreadTaskContext {
  public:
    SuspendedThreadTaskContext(Thread* thread, void *ucontext) : _thread(thread), _ucontext(ucontext) {}
    Thread* thread() const { return _thread; }
    void* ucontext() const { return _ucontext; }
  private:
    Thread* _thread;
    void* _ucontext;
  };
  class SuspendedThreadTask {
  public:
    SuspendedThreadTask(Thread* thread) : _thread(thread), _done(false) {}
    virtual ~SuspendedThreadTask() {}
    void run();
    bool is_done() { return _done; }
    virtual void do_task(const SuspendedThreadTaskContext& context) = 0;
  protected:
  private:
    void internal_do_task();
    Thread* _thread;
    bool _done;
  };
#ifndef TARGET_OS_FAMILY_windows
  class SuspendResume {
   public:
    enum State {
      SR_RUNNING,
      SR_SUSPEND_REQUEST,
      SR_SUSPENDED,
      SR_WAKEUP_REQUEST
    };
  private:
    volatile State _state;
  private:
    State switch_state(State from, State to);
  public:
    SuspendResume() : _state(SR_RUNNING) { }
    State state() const { return _state; }
    State request_suspend() {
      return switch_state(SR_RUNNING, SR_SUSPEND_REQUEST);
    }
    State cancel_suspend() {
      return switch_state(SR_SUSPEND_REQUEST, SR_RUNNING);
    }
    State suspended() {
      return switch_state(SR_SUSPEND_REQUEST, SR_SUSPENDED);
    }
    State request_wakeup() {
      return switch_state(SR_SUSPENDED, SR_WAKEUP_REQUEST);
    }
    State running() {
      return switch_state(SR_WAKEUP_REQUEST, SR_RUNNING);
    }
    bool is_running() const {
      return _state == SR_RUNNING;
    }
    bool is_suspend_request() const {
      return _state == SR_SUSPEND_REQUEST;
    }
    bool is_suspended() const {
      return _state == SR_SUSPENDED;
    }
  };
#endif
 protected:
  static long _rand_seed;                     // seed for random number generator
  static int _processor_count;                // number of processors
  static int _initial_active_processor_count; // number of active processors during initialization.
  static char* format_boot_path(const char* format_string,
                                const char* home,
                                int home_len,
                                char fileSep,
                                char pathSep);
  static bool set_boot_path(char fileSep, char pathSep);
  static char** split_path(const char* path, int* n);
};
extern "C" int SpinPause();
#endif // SHARE_VM_RUNTIME_OS_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/osThread.cpp
#include "precompiled.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/osThread.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) {
  pd_initialize();
  set_start_proc(start_proc);
  set_start_parm(start_parm);
  set_interrupted(false);
}
OSThread::~OSThread() {
  pd_destroy();
}
void OSThread::print_on(outputStream *st) const {
  st->print("nid=0x%lx ", thread_id());
  switch (_state) {
    case ALLOCATED:               st->print("allocated ");                 break;
    case INITIALIZED:             st->print("initialized ");               break;
    case RUNNABLE:                st->print("runnable ");                  break;
    case MONITOR_WAIT:            st->print("waiting for monitor entry "); break;
    case CONDVAR_WAIT:            st->print("waiting on condition ");      break;
    case OBJECT_WAIT:             st->print("in Object.wait() ");          break;
    case BREAKPOINTED:            st->print("at breakpoint");               break;
    case SLEEPING:                st->print("sleeping");                    break;
    case ZOMBIE:                  st->print("zombie");                      break;
    default:                      st->print("unknown state %d", _state); break;
  }
}
C:\hotspot-69087d08d473\src\share\vm/runtime/osThread.hpp
#ifndef SHARE_VM_RUNTIME_OSTHREAD_HPP
#define SHARE_VM_RUNTIME_OSTHREAD_HPP
#include "runtime/frame.hpp"
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
#include "runtime/objectMonitor.hpp"
#include "utilities/top.hpp"
enum ThreadState {
  ALLOCATED,                    // Memory has been allocated but not initialized
  INITIALIZED,                  // The thread has been initialized but yet started
  RUNNABLE,                     // Has been started and is runnable, but not necessarily running
  MONITOR_WAIT,                 // Waiting on a contended monitor lock
  CONDVAR_WAIT,                 // Waiting on a condition variable
  OBJECT_WAIT,                  // Waiting on an Object.wait() call
  BREAKPOINTED,                 // Suspended at breakpoint
  SLEEPING,                     // Thread.sleep()
  ZOMBIE                        // All done, but not reclaimed yet
};
class OSThread: public CHeapObj<mtThread> {
  friend class VMStructs;
 private:
  OSThreadStartFunc _start_proc;  // Thread start routine
  void* _start_parm;              // Thread start routine parameter
  volatile ThreadState _state;    // Thread state *hint*
  volatile jint _interrupted;     // Thread.isInterrupted state
 public:
  void set_state(ThreadState state)                { _state = state; }
  ThreadState get_state()                          { return _state; }
  OSThread(OSThreadStartFunc start_proc, void* start_parm);
  ~OSThread();
  OSThreadStartFunc start_proc() const              { return _start_proc; }
  void set_start_proc(OSThreadStartFunc start_proc) { _start_proc = start_proc; }
  void* start_parm() const                          { return _start_parm; }
  void set_start_parm(void* start_parm)             { _start_parm = start_parm; }
  volatile bool interrupted() const                 { return _interrupted != 0; }
  void set_interrupted(bool z)                      { _interrupted = z ? 1 : 0; }
  void print_on(outputStream* st) const;
  void print() const                                { print_on(tty); }
  static ByteSize interrupted_offset()            { return byte_offset_of(OSThread, _interrupted); }
#ifdef TARGET_OS_FAMILY_linux
# include "osThread_linux.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "osThread_solaris.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "osThread_windows.hpp"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "osThread_aix.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "osThread_bsd.hpp"
#endif
 public:
  static ByteSize thread_id_offset()              { return byte_offset_of(OSThread, _thread_id); }
  static size_t thread_id_size()                  { return sizeof(thread_id_t); }
  thread_id_t thread_id() const                   { return _thread_id; }
  void set_thread_id(thread_id_t id)              { _thread_id = id; }
 private:
  thread_id_t _thread_id;
};
class OSThreadWaitState : public StackObj {
  OSThread*   _osthread;
  ThreadState _old_state;
 public:
  OSThreadWaitState(OSThread* osthread, bool is_object_wait) {
    _osthread  = osthread;
    _old_state = osthread->get_state();
    if (is_object_wait) {
      osthread->set_state(OBJECT_WAIT);
    } else {
      osthread->set_state(CONDVAR_WAIT);
    }
  }
  ~OSThreadWaitState() {
    _osthread->set_state(_old_state);
  }
};
class OSThreadContendState : public StackObj {
  OSThread*   _osthread;
  ThreadState _old_state;
 public:
  OSThreadContendState(OSThread* osthread) {
    _osthread  = osthread;
    _old_state = osthread->get_state();
    osthread->set_state(MONITOR_WAIT);
  }
  ~OSThreadContendState() {
    _osthread->set_state(_old_state);
  }
};
#endif // SHARE_VM_RUNTIME_OSTHREAD_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/os_ext.hpp
#ifndef SHARE_VM_RUNTIME_OS_EXT_HPP
#define SHARE_VM_RUNTIME_OS_EXT_HPP
 public:
  static void init_globals_ext() {} // Run from init_globals().
 private:
#endif // SHARE_VM_RUNTIME_OS_EXT_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/os_perf.hpp
#ifndef SHARE_VM_RUNTIME_OS_PERF_HPP
#define SHARE_VM_RUNTIME_OS_PERF_HPP
#include "utilities/macros.hpp"
#include "memory/allocation.inline.hpp"
#include "utilities/globalDefinitions.hpp"
#define FUNCTIONALITY_NOT_IMPLEMENTED -8
class CPUInformation : public CHeapObj<mtInternal> {
 private:
  int   _no_of_sockets;
  int   _no_of_cores;
  int   _no_of_hw_threads;
  const char* _description;
  const char* _name;
 public:
  CPUInformation() {
    _no_of_sockets = 0;
    _no_of_cores = 0;
    _no_of_hw_threads = 0;
    _description = NULL;
    _name = NULL;
  }
  int number_of_sockets(void) const {
    return _no_of_sockets;
  }
  void set_number_of_sockets(int no_of_sockets) {
    _no_of_sockets = no_of_sockets;
  }
  int number_of_cores(void) const {
    return _no_of_cores;
  }
  void set_number_of_cores(int no_of_cores) {
    _no_of_cores = no_of_cores;
  }
  int number_of_hardware_threads(void) const {
    return _no_of_hw_threads;
  }
  void set_number_of_hardware_threads(int no_of_hw_threads) {
    _no_of_hw_threads = no_of_hw_threads;
  }
  const char* cpu_name(void)  const {
    return _name;
  }
  void set_cpu_name(const char* cpu_name) {
    _name = cpu_name;
  }
  const char* cpu_description(void) const {
    return _description;
  }
  void set_cpu_description(const char* cpu_description) {
    _description = cpu_description;
  }
};
class SystemProcess : public CHeapObj<mtInternal> {
 private:
  int   _pid;
  char* _name;
  char* _path;
  char* _command_line;
  SystemProcess* _next;
 public:
  SystemProcess() {
    _pid  = 0;
    _name = NULL;
    _path = NULL;
    _command_line = NULL;
    _next = NULL;
  }
  SystemProcess(int pid, char* name, char* path, char* command_line, SystemProcess* next) {
    _pid = pid;
    _name = name;
    _path = path;
    _command_line = command_line;
    _next = next;
  }
  void set_next(SystemProcess* sys_process) {
    _next = sys_process;
  }
  SystemProcess* next(void) const {
    return _next;
  }
  int pid(void) const {
    return _pid;
  }
  void set_pid(int pid) {
    _pid = pid;
  }
  const char* name(void) const {
    return _name;
  }
  void set_name(char* name) {
    _name = name;
  }
  const char* path(void) const {
    return _path;
  }
  void set_path(char* path) {
    _path = path;
  }
  const char* command_line(void) const {
    return _command_line;
  }
  void set_command_line(char* command_line) {
    _command_line = command_line;
  }
  virtual ~SystemProcess(void) {
    if (_name != NULL) {
      FREE_C_HEAP_ARRAY(char, _name, mtInternal);
    }
    if (_path != NULL) {
      FREE_C_HEAP_ARRAY(char, _path, mtInternal);
    }
    if (_command_line != NULL) {
      FREE_C_HEAP_ARRAY(char, _command_line, mtInternal);
    }
  }
};
class NetworkInterface : public ResourceObj {
 private:
  char* _name;
  uint64_t _bytes_in;
  uint64_t _bytes_out;
  NetworkInterface* _next;
  NetworkInterface(); // no impl
  NetworkInterface(const NetworkInterface& rhs); // no impl
  NetworkInterface& operator=(const NetworkInterface& rhs); // no impl
 public:
  NetworkInterface(const char* name, uint64_t bytes_in, uint64_t bytes_out, NetworkInterface* next) :
  _name(NULL),
  _bytes_in(bytes_in),
  _bytes_out(bytes_out),
  _next(next) {
    assert(name != NULL, "invariant");
    const size_t length = strlen(name);
    assert(allocated_on_res_area(), "invariant");
    _name = NEW_RESOURCE_ARRAY(char, length + 1);
    strncpy(_name, name, length + 1);
    assert(strncmp(_name, name, length) == 0, "invariant");
  }
  NetworkInterface* next() const {
    return _next;
  }
  const char* get_name() const {
    return _name;
  }
  uint64_t get_bytes_out() const {
    return _bytes_out;
  }
  uint64_t get_bytes_in() const {
    return _bytes_in;
  }
};
class CPUInformationInterface : public CHeapObj<mtInternal> {
 private:
  CPUInformation* _cpu_info;
 public:
  CPUInformationInterface();
  bool initialize();
  ~CPUInformationInterface();
  int cpu_information(CPUInformation& cpu_info);
};
class CPUPerformanceInterface : public CHeapObj<mtInternal> {
 private:
  class CPUPerformance;
  CPUPerformance* _impl;
 public:
  CPUPerformanceInterface();
  ~CPUPerformanceInterface();
  bool initialize();
  int cpu_load(int which_logical_cpu, double* const cpu_load) const;
  int context_switch_rate(double* const rate) const;
  int cpu_load_total_process(double* const cpu_load) const;
  int cpu_loads_process(double* const pjvmUserLoad,
                        double* const pjvmKernelLoad,
                        double* const psystemTotalLoad) const;
};
class SystemProcessInterface : public CHeapObj<mtInternal> {
 private:
   class SystemProcesses;
   SystemProcesses* _impl;
 public:
   SystemProcessInterface();
   ~SystemProcessInterface();
   bool initialize();
  int system_processes(SystemProcess** system_procs, int* const no_of_sys_processes) const;
};
class NetworkPerformanceInterface : public CHeapObj<mtInternal> {
 private:
  class NetworkPerformance;
  NetworkPerformance* _impl;
  NetworkPerformanceInterface(const NetworkPerformanceInterface& rhs); // no impl
  NetworkPerformanceInterface& operator=(const NetworkPerformanceInterface& rhs); // no impl
 public:
  NetworkPerformanceInterface();
  bool initialize();
  ~NetworkPerformanceInterface();
  int network_utilization(NetworkInterface** network_interfaces) const;
};
#endif // SHARE_VM_RUNTIME_OS_PERF_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/park.cpp
#include "precompiled.hpp"
#include "runtime/thread.hpp"
volatile int ParkEvent::ListLock = 0 ;
ParkEvent * volatile ParkEvent::FreeList = NULL ;
ParkEvent * ParkEvent::Allocate (Thread * t) {
  ParkEvent * ev ;
  Thread::SpinAcquire(&ListLock, "ParkEventFreeListAllocate");
  {
    ev = FreeList;
    if (ev != NULL) {
      FreeList = ev->FreeNext;
    }
  }
  Thread::SpinRelease(&ListLock);
  if (ev != NULL) {
    guarantee (ev->AssociatedWith == NULL, "invariant") ;
  } else {
    ev = new ParkEvent () ;
    guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ;
  }
  ev->reset() ;                     // courtesy to caller
  ev->AssociatedWith = t ;          // Associate ev with t
  ev->FreeNext       = NULL ;
  return ev ;
}
void ParkEvent::Release (ParkEvent * ev) {
  if (ev == NULL) return ;
  guarantee (ev->FreeNext == NULL      , "invariant") ;
  ev->AssociatedWith = NULL ;
  Thread::SpinAcquire(&ListLock, "ParkEventFreeListRelease");
  {
    ev->FreeNext = FreeList;
    FreeList = ev;
  }
  Thread::SpinRelease(&ListLock);
}
void * ParkEvent::operator new (size_t sz) throw() {
  return (void *) ((intptr_t (AllocateHeap(sz + 256, mtInternal, CALLER_PC)) + 256) & -256) ;
}
void ParkEvent::operator delete (void * a) {
  ShouldNotReachHere();
}
volatile int Parker::ListLock = 0 ;
Parker * volatile Parker::FreeList = NULL ;
Parker * Parker::Allocate (JavaThread * t) {
  guarantee (t != NULL, "invariant") ;
  Parker * p ;
  Thread::SpinAcquire(&ListLock, "ParkerFreeListAllocate");
  {
    p = FreeList;
    if (p != NULL) {
      FreeList = p->FreeNext;
    }
  }
  Thread::SpinRelease(&ListLock);
  if (p != NULL) {
    guarantee (p->AssociatedWith == NULL, "invariant") ;
  } else {
    p = new Parker() ;
  }
  p->AssociatedWith = t ;          // Associate p with t
  p->FreeNext       = NULL ;
  return p ;
}
void Parker::Release (Parker * p) {
  if (p == NULL) return ;
  guarantee (p->AssociatedWith != NULL, "invariant") ;
  guarantee (p->FreeNext == NULL      , "invariant") ;
  p->AssociatedWith = NULL ;
  Thread::SpinAcquire(&ListLock, "ParkerFreeListRelease");
  {
    p->FreeNext = FreeList;
    FreeList = p;
  }
  Thread::SpinRelease(&ListLock);
}
C:\hotspot-69087d08d473\src\share\vm/runtime/park.hpp
#ifndef SHARE_VM_RUNTIME_PARK_HPP
#define SHARE_VM_RUNTIME_PARK_HPP
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
class Parker : public os::PlatformParker {
private:
  volatile int _counter ;
  Parker * FreeNext ;
  JavaThread * AssociatedWith ; // Current association
public:
  Parker() : PlatformParker() {
    _counter       = 0 ;
    FreeNext       = NULL ;
    AssociatedWith = NULL ;
  }
protected:
  ~Parker() { ShouldNotReachHere(); }
public:
  void park(bool isAbsolute, jlong time);
  void unpark();
  static Parker * Allocate (JavaThread * t) ;
  static void Release (Parker * e) ;
private:
  static Parker * volatile FreeList ;
  static volatile int ListLock ;
};
class ParkEvent : public os::PlatformEvent {
  private:
    ParkEvent * FreeNext ;
    Thread * AssociatedWith ;
    intptr_t RawThreadIdentity ;        // LWPID etc
    volatile int Incarnation ;
    void * LastWaker ;
  public:
    ParkEvent * volatile ListNext ;
    ParkEvent * volatile ListPrev ;
    volatile intptr_t OnList ;
    volatile int TState ;
    volatile int Notified ;             // for native monitor construct
    volatile int IsWaiting ;            // Enqueued on WaitSet
  private:
    static ParkEvent * volatile FreeList ;
    static volatile int ListLock ;
  protected:        // Ensure dtor is never invoked
    ~ParkEvent() { guarantee (0, "invariant") ; }
    ParkEvent() : PlatformEvent() {
       AssociatedWith = NULL ;
       FreeNext       = NULL ;
       ListNext       = NULL ;
       ListPrev       = NULL ;
       OnList         = 0 ;
       TState         = 0 ;
       Notified       = 0 ;
       IsWaiting      = 0 ;
    }
    void * operator new (size_t sz) throw();
    void operator delete (void * a) ;
  public:
    static ParkEvent * Allocate (Thread * t) ;
    static void Release (ParkEvent * e) ;
} ;
#endif // SHARE_VM_RUNTIME_PARK_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/perfData.cpp
#include "precompiled.hpp"
#include "classfile/vmSymbols.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/globalDefinitions.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
PerfDataList*   PerfDataManager::_all = NULL;
PerfDataList*   PerfDataManager::_sampled = NULL;
PerfDataList*   PerfDataManager::_constants = NULL;
const char* PerfDataManager::_name_spaces[] = {
  "java",                   // stable and supported name space
  "com.sun",                // unstable but supported name space
  "sun",                    // unstable and unsupported name space
  "java.gc",                // Garbage Collection name spaces
  "com.sun.gc",
  "sun.gc",
  "java.ci",                // Compiler name spaces
  "com.sun.ci",
  "sun.ci",
  "java.cls",               // Class Loader name spaces
  "com.sun.cls",
  "sun.cls",
  "java.rt",                // Runtime name spaces
  "com.sun.rt",
  "sun.rt",
  "java.os",                // Operating System name spaces
  "com.sun.os",
  "sun.os",
  "java.threads",           // Threads System name spaces
  "com.sun.threads",
  "sun.threads",
  "java.property",          // Java Property name spaces
  "com.sun.property",
  "sun.property",
  "",
};
PerfData::PerfData(CounterNS ns, const char* name, Units u, Variability v)
                  : _name(NULL), _u(u), _v(v), _valuep(NULL),
                    _on_c_heap(false) {
  const char* prefix = PerfDataManager::ns_to_string(ns);
  _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2, mtInternal);
  assert(_name != NULL && strlen(name) != 0, "invalid name");
  if (ns == NULL_NS) {
     strcpy(_name, name);
     if (PerfDataManager::is_stable_supported(_name) ||
         PerfDataManager::is_unstable_supported(_name)) {
       _flags = F_Supported;
     }
     else {
       _flags = F_None;
     }
  }
  else {
    sprintf(_name, "%s.%s", prefix, name);
    if (PerfDataManager::is_stable_supported(ns) ||
        PerfDataManager::is_unstable_supported(ns)) {
      _flags = F_Supported;
    }
    else {
      _flags = F_None;
    }
  }
}
PerfData::~PerfData() {
  if (_name != NULL) {
    FREE_C_HEAP_ARRAY(char, _name, mtInternal);
  }
  if (is_on_c_heap()) {
    FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep, mtInternal);
  }
}
void PerfData::create_entry(BasicType dtype, size_t dsize, size_t vlen) {
  size_t dlen = vlen==0 ? 1 : vlen;
  size_t namelen = strlen(name()) + 1;  // include null terminator
  size_t size = sizeof(PerfDataEntry) + namelen;
  size_t pad_length = ((size % dsize) == 0) ? 0 : dsize - (size % dsize);
  size += pad_length;
  size_t data_start = size;
  size += (dsize * dlen);
  int align = sizeof(jlong) - 1;
  size = ((size + align) & ~align);
  char* psmp = PerfMemory::alloc(size);
  if (psmp == NULL) {
    psmp = NEW_C_HEAP_ARRAY(char, size, mtInternal);
    _on_c_heap = true;
  }
  char* cname = psmp + sizeof(PerfDataEntry);
  void* valuep = (void*) (psmp + data_start);
  assert(is_on_c_heap() || PerfMemory::contains(cname), "just checking");
  assert(is_on_c_heap() || PerfMemory::contains((char*)valuep), "just checking");
  strcpy(cname, name());
  PerfDataEntry* pdep = (PerfDataEntry*)psmp;
  pdep->entry_length = (jint)size;
  pdep->name_offset = (jint) ((uintptr_t) cname - (uintptr_t) psmp);
  pdep->vector_length = (jint)vlen;
  pdep->data_type = (jbyte) type2char(dtype);
  pdep->data_units = units();
  pdep->data_variability = variability();
  pdep->flags = (jbyte)flags();
  pdep->data_offset = (jint) data_start;
  if (PerfTraceDataCreation) {
    tty->print("name = %s, dtype = %d, variability = %d,"
               " units = %d, dsize = %d, vlen = %d,"
               " pad_length = %d, size = %d, on_c_heap = %s,"
               " address = " INTPTR_FORMAT ","
               " data address = " INTPTR_FORMAT "\n",
               cname, dtype, variability(),
               units(), dsize, vlen,
               pad_length, size, is_on_c_heap() ? "TRUE":"FALSE",
               psmp, valuep);
  }
  _pdep = pdep;
  _valuep = valuep;
  PerfMemory::mark_updated();
}
PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
                 : PerfData(ns, namep, u, v) {
  create_entry(T_LONG, sizeof(jlong));
}
int PerfLong::format(char* buffer, int length) {
  return jio_snprintf(buffer, length, JLONG_FORMAT, *(jlong*)_valuep);
}
PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
                                 Variability v, jlong* sampled)
                                : PerfLong(ns, namep, u, v),
                                  _sampled(sampled), _sample_helper(NULL) {
  sample();
}
PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
                                 Variability v, PerfLongSampleHelper* helper)
                                : PerfLong(ns, namep, u, v),
                                  _sampled(NULL), _sample_helper(helper) {
  sample();
}
void PerfLongVariant::sample() {
  if (_sample_helper == NULL) return;
  if (_sample_helper != NULL) {
  }
  else if (_sampled != NULL) {
  }
}
PerfByteArray::PerfByteArray(CounterNS ns, const char* namep, Units u,
                             Variability v, jint length)
                            : PerfData(ns, namep, u, v), _length(length) {
  create_entry(T_BYTE, sizeof(jbyte), (size_t)_length);
}
void PerfString::set_string(const char* s2) {
  strncpy((char *)_valuep, s2 == NULL ? "" : s2, _length);
  ((char*)_valuep)[_length-1] = '\0';
}
int PerfString::format(char* buffer, int length) {
  return jio_snprintf(buffer, length, "%s", (char*)_valuep);
}
PerfStringConstant::PerfStringConstant(CounterNS ns, const char* namep,
                                       const char* initial_value)
                     : PerfString(ns, namep, V_Constant,
                                  initial_value == NULL ? 1 :
                                  MIN2((jint)(strlen((char*)initial_value)+1),
                                       (jint)(PerfMaxStringConstLength+1)),
                                  initial_value) {
  if (PrintMiscellaneous && Verbose) {
    if (is_valid() && initial_value != NULL &&
        ((jint)strlen(initial_value) > (jint)PerfMaxStringConstLength)) {
      warning("Truncating PerfStringConstant: name = %s,"
              " length = " INT32_FORMAT ","
              " PerfMaxStringConstLength = " INT32_FORMAT "\n",
              namep,
              (jint)strlen(initial_value),
              (jint)PerfMaxStringConstLength);
    }
  }
}
void PerfDataManager::destroy() {
  if (_all == NULL)
    return;
  for (int index = 0; index < _all->length(); index++) {
    PerfData* p = _all->at(index);
    delete p;
  }
  delete(_all);
  delete(_sampled);
  delete(_constants);
  _all = NULL;
  _sampled = NULL;
  _constants = NULL;
}
void PerfDataManager::add_item(PerfData* p, bool sampled) {
  MutexLocker ml(PerfDataManager_lock);
  if (_all == NULL) {
    _all = new PerfDataList(100);
  }
  assert(!_all->contains(p->name()), "duplicate name added");
  _all->append(p);
  if (p->variability() == PerfData::V_Constant) {
    if (_constants == NULL) {
      _constants = new PerfDataList(25);
    }
    _constants->append(p);
    return;
  }
  if (sampled) {
    if (_sampled == NULL) {
      _sampled = new PerfDataList(25);
    }
    _sampled->append(p);
  }
}
PerfData* PerfDataManager::find_by_name(const char* name) {
  return _all->find_by_name(name);
}
PerfDataList* PerfDataManager::all() {
  MutexLocker ml(PerfDataManager_lock);
  if (_all == NULL)
    return NULL;
  PerfDataList* clone = _all->clone();
  return clone;
}
PerfDataList* PerfDataManager::sampled() {
  MutexLocker ml(PerfDataManager_lock);
  if (_sampled == NULL)
    return NULL;
  PerfDataList* clone = _sampled->clone();
  return clone;
}
PerfDataList* PerfDataManager::constants() {
  MutexLocker ml(PerfDataManager_lock);
  if (_constants == NULL)
    return NULL;
  PerfDataList* clone = _constants->clone();
  return clone;
}
char* PerfDataManager::counter_name(const char* ns, const char* name) {
   assert(ns != NULL, "ns string required");
   assert(name != NULL, "name string required");
   size_t len = strlen(ns) + strlen(name) + 2;
   char* result = NEW_RESOURCE_ARRAY(char, len);
   sprintf(result, "%s.%s", ns, name);
   return result;
}
char* PerfDataManager::name_space(const char* ns, const char* sub,
                                  int instance) {
   char intbuf[40];
   jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   return name_space(ns, name_space(sub, intbuf));
}
char *PerfDataManager::name_space(const char* ns, int instance) {
   char intbuf[40];
   jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   return name_space(ns, intbuf);
}
PerfStringConstant* PerfDataManager::create_string_constant(CounterNS ns,
                                                            const char* name,
                                                            const char* s,
                                                            TRAPS) {
  PerfStringConstant* p = new PerfStringConstant(ns, name, s);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, false);
  return p;
}
PerfLongConstant* PerfDataManager::create_long_constant(CounterNS ns,
                                                        const char* name,
                                                        PerfData::Units u,
                                                        jlong val, TRAPS) {
  PerfLongConstant* p = new PerfLongConstant(ns, name, u, val);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, false);
  return p;
}
PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns,
                                                            const char* name,
                                                            jint max_length,
                                                            const char* s,
                                                            TRAPS) {
  if (max_length == 0 && s != NULL) max_length = (jint)strlen(s);
  assert(max_length != 0, "PerfStringVariable with length 0");
  PerfStringVariable* p = new PerfStringVariable(ns, name, max_length, s);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, false);
  return p;
}
PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
                                                        const char* name,
                                                        PerfData::Units u,
                                                        jlong ival, TRAPS) {
  PerfLongVariable* p = new PerfLongVariable(ns, name, u, ival);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, false);
  return p;
}
PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
                                                        const char* name,
                                                        PerfData::Units u,
                                                        jlong* sp, TRAPS) {
  if (!UsePerfData) return NULL;
  PerfLongVariable* p = new PerfLongVariable(ns, name, u, sp);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, true);
  return p;
}
PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
                                                        const char* name,
                                                        PerfData::Units u,
                                                        PerfSampleHelper* sh,
                                                        TRAPS) {
  if (!UsePerfData) return NULL;
  PerfLongVariable* p = new PerfLongVariable(ns, name, u, sh);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, true);
  return p;
}
PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
                                                      const char* name,
                                                      PerfData::Units u,
                                                      jlong ival, TRAPS) {
  PerfLongCounter* p = new PerfLongCounter(ns, name, u, ival);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, false);
  return p;
}
PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
                                                      const char* name,
                                                      PerfData::Units u,
                                                      jlong* sp, TRAPS) {
  if (!UsePerfData) return NULL;
  PerfLongCounter* p = new PerfLongCounter(ns, name, u, sp);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, true);
  return p;
}
PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
                                                      const char* name,
                                                      PerfData::Units u,
                                                      PerfSampleHelper* sh,
                                                      TRAPS) {
  if (!UsePerfData) return NULL;
  PerfLongCounter* p = new PerfLongCounter(ns, name, u, sh);
  if (!p->is_valid()) {
    delete p;
    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
  }
  add_item(p, true);
  return p;
}
PerfDataList::PerfDataList(int length) {
  _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(length, true);
}
PerfDataList::PerfDataList(PerfDataList* p) {
  _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(p->length(), true);
  _set->appendAll(p->get_impl());
}
PerfDataList::~PerfDataList() {
  delete _set;
}
bool PerfDataList::by_name(void* name, PerfData* pd) {
  if (pd == NULL)
    return false;
  return strcmp((const char*)name, pd->name()) == 0;
}
PerfData* PerfDataList::find_by_name(const char* name) {
  if (this == NULL)
    return NULL;
  int i = _set->find((void*)name, PerfDataList::by_name);
  if (i >= 0 && i <= _set->length())
    return _set->at(i);
  else
    return NULL;
}
PerfDataList* PerfDataList::clone() {
  PerfDataList* copy = new PerfDataList(this);
  assert(copy != NULL, "just checking");
  return copy;
}
C:\hotspot-69087d08d473\src\share\vm/runtime/perfData.hpp
#ifndef SHARE_VM_RUNTIME_PERFDATA_HPP
#define SHARE_VM_RUNTIME_PERFDATA_HPP
#include "memory/allocation.inline.hpp"
#include "runtime/perfMemory.hpp"
#include "runtime/timer.hpp"
#include "utilities/growableArray.hpp"
enum CounterNS {
  JAVA_NS,
  COM_NS,
  SUN_NS,
  JAVA_GC,              // Garbage Collection name spaces
  COM_GC,
  SUN_GC,
  JAVA_CI,              // Compiler name spaces
  COM_CI,
  SUN_CI,
  JAVA_CLS,             // Class Loader name spaces
  COM_CLS,
  SUN_CLS,
  JAVA_RT,              // Runtime name spaces
  COM_RT,
  SUN_RT,
  JAVA_OS,              // Operating System name spaces
  COM_OS,
  SUN_OS,
  JAVA_THREADS,         // Threads System name spaces
  COM_THREADS,
  SUN_THREADS,
  JAVA_PROPERTY,        // Java Property name spaces
  COM_PROPERTY,
  SUN_PROPERTY,
  NULL_NS,
  COUNTERNS_LAST = NULL_NS
};
.*                                                        PerfData::U_Bytes,
class PerfData : public CHeapObj<mtInternal> {
  friend class StatSampler;      // for access to protected void sample()
  friend class PerfDataManager;  // for access to protected destructor
  public:
    enum Variability {
      V_Constant = 1,
      V_Monotonic = 2,
      V_Variable = 3,
      V_last = V_Variable
    };
    enum Units {
      U_None = 1,
      U_Bytes = 2,
      U_Ticks = 3,
      U_Events = 4,
      U_String = 5,
      U_Hertz = 6,
      U_Last = U_Hertz
    };
    enum Flags {
      F_None = 0x0,
      F_Supported = 0x1    // interface is supported - java.* and com.sun.*
    };
  private:
    char* _name;
    Variability _v;
    Units _u;
    bool _on_c_heap;
    Flags _flags;
    PerfDataEntry* _pdep;
  protected:
    void *_valuep;
    PerfData(CounterNS ns, const char* name, Units u, Variability v);
    virtual ~PerfData();
    void create_entry(BasicType dtype, size_t dsize, size_t dlen = 0);
    virtual void sample() = 0;
  public:
    inline bool is_valid() { return _valuep != NULL; }
    inline bool is_on_c_heap() { return _on_c_heap; }
    const char* name() { return _name; }
    Variability variability() { return _v; }
    Units units() { return _u; }
    Flags flags() { return _flags; }
    inline void* get_address() { return _valuep; }
    virtual int format(char* cp, int length) = 0;
};
class PerfLongSampleHelper : public CHeapObj<mtInternal> {
  public:
    virtual jlong take_sample() = 0;
};
typedef PerfLongSampleHelper PerfSampleHelper;
class PerfLong : public PerfData {
  protected:
    PerfLong(CounterNS ns, const char* namep, Units u, Variability v);
  public:
    int format(char* buffer, int length);
    inline jlong get_value() { return *(jlong*)_valuep; }
};
class PerfLongConstant : public PerfLong {
  friend class PerfDataManager; // for access to protected constructor
  private:
    void sample() { }
  protected:
    PerfLongConstant(CounterNS ns, const char* namep, Units u,
                     jlong initial_value=0)
                    : PerfLong(ns, namep, u, V_Constant) {
       if (is_valid()) *(jlong*)_valuep = initial_value;
    }
};
typedef PerfLongConstant PerfConstant;
class PerfLongVariant : public PerfLong {
  protected:
    jlong* _sampled;
    PerfLongSampleHelper* _sample_helper;
    PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
                    jlong initial_value=0)
                   : PerfLong(ns, namep, u, v) {
      if (is_valid()) *(jlong*)_valuep = initial_value;
    }
    PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
                    jlong* sampled);
    PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
                    PerfLongSampleHelper* sample_helper);
    void sample();
  public:
    inline void inc() { (*(jlong*)_valuep)++; }
    inline void inc(jlong val) { (*(jlong*)_valuep) += val; }
    inline void add(jlong val) { (*(jlong*)_valuep) += val; }
    void clear_sample_helper() { _sample_helper = NULL; }
};
class PerfLongCounter : public PerfLongVariant {
  friend class PerfDataManager; // for access to protected constructor
  protected:
    PerfLongCounter(CounterNS ns, const char* namep, Units u,
                    jlong initial_value=0)
                   : PerfLongVariant(ns, namep, u, V_Monotonic,
                                     initial_value) { }
    PerfLongCounter(CounterNS ns, const char* namep, Units u, jlong* sampled)
                  : PerfLongVariant(ns, namep, u, V_Monotonic, sampled) { }
    PerfLongCounter(CounterNS ns, const char* namep, Units u,
                    PerfLongSampleHelper* sample_helper)
                   : PerfLongVariant(ns, namep, u, V_Monotonic,
                                     sample_helper) { }
};
typedef PerfLongCounter PerfCounter;
class PerfLongVariable : public PerfLongVariant {
  friend class PerfDataManager; // for access to protected constructor
  protected:
    PerfLongVariable(CounterNS ns, const char* namep, Units u,
                     jlong initial_value=0)
                    : PerfLongVariant(ns, namep, u, V_Variable,
                                      initial_value) { }
    PerfLongVariable(CounterNS ns, const char* namep, Units u, jlong* sampled)
                    : PerfLongVariant(ns, namep, u, V_Variable, sampled) { }
    PerfLongVariable(CounterNS ns, const char* namep, Units u,
                     PerfLongSampleHelper* sample_helper)
                    : PerfLongVariant(ns, namep, u, V_Variable,
                                      sample_helper) { }
  public:
    inline void set_value(jlong val) { (*(jlong*)_valuep) = val; }
};
typedef PerfLongVariable PerfVariable;
class PerfByteArray : public PerfData {
  protected:
    jint _length;
    PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v,
                  jint length);
};
class PerfString : public PerfByteArray {
  protected:
    void set_string(const char* s2);
    PerfString(CounterNS ns, const char* namep, Variability v, jint length,
               const char* initial_value)
              : PerfByteArray(ns, namep, U_String, v, length) {
       if (is_valid()) set_string(initial_value);
    }
  public:
    int format(char* buffer, int length);
};
class PerfStringConstant : public PerfString {
  friend class PerfDataManager; // for access to protected constructor
  private:
    void sample() { }
  protected:
    PerfStringConstant(CounterNS ns, const char* namep,
                       const char* initial_value);
};
class PerfStringVariable : public PerfString {
  friend class PerfDataManager; // for access to protected constructor
  protected:
    void sample() { }
    PerfStringVariable(CounterNS ns, const char* namep, jint max_length,
                       const char* initial_value)
                      : PerfString(ns, namep, V_Variable, max_length+1,
                                   initial_value) { }
  public:
    inline void set_value(const char* val) { set_string(val); }
};
class PerfDataList : public CHeapObj<mtInternal> {
  private:
    typedef GrowableArray<PerfData*> PerfDataArray;
    PerfDataArray* _set;
    static bool by_name(void* name, PerfData* pd);
  protected:
    PerfDataArray* get_impl() { return _set; }
  public:
    PerfDataList(int length);
    PerfDataList(PerfDataList* p);
    ~PerfDataList();
    PerfData* find_by_name(const char* name);
    bool contains(const char* name) { return find_by_name(name) != NULL; }
    int length() { return _set->length(); }
    void append(PerfData *p) { _set->append(p); }
    void remove(PerfData *p) { _set->remove(p); }
    PerfDataList* clone();
    PerfData* at(int index) { return _set->at(index); }
};
class PerfDataManager : AllStatic {
  friend class StatSampler;   // for access to protected PerfDataList methods
  private:
    static PerfDataList* _all;
    static PerfDataList* _sampled;
    static PerfDataList* _constants;
    static const char* _name_spaces[];
    static void add_item(PerfData* p, bool sampled);
  protected:
    static PerfDataList* all();
    static int count() { return _all->length(); }
    static PerfDataList* sampled();
    static int sampled_count() { return _sampled->length(); }
    static PerfDataList* constants();
    static int constants_count() { return _constants->length(); }
  public:
    static bool exists(const char* name) { return _all->contains(name); }
    static PerfData* find_by_name(const char* name);
    static const char* ns_to_string(CounterNS ns) {
      return _name_spaces[ns];
    }
    static bool is_stable_supported(CounterNS ns) {
      return (ns != NULL_NS) && ((ns % 3) == JAVA_NS);
    }
    static bool is_unstable_supported(CounterNS ns) {
      return (ns != NULL_NS) && ((ns % 3) == COM_NS);
    }
    static bool is_unstable_unsupported(CounterNS ns) {
      return (ns == NULL_NS) || ((ns % 3) == SUN_NS);
    }
    static bool is_stable_supported(const char* name) {
      const char* javadot = "java.";
      return strncmp(name, javadot, strlen(javadot)) == 0;
    }
    static bool is_unstable_supported(const char* name) {
      const char* comdot = "com.sun.";
      return strncmp(name, comdot, strlen(comdot)) == 0;
    }
    static bool is_unstable_unsupported(const char* name) {
      return !(is_stable_supported(name) && is_unstable_supported(name));
    }
    static char* counter_name(const char* name_space, const char* name);
    static char* name_space(const char* name_space, const char* sub_space) {
      return counter_name(name_space, sub_space);
    }
    static char* name_space(const char* name_space, const char* sub_space,
                            int instance);
    static char* name_space(const char* name_space, int instance);
    static PerfStringConstant* create_string_constant(CounterNS ns,
                                                      const char* name,
                                                      const char *s, TRAPS);
    static PerfLongConstant* create_long_constant(CounterNS ns,
                                                  const char* name,
                                                  PerfData::Units u,
                                                  jlong val, TRAPS);
    static PerfStringVariable* create_string_variable(CounterNS ns,
                                                      const char* name,
                                                      int max_length,
                                                      const char *s, TRAPS);
    static PerfStringVariable* create_string_variable(CounterNS ns,
                                                      const char* name,
                                                      const char *s, TRAPS) {
      return create_string_variable(ns, name, 0, s, THREAD);
    };
    static PerfLongVariable* create_long_variable(CounterNS ns,
                                                  const char* name,
                                                  PerfData::Units u,
                                                  jlong ival, TRAPS);
    static PerfLongVariable* create_long_variable(CounterNS ns,
                                                  const char* name,
                                                  PerfData::Units u, TRAPS) {
      return create_long_variable(ns, name, u, (jlong)0, THREAD);
    };
    static PerfLongVariable* create_long_variable(CounterNS, const char* name,
                                                  PerfData::Units u,
                                                  jlong* sp, TRAPS);
    static PerfLongVariable* create_long_variable(CounterNS ns,
                                                  const char* name,
                                                  PerfData::Units u,
                                                  PerfLongSampleHelper* sh,
                                                  TRAPS);
    static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
                                                PerfData::Units u,
                                                jlong ival, TRAPS);
    static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
                                                PerfData::Units u, TRAPS) {
      return create_long_counter(ns, name, u, (jlong)0, THREAD);
    };
    static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
                                                PerfData::Units u, jlong* sp,
                                                TRAPS);
    static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
                                                PerfData::Units u,
                                                PerfLongSampleHelper* sh,
                                                TRAPS);
    static PerfConstant* create_constant(CounterNS ns, const char* name,
                                         PerfData::Units u, jlong val, TRAPS) {
      return create_long_constant(ns, name, u, val, THREAD);
    }
    static PerfVariable* create_variable(CounterNS ns, const char* name,
                                         PerfData::Units u, jlong ival, TRAPS) {
      return create_long_variable(ns, name, u, ival, THREAD);
    }
    static PerfVariable* create_variable(CounterNS ns, const char* name,
                                         PerfData::Units u, TRAPS) {
      return create_long_variable(ns, name, u, (jlong)0, THREAD);
    }
    static PerfVariable* create_variable(CounterNS ns, const char* name,
                                         PerfData::Units u, jlong* sp, TRAPS) {
      return create_long_variable(ns, name, u, sp, THREAD);
    }
    static PerfVariable* create_variable(CounterNS ns, const char* name,
                                         PerfData::Units u,
                                         PerfSampleHelper* sh, TRAPS) {
      return create_long_variable(ns, name, u, sh, THREAD);
    }
    static PerfCounter* create_counter(CounterNS ns, const char* name,
                                       PerfData::Units u, jlong ival, TRAPS) {
      return create_long_counter(ns, name, u, ival, THREAD);
    }
    static PerfCounter* create_counter(CounterNS ns, const char* name,
                                       PerfData::Units u, TRAPS) {
      return create_long_counter(ns, name, u, (jlong)0, THREAD);
    }
    static PerfCounter* create_counter(CounterNS ns, const char* name,
                                       PerfData::Units u, jlong* sp, TRAPS) {
      return create_long_counter(ns, name, u, sp, THREAD);
    }
    static PerfCounter* create_counter(CounterNS ns, const char* name,
                                       PerfData::Units u,
                                       PerfSampleHelper* sh, TRAPS) {
      return create_long_counter(ns, name, u, sh, THREAD);
    }
    static void destroy();
};
#define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name)  \
  {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
                                             PerfData::U_Ticks,CHECK);}
#define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name)  \
  {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
                                             PerfData::U_Events,CHECK);}
#define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name)  \
  {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
                                             PerfData::U_Bytes,CHECK);}
class PerfTraceTime : public StackObj {
  protected:
    elapsedTimer _t;
    PerfLongCounter* _timerp;
    int* _recursion_counter;
  public:
    inline PerfTraceTime(PerfLongCounter* timerp) : _timerp(timerp), _recursion_counter(NULL) {
      if (!UsePerfData) return;
      _t.start();
    }
    inline PerfTraceTime(PerfLongCounter* timerp, int* recursion_counter) : _timerp(timerp), _recursion_counter(recursion_counter) {
      if (!UsePerfData || (_recursion_counter != NULL &&
                           (*_recursion_counter)++ > 0)) return;
      _t.start();
    }
    inline void suspend() { if (!UsePerfData) return; _t.stop(); }
    inline void resume() { if (!UsePerfData) return; _t.start(); }
    inline ~PerfTraceTime() {
      if (!UsePerfData || (_recursion_counter != NULL &&
                           --(*_recursion_counter) > 0)) return;
      _t.stop();
      _timerp->inc(_t.ticks());
    }
};
class PerfTraceTimedEvent : public PerfTraceTime {
  protected:
    PerfLongCounter* _eventp;
  public:
    inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp): PerfTraceTime(timerp), _eventp(eventp) {
      if (!UsePerfData) return;
      _eventp->inc();
    }
    inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp, int* recursion_counter): PerfTraceTime(timerp, recursion_counter), _eventp(eventp) {
      if (!UsePerfData) return;
      _eventp->inc();
    }
};
#endif // SHARE_VM_RUNTIME_PERFDATA_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/perfMemory.cpp
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/java.hpp"
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "runtime/perfMemory.hpp"
#include "runtime/statSampler.hpp"
#include "utilities/globalDefinitions.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
const char               PERFDATA_NAME[] = "hsperfdata";
static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
                                            UINT_CHARS + 1;
char*                    PerfMemory::_start = NULL;
char*                    PerfMemory::_end = NULL;
char*                    PerfMemory::_top = NULL;
size_t                   PerfMemory::_capacity = 0;
jint                     PerfMemory::_initialized = false;
PerfDataPrologue*        PerfMemory::_prologue = NULL;
void perfMemory_init() {
  if (!UsePerfData) return;
  PerfMemory::initialize();
}
void perfMemory_exit() {
  if (!UsePerfData) return;
  if (!PerfMemory::is_initialized()) return;
  if (!StatSampler::is_active())
    PerfDataManager::destroy();
  PerfMemory::destroy();
}
void PerfMemory::initialize() {
  if (_prologue != NULL)
    return;
  size_t capacity = align_size_up(PerfDataMemorySize,
                                  os::vm_allocation_granularity());
  if (PerfTraceMemOps) {
    tty->print("PerfDataMemorySize = " SIZE_FORMAT ","
               " os::vm_allocation_granularity = " SIZE_FORMAT ","
               " adjusted size = " SIZE_FORMAT "\n",
               PerfDataMemorySize,
               os::vm_allocation_granularity(),
               capacity);
  }
  create_memory_region(capacity);
  if (_start == NULL) {
    if (PrintMiscellaneous && Verbose) {
      warning("Could not create PerfData Memory region, reverting to malloc");
    }
    _prologue = NEW_C_HEAP_OBJ(PerfDataPrologue, mtInternal);
  }
  else {
    if (PerfTraceMemOps) {
      tty->print("PerfMemory created: address = " INTPTR_FORMAT ","
                 " size = " SIZE_FORMAT "\n",
                 (void*)_start,
                 _capacity);
    }
    _prologue = (PerfDataPrologue *)_start;
    _end = _start + _capacity;
    _top = _start + sizeof(PerfDataPrologue);
  }
  assert(_prologue != NULL, "prologue pointer must be initialized");
#ifdef VM_LITTLE_ENDIAN
  _prologue->magic = (jint)0xc0c0feca;
  _prologue->byte_order = PERFDATA_LITTLE_ENDIAN;
#else
  _prologue->magic = (jint)0xcafec0c0;
  _prologue->byte_order = PERFDATA_BIG_ENDIAN;
#endif
  _prologue->major_version = PERFDATA_MAJOR_VERSION;
  _prologue->minor_version = PERFDATA_MINOR_VERSION;
  _prologue->accessible = 0;
  _prologue->entry_offset = sizeof(PerfDataPrologue);
  _prologue->num_entries = 0;
  _prologue->used = 0;
  _prologue->overflow = 0;
  _prologue->mod_time_stamp = 0;
  OrderAccess::release_store(&_initialized, 1);
}
void PerfMemory::destroy() {
  if (_prologue == NULL) return;
  if (_start != NULL && _prologue->overflow != 0) {
    if (PrintMiscellaneous && Verbose) {
      warning("PerfMemory Overflow Occurred.\n"
              "\tCapacity = " SIZE_FORMAT " bytes"
              "  Used = " SIZE_FORMAT " bytes"
              "  Overflow = " INT32_FORMAT " bytes"
              "\n\tUse -XX:PerfDataMemorySize=<size> to specify larger size.",
              PerfMemory::capacity(),
              PerfMemory::used(),
              _prologue->overflow);
    }
  }
  if (_start != NULL) {
    delete_memory_region();
  }
  _start = NULL;
  _end = NULL;
  _top = NULL;
  _prologue = NULL;
  _capacity = 0;
}
char* PerfMemory::alloc(size_t size) {
  if (!UsePerfData) return NULL;
  MutexLocker ml(PerfDataMemAlloc_lock);
  assert(_prologue != NULL, "called before initialization");
  if ((_top + size) >= _end) {
    _prologue->overflow += (jint)size;
    return NULL;
  }
  char* result = _top;
  _top += size;
  assert(contains(result), "PerfData memory pointer out of range");
  _prologue->used = (jint)used();
  _prologue->num_entries = _prologue->num_entries + 1;
  return result;
}
void PerfMemory::mark_updated() {
  if (!UsePerfData) return;
  _prologue->mod_time_stamp = os::elapsed_counter();
}
char* PerfMemory::get_perfdata_file_path() {
  char* dest_file = NULL;
  if (PerfDataSaveFile != NULL) {
    dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN, mtInternal);
    if(!Arguments::copy_expand_pid(PerfDataSaveFile, strlen(PerfDataSaveFile),
                                   dest_file, JVM_MAXPATHLEN)) {
      FREE_C_HEAP_ARRAY(char, dest_file, mtInternal);
      if (PrintMiscellaneous && Verbose) {
        warning("Invalid performance data file path name specified, "\
                "fall back to a default name");
      }
    } else {
      return dest_file;
    }
  }
  dest_file = NEW_C_HEAP_ARRAY(char, PERFDATA_FILENAME_LEN, mtInternal);
  jio_snprintf(dest_file, PERFDATA_FILENAME_LEN,
               "%s_%d", PERFDATA_NAME, os::current_process_id());
  return dest_file;
}
C:\hotspot-69087d08d473\src\share\vm/runtime/perfMemory.hpp
#ifndef SHARE_VM_RUNTIME_PERFMEMORY_HPP
#define SHARE_VM_RUNTIME_PERFMEMORY_HPP
#include "utilities/exceptions.hpp"
#define PERFDATA_MAJOR_VERSION 2
#define PERFDATA_MINOR_VERSION 0
#define PERFDATA_BIG_ENDIAN     0
#define PERFDATA_LITTLE_ENDIAN  1
typedef struct {
  jint   magic;              // magic number - 0xcafec0c0
  jbyte  byte_order;         // byte order of the buffer
  jbyte  major_version;      // major and minor version numbers
  jbyte  minor_version;
  jbyte  accessible;         // ready to access
  jint   used;               // number of PerfData memory bytes used
  jint   overflow;           // number of bytes of overflow
  jlong  mod_time_stamp;     // time stamp of last structural modification
  jint   entry_offset;       // offset of the first PerfDataEntry
  jint   num_entries;        // number of allocated PerfData entries
} PerfDataPrologue;
typedef struct {
  jint entry_length;      // entry length in bytes
  jint name_offset;       // offset of the data item name
  jint vector_length;     // length of the vector. If 0, then scalar
  jbyte data_type;        // type of the data item -
  jbyte flags;            // flags indicating misc attributes
  jbyte data_units;       // unit of measure for the data type
  jbyte data_variability; // variability classification of data type
  jint  data_offset;      // offset of the data item
  body of PerfData memory entry is variable length
  jbyte[name_length] data_name;        // name of the data item
  jbyte[pad_length] data_pad;          // alignment of data item
  j<data_type>[data_length] data_item; // array of appropriate types.
} PerfDataEntry;
extern const char PERFDATA_NAME[];
static const size_t UINT_CHARS = 10;
class PerfMemory : AllStatic {
    friend class VMStructs;
  private:
    static char*  _start;
    static char*  _end;
    static char*  _top;
    static size_t _capacity;
    static PerfDataPrologue*  _prologue;
    static jint   _initialized;
    static void create_memory_region(size_t sizep);
    static void delete_memory_region();
  public:
    enum PerfMemoryMode {
      PERF_MODE_RO = 0,
      PERF_MODE_RW = 1
    };
    static char* alloc(size_t size);
    static char* start() { return _start; }
    static char* end() { return _end; }
    static size_t used() { return (size_t) (_top - _start); }
    static size_t capacity() { return _capacity; }
    static bool is_initialized() { return _initialized != 0; }
    static bool contains(char* addr) {
      return ((_start != NULL) && (addr >= _start) && (addr < _end));
    }
    static void mark_updated();
    static void attach(const char* user, int vmid, PerfMemoryMode mode,
                       char** addrp, size_t* size, TRAPS);
    static void detach(char* addr, size_t bytes, TRAPS);
    static void initialize();
    static void destroy();
    static void set_accessible(bool value) {
      if (UsePerfData) {
        _prologue->accessible = value;
      }
    }
    static char* backing_store_filename();
    static char* get_perfdata_file_path();
};
void perfMemory_init();
void perfMemory_exit();
#endif // SHARE_VM_RUNTIME_PERFMEMORY_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/prefetch.hpp
#ifndef SHARE_VM_RUNTIME_PREFETCH_HPP
#define SHARE_VM_RUNTIME_PREFETCH_HPP
#include "memory/allocation.hpp"
class Prefetch : AllStatic {
 public:
  enum style {
    do_none,  // Do no prefetching
    do_read,  // Do read prefetching
    do_write  // Do write prefetching
  };
  static void read(void* loc, intx interval);
  static void write(void* loc, intx interval);
};
#endif // SHARE_VM_RUNTIME_PREFETCH_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/prefetch.inline.hpp
#ifndef SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP
#define SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP
#include "runtime/prefetch.hpp"
#ifdef TARGET_OS_ARCH_linux_x86
# include "prefetch_linux_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_sparc
# include "prefetch_linux_sparc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_zero
# include "prefetch_linux_zero.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_arm
# include "prefetch_linux_arm.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_aarch64
# include "prefetch_linux_aarch64.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_linux_ppc
# include "prefetch_linux_ppc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_x86
# include "prefetch_solaris_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_solaris_sparc
# include "prefetch_solaris_sparc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_windows_x86
# include "prefetch_windows_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_aix_ppc
# include "prefetch_aix_ppc.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_x86
# include "prefetch_bsd_x86.inline.hpp"
#endif
#ifdef TARGET_OS_ARCH_bsd_zero
# include "prefetch_bsd_zero.inline.hpp"
#endif
#endif // SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/reflection.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "prims/jvm.h"
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/reflection.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframe.hpp"
static void trace_class_resolution(Klass* to_class) {
  ResourceMark rm;
  int line_number = -1;
  const char * source_file = NULL;
  Klass* caller = NULL;
  JavaThread* jthread = JavaThread::current();
  if (jthread->has_last_Java_frame()) {
    vframeStream vfst(jthread);
    while (!vfst.at_end() &&
           vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
      vfst.next();
    }
    if (!vfst.at_end()) {
      caller = vfst.method()->method_holder();
      line_number = vfst.method()->line_number_from_bci(vfst.bci());
      Symbol* s = vfst.method()->method_holder()->source_file_name();
      if (s != NULL) {
        source_file = s->as_C_string();
      }
    }
  }
  if (caller != NULL) {
    const char * from = caller->external_name();
    const char * to = to_class->external_name();
    if (source_file != NULL) {
      tty->print("RESOLVE %s %s %s:%d (reflection)\n", from, to, source_file, line_number);
    } else {
      tty->print("RESOLVE %s %s (reflection)\n", from, to);
    }
  }
}
oop Reflection::box(jvalue* value, BasicType type, TRAPS) {
  if (type == T_VOID) {
    return NULL;
  }
  if (type == T_OBJECT || type == T_ARRAY) {
    return (oop) value->l;
  }
  oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
  if (result == NULL) {
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
  }
  return result;
}
BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) {
  if (box == NULL) {
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL);
  }
  return java_lang_boxing_object::get_value(box, value);
}
BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) {
  value->l = (jobject) box;
  return T_OBJECT;
}
void Reflection::widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS) {
  assert(wide_type != current_type, "widen should not be called with identical types");
  switch (wide_type) {
    case T_BOOLEAN:
    case T_BYTE:
    case T_CHAR:
      break;  // fail
    case T_SHORT:
      switch (current_type) {
        case T_BYTE:
          value->s = (jshort) value->b;
          return;
      }
      break;  // fail
    case T_INT:
      switch (current_type) {
        case T_BYTE:
          value->i = (jint) value->b;
          return;
        case T_CHAR:
          value->i = (jint) value->c;
          return;
        case T_SHORT:
          value->i = (jint) value->s;
          return;
      }
      break;  // fail
    case T_LONG:
      switch (current_type) {
        case T_BYTE:
          value->j = (jlong) value->b;
          return;
        case T_CHAR:
          value->j = (jlong) value->c;
          return;
        case T_SHORT:
          value->j = (jlong) value->s;
          return;
        case T_INT:
          value->j = (jlong) value->i;
          return;
      }
      break;  // fail
    case T_FLOAT:
      switch (current_type) {
        case T_BYTE:
          value->f = (jfloat) value->b;
          return;
        case T_CHAR:
          value->f = (jfloat) value->c;
          return;
        case T_SHORT:
          value->f = (jfloat) value->s;
          return;
        case T_INT:
          value->f = (jfloat) value->i;
          return;
        case T_LONG:
          value->f = (jfloat) value->j;
          return;
      }
      break;  // fail
    case T_DOUBLE:
      switch (current_type) {
        case T_BYTE:
          value->d = (jdouble) value->b;
          return;
        case T_CHAR:
          value->d = (jdouble) value->c;
          return;
        case T_SHORT:
          value->d = (jdouble) value->s;
          return;
        case T_INT:
          value->d = (jdouble) value->i;
          return;
        case T_FLOAT:
          value->d = (jdouble) value->f;
          return;
        case T_LONG:
          value->d = (jdouble) value->j;
          return;
      }
      break;  // fail
    default:
      break;  // fail
  }
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
}
BasicType Reflection::array_get(jvalue* value, arrayOop a, int index, TRAPS) {
  if (!a->is_within_bounds(index)) {
    THROW_(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), T_ILLEGAL);
  }
  if (a->is_objArray()) {
    value->l = (jobject) objArrayOop(a)->obj_at(index);
    return T_OBJECT;
  } else {
    assert(a->is_typeArray(), "just checking");
    BasicType type = TypeArrayKlass::cast(a->klass())->element_type();
    switch (type) {
      case T_BOOLEAN:
        value->z = typeArrayOop(a)->bool_at(index);
        break;
      case T_CHAR:
        value->c = typeArrayOop(a)->char_at(index);
        break;
      case T_FLOAT:
        value->f = typeArrayOop(a)->float_at(index);
        break;
      case T_DOUBLE:
        value->d = typeArrayOop(a)->double_at(index);
        break;
      case T_BYTE:
        value->b = typeArrayOop(a)->byte_at(index);
        break;
      case T_SHORT:
        value->s = typeArrayOop(a)->short_at(index);
        break;
      case T_INT:
        value->i = typeArrayOop(a)->int_at(index);
        break;
      case T_LONG:
        value->j = typeArrayOop(a)->long_at(index);
        break;
      default:
        return T_ILLEGAL;
    }
    return type;
  }
}
void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS) {
  if (!a->is_within_bounds(index)) {
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
  }
  if (a->is_objArray()) {
    if (value_type == T_OBJECT) {
      oop obj = (oop) value->l;
      if (obj != NULL) {
        Klass* element_klass = ObjArrayKlass::cast(a->klass())->element_klass();
        if (!obj->is_a(element_klass)) {
          THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch");
        }
      }
      objArrayOop(a)->obj_at_put(index, obj);
    }
  } else {
    assert(a->is_typeArray(), "just checking");
    BasicType array_type = TypeArrayKlass::cast(a->klass())->element_type();
    if (array_type != value_type) {
      widen(value, value_type, array_type, CHECK);
    }
    switch (array_type) {
      case T_BOOLEAN:
        typeArrayOop(a)->bool_at_put(index, value->z);
        break;
      case T_CHAR:
        typeArrayOop(a)->char_at_put(index, value->c);
        break;
      case T_FLOAT:
        typeArrayOop(a)->float_at_put(index, value->f);
        break;
      case T_DOUBLE:
        typeArrayOop(a)->double_at_put(index, value->d);
        break;
      case T_BYTE:
        typeArrayOop(a)->byte_at_put(index, value->b);
        break;
      case T_SHORT:
        typeArrayOop(a)->short_at_put(index, value->s);
        break;
      case T_INT:
        typeArrayOop(a)->int_at_put(index, value->i);
        break;
      case T_LONG:
        typeArrayOop(a)->long_at_put(index, value->j);
        break;
      default:
        THROW(vmSymbols::java_lang_IllegalArgumentException());
    }
  }
}
Klass* Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) {
  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
  BasicType type = java_lang_Class::primitive_type(basic_type_mirror);
  if (type == T_VOID) {
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
  } else {
    return Universe::typeArrayKlassObj(type);
  }
}
oop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) {
  BasicType type = TypeArrayKlass::cast(basic_type_arrayklass)->element_type();
  return Universe::java_mirror(type);
}
arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) {
  if (element_mirror == NULL) {
    THROW_0(vmSymbols::java_lang_NullPointerException());
  }
  if (length < 0) {
    THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
  }
  if (java_lang_Class::is_primitive(element_mirror)) {
    Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
    return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
  } else {
    Klass* k = java_lang_Class::as_Klass(element_mirror);
    if (k->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
    }
    return oopFactory::new_objArray(k, length, THREAD);
  }
}
arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
  assert(dim_array->is_typeArray(), "just checking");
  assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking");
  if (element_mirror == NULL) {
    THROW_0(vmSymbols::java_lang_NullPointerException());
  }
  int len = dim_array->length();
  if (len <= 0 || len > MAX_DIM) {
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
  }
  jint dimensions[MAX_DIM];   // C array copy of intArrayOop
  for (int i = 0; i < len; i++) {
    int d = dim_array->int_at(i);
    if (d < 0) {
      THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
    }
    dimensions[i] = d;
  }
  Klass* klass;
  int dim = len;
  if (java_lang_Class::is_primitive(element_mirror)) {
    klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
  } else {
    klass = java_lang_Class::as_Klass(element_mirror);
    if (klass->oop_is_array()) {
      int k_dim = ArrayKlass::cast(klass)->dimension();
      if (k_dim + len > MAX_DIM) {
        THROW_0(vmSymbols::java_lang_IllegalArgumentException());
      }
      dim += k_dim;
    }
  }
  klass = klass->array_klass(dim, CHECK_NULL);
  oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
  assert(obj->is_array(), "just checking");
  return arrayOop(obj);
}
oop Reflection::array_component_type(oop mirror, TRAPS) {
  if (java_lang_Class::is_primitive(mirror)) {
    return NULL;
  }
  Klass* klass = java_lang_Class::as_Klass(mirror);
  if (!klass->oop_is_array()) {
    return NULL;
  }
  oop result = ArrayKlass::cast(klass)->component_mirror();
#ifdef ASSERT
  oop result2 = NULL;
  if (ArrayKlass::cast(klass)->dimension() == 1) {
    if (klass->oop_is_typeArray()) {
      result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL);
    } else {
      result2 = ObjArrayKlass::cast(klass)->element_klass()->java_mirror();
    }
  } else {
    Klass* lower_dim = ArrayKlass::cast(klass)->lower_dimension();
    assert(lower_dim->oop_is_array(), "just checking");
    result2 = lower_dim->java_mirror();
  }
  assert(result == result2, "results must be consistent");
#endif //ASSERT
  return result;
}
bool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) {
  ResourceMark rm(THREAD);
  assert(THREAD->is_Java_thread(), "sanity check");
  Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
  if (client_class != field_class) {
    if (!verify_class_access(client_class, field_class, false)
        || !verify_field_access(client_class,
                                field_class,
                                field_class,
                                acc,
                                false)) {
      THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
    }
  }
  if (acc.is_protected()) {
    if (target_class != client_class) {
      if (!is_same_class_package(client_class, field_class)) {
        if (!target_class->is_subclass_of(client_class)) {
          THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
        }
      }
    }
  }
  return true;
}
bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
  if ((current_class == NULL) ||
      (current_class == new_class) ||
      (new_class->is_public()) ||
      is_same_class_package(current_class, new_class)) {
    return true;
  }
  if (   JDK_Version::is_gte_jdk14x_version()
      && UseNewReflection
      && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
    return true;
  }
  return can_relax_access_check_for(current_class, new_class, classloader_only);
}
static bool under_host_klass(InstanceKlass* ik, Klass* host_klass) {
  DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
  for (;;) {
    Klass* hc = (Klass*) ik->host_klass();
    if (hc == NULL)        return false;
    if (hc == host_klass)  return true;
    ik = InstanceKlass::cast(hc);
    assert(--inf_loop_check > 0, "no host_klass loop");
  }
}
bool Reflection::can_relax_access_check_for(
    Klass* accessor, Klass* accessee, bool classloader_only) {
  InstanceKlass* accessor_ik = InstanceKlass::cast(accessor);
  InstanceKlass* accessee_ik  = InstanceKlass::cast(accessee);
  if (under_host_klass(accessor_ik, accessee) ||
      under_host_klass(accessee_ik, accessor))
    return true;
  if ((RelaxAccessControlCheck &&
        accessor_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION &&
        accessee_ik->major_version() < Verifier::NO_RELAX_ACCESS_CTRL_CHECK_VERSION) ||
      (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION &&
       accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) {
    return classloader_only &&
      Verifier::relax_access_for(accessor_ik->class_loader()) &&
      accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
      accessor_ik->class_loader() == accessee_ik->class_loader();
  } else {
    return false;
  }
}
bool Reflection::verify_field_access(Klass* current_class,
                                     Klass* resolved_class,
                                     Klass* field_class,
                                     AccessFlags access,
                                     bool classloader_only,
                                     bool protected_restriction) {
  if ((current_class == NULL) ||
      (current_class == field_class) ||
      access.is_public()) {
    return true;
  }
  Klass* host_class = current_class;
  while (host_class->oop_is_instance() &&
         InstanceKlass::cast(host_class)->is_anonymous()) {
    Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass();
    if (next_host_class == NULL)  break;
    host_class = next_host_class;
  }
  if (host_class == field_class) {
    return true;
  }
  if (access.is_protected()) {
    if (!protected_restriction) {
      if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) {
        if (access.is_static() || // static fields are ok, see 6622385
            current_class == resolved_class ||
            field_class == resolved_class ||
            host_class->is_subclass_of(resolved_class) ||
            resolved_class->is_subclass_of(host_class)) {
          return true;
        }
      }
    }
  }
  if (!access.is_private() && is_same_class_package(current_class, field_class)) {
    return true;
  }
  if (   JDK_Version::is_gte_jdk14x_version()
      && UseNewReflection
      && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
    return true;
  }
  return can_relax_access_check_for(
    current_class, field_class, classloader_only);
}
bool Reflection::is_same_class_package(Klass* class1, Klass* class2) {
  return InstanceKlass::cast(class1)->is_same_class_package(class2);
}
bool Reflection::is_same_package_member(Klass* class1, Klass* class2, TRAPS) {
  return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD);
}
void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
                                       bool inner_is_member, TRAPS) {
  InnerClassesIterator iter(outer);
  constantPoolHandle cp   (THREAD, outer->constants());
  for (; !iter.done(); iter.next()) {
     int ioff = iter.inner_class_info_index();
     int ooff = iter.outer_class_info_index();
     if (inner_is_member && ioff != 0 && ooff != 0) {
        Klass* o = cp->klass_at(ooff, CHECK);
        if (o == outer()) {
          Klass* i = cp->klass_at(ioff, CHECK);
          if (i == inner()) {
            return;
          }
        }
     }
     if (!inner_is_member && ioff != 0 && ooff == 0 &&
         cp->klass_name_at_matches(inner, ioff)) {
        Klass* i = cp->klass_at(ioff, CHECK);
        if (i == inner()) {
          return;
        }
     }
  }
  ResourceMark rm(THREAD);
  Exceptions::fthrow(
    THREAD_AND_LOCATION,
    vmSymbols::java_lang_IncompatibleClassChangeError(),
    "%s and %s disagree on InnerClasses attribute",
    outer->external_name(),
    inner->external_name()
  );
}
oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) {
  switch (ss->type()) {
    default:
      assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type");
      return java_lang_Class::primitive_mirror(ss->type());
    case T_OBJECT:
    case T_ARRAY:
      Symbol* name        = ss->as_symbol(CHECK_NULL);
      oop loader            = method->method_holder()->class_loader();
      oop protection_domain = method->method_holder()->protection_domain();
      Klass* k = SystemDictionary::resolve_or_fail(
                                       name,
                                       Handle(THREAD, loader),
                                       Handle(THREAD, protection_domain),
                                       true, CHECK_NULL);
      if (TraceClassResolution) {
        trace_class_resolution(k);
      }
      return k->java_mirror();
  };
}
objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) {
  objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
  objArrayHandle mirrors (THREAD, m);
  int index = 0;
  ResourceMark rm(THREAD);
  Symbol*  signature  = method->signature();
  SignatureStream ss(signature);
  while (!ss.at_return_type()) {
    oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
    mirrors->obj_at_put(index++, mirror);
    ss.next();
  }
  assert(index == parameter_count, "invalid parameter count");
  if (return_type != NULL) {
    assert(ss.at_return_type(), "return type should be present");
  }
  return mirrors;
}
objArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) {
  return method->resolved_checked_exceptions(THREAD);
}
Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) {
  BasicType type = vmSymbols::signature_type(signature);
  if (type != T_OBJECT) {
    return Handle(THREAD, Universe::java_mirror(type));
  }
  oop loader = InstanceKlass::cast(k())->class_loader();
  oop protection_domain = k()->protection_domain();
  Klass* result = SystemDictionary::resolve_or_fail(signature,
                                    Handle(THREAD, loader),
                                    Handle(THREAD, protection_domain),
                                    true, CHECK_(Handle()));
  if (TraceClassResolution) {
    trace_class_resolution(result);
  }
  oop nt = result->java_mirror();
  return Handle(THREAD, nt);
}
oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) {
  assert(!method()->is_initializer() ||
         (for_constant_pool_access && method()->is_static()) ||
         (method()->name() == vmSymbols::class_initializer_name()
    && method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
  instanceKlassHandle holder (THREAD, method->method_holder());
  int slot = method->method_idnum();
  Symbol*  signature  = method->signature();
  int parameter_count = ArgumentCount(signature).size();
  oop return_type_oop = NULL;
  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
  if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
  Handle return_type(THREAD, return_type_oop);
  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
  if (exception_types.is_null()) return NULL;
  Symbol*  method_name = method->name();
  Handle name;
  if (intern_name) {
    oop name_oop = StringTable::intern(method_name, CHECK_NULL);
    name = Handle(THREAD, name_oop);
  } else {
    name = java_lang_String::create_from_symbol(method_name, CHECK_NULL);
  }
  if (name == NULL) return NULL;
  int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
  Handle mh = java_lang_reflect_Method::create(CHECK_NULL);
  java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror());
  java_lang_reflect_Method::set_slot(mh(), slot);
  java_lang_reflect_Method::set_name(mh(), name());
  java_lang_reflect_Method::set_return_type(mh(), return_type());
  java_lang_reflect_Method::set_parameter_types(mh(), parameter_types());
  java_lang_reflect_Method::set_exception_types(mh(), exception_types());
  java_lang_reflect_Method::set_modifiers(mh(), modifiers);
  java_lang_reflect_Method::set_override(mh(), false);
  if (java_lang_reflect_Method::has_signature_field() &&
      method->generic_signature() != NULL) {
    Symbol*  gs = method->generic_signature();
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
    java_lang_reflect_Method::set_signature(mh(), sig());
  }
  if (java_lang_reflect_Method::has_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
    java_lang_reflect_Method::set_annotations(mh(), an_oop);
  }
  if (java_lang_reflect_Method::has_parameter_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
    java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop);
  }
  if (java_lang_reflect_Method::has_annotation_default_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL);
    java_lang_reflect_Method::set_annotation_default(mh(), an_oop);
  }
  if (java_lang_reflect_Method::has_type_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL);
    java_lang_reflect_Method::set_type_annotations(mh(), an_oop);
  }
  return mh();
}
oop Reflection::new_constructor(methodHandle method, TRAPS) {
  assert(method()->is_initializer(), "should call new_method instead");
  instanceKlassHandle  holder (THREAD, method->method_holder());
  int slot = method->method_idnum();
  Symbol*  signature  = method->signature();
  int parameter_count = ArgumentCount(signature).size();
  objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL);
  if (parameter_types.is_null()) return NULL;
  objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
  if (exception_types.is_null()) return NULL;
  int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
  Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL);
  java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror());
  java_lang_reflect_Constructor::set_slot(ch(), slot);
  java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types());
  java_lang_reflect_Constructor::set_exception_types(ch(), exception_types());
  java_lang_reflect_Constructor::set_modifiers(ch(), modifiers);
  java_lang_reflect_Constructor::set_override(ch(), false);
  if (java_lang_reflect_Constructor::has_signature_field() &&
      method->generic_signature() != NULL) {
    Symbol*  gs = method->generic_signature();
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
    java_lang_reflect_Constructor::set_signature(ch(), sig());
  }
  if (java_lang_reflect_Constructor::has_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL);
    java_lang_reflect_Constructor::set_annotations(ch(), an_oop);
  }
  if (java_lang_reflect_Constructor::has_parameter_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL);
    java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop);
  }
  if (java_lang_reflect_Constructor::has_type_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL);
    java_lang_reflect_Constructor::set_type_annotations(ch(), an_oop);
  }
  return ch();
}
oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
  Symbol*  field_name = fd->name();
  Handle name;
  if (intern_name) {
    oop name_oop = StringTable::intern(field_name, CHECK_NULL);
    name = Handle(THREAD, name_oop);
  } else {
    name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
  }
  Symbol*  signature  = fd->signature();
  instanceKlassHandle  holder    (THREAD, fd->field_holder());
  Handle type = new_type(signature, holder, CHECK_NULL);
  Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
  java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
  java_lang_reflect_Field::set_slot(rh(), fd->index());
  java_lang_reflect_Field::set_name(rh(), name());
  java_lang_reflect_Field::set_type(rh(), type());
  java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
  java_lang_reflect_Field::set_override(rh(), false);
  if (java_lang_reflect_Field::has_signature_field() &&
      fd->has_generic_signature()) {
    Symbol*  gs = fd->generic_signature();
    Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
    java_lang_reflect_Field::set_signature(rh(), sig());
  }
  if (java_lang_reflect_Field::has_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL);
    java_lang_reflect_Field::set_annotations(rh(), an_oop);
  }
  if (java_lang_reflect_Field::has_type_annotations_field()) {
    typeArrayOop an_oop = Annotations::make_java_array(fd->type_annotations(), CHECK_NULL);
    java_lang_reflect_Field::set_type_annotations(rh(), an_oop);
  }
  return rh();
}
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
                              int flags, TRAPS) {
  Handle name;
  if(NULL != sym) {
    name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
  } else {
    name = java_lang_String::create_from_str("", CHECK_NULL);
  }
  Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
  java_lang_reflect_Parameter::set_name(rh(), name());
  java_lang_reflect_Parameter::set_modifiers(rh(), flags);
  java_lang_reflect_Parameter::set_executable(rh(), method());
  java_lang_reflect_Parameter::set_index(rh(), index);
  return rh();
}
methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
                                                KlassHandle recv_klass, Handle receiver, TRAPS) {
  assert(!method.is_null() , "method should not be null");
  CallInfo info;
  Symbol*  signature  = method->signature();
  Symbol*  name       = method->name();
  LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass,
                                       name, signature,
                                       KlassHandle(), false, true,
                                       CHECK_(methodHandle()));
  return info.selected_method();
}
oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
                       Handle receiver, bool override, objArrayHandle ptypes,
                       BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) {
  ResourceMark rm(THREAD);
  methodHandle method;      // actual method to invoke
  KlassHandle target_klass; // target klass, receiver's klass for non-static
  klass->initialize(CHECK_NULL);
  bool is_static = reflected_method->is_static();
  if (is_static) {
    method = reflected_method;
    target_klass = klass;
  } else {
    if (receiver.is_null()) {
      THROW_0(vmSymbols::java_lang_NullPointerException());
    }
    if (!receiver->is_a(klass())) {
      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
    }
    target_klass = KlassHandle(THREAD, receiver->klass());
    if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
      method = reflected_method;
    } else {
      if (reflected_method->method_holder()->is_interface()) {
        if (ReflectionWrapResolutionErrors) {
          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD);
          if (HAS_PENDING_EXCEPTION) {
            oop resolution_exception = PENDING_EXCEPTION;
            CLEAR_PENDING_EXCEPTION;
            if (THREAD->is_Java_thread()) {
              JvmtiExport::clear_detected_exception((JavaThread*) THREAD);
            }
            JavaCallArguments args(Handle(THREAD, resolution_exception));
            THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
                vmSymbols::throwable_void_signature(),
                &args);
          }
        } else {
          method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL));
        }
      }  else {
        assert(!reflected_method->has_itable_index(), "");
        int index = reflected_method->vtable_index();
        method = reflected_method;
        if (index != Method::nonvirtual_vtable_index) {
          InstanceKlass* inst = (InstanceKlass*)target_klass();
          method = methodHandle(THREAD, inst->method_at_vtable(index));
        }
        if (!method.is_null()) {
          if (method->is_abstract()) {
            if (ReflectionWrapResolutionErrors) {
              ResourceMark rm(THREAD);
              Handle h_origexception = Exceptions::new_exception(THREAD,
                     vmSymbols::java_lang_AbstractMethodError(),
                     Method::name_and_sig_as_C_string(target_klass(),
                     method->name(),
                     method->signature()));
              JavaCallArguments args(h_origexception);
              THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
                vmSymbols::throwable_void_signature(),
                &args);
            } else {
              ResourceMark rm(THREAD);
              THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(),
                        Method::name_and_sig_as_C_string(target_klass(),
                                                                method->name(),
                                                                method->signature()));
            }
          }
        }
      }
    }
  }
  if (method.is_null()) {
    ResourceMark rm(THREAD);
    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
                Method::name_and_sig_as_C_string(klass(),
                                                        reflected_method->name(),
                                                        reflected_method->signature()));
  }
  if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) {
  if (!override) {
    if (!(klass->is_public() && reflected_method->is_public())) {
      bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
      if (!access) {
        return NULL; // exception
      }
    }
  }
  } // !(Universe::is_gte_jdk14x_version() && UseNewReflection)
  assert(ptypes->is_objArray(), "just checking");
  int args_len = args.is_null() ? 0 : args->length();
  if (ptypes->length() != args_len) {
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments");
  }
  JavaCallArguments java_args(method->size_of_parameters());
  if (!is_static) {
    java_args.push_oop(receiver);
  }
  for (int i = 0; i < args_len; i++) {
    oop type_mirror = ptypes->obj_at(i);
    oop arg = args->obj_at(i);
    if (java_lang_Class::is_primitive(type_mirror)) {
      jvalue value;
      BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL);
      BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL);
      if (ptype != atype) {
        widen(&value, atype, ptype, CHECK_NULL);
      }
      switch (ptype) {
        case T_BOOLEAN:     java_args.push_int(value.z);    break;
        case T_CHAR:        java_args.push_int(value.c);    break;
        case T_BYTE:        java_args.push_int(value.b);    break;
        case T_SHORT:       java_args.push_int(value.s);    break;
        case T_INT:         java_args.push_int(value.i);    break;
        case T_LONG:        java_args.push_long(value.j);   break;
        case T_FLOAT:       java_args.push_float(value.f);  break;
        case T_DOUBLE:      java_args.push_double(value.d); break;
        default:
          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
      }
    } else {
      if (arg != NULL) {
        Klass* k = java_lang_Class::as_Klass(type_mirror);
        if (!arg->is_a(k)) {
          THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
        }
      }
      Handle arg_handle(THREAD, arg);         // Create handle for argument
      java_args.push_oop(arg_handle); // Push handle
    }
  }
  assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking");
  JavaValue result(rtype);
  JavaCalls::call(&result, method, &java_args, THREAD);
  if (HAS_PENDING_EXCEPTION) {
    oop target_exception = PENDING_EXCEPTION;
    CLEAR_PENDING_EXCEPTION;
    if (THREAD->is_Java_thread()) {
      JvmtiExport::clear_detected_exception((JavaThread*) THREAD);
    }
    JavaCallArguments args(Handle(THREAD, target_exception));
    THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
                vmSymbols::throwable_void_signature(),
                &args);
  } else {
    if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT)
      narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
    return box((jvalue*) result.get_value_addr(), rtype, THREAD);
  }
}
void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) {
  switch (narrow_type) {
    case T_BOOLEAN:
     value->z = (jboolean) (value->i & 1);
     return;
    case T_BYTE:
     value->b = (jbyte) value->i;
     return;
    case T_CHAR:
     value->c = (jchar) value->i;
     return;
    case T_SHORT:
     value->s = (jshort) value->i;
     return;
    default:
      break; // fail
   }
  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
}
BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) {
  assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking");
  return java_lang_Class::primitive_type(basic_type_mirror);
}
oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) {
  oop mirror             = java_lang_reflect_Method::clazz(method_mirror);
  int slot               = java_lang_reflect_Method::slot(method_mirror);
  bool override          = java_lang_reflect_Method::override(method_mirror) != 0;
  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror)));
  oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
  BasicType rtype;
  if (java_lang_Class::is_primitive(return_type_mirror)) {
    rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
  } else {
    rtype = T_OBJECT;
  }
  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
  Method* m = klass->method_with_idnum(slot);
  if (m == NULL) {
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
  }
  methodHandle method(THREAD, m);
  return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
}
oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) {
  oop mirror             = java_lang_reflect_Constructor::clazz(constructor_mirror);
  int slot               = java_lang_reflect_Constructor::slot(constructor_mirror);
  bool override          = java_lang_reflect_Constructor::override(constructor_mirror) != 0;
  objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
  instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror));
  Method* m = klass->method_with_idnum(slot);
  if (m == NULL) {
    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
  }
  methodHandle method(THREAD, m);
  assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
  klass->initialize(CHECK_NULL);
  klass->check_valid_for_instantiation(false, CHECK_NULL);
  Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
  invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
  return receiver();
}
C:\hotspot-69087d08d473\src\share\vm/runtime/reflection.hpp
#ifndef SHARE_VM_RUNTIME_REFLECTION_HPP
#define SHARE_VM_RUNTIME_REFLECTION_HPP
#include "oops/oop.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/growableArray.hpp"
class FieldStream;
class Reflection: public AllStatic {
 private:
  static bool reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS);
  static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS);
  static oop      basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS);
  static objArrayHandle get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS);
  static objArrayHandle get_exception_types(methodHandle method, TRAPS);
  static Handle new_type(Symbol* signature, KlassHandle k, TRAPS);
 public:
  enum SomeConstants {
    PUBLIC            = 0,
    DECLARED          = 1,
    MEMBER_PUBLIC     = 0,
    MEMBER_DECLARED   = 1,
    MAX_DIM           = 255
  };
  static oop box(jvalue* v, BasicType type, TRAPS);
  static BasicType unbox_for_primitive(oop boxed_value, jvalue* value, TRAPS);
  static BasicType unbox_for_regular_object(oop boxed_value, jvalue* value);
  static void widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS);
  static BasicType array_get(jvalue* value, arrayOop a, int index, TRAPS);
  static void      array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS);
  static oop       array_component_type(oop mirror, TRAPS);
  static arrayOop reflect_new_array(oop element_mirror, jint length, TRAPS);
  static arrayOop reflect_new_multi_array(oop element_mirror, typeArrayOop dimensions, TRAPS);
  static bool     verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only);
  static bool     verify_field_access(Klass* current_class,
                                      Klass* resolved_class,
                                      Klass* field_class,
                                      AccessFlags access,
                                      bool classloader_only,
                                      bool protected_restriction = false);
  static bool     is_same_class_package(Klass* class1, Klass* class2);
  static bool     is_same_package_member(Klass* class1, Klass* class2, TRAPS);
  static bool can_relax_access_check_for(
    Klass* accessor, Klass* accesee, bool classloader_only);
  static void check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
                                    bool inner_is_member, TRAPS);
  static oop new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS);
  static oop new_constructor(methodHandle method, TRAPS);
  static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS);
  static oop new_parameter(Handle method, int index, Symbol* sym,
                           int flags, TRAPS);
private:
  static methodHandle resolve_interface_call(instanceKlassHandle klass, methodHandle method, KlassHandle recv_klass, Handle receiver, TRAPS);
  static oop  invoke(instanceKlassHandle klass, methodHandle method, Handle receiver, bool override, objArrayHandle ptypes, BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS);
  static void narrow(jvalue* value, BasicType narrow_type, TRAPS);
  static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS);
public:
  static oop      invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS);
  static oop      invoke_constructor(oop method_mirror, objArrayHandle args, TRAPS);
};
#endif // SHARE_VM_RUNTIME_REFLECTION_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/reflectionUtils.cpp
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "memory/universe.inline.hpp"
#include "runtime/reflectionUtils.hpp"
KlassStream::KlassStream(instanceKlassHandle klass, bool local_only,
                         bool classes_only, bool walk_defaults) {
  _klass = _base_klass = klass;
  _base_class_search_defaults = false;
  _defaults_checked = false;
  if (classes_only) {
    _interfaces = Universe::the_empty_klass_array();
  } else {
    _interfaces = klass->transitive_interfaces();
  }
  _interface_index = _interfaces->length();
  _local_only = local_only;
  _classes_only = classes_only;
  _walk_defaults = walk_defaults;
}
bool KlassStream::eos() {
  if (index() >= 0) return false;
  if (_local_only) return true;
  if (!_klass->is_interface() && _klass->super() != NULL) {
    _klass = _klass->super();
  } else if (_walk_defaults && (_defaults_checked == false)  && (_base_klass->default_methods() != NULL)) {
      _base_class_search_defaults = true;
      _klass = _base_klass;
      _defaults_checked = true;
  } else {
    if (_interface_index > 0) {
      _klass = _interfaces->at(--_interface_index);
    } else {
      return true;
    }
  }
  _index = length();
  next();
  return eos();
}
GrowableArray<FilteredField*> *FilteredFieldsMap::_filtered_fields =
  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<FilteredField*>(3,true);
void FilteredFieldsMap::initialize() {
  int offset;
  offset = java_lang_Throwable::get_backtrace_offset();
  _filtered_fields->append(new FilteredField(SystemDictionary::Throwable_klass(), offset));
  if (JDK_Version::is_gte_jdk16x_version()) {
    offset = sun_reflect_ConstantPool::oop_offset();
    _filtered_fields->append(new FilteredField(SystemDictionary::reflect_ConstantPool_klass(), offset));
    offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
    _filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
  }
}
int FilteredFieldStream::field_count() {
  int numflds = 0;
  for (;!eos(); next()) {
    numflds++;
  }
  return numflds;
}
C:\hotspot-69087d08d473\src\share\vm/runtime/reflectionUtils.hpp
#ifndef SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP
#define SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP
#include "memory/allocation.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/reflection.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/globalDefinitions.hpp"
class KlassStream VALUE_OBJ_CLASS_SPEC {
 protected:
  instanceKlassHandle _klass;           // current klass/interface iterated over
  instanceKlassHandle _base_klass;      // initial klass/interface to iterate over
  Array<Klass*>*      _interfaces;      // transitive interfaces for initial class
  int                 _interface_index; // current interface being processed
  bool                _local_only;      // process initial class/interface only
  bool                _classes_only;    // process classes only (no interfaces)
  bool                _walk_defaults;   // process default methods
  bool                _base_class_search_defaults; // time to process default methods
  bool                _defaults_checked; // already checked for default methods
  int                 _index;
  virtual int length() = 0;
 public:
  KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only, bool walk_defaults);
  bool eos();
  virtual void next() = 0;
  instanceKlassHandle klass() const { return _klass; }
  int index() const                 { return _index; }
  bool base_class_search_defaults() const { return _base_class_search_defaults; }
  void base_class_search_defaults(bool b) { _base_class_search_defaults = b; }
};
class MethodStream : public KlassStream {
 private:
  int length()                    { return methods()->length(); }
  Array<Method*>* methods() {
    if (base_class_search_defaults()) {
      base_class_search_defaults(false);
      return _klass->default_methods();
    } else {
      return _klass->methods();
    }
  }
 public:
  MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only)
    : KlassStream(klass, local_only, classes_only, true) {
    _index = length();
    next();
  }
  void next() { _index--; }
  Method* method() { return methods()->at(index()); }
};
class FieldStream : public KlassStream {
 private:
  int length() { return _klass->java_fields_count(); }
  fieldDescriptor _fd_buf;
 public:
  FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
    : KlassStream(klass, local_only, classes_only, false) {
    _index = length();
    next();
  }
  void next() { _index -= 1; }
  AccessFlags access_flags() const {
    AccessFlags flags;
    flags.set_flags(_klass->field_access_flags(_index));
    return flags;
  }
  Symbol* name() const {
    return _klass->field_name(_index);
  }
  Symbol* signature() const {
    return _klass->field_signature(_index);
  }
  int offset() const {
    return _klass->field_offset( index() );
  }
  fieldDescriptor& field_descriptor() const {
    fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
    field.reinitialize(_klass(), _index);
    return field;
  }
};
class FilteredField : public CHeapObj<mtInternal>  {
 private:
  Klass* _klass;
  int    _field_offset;
 public:
  FilteredField(Klass* klass, int field_offset) {
    _klass = klass;
    _field_offset = field_offset;
  }
  Klass* klass() { return _klass; }
  int  field_offset() { return _field_offset; }
};
class FilteredFieldsMap : AllStatic {
 private:
  static GrowableArray<FilteredField *> *_filtered_fields;
 public:
  static void initialize();
  static bool is_filtered_field(Klass* klass, int field_offset) {
    for (int i=0; i < _filtered_fields->length(); i++) {
      if (klass == _filtered_fields->at(i)->klass() &&
        field_offset == _filtered_fields->at(i)->field_offset()) {
        return true;
      }
    }
    return false;
  }
  static int  filtered_fields_count(Klass* klass, bool local_only) {
    int nflds = 0;
    for (int i=0; i < _filtered_fields->length(); i++) {
      if (local_only && klass == _filtered_fields->at(i)->klass()) {
        nflds++;
      } else if (klass->is_subtype_of(_filtered_fields->at(i)->klass())) {
        nflds++;
      }
    }
    return nflds;
  }
  static void classes_do(KlassClosure* f) {
    for (int i = 0; i < _filtered_fields->length(); i++) {
      f->do_klass(_filtered_fields->at(i)->klass());
    }
  }
};
class FilteredFieldStream : public FieldStream {
 private:
  int  _filtered_fields_count;
  bool has_filtered_field() { return (_filtered_fields_count > 0); }
 public:
  FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
    : FieldStream(klass, local_only, classes_only) {
    _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((Klass*)klass(), local_only);
  }
  int field_count();
  void next() {
    _index -= 1;
    if (has_filtered_field()) {
      while (_index >=0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass(), offset())) {
        _index -= 1;
      }
    }
  }
};
#endif // SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/registerMap.hpp
#ifndef SHARE_VM_RUNTIME_REGISTERMAP_HPP
#define SHARE_VM_RUNTIME_REGISTERMAP_HPP
#include "code/vmreg.hpp"
#include "utilities/globalDefinitions.hpp"
#ifdef TARGET_ARCH_x86
# include "register_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "register_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "register_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "register_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "register_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "register_ppc.hpp"
#endif
class JavaThread;
class RegisterMap : public StackObj {
 public:
    typedef julong LocationValidType;
  enum {
    reg_count = ConcreteRegisterImpl::number_of_registers,
    location_valid_type_size = sizeof(LocationValidType)*8,
    location_valid_size = (reg_count+location_valid_type_size-1)/location_valid_type_size
  };
 private:
  intptr_t*    _location[reg_count];    // Location of registers (intptr_t* looks better than address in the debugger)
  LocationValidType _location_valid[location_valid_size];
  bool        _include_argument_oops;   // Should include argument_oop marked locations for compiler
  JavaThread* _thread;                  // Reference to current thread
  bool        _update_map;              // Tells if the register map need to be
#ifdef ASSERT
  void check_location_valid();
#else
  void check_location_valid() {}
#endif
 public:
  debug_only(intptr_t* _update_for_id;) // Assert that RegisterMap is not updated twice for same frame
  RegisterMap(JavaThread *thread, bool update_map = true);
  RegisterMap(const RegisterMap* map);
  address location(VMReg reg) const {
    int index = reg->value() / location_valid_type_size;
    assert(0 <= reg->value() && reg->value() < reg_count, "range check");
    assert(0 <= index && index < location_valid_size, "range check");
    if (_location_valid[index] & ((LocationValidType)1 << (reg->value() % location_valid_type_size))) {
      return (address) _location[reg->value()];
    } else {
      return pd_location(reg);
    }
  }
  void set_location(VMReg reg, address loc) {
    int index = reg->value() / location_valid_type_size;
    assert(0 <= reg->value() && reg->value() < reg_count, "range check");
    assert(0 <= index && index < location_valid_size, "range check");
    assert(_update_map, "updating map that does not need updating");
    _location[reg->value()] = (intptr_t*) loc;
    _location_valid[index] |= ((LocationValidType)1 << (reg->value() % location_valid_type_size));
    check_location_valid();
  }
  void clear();
  bool include_argument_oops() const      { return _include_argument_oops; }
  void set_include_argument_oops(bool f)  { _include_argument_oops = f; }
  JavaThread *thread() const { return _thread; }
  bool update_map()    const { return _update_map; }
  void print_on(outputStream* st) const;
  void print() const;
#ifdef TARGET_ARCH_x86
# include "registerMap_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "registerMap_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "registerMap_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "registerMap_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "registerMap_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "registerMap_ppc.hpp"
#endif
};
#endif // SHARE_VM_RUNTIME_REGISTERMAP_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/relocator.cpp
#include "precompiled.hpp"
#include "classfile/stackMapTableFormat.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/relocator.hpp"
#define MAX_METHOD_LENGTH  65535
#define MAX_SHORT ((1 << 15) - 1)
#define MIN_SHORT (- (1 << 15))
class ChangeItem : public ResourceObj {
  int _bci;
 public:
   ChangeItem(int bci) { _bci = bci; }
   virtual bool handle_code_change(Relocator *r) = 0;
   virtual bool is_widen()      { return false; }
   virtual bool is_jump_widen() { return false; }
   virtual bool is_switch_pad() { return false; }
   int bci()    { return _bci; }
   void relocate(int break_bci, int delta) { if (_bci > break_bci) { _bci += delta; } }
   virtual bool adjust(int bci, int delta) { return false; }
   virtual void print() = 0;
};
class ChangeWiden : public ChangeItem {
  int              _new_ilen;    // New length of instruction at bci
  u_char*          _inst_buffer; // New bytecodes
 public:
  ChangeWiden(int bci, int new_ilen, u_char* inst_buffer) : ChangeItem(bci) {
    _new_ilen = new_ilen;
    _inst_buffer = inst_buffer;
  }
  bool handle_code_change(Relocator *r) { return r->handle_widen(bci(), _new_ilen, _inst_buffer); };
  bool is_widen()              { return true; }
  void print()                 { tty->print_cr("ChangeWiden. bci: %d   New_ilen: %d", bci(), _new_ilen); }
};
class ChangeJumpWiden : public ChangeItem {
  int _delta;  // New length of instruction at bci
 public:
  ChangeJumpWiden(int bci, int delta) : ChangeItem(bci) { _delta = delta; }
  bool handle_code_change(Relocator *r) { return r->handle_jump_widen(bci(), _delta); };
  bool is_jump_widen()         { return true; }
  bool adjust(int jump_bci, int delta) {
    if (bci() == jump_bci) {
      if (_delta > 0)
        _delta += delta;
      else
        _delta -= delta;
      return true;
    }
    return false;
  }
  void print()                 { tty->print_cr("ChangeJumpWiden. bci: %d   Delta: %d", bci(), _delta); }
};
class ChangeSwitchPad : public ChangeItem {
  int  _padding;
  bool _is_lookup_switch;
 public:
   ChangeSwitchPad(int bci, int padding, bool is_lookup_switch) : ChangeItem(bci) {
     _padding = padding;
     _is_lookup_switch = is_lookup_switch;
   }
   bool handle_code_change(Relocator *r) { return r->handle_switch_pad(bci(), _padding, _is_lookup_switch); };
   bool is_switch_pad()        { return true; }
   int  padding()              { return _padding;  }
   bool is_lookup_switch()     { return _is_lookup_switch; }
   void print()                { tty->print_cr("ChangeSwitchPad. bci: %d   Padding: %d  IsLookupSwitch: %d", bci(), _padding, _is_lookup_switch); }
};
Relocator::Relocator(methodHandle m, RelocatorListener* listener) {
  set_method(m);
  set_code_length(method()->code_size());
  set_code_array(NULL);
  if (!expand_code_array(0)) {
    ShouldNotReachHere();
  }
  set_compressed_line_number_table(NULL);
  set_compressed_line_number_table_size(0);
  _listener = listener;
}
methodHandle Relocator::insert_space_at(int bci, int size, u_char inst_buffer[], TRAPS) {
  _changes = new GrowableArray<ChangeItem*> (10);
  _changes->push(new ChangeWiden(bci, size, inst_buffer));
  if (TraceRelocator) {
    tty->print_cr("Space at: %d Size: %d", bci, size);
    _method->print();
    _method->print_codes();
    tty->print_cr("-------------------------------------------------");
  }
  if (!handle_code_changes()) return methodHandle();
  methodHandle new_method = Method::clone_with_new_data(method(),
                              code_array(), code_length(),
                              compressed_line_number_table(),
                              compressed_line_number_table_size(),
                              CHECK_(methodHandle()));
  ClassLoaderData* loader_data = method()->method_holder()->class_loader_data();
  loader_data->add_to_deallocate_list(method()());
    set_method(new_method);
  if (TraceRelocator) {
    tty->print_cr("-------------------------------------------------");
    tty->print_cr("new method");
    _method->print_codes();
  }
  return new_method;
}
bool Relocator::handle_code_changes() {
  assert(_changes != NULL, "changes vector must be initialized");
  while (!_changes->is_empty()) {
    ChangeItem* ci = _changes->first();
    if (TraceRelocator) {
      ci->print();
    }
    if (!ci->handle_code_change(this)) return false;
    for (int index = 1; index < _changes->length(); index++) {
      _changes->at_put(index-1, _changes->at(index));
    }
    _changes->pop();
  }
  return true;
}
bool Relocator::is_opcode_lookupswitch(Bytecodes::Code bc) {
  switch (bc) {
    case Bytecodes::_tableswitch:       return false;
    case Bytecodes::_lookupswitch:                   // not rewritten on ia64
    case Bytecodes::_fast_linearswitch:              // rewritten _lookupswitch
    case Bytecodes::_fast_binaryswitch: return true; // rewritten _lookupswitch
    default: ShouldNotReachHere();
  }
  return true; // dummy
}
int Relocator::rc_instr_len(int bci) {
  Bytecodes::Code bc= code_at(bci);
  switch (bc) {
    case Bytecodes::_tableswitch:
    case Bytecodes::_lookupswitch:
    case Bytecodes::_fast_linearswitch:
    case Bytecodes::_fast_binaryswitch:
    {
      int pad = get_orig_switch_pad(bci, is_opcode_lookupswitch(bc));
      if (pad == -1) {
        return instruction_length_at(bci);
      }
      switch (bc) {
        case Bytecodes::_tableswitch: {
          int lo = int_at(bci + 1 + pad + 4 * 1);
          int hi = int_at(bci + 1 + pad + 4 * 2);
          int n = hi - lo + 1;
          return 1 + pad + 4*(3 + n);
        }
        case Bytecodes::_lookupswitch:
        case Bytecodes::_fast_linearswitch:
        case Bytecodes::_fast_binaryswitch: {
          int npairs = int_at(bci + 1 + pad + 4 * 1);
          return 1 + pad + 4*(2 + 2*npairs);
        }
        default:
          ShouldNotReachHere();
      }
    }
  }
  return instruction_length_at(bci);
}
int Relocator::get_orig_switch_pad(int bci, bool is_lookup_switch) {
  for (int k = 0; k < _changes->length(); k++) {
    ChangeItem* ci = _changes->at(k);
    if (ci->is_switch_pad()) {
      ChangeSwitchPad* csp = (ChangeSwitchPad*)ci;
      if (csp->is_lookup_switch() == is_lookup_switch && csp->bci() == bci) {
        return csp->padding();
      }
    }
  }
  return -1;
}
void Relocator::push_jump_widen(int bci, int delta, int new_delta) {
  for (int j = 0; j < _changes->length(); j++) {
    ChangeItem* ci = _changes->at(j);
    if (ci->adjust(bci, delta)) return;
  }
  _changes->push(new ChangeJumpWiden(bci, new_delta));
}
void Relocator::change_jump(int bci, int offset, bool is_short, int break_bci, int delta) {
  int bci_delta = (is_short) ? short_at(offset) : int_at(offset);
  int targ = bci + bci_delta;
  if ((bci <= break_bci && targ >  break_bci) ||
      (bci >  break_bci && targ <= break_bci)) {
    int new_delta;
    if (bci_delta > 0)
      new_delta = bci_delta + delta;
    else
      new_delta = bci_delta - delta;
    if (is_short && ((new_delta > MAX_SHORT) || new_delta < MIN_SHORT)) {
      push_jump_widen(bci, delta, new_delta);
    } else if (is_short) {
      short_at_put(offset, new_delta);
    } else {
      int_at_put(offset, new_delta);
    }
  }
}
void Relocator::change_jumps(int break_bci, int delta) {
  int bci = 0;
  Bytecodes::Code bc;
  while (bci < code_length()) {
    switch (bc= code_at(bci)) {
      case Bytecodes::_ifeq:
      case Bytecodes::_ifne:
      case Bytecodes::_iflt:
      case Bytecodes::_ifge:
      case Bytecodes::_ifgt:
      case Bytecodes::_ifle:
      case Bytecodes::_if_icmpeq:
      case Bytecodes::_if_icmpne:
      case Bytecodes::_if_icmplt:
      case Bytecodes::_if_icmpge:
      case Bytecodes::_if_icmpgt:
      case Bytecodes::_if_icmple:
      case Bytecodes::_if_acmpeq:
      case Bytecodes::_if_acmpne:
      case Bytecodes::_ifnull:
      case Bytecodes::_ifnonnull:
      case Bytecodes::_goto:
      case Bytecodes::_jsr:
        change_jump(bci, bci+1, true, break_bci, delta);
        break;
      case Bytecodes::_goto_w:
      case Bytecodes::_jsr_w:
        change_jump(bci, bci+1, false, break_bci, delta);
        break;
      case Bytecodes::_tableswitch:
      case Bytecodes::_lookupswitch:
      case Bytecodes::_fast_linearswitch:
      case Bytecodes::_fast_binaryswitch: {
        int recPad = get_orig_switch_pad(bci, (bc != Bytecodes::_tableswitch));
        int oldPad = (recPad != -1) ? recPad : align(bci+1) - (bci+1);
        if (bci > break_bci) {
          int new_bci = bci + delta;
          int newPad = align(new_bci+1) - (new_bci+1);
          if (newPad != oldPad) {
            if (recPad == -1) {
              _changes->push(new ChangeSwitchPad(bci, oldPad, (bc != Bytecodes::_tableswitch)));
            }
          }
        }
        switch (bc) {
          case Bytecodes::_tableswitch: {
            change_jump(bci, bci +1 + oldPad, false, break_bci, delta);
            int lo = int_at(bci + 1 + oldPad + 4 * 1);
            int hi = int_at(bci + 1 + oldPad + 4 * 2);
            int n = hi - lo + 1;
            for (int k = 0; k < n; k++) {
              change_jump(bci, bci +1 + oldPad + 4*(k+3), false, break_bci, delta);
            }
            bci += 1 + oldPad + (n+3)*4;
            continue;
          }
          case Bytecodes::_lookupswitch:
          case Bytecodes::_fast_linearswitch:
          case Bytecodes::_fast_binaryswitch: {
            change_jump(bci, bci +1 + oldPad, false, break_bci, delta);
            int npairs = int_at(bci + 1 + oldPad + 4 * 1);
            for (int k = 0; k < npairs; k++) {
              change_jump(bci, bci + 1 + oldPad + 4*(2 + 2*k + 1), false, break_bci, delta);
            }
            bci += 1 + oldPad + (2 + (npairs*2))*4;
            continue;
          }
          default:
            ShouldNotReachHere();
        }
      }
      default:
        break;
    }
    bci += rc_instr_len(bci);
  }
}
void Relocator::adjust_exception_table(int bci, int delta) {
  ExceptionTable table(_method());
  for (int index = 0; index < table.length(); index ++) {
    if (table.start_pc(index) > bci) {
      table.set_start_pc(index, table.start_pc(index) + delta);
      table.set_end_pc(index, table.end_pc(index) + delta);
    } else if (bci < table.end_pc(index)) {
      table.set_end_pc(index, table.end_pc(index) + delta);
    }
    if (table.handler_pc(index) > bci)
      table.set_handler_pc(index, table.handler_pc(index) + delta);
  }
}
void Relocator::adjust_line_no_table(int bci, int delta) {
  if (method()->has_linenumber_table()) {
    CompressedLineNumberReadStream  reader(method()->compressed_linenumber_table());
    CompressedLineNumberWriteStream writer(64);  // plenty big for most line number tables
    while (reader.read_pair()) {
      int adjustment = (reader.bci() > bci) ? delta : 0;
      writer.write_pair(reader.bci() + adjustment, reader.line());
    }
    writer.write_terminator();
    set_compressed_line_number_table(writer.buffer());
    set_compressed_line_number_table_size(writer.position());
  }
}
void Relocator::adjust_local_var_table(int bci, int delta) {
  int localvariable_table_length = method()->localvariable_table_length();
  if (localvariable_table_length > 0) {
    LocalVariableTableElement* table = method()->localvariable_table_start();
    for (int i = 0; i < localvariable_table_length; i++) {
      u2 current_bci = table[i].start_bci;
      if (current_bci > bci) {
        table[i].start_bci = current_bci + delta;
      } else {
        u2 current_length = table[i].length;
        if (current_bci + current_length > bci) {
          table[i].length = current_length + delta;
        }
      }
    }
  }
}
static Array<u1>* insert_hole_at(ClassLoaderData* loader_data,
    size_t where, int hole_sz, Array<u1>* src) {
  Thread* THREAD = Thread::current();
  Array<u1>* dst =
      MetadataFactory::new_array<u1>(loader_data, src->length() + hole_sz, 0, CHECK_NULL);
  address src_addr = (address)src->adr_at(0);
  address dst_addr = (address)dst->adr_at(0);
  memcpy(dst_addr, src_addr, where);
  memcpy(dst_addr + where + hole_sz,
         src_addr + where, src->length() - where);
  return dst;
}
void Relocator::adjust_stack_map_table(int bci, int delta) {
  if (method()->has_stackmap_table()) {
    Array<u1>* data = method()->stackmap_data();
    stack_map_table* sm_table =
        stack_map_table::at((address)data->adr_at(0));
    int count = sm_table->number_of_entries();
    stack_map_frame* frame = sm_table->entries();
    int bci_iter = -1;
    bool offset_adjusted = false; // only need to adjust one offset
    for (int i = 0; i < count; ++i) {
      int offset_delta = frame->offset_delta();
      bci_iter += offset_delta;
      if (!offset_adjusted && bci_iter > bci) {
        int new_offset_delta = offset_delta + delta;
        if (frame->is_valid_offset(new_offset_delta)) {
          frame->set_offset_delta(new_offset_delta);
        } else {
          assert(frame->is_same_frame() ||
                 frame->is_same_locals_1_stack_item_frame(),
                 "Frame must be one of the compressed forms");
          size_t frame_offset = (address)frame - (address)data->adr_at(0);
          ClassLoaderData* loader_data = method()->method_holder()->class_loader_data();
          Array<u1>* new_data = insert_hole_at(loader_data, frame_offset + 1, 2, data);
          if (new_data == NULL) {
            return; // out-of-memory?
          }
          MetadataFactory::free_array<u1>(loader_data, data);
          data = new_data;
          address frame_addr = (address)(data->adr_at(0) + frame_offset);
          frame = stack_map_frame::at(frame_addr);
          if (frame->is_same_frame()) {
            same_frame_extended::create_at(frame_addr, new_offset_delta);
          } else {
            same_locals_1_stack_item_extended::create_at(
              frame_addr, new_offset_delta, NULL);
          }
        }
        offset_adjusted = true; // needs to be done only once, since subsequent
      }
      int number_of_types = frame->number_of_types();
      verification_type_info* types = frame->types();
      for (int i = 0; i < number_of_types; ++i) {
        if (types->is_uninitialized() && types->bci() > bci) {
          types->set_bci(types->bci() + delta);
        }
        types = types->next();
      }
      full_frame* ff = frame->as_full_frame();
      if (ff != NULL) {
        address eol = (address)types;
        number_of_types = ff->stack_slots(eol);
        types = ff->stack(eol);
        for (int i = 0; i < number_of_types; ++i) {
          if (types->is_uninitialized() && types->bci() > bci) {
            types->set_bci(types->bci() + delta);
          }
          types = types->next();
        }
      }
      frame = frame->next();
    }
    method()->set_stackmap_data(data); // in case it has changed
  }
}
bool Relocator::expand_code_array(int delta) {
  int length = MAX2(code_length() + delta, code_length() * (100+code_slop_pct()) / 100);
  if (length > MAX_METHOD_LENGTH) {
    if (delta == 0 && code_length() <= MAX_METHOD_LENGTH) {
      length = MAX_METHOD_LENGTH;
    } else {
      return false;
    }
  }
  unsigned char* new_code_array = NEW_RESOURCE_ARRAY(unsigned char, length);
  if (!new_code_array) return false;
  if (code_array() != NULL) {
    memcpy(new_code_array, code_array(), code_length());
  } else {
    memcpy(new_code_array, method()->code_base(), code_length());
  }
  set_code_array(new_code_array);
  set_code_array_length(length);
  return true;
}
bool Relocator::relocate_code(int bci, int ilen, int delta) {
  int next_bci = bci + ilen;
  if (delta > 0 && code_length() + delta > code_array_length())  {
    if (!expand_code_array(delta)) {
          return false;
    }
  }
  assert(((intptr_t)code_array() & 3) == 0, "check code alignment");
  change_jumps(bci, delta);
  if (delta < 0) {
    assert(delta>=-3, "we cannot overwrite more than 3 bytes");
    memcpy(_overwrite, addr_at(bci + ilen + delta), -delta);
  }
  memmove(addr_at(next_bci + delta), addr_at(next_bci), code_length() - next_bci);
  set_code_length(code_length() + delta);
  adjust_exception_table(bci, delta);
  adjust_line_no_table(bci, delta);
  adjust_local_var_table(bci, delta);
  adjust_stack_map_table(bci, delta);
  for (int j = 0; j < _changes->length(); j++) {
    ChangeItem* ci = _changes->at(j);
    ci->relocate(bci, delta);
  }
  notify(bci, delta, code_length());
  return true;
}
bool Relocator::handle_widen(int bci, int new_ilen, u_char inst_buffer[]) {
  int ilen = rc_instr_len(bci);
  if (!relocate_code(bci, ilen, new_ilen - ilen))
    return false;
  for(int k = 0; k < new_ilen; k++) {
    code_at_put(bci + k, (Bytecodes::Code)inst_buffer[k]);
  }
  return true;
}
bool Relocator::handle_jump_widen(int bci, int delta) {
  int ilen = rc_instr_len(bci);
  Bytecodes::Code bc = code_at(bci);
  switch (bc) {
    case Bytecodes::_ifeq:
    case Bytecodes::_ifne:
    case Bytecodes::_iflt:
    case Bytecodes::_ifge:
    case Bytecodes::_ifgt:
    case Bytecodes::_ifle:
    case Bytecodes::_if_icmpeq:
    case Bytecodes::_if_icmpne:
    case Bytecodes::_if_icmplt:
    case Bytecodes::_if_icmpge:
    case Bytecodes::_if_icmpgt:
    case Bytecodes::_if_icmple:
    case Bytecodes::_if_acmpeq:
    case Bytecodes::_if_acmpne:
    case Bytecodes::_ifnull:
    case Bytecodes::_ifnonnull: {
      const int goto_length   = Bytecodes::length_for(Bytecodes::_goto);
      assert (short_at(bci+1) != ilen+goto_length, "if relocation already handled");
      assert(ilen == 3, "check length");
      const int goto_w_length = Bytecodes::length_for(Bytecodes::_goto_w);
      const int add_bci = goto_length + goto_w_length;
      if (!relocate_code(bci, 3, /*delta*/add_bci)) return false;
      short_at_put(bci + 1, ilen + goto_length);
      int cbci = bci + ilen;
      code_at_put(cbci, Bytecodes::_goto);
      short_at_put(cbci + 1, add_bci);
      cbci = cbci + goto_length;
      code_at_put(cbci, Bytecodes::_goto_w);
      if (delta > 0) {
        delta += 2;                 // goto_w is 2 bytes more than "if" code
      } else {
        delta -= ilen+goto_length;  // branch starts at goto_w offset
      }
      int_at_put(cbci + 1, delta);
      break;
      }
    case Bytecodes::_goto:
    case Bytecodes::_jsr:
      assert(ilen == 3, "check length");
      if (!relocate_code(bci, 3, 2)) return false;
      if (bc == Bytecodes::_goto)
        code_at_put(bci, Bytecodes::_goto_w);
      else
        code_at_put(bci, Bytecodes::_jsr_w);
      if (delta > 0) delta += 2;
      int_at_put(bci + 1, delta);
      break;
    default: ShouldNotReachHere();
  }
  return true;
}
bool Relocator::handle_switch_pad(int bci, int old_pad, bool is_lookup_switch) {
  int ilen = rc_instr_len(bci);
  int new_pad = align(bci+1) - (bci+1);
  int pad_delta = new_pad - old_pad;
  if (pad_delta != 0) {
    int len;
    if (!is_lookup_switch) {
      int low  = int_at(bci+1+old_pad+4);
      int high = int_at(bci+1+old_pad+8);
      len = high-low+1 + 3; // 3 for default, hi, lo.
    } else {
      int npairs = int_at(bci+1+old_pad+4);
      len = npairs*2 + 2; // 2 for default, npairs.
    }
    if (!relocate_code(bci, ilen, pad_delta)) return false;
    if (pad_delta < 0) {
      memmove(addr_at(bci + 1 + new_pad),
              addr_at(bci + 1 + old_pad),
              len * 4 + pad_delta);
      memmove(addr_at(bci + 1 + new_pad + len*4 + pad_delta),
              _overwrite, -pad_delta);
    } else {
      assert(pad_delta > 0, "check");
      memmove(addr_at(bci +1 + new_pad),
              addr_at(bci +1 + old_pad),
              len * 4);
      memset(addr_at(bci + 1), 0, new_pad); // pad must be 0
    }
  }
  return true;
}
C:\hotspot-69087d08d473\src\share\vm/runtime/relocator.hpp
#ifndef SHARE_VM_RUNTIME_RELOCATOR_HPP
#define SHARE_VM_RUNTIME_RELOCATOR_HPP
#include "interpreter/bytecodes.hpp"
#include "oops/method.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "bytes_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif
class ChangeItem;
class RelocatorListener : public StackObj {
 public:
  RelocatorListener() {};
  virtual void relocated(int bci, int delta, int new_method_size) = 0;
};
class Relocator : public ResourceObj {
 public:
  Relocator(methodHandle method, RelocatorListener* listener);
  methodHandle insert_space_at(int bci, int space, u_char inst_buffer[], TRAPS);
  bool handle_code_changes();
  bool handle_widen       (int bci, int new_ilen, u_char inst_buffer[]);  // handles general instructions
  void push_jump_widen  (int bci, int delta, int new_delta);    // pushes jumps
  bool handle_jump_widen  (int bci, int delta);     // handles jumps
  bool handle_switch_pad  (int bci, int old_pad, bool is_lookup_switch); // handles table and lookup switches
 private:
  unsigned char* _code_array;
  int            _code_array_length;
  int            _code_length;
  unsigned char* _compressed_line_number_table;
  int            _compressed_line_number_table_size;
  methodHandle   _method;
  u_char         _overwrite[3];             // stores overwritten bytes for shrunken instructions
  GrowableArray<ChangeItem*>* _changes;
  unsigned char* code_array() const         { return _code_array; }
  void set_code_array(unsigned char* array) { _code_array = array; }
  int code_length() const                   { return _code_length; }
  void set_code_length(int length)          { _code_length = length; }
  int code_array_length() const             { return _code_array_length; }
  void set_code_array_length(int length)    { _code_array_length = length; }
  unsigned char* compressed_line_number_table() const         { return _compressed_line_number_table; }
  void set_compressed_line_number_table(unsigned char* table) { _compressed_line_number_table = table; }
  int compressed_line_number_table_size() const               { return _compressed_line_number_table_size; }
  void set_compressed_line_number_table_size(int size)        { _compressed_line_number_table_size = size; }
  methodHandle method() const               { return _method; }
  void set_method(methodHandle method)      { _method = method; }
  Bytecodes::Code code_at(int bci) const          { return (Bytecodes::Code) code_array()[bci]; }
  void code_at_put(int bci, Bytecodes::Code code) { code_array()[bci] = (char) code; }
  inline int   int_at(int bci) const               { return Bytes::get_Java_u4(&code_array()[bci]); }
  inline void  int_at_put(int bci, int value)      { Bytes::put_Java_u4(&code_array()[bci], value); }
  inline short short_at(int bci) const            { return (short)Bytes::get_Java_u2(&code_array()[bci]); }
  inline void  short_at_put(int bci, short value) { Bytes::put_Java_u2((address) &code_array()[bci], value); }
  inline char* addr_at(int bci) const             { return (char*) &code_array()[bci]; }
  int  instruction_length_at(int bci)             { return Bytecodes::length_at(NULL, code_array() + bci); }
  int  align(int n) const                          { return (n+3) & ~3; }
  int  code_slop_pct() const                       { return 25; }
  bool is_opcode_lookupswitch(Bytecodes::Code bc);
  bool relocate_code         (int bci, int ilen, int delta);
  void change_jumps          (int break_bci, int delta);
  void change_jump           (int bci, int offset, bool is_short, int break_bci, int delta);
  void adjust_exception_table(int bci, int delta);
  void adjust_line_no_table  (int bci, int delta);
  void adjust_local_var_table(int bci, int delta);
  void adjust_stack_map_table(int bci, int delta);
  int  get_orig_switch_pad   (int bci, bool is_lookup_switch);
  int  rc_instr_len          (int bci);
  bool expand_code_array     (int delta);
  RelocatorListener *_listener;
  void notify(int bci, int delta, int new_code_length) {
    if (_listener != NULL)
      _listener->relocated(bci, delta, new_code_length);
  }
};
#endif // SHARE_VM_RUNTIME_RELOCATOR_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/rframe.cpp
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/rframe.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframe_hp.hpp"
static RFrame*const  noCaller    = (RFrame*) 0x1;               // no caller (i.e., initial frame)
static RFrame*const  noCallerYet = (RFrame*) 0x0;               // caller not yet computed
RFrame::RFrame(frame fr, JavaThread* thread, RFrame*const callee) :
  _fr(fr), _thread(thread), _callee(callee), _num(callee ? callee->num() + 1 : 0) {
  _caller = (RFrame*)noCallerYet;
  _invocations = 0;
  _distance = 0;
}
void RFrame::set_distance(int d) {
  assert(is_compiled() || d >= 0, "should be positive");
  _distance = d;
}
InterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, RFrame*const callee)
: RFrame(fr, thread, callee) {
  RegisterMap map(thread, false);
  _vf     = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread));
  _method = methodHandle(thread, _vf->method());
  assert(   _vf->is_interpreted_frame(), "must be interpreted");
  init();
}
InterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, methodHandle m)
: RFrame(fr, thread, NULL) {
  RegisterMap map(thread, false);
  _vf     = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread));
  _method = m;
  assert(   _vf->is_interpreted_frame(),  "must be interpreted");
  init();
}
CompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread, RFrame*const  callee)
: RFrame(fr, thread, callee) {
  init();
}
CompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread)
: RFrame(fr, thread, NULL) {
  init();
}
DeoptimizedRFrame::DeoptimizedRFrame(frame fr, JavaThread* thread, RFrame*const  callee)
: InterpretedRFrame(fr, thread, callee) {}
RFrame* RFrame::new_RFrame(frame fr, JavaThread* thread, RFrame*const  callee) {
  RFrame* rf;
  int dist = callee ? callee->distance() : -1;
  if (fr.is_interpreted_frame()) {
    rf = new InterpretedRFrame(fr, thread, callee);
    dist++;
  } else if (fr.is_compiled_frame()) {
    rf = new CompiledRFrame(fr, thread, callee);
  } else {
    assert(false, "Unhandled frame type");
  }
  rf->set_distance(dist);
  rf->init();
  return rf;
}
RFrame* RFrame::caller() {
  if (_caller != noCallerYet) return (_caller == noCaller) ? NULL : _caller;    // already computed caller
  if (_fr.is_first_java_frame()) {
    _caller = (RFrame*)noCaller;
    return NULL;
  }
  RegisterMap map(_thread, false);
  frame sender = _fr.real_sender(&map);
  if (sender.is_java_frame()) {
    _caller = new_RFrame(sender, thread(), this);
    return _caller;
  }
  _caller = (RFrame*)noCaller;
  return NULL;
}
int InterpretedRFrame::cost() const {
  return _method->code_size();    // fix this
}
int CompiledRFrame::cost() const {
  nmethod* nm = top_method()->code();
  if (nm != NULL) {
    return nm->insts_size();
  } else {
    return top_method()->code_size();
  }
}
void CompiledRFrame::init() {
  RegisterMap map(thread(), false);
  vframe* vf = vframe::new_vframe(&_fr, &map, thread());
  assert(vf->is_compiled_frame(), "must be compiled");
  _nm = compiledVFrame::cast(vf)->code();
  vf = vf->top();
  _vf = javaVFrame::cast(vf);
  _method = methodHandle(thread(), CodeCache::find_nmethod(_fr.pc())->method());
  assert(_method(), "should have found a method");
#ifndef PRODUCT
  _invocations = _method->compiled_invocation_count();
#endif
}
void InterpretedRFrame::init() {
  _invocations = _method->invocation_count() + _method->backedge_count();
}
void RFrame::print(const char* kind) {
#ifndef PRODUCT
#ifdef COMPILER2
  int cnt = top_method()->interpreter_invocation_count();
#else
  int cnt = top_method()->invocation_count();
#endif
  tty->print("%3d %s ", _num, is_interpreted() ? "I" : "C");
  top_method()->print_short_name(tty);
  tty->print_cr(": inv=%5d(%d) cst=%4d", _invocations, cnt, cost());
#endif
}
void CompiledRFrame::print() {
  RFrame::print("comp");
}
void InterpretedRFrame::print() {
  RFrame::print("int.");
}
void DeoptimizedRFrame::print() {
  RFrame::print("deopt.");
}
C:\hotspot-69087d08d473\src\share\vm/runtime/rframe.hpp
#ifndef SHARE_VM_RUNTIME_RFRAME_HPP
#define SHARE_VM_RUNTIME_RFRAME_HPP
#include "memory/allocation.hpp"
#include "runtime/frame.inline.hpp"
class RFrame : public ResourceObj {
 protected:
  const frame _fr;                  // my frame
  JavaThread* const _thread;        // thread where frame resides.
  RFrame* _caller;                  // caller / callee rframes (or NULL)
  RFrame*const _callee;
  const int _num;                   // stack frame number (0 = most recent)
  int _invocations;                 // current invocation estimate (for this frame)
  int _distance;                    // recompilation search "distance" (measured in # of interpreted frames)
  RFrame(frame fr, JavaThread* thread, RFrame*const callee);
  virtual void init() = 0;          // compute invocations, loopDepth, etc.
  void print(const char* name);
 public:
  static RFrame* new_RFrame(frame fr, JavaThread* thread, RFrame*const callee);
  virtual bool is_interpreted() const     { return false; }
  virtual bool is_compiled() const        { return false; }
  int distance() const                    { return _distance; }
  void set_distance(int d);
  int invocations() const                 { return _invocations; }
  int num() const                         { return _num; }
  frame fr() const                        { return _fr; }
  JavaThread* thread() const              { return _thread; }
  virtual int cost() const = 0;           // estimated inlining cost (size)
  virtual methodHandle top_method() const  = 0;
  virtual javaVFrame* top_vframe() const = 0;
  virtual nmethod* nm() const             { ShouldNotCallThis(); return NULL; }
  RFrame* caller();
  RFrame* callee() const                  { return _callee; }
  RFrame* parent() const;                 // rframe containing lexical scope (if any)
  virtual void print()                    = 0;
  static int computeSends(Method* m);
  static int computeSends(nmethod* nm);
  static int computeCumulSends(Method* m);
  static int computeCumulSends(nmethod* nm);
};
class CompiledRFrame : public RFrame {    // frame containing a compiled method
 protected:
  nmethod*    _nm;
  javaVFrame* _vf;                        // top vframe; may be NULL (for most recent frame)
  methodHandle _method;                   // top method
  CompiledRFrame(frame fr, JavaThread* thread, RFrame*const  callee);
  void init();
  friend class RFrame;
 public:
  CompiledRFrame(frame fr, JavaThread* thread); // for nmethod triggering its counter (callee == NULL)
  bool is_compiled() const                 { return true; }
  methodHandle top_method() const          { return _method; }
  javaVFrame* top_vframe() const           { return _vf; }
  nmethod* nm() const                      { return _nm; }
  int cost() const;
  void print();
};
class InterpretedRFrame : public RFrame {    // interpreter frame
 protected:
  javaVFrame* _vf;                           // may be NULL (for most recent frame)
  methodHandle   _method;
  InterpretedRFrame(frame fr, JavaThread* thread, RFrame*const  callee);
  void init();
  friend class RFrame;
 public:
  InterpretedRFrame(frame fr, JavaThread* thread, methodHandle m); // constructor for method triggering its invocation counter
  bool is_interpreted() const                { return true; }
  methodHandle top_method() const            { return _method; }
  javaVFrame* top_vframe() const             { return _vf; }
  int cost() const;
  void print();
};
class DeoptimizedRFrame : public InterpretedRFrame {
 protected:
  DeoptimizedRFrame(frame fr, JavaThread* thread, RFrame*const  callee);
  friend class RFrame;
 public:
  void print();
};
#endif // SHARE_VM_RUNTIME_RFRAME_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/rtmLocking.hpp
#ifndef SHARE_VM_RUNTIME_RTMLOCKING_HPP
#define SHARE_VM_RUNTIME_RTMLOCKING_HPP
class RTMLockingCounters VALUE_OBJ_CLASS_SPEC {
 private:
  uintx _total_count; // Total RTM locks count
  uintx _abort_count; // Total aborts count
 public:
  enum { ABORT_STATUS_LIMIT = 6 };
 private:
  uintx _abortX_count[ABORT_STATUS_LIMIT];
 public:
  static uintx _calculation_flag;
  static uintx* rtm_calculation_flag_addr() { return &_calculation_flag; }
  static void init();
  RTMLockingCounters() : _total_count(0), _abort_count(0) {
    for (int i = 0; i < ABORT_STATUS_LIMIT; i++) {
      _abortX_count[i] = 0;
    }
  }
  uintx* total_count_addr()               { return &_total_count; }
  uintx* abort_count_addr()               { return &_abort_count; }
  uintx* abortX_count_addr()              { return &_abortX_count[0]; }
  static int total_count_offset()         { return (int)offset_of(RTMLockingCounters, _total_count); }
  static int abort_count_offset()         { return (int)offset_of(RTMLockingCounters, _abort_count); }
  static int abortX_count_offset()        { return (int)offset_of(RTMLockingCounters, _abortX_count[0]); }
  bool nonzero() {  return (_abort_count + _total_count) > 0; }
  void print_on(outputStream* st);
  void print() { print_on(tty); }
};
#endif // SHARE_VM_RUNTIME_RTMLOCKING_HPP
C:\hotspot-69087d08d473\src\share\vm/runtime/safepoint.cpp
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "interpreter/interpreter.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.inline.hpp"
#include "services/runtimeService.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
# include "vmreg_x86.inline.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "nativeInst_aarch64.hpp"
# include "vmreg_aarch64.inline.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "nativeInst_sparc.hpp"
# include "vmreg_sparc.inline.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "nativeInst_zero.hpp"
# include "vmreg_zero.inline.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "nativeInst_arm.hpp"
# include "vmreg_arm.inline.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "nativeInst_ppc.hpp"
# include "vmreg_ppc.inline.hpp"
#endif
#if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/shared/suspendibleThreadSet.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
template <typename E>
static void set_current_safepoint_id(E* event, int adjustment = 0) {
  assert(event != NULL, "invariant");
  event->set_safepointId(SafepointSynchronize::safepoint_counter() + adjustment);
}
static void post_safepoint_begin_event(EventSafepointBegin* event,
                                       int thread_count,
                                       int critical_thread_count) {
  assert(event != NULL, "invariant");
  assert(event->should_commit(), "invariant");
  set_current_safepoint_id(event);
  event->set_totalThreadCount(thread_count);
  event->set_jniCriticalThreadCount(critical_thread_count);
  event->commit();
}
static void post_safepoint_cleanup_event(EventSafepointCleanup* event) {
  assert(event != NULL, "invariant");
  assert(event->should_commit(), "invariant");
  set_current_safepoint_id(event);
  event->commit();
}
static void post_safepoint_synchronize_event(EventSafepointStateSynchronization* event,
                                             int initial_number_of_threads,
                                             int threads_waiting_to_block,
                                             unsigned int iterations) {
  assert(event != NULL, "invariant");
  if (event->should_commit()) {
    set_current_safepoint_id(event, 1);
    event->set_initialThreadCount(initial_number_of_threads);
    event->set_runningThreadCount(threads_waiting_to_block);
    event->set_iterations(iterations);
    event->commit();
  }
}
static void post_safepoint_wait_blocked_event(EventSafepointWaitBlocked* event,
                                              int initial_threads_waiting_to_block) {
  assert(event != NULL, "invariant");
  assert(event->should_commit(), "invariant");
  set_current_safepoint_id(event);
  event->set_runningThreadCount(initial_threads_waiting_to_block);
  event->commit();
}
static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask* event,
                                              const char* name) {
  assert(event != NULL, "invariant");
  if (event->should_commit()) {
    set_current_safepoint_id(event);
    event->set_name(name);
    event->commit();
  }
}
static void post_safepoint_end_event(EventSafepointEnd* event) {
  assert(event != NULL, "invariant");
  if (event->should_commit()) {
    set_current_safepoint_id(event, -1);
    event->commit();
  }
}
SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
volatile int  SafepointSynchronize::_waiting_to_block = 0;
volatile int SafepointSynchronize::_safepoint_counter = 0;
int SafepointSynchronize::_current_jni_active_count = 0;
long  SafepointSynchronize::_end_of_last_safepoint = 0;
static volatile int PageArmed = 0 ;        // safepoint polling page is RO|RW vs PROT_NONE
static volatile int TryingToBlock = 0 ;    // proximate value -- for advisory use only
static bool timeout_error_printed = false;
void SafepointSynchronize::begin() {
  EventSafepointBegin begin_event;
  Thread* myThread = Thread::current();
  assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
  if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
    _safepoint_begin_time = os::javaTimeNanos();
    _ts_of_current_safepoint = tty->time_stamp().seconds();
  }
#if INCLUDE_ALL_GCS
  if (UseConcMarkSweepGC) {
    ConcurrentMarkSweepThread::synchronize(false);
  } else if (UseG1GC) {
    SuspendibleThreadSet::synchronize();
  }
#endif // INCLUDE_ALL_GCS
  Threads_lock->lock();
  assert( _state == _not_synchronized, "trying to safepoint synchronize with wrong state");
  int nof_threads = Threads::number_of_threads();
  if (TraceSafepoint) {
    tty->print_cr("Safepoint synchronization initiated. (%d)", nof_threads);
  }
  RuntimeService::record_safepoint_begin();
  MutexLocker mu(Safepoint_lock);
  _current_jni_active_count = 0;
  _waiting_to_block = nof_threads;
  TryingToBlock     = 0 ;
  int still_running = nof_threads;
  jlong safepoint_limit_time = 0;
  timeout_error_printed = false;
  if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
    deferred_initialize_stat();
  }
  EventSafepointStateSynchronization sync_event;
  int initial_running = 0;
  _state            = _synchronizing;
  OrderAccess::fence();
  if (!UseMembar) {
    os::serialize_thread_states();
  }
  Interpreter::notice_safepoints();
  if (UseCompilerSafepoints && DeferPollingPageLoopCount < 0) {
    guarantee (PageArmed == 0, "invariant") ;
    PageArmed = 1 ;
    os::make_polling_page_unreadable();
  }
  int ncpus = os::processor_count() ;
#ifdef ASSERT
  for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
    assert(cur->safepoint_state()->is_running(), "Illegal initial state");
    cur->set_visited_for_critical_count(false);
  }
#endif // ASSERT
  if (SafepointTimeout)
    safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
  unsigned int iterations = 0;
  int steps = 0 ;
  while(still_running > 0) {
    for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
      assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
      ThreadSafepointState *cur_state = cur->safepoint_state();
      if (cur_state->is_running()) {
        cur_state->examine_state_of_thread();
        if (!cur_state->is_running()) {
           still_running--;
        }
        if (TraceSafepoint && Verbose) cur_state->print();
      }
    }
    if (iterations == 0) {
      initial_running = still_running;
      if (PrintSafepointStatistics) {
        begin_statistics(nof_threads, still_running);
      }
    }
    if (still_running > 0) {
      if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
        print_safepoint_timeout(_spinning_timeout);
      }
      if (UseCompilerSafepoints && int(iterations) == DeferPollingPageLoopCount) {
         guarantee (PageArmed == 0, "invariant") ;
         PageArmed = 1 ;
         os::make_polling_page_unreadable();
      }
      ++steps ;
      if (ncpus > 1 && steps < SafepointSpinBeforeYield) {
        SpinPause() ;     // MP-Polite spin
      } else
      if (steps < DeferThrSuspendLoopCount) {
        os::NakedYield() ;
      } else {
        os::yield_all(steps) ;
      }
      iterations ++ ;
    }
    assert(iterations < (uint)max_jint, "We have been iterating in the safepoint loop too long");
  }
  assert(still_running == 0, "sanity check");
  if (PrintSafepointStatistics) {
    update_statistics_on_spin_end();
  }
  if (sync_event.should_commit()) {
    post_safepoint_synchronize_event(&sync_event, initial_running, _waiting_to_block, iterations);
  }
  {
    EventSafepointWaitBlocked wait_blocked_event;
    int initial_waiting_to_block = _waiting_to_block;
    while (_waiting_to_block > 0) {
      if (TraceSafepoint) tty->print_cr("Waiting for %d thread(s) to block", _waiting_to_block);
      if (!SafepointTimeout || timeout_error_printed) {
        Safepoint_lock->wait(true);  // true, means with no safepoint checks
      } else {
        jlong remaining_time = safepoint_limit_time - os::javaTimeNanos();
        if (remaining_time < 0 || Safepoint_lock->wait(true, remaining_time / MICROUNITS)) {
          print_safepoint_timeout(_blocking_timeout);
        }
      }
    }
    assert(_waiting_to_block == 0, "sanity check");
#ifndef PRODUCT
    if (SafepointTimeout) {
      jlong current_time = os::javaTimeNanos();
      if (safepoint_limit_time < current_time) {
        tty->print_cr("# SafepointSynchronize: Finished after "
                      INT64_FORMAT_W(6) " ms",
                      ((current_time - safepoint_limit_time) / MICROUNITS +
                       SafepointTimeoutDelay));
      }
    }
#endif
    assert((_safepoint_counter & 0x1) == 0, "must be even");
    assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
    _safepoint_counter ++;
    _state = _synchronized;
    OrderAccess::fence();
    if (wait_blocked_event.should_commit()) {
      post_safepoint_wait_blocked_event(&wait_blocked_event, initial_waiting_to_block);
    }
  }
#ifdef ASSERT
  for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
    assert(cur->was_visited_for_critical_count(), "missed a thread");
  }
#endif // ASSERT
  GC_locker::set_jni_lock_count(_current_jni_active_count);
  if (TraceSafepoint) {
    VM_Operation *op = VMThread::vm_operation();
    tty->print_cr("Entering safepoint region: %s", (op != NULL) ? op->name() : "no vm operation");
  }
  RuntimeService::record_safepoint_synchronized();
  if (PrintSafepointStatistics) {
    update_statistics_on_sync_end(os::javaTimeNanos());
  }
  {
    EventSafepointCleanup cleanup_event;
    do_cleanup_tasks();
    if (cleanup_event.should_commit()) {
      post_safepoint_cleanup_event(&cleanup_event);
    }
  }
  if (PrintSafepointStatistics) {
    update_statistics_on_cleanup_end(os::javaTimeNanos());
  }
  if (begin_event.should_commit()) {
    post_safepoint_begin_event(&begin_event, nof_threads, _current_jni_active_count);
  }
}
void SafepointSynchronize::end() {
  assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
  assert((_safepoint_counter & 0x1) == 1, "must be odd");
  EventSafepointEnd event;
  _safepoint_counter ++;
  DEBUG_ONLY(Thread* myThread = Thread::current();)
  assert(myThread->is_VM_thread(), "Only VM thread can execute a safepoint");
  if (PrintSafepointStatistics) {
    end_statistics(os::javaTimeNanos());
  }
#ifdef ASSERT
  for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
    assert (!(cur->has_pending_exception() &&
              cur->safepoint_state()->is_at_poll_safepoint()),
            "safepoint installed a pending exception");
  }
#endif // ASSERT
  if (PageArmed) {
    os::make_polling_page_readable();
    PageArmed = 0 ;
  }
  Interpreter::ignore_safepoints();
  {
    MutexLocker mu(Safepoint_lock);
    assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
    _state = _not_synchronized;
    OrderAccess::fence();
    if (TraceSafepoint) {
       tty->print_cr("Leaving safepoint region");
    }
    for(JavaThread *current = Threads::first(); current; current = current->next()) {
      if (VMThreadHintNoPreempt) {
        os::hint_no_preempt();
      }
      ThreadSafepointState* cur_state = current->safepoint_state();
      assert(cur_state->type() != ThreadSafepointState::_running, "Thread not suspended at safepoint");
      cur_state->restart();
      assert(cur_state->is_running(), "safepoint state has not been reset");
    }
    RuntimeService::record_safepoint_end();
    Threads_lock->unlock();
  }
#if INCLUDE_ALL_GCS
  if (UseConcMarkSweepGC) {
    ConcurrentMarkSweepThread::desynchronize(false);
  } else if (UseG1GC) {
    SuspendibleThreadSet::desynchronize();
  }
#endif // INCLUDE_ALL_GCS
  _end_of_last_safepoint = os::javaTimeMillis();
  if (event.should_commit()) {
    post_safepoint_end_event(&event);
  }
}
bool SafepointSynchronize::is_cleanup_needed() {
  if (!InlineCacheBuffer::is_empty()) return true;
  return false;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值