/*
 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

// Must be at least Windows 2000 or XP to use IsDebuggerPresent
#define _WIN32_WINNT 0x500

// no precompiled headers
#include "classfile/classLoader.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_windows.h"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "mutex_windows.inline.hpp"
#include "oops/oop.inline.hpp"
#include "os_share_windows.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/perfMemory.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/vmError.hpp"

#ifdef _DEBUG
#include <crtdbg.h>
#endif


#include <windows.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <objidl.h>
#include <shlobj.h>

#include <malloc.h>
#include <signal.h>
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>              // For _beginthreadex(), _endthreadex()
#include <imagehlp.h>             // For os::dll_address_to_function_name
/* for enumerating dll libraries */
#include <vdmdbg.h>

// for timer info max values which include all bits
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)

// For DLL loading/load error detection
// Values of PE COFF
#define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
#define IMAGE_FILE_SIGNATURE_LENGTH 4

static HANDLE main_process;
static HANDLE main_thread;
static int    main_thread_id;

static FILETIME process_creation_time;
static FILETIME process_exit_time;
static FILETIME process_user_time;
static FILETIME process_kernel_time;

#ifdef _M_IA64
  #define __CPU__ ia64
#else
  #ifdef _M_AMD64
    #define __CPU__ amd64
  #else
    #define __CPU__ i486
  #endif
#endif

// save DLL module handle, used by GetModuleFileName

HINSTANCE vm_lib_handle;

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
  switch (reason) {
    case DLL_PROCESS_ATTACH:
      vm_lib_handle = hinst;
      if(ForceTimeHighResolution)
        timeBeginPeriod(1L);
      break;
    case DLL_PROCESS_DETACH:
      if(ForceTimeHighResolution)
        timeEndPeriod(1L);

      break;
    default:
      break;
  }
  return true;
}

static inline double fileTimeAsDouble(FILETIME* time) {
  const double high  = (double) ((unsigned int) ~0);
  const double split = 10000000.0;
  double result = (time->dwLowDateTime / split) +
                   time->dwHighDateTime * (high/split);
  return result;
}

// Implementation of os

bool os::getenv(const char* name, char* buffer, int len) {
 int result = GetEnvironmentVariable(name, buffer, len);
 return result > 0 && result < len;
}

bool os::unsetenv(const char* name) {
  assert(name != NULL, "Null pointer");
  return (SetEnvironmentVariable(name, NULL) == TRUE);
}

// No setuid programs under Windows.
bool os::have_special_privileges() {
  return false;
}


// This method is  a periodic task to check for misbehaving JNI applications
// under CheckJNI, we can add any periodic checks here.
// For Windows at the moment does nothing
void os::run_periodic_checks() {
  return;
}

#ifndef _WIN64
// previous UnhandledExceptionFilter, if there is one
static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;

LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);
#endif
void os::init_system_properties_values() {
  /* sysclasspath, java_home, dll_dir */
  {
      char *home_path;
      char *dll_path;
      char *pslash;
      char *bin = "\\bin";
      char home_dir[MAX_PATH];

      if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {
          os::jvm_path(home_dir, sizeof(home_dir));
          // Found the full path to jvm.dll.
          // Now cut the path to <java_home>/jre if we can.
          *(strrchr(home_dir, '\\')) = '\0';  /* get rid of \jvm.dll */
          pslash = strrchr(home_dir, '\\');
          if (pslash != NULL) {
              *pslash = '\0';                 /* get rid of \{client|server} */
              pslash = strrchr(home_dir, '\\');
              if (pslash != NULL)
                  *pslash = '\0';             /* get rid of \bin */
          }
      }

      home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal);
      if (home_path == NULL)
          return;
      strcpy(home_path, home_dir);
      Arguments::set_java_home(home_path);

      dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal);
      if (dll_path == NULL)
          return;
      strcpy(dll_path, home_dir);
      strcat(dll_path, bin);
      Arguments::set_dll_dir(dll_path);

      if (!set_boot_path('\\', ';'))
          return;
  }

  /* library_path */
  #define EXT_DIR "\\lib\\ext"
  #define BIN_DIR "\\bin"
  #define PACKAGE_DIR "\\Sun\\Java"
  {
    /* Win32 library search order (See the documentation for LoadLibrary):
     *
     * 1. The directory from which application is loaded.
     * 2. The system wide Java Extensions directory (Java only)
     * 3. System directory (GetSystemDirectory)
     * 4. Windows directory (GetWindowsDirectory)
     * 5. The PATH environment variable
     * 6. The current directory
     */

    char *library_path;
    char tmp[MAX_PATH];
    char *path_str = ::getenv("PATH");

    library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +
        sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal);

    library_path[0] = '\0';

    GetModuleFileName(NULL, tmp, sizeof(tmp));
    *(strrchr(tmp, '\\')) = '\0';
    strcat(library_path, tmp);

    GetWindowsDirectory(tmp, sizeof(tmp));
    strcat(library_path, ";");
    strcat(library_path, tmp);
    strcat(library_path, PACKAGE_DIR BIN_DIR);

    GetSystemDirectory(tmp, sizeof(tmp));
    strcat(library_path, ";");
    strcat(library_path, tmp);

    GetWindowsDirectory(tmp, sizeof(tmp));
    strcat(library_path, ";");
    strcat(library_path, tmp);

    if (path_str) {
        strcat(library_path, ";");
        strcat(library_path, path_str);
    }

    strcat(library_path, ";.");

    Arguments::set_library_path(library_path);
    FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
  }

  /* Default extensions directory */
  {
    char path[MAX_PATH];
    char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1];
    GetWindowsDirectory(path, MAX_PATH);
    sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR,
        path, PACKAGE_DIR, EXT_DIR);
    Arguments::set_ext_dirs(buf);
  }
  #undef EXT_DIR
  #undef BIN_DIR
  #undef PACKAGE_DIR

  /* Default endorsed standards directory. */
  {
    #define ENDORSED_DIR "\\lib\\endorsed"
    size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);
    char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);
    sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
    Arguments::set_endorsed_dirs(buf);
    #undef ENDORSED_DIR
  }

#ifndef _WIN64
  // set our UnhandledExceptionFilter and save any previous one
  prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);
#endif

  // Done
  return;
}

void os::breakpoint() {
  DebugBreak();
}

// Invoked from the BREAKPOINT Macro
extern "C" void breakpoint() {
  os::breakpoint();
}

/*
 * RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP.
 * So far, this method is only used by Native Memory Tracking, which is
 * only supported on Windows XP or later.
 */

int os::get_native_stack(address* stack, int frames, int toSkip) {
#ifdef _NMT_NOINLINE_
  toSkip ++;
#endif
  int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames,
    (PVOID*)stack, NULL);
  for (int index = captured; index < frames; index ++) {
    stack[index] = NULL;
  }
  return captured;
}


// os::current_stack_base()
//
//   Returns the base of the stack, which is the stack's
//   starting address.  This function must be called
//   while running on the stack of the thread being queried.

address os::current_stack_base() {
  MEMORY_BASIC_INFORMATION minfo;
  address stack_bottom;
  size_t stack_size;

  VirtualQuery(&minfo, &minfo, sizeof(minfo));
  stack_bottom =  (address)minfo.AllocationBase;
  stack_size = minfo.RegionSize;

  // Add up the sizes of all the regions with the same
  // AllocationBase.
  while( 1 )
  {
    VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));
    if ( stack_bottom == (address)minfo.AllocationBase )
      stack_size += minfo.RegionSize;
    else
      break;
  }

#ifdef _M_IA64
  // IA64 has memory and register stacks
  //
  // This is the stack layout you get on NT/IA64 if you specify 1MB stack limit
  // at thread creation (1MB backing store growing upwards, 1MB memory stack
  // growing downwards, 2MB summed up)
  //
  // ...
  // ------- top of stack (high address) -----
  // |
  // |      1MB
  // |      Backing Store (Register Stack)
  // |
  // |         / \
  // |          |
  // |          |
  // |          |
  // ------------------------ stack base -----
  // |      1MB
  // |      Memory Stack
  // |
  // |          |
  // |          |
  // |          |
  // |         \ /
  // |
  // ----- bottom of stack (low address) -----
  // ...

  stack_size = stack_size / 2;
#endif
  return stack_bottom + stack_size;
}

size_t os::current_stack_size() {
  size_t sz;
  MEMORY_BASIC_INFORMATION minfo;
  VirtualQuery(&minfo, &minfo, sizeof(minfo));
  sz = (size_t)os::current_stack_base() - (size_t)minfo.AllocationBase;
  return sz;
}

struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
  const struct tm* time_struct_ptr = localtime(clock);
  if (time_struct_ptr != NULL) {
    *res = *time_struct_ptr;
    return res;
  }
  return NULL;
}

LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);

// Thread start routine for all new Java threads
static unsigned __stdcall java_start(Thread* thread) {
  // Try to randomize the cache line index of hot stack frames.
  // This helps when threads of the same stack traces evict each other's
  // cache lines. The threads can be either from the same JVM instance, or
  // from different JVM instances. The benefit is especially true for
  // processors with hyperthreading technology.
  static int counter = 0;
  int pid = os::current_process_id();
  _alloca(((pid ^ counter++) & 7) * 128);

  OSThread* osthr = thread->osthread();
  assert(osthr->get_state() == RUNNABLE, "invalid os thread state");

  if (UseNUMA) {
    int lgrp_id = os::numa_get_group_id();
    if (lgrp_id != -1) {
      thread->set_lgrp_id(lgrp_id);
    }
  }


  // Install a win32 structured exception handler around every thread created
  // by VM, so VM can genrate error dump when an exception occurred in non-
  // Java thread (e.g. VM thread).
  __try {
     thread->run();
  } __except(topLevelExceptionFilter(
             (_EXCEPTION_POINTERS*)_exception_info())) {
      // Nothing to do.
  }

  // One less thread is executing
  // When the VMThread gets here, the main thread may have already exited
  // which frees the CodeHeap containing the Atomic::add code
  if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
    Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
  }

  return 0;
}

static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) {
  // Allocate the OSThread object
  OSThread* osthread = new OSThread(NULL, NULL);
  if (osthread == NULL) return NULL;

  // Initialize support for Java interrupts
  HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
  if (interrupt_event == NULL) {
    delete osthread;
    return NULL;
  }
  osthread->set_interrupt_event(interrupt_event);

  // Store info on the Win32 thread into the OSThread
  osthread->set_thread_handle(thread_handle);
  osthread->set_thread_id(thread_id);

  if (UseNUMA) {
    int lgrp_id = os::numa_get_group_id();
    if (lgrp_id != -1) {
      thread->set_lgrp_id(lgrp_id);
    }
  }

  // Initial thread state is INITIALIZED, not SUSPENDED
  osthread->set_state(INITIALIZED);

  return osthread;
}


bool os::create_attached_thread(JavaThread* thread) {
#ifdef ASSERT
  thread->verify_not_published();
#endif
  HANDLE thread_h;
  if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),
                       &thread_h, THREAD_ALL_ACCESS, false, 0)) {
    fatal("DuplicateHandle failed\n");
  }
  OSThread* osthread = create_os_thread(thread, thread_h,
                                        (int)current_thread_id());
  if (osthread == NULL) {
     return false;
  }

  // Initial thread state is RUNNABLE
  osthread->set_state(RUNNABLE);

  thread->set_osthread(osthread);
  return true;
}

bool os::create_main_thread(JavaThread* thread) {
#ifdef ASSERT
  thread->verify_not_published();
#endif
  if (_starting_thread == NULL) {
    _starting_thread = create_os_thread(thread, main_thread, main_thread_id);
     if (_starting_thread == NULL) {
        return false;
     }
  }

  // The primordial thread is runnable from the start)
  _starting_thread->set_state(RUNNABLE);

  thread->set_osthread(_starting_thread);
  return true;
}

// Allocate and initialize a new OSThread
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
  unsigned thread_id;

  // Allocate the OSThread object
  OSThread* osthread = new OSThread(NULL, NULL);
  if (osthread == NULL) {
    return false;
  }

  // Initialize support for Java interrupts
  HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
  if (interrupt_event == NULL) {
    delete osthread;
    return NULL;
  }
  osthread->set_interrupt_event(interrupt_event);
  osthread->set_interrupted(false);

  thread->set_osthread(osthread);

  if (stack_size == 0) {
    switch (thr_type) {
    case os::java_thread:
      // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
      if (JavaThread::stack_size_at_create() > 0)
        stack_size = JavaThread::stack_size_at_create();
      break;
    case os::compiler_thread:
      if (CompilerThreadStackSize > 0) {
        stack_size = (size_t)(CompilerThreadStackSize * K);
        break;
      } // else fall through:
        // use VMThreadStackSize if CompilerThreadStackSize is not defined
    case os::vm_thread:
    case os::pgc_thread:
    case os::cgc_thread:
    case os::watcher_thread:
      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
      break;
    }
  }

  // Create the Win32 thread
  //
  // Contrary to what MSDN document says, "stack_size" in _beginthreadex()
  // does not specify stack size. Instead, it specifies the size of
  // initially committed space. The stack size is determined by
  // PE header in the executable. If the committed "stack_size" is larger
  // than default value in the PE header, the stack is rounded up to the
  // nearest multiple of 1MB. For example if the launcher has default
  // stack size of 320k, specifying any size less than 320k does not
  // affect the actual stack size at all, it only affects the initial
  // commitment. On the other hand, specifying 'stack_size' larger than
  // default value may cause significant increase in memory usage, because
  // not only the stack space will be rounded up to MB, but also the
  // entire space is committed upfront.
  //
  // Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'
  // for CreateThread() that can treat 'stack_size' as stack size. However we
  // are not supposed to call CreateThread() directly according to MSDN
  // document because JVM uses C runtime library. The good news is that the
  // flag appears to work with _beginthredex() as well.

#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
#define STACK_SIZE_PARAM_IS_A_RESERVATION  (0x10000)
#endif

  HANDLE thread_handle =
    (HANDLE)_beginthreadex(NULL,
                           (unsigned)stack_size,
                           (unsigned (__stdcall *)(void*)) java_start,
                           thread,
                           CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
                           &thread_id);
  if (thread_handle == NULL) {
    // perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again
    // without the flag.
    thread_handle =
    (HANDLE)_beginthreadex(NULL,
                           (unsigned)stack_size,
                           (unsigned (__stdcall *)(void*)) java_start,
                           thread,
                           CREATE_SUSPENDED,
                           &thread_id);
  }
  if (thread_handle == NULL) {
    // Need to clean up stuff we've allocated so far
    CloseHandle(osthread->interrupt_event());
    thread->set_osthread(NULL);
    delete osthread;
    return NULL;
  }

  Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);

  // Store info on the Win32 thread into the OSThread
  osthread->set_thread_handle(thread_handle);
  osthread->set_thread_id(thread_id);

  // Initial thread state is INITIALIZED, not SUSPENDED
  osthread->set_state(INITIALIZED);

  // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
  return true;
}


// Free Win32 resources related to the OSThread
void os::free_thread(OSThread* osthread) {
  assert(osthread != NULL, "osthread not set");
  CloseHandle(osthread->thread_handle());
  CloseHandle(osthread->interrupt_event());
  delete osthread;
}


static int    has_performance_count = 0;
static jlong first_filetime;
static jlong initial_performance_count;
static jlong performance_frequency;


jlong as_long(LARGE_INTEGER x) {
  jlong result = 0; // initialization to avoid warning
  set_high(&result, x.HighPart);
  set_low(&result,  x.LowPart);
  return result;
}


jlong os::elapsed_counter() {
  LARGE_INTEGER count;
  if (has_performance_count) {
    QueryPerformanceCounter(&count);
    return as_long(count) - initial_performance_count;
  } else {
    FILETIME wt;
    GetSystemTimeAsFileTime(&wt);
    return (jlong_from(wt.dwHighDateTime, wt.dwLowDateTime) - first_filetime);
  }
}


jlong os::elapsed_frequency() {
  if (has_performance_count) {
    return performance_frequency;
  } else {
   // the FILETIME time is the number of 100-nanosecond intervals since January 1,1601.
   return 10000000;
  }
}


julong os::available_memory() {
  return win32::available_memory();
}

julong os::win32::available_memory() {
  // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
  // value if total memory is larger than 4GB
  MEMORYSTATUSEX ms;
  ms.dwLength = sizeof(ms);
  GlobalMemoryStatusEx(&ms);

  return (julong)ms.ullAvailPhys;
}

julong os::physical_memory() {
  return win32::physical_memory();
}

bool os::has_allocatable_memory_limit(julong* limit) {
  MEMORYSTATUSEX ms;
  ms.dwLength = sizeof(ms);
  GlobalMemoryStatusEx(&ms);
#ifdef _LP64
  *limit = (julong)ms.ullAvailVirtual;
  return true;
#else
  // Limit to 1400m because of the 2gb address space wall
  *limit = MIN2((julong)1400*M, (julong)ms.ullAvailVirtual);
  return true;
#endif
}

// VC6 lacks DWORD_PTR
#if _MSC_VER < 1300
typedef UINT_PTR DWORD_PTR;
#endif

int os::active_processor_count() {
  DWORD_PTR lpProcessAffinityMask = 0;
  DWORD_PTR lpSystemAffinityMask = 0;
  int proc_count = processor_count();
  if (proc_count <= sizeof(UINT_PTR) * BitsPerByte &&
      GetProcessAffinityMask(GetCurrentProcess(), &lpProcessAffinityMask, &lpSystemAffinityMask)) {
    // Nof active processors is number of bits in process affinity mask
    int bitcount = 0;
    while (lpProcessAffinityMask != 0) {
      lpProcessAffinityMask = lpProcessAffinityMask & (lpProcessAffinityMask-1);
      bitcount++;
    }
    return bitcount;
  } else {
    return proc_count;
  }
}

void os::set_native_thread_name(const char *name) {
  // Not yet implemented.
  return;
}

bool os::distribute_processes(uint length, uint* distribution) {
  // Not yet implemented.
  return false;
}

bool os::bind_to_processor(uint processor_id) {
  // Not yet implemented.
  return false;
}

static void initialize_performance_counter() {
  LARGE_INTEGER count;
  if (QueryPerformanceFrequency(&count)) {
    has_performance_count = 1;
    performance_frequency = as_long(count);
    QueryPerformanceCounter(&count);
    initial_performance_count = as_long(count);
  } else {
    has_performance_count = 0;
    FILETIME wt;
    GetSystemTimeAsFileTime(&wt);
    first_filetime = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
  }
}


double os::elapsedTime() {
  return (double) elapsed_counter() / (double) elapsed_frequency();
}


// Windows format:
//   The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.
// Java format:
//   Java standards require the number of milliseconds since 1/1/1970

// Constant offset - calculated using offset()
static jlong  _offset   = 116444736000000000;
// Fake time counter for reproducible results when debugging
static jlong  fake_time = 0;

#ifdef ASSERT
// Just to be safe, recalculate the offset in debug mode
static jlong _calculated_offset = 0;
static int   _has_calculated_offset = 0;

jlong offset() {
  if (_has_calculated_offset) return _calculated_offset;
  SYSTEMTIME java_origin;
  java_origin.wYear          = 1970;
  java_origin.wMonth         = 1;
  java_origin.wDayOfWeek     = 0; // ignored
  java_origin.wDay           = 1;
  java_origin.wHour          = 0;
  java_origin.wMinute        = 0;
  java_origin.wSecond        = 0;
  java_origin.wMilliseconds  = 0;
  FILETIME jot;
  if (!SystemTimeToFileTime(&java_origin, &jot)) {
    fatal(err_msg("Error = %d\nWindows error", GetLastError()));
  }
  _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);
  _has_calculated_offset = 1;
  assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");
  return _calculated_offset;
}
#else
jlong offset() {
  return _offset;
}
#endif

jlong windows_to_java_time(FILETIME wt) {
  jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
  return (a - offset()) / 10000;
}

FILETIME java_to_windows_time(jlong l) {
  jlong a = (l * 10000) + offset();
  FILETIME result;
  result.dwHighDateTime = high(a);
  result.dwLowDateTime  = low(a);
  return result;
}

bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }

double os::elapsedVTime() {
  FILETIME created;
  FILETIME exited;
  FILETIME kernel;
  FILETIME user;
  if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {
    // the resolution of windows_to_java_time() should be sufficient (ms)
    return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;
  } else {
    return elapsedTime();
  }
}

jlong os::javaTimeMillis() {
  if (UseFakeTimers) {
    return fake_time++;
  } else {
    FILETIME wt;
    GetSystemTimeAsFileTime(&wt);
    return windows_to_java_time(wt);
  }
}

jlong os::javaTimeNanos() {
  if (!has_performance_count) {
    return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
  } else {
    LARGE_INTEGER current_count;
    QueryPerformanceCounter(&current_count);
    double current = as_long(current_count);
    double freq = performance_frequency;
    jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);
    return time;
  }
}

void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
  if (!has_performance_count) {
    // javaTimeMillis() doesn't have much percision,
    // but it is not going to wrap -- so all 64 bits
    info_ptr->max_value = ALL_64_BITS;

    // this is a wall clock timer, so may skip
    info_ptr->may_skip_backward = true;
    info_ptr->may_skip_forward = true;
  } else {
    jlong freq = performance_frequency;
    if (freq < NANOSECS_PER_SEC) {
      // the performance counter is 64 bits and we will
      // be multiplying it -- so no wrap in 64 bits
      info_ptr->max_value = ALL_64_BITS;
    } else if (freq > NANOSECS_PER_SEC) {
      // use the max value the counter can reach to
      // determine the max value which could be returned
      julong max_counter = (julong)ALL_64_BITS;
      info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));
    } else {
      // the performance counter is 64 bits and we will
      // be using it directly -- so no wrap in 64 bits
      info_ptr->max_value = ALL_64_BITS;
    }

    // using a counter, so no skipping
    info_ptr->may_skip_backward = false;
    info_ptr->may_skip_forward = false;
  }
  info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
}

char* os::local_time_string(char *buf, size_t buflen) {
  SYSTEMTIME st;
  GetLocalTime(&st);
  jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
               st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
  return buf;
}

bool os::getTimesSecs(double* process_real_time,
                     double* process_user_time,
                     double* process_system_time) {
  HANDLE h_process = GetCurrentProcess();
  FILETIME create_time, exit_time, kernel_time, user_time;
  BOOL result = GetProcessTimes(h_process,
                               &create_time,
                               &exit_time,
                               &kernel_time,
                               &user_time);
  if (result != 0) {
    FILETIME wt;
    GetSystemTimeAsFileTime(&wt);
    jlong rtc_millis = windows_to_java_time(wt);
    jlong user_millis = windows_to_java_time(user_time);
    jlong system_millis = windows_to_java_time(kernel_time);
    *process_real_time = ((double) rtc_millis) / ((double) MILLIUNITS);
    *process_user_time = ((double) user_millis) / ((double) MILLIUNITS);
    *process_system_time = ((double) system_millis) / ((double) MILLIUNITS);
    return true;
  } else {
    return false;
  }
}

void os::shutdown() {

  // allow PerfMemory to attempt cleanup of any persistent resources
  perfMemory_exit();

  // flush buffered output, finish log files
  ostream_abort();

  // Check for abort hook
  abort_hook_t abort_hook = Arguments::abort_hook();
  if (abort_hook != NULL) {
    abort_hook();
  }
}


static BOOL  (WINAPI *_MiniDumpWriteDump)  ( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
                                            PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);

void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
  HINSTANCE dbghelp;
  EXCEPTION_POINTERS ep;
  MINIDUMP_EXCEPTION_INFORMATION mei;
  MINIDUMP_EXCEPTION_INFORMATION* pmei;

  HANDLE hProcess = GetCurrentProcess();
  DWORD processId = GetCurrentProcessId();
  HANDLE dumpFile;
  MINIDUMP_TYPE dumpType;
  static const char* cwd;

// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.
#ifndef ASSERT
  // If running on a client version of Windows and user has not explicitly enabled dumping
  if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
    VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
    return;
    // If running on a server version of Windows and user has explictly disabled dumping
  } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
    VMError::report_coredump_status("Minidump has been disabled from the command line", false);
    return;
  }
#else
  if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
    VMError::report_coredump_status("Minidump has been disabled from the command line", false);
    return;
  }
#endif

  dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);

  if (dbghelp == NULL) {
    VMError::report_coredump_status("Failed to load dbghelp.dll", false);
    return;
  }

  _MiniDumpWriteDump = CAST_TO_FN_PTR(
    BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
    PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION),
    GetProcAddress(dbghelp, "MiniDumpWriteDump"));

  if (_MiniDumpWriteDump == NULL) {
    VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false);
    return;
  }

  dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData);

// Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with
// API_VERSION_NUMBER 11 or higher contains the ones we want though
#if API_VERSION_NUMBER >= 11
  dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo |
    MiniDumpWithUnloadedModules);
#endif

  cwd = get_current_directory(NULL, 0);
  jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp",cwd, current_process_id());
  dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (dumpFile == INVALID_HANDLE_VALUE) {
    VMError::report_coredump_status("Failed to create file for dumping", false);
    return;
  }
  if (exceptionRecord != NULL && contextRecord != NULL) {
    ep.ContextRecord = (PCONTEXT) contextRecord;
    ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord;

    mei.ThreadId = GetCurrentThreadId();
    mei.ExceptionPointers = &ep;
    pmei = &mei;
  } else {
    pmei = NULL;
  }


  // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all
  // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
  if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
      _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
        DWORD error = GetLastError();
        LPTSTR msgbuf = NULL;

        if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                      FORMAT_MESSAGE_FROM_SYSTEM |
                      FORMAT_MESSAGE_IGNORE_INSERTS,
                      NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {

          jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);
          LocalFree(msgbuf);
        } else {
          // Call to FormatMessage failed, just include the result from GetLastError
          jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);
        }
        VMError::report_coredump_status(buffer, false);
  } else {
    VMError::report_coredump_status(buffer, true);
  }

  CloseHandle(dumpFile);
}



void os::abort(bool dump_core)
{
  os::shutdown();
  // no core dump on Windows
  ::exit(1);
}

// Die immediately, no exit hook, no abort hook, no cleanup.
void os::die() {
  _exit(-1);
}

// Directory routines copied from src/win32/native/java/io/dirent_md.c
//  * dirent_md.c       1.15 00/02/02
//
// The declarations for DIR and struct dirent are in jvm_win32.h.

/* Caller must have already run dirname through JVM_NativePath, which removes
   duplicate slashes and converts all instances of '/' into '\\'. */

DIR *
os::opendir(const char *dirname)
{
    assert(dirname != NULL, "just checking");   // hotspot change
    DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal);
    DWORD fattr;                                // hotspot change
    char alt_dirname[4] = { 0, 0, 0, 0 };

    if (dirp == 0) {
        errno = ENOMEM;
        return 0;
    }

    /*
     * Win32 accepts "\" in its POSIX stat(), but refuses to treat it
     * as a directory in FindFirstFile().  We detect this case here and
     * prepend the current drive name.
     */
    if (dirname[1] == '\0' && dirname[0] == '\\') {
        alt_dirname[0] = _getdrive() + 'A' - 1;
        alt_dirname[1] = ':';
        alt_dirname[2] = '\\';
        alt_dirname[3] = '\0';
        dirname = alt_dirname;
    }

    dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);
    if (dirp->path == 0) {
        free(dirp, mtInternal);
        errno = ENOMEM;
        return 0;
    }
    strcpy(dirp->path, dirname);

    fattr = GetFileAttributes(dirp->path);
    if (fattr == 0xffffffff) {
        free(dirp->path, mtInternal);
        free(dirp, mtInternal);
        errno = ENOENT;
        return 0;
    } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
        free(dirp->path, mtInternal);
        free(dirp, mtInternal);
        errno = ENOTDIR;
        return 0;
    }

    /* Append "*.*", or possibly "\\*.*", to path */
    if (dirp->path[1] == ':'
        && (dirp->path[2] == '\0'
            || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) {
        /* No '\\' needed for cases like "Z:" or "Z:\" */
        strcat(dirp->path, "*.*");
    } else {
        strcat(dirp->path, "\\*.*");
    }

    dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
    if (dirp->handle == INVALID_HANDLE_VALUE) {
        if (GetLastError() != ERROR_FILE_NOT_FOUND) {
            free(dirp->path, mtInternal);
            free(dirp, mtInternal);
            errno = EACCES;
            return 0;
        }
    }
    return dirp;
}

/* parameter dbuf unused on Windows */

struct dirent *
os::readdir(DIR *dirp, dirent *dbuf)
{
    assert(dirp != NULL, "just checking");      // hotspot change
    if (dirp->handle == INVALID_HANDLE_VALUE) {
        return 0;
    }

    strcpy(dirp->dirent.d_name, dirp->find_data.cFileName);

    if (!FindNextFile(dirp->handle, &dirp->find_data)) {
        if (GetLastError() == ERROR_INVALID_HANDLE) {
            errno = EBADF;
            return 0;
        }
        FindClose(dirp->handle);
        dirp->handle = INVALID_HANDLE_VALUE;
    }

    return &dirp->dirent;
}

int
os::closedir(DIR *dirp)
{
    assert(dirp != NULL, "just checking");      // hotspot change
    if (dirp->handle != INVALID_HANDLE_VALUE) {
        if (!FindClose(dirp->handle)) {
            errno = EBADF;
            return -1;
        }
        dirp->handle = INVALID_HANDLE_VALUE;
    }
    free(dirp->path, mtInternal);
    free(dirp, mtInternal);
    return 0;
}

// This must be hard coded because it's the system's temporary
// directory not the java application's temp directory, ala java.io.tmpdir.
const char* os::get_temp_directory() {
  static char path_buf[MAX_PATH];
  if (GetTempPath(MAX_PATH, path_buf)>0)
    return path_buf;
  else{
    path_buf[0]='\0';
    return path_buf;
  }
}

static bool file_exists(const char* filename) {
  if (filename == NULL || strlen(filename) == 0) {
    return false;
  }
  return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
}

bool os::dll_build_name(char *buffer, size_t buflen,
                        const char* pname, const char* fname) {
  bool retval = false;
  const size_t pnamelen = pname ? strlen(pname) : 0;
  const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;

  // Return error on buffer overflow.
  if (pnamelen + strlen(fname) + 10 > buflen) {
    return retval;
  }

  if (pnamelen == 0) {
    jio_snprintf(buffer, buflen, "%s.dll", fname);
    retval = true;
  } else if (c == ':' || c == '\\') {
    jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);
    retval = true;
  } else if (strchr(pname, *os::path_separator()) != NULL) {
    int n;
    char** pelements = split_path(pname, &n);
    if (pelements == NULL) {
      return false;
    }
    for (int i = 0 ; i < n ; i++) {
      char* path = pelements[i];
      // Really shouldn't be NULL, but check can't hurt
      size_t plen = (path == NULL) ? 0 : strlen(path);
      if (plen == 0) {
        continue; // skip the empty path values
      }
      const char lastchar = path[plen - 1];
      if (lastchar == ':' || lastchar == '\\') {
        jio_snprintf(buffer, buflen, "%s%s.dll", path, fname);
      } else {
        jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
      }
      if (file_exists(buffer)) {
        retval = true;
        break;
      }
    }
    // release the storage
    for (int i = 0 ; i < n ; i++) {
      if (pelements[i] != NULL) {
        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
      }
    }
    if (pelements != NULL) {
      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
    }
  } else {
    jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
    retval = true;
  }
  return retval;
}

// Needs to be in os specific directory because windows requires another
// header file <direct.h>
const char* os::get_current_directory(char *buf, size_t buflen) {
  int n = static_cast<int>(buflen);
  if (buflen > INT_MAX)  n = INT_MAX;
  return _getcwd(buf, n);
}

//-----------------------------------------------------------
// Helper functions for fatal error handler
#ifdef _WIN64
// Helper routine which returns true if address in
// within the NTDLL address space.
//
static bool _addr_in_ntdll( address addr )
{
  HMODULE hmod;
  MODULEINFO minfo;

  hmod = GetModuleHandle("NTDLL.DLL");
  if ( hmod == NULL ) return false;
  if ( !os::PSApiDll::GetModuleInformation( GetCurrentProcess(), hmod,
                               &minfo, sizeof(MODULEINFO)) )
    return false;

  if ( (addr >= minfo.lpBaseOfDll) &&
       (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage)))
    return true;
  else
    return false;
}
#endif


// Enumerate all modules for a given process ID
//
// Notice that Windows 95/98/Me and Windows NT/2000/XP have
// different API for doing this. We use PSAPI.DLL on NT based
// Windows and ToolHelp on 95/98/Me.

// Callback function that is called by enumerate_modules() on
// every DLL module.
// Input parameters:
//    int       pid,
//    char*     module_file_name,
//    address   module_base_addr,
//    unsigned  module_size,
//    void*     param
typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *);

// enumerate_modules for Windows NT, using PSAPI
static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param)
{
  HANDLE   hProcess ;

# define MAX_NUM_MODULES 128
  HMODULE     modules[MAX_NUM_MODULES];
  static char filename[ MAX_PATH ];
  int         result = 0;

  if (!os::PSApiDll::PSApiAvailable()) {
    return 0;
  }

  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                         FALSE, pid ) ;
  if (hProcess == NULL) return 0;

  DWORD size_needed;
  if (!os::PSApiDll::EnumProcessModules(hProcess, modules,
                           sizeof(modules), &size_needed)) {
      CloseHandle( hProcess );
      return 0;
  }

  // number of modules that are currently loaded
  int num_modules = size_needed / sizeof(HMODULE);

  for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {
    // Get Full pathname:
    if(!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i],
                             filename, sizeof(filename))) {
        filename[0] = '\0';
    }

    MODULEINFO modinfo;
    if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i],
                               &modinfo, sizeof(modinfo))) {
        modinfo.lpBaseOfDll = NULL;
        modinfo.SizeOfImage = 0;
    }

    // Invoke callback function
    result = func(pid, filename, (address)modinfo.lpBaseOfDll,
                  modinfo.SizeOfImage, param);
    if (result) break;
  }

  CloseHandle( hProcess ) ;
  return result;
}


// enumerate_modules for Windows 95/98/ME, using TOOLHELP
static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param)
{
  HANDLE                hSnapShot ;
  static MODULEENTRY32  modentry ;
  int                   result = 0;

  if (!os::Kernel32Dll::HelpToolsAvailable()) {
    return 0;
  }

  // Get a handle to a Toolhelp snapshot of the system
  hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid ) ;
  if( hSnapShot == INVALID_HANDLE_VALUE ) {
      return FALSE ;
  }

  // iterate through all modules
  modentry.dwSize = sizeof(MODULEENTRY32) ;
  bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0;

  while( not_done ) {
    // invoke the callback
    result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr,
                modentry.modBaseSize, param);
    if (result) break;

    modentry.dwSize = sizeof(MODULEENTRY32) ;
    not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0;
  }

  CloseHandle(hSnapShot);
  return result;
}

int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param )
{
  // Get current process ID if caller doesn't provide it.
  if (!pid) pid = os::current_process_id();

  if (os::win32::is_nt()) return _enumerate_modules_winnt  (pid, func, param);
  else                    return _enumerate_modules_windows(pid, func, param);
}

struct _modinfo {
   address addr;
   char*   full_path;   // point to a char buffer
   int     buflen;      // size of the buffer
   address base_addr;
};

static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr,
                                  unsigned size, void * param) {
   struct _modinfo *pmod = (struct _modinfo *)param;
   if (!pmod) return -1;

   if (base_addr     <= pmod->addr &&
       base_addr+size > pmod->addr) {
     // if a buffer is provided, copy path name to the buffer
     if (pmod->full_path) {
       jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname);
     }
     pmod->base_addr = base_addr;
     return 1;
   }
   return 0;
}

bool os::dll_address_to_library_name(address addr, char* buf,
                                     int buflen, int* offset) {
  // buf is not optional, but offset is optional
  assert(buf != NULL, "sanity check");

// NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always
//       return the full path to the DLL file, sometimes it returns path
//       to the corresponding PDB file (debug info); sometimes it only
//       returns partial path, which makes life painful.

  struct _modinfo mi;
  mi.addr      = addr;
  mi.full_path = buf;
  mi.buflen    = buflen;
  int pid = os::current_process_id();
  if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {
    // buf already contains path name
    if (offset) *offset = addr - mi.base_addr;
    return true;
  }

  buf[0] = '\0';
  if (offset) *offset = -1;
  return false;
}

bool os::dll_address_to_function_name(address addr, char *buf,
                                      int buflen, int *offset) {
  // buf is not optional, but offset is optional
  assert(buf != NULL, "sanity check");

  if (Decoder::decode(addr, buf, buflen, offset)) {
    return true;
  }
  if (offset != NULL)  *offset  = -1;
  buf[0] = '\0';
  return false;
}

// save the start and end address of jvm.dll into param[0] and param[1]
static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,
                    unsigned size, void * param) {
   if (!param) return -1;

   if (base_addr     <= (address)_locate_jvm_dll &&
       base_addr+size > (address)_locate_jvm_dll) {
         ((address*)param)[0] = base_addr;
         ((address*)param)[1] = base_addr + size;
         return 1;
   }
   return 0;
}

address vm_lib_location[2];    // start and end address of jvm.dll

// check if addr is inside jvm.dll
bool os::address_is_in_vm(address addr) {
  if (!vm_lib_location[0] || !vm_lib_location[1]) {
    int pid = os::current_process_id();
    if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) {
      assert(false, "Can't find jvm module.");
      return false;
    }
  }

  return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]);
}

// print module info; param is outputStream*
static int _print_module(int pid, char* fname, address base,
                         unsigned size, void* param) {
   if (!param) return -1;

   outputStream* st = (outputStream*)param;

   address end_addr = base + size;
   st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname);
   return 0;
}

// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on
void * os::dll_load(const char *name, char *ebuf, int ebuflen)
{
  void * result = LoadLibrary(name);
  if (result != NULL)
  {
    return result;
  }

  DWORD errcode = GetLastError();
  if (errcode == ERROR_MOD_NOT_FOUND) {
    strncpy(ebuf, "Can't find dependent libraries", ebuflen-1);
    ebuf[ebuflen-1]='\0';
    return NULL;
  }

  // Parsing dll below
  // If we can read dll-info and find that dll was built
  // for an architecture other than Hotspot is running in
  // - then print to buffer "DLL was built for a different architecture"
  // else call os::lasterror to obtain system error message

  // Read system error message into ebuf
  // It may or may not be overwritten below (in the for loop and just above)
  lasterror(ebuf, (size_t) ebuflen);
  ebuf[ebuflen-1]='\0';
  int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0);
  if (file_descriptor<0)
  {
    return NULL;
  }

  uint32_t signature_offset;
  uint16_t lib_arch=0;
  bool failed_to_get_lib_arch=
  (
    //Go to position 3c in the dll
    (os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0)
    ||
    // Read loacation of signature
    (sizeof(signature_offset)!=
      (os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset))))
    ||
    //Go to COFF File Header in dll
    //that is located after"signature" (4 bytes long)
    (os::seek_to_file_offset(file_descriptor,
      signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0)
    ||
    //Read field that contains code of architecture
    // that dll was build for
    (sizeof(lib_arch)!=
      (os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch))))
  );

  ::close(file_descriptor);
  if (failed_to_get_lib_arch)
  {
    // file i/o error - report os::lasterror(...) msg
    return NULL;
  }

  typedef struct
  {
    uint16_t arch_code;
    char* arch_name;
  } arch_t;

  static const arch_t arch_array[]={
    {IMAGE_FILE_MACHINE_I386,      (char*)"IA 32"},
    {IMAGE_FILE_MACHINE_AMD64,     (char*)"AMD 64"},
    {IMAGE_FILE_MACHINE_IA64,      (char*)"IA 64"}
  };
  #if   (defined _M_IA64)
    static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64;
  #elif (defined _M_AMD64)
    static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64;
  #elif (defined _M_IX86)
    static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386;
  #else
    #error Method os::dll_load requires that one of following \
           is defined :_M_IA64,_M_AMD64 or _M_IX86
  #endif


  // Obtain a string for printf operation
  // lib_arch_str shall contain string what platform this .dll was built for
  // running_arch_str shall string contain what platform Hotspot was built for
  char *running_arch_str=NULL,*lib_arch_str=NULL;
  for (unsigned int i=0;i<ARRAY_SIZE(arch_array);i++)
  {
    if (lib_arch==arch_array[i].arch_code)
      lib_arch_str=arch_array[i].arch_name;
    if (running_arch==arch_array[i].arch_code)
      running_arch_str=arch_array[i].arch_name;
  }

  assert(running_arch_str,
    "Didn't find runing architecture code in arch_array");

  // If the architure is right
  // but some other error took place - report os::lasterror(...) msg
  if (lib_arch == running_arch)
  {
    return NULL;
  }

  if (lib_arch_str!=NULL)
  {
    ::_snprintf(ebuf, ebuflen-1,
      "Can't load %s-bit .dll on a %s-bit platform",
      lib_arch_str,running_arch_str);
  }
  else
  {
    // don't know what architecture this dll was build for
    ::_snprintf(ebuf, ebuflen-1,
      "Can't load this .dll (machine code=0x%x) on a %s-bit platform",
      lib_arch,running_arch_str);
  }

  return NULL;
}


void os::print_dll_info(outputStream *st) {
   int pid = os::current_process_id();
   st->print_cr("Dynamic libraries:");
   enumerate_modules(pid, _print_module, (void *)st);
}

void os::print_os_info_brief(outputStream* st) {
  os::print_os_info(st);
}

void os::print_os_info(outputStream* st) {
  st->print("OS:");

  os::win32::print_windows_version(st);
}

void os::win32::print_windows_version(outputStream* st) {
  OSVERSIONINFOEX osvi;
  VS_FIXEDFILEINFO *file_info;
  TCHAR kernel32_path[MAX_PATH];
  UINT len, ret;

  // Use the GetVersionEx information to see if we're on a server or
  // workstation edition of Windows. Starting with Windows 8.1 we can't
  // trust the OS version information returned by this API.
  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
    st->print_cr("Call to GetVersionEx failed");
    return;
  }
  bool is_workstation = (osvi.wProductType == VER_NT_WORKSTATION);

  // Get the full path to \Windows\System32\kernel32.dll and use that for
  // determining what version of Windows we're running on.
  len = MAX_PATH - (UINT)strlen("\\kernel32.dll") - 1;
  ret = GetSystemDirectory(kernel32_path, len);
  if (ret == 0 || ret > len) {
    st->print_cr("Call to GetSystemDirectory failed");
    return;
  }
  strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);

  DWORD version_size = GetFileVersionInfoSize(kernel32_path, NULL);
  if (version_size == 0) {
    st->print_cr("Call to GetFileVersionInfoSize failed");
    return;
  }

  LPTSTR version_info = (LPTSTR)os::malloc(version_size, mtInternal);
  if (version_info == NULL) {
    st->print_cr("Failed to allocate version_info");
    return;
  }

  if (!GetFileVersionInfo(kernel32_path, NULL, version_size, version_info)) {
    os::free(version_info);
    st->print_cr("Call to GetFileVersionInfo failed");
    return;
  }

  if (!VerQueryValue(version_info, TEXT("\\"), (LPVOID*)&file_info, &len)) {
    os::free(version_info);
    st->print_cr("Call to VerQueryValue failed");
    return;
  }

  int major_version = HIWORD(file_info->dwProductVersionMS);
  int minor_version = LOWORD(file_info->dwProductVersionMS);
  int build_number = HIWORD(file_info->dwProductVersionLS);
  int build_minor = LOWORD(file_info->dwProductVersionLS);
  int os_vers = major_version * 1000 + minor_version;
  os::free(version_info);

  st->print(" Windows ");
  switch (os_vers) {

  case 6000:
    if (is_workstation) {
      st->print("Vista");
    } else {
      st->print("Server 2008");
    }
    break;

  case 6001:
    if (is_workstation) {
      st->print("7");
    } else {
      st->print("Server 2008 R2");
    }
    break;

  case 6002:
    if (is_workstation) {
      st->print("8");
    } else {
      st->print("Server 2012");
    }
    break;

  case 6003:
    if (is_workstation) {
      st->print("8.1");
    } else {
      st->print("Server 2012 R2");
    }
    break;

  case 6004:
    if (is_workstation) {
      st->print("10");
    } else {
      st->print("Server 2016");
    }
    break;

  default:
    // Unrecognized windows, print out its major and minor versions
    st->print("%d.%d", major_version, minor_version);
    break;
  }

  // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
  // find out whether we are running on 64 bit processor or not
  SYSTEM_INFO si;
  ZeroMemory(&si, sizeof(SYSTEM_INFO));
  os::Kernel32Dll::GetNativeSystemInfo(&si);
  if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
    st->print(" , 64 bit");
  }

  st->print(" Build %d", build_number);
  st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
  st->cr();
}

void os::pd_print_cpu_info(outputStream* st) {
  // Nothing to do for now.
}

void os::print_memory_info(outputStream* st) {
  st->print("Memory:");
  st->print(" %dk page", os::vm_page_size()>>10);

  // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
  // value if total memory is larger than 4GB
  MEMORYSTATUSEX ms;
  ms.dwLength = sizeof(ms);
  GlobalMemoryStatusEx(&ms);

  st->print(", physical %uk", os::physical_memory() >> 10);
  st->print("(%uk free)", os::available_memory() >> 10);

  st->print(", swap %uk", ms.ullTotalPageFile >> 10);
  st->print("(%uk free)", ms.ullAvailPageFile >> 10);
  st->cr();
}

void os::print_siginfo(outputStream *st, void *siginfo) {
  EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;
  st->print("siginfo:");
  st->print(" ExceptionCode=0x%x", er->ExceptionCode);

  if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
      er->NumberParameters >= 2) {
      switch (er->ExceptionInformation[0]) {
      case 0: st->print(", reading address"); break;
      case 1: st->print(", writing address"); break;
      default: st->print(", ExceptionInformation=" INTPTR_FORMAT,
                            er->ExceptionInformation[0]);
      }
      st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);
  } else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR &&
             er->NumberParameters >= 2 && UseSharedSpaces) {
    FileMapInfo* mapinfo = FileMapInfo::current_info();
    if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {
      st->print("\n\nError accessing class data sharing archive."       \
                " Mapped file inaccessible during execution, "          \
                " possible disk/network problem.");
    }
  } else {
    int num = er->NumberParameters;
    if (num > 0) {
      st->print(", ExceptionInformation=");
      for (int i = 0; i < num; i++) {
        st->print(INTPTR_FORMAT " ", er->ExceptionInformation[i]);
      }
    }
  }
  st->cr();
}

void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
  // do nothing
}

static char saved_jvm_path[MAX_PATH] = {0};

// Find the full path to the current module, jvm.dll
void os::jvm_path(char *buf, jint buflen) {
  // Error checking.
  if (buflen < MAX_PATH) {
    assert(false, "must use a large-enough buffer");
    buf[0] = '\0';
    return;
  }
  // Lazy resolve the path to current module.
  if (saved_jvm_path[0] != 0) {
    strcpy(buf, saved_jvm_path);
    return;
  }

  buf[0] = '\0';
  if (Arguments::created_by_gamma_launcher()) {
     // Support for the gamma launcher. Check for an
     // JAVA_HOME environment variable
     // and fix up the path so it looks like
     // libjvm.so is installed there (append a fake suffix
     // hotspot/libjvm.so).
     char* java_home_var = ::getenv("JAVA_HOME");
     if (java_home_var != NULL && java_home_var[0] != 0 &&
         strlen(java_home_var) < (size_t)buflen) {

        strncpy(buf, java_home_var, buflen);

        // determine if this is a legacy image or modules image
        // modules image doesn't have "jre" subdirectory
        size_t len = strlen(buf);
        char* jrebin_p = buf + len;
        jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\");
        if (0 != _access(buf, 0)) {
          jio_snprintf(jrebin_p, buflen-len, "\\bin\\");
        }
        len = strlen(buf);
        jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll");
     }
  }

  if(buf[0] == '\0') {
    GetModuleFileName(vm_lib_handle, buf, buflen);
  }
  strncpy(saved_jvm_path, buf, MAX_PATH);
}


void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
#ifndef _WIN64
  st->print("_");
#endif
}


void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
#ifndef _WIN64
  st->print("@%d", args_size  * sizeof(int));
#endif
}

// This method is a copy of JDK's sysGetLastErrorString
// from src/windows/hpi/src/system_md.c

size_t os::lasterror(char* buf, size_t len) {
  DWORD errval;

  if ((errval = GetLastError()) != 0) {
    // DOS error
    size_t n = (size_t)FormatMessage(
          FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
          NULL,
          errval,
          0,
          buf,
          (DWORD)len,
          NULL);
    if (n > 3) {
      // Drop final '.', CR, LF
      if (buf[n - 1] == '\n') n--;
      if (buf[n - 1] == '\r') n--;
      if (buf[n - 1] == '.') n--;
      buf[n] = '\0';
    }
    return n;
  }

  if (errno != 0) {
    // C runtime error that has no corresponding DOS error code
    const char* s = strerror(errno);
    size_t n = strlen(s);
    if (n >= len) n = len - 1;
    strncpy(buf, s, n);
    buf[n] = '\0';
    return n;
  }

  return 0;
}

int os::get_last_error() {
  DWORD error = GetLastError();
  if (error == 0)
    error = errno;
  return (int)error;
}

// sun.misc.Signal
// NOTE that this is a workaround for an apparent kernel bug where if
// a signal handler for SIGBREAK is installed then that signal handler
// takes priority over the console control handler for CTRL_CLOSE_EVENT.
// See bug 4416763.
static void (*sigbreakHandler)(int) = NULL;

static void UserHandler(int sig, void *siginfo, void *context) {
  os::signal_notify(sig);
  // We need to reinstate the signal handler each time...
  os::signal(sig, (void*)UserHandler);
}

void* os::user_handler() {
  return (void*) UserHandler;
}

void* os::signal(int signal_number, void* handler) {
  if ((signal_number == SIGBREAK) && (!ReduceSignalUsage)) {
    void (*oldHandler)(int) = sigbreakHandler;
    sigbreakHandler = (void (*)(int)) handler;
    return (void*) oldHandler;
  } else {
    return (void*)::signal(signal_number, (void (*)(int))handler);
  }
}

void os::signal_raise(int signal_number) {
  raise(signal_number);
}

// The Win32 C runtime library maps all console control events other than ^C
// into SIGBREAK, which makes it impossible to distinguish ^BREAK from close,
// logoff, and shutdown events.  We therefore install our own console handler
// that raises SIGTERM for the latter cases.
//
static BOOL WINAPI consoleHandler(DWORD event) {
  switch(event) {
    case CTRL_C_EVENT:
      if (is_error_reported()) {
        // Ctrl-C is pressed during error reporting, likely because the error
        // handler fails to abort. Let VM die immediately.
        os::die();
      }

      os::signal_raise(SIGINT);
      return TRUE;
      break;
    case CTRL_BREAK_EVENT:
      if (sigbreakHandler != NULL) {
        (*sigbreakHandler)(SIGBREAK);
      }
      return TRUE;
      break;
    case CTRL_LOGOFF_EVENT: {
      // Don't terminate JVM if it is running in a non-interactive session,
      // such as a service process.
      USEROBJECTFLAGS flags;
      HANDLE handle = GetProcessWindowStation();
      if (handle != NULL &&
          GetUserObjectInformation(handle, UOI_FLAGS, &flags,
            sizeof( USEROBJECTFLAGS), NULL)) {
        // If it is a non-interactive session, let next handler to deal
        // with it.
        if ((flags.dwFlags & WSF_VISIBLE) == 0) {
          return FALSE;
        }
      }
    }
    case CTRL_CLOSE_EVENT:
    case CTRL_SHUTDOWN_EVENT:
      os::signal_raise(SIGTERM);
      return TRUE;
      break;
    default:
      break;
  }
  return FALSE;
}

/*
 * The following code is moved from os.cpp for making this
 * code platform specific, which it is by its very nature.
 */

// Return maximum OS signal used + 1 for internal use only
// Used as exit signal for signal_thread
int os::sigexitnum_pd(){
  return NSIG;
}

// a counter for each possible signal value, including signal_thread exit signal
static volatile jint pending_signals[NSIG+1] = { 0 };
static HANDLE sig_sem = NULL;

void os::signal_init_pd() {
  // Initialize signal structures
  memset((void*)pending_signals, 0, sizeof(pending_signals));

  sig_sem = ::CreateSemaphore(NULL, 0, NSIG+1, NULL);

  // Programs embedding the VM do not want it to attempt to receive
  // events like CTRL_LOGOFF_EVENT, which are used to implement the
  // shutdown hooks mechanism introduced in 1.3.  For example, when
  // the VM is run as part of a Windows NT service (i.e., a servlet
  // engine in a web server), the correct behavior is for any console
  // control handler to return FALSE, not TRUE, because the OS's
  // "final" handler for such events allows the process to continue if
  // it is a service (while terminating it if it is not a service).
  // To make this behavior uniform and the mechanism simpler, we
  // completely disable the VM's usage of these console events if -Xrs
  // (=ReduceSignalUsage) is specified.  This means, for example, that
  // the CTRL-BREAK thread dump mechanism is also disabled in this
  // case.  See bugs 4323062, 4345157, and related bugs.

  if (!ReduceSignalUsage) {
    // Add a CTRL-C handler
    SetConsoleCtrlHandler(consoleHandler, TRUE);
  }
}

void os::signal_notify(int signal_number) {
  BOOL ret;
  if (sig_sem != NULL) {
    Atomic::inc(&pending_signals[signal_number]);
    ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
    assert(ret != 0, "ReleaseSemaphore() failed");
  }
}

static int check_pending_signals(bool wait_for_signal) {
  DWORD ret;
  while (true) {
    for (int i = 0; i < NSIG + 1; i++) {
      jint n = pending_signals[i];
      if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
        return i;
      }
    }
    if (!wait_for_signal) {
      return -1;
    }

    JavaThread *thread = JavaThread::current();

    ThreadBlockInVM tbivm(thread);

    bool threadIsSuspended;
    do {
      thread->set_suspend_equivalent();
      // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
      ret = ::WaitForSingleObject(sig_sem, INFINITE);
      assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed");

      // were we externally suspended while we were waiting?
      threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
      if (threadIsSuspended) {
        //
        // The semaphore has been incremented, but while we were waiting
        // another thread suspended us. We don't want to continue running
        // while suspended because that would surprise the thread that
        // suspended us.
        //
        ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
        assert(ret != 0, "ReleaseSemaphore() failed");

        thread->java_suspend_self();
      }
    } while (threadIsSuspended);
  }
}

int os::signal_lookup() {
  return check_pending_signals(false);
}

int os::signal_wait() {
  return check_pending_signals(true);
}

// Implicit OS exception handling

LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
  JavaThread* thread = JavaThread::current();
  // Save pc in thread
#ifdef _M_IA64
  // Do not blow up if no thread info available.
  if (thread) {
    // Saving PRECISE pc (with slot information) in thread.
    uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;
    // Convert precise PC into "Unix" format
    precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);
    thread->set_saved_exception_pc((address)precise_pc);
  }
  // Set pc to handler
  exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
  // Clear out psr.ri (= Restart Instruction) in order to continue
  // at the beginning of the target bundle.
  exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;
  assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");
#else
  #ifdef _M_AMD64
  // Do not blow up if no thread info available.
  if (thread) {
    thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
  }
  // Set pc to handler
  exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
  #else
  // Do not blow up if no thread info available.
  if (thread) {
    thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
  }
  // Set pc to handler
  exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
  #endif
#endif

  // Continue the execution
  return EXCEPTION_CONTINUE_EXECUTION;
}


// Used for PostMortemDump
extern "C" void safepoints();
extern "C" void find(int x);
extern "C" void events();

// According to Windows API documentation, an illegal instruction sequence should generate
// the 0xC000001C exception code. However, real world experience shows that occasionnaly
// the execution of an illegal instruction can generate the exception code 0xC000001E. This
// seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).

#define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E

// From "Execution Protection in the Windows Operating System" draft 0.35
// Once a system header becomes available, the "real" define should be
// included or copied here.
#define EXCEPTION_INFO_EXEC_VIOLATION 0x08

// Handle NAT Bit consumption on IA64.
#ifdef _M_IA64
#define EXCEPTION_REG_NAT_CONSUMPTION    STATUS_REG_NAT_CONSUMPTION
#endif

// Windows Vista/2008 heap corruption check
#define EXCEPTION_HEAP_CORRUPTION        0xC0000374

#define def_excpt(val) #val, val

struct siglabel {
  char *name;
  int   number;
};

// All Visual C++ exceptions thrown from code generated by the Microsoft Visual
// C++ compiler contain this error code. Because this is a compiler-generated
// error, the code is not listed in the Win32 API header files.
// The code is actually a cryptic mnemonic device, with the initial "E"
// standing for "exception" and the final 3 bytes (0x6D7363) representing the
// ASCII values of "msc".

#define EXCEPTION_UNCAUGHT_CXX_EXCEPTION    0xE06D7363


struct siglabel exceptlabels[] = {
    def_excpt(EXCEPTION_ACCESS_VIOLATION),
    def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
    def_excpt(EXCEPTION_BREAKPOINT),
    def_excpt(EXCEPTION_SINGLE_STEP),
    def_excpt(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
    def_excpt(EXCEPTION_FLT_DENORMAL_OPERAND),
    def_excpt(EXCEPTION_FLT_DIVIDE_BY_ZERO),
    def_excpt(EXCEPTION_FLT_INEXACT_RESULT),
    def_excpt(EXCEPTION_FLT_INVALID_OPERATION),
    def_excpt(EXCEPTION_FLT_OVERFLOW),
    def_excpt(EXCEPTION_FLT_STACK_CHECK),
    def_excpt(EXCEPTION_FLT_UNDERFLOW),
    def_excpt(EXCEPTION_INT_DIVIDE_BY_ZERO),
    def_excpt(EXCEPTION_INT_OVERFLOW),
    def_excpt(EXCEPTION_PRIV_INSTRUCTION),
    def_excpt(EXCEPTION_IN_PAGE_ERROR),
    def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION),
    def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION_2),
    def_excpt(EXCEPTION_NONCONTINUABLE_EXCEPTION),
    def_excpt(EXCEPTION_STACK_OVERFLOW),
    def_excpt(EXCEPTION_INVALID_DISPOSITION),
    def_excpt(EXCEPTION_GUARD_PAGE),
    def_excpt(EXCEPTION_INVALID_HANDLE),
    def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
    def_excpt(EXCEPTION_HEAP_CORRUPTION),
#ifdef _M_IA64
    def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
#endif
    NULL, 0
};

const char* os::exception_name(int exception_code, char *buf, size_t size) {
  for (int i = 0; exceptlabels[i].name != NULL; i++) {
    if (exceptlabels[i].number == exception_code) {
       jio_snprintf(buf, size, "%s", exceptlabels[i].name);
       return buf;
    }
  }

  return NULL;
}

//-----------------------------------------------------------------------------
LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
  // handle exception caused by idiv; should only happen for -MinInt/-1
  // (division by zero is handled explicitly)
#ifdef _M_IA64
  assert(0, "Fix Handle_IDiv_Exception");
#else
  #ifdef  _M_AMD64
  PCONTEXT ctx = exceptionInfo->ContextRecord;
  address pc = (address)ctx->Rip;
  assert(pc[0] == 0xF7, "not an idiv opcode");
  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
  assert(ctx->Rax == min_jint, "unexpected idiv exception");
  // set correct result values and continue after idiv instruction
  ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
  ctx->Rax = (DWORD)min_jint;      // result
  ctx->Rdx = (DWORD)0;             // remainder
  // Continue the execution
  #else
  PCONTEXT ctx = exceptionInfo->ContextRecord;
  address pc = (address)ctx->Eip;
  assert(pc[0] == 0xF7, "not an idiv opcode");
  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
  assert(ctx->Eax == min_jint, "unexpected idiv exception");
  // set correct result values and continue after idiv instruction
  ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
  ctx->Eax = (DWORD)min_jint;      // result
  ctx->Edx = (DWORD)0;             // remainder
  // Continue the execution
  #endif
#endif
  return EXCEPTION_CONTINUE_EXECUTION;
}

#ifndef  _WIN64
//-----------------------------------------------------------------------------
LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
  // handle exception caused by native method modifying control word
  PCONTEXT ctx = exceptionInfo->ContextRecord;
  DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;

  switch (exception_code) {
    case EXCEPTION_FLT_DENORMAL_OPERAND:
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
    case EXCEPTION_FLT_INEXACT_RESULT:
    case EXCEPTION_FLT_INVALID_OPERATION:
    case EXCEPTION_FLT_OVERFLOW:
    case EXCEPTION_FLT_STACK_CHECK:
    case EXCEPTION_FLT_UNDERFLOW:
      jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
      if (fp_control_word != ctx->FloatSave.ControlWord) {
        // Restore FPCW and mask out FLT exceptions
        ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;
        // Mask out pending FLT exceptions
        ctx->FloatSave.StatusWord &=  0xffffff00;
        return EXCEPTION_CONTINUE_EXECUTION;
      }
  }

  if (prev_uef_handler != NULL) {
    // We didn't handle this exception so pass it to the previous
    // UnhandledExceptionFilter.
    return (prev_uef_handler)(exceptionInfo);
  }

  return EXCEPTION_CONTINUE_SEARCH;
}
#else //_WIN64
/*
  On Windows, the mxcsr control bits are non-volatile across calls
  See also CR 6192333
  If EXCEPTION_FLT_* happened after some native method modified
  mxcsr - it is not a jvm fault.
  However should we decide to restore of mxcsr after a faulty
  native method we can uncomment following code
      jint MxCsr = INITIAL_MXCSR;
        // we can't use StubRoutines::addr_mxcsr_std()
        // because in Win64 mxcsr is not saved there
      if (MxCsr != ctx->MxCsr) {
        ctx->MxCsr = MxCsr;
        return EXCEPTION_CONTINUE_EXECUTION;
      }

*/
#endif // _WIN64


static inline void report_error(Thread* t, DWORD exception_code,
                                address addr, void* siginfo, void* context) {
  VMError err(t, exception_code, addr, siginfo, context);
  err.report_and_die();

  // If UseOsErrorReporting, this will return here and save the error file
  // somewhere where we can find it in the minidump.
}

//-----------------------------------------------------------------------------
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
  if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
  DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
#ifdef _M_IA64
  // On Itanium, we need the "precise pc", which has the slot number coded
  // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).
  address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;
  // Convert the pc to "Unix format", which has the slot number coded
  // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2
  // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"
  // information is saved in the Unix format.
  address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));
#else
  #ifdef _M_AMD64
  address pc = (address) exceptionInfo->ContextRecord->Rip;
  #else
  address pc = (address) exceptionInfo->ContextRecord->Eip;
  #endif
#endif
  Thread* t = ThreadLocalStorage::get_thread_slow();          // slow & steady

  // Handle SafeFetch32 and SafeFetchN exceptions.
  if (StubRoutines::is_safefetch_fault(pc)) {
    return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
  }

#ifndef _WIN64
  // Execution protection violation - win32 running on AMD64 only
  // Handled first to avoid misdiagnosis as a "normal" access violation;
  // This is safe to do because we have a new/unique ExceptionInformation
  // code for this condition.
  if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
    PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
    int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
    address addr = (address) exceptionRecord->ExceptionInformation[1];

    if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
      int page_size = os::vm_page_size();

      // Make sure the pc and the faulting address are sane.
      //
      // If an instruction spans a page boundary, and the page containing
      // the beginning of the instruction is executable but the following
      // page is not, the pc and the faulting address might be slightly
      // different - we still want to unguard the 2nd page in this case.
      //
      // 15 bytes seems to be a (very) safe value for max instruction size.
      bool pc_is_near_addr =
        (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
      bool instr_spans_page_boundary =
        (align_size_down((intptr_t) pc ^ (intptr_t) addr,
                         (intptr_t) page_size) > 0);

      if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
        static volatile address last_addr =
          (address) os::non_memory_address_word();

        // In conservative mode, don't unguard unless the address is in the VM
        if (UnguardOnExecutionViolation > 0 && addr != last_addr &&
            (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {

          // Set memory to RWX and retry
          address page_start =
            (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
          bool res = os::protect_memory((char*) page_start, page_size,
                                        os::MEM_PROT_RWX);

          if (PrintMiscellaneous && Verbose) {
            char buf[256];
            jio_snprintf(buf, sizeof(buf), "Execution protection violation "
                         "at " INTPTR_FORMAT
                         ", unguarding " INTPTR_FORMAT ": %s", addr,
                         page_start, (res ? "success" : strerror(errno)));
            tty->print_raw_cr(buf);
          }

          // Set last_addr so if we fault again at the same address, we don't
          // end up in an endless loop.
          //
          // There are two potential complications here.  Two threads trapping
          // at the same address at the same time could cause one of the
          // threads to think it already unguarded, and abort the VM.  Likely
          // very rare.
          //
          // The other race involves two threads alternately trapping at
          // different addresses and failing to unguard the page, resulting in
          // an endless loop.  This condition is probably even more unlikely
          // than the first.
          //
          // Although both cases could be avoided by using locks or thread
          // local last_addr, these solutions are unnecessary complication:
          // this handler is a best-effort safety net, not a complete solution.
          // It is disabled by default and should only be used as a workaround
          // in case we missed any no-execute-unsafe VM code.

          last_addr = addr;

          return EXCEPTION_CONTINUE_EXECUTION;
        }
      }

      // Last unguard failed or not unguarding
      tty->print_raw_cr("Execution protection violation");
      report_error(t, exception_code, addr, exceptionInfo->ExceptionRecord,
                   exceptionInfo->ContextRecord);
      return EXCEPTION_CONTINUE_SEARCH;
    }
  }
#endif // _WIN64

  // Check to see if we caught the safepoint code in the
  // process of write protecting the memory serialization page.
  // It write enables the page immediately after protecting it
  // so just return.
  if ( exception_code == EXCEPTION_ACCESS_VIOLATION ) {
    JavaThread* thread = (JavaThread*) t;
    PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
    address addr = (address) exceptionRecord->ExceptionInformation[1];
    if ( os::is_memory_serialize_page(thread, addr) ) {
      // Block current thread until the memory serialize page permission restored.
      os::block_on_serialize_page_trap();
      return EXCEPTION_CONTINUE_EXECUTION;
    }
  }

  if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
      VM_Version::is_cpuinfo_segv_addr(pc)) {
    // Verify that OS save/restore AVX registers.
    return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());
  }

  if (t != NULL && t->is_Java_thread()) {
    JavaThread* thread = (JavaThread*) t;
    bool in_java = thread->thread_state() == _thread_in_Java;

    // Handle potential stack overflows up front.
    if (exception_code == EXCEPTION_STACK_OVERFLOW) {
      if (os::uses_stack_guard_pages()) {
#ifdef _M_IA64
        // Use guard page for register stack.
        PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
        address addr = (address) exceptionRecord->ExceptionInformation[1];
        // Check for a register stack overflow on Itanium
        if (thread->addr_inside_register_stack_red_zone(addr)) {
          // Fatal red zone violation happens if the Java program
          // catches a StackOverflow error and does so much processing
          // that it runs beyond the unprotected yellow guard zone. As
          // a result, we are out of here.
          fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit.");
        } else if(thread->addr_inside_register_stack(addr)) {
          // Disable the yellow zone which sets the state that
          // we've got a stack overflow problem.
          if (thread->stack_yellow_zone_enabled()) {
            thread->disable_stack_yellow_zone();
          }
          // Give us some room to process the exception.
          thread->disable_register_stack_guard();
          // Tracing with +Verbose.
          if (Verbose) {
            tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);
            tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);
            tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());
            tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",
                          thread->register_stack_base(),
                          thread->register_stack_base() + thread->stack_size());
          }

          // Reguard the permanent register stack red zone just to be sure.
          // We saw Windows silently disabling this without telling us.
          thread->enable_register_stack_red_zone();

          return Handle_Exception(exceptionInfo,
            SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
        }
#endif
        if (thread->stack_yellow_zone_enabled()) {
          // Yellow zone violation.  The o/s has unprotected the first yellow
          // zone page for us.  Note:  must call disable_stack_yellow_zone to
          // update the enabled status, even if the zone contains only one page.
          thread->disable_stack_yellow_zone();
          // If not in java code, return and hope for the best.
          return in_java ? Handle_Exception(exceptionInfo,
            SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
            :  EXCEPTION_CONTINUE_EXECUTION;
        } else {
          // Fatal red zone violation.
          thread->disable_stack_red_zone();
          tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
          report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                       exceptionInfo->ContextRecord);
          return EXCEPTION_CONTINUE_SEARCH;
        }
      } else if (in_java) {
        // JVM-managed guard pages cannot be used on win95/98.  The o/s provides
        // a one-time-only guard page, which it has released to us.  The next
        // stack overflow on this thread will result in an ACCESS_VIOLATION.
        return Handle_Exception(exceptionInfo,
          SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
      } else {
        // Can only return and hope for the best.  Further stack growth will
        // result in an ACCESS_VIOLATION.
        return EXCEPTION_CONTINUE_EXECUTION;
      }
    } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
      // Either stack overflow or null pointer exception.
      if (in_java) {
        PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
        address addr = (address) exceptionRecord->ExceptionInformation[1];
        address stack_end = thread->stack_base() - thread->stack_size();
        if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {
          // Stack overflow.
          assert(!os::uses_stack_guard_pages(),
            "should be caught by red zone code above.");
          return Handle_Exception(exceptionInfo,
            SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
        }
        //
        // Check for safepoint polling and implicit null
        // We only expect null pointers in the stubs (vtable)
        // the rest are checked explicitly now.
        //
        CodeBlob* cb = CodeCache::find_blob(pc);
        if (cb != NULL) {
          if (os::is_poll_address(addr)) {
            address stub = SharedRuntime::get_poll_stub(pc);
            return Handle_Exception(exceptionInfo, stub);
          }
        }
        {
#ifdef _WIN64
          //
          // If it's a legal stack address map the entire region in
          //
          PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
          address addr = (address) exceptionRecord->ExceptionInformation[1];
          if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
                  addr = (address)((uintptr_t)addr &
                         (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
                  os::commit_memory((char *)addr, thread->stack_base() - addr,
                                    !ExecMem);
                  return EXCEPTION_CONTINUE_EXECUTION;
          }
          else
#endif
          {
            // Null pointer exception.
#ifdef _M_IA64
            // Process implicit null checks in compiled code. Note: Implicit null checks
            // can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs.
            if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) {
              CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format);
              // Handle implicit null check in UEP method entry
              if (cb && (cb->is_frame_complete_at(pc) ||
                         (cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) {
                if (Verbose) {
                  intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0);
                  tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format);
                  tty->print_cr("      to addr " INTPTR_FORMAT, addr);
                  tty->print_cr("      bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)",
                                *(bundle_start + 1), *bundle_start);
                }
                return Handle_Exception(exceptionInfo,
                  SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL));
              }
            }

            // Implicit null checks were processed above.  Hence, we should not reach
            // here in the usual case => die!
            if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception");
            report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                         exceptionInfo->ContextRecord);
            return EXCEPTION_CONTINUE_SEARCH;

#else // !IA64

            // Windows 98 reports faulting addresses incorrectly
            if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
                !os::win32::is_nt()) {
              address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
              if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
            }
            report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                         exceptionInfo->ContextRecord);
            return EXCEPTION_CONTINUE_SEARCH;
#endif
          }
        }
      }

#ifdef _WIN64
      // Special care for fast JNI field accessors.
      // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks
      // in and the heap gets shrunk before the field access.
      if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
        address addr = JNI_FastGetField::find_slowcase_pc(pc);
        if (addr != (address)-1) {
          return Handle_Exception(exceptionInfo, addr);
        }
      }
#endif

      // Stack overflow or null pointer exception in native code.
      report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                   exceptionInfo->ContextRecord);
      return EXCEPTION_CONTINUE_SEARCH;
    } // /EXCEPTION_ACCESS_VIOLATION
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if defined _M_IA64
    else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
              exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
      M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0);

      // Compiled method patched to be non entrant? Following conditions must apply:
      // 1. must be first instruction in bundle
      // 2. must be a break instruction with appropriate code
      if((((uint64_t) pc & 0x0F) == 0) &&
         (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {
        return Handle_Exception(exceptionInfo,
                                (address)SharedRuntime::get_handle_wrong_method_stub());
      }
    } // /EXCEPTION_ILLEGAL_INSTRUCTION
#endif


    if (in_java) {
      switch (exception_code) {
      case EXCEPTION_INT_DIVIDE_BY_ZERO:
        return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));

      case EXCEPTION_INT_OVERFLOW:
        return Handle_IDiv_Exception(exceptionInfo);

      } // switch
    }
#ifndef _WIN64
    if (((thread->thread_state() == _thread_in_Java) ||
        (thread->thread_state() == _thread_in_native)) &&
        exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION)
    {
      LONG result=Handle_FLT_Exception(exceptionInfo);
      if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
    }
#endif //_WIN64
  }

  if (exception_code != EXCEPTION_BREAKPOINT) {
    report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                 exceptionInfo->ContextRecord);
  }
  return EXCEPTION_CONTINUE_SEARCH;
}

#ifndef _WIN64
// Special care for fast JNI accessors.
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
// the heap gets shrunk before the field access.
// Need to install our own structured exception handler since native code may
// install its own.
LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
  DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
  if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
    address pc = (address) exceptionInfo->ContextRecord->Eip;
    address addr = JNI_FastGetField::find_slowcase_pc(pc);
    if (addr != (address)-1) {
      return Handle_Exception(exceptionInfo, addr);
    }
  }
  return EXCEPTION_CONTINUE_SEARCH;
}

#define DEFINE_FAST_GETFIELD(Return,Fieldname,Result) \
Return JNICALL jni_fast_Get##Result##Field_wrapper(JNIEnv *env, jobject obj, jfieldID fieldID) { \
  __try { \
    return (*JNI_FastGetField::jni_fast_Get##Result##Field_fp)(env, obj, fieldID); \
  } __except(fastJNIAccessorExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { \
  } \
  return 0; \
}

DEFINE_FAST_GETFIELD(jboolean, bool,   Boolean)
DEFINE_FAST_GETFIELD(jbyte,    byte,   Byte)
DEFINE_FAST_GETFIELD(jchar,    char,   Char)
DEFINE_FAST_GETFIELD(jshort,   short,  Short)
DEFINE_FAST_GETFIELD(jint,     int,    Int)
DEFINE_FAST_GETFIELD(jlong,    long,   Long)
DEFINE_FAST_GETFIELD(jfloat,   float,  Float)
DEFINE_FAST_GETFIELD(jdouble,  double, Double)

address os::win32::fast_jni_accessor_wrapper(BasicType type) {
  switch (type) {
    case T_BOOLEAN: return (address)jni_fast_GetBooleanField_wrapper;
    case T_BYTE:    return (address)jni_fast_GetByteField_wrapper;
    case T_CHAR:    return (address)jni_fast_GetCharField_wrapper;
    case T_SHORT:   return (address)jni_fast_GetShortField_wrapper;
    case T_INT:     return (address)jni_fast_GetIntField_wrapper;
    case T_LONG:    return (address)jni_fast_GetLongField_wrapper;
    case T_FLOAT:   return (address)jni_fast_GetFloatField_wrapper;
    case T_DOUBLE:  return (address)jni_fast_GetDoubleField_wrapper;
    default:        ShouldNotReachHere();
  }
  return (address)-1;
}
#endif

void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {
  // Install a win32 structured exception handler around the test
  // function call so the VM can generate an error dump if needed.
  __try {
    (*funcPtr)();
  } __except(topLevelExceptionFilter(
             (_EXCEPTION_POINTERS*)_exception_info())) {
    // Nothing to do.
  }
}

// Virtual Memory

int os::vm_page_size() { return os::win32::vm_page_size(); }
int os::vm_allocation_granularity() {
  return os::win32::vm_allocation_granularity();
}

// Windows large page support is available on Windows 2003. In order to use
// large page memory, the administrator must first assign additional privilege
// to the user:
//   + select Control Panel -> Administrative Tools -> Local Security Policy
//   + select Local Policies -> User Rights Assignment
//   + double click "Lock pages in memory", add users and/or groups
//   + reboot
// Note the above steps are needed for administrator as well, as administrators
// by default do not have the privilege to lock pages in memory.
//
// Note about Windows 2003: although the API supports committing large page
// memory on a page-by-page basis and VirtualAlloc() returns success under this
// scenario, I found through experiment it only uses large page if the entire
// memory region is reserved and committed in a single VirtualAlloc() call.
// This makes Windows large page support more or less like Solaris ISM, in
// that the entire heap must be committed upfront. This probably will change
// in the future, if so the code below needs to be revisited.

#ifndef MEM_LARGE_PAGES
#define MEM_LARGE_PAGES 0x20000000
#endif

static HANDLE    _hProcess;
static HANDLE    _hToken;

// Container for NUMA node list info
class NUMANodeListHolder {
private:
  int *_numa_used_node_list;  // allocated below
  int _numa_used_node_count;

  void free_node_list() {
    if (_numa_used_node_list != NULL) {
      FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal);
    }
  }

public:
  NUMANodeListHolder() {
    _numa_used_node_count = 0;
    _numa_used_node_list = NULL;
    // do rest of initialization in build routine (after function pointers are set up)
  }

  ~NUMANodeListHolder() {
    free_node_list();
  }

  bool build() {
    DWORD_PTR proc_aff_mask;
    DWORD_PTR sys_aff_mask;
    if (!GetProcessAffinityMask(GetCurrentProcess(), &proc_aff_mask, &sys_aff_mask)) return false;
    ULONG highest_node_number;
    if (!os::Kernel32Dll::GetNumaHighestNodeNumber(&highest_node_number)) return false;
    free_node_list();
    _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1, mtInternal);
    for (unsigned int i = 0; i <= highest_node_number; i++) {
      ULONGLONG proc_mask_numa_node;
      if (!os::Kernel32Dll::GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;
      if ((proc_aff_mask & proc_mask_numa_node)!=0) {
        _numa_used_node_list[_numa_used_node_count++] = i;
      }
    }
    return (_numa_used_node_count > 1);
  }

  int get_count() {return _numa_used_node_count;}
  int get_node_list_entry(int n) {
    // for indexes out of range, returns -1
    return (n < _numa_used_node_count ? _numa_used_node_list[n] : -1);
  }

} numa_node_list_holder;



static size_t _large_page_size = 0;

static bool resolve_functions_for_large_page_init() {
  return os::Kernel32Dll::GetLargePageMinimumAvailable() &&
    os::Advapi32Dll::AdvapiAvailable();
}

static bool request_lock_memory_privilege() {
  _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
                                os::current_process_id());

  LUID luid;
  if (_hProcess != NULL &&
      os::Advapi32Dll::OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) &&
      os::Advapi32Dll::LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) {

    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    // AdjustTokenPrivileges() may return TRUE even when it couldn't change the
    // privilege. Check GetLastError() too. See MSDN document.
    if (os::Advapi32Dll::AdjustTokenPrivileges(_hToken, false, &tp, sizeof(tp), NULL, NULL) &&
        (GetLastError() == ERROR_SUCCESS)) {
      return true;
    }
  }

  return false;
}

static void cleanup_after_large_page_init() {
  if (_hProcess) CloseHandle(_hProcess);
  _hProcess = NULL;
  if (_hToken) CloseHandle(_hToken);
  _hToken = NULL;
}

static bool numa_interleaving_init() {
  bool success = false;
  bool use_numa_interleaving_specified = !FLAG_IS_DEFAULT(UseNUMAInterleaving);

  // print a warning if UseNUMAInterleaving flag is specified on command line
  bool warn_on_failure = use_numa_interleaving_specified;
# define WARN(msg) if (warn_on_failure) { warning(msg); }

  // NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages)
  size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity();
  NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity);

  if (os::Kernel32Dll::NumaCallsAvailable()) {
    if (numa_node_list_holder.build()) {
      if (PrintMiscellaneous && Verbose) {
        tty->print("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());
        for (int i = 0; i < numa_node_list_holder.get_count(); i++) {
          tty->print("%d ", numa_node_list_holder.get_node_list_entry(i));
        }
        tty->print("\n");
      }
      success = true;
    } else {
      WARN("Process does not cover multiple NUMA nodes.");
    }
  } else {
    WARN("NUMA Interleaving is not supported by the operating system.");
  }
  if (!success) {
    if (use_numa_interleaving_specified) WARN("...Ignoring UseNUMAInterleaving flag.");
  }
  return success;
#undef WARN
}

// this routine is used whenever we need to reserve a contiguous VA range
// but we need to make separate VirtualAlloc calls for each piece of the range
// Reasons for doing this:
//  * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise)
//  * UseNUMAInterleaving requires a separate node for each piece
static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, DWORD prot,
                                         bool should_inject_error=false) {
  char * p_buf;
  // note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size
  size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity();
  size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size;

  // first reserve enough address space in advance since we want to be
  // able to break a single contiguous virtual address range into multiple
  // large page commits but WS2003 does not allow reserving large page space
  // so we just use 4K pages for reserve, this gives us a legal contiguous
  // address space. then we will deallocate that reservation, and re alloc
  // using large pages
  const size_t size_of_reserve = bytes + chunk_size;
  if (bytes > size_of_reserve) {
    // Overflowed.
    return NULL;
  }
  p_buf = (char *) VirtualAlloc(addr,
                                size_of_reserve,  // size of Reserve
                                MEM_RESERVE,
                                PAGE_READWRITE);
  // If reservation failed, return NULL
  if (p_buf == NULL) return NULL;
  MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);
  os::release_memory(p_buf, bytes + chunk_size);

  // we still need to round up to a page boundary (in case we are using large pages)
  // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size)
  // instead we handle this in the bytes_to_rq computation below
  p_buf = (char *) align_size_up((size_t)p_buf, page_size);

  // now go through and allocate one chunk at a time until all bytes are
  // allocated
  size_t  bytes_remaining = bytes;
  // An overflow of align_size_up() would have been caught above
  // in the calculation of size_of_reserve.
  char * next_alloc_addr = p_buf;
  HANDLE hProc = GetCurrentProcess();

#ifdef ASSERT
  // Variable for the failure injection
  long ran_num = os::random();
  size_t fail_after = ran_num % bytes;
#endif

  int count=0;
  while (bytes_remaining) {
    // select bytes_to_rq to get to the next chunk_size boundary

    size_t bytes_to_rq = MIN2(bytes_remaining, chunk_size - ((size_t)next_alloc_addr % chunk_size));
    // Note allocate and commit
    char * p_new;

#ifdef ASSERT
    bool inject_error_now = should_inject_error && (bytes_remaining <= fail_after);
#else
    const bool inject_error_now = false;
#endif

    if (inject_error_now) {
      p_new = NULL;
    } else {
      if (!UseNUMAInterleaving) {
        p_new = (char *) VirtualAlloc(next_alloc_addr,
                                      bytes_to_rq,
                                      flags,
                                      prot);
      } else {
        // get the next node to use from the used_node_list
        assert(numa_node_list_holder.get_count() > 0, "Multiple NUMA nodes expected");
        DWORD node = numa_node_list_holder.get_node_list_entry(count % numa_node_list_holder.get_count());
        p_new = (char *)os::Kernel32Dll::VirtualAllocExNuma(hProc,
                                                            next_alloc_addr,
                                                            bytes_to_rq,
                                                            flags,
                                                            prot,
                                                            node);
      }
    }

    if (p_new == NULL) {
      // Free any allocated pages
      if (next_alloc_addr > p_buf) {
        // Some memory was committed so release it.
        size_t bytes_to_release = bytes - bytes_remaining;
        // NMT has yet to record any individual blocks, so it
        // need to create a dummy 'reserve' record to match
        // the release.
        MemTracker::record_virtual_memory_reserve((address)p_buf,
          bytes_to_release, CALLER_PC);
        os::release_memory(p_buf, bytes_to_release);
      }
#ifdef ASSERT
      if (should_inject_error) {
        if (TracePageSizes && Verbose) {
          tty->print_cr("Reserving pages individually failed.");
        }
      }
#endif
      return NULL;
    }

    bytes_remaining -= bytes_to_rq;
    next_alloc_addr += bytes_to_rq;
    count++;
  }
  // Although the memory is allocated individually, it is returned as one.
  // NMT records it as one block.
  if ((flags & MEM_COMMIT) != 0) {
    MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, CALLER_PC);
  } else {
    MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, CALLER_PC);
  }

  // made it this far, success
  return p_buf;
}



void os::large_page_init() {
  if (!UseLargePages) return;

  // print a warning if any large page related flag is specified on command line
  bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||
                         !FLAG_IS_DEFAULT(LargePageSizeInBytes);
  bool success = false;

# define WARN(msg) if (warn_on_failure) { warning(msg); }
  if (resolve_functions_for_large_page_init()) {
    if (request_lock_memory_privilege()) {
      size_t s = os::Kernel32Dll::GetLargePageMinimum();
      if (s) {
#if defined(IA32) || defined(AMD64)
        if (s > 4*M || LargePageSizeInBytes > 4*M) {
          WARN("JVM cannot use large pages bigger than 4mb.");
        } else {
#endif
          if (LargePageSizeInBytes && LargePageSizeInBytes % s == 0) {
            _large_page_size = LargePageSizeInBytes;
          } else {
            _large_page_size = s;
          }
          success = true;
#if defined(IA32) || defined(AMD64)
        }
#endif
      } else {
        WARN("Large page is not supported by the processor.");
      }
    } else {
      WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory.");
    }
  } else {
    WARN("Large page is not supported by the operating system.");
  }
#undef WARN

  const size_t default_page_size = (size_t) vm_page_size();
  if (success && _large_page_size > default_page_size) {
    _page_sizes[0] = _large_page_size;
    _page_sizes[1] = default_page_size;
    _page_sizes[2] = 0;
  }

  cleanup_after_large_page_init();
  UseLargePages = success;
}

// On win32, one cannot release just a part of reserved memory, it's an
// all or nothing deal.  When we split a reservation, we must break the
// reservation into two reservations.
void os::pd_split_reserved_memory(char *base, size_t size, size_t split,
                              bool realloc) {
  if (size > 0) {
    release_memory(base, size);
    if (realloc) {
      reserve_memory(split, base);
    }
    if (size != split) {
      reserve_memory(size - split, base + split);
    }
  }
}

// Multiple threads can race in this code but it's not possible to unmap small sections of
// virtual space to get requested alignment, like posix-like os's.
// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
char* os::reserve_memory_aligned(size_t size, size_t alignment) {
  assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
      "Alignment must be a multiple of allocation granularity (page size)");
  assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");

  size_t extra_size = size + alignment;
  assert(extra_size >= size, "overflow, size is too large to allow alignment");

  char* aligned_base = NULL;

  do {
    char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
    if (extra_base == NULL) {
      return NULL;
    }
    // Do manual alignment
    aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);

    os::release_memory(extra_base, extra_size);

    aligned_base = os::reserve_memory(size, aligned_base);

  } while (aligned_base == NULL);

  return aligned_base;
}

char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
  assert((size_t)addr % os::vm_allocation_granularity() == 0,
         "reserve alignment");
  assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
  char* res;
  // note that if UseLargePages is on, all the areas that require interleaving
  // will go thru reserve_memory_special rather than thru here.
  bool use_individual = (UseNUMAInterleaving && !UseLargePages);
  if (!use_individual) {
    res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
  } else {
    elapsedTimer reserveTimer;
    if( Verbose && PrintMiscellaneous ) reserveTimer.start();
    // in numa interleaving, we have to allocate pages individually
    // (well really chunks of NUMAInterleaveGranularity size)
    res = allocate_pages_individually(bytes, addr, MEM_RESERVE, PAGE_READWRITE);
    if (res == NULL) {
      warning("NUMA page allocation failed");
    }
    if( Verbose && PrintMiscellaneous ) {
      reserveTimer.stop();
      tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,
                    reserveTimer.milliseconds(), reserveTimer.ticks());
    }
  }
  assert(res == NULL || addr == NULL || addr == res,
         "Unexpected address from reserve.");

  return res;
}

// Reserve memory at an arbitrary address, only if that area is
// available (and not reserved for something else).
char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
  // Windows os::reserve_memory() fails of the requested address range is
  // not avilable.
  return reserve_memory(bytes, requested_addr);
}

size_t os::large_page_size() {
  return _large_page_size;
}

bool os::can_commit_large_page_memory() {
  // Windows only uses large page memory when the entire region is reserved
  // and committed in a single VirtualAlloc() call. This may change in the
  // future, but with Windows 2003 it's not possible to commit on demand.
  return false;
}

bool os::can_execute_large_page_memory() {
  return true;
}

char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, bool exec) {
  assert(UseLargePages, "only for large pages");

  if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
    return NULL; // Fallback to small pages.
  }

  const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
  const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;

  // with large pages, there are two cases where we need to use Individual Allocation
  // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)
  // 2) NUMA Interleaving is enabled, in which case we use a different node for each page
  if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {
    if (TracePageSizes && Verbose) {
       tty->print_cr("Reserving large pages individually.");
    }
    char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);
    if (p_buf == NULL) {
      // give an appropriate warning message
      if (UseNUMAInterleaving) {
        warning("NUMA large page allocation failed, UseLargePages flag ignored");
      }
      if (UseLargePagesIndividualAllocation) {
        warning("Individually allocated large pages failed, "
                "use -XX:-UseLargePagesIndividualAllocation to turn off");
      }
      return NULL;
    }

    return p_buf;

  } else {
    if (TracePageSizes && Verbose) {
       tty->print_cr("Reserving large pages in a single large chunk.");
    }
    // normal policy just allocate it all at once
    DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
    char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
    if (res != NULL) {
      MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, CALLER_PC);
    }

    return res;
  }
}

bool os::release_memory_special(char* base, size_t bytes) {
  assert(base != NULL, "Sanity check");
  return release_memory(base, bytes);
}

void os::print_statistics() {
}

static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) {
  int err = os::get_last_error();
  char buf[256];
  size_t buf_len = os::lasterror(buf, sizeof(buf));
  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
          ", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes,
          exec, buf_len != 0 ? buf : "<no_error_string>", err);
}

bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
  if (bytes == 0) {
    // Don't bother the OS with noops.
    return true;
  }
  assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");
  assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
  // Don't attempt to print anything if the OS call fails. We're
  // probably low on resources, so the print itself may cause crashes.

  // unless we have NUMAInterleaving enabled, the range of a commit
  // is always within a reserve covered by a single VirtualAlloc
  // in that case we can just do a single commit for the requested size
  if (!UseNUMAInterleaving) {
    if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) {
      NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
      return false;
    }
    if (exec) {
      DWORD oldprot;
      // Windows doc says to use VirtualProtect to get execute permissions
      if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) {
        NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
        return false;
      }
    }
    return true;
  } else {

    // when NUMAInterleaving is enabled, the commit might cover a range that
    // came from multiple VirtualAlloc reserves (using allocate_pages_individually).
    // VirtualQuery can help us determine that.  The RegionSize that VirtualQuery
    // returns represents the number of bytes that can be committed in one step.
    size_t bytes_remaining = bytes;
    char * next_alloc_addr = addr;
    while (bytes_remaining > 0) {
      MEMORY_BASIC_INFORMATION alloc_info;
      VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));
      size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
      if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT,
                       PAGE_READWRITE) == NULL) {
        NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
                                            exec);)
        return false;
      }
      if (exec) {
        DWORD oldprot;
        if (!VirtualProtect(next_alloc_addr, bytes_to_rq,
                            PAGE_EXECUTE_READWRITE, &oldprot)) {
          NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
                                              exec);)
          return false;
        }
      }
      bytes_remaining -= bytes_to_rq;
      next_alloc_addr += bytes_to_rq;
    }
  }
  // if we made it this far, return true
  return true;
}

bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                       bool exec) {
  // alignment_hint is ignored on this OS
  return pd_commit_memory(addr, size, exec);
}

void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
                                  const char* mesg) {
  assert(mesg != NULL, "mesg must be specified");
  if (!pd_commit_memory(addr, size, exec)) {
    warn_fail_commit_memory(addr, size, exec);
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
  }
}

void os::pd_commit_memory_or_exit(char* addr, size_t size,
                                  size_t alignment_hint, bool exec,
                                  const char* mesg) {
  // alignment_hint is ignored on this OS
  pd_commit_memory_or_exit(addr, size, exec, mesg);
}

bool os::pd_uncommit_memory(char* addr, size_t bytes) {
  if (bytes == 0) {
    // Don't bother the OS with noops.
    return true;
  }
  assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
  assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
  return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
}

bool os::pd_release_memory(char* addr, size_t bytes) {
  return VirtualFree(addr, 0, MEM_RELEASE) != 0;
}

bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
  return os::commit_memory(addr, size, !ExecMem);
}

bool os::remove_stack_guard_pages(char* addr, size_t size) {
  return os::uncommit_memory(addr, size);
}

// Set protections specified
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
                        bool is_committed) {
  unsigned int p = 0;
  switch (prot) {
  case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
  case MEM_PROT_READ: p = PAGE_READONLY; break;
  case MEM_PROT_RW:   p = PAGE_READWRITE; break;
  case MEM_PROT_RWX:  p = PAGE_EXECUTE_READWRITE; break;
  default:
    ShouldNotReachHere();
  }

  DWORD old_status;

  // Strange enough, but on Win32 one can change protection only for committed
  // memory, not a big deal anyway, as bytes less or equal than 64K
  if (!is_committed) {
    commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
                          "cannot commit protection page");
  }
  // One cannot use os::guard_memory() here, as on Win32 guard page
  // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
  //
  // Pages in the region become guard pages. Any attempt to access a guard page
  // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
  // the guard page status. Guard pages thus act as a one-time access alarm.
  return VirtualProtect(addr, bytes, p, &old_status) != 0;
}

bool os::guard_memory(char* addr, size_t bytes) {
  DWORD old_status;
  return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;
}

bool os::unguard_memory(char* addr, size_t bytes) {
  DWORD old_status;
  return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
}

void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }
void os::numa_make_global(char *addr, size_t bytes)    { }
void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
bool os::numa_topology_changed()                       { return false; }
size_t os::numa_get_groups_num()                       { return MAX2(numa_node_list_holder.get_count(), 1); }
int os::numa_get_group_id()                            { return 0; }
size_t os::numa_get_leaf_groups(int *ids, size_t size) {
  if (numa_node_list_holder.get_count() == 0 && size > 0) {
    // Provide an answer for UMA systems
    ids[0] = 0;
    return 1;
  } else {
    // check for size bigger than actual groups_num
    size = MIN2(size, numa_get_groups_num());
    for (int i = 0; i < (int)size; i++) {
      ids[i] = numa_node_list_holder.get_node_list_entry(i);
    }
    return size;
  }
}

bool os::get_page_info(char *start, page_info* info) {
  return false;
}

char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
  return end;
}

char* os::non_memory_address_word() {
  // Must never look like an address returned by reserve_memory,
  // even in its subfields (as defined by the CPU immediate fields,
  // if the CPU splits constants across multiple instructions).
  return (char*)-1;
}

#define MAX_ERROR_COUNT 100
#define SYS_THREAD_ERROR 0xffffffffUL

void os::pd_start_thread(Thread* thread) {
  DWORD ret = ResumeThread(thread->osthread()->thread_handle());
  // Returns previous suspend state:
  // 0:  Thread was not suspended
  // 1:  Thread is running now
  // >1: Thread is still suspended.
  assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back
}

class HighResolutionInterval : public CHeapObj<mtThread> {
  // The default timer resolution seems to be 10 milliseconds.
  // (Where is this written down?)
  // If someone wants to sleep for only a fraction of the default,
  // then we set the timer resolution down to 1 millisecond for
  // the duration of their interval.
  // We carefully set the resolution back, since otherwise we
  // seem to incur an overhead (3%?) that we don't need.
  // CONSIDER: if ms is small, say 3, then we should run with a high resolution time.
  // Buf if ms is large, say 500, or 503, we should avoid the call to timeBeginPeriod().
  // Alternatively, we could compute the relative error (503/500 = .6%) and only use
  // timeBeginPeriod() if the relative error exceeded some threshold.
  // timeBeginPeriod() has been linked to problems with clock drift on win32 systems and
  // to decreased efficiency related to increased timer "tick" rates.  We want to minimize
  // (a) calls to timeBeginPeriod() and timeEndPeriod() and (b) time spent with high
  // resolution timers running.
private:
    jlong resolution;
public:
  HighResolutionInterval(jlong ms) {
    resolution = ms % 10L;
    if (resolution != 0) {
      MMRESULT result = timeBeginPeriod(1L);
    }
  }
  ~HighResolutionInterval() {
    if (resolution != 0) {
      MMRESULT result = timeEndPeriod(1L);
    }
    resolution = 0L;
  }
};

int os::sleep(Thread* thread, jlong ms, bool interruptable) {
  jlong limit = (jlong) MAXDWORD;

  while(ms > limit) {
    int res;
    if ((res = sleep(thread, limit, interruptable)) != OS_TIMEOUT)
      return res;
    ms -= limit;
  }

  assert(thread == Thread::current(),  "thread consistency check");
  OSThread* osthread = thread->osthread();
  OSThreadWaitState osts(osthread, false /* not Object.wait() */);
  int result;
  if (interruptable) {
    assert(thread->is_Java_thread(), "must be java thread");
    JavaThread *jt = (JavaThread *) thread;
    ThreadBlockInVM tbivm(jt);

    jt->set_suspend_equivalent();
    // cleared by handle_special_suspend_equivalent_condition() or
    // java_suspend_self() via check_and_wait_while_suspended()

    HANDLE events[1];
    events[0] = osthread->interrupt_event();
    HighResolutionInterval *phri=NULL;
    if(!ForceTimeHighResolution)
      phri = new HighResolutionInterval( ms );
    if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) {
      result = OS_TIMEOUT;
    } else {
      ResetEvent(osthread->interrupt_event());
      osthread->set_interrupted(false);
      result = OS_INTRPT;
    }
    delete phri; //if it is NULL, harmless

    // were we externally suspended while we were waiting?
    jt->check_and_wait_while_suspended();
  } else {
    assert(!thread->is_Java_thread(), "must not be java thread");
    Sleep((long) ms);
    result = OS_TIMEOUT;
  }
  return result;
}

//
// Short sleep, direct OS call.
//
// ms = 0, means allow others (if any) to run.
//
void os::naked_short_sleep(jlong ms) {
  assert(ms < 1000, "Un-interruptable sleep, short time use only");
  Sleep(ms);
}

// Sleep forever; naked call to OS-specific sleep; use with CAUTION
void os::infinite_sleep() {
  while (true) {    // sleep forever ...
    Sleep(100000);  // ... 100 seconds at a time
  }
}

typedef BOOL (WINAPI * STTSignature)(void) ;

os::YieldResult os::NakedYield() {
  // Use either SwitchToThread() or Sleep(0)
  // Consider passing back the return value from SwitchToThread().
  if (os::Kernel32Dll::SwitchToThreadAvailable()) {
    return SwitchToThread() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
  } else {
    Sleep(0);
  }
  return os::YIELD_UNKNOWN ;
}

void os::yield() {  os::NakedYield(); }

void os::yield_all(int attempts) {
  // Yields to all threads, including threads with lower priorities
  Sleep(1);
}

// Win32 only gives you access to seven real priorities at a time,
// so we compress Java's ten down to seven.  It would be better
// if we dynamically adjusted relative priorities.

int os::java_to_os_priority[CriticalPriority + 1] = {
  THREAD_PRIORITY_IDLE,                         // 0  Entry should never be used
  THREAD_PRIORITY_LOWEST,                       // 1  MinPriority
  THREAD_PRIORITY_LOWEST,                       // 2
  THREAD_PRIORITY_BELOW_NORMAL,                 // 3
  THREAD_PRIORITY_BELOW_NORMAL,                 // 4
  THREAD_PRIORITY_NORMAL,                       // 5  NormPriority
  THREAD_PRIORITY_NORMAL,                       // 6
  THREAD_PRIORITY_ABOVE_NORMAL,                 // 7
  THREAD_PRIORITY_ABOVE_NORMAL,                 // 8
  THREAD_PRIORITY_HIGHEST,                      // 9  NearMaxPriority
  THREAD_PRIORITY_HIGHEST,                      // 10 MaxPriority
  THREAD_PRIORITY_HIGHEST                       // 11 CriticalPriority
};

int prio_policy1[CriticalPriority + 1] = {
  THREAD_PRIORITY_IDLE,                         // 0  Entry should never be used
  THREAD_PRIORITY_LOWEST,                       // 1  MinPriority
  THREAD_PRIORITY_LOWEST,                       // 2
  THREAD_PRIORITY_BELOW_NORMAL,                 // 3
  THREAD_PRIORITY_BELOW_NORMAL,                 // 4
  THREAD_PRIORITY_NORMAL,                       // 5  NormPriority
  THREAD_PRIORITY_ABOVE_NORMAL,                 // 6
  THREAD_PRIORITY_ABOVE_NORMAL,                 // 7
  THREAD_PRIORITY_HIGHEST,                      // 8
  THREAD_PRIORITY_HIGHEST,                      // 9  NearMaxPriority
  THREAD_PRIORITY_TIME_CRITICAL,                // 10 MaxPriority
  THREAD_PRIORITY_TIME_CRITICAL                 // 11 CriticalPriority
};

static int prio_init() {
  // If ThreadPriorityPolicy is 1, switch tables
  if (ThreadPriorityPolicy == 1) {
    int i;
    for (i = 0; i < CriticalPriority + 1; i++) {
      os::java_to_os_priority[i] = prio_policy1[i];
    }
  }
  if (UseCriticalJavaThreadPriority) {
    os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority] ;
  }
  return 0;
}

OSReturn os::set_native_priority(Thread* thread, int priority) {
  if (!UseThreadPriorities) return OS_OK;
  bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0;
  return ret ? OS_OK : OS_ERR;
}

OSReturn os::get_native_priority(const Thread* const thread, int* priority_ptr) {
  if ( !UseThreadPriorities ) {
    *priority_ptr = java_to_os_priority[NormPriority];
    return OS_OK;
  }
  int os_prio = GetThreadPriority(thread->osthread()->thread_handle());
  if (os_prio == THREAD_PRIORITY_ERROR_RETURN) {
    assert(false, "GetThreadPriority failed");
    return OS_ERR;
  }
  *priority_ptr = os_prio;
  return OS_OK;
}


// Hint to the underlying OS that a task switch would not be good.
// Void return because it's a hint and can fail.
void os::hint_no_preempt() {}

void os::interrupt(Thread* thread) {
  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
         "possibility of dangling Thread pointer");

  OSThread* osthread = thread->osthread();
  osthread->set_interrupted(true);
  // More than one thread can get here with the same value of osthread,
  // resulting in multiple notifications.  We do, however, want the store
  // to interrupted() to be visible to other threads before we post
  // the interrupt event.
  OrderAccess::release();
  SetEvent(osthread->interrupt_event());
  // For JSR166:  unpark after setting status
  if (thread->is_Java_thread())
    ((JavaThread*)thread)->parker()->unpark();

  ParkEvent * ev = thread->_ParkEvent ;
  if (ev != NULL) ev->unpark() ;

}


bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
         "possibility of dangling Thread pointer");

  OSThread* osthread = thread->osthread();
  // There is no synchronization between the setting of the interrupt
  // and it being cleared here. It is critical - see 6535709 - that
  // we only clear the interrupt state, and reset the interrupt event,
  // if we are going to report that we were indeed interrupted - else
  // an interrupt can be "lost", leading to spurious wakeups or lost wakeups
  // depending on the timing. By checking thread interrupt event to see
  // if the thread gets real interrupt thus prevent spurious wakeup.
  bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0);
  if (interrupted && clear_interrupted) {
    osthread->set_interrupted(false);
    ResetEvent(osthread->interrupt_event());
  } // Otherwise leave the interrupted state alone

  return interrupted;
}

// Get's a pc (hint) for a running thread. Currently used only for profiling.
ExtendedPC os::get_thread_pc(Thread* thread) {
  CONTEXT context;
  context.ContextFlags = CONTEXT_CONTROL;
  HANDLE handle = thread->osthread()->thread_handle();
#ifdef _M_IA64
  assert(0, "Fix get_thread_pc");
  return ExtendedPC(NULL);
#else
  if (GetThreadContext(handle, &context)) {
#ifdef _M_AMD64
    return ExtendedPC((address) context.Rip);
#else
    return ExtendedPC((address) context.Eip);
#endif
  } else {
    return ExtendedPC(NULL);
  }
#endif
}

// GetCurrentThreadId() returns DWORD
intx os::current_thread_id()          { return GetCurrentThreadId(); }

static int _initial_pid = 0;

int os::current_process_id()
{
  return (_initial_pid ? _initial_pid : _getpid());
}

int    os::win32::_vm_page_size       = 0;
int    os::win32::_vm_allocation_granularity = 0;
int    os::win32::_processor_type     = 0;
// Processor level is not available on non-NT systems, use vm_version instead
int    os::win32::_processor_level    = 0;
julong os::win32::_physical_memory    = 0;
size_t os::win32::_default_stack_size = 0;

         intx os::win32::_os_thread_limit    = 0;
volatile intx os::win32::_os_thread_count    = 0;

bool   os::win32::_is_nt              = false;
bool   os::win32::_is_windows_2003    = false;
bool   os::win32::_is_windows_server  = false;

void os::win32::initialize_system_info() {
  SYSTEM_INFO si;
  GetSystemInfo(&si);
  _vm_page_size    = si.dwPageSize;
  _vm_allocation_granularity = si.dwAllocationGranularity;
  _processor_type  = si.dwProcessorType;
  _processor_level = si.wProcessorLevel;
  set_processor_count(si.dwNumberOfProcessors);

  MEMORYSTATUSEX ms;
  ms.dwLength = sizeof(ms);

  // also returns dwAvailPhys (free physical memory bytes), dwTotalVirtual, dwAvailVirtual,
  // dwMemoryLoad (% of memory in use)
  GlobalMemoryStatusEx(&ms);
  _physical_memory = ms.ullTotalPhys;

  OSVERSIONINFOEX oi;
  oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  GetVersionEx((OSVERSIONINFO*)&oi);
  switch(oi.dwPlatformId) {
    case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break;
    case VER_PLATFORM_WIN32_NT:
      _is_nt = true;
      {
        int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;
        if (os_vers == 5002) {
          _is_windows_2003 = true;
        }
        if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER ||
          oi.wProductType == VER_NT_SERVER) {
            _is_windows_server = true;
        }
      }
      break;
    default: fatal("Unknown platform");
  }

  _default_stack_size = os::current_stack_size();
  assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");
  assert((_default_stack_size & (_vm_page_size - 1)) == 0,
    "stack size not a multiple of page size");

  initialize_performance_counter();

  // Win95/Win98 scheduler bug work-around. The Win95/98 scheduler is
  // known to deadlock the system, if the VM issues to thread operations with
  // a too high frequency, e.g., such as changing the priorities.
  // The 6000 seems to work well - no deadlocks has been notices on the test
  // programs that we have seen experience this problem.
  if (!os::win32::is_nt()) {
    StarvationMonitorInterval = 6000;
  }
}


HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf, int ebuflen) {
  char path[MAX_PATH];
  DWORD size;
  DWORD pathLen = (DWORD)sizeof(path);
  HINSTANCE result = NULL;

  // only allow library name without path component
  assert(strchr(name, '\\') == NULL, "path not allowed");
  assert(strchr(name, ':') == NULL, "path not allowed");
  if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) {
    jio_snprintf(ebuf, ebuflen,
      "Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name);
    return NULL;
  }

  // search system directory
  if ((size = GetSystemDirectory(path, pathLen)) > 0) {
    strcat(path, "\\");
    strcat(path, name);
    if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
      return result;
    }
  }

  // try Windows directory
  if ((size = GetWindowsDirectory(path, pathLen)) > 0) {
    strcat(path, "\\");
    strcat(path, name);
    if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
      return result;
    }
  }

  jio_snprintf(ebuf, ebuflen,
    "os::win32::load_windows_dll() cannot load %s from system directories.", name);
  return NULL;
}

void os::win32::setmode_streams() {
  _setmode(_fileno(stdin), _O_BINARY);
  _setmode(_fileno(stdout), _O_BINARY);
  _setmode(_fileno(stderr), _O_BINARY);
}


bool os::is_debugger_attached() {
  return IsDebuggerPresent() ? true : false;
}


void os::wait_for_keypress_at_exit(void) {
  if (PauseAtExit) {
    fprintf(stderr, "Press any key to continue...\n");
    fgetc(stdin);
  }
}


int os::message_box(const char* title, const char* message) {
  int result = MessageBox(NULL, message, title,
                          MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);
  return result == IDYES;
}

int os::allocate_thread_local_storage() {
  return TlsAlloc();
}


void os::free_thread_local_storage(int index) {
  TlsFree(index);
}


void os::thread_local_storage_at_put(int index, void* value) {
  TlsSetValue(index, value);
  assert(thread_local_storage_at(index) == value, "Just checking");
}


void* os::thread_local_storage_at(int index) {
  return TlsGetValue(index);
}


#ifndef PRODUCT
#ifndef _WIN64
// Helpers to check whether NX protection is enabled
int nx_exception_filter(_EXCEPTION_POINTERS *pex) {
  if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
      pex->ExceptionRecord->NumberParameters > 0 &&
      pex->ExceptionRecord->ExceptionInformation[0] ==
      EXCEPTION_INFO_EXEC_VIOLATION) {
    return EXCEPTION_EXECUTE_HANDLER;
  }
  return EXCEPTION_CONTINUE_SEARCH;
}

void nx_check_protection() {
  // If NX is enabled we'll get an exception calling into code on the stack
  char code[] = { (char)0xC3 }; // ret
  void *code_ptr = (void *)code;
  __try {
    __asm call code_ptr
  } __except(nx_exception_filter((_EXCEPTION_POINTERS*)_exception_info())) {
    tty->print_raw_cr("NX protection detected.");
  }
}
#endif // _WIN64
#endif // PRODUCT

// this is called _before_ the global arguments have been parsed
void os::init(void) {
  _initial_pid = _getpid();

  init_random(1234567);

  win32::initialize_system_info();
  win32::setmode_streams();
  init_page_sizes((size_t) win32::vm_page_size());

  // For better scalability on MP systems (must be called after initialize_system_info)
#ifndef PRODUCT
  if (is_MP()) {
    NoYieldsInMicrolock = true;
  }
#endif
  // This may be overridden later when argument processing is done.
  FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation,
    os::win32::is_windows_2003());

  // Initialize main_process and main_thread
  main_process = GetCurrentProcess();  // Remember main_process is a pseudo handle
 if (!DuplicateHandle(main_process, GetCurrentThread(), main_process,
                       &main_thread, THREAD_ALL_ACCESS, false, 0)) {
    fatal("DuplicateHandle failed\n");
  }
  main_thread_id = (int) GetCurrentThreadId();
}

// To install functions for atexit processing
extern "C" {
  static void perfMemory_exit_helper() {
    perfMemory_exit();
  }
}

static jint initSock();

// this is called _after_ the global arguments have been parsed
jint os::init_2(void) {
  // Allocate a single page and mark it as readable for safepoint polling
  address polling_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READONLY);
  guarantee( polling_page != NULL, "Reserve Failed for polling page");

  address return_page  = (address)VirtualAlloc(polling_page, os::vm_page_size(), MEM_COMMIT, PAGE_READONLY);
  guarantee( return_page != NULL, "Commit Failed for polling page");

  os::set_polling_page( polling_page );

#ifndef PRODUCT
  if( Verbose && PrintMiscellaneous )
    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
#endif

  if (!UseMembar) {
    address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);
    guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page");

    return_page  = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_READWRITE);
    guarantee( return_page != NULL, "Commit Failed for memory serialize page");

    os::set_memory_serialize_page( mem_serialize_page );

#ifndef PRODUCT
    if(Verbose && PrintMiscellaneous)
      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
#endif
  }

  // Setup Windows Exceptions

  // for debugging float code generation bugs
  if (ForceFloatExceptions) {
#ifndef  _WIN64
    static long fp_control_word = 0;
    __asm { fstcw fp_control_word }
    // see Intel PPro Manual, Vol. 2, p 7-16
    const long precision = 0x20;
    const long underflow = 0x10;
    const long overflow  = 0x08;
    const long zero_div  = 0x04;
    const long denorm    = 0x02;
    const long invalid   = 0x01;
    fp_control_word |= invalid;
    __asm { fldcw fp_control_word }
#endif
  }

  // If stack_commit_size is 0, windows will reserve the default size,
  // but only commit a small portion of it.
  size_t stack_commit_size = round_to(ThreadStackSize*K, os::vm_page_size());
  size_t default_reserve_size = os::win32::default_stack_size();
  size_t actual_reserve_size = stack_commit_size;
  if (stack_commit_size < default_reserve_size) {
    // If stack_commit_size == 0, we want this too
    actual_reserve_size = default_reserve_size;
  }

  // Check minimum allowable stack size for thread creation and to initialize
  // the java system classes, including StackOverflowError - depends on page
  // size.  Add a page for compiler2 recursion in main thread.
  // Add in 2*BytesPerWord times page size to account for VM stack during
  // class initialization depending on 32 or 64 bit VM.
  size_t min_stack_allowed =
            (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
            2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size();
  if (actual_reserve_size < min_stack_allowed) {
    tty->print_cr("\nThe stack size specified is too small, "
                  "Specify at least %dk",
                  min_stack_allowed / K);
    return JNI_ERR;
  }

  JavaThread::set_stack_size_at_create(stack_commit_size);

  // Calculate theoretical max. size of Threads to guard gainst artifical
  // out-of-memory situations, where all available address-space has been
  // reserved by thread stacks.
  assert(actual_reserve_size != 0, "Must have a stack");

  // Calculate the thread limit when we should start doing Virtual Memory
  // banging. Currently when the threads will have used all but 200Mb of space.
  //
  // TODO: consider performing a similar calculation for commit size instead
  // as reserve size, since on a 64-bit platform we'll run into that more
  // often than running out of virtual memory space.  We can use the
  // lower value of the two calculations as the os_thread_limit.
  size_t max_address_space = ((size_t)1 << (BitsPerWord - 1)) - (200 * K * K);
  win32::_os_thread_limit = (intx)(max_address_space / actual_reserve_size);

  // at exit methods are called in the reverse order of their registration.
  // there is no limit to the number of functions registered. atexit does
  // not set errno.

  if (PerfAllowAtExitRegistration) {
    // only register atexit functions if PerfAllowAtExitRegistration is set.
    // atexit functions can be delayed until process exit time, which
    // can be problematic for embedded VM situations. Embedded VMs should
    // call DestroyJavaVM() to assure that VM resources are released.

    // note: perfMemory_exit_helper atexit function may be removed in
    // the future if the appropriate cleanup code can be added to the
    // VM_Exit VMOperation's doit method.
    if (atexit(perfMemory_exit_helper) != 0) {
      warning("os::init_2 atexit(perfMemory_exit_helper) failed");
    }
  }

#ifndef _WIN64
  // Print something if NX is enabled (win32 on AMD64)
  NOT_PRODUCT(if (PrintMiscellaneous && Verbose) nx_check_protection());
#endif

  // initialize thread priority policy
  prio_init();

  if (UseNUMA && !ForceNUMA) {
    UseNUMA = false; // We don't fully support this yet
  }

  if (UseNUMAInterleaving) {
    // first check whether this Windows OS supports VirtualAllocExNuma, if not ignore this flag
    bool success = numa_interleaving_init();
    if (!success) UseNUMAInterleaving = false;
  }

  if (initSock() != JNI_OK) {
    return JNI_ERR;
  }

  return JNI_OK;
}

// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
  DWORD old_status;
  if( !VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_NOACCESS, &old_status) )
    fatal("Could not disable polling page");
};

// Mark the polling page as readable
void os::make_polling_page_readable(void) {
  DWORD old_status;
  if( !VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_READONLY, &old_status) )
    fatal("Could not enable polling page");
};


int os::stat(const char *path, struct stat *sbuf) {
  char pathbuf[MAX_PATH];
  if (strlen(path) > MAX_PATH - 1) {
    errno = ENAMETOOLONG;
    return -1;
  }
  os::native_path(strcpy(pathbuf, path));
  int ret = ::stat(pathbuf, sbuf);
  if (sbuf != NULL && UseUTCFileTimestamp) {
    // Fix for 6539723.  st_mtime returned from stat() is dependent on
    // the system timezone and so can return different values for the
    // same file if/when daylight savings time changes.  This adjustment
    // makes sure the same timestamp is returned regardless of the TZ.
    //
    // See:
    // http://msdn.microsoft.com/library/
    //   default.asp?url=/library/en-us/sysinfo/base/
    //   time_zone_information_str.asp
    // and
    // http://msdn.microsoft.com/library/default.asp?url=
    //   /library/en-us/sysinfo/base/settimezoneinformation.asp
    //
    // NOTE: there is a insidious bug here:  If the timezone is changed
    // after the call to stat() but before 'GetTimeZoneInformation()', then
    // the adjustment we do here will be wrong and we'll return the wrong
    // value (which will likely end up creating an invalid class data
    // archive).  Absent a better API for this, or some time zone locking
    // mechanism, we'll have to live with this risk.
    TIME_ZONE_INFORMATION tz;
    DWORD tzid = GetTimeZoneInformation(&tz);
    int daylightBias =
      (tzid == TIME_ZONE_ID_DAYLIGHT) ?  tz.DaylightBias : tz.StandardBias;
    sbuf->st_mtime += (tz.Bias + daylightBias) * 60;
  }
  return ret;
}


#define FT2INT64(ft) \
  ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))


// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
// are used by JVM M&M and JVMTI to get user+sys or user CPU time
// of a thread.
//
// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
// the fast estimate available on the platform.

// current_thread_cpu_time() is not optimized for Windows yet
jlong os::current_thread_cpu_time() {
  // return user + sys since the cost is the same
  return os::thread_cpu_time(Thread::current(), true /* user+sys */);
}

jlong os::thread_cpu_time(Thread* thread) {
  // consistent with what current_thread_cpu_time() returns.
  return os::thread_cpu_time(thread, true /* user+sys */);
}

jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
  return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
}

jlong os::thread_cpu_time(Thread* thread, bool user_sys_cpu_time) {
  // This code is copy from clasic VM -> hpi::sysThreadCPUTime
  // If this function changes, os::is_thread_cpu_time_supported() should too
  if (os::win32::is_nt()) {
    FILETIME CreationTime;
    FILETIME ExitTime;
    FILETIME KernelTime;
    FILETIME UserTime;

    if ( GetThreadTimes(thread->osthread()->thread_handle(),
                    &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0)
      return -1;
    else
      if (user_sys_cpu_time) {
        return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100;
      } else {
        return FT2INT64(UserTime) * 100;
      }
  } else {
    return (jlong) timeGetTime() * 1000000;
  }
}

void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
  info_ptr->max_value = ALL_64_BITS;        // the max value -- all 64 bits
  info_ptr->may_skip_backward = false;      // GetThreadTimes returns absolute time
  info_ptr->may_skip_forward = false;       // GetThreadTimes returns absolute time
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;   // user+system time is returned
}

void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
  info_ptr->max_value = ALL_64_BITS;        // the max value -- all 64 bits
  info_ptr->may_skip_backward = false;      // GetThreadTimes returns absolute time
  info_ptr->may_skip_forward = false;       // GetThreadTimes returns absolute time
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;   // user+system time is returned
}

bool os::is_thread_cpu_time_supported() {
  // see os::thread_cpu_time
  if (os::win32::is_nt()) {
    FILETIME CreationTime;
    FILETIME ExitTime;
    FILETIME KernelTime;
    FILETIME UserTime;

    if ( GetThreadTimes(GetCurrentThread(),
                    &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0)
      return false;
    else
      return true;
  } else {
    return false;
  }
}

// Windows does't provide a loadavg primitive so this is stubbed out for now.
// It does have primitives (PDH API) to get CPU usage and run queue length.
// "\\Processor(_Total)\\% Processor Time", "\\System\\Processor Queue Length"
// If we wanted to implement loadavg on Windows, we have a few options:
//
// a) Query CPU usage and run queue length and "fake" an answer by
//    returning the CPU usage if it's under 100%, and the run queue
//    length otherwise.  It turns out that querying is pretty slow
//    on Windows, on the order of 200 microseconds on a fast machine.
//    Note that on the Windows the CPU usage value is the % usage
//    since the last time the API was called (and the first call
//    returns 100%), so we'd have to deal with that as well.
//
// b) Sample the "fake" answer using a sampling thread and store
//    the answer in a global variable.  The call to loadavg would
//    just return the value of the global, avoiding the slow query.
//
// c) Sample a better answer using exponential decay to smooth the
//    value.  This is basically the algorithm used by UNIX kernels.
//
// Note that sampling thread starvation could affect both (b) and (c).
int os::loadavg(double loadavg[], int nelem) {
  return -1;
}


// DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield()
bool os::dont_yield() {
  return DontYieldALot;
}

// This method is a slightly reworked copy of JDK's sysOpen
// from src/windows/hpi/src/sys_api_md.c

int os::open(const char *path, int oflag, int mode) {
  char pathbuf[MAX_PATH];

  if (strlen(path) > MAX_PATH - 1) {
    errno = ENAMETOOLONG;
          return -1;
  }
  os::native_path(strcpy(pathbuf, path));
  return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);
}

FILE* os::open(int fd, const char* mode) {
  return ::_fdopen(fd, mode);
}

// Is a (classpath) directory empty?
bool os::dir_is_empty(const char* path) {
  WIN32_FIND_DATA fd;
  HANDLE f = FindFirstFile(path, &fd);
  if (f == INVALID_HANDLE_VALUE) {
    return true;
  }
  FindClose(f);
  return false;
}

// create binary file, rewriting existing file if required
int os::create_binary_file(const char* path, bool rewrite_existing) {
  int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;
  if (!rewrite_existing) {
    oflags |= _O_EXCL;
  }
  return ::open(path, oflags, _S_IREAD | _S_IWRITE);
}

// return current position of file pointer
jlong os::current_file_offset(int fd) {
  return (jlong)::_lseeki64(fd, (__int64)0L, SEEK_CUR);
}

// move file pointer to the specified offset
jlong os::seek_to_file_offset(int fd, jlong offset) {
  return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET);
}


jlong os::lseek(int fd, jlong offset, int whence) {
  return (jlong) ::_lseeki64(fd, offset, whence);
}

// This method is a slightly reworked copy of JDK's sysNativePath
// from src/windows/hpi/src/path_md.c

/* Convert a pathname to native format.  On win32, this involves forcing all
   separators to be '\\' rather than '/' (both are legal inputs, but Win95
   sometimes rejects '/') and removing redundant separators.  The input path is
   assumed to have been converted into the character encoding used by the local
   system.  Because this might be a double-byte encoding, care is taken to
   treat double-byte lead characters correctly.

   This procedure modifies the given path in place, as the result is never
   longer than the original.  There is no error return; this operation always
   succeeds. */
char * os::native_path(char *path) {
  char *src = path, *dst = path, *end = path;
  char *colon = NULL;           /* If a drive specifier is found, this will
                                        point to the colon following the drive
                                        letter */

  /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */
  assert(((!::IsDBCSLeadByte('/'))
    && (!::IsDBCSLeadByte('\\'))
    && (!::IsDBCSLeadByte(':'))),
    "Illegal lead byte");

  /* Check for leading separators */
#define isfilesep(c) ((c) == '/' || (c) == '\\')
  while (isfilesep(*src)) {
    src++;
  }

  if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') {
    /* Remove leading separators if followed by drive specifier.  This
      hack is necessary to support file URLs containing drive
      specifiers (e.g., "file://c:/path").  As a side effect,
      "/c:/path" can be used as an alternative to "c:/path". */
    *dst++ = *src++;
    colon = dst;
    *dst++ = ':';
    src++;
  } else {
    src = path;
    if (isfilesep(src[0]) && isfilesep(src[1])) {
      /* UNC pathname: Retain first separator; leave src pointed at
         second separator so that further separators will be collapsed
         into the second separator.  The result will be a pathname
         beginning with "\\\\" followed (most likely) by a host name. */
      src = dst = path + 1;
      path[0] = '\\';     /* Force first separator to '\\' */
    }
  }

  end = dst;

  /* Remove redundant separators from remainder of path, forcing all
      separators to be '\\' rather than '/'. Also, single byte space
      characters are removed from the end of the path because those
      are not legal ending characters on this operating system.
  */
  while (*src != '\0') {
    if (isfilesep(*src)) {
      *dst++ = '\\'; src++;
      while (isfilesep(*src)) src++;
      if (*src == '\0') {
        /* Check for trailing separator */
        end = dst;
        if (colon == dst - 2) break;                      /* "z:\\" */
        if (dst == path + 1) break;                       /* "\\" */
        if (dst == path + 2 && isfilesep(path[0])) {
          /* "\\\\" is not collapsed to "\\" because "\\\\" marks the
            beginning of a UNC pathname.  Even though it is not, by
            itself, a valid UNC pathname, we leave it as is in order
            to be consistent with the path canonicalizer as well
            as the win32 APIs, which treat this case as an invalid
            UNC pathname rather than as an alias for the root
            directory of the current drive. */
          break;
        }
        end = --dst;  /* Path does not denote a root directory, so
                                    remove trailing separator */
        break;
      }
      end = dst;
    } else {
      if (::IsDBCSLeadByte(*src)) { /* Copy a double-byte character */
        *dst++ = *src++;
        if (*src) *dst++ = *src++;
        end = dst;
      } else {         /* Copy a single-byte character */
        char c = *src++;
        *dst++ = c;
        /* Space is not a legal ending character */
        if (c != ' ') end = dst;
      }
    }
  }

  *end = '\0';

  /* For "z:", add "." to work around a bug in the C runtime library */
  if (colon == dst - 1) {
          path[2] = '.';
          path[3] = '\0';
  }

  return path;
}

// This code is a copy of JDK's sysSetLength
// from src/windows/hpi/src/sys_api_md.c

int os::ftruncate(int fd, jlong length) {
  HANDLE h = (HANDLE)::_get_osfhandle(fd);
  long high = (long)(length >> 32);
  DWORD ret;

  if (h == (HANDLE)(-1)) {
    return -1;
  }

  ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN);
  if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) {
      return -1;
  }

  if (::SetEndOfFile(h) == FALSE) {
    return -1;
  }

  return 0;
}


// This code is a copy of JDK's sysSync
// from src/windows/hpi/src/sys_api_md.c
// except for the legacy workaround for a bug in Win 98

int os::fsync(int fd) {
  HANDLE handle = (HANDLE)::_get_osfhandle(fd);

  if ( (!::FlushFileBuffers(handle)) &&
         (GetLastError() != ERROR_ACCESS_DENIED) ) {
    /* from winerror.h */
    return -1;
  }
  return 0;
}

static int nonSeekAvailable(int, long *);
static int stdinAvailable(int, long *);

#define S_ISCHR(mode)   (((mode) & _S_IFCHR) == _S_IFCHR)
#define S_ISFIFO(mode)  (((mode) & _S_IFIFO) == _S_IFIFO)

// This code is a copy of JDK's sysAvailable
// from src/windows/hpi/src/sys_api_md.c

int os::available(int fd, jlong *bytes) {
  jlong cur, end;
  struct _stati64 stbuf64;

  if (::_fstati64(fd, &stbuf64) >= 0) {
    int mode = stbuf64.st_mode;
    if (S_ISCHR(mode) || S_ISFIFO(mode)) {
      int ret;
      long lpbytes;
      if (fd == 0) {
        ret = stdinAvailable(fd, &lpbytes);
      } else {
        ret = nonSeekAvailable(fd, &lpbytes);
      }
      (*bytes) = (jlong)(lpbytes);
      return ret;
    }
    if ((cur = ::_lseeki64(fd, 0L, SEEK_CUR)) == -1) {
      return FALSE;
    } else if ((end = ::_lseeki64(fd, 0L, SEEK_END)) == -1) {
      return FALSE;
    } else if (::_lseeki64(fd, cur, SEEK_SET) == -1) {
      return FALSE;
    }
    *bytes = end - cur;
    return TRUE;
  } else {
    return FALSE;
  }
}

// This code is a copy of JDK's nonSeekAvailable
// from src/windows/hpi/src/sys_api_md.c

static int nonSeekAvailable(int fd, long *pbytes) {
  /* This is used for available on non-seekable devices
    * (like both named and anonymous pipes, such as pipes
    *  connected to an exec'd process).
    * Standard Input is a special case.
    *
    */
  HANDLE han;

  if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) {
    return FALSE;
  }

  if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) {
        /* PeekNamedPipe fails when at EOF.  In that case we
         * simply make *pbytes = 0 which is consistent with the
         * behavior we get on Solaris when an fd is at EOF.
         * The only alternative is to raise an Exception,
         * which isn't really warranted.
         */
    if (::GetLastError() != ERROR_BROKEN_PIPE) {
      return FALSE;
    }
    *pbytes = 0;
  }
  return TRUE;
}

#define MAX_INPUT_EVENTS 2000

// This code is a copy of JDK's stdinAvailable
// from src/windows/hpi/src/sys_api_md.c

static int stdinAvailable(int fd, long *pbytes) {
  HANDLE han;
  DWORD numEventsRead = 0;      /* Number of events read from buffer */
  DWORD numEvents = 0;  /* Number of events in buffer */
  DWORD i = 0;          /* Loop index */
  DWORD curLength = 0;  /* Position marker */
  DWORD actualLength = 0;       /* Number of bytes readable */
  BOOL error = FALSE;         /* Error holder */
  INPUT_RECORD *lpBuffer;     /* Pointer to records of input events */

  if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
        return FALSE;
  }

  /* Construct an array of input records in the console buffer */
  error = ::GetNumberOfConsoleInputEvents(han, &numEvents);
  if (error == 0) {
    return nonSeekAvailable(fd, pbytes);
  }

  /* lpBuffer must fit into 64K or else PeekConsoleInput fails */
  if (numEvents > MAX_INPUT_EVENTS) {
    numEvents = MAX_INPUT_EVENTS;
  }

  lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal);
  if (lpBuffer == NULL) {
    return FALSE;
  }

  error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);
  if (error == 0) {
    os::free(lpBuffer, mtInternal);
    return FALSE;
  }

  /* Examine input records for the number of bytes available */
  for(i=0; i<numEvents; i++) {
    if (lpBuffer[i].EventType == KEY_EVENT) {

      KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *)
                                      &(lpBuffer[i].Event);
      if (keyRecord->bKeyDown == TRUE) {
        CHAR *keyPressed = (CHAR *) &(keyRecord->uChar);
        curLength++;
        if (*keyPressed == '\r') {
          actualLength = curLength;
        }
      }
    }
  }

  if(lpBuffer != NULL) {
    os::free(lpBuffer, mtInternal);
  }

  *pbytes = (long) actualLength;
  return TRUE;
}

// Map a block of memory.
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
                     char *addr, size_t bytes, bool read_only,
                     bool allow_exec) {
  HANDLE hFile;
  char* base;

  hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == NULL) {
    if (PrintMiscellaneous && Verbose) {
      DWORD err = GetLastError();
      tty->print_cr("CreateFile() failed: GetLastError->%ld.", err);
    }
    return NULL;
  }

  if (allow_exec) {
    // CreateFileMapping/MapViewOfFileEx can't map executable memory
    // unless it comes from a PE image (which the shared archive is not.)
    // Even VirtualProtect refuses to give execute access to mapped memory
    // that was not previously executable.
    //
    // Instead, stick the executable region in anonymous memory.  Yuck.
    // Penalty is that ~4 pages will not be shareable - in the future
    // we might consider DLLizing the shared archive with a proper PE
    // header so that mapping executable + sharing is possible.

    base = (char*) VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE,
                                PAGE_READWRITE);
    if (base == NULL) {
      if (PrintMiscellaneous && Verbose) {
        DWORD err = GetLastError();
        tty->print_cr("VirtualAlloc() failed: GetLastError->%ld.", err);
      }
      CloseHandle(hFile);
      return NULL;
    }

    DWORD bytes_read;
    OVERLAPPED overlapped;
    overlapped.Offset = (DWORD)file_offset;
    overlapped.OffsetHigh = 0;
    overlapped.hEvent = NULL;
    // ReadFile guarantees that if the return value is true, the requested
    // number of bytes were read before returning.
    bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0;
    if (!res) {
      if (PrintMiscellaneous && Verbose) {
        DWORD err = GetLastError();
        tty->print_cr("ReadFile() failed: GetLastError->%ld.", err);
      }
      release_memory(base, bytes);
      CloseHandle(hFile);
      return NULL;
    }
  } else {
    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0,
                                    NULL /*file_name*/);
    if (hMap == NULL) {
      if (PrintMiscellaneous && Verbose) {
        DWORD err = GetLastError();
        tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err);
      }
      CloseHandle(hFile);
      return NULL;
    }

    DWORD access = read_only ? FILE_MAP_READ : FILE_MAP_COPY;
    base = (char*)MapViewOfFileEx(hMap, access, 0, (DWORD)file_offset,
                                  (DWORD)bytes, addr);
    if (base == NULL) {
      if (PrintMiscellaneous && Verbose) {
        DWORD err = GetLastError();
        tty->print_cr("MapViewOfFileEx() failed: GetLastError->%ld.", err);
      }
      CloseHandle(hMap);
      CloseHandle(hFile);
      return NULL;
    }

    if (CloseHandle(hMap) == 0) {
      if (PrintMiscellaneous && Verbose) {
        DWORD err = GetLastError();
        tty->print_cr("CloseHandle(hMap) failed: GetLastError->%ld.", err);
      }
      CloseHandle(hFile);
      return base;
    }
  }

  if (allow_exec) {
    DWORD old_protect;
    DWORD exec_access = read_only ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE;
    bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0;

    if (!res) {
      if (PrintMiscellaneous && Verbose) {
        DWORD err = GetLastError();
        tty->print_cr("VirtualProtect() failed: GetLastError->%ld.", err);
      }
      // Don't consider this a hard error, on IA32 even if the
      // VirtualProtect fails, we should still be able to execute
      CloseHandle(hFile);
      return base;
    }
  }

  if (CloseHandle(hFile) == 0) {
    if (PrintMiscellaneous && Verbose) {
      DWORD err = GetLastError();
      tty->print_cr("CloseHandle(hFile) failed: GetLastError->%ld.", err);
    }
    return base;
  }

  return base;
}


// Remap a block of memory.
char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                       char *addr, size_t bytes, bool read_only,
                       bool allow_exec) {
  // This OS does not allow existing memory maps to be remapped so we
  // have to unmap the memory before we remap it.
  if (!os::unmap_memory(addr, bytes)) {
    return NULL;
  }

  // There is a very small theoretical window between the unmap_memory()
  // call above and the map_memory() call below where a thread in native
  // code may be able to access an address that is no longer mapped.

  return os::map_memory(fd, file_name, file_offset, addr, bytes,
           read_only, allow_exec);
}


// Unmap a block of memory.
// Returns true=success, otherwise false.

bool os::pd_unmap_memory(char* addr, size_t bytes) {
  BOOL result = UnmapViewOfFile(addr);
  if (result == 0) {
    if (PrintMiscellaneous && Verbose) {
      DWORD err = GetLastError();
      tty->print_cr("UnmapViewOfFile() failed: GetLastError->%ld.", err);
    }
    return false;
  }
  return true;
}

void os::pause() {
  char filename[MAX_PATH];
  if (PauseAtStartupFile && PauseAtStartupFile[0]) {
    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
  } else {
    jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
  }

  int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  if (fd != -1) {
    struct stat buf;
    ::close(fd);
    while (::stat(filename, &buf) == 0) {
      Sleep(100);
    }
  } else {
    jio_fprintf(stderr,
      "Could not open pause file '%s', continuing immediately.\n", filename);
  }
}

os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
  assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
}

/*
 * See the caveats for this class in os_windows.hpp
 * Protects the callback call so that raised OS EXCEPTIONS causes a jump back
 * into this method and returns false. If no OS EXCEPTION was raised, returns
 * true.
 * The callback is supposed to provide the method that should be protected.
 */
bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
  assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
  assert(!WatcherThread::watcher_thread()->has_crash_protection(),
      "crash_protection already set?");

  bool success = true;
  __try {
    WatcherThread::watcher_thread()->set_crash_protection(this);
    cb.call();
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    // only for protection, nothing to do
    success = false;
  }
  WatcherThread::watcher_thread()->set_crash_protection(NULL);
  return success;
}

// An Event wraps a win32 "CreateEvent" kernel handle.
//
// We have a number of choices regarding "CreateEvent" win32 handle leakage:
//
// 1:  When a thread dies return the Event to the EventFreeList, clear the ParkHandle
//     field, and call CloseHandle() on the win32 event handle.  Unpark() would
//     need to be modified to tolerate finding a NULL (invalid) win32 event handle.
//     In addition, an unpark() operation might fetch the handle field, but the
//     event could recycle between the fetch and the SetEvent() operation.
//     SetEvent() would either fail because the handle was invalid, or inadvertently work,
//     as the win32 handle value had been recycled.  In an ideal world calling SetEvent()
//     on an stale but recycled handle would be harmless, but in practice this might
//     confuse other non-Sun code, so it's not a viable approach.
//
// 2:  Once a win32 event handle is associated with an Event, it remains associated
//     with the Event.  The event handle is never closed.  This could be construed
//     as handle leakage, but only up to the maximum # of threads that have been extant
//     at any one time.  This shouldn't be an issue, as windows platforms typically
//     permit a process to have hundreds of thousands of open handles.
//
// 3:  Same as (1), but periodically, at stop-the-world time, rundown the EventFreeList
//     and release unused handles.
//
// 4:  Add a CRITICAL_SECTION to the Event to protect LD+SetEvent from LD;ST(null);CloseHandle.
//     It's not clear, however, that we wouldn't be trading one type of leak for another.
//
// 5.  Use an RCU-like mechanism (Read-Copy Update).
//     Or perhaps something similar to Maged Michael's "Hazard pointers".
//
// We use (2).
//
// TODO-FIXME:
// 1.  Reconcile Doug's JSR166 j.u.c park-unpark with the objectmonitor implementation.
// 2.  Consider wrapping the WaitForSingleObject(Ex) calls in SEH try/finally blocks
//     to recover from (or at least detect) the dreaded Windows 841176 bug.
// 3.  Collapse the interrupt_event, the JSR166 parker event, and the objectmonitor ParkEvent
//     into a single win32 CreateEvent() handle.
//
// _Event transitions in park()
//   -1 => -1 : illegal
//    1 =>  0 : pass - return immediately
//    0 => -1 : block
//
// _Event serves as a restricted-range semaphore :
//    -1 : thread is blocked
//     0 : neutral  - thread is running or ready
//     1 : signaled - thread is running or ready
//
// Another possible encoding of _Event would be
// with explicit "PARKED" and "SIGNALED" bits.

int os::PlatformEvent::park (jlong Millis) {
    guarantee (_ParkHandle != NULL , "Invariant") ;
    guarantee (Millis > 0          , "Invariant") ;
    int v ;

    // CONSIDER: defer assigning a CreateEvent() handle to the Event until
    // the initial park() operation.

    for (;;) {
        v = _Event ;
        if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
    }
    guarantee ((v == 0) || (v == 1), "invariant") ;
    if (v != 0) return OS_OK ;

    // Do this the hard way by blocking ...
    // TODO: consider a brief spin here, gated on the success of recent
    // spin attempts by this thread.
    //
    // We decompose long timeouts into series of shorter timed waits.
    // Evidently large timo values passed in WaitForSingleObject() are problematic on some
    // versions of Windows.  See EventWait() for details.  This may be superstition.  Or not.
    // We trust the WAIT_TIMEOUT indication and don't track the elapsed wait time
    // with os::javaTimeNanos().  Furthermore, we assume that spurious returns from
    // ::WaitForSingleObject() caused by latent ::setEvent() operations will tend
    // to happen early in the wait interval.  Specifically, after a spurious wakeup (rv ==
    // WAIT_OBJECT_0 but _Event is still < 0) we don't bother to recompute Millis to compensate
    // for the already waited time.  This policy does not admit any new outcomes.
    // In the future, however, we might want to track the accumulated wait time and
    // adjust Millis accordingly if we encounter a spurious wakeup.

    const int MAXTIMEOUT = 0x10000000 ;
    DWORD rv = WAIT_TIMEOUT ;
    while (_Event < 0 && Millis > 0) {
       DWORD prd = Millis ;     // set prd = MAX (Millis, MAXTIMEOUT)
       if (Millis > MAXTIMEOUT) {
          prd = MAXTIMEOUT ;
       }
       rv = ::WaitForSingleObject (_ParkHandle, prd) ;
       assert (rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT, "WaitForSingleObject failed") ;
       if (rv == WAIT_TIMEOUT) {
           Millis -= prd ;
       }
    }
    v = _Event ;
    _Event = 0 ;
    // see comment at end of os::PlatformEvent::park() below:
    OrderAccess::fence() ;
    // If we encounter a nearly simultanous timeout expiry and unpark()
    // we return OS_OK indicating we awoke via unpark().
    // Implementor's license -- returning OS_TIMEOUT would be equally valid, however.
    return (v >= 0) ? OS_OK : OS_TIMEOUT ;
}

void os::PlatformEvent::park () {
    guarantee (_ParkHandle != NULL, "Invariant") ;
    // Invariant: Only the thread associated with the Event/PlatformEvent
    // may call park().
    int v ;
    for (;;) {
        v = _Event ;
        if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
    }
    guarantee ((v == 0) || (v == 1), "invariant") ;
    if (v != 0) return ;

    // Do this the hard way by blocking ...
    // TODO: consider a brief spin here, gated on the success of recent
    // spin attempts by this thread.
    while (_Event < 0) {
       DWORD rv = ::WaitForSingleObject (_ParkHandle, INFINITE) ;
       assert (rv == WAIT_OBJECT_0, "WaitForSingleObject failed") ;
    }

    // Usually we'll find _Event == 0 at this point, but as
    // an optional optimization we clear it, just in case can
    // multiple unpark() operations drove _Event up to 1.
    _Event = 0 ;
    OrderAccess::fence() ;
    guarantee (_Event >= 0, "invariant") ;
}

void os::PlatformEvent::unpark() {
  guarantee (_ParkHandle != NULL, "Invariant") ;

  // Transitions for _Event:
  //    0 :=> 1
  //    1 :=> 1
  //   -1 :=> either 0 or 1; must signal target thread
  //          That is, we can safely transition _Event from -1 to either
  //          0 or 1. Forcing 1 is slightly more efficient for back-to-back
  //          unpark() calls.
  // See also: "Semaphores in Plan 9" by Mullender & Cox
  //
  // Note: Forcing a transition from "-1" to "1" on an unpark() means
  // that it will take two back-to-back park() calls for the owning
  // thread to block. This has the benefit of forcing a spurious return
  // from the first park() call after an unpark() call which will help
  // shake out uses of park() and unpark() without condition variables.

  if (Atomic::xchg(1, &_Event) >= 0) return;

  ::SetEvent(_ParkHandle);
}


// JSR166
// -------------------------------------------------------

/*
 * The Windows implementation of Park is very straightforward: Basic
 * operations on Win32 Events turn out to have the right semantics to
 * use them directly. We opportunistically resuse the event inherited
 * from Monitor.
 */


void Parker::park(bool isAbsolute, jlong time) {
  guarantee (_ParkEvent != NULL, "invariant") ;
  // First, demultiplex/decode time arguments
  if (time < 0) { // don't wait
    return;
  }
  else if (time == 0 && !isAbsolute) {
    time = INFINITE;
  }
  else if  (isAbsolute) {
    time -= os::javaTimeMillis(); // convert to relative time
    if (time <= 0) // already elapsed
      return;
  }
  else { // relative
    time /= 1000000; // Must coarsen from nanos to millis
    if (time == 0)   // Wait for the minimal time unit if zero
      time = 1;
  }

  JavaThread* thread = (JavaThread*)(Thread::current());
  assert(thread->is_Java_thread(), "Must be JavaThread");
  JavaThread *jt = (JavaThread *)thread;

  // Don't wait if interrupted or already triggered
  if (Thread::is_interrupted(thread, false) ||
    WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) {
    ResetEvent(_ParkEvent);
    return;
  }
  else {
    ThreadBlockInVM tbivm(jt);
    OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
    jt->set_suspend_equivalent();

    WaitForSingleObject(_ParkEvent,  time);
    ResetEvent(_ParkEvent);

    // If externally suspended while waiting, re-suspend
    if (jt->handle_special_suspend_equivalent_condition()) {
      jt->java_suspend_self();
    }
  }
}

void Parker::unpark() {
  guarantee (_ParkEvent != NULL, "invariant") ;
  SetEvent(_ParkEvent);
}

// Run the specified command in a separate process. Return its exit value,
// or -1 on failure (e.g. can't create a new process).
int os::fork_and_exec(char* cmd) {
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  memset(&pi, 0, sizeof(pi));
  BOOL rslt = CreateProcess(NULL,   // executable name - use command line
                            cmd,    // command line
                            NULL,   // process security attribute
                            NULL,   // thread security attribute
                            TRUE,   // inherits system handles
                            0,      // no creation flags
                            NULL,   // use parent's environment block
                            NULL,   // use parent's starting directory
                            &si,    // (in) startup information
                            &pi);   // (out) process information

  if (rslt) {
    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);

    DWORD exit_code;
    GetExitCodeProcess(pi.hProcess, &exit_code);

    // Close process and thread handles.
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return (int)exit_code;
  } else {
    return -1;
  }
}

//--------------------------------------------------------------------------------------------------
// Non-product code

static int mallocDebugIntervalCounter = 0;
static int mallocDebugCounter = 0;
bool os::check_heap(bool force) {
  if (++mallocDebugCounter < MallocVerifyStart && !force) return true;
  if (++mallocDebugIntervalCounter >= MallocVerifyInterval || force) {
    // Note: HeapValidate executes two hardware breakpoints when it finds something
    // wrong; at these points, eax contains the address of the offending block (I think).
    // To get to the exlicit error message(s) below, just continue twice.
    HANDLE heap = GetProcessHeap();
    { HeapLock(heap);
      PROCESS_HEAP_ENTRY phe;
      phe.lpData = NULL;
      while (HeapWalk(heap, &phe) != 0) {
        if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) &&
            !HeapValidate(heap, 0, phe.lpData)) {
          tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter);
          tty->print_cr("corrupted block near address %#x, length %d", phe.lpData, phe.cbData);
          fatal("corrupted C heap");
        }
      }
      DWORD err = GetLastError();
      if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) {
        fatal(err_msg("heap walk aborted with error %d", err));
      }
      HeapUnlock(heap);
    }
    mallocDebugIntervalCounter = 0;
  }
  return true;
}


bool os::find(address addr, outputStream* st) {
  // Nothing yet
  return false;
}

LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
  DWORD exception_code = e->ExceptionRecord->ExceptionCode;

  if ( exception_code == EXCEPTION_ACCESS_VIOLATION ) {
    JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
    PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;
    address addr = (address) exceptionRecord->ExceptionInformation[1];

    if (os::is_memory_serialize_page(thread, addr))
      return EXCEPTION_CONTINUE_EXECUTION;
  }

  return EXCEPTION_CONTINUE_SEARCH;
}

// We don't build a headless jre for Windows
bool os::is_headless_jre() { return false; }

static jint initSock() {
  WSADATA wsadata;

  if (!os::WinSock2Dll::WinSock2Available()) {
    jio_fprintf(stderr, "Could not load Winsock (error: %d)\n",
      ::GetLastError());
    return JNI_ERR;
  }

  if (os::WinSock2Dll::WSAStartup(MAKEWORD(2,2), &wsadata) != 0) {
    jio_fprintf(stderr, "Could not initialize Winsock (error: %d)\n",
      ::GetLastError());
    return JNI_ERR;
  }
  return JNI_OK;
}

struct hostent* os::get_host_by_name(char* name) {
  return (struct hostent*)os::WinSock2Dll::gethostbyname(name);
}

int os::socket_close(int fd) {
  return ::closesocket(fd);
}

int os::socket_available(int fd, jint *pbytes) {
  int ret = ::ioctlsocket(fd, FIONREAD, (u_long*)pbytes);
  return (ret < 0) ? 0 : 1;
}

int os::socket(int domain, int type, int protocol) {
  return ::socket(domain, type, protocol);
}

int os::listen(int fd, int count) {
  return ::listen(fd, count);
}

int os::connect(int fd, struct sockaddr* him, socklen_t len) {
  return ::connect(fd, him, len);
}

int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
  return ::accept(fd, him, len);
}

int os::sendto(int fd, char* buf, size_t len, uint flags,
               struct sockaddr* to, socklen_t tolen) {

  return ::sendto(fd, buf, (int)len, flags, to, tolen);
}

int os::recvfrom(int fd, char *buf, size_t nBytes, uint flags,
                 sockaddr* from, socklen_t* fromlen) {

  return ::recvfrom(fd, buf, (int)nBytes, flags, from, fromlen);
}

int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
  return ::recv(fd, buf, (int)nBytes, flags);
}

int os::send(int fd, char* buf, size_t nBytes, uint flags) {
  return ::send(fd, buf, (int)nBytes, flags);
}

int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
  return ::send(fd, buf, (int)nBytes, flags);
}

int os::timeout(int fd, long timeout) {
  fd_set tbl;
  struct timeval t;

  t.tv_sec  = timeout / 1000;
  t.tv_usec = (timeout % 1000) * 1000;

  tbl.fd_count    = 1;
  tbl.fd_array[0] = fd;

  return ::select(1, &tbl, 0, 0, &t);
}

int os::get_host_name(char* name, int namelen) {
  return ::gethostname(name, namelen);
}

int os::socket_shutdown(int fd, int howto) {
  return ::shutdown(fd, howto);
}

int os::bind(int fd, struct sockaddr* him, socklen_t len) {
  return ::bind(fd, him, len);
}

int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {
  return ::getsockname(fd, him, len);
}

int os::get_sock_opt(int fd, int level, int optname,
                     char* optval, socklen_t* optlen) {
  return ::getsockopt(fd, level, optname, optval, optlen);
}

int os::set_sock_opt(int fd, int level, int optname,
                     const char* optval, socklen_t optlen) {
  return ::setsockopt(fd, level, optname, optval, optlen);
}

// WINDOWS CONTEXT Flags for THREAD_SAMPLING
#if defined(IA32)
#  define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
#elif defined (AMD64)
#  define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
#endif

// returns true if thread could be suspended,
// false otherwise
static bool do_suspend(HANDLE* h) {
  if (h != NULL) {
    if (SuspendThread(*h) != ~0) {
      return true;
    }
  }
  return false;
}

// resume the thread
// calling resume on an active thread is a no-op
static void do_resume(HANDLE* h) {
  if (h != NULL) {
    ResumeThread(*h);
  }
}

// retrieve a suspend/resume context capable handle
// from the tid. Caller validates handle return value.
void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) {
  if (h != NULL) {
    *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
  }
}

//
// Thread sampling implementation
//
void os::SuspendedThreadTask::internal_do_task() {
  CONTEXT    ctxt;
  HANDLE     h = NULL;

  // get context capable handle for thread
  get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());

  // sanity
  if (h == NULL || h == INVALID_HANDLE_VALUE) {
    return;
  }

  // suspend the thread
  if (do_suspend(&h)) {
    ctxt.ContextFlags = sampling_context_flags;
    // get thread context
    GetThreadContext(h, &ctxt);
    SuspendedThreadTaskContext context(_thread, &ctxt);
    // pass context to Thread Sampling impl
    do_task(context);
    // resume thread
    do_resume(&h);
  }

  // close handle
  CloseHandle(h);
}


// Kernel32 API
typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);
typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG);
typedef USHORT (WINAPI* RtlCaptureStackBackTrace_Fn)(ULONG, ULONG, PVOID*, PULONG);

GetLargePageMinimum_Fn      os::Kernel32Dll::_GetLargePageMinimum = NULL;
VirtualAllocExNuma_Fn       os::Kernel32Dll::_VirtualAllocExNuma = NULL;
GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL;
GetNumaNodeProcessorMask_Fn os::Kernel32Dll::_GetNumaNodeProcessorMask = NULL;
RtlCaptureStackBackTrace_Fn os::Kernel32Dll::_RtlCaptureStackBackTrace = NULL;


BOOL                        os::Kernel32Dll::initialized = FALSE;
SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
  assert(initialized && _GetLargePageMinimum != NULL,
    "GetLargePageMinimumAvailable() not yet called");
  return _GetLargePageMinimum();
}

BOOL os::Kernel32Dll::GetLargePageMinimumAvailable() {
  if (!initialized) {
    initialize();
  }
  return _GetLargePageMinimum != NULL;
}

BOOL os::Kernel32Dll::NumaCallsAvailable() {
  if (!initialized) {
    initialize();
  }
  return _VirtualAllocExNuma != NULL;
}

LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) {
  assert(initialized && _VirtualAllocExNuma != NULL,
    "NUMACallsAvailable() not yet called");

  return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node);
}

BOOL os::Kernel32Dll::GetNumaHighestNodeNumber(PULONG ptr_highest_node_number) {
  assert(initialized && _GetNumaHighestNodeNumber != NULL,
    "NUMACallsAvailable() not yet called");

  return _GetNumaHighestNodeNumber(ptr_highest_node_number);
}

BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) {
  assert(initialized && _GetNumaNodeProcessorMask != NULL,
    "NUMACallsAvailable() not yet called");

  return _GetNumaNodeProcessorMask(node, proc_mask);
}

USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip,
  ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) {
    if (!initialized) {
      initialize();
    }

    if (_RtlCaptureStackBackTrace != NULL) {
      return _RtlCaptureStackBackTrace(FrameToSkip, FrameToCapture,
        BackTrace, BackTraceHash);
    } else {
      return 0;
    }
}

void os::Kernel32Dll::initializeCommon() {
  if (!initialized) {
    HMODULE handle = ::GetModuleHandle("Kernel32.dll");
    assert(handle != NULL, "Just check");
    _GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
    _VirtualAllocExNuma = (VirtualAllocExNuma_Fn)::GetProcAddress(handle, "VirtualAllocExNuma");
    _GetNumaHighestNodeNumber = (GetNumaHighestNodeNumber_Fn)::GetProcAddress(handle, "GetNumaHighestNodeNumber");
    _GetNumaNodeProcessorMask = (GetNumaNodeProcessorMask_Fn)::GetProcAddress(handle, "GetNumaNodeProcessorMask");
    _RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_Fn)::GetProcAddress(handle, "RtlCaptureStackBackTrace");
    initialized = TRUE;
  }
}



#ifndef JDK6_OR_EARLIER

void os::Kernel32Dll::initialize() {
  initializeCommon();
}


// Kernel32 API
inline BOOL os::Kernel32Dll::SwitchToThread() {
  return ::SwitchToThread();
}

inline BOOL os::Kernel32Dll::SwitchToThreadAvailable() {
  return true;
}

  // Help tools
inline BOOL os::Kernel32Dll::HelpToolsAvailable() {
  return true;
}

inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) {
  return ::CreateToolhelp32Snapshot(dwFlags, th32ProcessId);
}

inline BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
  return ::Module32First(hSnapshot, lpme);
}

inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
  return ::Module32Next(hSnapshot, lpme);
}

inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
  ::GetNativeSystemInfo(lpSystemInfo);
}

// PSAPI API
inline BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) {
  return ::EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);
}

inline DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {
  return ::GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);
}

inline BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) {
  return ::GetModuleInformation(hProcess, hModule, lpmodinfo, cb);
}

inline BOOL os::PSApiDll::PSApiAvailable() {
  return true;
}


// WinSock2 API
inline BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
  return ::WSAStartup(wVersionRequested, lpWSAData);
}

inline struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {
  return ::gethostbyname(name);
}

inline BOOL os::WinSock2Dll::WinSock2Available() {
  return true;
}

// Advapi API
inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,
   BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
   PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) {
     return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,
       BufferLength, PreviousState, ReturnLength);
}

inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess,
  PHANDLE TokenHandle) {
    return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);
}

inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) {
  return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid);
}

inline BOOL os::Advapi32Dll::AdvapiAvailable() {
  return true;
}

void* os::get_default_process_handle() {
  return (void*)GetModuleHandle(NULL);
}

// Builds a platform dependent Agent_OnLoad_<lib_name> function name
// which is used to find statically linked in agents.
// Additionally for windows, takes into account __stdcall names.
// Parameters:
//            sym_name: Symbol in library we are looking for
//            lib_name: Name of library to look in, NULL for shared libs.
//            is_absolute_path == true if lib_name is absolute path to agent
//                                     such as "C:/a/b/L.dll"
//            == false if only the base name of the library is passed in
//               such as "L"
char* os::build_agent_function_name(const char *sym_name, const char *lib_name,
                                    bool is_absolute_path) {
  char *agent_entry_name;
  size_t len;
  size_t name_len;
  size_t prefix_len = strlen(JNI_LIB_PREFIX);
  size_t suffix_len = strlen(JNI_LIB_SUFFIX);
  const char *start;

  if (lib_name != NULL) {
    len = name_len = strlen(lib_name);
    if (is_absolute_path) {
      // Need to strip path, prefix and suffix
      if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {
        lib_name = ++start;
      } else {
        // Need to check for drive prefix
        if ((start = strchr(lib_name, ':')) != NULL) {
          lib_name = ++start;
        }
      }
      if (len <= (prefix_len + suffix_len)) {
        return NULL;
      }
      lib_name += prefix_len;
      name_len = strlen(lib_name) - suffix_len;
    }
  }
  len = (lib_name != NULL ? name_len : 0) + strlen(sym_name) + 2;
  agent_entry_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtThread);
  if (agent_entry_name == NULL) {
    return NULL;
  }
  if (lib_name != NULL) {
    const char *p = strrchr(sym_name, '@');
    if (p != NULL && p != sym_name) {
      // sym_name == _Agent_OnLoad@XX
      strncpy(agent_entry_name, sym_name, (p - sym_name));
      agent_entry_name[(p-sym_name)] = '\0';
      // agent_entry_name == _Agent_OnLoad
      strcat(agent_entry_name, "_");
      strncat(agent_entry_name, lib_name, name_len);
      strcat(agent_entry_name, p);
      // agent_entry_name == _Agent_OnLoad_lib_name@XX
    } else {
      strcpy(agent_entry_name, sym_name);
      strcat(agent_entry_name, "_");
      strncat(agent_entry_name, lib_name, name_len);
    }
  } else {
    strcpy(agent_entry_name, sym_name);
  }
  return agent_entry_name;
}

#else
// Kernel32 API
typedef BOOL (WINAPI* SwitchToThread_Fn)(void);
typedef HANDLE (WINAPI* CreateToolhelp32Snapshot_Fn)(DWORD,DWORD);
typedef BOOL (WINAPI* Module32First_Fn)(HANDLE,LPMODULEENTRY32);
typedef BOOL (WINAPI* Module32Next_Fn)(HANDLE,LPMODULEENTRY32);
typedef void (WINAPI* GetNativeSystemInfo_Fn)(LPSYSTEM_INFO);

SwitchToThread_Fn           os::Kernel32Dll::_SwitchToThread = NULL;
CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL;
Module32First_Fn            os::Kernel32Dll::_Module32First = NULL;
Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;

void os::Kernel32Dll::initialize() {
  if (!initialized) {
    HMODULE handle = ::GetModuleHandle("Kernel32.dll");
    assert(handle != NULL, "Just check");

    _SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");
    _CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)
      ::GetProcAddress(handle, "CreateToolhelp32Snapshot");
    _Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");
    _Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");
    _GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");
    initializeCommon();  // resolve the functions that always need resolving

    initialized = TRUE;
  }
}

BOOL os::Kernel32Dll::SwitchToThread() {
  assert(initialized && _SwitchToThread != NULL,
    "SwitchToThreadAvailable() not yet called");
  return _SwitchToThread();
}


BOOL os::Kernel32Dll::SwitchToThreadAvailable() {
  if (!initialized) {
    initialize();
  }
  return _SwitchToThread != NULL;
}

// Help tools
BOOL os::Kernel32Dll::HelpToolsAvailable() {
  if (!initialized) {
    initialize();
  }
  return _CreateToolhelp32Snapshot != NULL &&
         _Module32First != NULL &&
         _Module32Next != NULL;
}

HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) {
  assert(initialized && _CreateToolhelp32Snapshot != NULL,
    "HelpToolsAvailable() not yet called");

  return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId);
}

BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
  assert(initialized && _Module32First != NULL,
    "HelpToolsAvailable() not yet called");

  return _Module32First(hSnapshot, lpme);
}

inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
  assert(initialized && _Module32Next != NULL,
    "HelpToolsAvailable() not yet called");

  return _Module32Next(hSnapshot, lpme);
}


BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
  if (!initialized) {
    initialize();
  }
  return _GetNativeSystemInfo != NULL;
}

void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
  assert(initialized && _GetNativeSystemInfo != NULL,
    "GetNativeSystemInfoAvailable() not yet called");

  _GetNativeSystemInfo(lpSystemInfo);
}

// PSAPI API


typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD);
typedef BOOL (WINAPI *GetModuleFileNameEx_Fn)(HANDLE, HMODULE, LPTSTR, DWORD);;
typedef BOOL (WINAPI *GetModuleInformation_Fn)(HANDLE, HMODULE, LPMODULEINFO, DWORD);

EnumProcessModules_Fn   os::PSApiDll::_EnumProcessModules = NULL;
GetModuleFileNameEx_Fn  os::PSApiDll::_GetModuleFileNameEx = NULL;
GetModuleInformation_Fn os::PSApiDll::_GetModuleInformation = NULL;
BOOL                    os::PSApiDll::initialized = FALSE;

void os::PSApiDll::initialize() {
  if (!initialized) {
    HMODULE handle = os::win32::load_Windows_dll("PSAPI.DLL", NULL, 0);
    if (handle != NULL) {
      _EnumProcessModules = (EnumProcessModules_Fn)::GetProcAddress(handle,
        "EnumProcessModules");
      _GetModuleFileNameEx = (GetModuleFileNameEx_Fn)::GetProcAddress(handle,
        "GetModuleFileNameExA");
      _GetModuleInformation = (GetModuleInformation_Fn)::GetProcAddress(handle,
        "GetModuleInformation");
    }
    initialized = TRUE;
  }
}



BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) {
  assert(initialized && _EnumProcessModules != NULL,
    "PSApiAvailable() not yet called");
  return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);
}

DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {
  assert(initialized && _GetModuleFileNameEx != NULL,
    "PSApiAvailable() not yet called");
  return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);
}

BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) {
  assert(initialized && _GetModuleInformation != NULL,
    "PSApiAvailable() not yet called");
  return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb);
}

BOOL os::PSApiDll::PSApiAvailable() {
  if (!initialized) {
    initialize();
  }
  return _EnumProcessModules != NULL &&
    _GetModuleFileNameEx != NULL &&
    _GetModuleInformation != NULL;
}


// WinSock2 API
typedef int (PASCAL FAR* WSAStartup_Fn)(WORD, LPWSADATA);
typedef struct hostent *(PASCAL FAR *gethostbyname_Fn)(...);

WSAStartup_Fn    os::WinSock2Dll::_WSAStartup = NULL;
gethostbyname_Fn os::WinSock2Dll::_gethostbyname = NULL;
BOOL             os::WinSock2Dll::initialized = FALSE;

void os::WinSock2Dll::initialize() {
  if (!initialized) {
    HMODULE handle = os::win32::load_Windows_dll("ws2_32.dll", NULL, 0);
    if (handle != NULL) {
      _WSAStartup = (WSAStartup_Fn)::GetProcAddress(handle, "WSAStartup");
      _gethostbyname = (gethostbyname_Fn)::GetProcAddress(handle, "gethostbyname");
    }
    initialized = TRUE;
  }
}


BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
  assert(initialized && _WSAStartup != NULL,
    "WinSock2Available() not yet called");
  return _WSAStartup(wVersionRequested, lpWSAData);
}

struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {
  assert(initialized && _gethostbyname != NULL,
    "WinSock2Available() not yet called");
  return _gethostbyname(name);
}

BOOL os::WinSock2Dll::WinSock2Available() {
  if (!initialized) {
    initialize();
  }
  return _WSAStartup != NULL &&
    _gethostbyname != NULL;
}

typedef BOOL (WINAPI *AdjustTokenPrivileges_Fn)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
typedef BOOL (WINAPI *OpenProcessToken_Fn)(HANDLE, DWORD, PHANDLE);
typedef BOOL (WINAPI *LookupPrivilegeValue_Fn)(LPCTSTR, LPCTSTR, PLUID);

AdjustTokenPrivileges_Fn os::Advapi32Dll::_AdjustTokenPrivileges = NULL;
OpenProcessToken_Fn      os::Advapi32Dll::_OpenProcessToken = NULL;
LookupPrivilegeValue_Fn  os::Advapi32Dll::_LookupPrivilegeValue = NULL;
BOOL                     os::Advapi32Dll::initialized = FALSE;

void os::Advapi32Dll::initialize() {
  if (!initialized) {
    HMODULE handle = os::win32::load_Windows_dll("advapi32.dll", NULL, 0);
    if (handle != NULL) {
      _AdjustTokenPrivileges = (AdjustTokenPrivileges_Fn)::GetProcAddress(handle,
        "AdjustTokenPrivileges");
      _OpenProcessToken = (OpenProcessToken_Fn)::GetProcAddress(handle,
        "OpenProcessToken");
      _LookupPrivilegeValue = (LookupPrivilegeValue_Fn)::GetProcAddress(handle,
        "LookupPrivilegeValueA");
    }
    initialized = TRUE;
  }
}

BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,
   BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
   PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) {
   assert(initialized && _AdjustTokenPrivileges != NULL,
     "AdvapiAvailable() not yet called");
   return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,
       BufferLength, PreviousState, ReturnLength);
}

BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess,
  PHANDLE TokenHandle) {
   assert(initialized && _OpenProcessToken != NULL,
     "AdvapiAvailable() not yet called");
    return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);
}

BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) {
   assert(initialized && _LookupPrivilegeValue != NULL,
     "AdvapiAvailable() not yet called");
  return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid);
}

BOOL os::Advapi32Dll::AdvapiAvailable() {
  if (!initialized) {
    initialize();
  }
  return _AdjustTokenPrivileges != NULL &&
    _OpenProcessToken != NULL &&
    _LookupPrivilegeValue != NULL;
}

#endif

#ifndef PRODUCT

// test the code path in reserve_memory_special() that tries to allocate memory in a single
// contiguous memory block at a particular address.
// The test first tries to find a good approximate address to allocate at by using the same
// method to allocate some memory at any address. The test then tries to allocate memory in
// the vicinity (not directly after it to avoid possible by-chance use of that location)
// This is of course only some dodgy assumption, there is no guarantee that the vicinity of
// the previously allocated memory is available for allocation. The only actual failure
// that is reported is when the test tries to allocate at a particular location but gets a
// different valid one. A NULL return value at this point is not considered an error but may
// be legitimate.
// If -XX:+VerboseInternalVMTests is enabled, print some explanatory messages.
void TestReserveMemorySpecial_test() {
  if (!UseLargePages) {
    if (VerboseInternalVMTests) {
      gclog_or_tty->print("Skipping test because large pages are disabled");
    }
    return;
  }
  // save current value of globals
  bool old_use_large_pages_individual_allocation = UseLargePagesIndividualAllocation;
  bool old_use_numa_interleaving = UseNUMAInterleaving;

  // set globals to make sure we hit the correct code path
  UseLargePagesIndividualAllocation = UseNUMAInterleaving = false;

  // do an allocation at an address selected by the OS to get a good one.
  const size_t large_allocation_size = os::large_page_size() * 4;
  char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
  if (result == NULL) {
    if (VerboseInternalVMTests) {
      gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.",
        large_allocation_size);
    }
  } else {
    os::release_memory_special(result, large_allocation_size);

    // allocate another page within the recently allocated memory area which seems to be a good location. At least
    // we managed to get it once.
    const size_t expected_allocation_size = os::large_page_size();
    char* expected_location = result + os::large_page_size();
    char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
    if (actual_location == NULL) {
      if (VerboseInternalVMTests) {
        gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.",
          expected_location, large_allocation_size);
      }
    } else {
      // release memory
      os::release_memory_special(actual_location, expected_allocation_size);
      // only now check, after releasing any memory to avoid any leaks.
      assert(actual_location == expected_location,
        err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead",
          expected_location, expected_allocation_size, actual_location));
    }
  }

  // restore globals
  UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation;
  UseNUMAInterleaving = old_use_numa_interleaving;
}
#endif // PRODUCT

