os_windows.cpp revision 1934:aa6e219afbf1
160484Sobrien/*
2218822Sdim * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3218822Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
433965Sjdp *
533965Sjdp * This code is free software; you can redistribute it and/or modify it
633965Sjdp * under the terms of the GNU General Public License version 2 only, as
733965Sjdp * published by the Free Software Foundation.
833965Sjdp *
933965Sjdp * This code is distributed in the hope that it will be useful, but WITHOUT
1033965Sjdp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1133965Sjdp * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1233965Sjdp * version 2 for more details (a copy is included in the LICENSE file that
1333965Sjdp * accompanied this code).
1433965Sjdp *
1533965Sjdp * You should have received a copy of the GNU General Public License version
1633965Sjdp * 2 along with this work; if not, write to the Free Software Foundation,
1733965Sjdp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1833965Sjdp *
19218822Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20218822Sdim * or visit www.oracle.com if you need additional information or have any
2133965Sjdp * questions.
2233965Sjdp *
23130561Sobrien */
2433965Sjdp
2533965Sjdp#ifdef _WIN64
2633965Sjdp// Must be at least Windows 2000 or XP to use VectoredExceptions
2733965Sjdp#define _WIN32_WINNT 0x500
2833965Sjdp#endif
2933965Sjdp
3033965Sjdp// no precompiled headers
3133965Sjdp#include "classfile/classLoader.hpp"
3233965Sjdp#include "classfile/systemDictionary.hpp"
3333965Sjdp#include "classfile/vmSymbols.hpp"
3460484Sobrien#include "code/icBuffer.hpp"
3533965Sjdp#include "code/vtableStubs.hpp"
3633965Sjdp#include "compiler/compileBroker.hpp"
3733965Sjdp#include "interpreter/interpreter.hpp"
3833965Sjdp#include "jvm_windows.h"
3960484Sobrien#include "memory/allocation.inline.hpp"
4033965Sjdp#include "memory/filemap.hpp"
4133965Sjdp#include "mutex_windows.inline.hpp"
4233965Sjdp#include "oops/oop.inline.hpp"
4333965Sjdp#include "os_share_windows.hpp"
4460484Sobrien#include "prims/jniFastGetField.hpp"
4533965Sjdp#include "prims/jvm.h"
4633965Sjdp#include "prims/jvm_misc.hpp"
4760484Sobrien#include "runtime/arguments.hpp"
4833965Sjdp#include "runtime/extendedPC.hpp"
4933965Sjdp#include "runtime/globals.hpp"
5089857Sobrien#include "runtime/interfaceSupport.hpp"
5189857Sobrien#include "runtime/java.hpp"
52130561Sobrien#include "runtime/javaCalls.hpp"
5333965Sjdp#include "runtime/mutexLocker.hpp"
5489857Sobrien#include "runtime/objectMonitor.hpp"
5589857Sobrien#include "runtime/osThread.hpp"
5689857Sobrien#include "runtime/perfMemory.hpp"
5733965Sjdp#include "runtime/sharedRuntime.hpp"
5860484Sobrien#include "runtime/statSampler.hpp"
5960484Sobrien#include "runtime/stubRoutines.hpp"
60218822Sdim#include "runtime/threadCritical.hpp"
6160484Sobrien#include "runtime/timer.hpp"
6260484Sobrien#include "services/attachListener.hpp"
63130561Sobrien#include "services/runtimeService.hpp"
6433965Sjdp#include "thread_windows.inline.hpp"
6533965Sjdp#include "utilities/decoder.hpp"
6633965Sjdp#include "utilities/defaultStream.hpp"
6733965Sjdp#include "utilities/events.hpp"
6833965Sjdp#include "utilities/growableArray.hpp"
6933965Sjdp#include "utilities/vmError.hpp"
7033965Sjdp#ifdef TARGET_ARCH_x86
7133965Sjdp# include "assembler_x86.inline.hpp"
7233965Sjdp# include "nativeInst_x86.hpp"
7333965Sjdp#endif
7433965Sjdp#ifdef COMPILER1
7533965Sjdp#include "c1/c1_Runtime1.hpp"
7633965Sjdp#endif
7733965Sjdp#ifdef COMPILER2
7833965Sjdp#include "opto/runtime.hpp"
7933965Sjdp#endif
8033965Sjdp
8133965Sjdp#ifdef _DEBUG
8233965Sjdp#include <crtdbg.h>
8333965Sjdp#endif
8433965Sjdp
8533965Sjdp
8633965Sjdp#include <windows.h>
8733965Sjdp#include <sys/types.h>
8860484Sobrien#include <sys/stat.h>
8933965Sjdp#include <sys/timeb.h>
9033965Sjdp#include <objidl.h>
9133965Sjdp#include <shlobj.h>
9233965Sjdp
9333965Sjdp#include <malloc.h>
9433965Sjdp#include <signal.h>
9533965Sjdp#include <direct.h>
9633965Sjdp#include <errno.h>
9733965Sjdp#include <fcntl.h>
9833965Sjdp#include <io.h>
9960484Sobrien#include <process.h>              // For _beginthreadex(), _endthreadex()
10060484Sobrien#include <imagehlp.h>             // For os::dll_address_to_function_name
10133965Sjdp
10233965Sjdp/* for enumerating dll libraries */
10360484Sobrien#include <tlhelp32.h>
10433965Sjdp#include <vdmdbg.h>
10560484Sobrien
10633965Sjdp// for timer info max values which include all bits
10733965Sjdp#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
10860484Sobrien
10933965Sjdp// For DLL loading/load error detection
11060484Sobrien// Values of PE COFF
11133965Sjdp#define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
11233965Sjdp#define IMAGE_FILE_SIGNATURE_LENGTH 4
11360484Sobrien
11433965Sjdpstatic HANDLE main_process;
11533965Sjdpstatic HANDLE main_thread;
11633965Sjdpstatic int    main_thread_id;
117104834Sobrien
11860484Sobrienstatic FILETIME process_creation_time;
11933965Sjdpstatic FILETIME process_exit_time;
12060484Sobrienstatic FILETIME process_user_time;
12133965Sjdpstatic FILETIME process_kernel_time;
12233965Sjdp
12360484Sobrien#ifdef _WIN64
12433965SjdpPVOID  topLevelVectoredExceptionHandler = NULL;
12560484Sobrien#endif
12633965Sjdp
12733965Sjdp#ifdef _M_IA64
12860484Sobrien#define __CPU__ ia64
12933965Sjdp#elif _M_AMD64
13060484Sobrien#define __CPU__ amd64
13133965Sjdp#else
13233965Sjdp#define __CPU__ i486
13360484Sobrien#endif
13460484Sobrien
13533965Sjdp// save DLL module handle, used by GetModuleFileName
13660484Sobrien
13760484SobrienHINSTANCE vm_lib_handle;
13833965Sjdpstatic int getLastErrorString(char *buf, size_t len);
13933965Sjdp
14060484SobrienBOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
14133965Sjdp  switch (reason) {
14233965Sjdp    case DLL_PROCESS_ATTACH:
14333965Sjdp      vm_lib_handle = hinst;
14433965Sjdp      if(ForceTimeHighResolution)
14560484Sobrien        timeBeginPeriod(1L);
14633965Sjdp      break;
14733965Sjdp    case DLL_PROCESS_DETACH:
14833965Sjdp      if(ForceTimeHighResolution)
14933965Sjdp        timeEndPeriod(1L);
15060484Sobrien#ifdef _WIN64
15133965Sjdp      if (topLevelVectoredExceptionHandler != NULL) {
15260484Sobrien        RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
15333965Sjdp        topLevelVectoredExceptionHandler = NULL;
15460484Sobrien      }
15560484Sobrien#endif
15660484Sobrien      break;
15733965Sjdp    default:
15833965Sjdp      break;
15933965Sjdp  }
16033965Sjdp  return true;
16160484Sobrien}
16260484Sobrien
16360484Sobrienstatic inline double fileTimeAsDouble(FILETIME* time) {
164104834Sobrien  const double high  = (double) ((unsigned int) ~0);
16560484Sobrien  const double split = 10000000.0;
16633965Sjdp  double result = (time->dwLowDateTime / split) +
16760484Sobrien                   time->dwHighDateTime * (high/split);
168104834Sobrien  return result;
16933965Sjdp}
17033965Sjdp
17160484Sobrien// Implementation of os
172104834Sobrien
17360484Sobrienbool os::getenv(const char* name, char* buffer, int len) {
17433965Sjdp int result = GetEnvironmentVariable(name, buffer, len);
17560484Sobrien return result > 0 && result < len;
17633965Sjdp}
17760484Sobrien
17860484Sobrien
17960484Sobrien// No setuid programs under Windows.
18060484Sobrienbool os::have_special_privileges() {
18160484Sobrien  return false;
182104834Sobrien}
18360484Sobrien
18460484Sobrien
18560484Sobrien// This method is  a periodic task to check for misbehaving JNI applications
18660484Sobrien// under CheckJNI, we can add any periodic checks here.
187104834Sobrien// For Windows at the moment does nothing
18860484Sobrienvoid os::run_periodic_checks() {
18960484Sobrien  return;
19060484Sobrien}
19160484Sobrien
192104834Sobrien#ifndef _WIN64
19360484Sobrien// previous UnhandledExceptionFilter, if there is one
19460484Sobrienstatic LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;
19560484Sobrien
196104834SobrienLONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);
197130561Sobrien#endif
19833965Sjdpvoid os::init_system_properties_values() {
19933965Sjdp  /* sysclasspath, java_home, dll_dir */
20033965Sjdp  {
20133965Sjdp      char *home_path;
20233965Sjdp      char *dll_path;
20333965Sjdp      char *pslash;
20433965Sjdp      char *bin = "\\bin";
20533965Sjdp      char home_dir[MAX_PATH];
20633965Sjdp
20733965Sjdp      if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {
20860484Sobrien          os::jvm_path(home_dir, sizeof(home_dir));
20933965Sjdp          // Found the full path to jvm[_g].dll.
21033965Sjdp          // Now cut the path to <java_home>/jre if we can.
21133965Sjdp          *(strrchr(home_dir, '\\')) = '\0';  /* get rid of \jvm.dll */
21233965Sjdp          pslash = strrchr(home_dir, '\\');
21333965Sjdp          if (pslash != NULL) {
21433965Sjdp              *pslash = '\0';                 /* get rid of \{client|server} */
21533965Sjdp              pslash = strrchr(home_dir, '\\');
21633965Sjdp              if (pslash != NULL)
21733965Sjdp                  *pslash = '\0';             /* get rid of \bin */
21833965Sjdp          }
21933965Sjdp      }
22033965Sjdp
22133965Sjdp      home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1);
22233965Sjdp      if (home_path == NULL)
22333965Sjdp          return;
22433965Sjdp      strcpy(home_path, home_dir);
22533965Sjdp      Arguments::set_java_home(home_path);
22633965Sjdp
22733965Sjdp      dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1);
22833965Sjdp      if (dll_path == NULL)
22933965Sjdp          return;
23033965Sjdp      strcpy(dll_path, home_dir);
23133965Sjdp      strcat(dll_path, bin);
23233965Sjdp      Arguments::set_dll_dir(dll_path);
233130561Sobrien
23433965Sjdp      if (!set_boot_path('\\', ';'))
23533965Sjdp          return;
23633965Sjdp  }
23733965Sjdp
23833965Sjdp  /* library_path */
23933965Sjdp  #define EXT_DIR "\\lib\\ext"
24033965Sjdp  #define BIN_DIR "\\bin"
24133965Sjdp  #define PACKAGE_DIR "\\Sun\\Java"
24233965Sjdp  {
24333965Sjdp    /* Win32 library search order (See the documentation for LoadLibrary):
24433965Sjdp     *
24533965Sjdp     * 1. The directory from which application is loaded.
246218822Sdim     * 2. The current directory
24733965Sjdp     * 3. The system wide Java Extensions directory (Java only)
24833965Sjdp     * 4. System directory (GetSystemDirectory)
24933965Sjdp     * 5. Windows directory (GetWindowsDirectory)
25033965Sjdp     * 6. The PATH environment variable
25160484Sobrien     */
252218822Sdim
25338889Sjdp    char *library_path;
25489857Sobrien    char tmp[MAX_PATH];
25538889Sjdp    char *path_str = ::getenv("PATH");
25638889Sjdp
25760484Sobrien    library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +
25860484Sobrien        sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10);
259218822Sdim
26060484Sobrien    library_path[0] = '\0';
26160484Sobrien
26260484Sobrien    GetModuleFileName(NULL, tmp, sizeof(tmp));
26360484Sobrien    *(strrchr(tmp, '\\')) = '\0';
26460484Sobrien    strcat(library_path, tmp);
265218822Sdim
266218822Sdim    strcat(library_path, ";.");
267218822Sdim
26860484Sobrien    GetWindowsDirectory(tmp, sizeof(tmp));
26960484Sobrien    strcat(library_path, ";");
270130561Sobrien    strcat(library_path, tmp);
271130561Sobrien    strcat(library_path, PACKAGE_DIR BIN_DIR);
27260484Sobrien
27360484Sobrien    GetSystemDirectory(tmp, sizeof(tmp));
27460484Sobrien    strcat(library_path, ";");
27560484Sobrien    strcat(library_path, tmp);
27660484Sobrien
277104834Sobrien    GetWindowsDirectory(tmp, sizeof(tmp));
27833965Sjdp    strcat(library_path, ";");
27933965Sjdp    strcat(library_path, tmp);
28038889Sjdp
28138889Sjdp    if (path_str) {
28233965Sjdp        strcat(library_path, ";");
283130561Sobrien        strcat(library_path, path_str);
28433965Sjdp    }
28533965Sjdp
286130561Sobrien    Arguments::set_library_path(library_path);
28733965Sjdp    FREE_C_HEAP_ARRAY(char, library_path);
28833965Sjdp  }
28933965Sjdp
29033965Sjdp  /* Default extensions directory */
29133965Sjdp  {
29233965Sjdp    char path[MAX_PATH];
29333965Sjdp    char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1];
29438889Sjdp    GetWindowsDirectory(path, MAX_PATH);
29538889Sjdp    sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR,
29638889Sjdp        path, PACKAGE_DIR, EXT_DIR);
29733965Sjdp    Arguments::set_ext_dirs(buf);
29838889Sjdp  }
29938889Sjdp  #undef EXT_DIR
30033965Sjdp  #undef BIN_DIR
30138889Sjdp  #undef PACKAGE_DIR
30238889Sjdp
30338889Sjdp  /* Default endorsed standards directory. */
30438889Sjdp  {
30538889Sjdp    #define ENDORSED_DIR "\\lib\\endorsed"
30638889Sjdp    size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);
30738889Sjdp    char * buf = NEW_C_HEAP_ARRAY(char, len);
30838889Sjdp    sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
30933965Sjdp    Arguments::set_endorsed_dirs(buf);
31060484Sobrien    #undef ENDORSED_DIR
31133965Sjdp  }
31260484Sobrien
31360484Sobrien#ifndef _WIN64
31460484Sobrien  // set our UnhandledExceptionFilter and save any previous one
31560484Sobrien  prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);
31660484Sobrien#endif
31760484Sobrien
31860484Sobrien  // Done
31960484Sobrien  return;
32060484Sobrien}
32160484Sobrien
32260484Sobrienvoid os::breakpoint() {
32360484Sobrien  DebugBreak();
32460484Sobrien}
32560484Sobrien
32660484Sobrien// Invoked from the BREAKPOINT Macro
327130561Sobrienextern "C" void breakpoint() {
328130561Sobrien  os::breakpoint();
32960484Sobrien}
33060484Sobrien
33160484Sobrien// Returns an estimate of the current stack pointer. Result must be guaranteed
33260484Sobrien// to point into the calling threads stack, and be no lower than the current
33360484Sobrien// stack pointer.
334130561Sobrien
335130561Sobrienaddress os::current_stack_pointer() {
336130561Sobrien  int dummy;
337130561Sobrien  address sp = (address)&dummy;
338130561Sobrien  return sp;
33960484Sobrien}
34060484Sobrien
34160484Sobrien// os::current_stack_base()
34260484Sobrien//
34360484Sobrien//   Returns the base of the stack, which is the stack's
34460484Sobrien//   starting address.  This function must be called
34560484Sobrien//   while running on the stack of the thread being queried.
34660484Sobrien
34760484Sobrienaddress os::current_stack_base() {
34860484Sobrien  MEMORY_BASIC_INFORMATION minfo;
349130561Sobrien  address stack_bottom;
350130561Sobrien  size_t stack_size;
35133965Sjdp
35233965Sjdp  VirtualQuery(&minfo, &minfo, sizeof(minfo));
35333965Sjdp  stack_bottom =  (address)minfo.AllocationBase;
35433965Sjdp  stack_size = minfo.RegionSize;
35533965Sjdp
35633965Sjdp  // Add up the sizes of all the regions with the same
35733965Sjdp  // AllocationBase.
35833965Sjdp  while( 1 )
35933965Sjdp  {
36033965Sjdp    VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));
361218822Sdim    if ( stack_bottom == (address)minfo.AllocationBase )
36233965Sjdp      stack_size += minfo.RegionSize;
36333965Sjdp    else
364130561Sobrien      break;
36560484Sobrien  }
366130561Sobrien
36760484Sobrien#ifdef _M_IA64
368130561Sobrien  // IA64 has memory and register stacks
36960484Sobrien  stack_size = stack_size / 2;
370130561Sobrien#endif
37160484Sobrien  return stack_bottom + stack_size;
37260484Sobrien}
37360484Sobrien
37460484Sobriensize_t os::current_stack_size() {
375130561Sobrien  size_t sz;
37660484Sobrien  MEMORY_BASIC_INFORMATION minfo;
377130561Sobrien  VirtualQuery(&minfo, &minfo, sizeof(minfo));
37860484Sobrien  sz = (size_t)os::current_stack_base() - (size_t)minfo.AllocationBase;
37933965Sjdp  return sz;
38033965Sjdp}
38160484Sobrien
38233965Sjdpstruct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
38333965Sjdp  const struct tm* time_struct_ptr = localtime(clock);
38438889Sjdp  if (time_struct_ptr != NULL) {
38560484Sobrien    *res = *time_struct_ptr;
386218822Sdim    return res;
38733965Sjdp  }
38838889Sjdp  return NULL;
38938889Sjdp}
39033965Sjdp
391218822SdimLONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
39238889Sjdp
39333965Sjdp// Thread start routine for all new Java threads
394218822Sdimstatic unsigned __stdcall java_start(Thread* thread) {
395218822Sdim  // Try to randomize the cache line index of hot stack frames.
396218822Sdim  // This helps when threads of the same stack traces evict each other's
39777298Sobrien  // cache lines. The threads can be either from the same JVM instance, or
39833965Sjdp  // from different JVM instances. The benefit is especially true for
399218822Sdim  // processors with hyperthreading technology.
400218822Sdim  static int counter = 0;
401218822Sdim  int pid = os::current_process_id();
402218822Sdim  _alloca(((pid ^ counter++) & 7) * 128);
403218822Sdim
40438889Sjdp  OSThread* osthr = thread->osthread();
40533965Sjdp  assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
40633965Sjdp
407218822Sdim  if (UseNUMA) {
408218822Sdim    int lgrp_id = os::numa_get_group_id();
409218822Sdim    if (lgrp_id != -1) {
410218822Sdim      thread->set_lgrp_id(lgrp_id);
411218822Sdim    }
41238889Sjdp  }
41333965Sjdp
41433965Sjdp
415218822Sdim  if (UseVectoredExceptions) {
41660484Sobrien    // If we are using vectored exception we don't need to set a SEH
41760484Sobrien    thread->run();
41860484Sobrien  }
419218822Sdim  else {
42060484Sobrien    // Install a win32 structured exception handler around every thread created
42160484Sobrien    // by VM, so VM can genrate error dump when an exception occurred in non-
42260484Sobrien    // Java thread (e.g. VM thread).
423218822Sdim    __try {
42460484Sobrien       thread->run();
42560484Sobrien    } __except(topLevelExceptionFilter(
42660484Sobrien               (_EXCEPTION_POINTERS*)_exception_info())) {
427218822Sdim        // Nothing to do.
42860484Sobrien    }
42960484Sobrien  }
43060484Sobrien
43160484Sobrien  // One less thread is executing
43260484Sobrien  // When the VMThread gets here, the main thread may have already exited
43360484Sobrien  // which frees the CodeHeap containing the Atomic::add code
43460484Sobrien  if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
43560484Sobrien    Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
43660484Sobrien  }
43760484Sobrien
43860484Sobrien  return 0;
43960484Sobrien}
440218822Sdim
441218822Sdimstatic OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) {
44233965Sjdp  // Allocate the OSThread object
443218822Sdim  OSThread* osthread = new OSThread(NULL, NULL);
444218822Sdim  if (osthread == NULL) return NULL;
445218822Sdim
446130561Sobrien  // Initialize support for Java interrupts
447130561Sobrien  HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
448130561Sobrien  if (interrupt_event == NULL) {
449130561Sobrien    delete osthread;
450130561Sobrien    return NULL;
451130561Sobrien  }
45260484Sobrien  osthread->set_interrupt_event(interrupt_event);
453130561Sobrien
454130561Sobrien  // Store info on the Win32 thread into the OSThread
455130561Sobrien  osthread->set_thread_handle(thread_handle);
456130561Sobrien  osthread->set_thread_id(thread_id);
457130561Sobrien
458130561Sobrien  if (UseNUMA) {
459130561Sobrien    int lgrp_id = os::numa_get_group_id();
460130561Sobrien    if (lgrp_id != -1) {
46138889Sjdp      thread->set_lgrp_id(lgrp_id);
46238889Sjdp    }
46338889Sjdp  }
46438889Sjdp
46533965Sjdp  // Initial thread state is INITIALIZED, not SUSPENDED
46638889Sjdp  osthread->set_state(INITIALIZED);
46738889Sjdp
46860484Sobrien  return osthread;
46960484Sobrien}
47038889Sjdp
47138889Sjdp
47233965Sjdpbool os::create_attached_thread(JavaThread* thread) {
47360484Sobrien#ifdef ASSERT
47460484Sobrien  thread->verify_not_published();
47560484Sobrien#endif
47660484Sobrien  HANDLE thread_h;
47760484Sobrien  if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),
47860484Sobrien                       &thread_h, THREAD_ALL_ACCESS, false, 0)) {
47960484Sobrien    fatal("DuplicateHandle failed\n");
48060484Sobrien  }
48160484Sobrien  OSThread* osthread = create_os_thread(thread, thread_h,
48260484Sobrien                                        (int)current_thread_id());
48360484Sobrien  if (osthread == NULL) {
48460484Sobrien     return false;
48560484Sobrien  }
48660484Sobrien
48760484Sobrien  // Initial thread state is RUNNABLE
48860484Sobrien  osthread->set_state(RUNNABLE);
48960484Sobrien
49060484Sobrien  thread->set_osthread(osthread);
49160484Sobrien  return true;
49260484Sobrien}
49360484Sobrien
49460484Sobrienbool os::create_main_thread(JavaThread* thread) {
495104834Sobrien#ifdef ASSERT
49660484Sobrien  thread->verify_not_published();
49760484Sobrien#endif
498104834Sobrien  if (_starting_thread == NULL) {
49960484Sobrien    _starting_thread = create_os_thread(thread, main_thread, main_thread_id);
50060484Sobrien     if (_starting_thread == NULL) {
50160484Sobrien        return false;
50260484Sobrien     }
50360484Sobrien  }
504104834Sobrien
50560484Sobrien  // The primordial thread is runnable from the start)
50660484Sobrien  _starting_thread->set_state(RUNNABLE);
507104834Sobrien
50860484Sobrien  thread->set_osthread(_starting_thread);
50960484Sobrien  return true;
510130561Sobrien}
511130561Sobrien
512130561Sobrien// Allocate and initialize a new OSThread
513130561Sobrienbool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
514130561Sobrien  unsigned thread_id;
51560484Sobrien
51660484Sobrien  // Allocate the OSThread object
51733965Sjdp  OSThread* osthread = new OSThread(NULL, NULL);
51833965Sjdp  if (osthread == NULL) {
51933965Sjdp    return false;
52033965Sjdp  }
52133965Sjdp
52233965Sjdp  // Initialize support for Java interrupts
52333965Sjdp  HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
52433965Sjdp  if (interrupt_event == NULL) {
52533965Sjdp    delete osthread;
52638889Sjdp    return NULL;
527130561Sobrien  }
528130561Sobrien  osthread->set_interrupt_event(interrupt_event);
52938889Sjdp  osthread->set_interrupted(false);
53038889Sjdp
53133965Sjdp  thread->set_osthread(osthread);
53233965Sjdp
53333965Sjdp  if (stack_size == 0) {
53438889Sjdp    switch (thr_type) {
53538889Sjdp    case os::java_thread:
53638889Sjdp      // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
53738889Sjdp      if (JavaThread::stack_size_at_create() > 0)
53838889Sjdp        stack_size = JavaThread::stack_size_at_create();
53938889Sjdp      break;
54038889Sjdp    case os::compiler_thread:
54138889Sjdp      if (CompilerThreadStackSize > 0) {
54238889Sjdp        stack_size = (size_t)(CompilerThreadStackSize * K);
54338889Sjdp        break;
54438889Sjdp      } // else fall through:
54560484Sobrien        // use VMThreadStackSize if CompilerThreadStackSize is not defined
54638889Sjdp    case os::vm_thread:
54733965Sjdp    case os::pgc_thread:
54838889Sjdp    case os::cgc_thread:
549130561Sobrien    case os::watcher_thread:
550130561Sobrien      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
55138889Sjdp      break;
55238889Sjdp    }
55360484Sobrien  }
55460484Sobrien
55533965Sjdp  // Create the Win32 thread
55633965Sjdp  //
55733965Sjdp  // Contrary to what MSDN document says, "stack_size" in _beginthreadex()
55860484Sobrien  // does not specify stack size. Instead, it specifies the size of
55933965Sjdp  // initially committed space. The stack size is determined by
56060484Sobrien  // PE header in the executable. If the committed "stack_size" is larger
56160484Sobrien  // than default value in the PE header, the stack is rounded up to the
56260484Sobrien  // nearest multiple of 1MB. For example if the launcher has default
56333965Sjdp  // stack size of 320k, specifying any size less than 320k does not
56433965Sjdp  // affect the actual stack size at all, it only affects the initial
56533965Sjdp  // commitment. On the other hand, specifying 'stack_size' larger than
56633965Sjdp  // default value may cause significant increase in memory usage, because
56760484Sobrien  // not only the stack space will be rounded up to MB, but also the
56860484Sobrien  // entire space is committed upfront.
56960484Sobrien  //
57060484Sobrien  // Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'
57133965Sjdp  // for CreateThread() that can treat 'stack_size' as stack size. However we
57233965Sjdp  // are not supposed to call CreateThread() directly according to MSDN
57333965Sjdp  // document because JVM uses C runtime library. The good news is that the
57433965Sjdp  // flag appears to work with _beginthredex() as well.
57560484Sobrien
57660484Sobrien#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
57760484Sobrien#define STACK_SIZE_PARAM_IS_A_RESERVATION  (0x10000)
57860484Sobrien#endif
57933965Sjdp
58033965Sjdp  HANDLE thread_handle =
58160484Sobrien    (HANDLE)_beginthreadex(NULL,
58260484Sobrien                           (unsigned)stack_size,
58360484Sobrien                           (unsigned (__stdcall *)(void*)) java_start,
58460484Sobrien                           thread,
58560484Sobrien                           CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
58660484Sobrien                           &thread_id);
58760484Sobrien  if (thread_handle == NULL) {
58860484Sobrien    // perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again
58960484Sobrien    // without the flag.
59060484Sobrien    thread_handle =
59160484Sobrien    (HANDLE)_beginthreadex(NULL,
59260484Sobrien                           (unsigned)stack_size,
59360484Sobrien                           (unsigned (__stdcall *)(void*)) java_start,
59460484Sobrien                           thread,
59560484Sobrien                           CREATE_SUSPENDED,
59660484Sobrien                           &thread_id);
59760484Sobrien  }
59860484Sobrien  if (thread_handle == NULL) {
59960484Sobrien    // Need to clean up stuff we've allocated so far
60060484Sobrien    CloseHandle(osthread->interrupt_event());
60160484Sobrien    thread->set_osthread(NULL);
60260484Sobrien    delete osthread;
60360484Sobrien    return NULL;
60460484Sobrien  }
60560484Sobrien
60660484Sobrien  Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);
60760484Sobrien
60860484Sobrien  // Store info on the Win32 thread into the OSThread
60960484Sobrien  osthread->set_thread_handle(thread_handle);
61060484Sobrien  osthread->set_thread_id(thread_id);
61160484Sobrien
61260484Sobrien  // Initial thread state is INITIALIZED, not SUSPENDED
61360484Sobrien  osthread->set_state(INITIALIZED);
61460484Sobrien
61560484Sobrien  // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
61660484Sobrien  return true;
61760484Sobrien}
61860484Sobrien
61960484Sobrien
62060484Sobrien// Free Win32 resources related to the OSThread
62160484Sobrienvoid os::free_thread(OSThread* osthread) {
62260484Sobrien  assert(osthread != NULL, "osthread not set");
62360484Sobrien  CloseHandle(osthread->thread_handle());
62460484Sobrien  CloseHandle(osthread->interrupt_event());
62560484Sobrien  delete osthread;
62660484Sobrien}
62760484Sobrien
62860484Sobrien
62960484Sobrienstatic int    has_performance_count = 0;
63060484Sobrienstatic jlong first_filetime;
63160484Sobrienstatic jlong initial_performance_count;
63260484Sobrienstatic jlong performance_frequency;
63360484Sobrien
63460484Sobrien
63560484Sobrienjlong as_long(LARGE_INTEGER x) {
63660484Sobrien  jlong result = 0; // initialization to avoid warning
63777298Sobrien  set_high(&result, x.HighPart);
63860484Sobrien  set_low(&result,  x.LowPart);
63960484Sobrien  return result;
64060484Sobrien}
64160484Sobrien
64260484Sobrien
64360484Sobrienjlong os::elapsed_counter() {
644218822Sdim  LARGE_INTEGER count;
645218822Sdim  if (has_performance_count) {
646218822Sdim    QueryPerformanceCounter(&count);
647218822Sdim    return as_long(count) - initial_performance_count;
648218822Sdim  } else {
649218822Sdim    FILETIME wt;
650218822Sdim    GetSystemTimeAsFileTime(&wt);
651218822Sdim    return (jlong_from(wt.dwHighDateTime, wt.dwLowDateTime) - first_filetime);
652218822Sdim  }
653218822Sdim}
654218822Sdim
655218822Sdim
656218822Sdimjlong os::elapsed_frequency() {
657218822Sdim  if (has_performance_count) {
658218822Sdim    return performance_frequency;
659218822Sdim  } else {
660218822Sdim   // the FILETIME time is the number of 100-nanosecond intervals since January 1,1601.
66160484Sobrien   return 10000000;
66233965Sjdp  }
66333965Sjdp}
66438889Sjdp
66538889Sjdp
66638889Sjdpjulong os::available_memory() {
66738889Sjdp  return win32::available_memory();
66838889Sjdp}
66938889Sjdp
67033965Sjdpjulong os::win32::available_memory() {
67138889Sjdp  // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
67238889Sjdp  // value if total memory is larger than 4GB
67338889Sjdp  MEMORYSTATUSEX ms;
67438889Sjdp  ms.dwLength = sizeof(ms);
675218822Sdim  GlobalMemoryStatusEx(&ms);
67638889Sjdp
67738889Sjdp  return (julong)ms.ullAvailPhys;
678130561Sobrien}
679130561Sobrien
68038889Sjdpjulong os::physical_memory() {
68138889Sjdp  return win32::physical_memory();
682130561Sobrien}
68338889Sjdp
68438889Sjdpjulong os::allocatable_physical_memory(julong size) {
68538889Sjdp#ifdef _LP64
68638889Sjdp  return size;
68760484Sobrien#else
688104834Sobrien  // Limit to 1400m because of the 2gb address space wall
68960484Sobrien  return MIN2(size, (julong)1400*M);
69060484Sobrien#endif
69160484Sobrien}
69260484Sobrien
69360484Sobrien// VC6 lacks DWORD_PTR
69460484Sobrien#if _MSC_VER < 1300
69560484Sobrientypedef UINT_PTR DWORD_PTR;
69660484Sobrien#endif
697130561Sobrien
698130561Sobrienint os::active_processor_count() {
699218822Sdim  DWORD_PTR lpProcessAffinityMask = 0;
700130561Sobrien  DWORD_PTR lpSystemAffinityMask = 0;
701130561Sobrien  int proc_count = processor_count();
702130561Sobrien  if (proc_count <= sizeof(UINT_PTR) * BitsPerByte &&
703130561Sobrien      GetProcessAffinityMask(GetCurrentProcess(), &lpProcessAffinityMask, &lpSystemAffinityMask)) {
704130561Sobrien    // Nof active processors is number of bits in process affinity mask
705130561Sobrien    int bitcount = 0;
706130561Sobrien    while (lpProcessAffinityMask != 0) {
707130561Sobrien      lpProcessAffinityMask = lpProcessAffinityMask & (lpProcessAffinityMask-1);
708130561Sobrien      bitcount++;
709130561Sobrien    }
710130561Sobrien    return bitcount;
711130561Sobrien  } else {
712130561Sobrien    return proc_count;
713130561Sobrien  }
714130561Sobrien}
715130561Sobrien
716130561Sobrienbool os::distribute_processes(uint length, uint* distribution) {
717130561Sobrien  // Not yet implemented.
718130561Sobrien  return false;
719130561Sobrien}
720130561Sobrien
721130561Sobrienbool os::bind_to_processor(uint processor_id) {
722130561Sobrien  // Not yet implemented.
723130561Sobrien  return false;
724130561Sobrien}
725130561Sobrien
726130561Sobrienstatic void initialize_performance_counter() {
727130561Sobrien  LARGE_INTEGER count;
728130561Sobrien  if (QueryPerformanceFrequency(&count)) {
729130561Sobrien    has_performance_count = 1;
730130561Sobrien    performance_frequency = as_long(count);
731130561Sobrien    QueryPerformanceCounter(&count);
732130561Sobrien    initial_performance_count = as_long(count);
733130561Sobrien  } else {
734218822Sdim    has_performance_count = 0;
735218822Sdim    FILETIME wt;
73638889Sjdp    GetSystemTimeAsFileTime(&wt);
737130561Sobrien    first_filetime = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
738130561Sobrien  }
739130561Sobrien}
740130561Sobrien
741130561Sobrien
742130561Sobriendouble os::elapsedTime() {
743130561Sobrien  return (double) elapsed_counter() / (double) elapsed_frequency();
744130561Sobrien}
745130561Sobrien
746130561Sobrien
747130561Sobrien// Windows format:
748130561Sobrien//   The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.
749130561Sobrien// Java format:
750130561Sobrien//   Java standards require the number of milliseconds since 1/1/1970
75160484Sobrien
752130561Sobrien// Constant offset - calculated using offset()
753130561Sobrienstatic jlong  _offset   = 116444736000000000;
754130561Sobrien// Fake time counter for reproducible results when debugging
755130561Sobrienstatic jlong  fake_time = 0;
756130561Sobrien
757130561Sobrien#ifdef ASSERT
758130561Sobrien// Just to be safe, recalculate the offset in debug mode
759130561Sobrienstatic jlong _calculated_offset = 0;
760130561Sobrienstatic int   _has_calculated_offset = 0;
761130561Sobrien
762130561Sobrienjlong offset() {
76360484Sobrien  if (_has_calculated_offset) return _calculated_offset;
764130561Sobrien  SYSTEMTIME java_origin;
76560484Sobrien  java_origin.wYear          = 1970;
76699461Sobrien  java_origin.wMonth         = 1;
76799461Sobrien  java_origin.wDayOfWeek     = 0; // ignored
76899461Sobrien  java_origin.wDay           = 1;
76960484Sobrien  java_origin.wHour          = 0;
77060484Sobrien  java_origin.wMinute        = 0;
77160484Sobrien  java_origin.wSecond        = 0;
77299461Sobrien  java_origin.wMilliseconds  = 0;
77360484Sobrien  FILETIME jot;
77499461Sobrien  if (!SystemTimeToFileTime(&java_origin, &jot)) {
77560484Sobrien    fatal(err_msg("Error = %d\nWindows error", GetLastError()));
77660484Sobrien  }
77738889Sjdp  _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);
778130561Sobrien  _has_calculated_offset = 1;
77933965Sjdp  assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");
78033965Sjdp  return _calculated_offset;
78133965Sjdp}
78233965Sjdp#else
78333965Sjdpjlong offset() {
784218822Sdim  return _offset;
78533965Sjdp}
78660484Sobrien#endif
78760484Sobrien
78860484Sobrienjlong windows_to_java_time(FILETIME wt) {
78960484Sobrien  jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
79060484Sobrien  return (a - offset()) / 10000;
79160484Sobrien}
79277298Sobrien
793218822SdimFILETIME java_to_windows_time(jlong l) {
79460484Sobrien  jlong a = (l * 10000) + offset();
79560484Sobrien  FILETIME result;
79660484Sobrien  result.dwHighDateTime = high(a);
79760484Sobrien  result.dwLowDateTime  = low(a);
79860484Sobrien  return result;
79933965Sjdp}
80038889Sjdp
80133965Sjdp// For now, we say that Windows does not support vtime.  I have no idea
80233965Sjdp// whether it can actually be made to (DLD, 9/13/05).
80338889Sjdp
804130561Sobrienbool os::supports_vtime() { return false; }
80533965Sjdpbool os::enable_vtime() { return false; }
80633965Sjdpbool os::vtime_enabled() { return false; }
80733965Sjdpdouble os::elapsedVTime() {
80833965Sjdp  // better than nothing, but not much
80933965Sjdp  return elapsedTime();
810218822Sdim}
81133965Sjdp
81260484Sobrienjlong os::javaTimeMillis() {
81360484Sobrien  if (UseFakeTimers) {
81460484Sobrien    return fake_time++;
81560484Sobrien  } else {
81660484Sobrien    FILETIME wt;
81760484Sobrien    GetSystemTimeAsFileTime(&wt);
81877298Sobrien    return windows_to_java_time(wt);
819218822Sdim  }
82033965Sjdp}
82160484Sobrien
82260484Sobrien#define NANOS_PER_SEC         CONST64(1000000000)
82360484Sobrien#define NANOS_PER_MILLISEC    1000000
82460484Sobrienjlong os::javaTimeNanos() {
82533965Sjdp  if (!has_performance_count) {
82638889Sjdp    return javaTimeMillis() * NANOS_PER_MILLISEC; // the best we can do.
82733965Sjdp  } else {
82833965Sjdp    LARGE_INTEGER current_count;
82938889Sjdp    QueryPerformanceCounter(&current_count);
830218822Sdim    double current = as_long(current_count);
83133965Sjdp    double freq = performance_frequency;
83233965Sjdp    jlong time = (jlong)((current/freq) * NANOS_PER_SEC);
83333965Sjdp    return time;
83433965Sjdp  }
83560484Sobrien}
83660484Sobrien
83760484Sobrienvoid os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
83860484Sobrien  if (!has_performance_count) {
83960484Sobrien    // javaTimeMillis() doesn't have much percision,
84060484Sobrien    // but it is not going to wrap -- so all 64 bits
84160484Sobrien    info_ptr->max_value = ALL_64_BITS;
84277298Sobrien
843218822Sdim    // this is a wall clock timer, so may skip
84460484Sobrien    info_ptr->may_skip_backward = true;
84533965Sjdp    info_ptr->may_skip_forward = true;
846218822Sdim  } else {
847218822Sdim    jlong freq = performance_frequency;
848218822Sdim    if (freq < NANOS_PER_SEC) {
849218822Sdim      // the performance counter is 64 bits and we will
850218822Sdim      // be multiplying it -- so no wrap in 64 bits
851218822Sdim      info_ptr->max_value = ALL_64_BITS;
85260484Sobrien    } else if (freq > NANOS_PER_SEC) {
85360484Sobrien      // use the max value the counter can reach to
85460484Sobrien      // determine the max value which could be returned
85560484Sobrien      julong max_counter = (julong)ALL_64_BITS;
85633965Sjdp      info_ptr->max_value = (jlong)(max_counter / (freq / NANOS_PER_SEC));
85738889Sjdp    } else {
85833965Sjdp      // the performance counter is 64 bits and we will
85938889Sjdp      // be using it directly -- so no wrap in 64 bits
860218822Sdim      info_ptr->max_value = ALL_64_BITS;
861218822Sdim    }
862218822Sdim
863218822Sdim    // using a counter, so no skipping
864218822Sdim    info_ptr->may_skip_backward = false;
865218822Sdim    info_ptr->may_skip_forward = false;
866218822Sdim  }
867218822Sdim  info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
868218822Sdim}
869218822Sdim
870218822Sdimchar* os::local_time_string(char *buf, size_t buflen) {
871218822Sdim  SYSTEMTIME st;
872218822Sdim  GetLocalTime(&st);
873218822Sdim  jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
874218822Sdim               st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
875218822Sdim  return buf;
876218822Sdim}
877218822Sdim
878218822Sdimbool os::getTimesSecs(double* process_real_time,
879218822Sdim                     double* process_user_time,
88060484Sobrien                     double* process_system_time) {
88133965Sjdp  HANDLE h_process = GetCurrentProcess();
88233965Sjdp  FILETIME create_time, exit_time, kernel_time, user_time;
88399461Sobrien  BOOL result = GetProcessTimes(h_process,
884130561Sobrien                               &create_time,
88533965Sjdp                               &exit_time,
88633965Sjdp                               &kernel_time,
887104834Sobrien                               &user_time);
88833965Sjdp  if (result != 0) {
88960484Sobrien    FILETIME wt;
89060484Sobrien    GetSystemTimeAsFileTime(&wt);
89133965Sjdp    jlong rtc_millis = windows_to_java_time(wt);
89233965Sjdp    jlong user_millis = windows_to_java_time(user_time);
89333965Sjdp    jlong system_millis = windows_to_java_time(kernel_time);
89460484Sobrien    *process_real_time = ((double) rtc_millis) / ((double) MILLIUNITS);
89560484Sobrien    *process_user_time = ((double) user_millis) / ((double) MILLIUNITS);
896104834Sobrien    *process_system_time = ((double) system_millis) / ((double) MILLIUNITS);
89733965Sjdp    return true;
89860484Sobrien  } else {
89960484Sobrien    return false;
90033965Sjdp  }
90133965Sjdp}
90233965Sjdp
90333965Sjdpvoid os::shutdown() {
904130561Sobrien
90533965Sjdp  // allow PerfMemory to attempt cleanup of any persistent resources
906130561Sobrien  perfMemory_exit();
907130561Sobrien
908130561Sobrien  // flush buffered output, finish log files
909130561Sobrien  ostream_abort();
910130561Sobrien
911130561Sobrien  // Check for abort hook
912130561Sobrien  abort_hook_t abort_hook = Arguments::abort_hook();
913130561Sobrien  if (abort_hook != NULL) {
914130561Sobrien    abort_hook();
91533965Sjdp  }
91633965Sjdp}
91733965Sjdp
91833965Sjdpvoid os::abort(bool dump_core)
91960484Sobrien{
920130561Sobrien  os::shutdown();
92133965Sjdp  // no core dump on Windows
92260484Sobrien  ::exit(1);
92360484Sobrien}
924104834Sobrien
92533965Sjdp// Die immediately, no exit hook, no abort hook, no cleanup.
92633965Sjdpvoid os::die() {
92733965Sjdp  _exit(-1);
92833965Sjdp}
929130561Sobrien
930130561Sobrien// Directory routines copied from src/win32/native/java/io/dirent_md.c
93133965Sjdp//  * dirent_md.c       1.15 00/02/02
93233965Sjdp//
93333965Sjdp// The declarations for DIR and struct dirent are in jvm_win32.h.
93433965Sjdp
93533965Sjdp/* Caller must have already run dirname through JVM_NativePath, which removes
936218822Sdim   duplicate slashes and converts all instances of '/' into '\\'. */
93733965Sjdp
93833965SjdpDIR *
93933965Sjdpos::opendir(const char *dirname)
940130561Sobrien{
94138889Sjdp    assert(dirname != NULL, "just checking");   // hotspot change
94233965Sjdp    DIR *dirp = (DIR *)malloc(sizeof(DIR));
94333965Sjdp    DWORD fattr;                                // hotspot change
94433965Sjdp    char alt_dirname[4] = { 0, 0, 0, 0 };
945104834Sobrien
946104834Sobrien    if (dirp == 0) {
94789857Sobrien        errno = ENOMEM;
94889857Sobrien        return 0;
94989857Sobrien    }
95089857Sobrien
95133965Sjdp    /*
95233965Sjdp     * Win32 accepts "\" in its POSIX stat(), but refuses to treat it
953218822Sdim     * as a directory in FindFirstFile().  We detect this case here and
954218822Sdim     * prepend the current drive name.
955218822Sdim     */
956218822Sdim    if (dirname[1] == '\0' && dirname[0] == '\\') {
957218822Sdim        alt_dirname[0] = _getdrive() + 'A' - 1;
958218822Sdim        alt_dirname[1] = ':';
959218822Sdim        alt_dirname[2] = '\\';
960218822Sdim        alt_dirname[3] = '\0';
961218822Sdim        dirname = alt_dirname;
962218822Sdim    }
96333965Sjdp
964130561Sobrien    dirp->path = (char *)malloc(strlen(dirname) + 5);
96533965Sjdp    if (dirp->path == 0) {
96660484Sobrien        free(dirp);
96760484Sobrien        errno = ENOMEM;
968104834Sobrien        return 0;
96933965Sjdp    }
97060484Sobrien    strcpy(dirp->path, dirname);
971104834Sobrien
972130561Sobrien    fattr = GetFileAttributes(dirp->path);
973130561Sobrien    if (fattr == 0xffffffff) {
97460484Sobrien        free(dirp->path);
975218822Sdim        free(dirp);
97633965Sjdp        errno = ENOENT;
97733965Sjdp        return 0;
97833965Sjdp    } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
97933965Sjdp        free(dirp->path);
980130561Sobrien        free(dirp);
98133965Sjdp        errno = ENOTDIR;
98260484Sobrien        return 0;
98360484Sobrien    }
984104834Sobrien
98533965Sjdp    /* Append "*.*", or possibly "\\*.*", to path */
98660484Sobrien    if (dirp->path[1] == ':'
987104834Sobrien        && (dirp->path[2] == '\0'
988130561Sobrien            || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) {
98960484Sobrien        /* No '\\' needed for cases like "Z:" or "Z:\" */
990218822Sdim        strcat(dirp->path, "*.*");
99133965Sjdp    } else {
99233965Sjdp        strcat(dirp->path, "\\*.*");
99333965Sjdp    }
99433965Sjdp
995130561Sobrien    dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
99633965Sjdp    if (dirp->handle == INVALID_HANDLE_VALUE) {
99733965Sjdp        if (GetLastError() != ERROR_FILE_NOT_FOUND) {
99838889Sjdp            free(dirp->path);
99933965Sjdp            free(dirp);
100033965Sjdp            errno = EACCES;
100133965Sjdp            return 0;
100233965Sjdp        }
100399461Sobrien    }
1004130561Sobrien    return dirp;
100533965Sjdp}
100633965Sjdp
100738889Sjdp/* parameter dbuf unused on Windows */
100833965Sjdp
100933965Sjdpstruct dirent *
101033965Sjdpos::readdir(DIR *dirp, dirent *dbuf)
101133965Sjdp{
101233965Sjdp    assert(dirp != NULL, "just checking");      // hotspot change
1013130561Sobrien    if (dirp->handle == INVALID_HANDLE_VALUE) {
101433965Sjdp        return 0;
101533965Sjdp    }
101633965Sjdp
101760484Sobrien    strcpy(dirp->dirent.d_name, dirp->find_data.cFileName);
101833965Sjdp
101960484Sobrien    if (!FindNextFile(dirp->handle, &dirp->find_data)) {
102038889Sjdp        if (GetLastError() == ERROR_INVALID_HANDLE) {
102133965Sjdp            errno = EBADF;
102233965Sjdp            return 0;
102333965Sjdp        }
1024130561Sobrien        FindClose(dirp->handle);
102533965Sjdp        dirp->handle = INVALID_HANDLE_VALUE;
102633965Sjdp    }
102733965Sjdp
102860484Sobrien    return &dirp->dirent;
102933965Sjdp}
103060484Sobrien
103138889Sjdpint
103233965Sjdpos::closedir(DIR *dirp)
103333965Sjdp{
103460484Sobrien    assert(dirp != NULL, "just checking");      // hotspot change
103560484Sobrien    if (dirp->handle != INVALID_HANDLE_VALUE) {
103660484Sobrien        if (!FindClose(dirp->handle)) {
103760484Sobrien            errno = EBADF;
1038130561Sobrien            return -1;
103960484Sobrien        }
104060484Sobrien        dirp->handle = INVALID_HANDLE_VALUE;
104160484Sobrien    }
104260484Sobrien    free(dirp->path);
104360484Sobrien    free(dirp);
104460484Sobrien    return 0;
104560484Sobrien}
104660484Sobrien
104760484Sobrienconst char* os::get_temp_directory() {
104860484Sobrien  const char *prop = Arguments::get_property("java.io.tmpdir");
104960484Sobrien  if (prop != 0) return prop;
105060484Sobrien  static char path_buf[MAX_PATH];
105160484Sobrien  if (GetTempPath(MAX_PATH, path_buf)>0)
105260484Sobrien    return path_buf;
105360484Sobrien  else{
105460484Sobrien    path_buf[0]='\0';
105560484Sobrien    return path_buf;
105660484Sobrien  }
105760484Sobrien}
105860484Sobrien
105960484Sobrienstatic bool file_exists(const char* filename) {
106060484Sobrien  if (filename == NULL || strlen(filename) == 0) {
106160484Sobrien    return false;
106260484Sobrien  }
106360484Sobrien  return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
106460484Sobrien}
106560484Sobrien
106660484Sobrienvoid os::dll_build_name(char *buffer, size_t buflen,
106760484Sobrien                        const char* pname, const char* fname) {
106860484Sobrien  const size_t pnamelen = pname ? strlen(pname) : 0;
106960484Sobrien  const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
107060484Sobrien
107160484Sobrien  // Quietly truncates on buffer overflow. Should be an error.
107260484Sobrien  if (pnamelen + strlen(fname) + 10 > buflen) {
107360484Sobrien    *buffer = '\0';
107460484Sobrien    return;
107560484Sobrien  }
107660484Sobrien
107760484Sobrien  if (pnamelen == 0) {
107860484Sobrien    jio_snprintf(buffer, buflen, "%s.dll", fname);
107960484Sobrien  } else if (c == ':' || c == '\\') {
108060484Sobrien    jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);
108160484Sobrien  } else if (strchr(pname, *os::path_separator()) != NULL) {
108260484Sobrien    int n;
108360484Sobrien    char** pelements = split_path(pname, &n);
108460484Sobrien    for (int i = 0 ; i < n ; i++) {
108560484Sobrien      char* path = pelements[i];
108660484Sobrien      // Really shouldn't be NULL, but check can't hurt
108760484Sobrien      size_t plen = (path == NULL) ? 0 : strlen(path);
108860484Sobrien      if (plen == 0) {
108960484Sobrien        continue; // skip the empty path values
109060484Sobrien      }
109160484Sobrien      const char lastchar = path[plen - 1];
109260484Sobrien      if (lastchar == ':' || lastchar == '\\') {
109360484Sobrien        jio_snprintf(buffer, buflen, "%s%s.dll", path, fname);
109460484Sobrien      } else {
109560484Sobrien        jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
109660484Sobrien      }
109760484Sobrien      if (file_exists(buffer)) {
109860484Sobrien        break;
109960484Sobrien      }
110060484Sobrien    }
110133965Sjdp    // release the storage
1102130561Sobrien    for (int i = 0 ; i < n ; i++) {
1103130561Sobrien      if (pelements[i] != NULL) {
110433965Sjdp        FREE_C_HEAP_ARRAY(char, pelements[i]);
110560484Sobrien      }
110660484Sobrien    }
110760484Sobrien    if (pelements != NULL) {
110860484Sobrien      FREE_C_HEAP_ARRAY(char*, pelements);
110960484Sobrien    }
111060484Sobrien  } else {
111160484Sobrien    jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
111260484Sobrien  }
111360484Sobrien}
111460484Sobrien
111560484Sobrien// Needs to be in os specific directory because windows requires another
111660484Sobrien// header file <direct.h>
1117104834Sobrienconst char* os::get_current_directory(char *buf, int buflen) {
111860484Sobrien  return _getcwd(buf, buflen);
111960484Sobrien}
112060484Sobrien
112160484Sobrien//-----------------------------------------------------------
112260484Sobrien// Helper functions for fatal error handler
112360484Sobrien
112460484Sobrien// The following library functions are resolved dynamically at runtime:
112560484Sobrien
112633965Sjdp// PSAPI functions, for Windows NT, 2000, XP
112733965Sjdp
112833965Sjdp// psapi.h doesn't come with Visual Studio 6; it can be downloaded as Platform
1129130561Sobrien// SDK from Microsoft.  Here are the definitions copied from psapi.h
113033965Sjdptypedef struct _MODULEINFO {
113133965Sjdp    LPVOID lpBaseOfDll;
113233965Sjdp    DWORD SizeOfImage;
113333965Sjdp    LPVOID EntryPoint;
113433965Sjdp} MODULEINFO, *LPMODULEINFO;
1135130561Sobrien
113633965Sjdpstatic BOOL  (WINAPI *_EnumProcessModules)  ( HANDLE, HMODULE *, DWORD, LPDWORD );
113733965Sjdpstatic DWORD (WINAPI *_GetModuleFileNameEx) ( HANDLE, HMODULE, LPTSTR, DWORD );
113833965Sjdpstatic BOOL  (WINAPI *_GetModuleInformation)( HANDLE, HMODULE, LPMODULEINFO, DWORD );
113933965Sjdp
114033965Sjdp// ToolHelp Functions, for Windows 95, 98 and ME
114133965Sjdp
114233965Sjdpstatic HANDLE(WINAPI *_CreateToolhelp32Snapshot)(DWORD,DWORD) ;
114333965Sjdpstatic BOOL  (WINAPI *_Module32First)           (HANDLE,LPMODULEENTRY32) ;
114433965Sjdpstatic BOOL  (WINAPI *_Module32Next)            (HANDLE,LPMODULEENTRY32) ;
114533965Sjdp
114633965Sjdpbool _has_psapi;
114733965Sjdpbool _psapi_init = false;
114833965Sjdpbool _has_toolhelp;
114933965Sjdp
115033965Sjdpstatic bool _init_psapi() {
115138889Sjdp  HINSTANCE psapi = LoadLibrary( "PSAPI.DLL" ) ;
115233965Sjdp  if( psapi == NULL ) return false ;
115338889Sjdp
115433965Sjdp  _EnumProcessModules = CAST_TO_FN_PTR(
1155130561Sobrien      BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD),
115633965Sjdp      GetProcAddress(psapi, "EnumProcessModules")) ;
115733965Sjdp  _GetModuleFileNameEx = CAST_TO_FN_PTR(
115833965Sjdp      DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD),
115933965Sjdp      GetProcAddress(psapi, "GetModuleFileNameExA"));
116033965Sjdp  _GetModuleInformation = CAST_TO_FN_PTR(
116133965Sjdp      BOOL (WINAPI *)(HANDLE, HMODULE, LPMODULEINFO, DWORD),
1162130561Sobrien      GetProcAddress(psapi, "GetModuleInformation"));
116333965Sjdp
116433965Sjdp  _has_psapi = (_EnumProcessModules && _GetModuleFileNameEx && _GetModuleInformation);
116533965Sjdp  _psapi_init = true;
116633965Sjdp  return _has_psapi;
116733965Sjdp}
116833965Sjdp
116938889Sjdpstatic bool _init_toolhelp() {
1170130561Sobrien  HINSTANCE kernel32 = LoadLibrary("Kernel32.DLL") ;
117133965Sjdp  if (kernel32 == NULL) return false ;
117233965Sjdp
117338889Sjdp  _CreateToolhelp32Snapshot = CAST_TO_FN_PTR(
117433965Sjdp      HANDLE(WINAPI *)(DWORD,DWORD),
117538889Sjdp      GetProcAddress(kernel32, "CreateToolhelp32Snapshot"));
117638889Sjdp  _Module32First = CAST_TO_FN_PTR(
117738889Sjdp      BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32),
117838889Sjdp      GetProcAddress(kernel32, "Module32First" ));
117960484Sobrien  _Module32Next = CAST_TO_FN_PTR(
118033965Sjdp      BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32),
118133965Sjdp      GetProcAddress(kernel32, "Module32Next" ));
118233965Sjdp
118333965Sjdp  _has_toolhelp = (_CreateToolhelp32Snapshot && _Module32First && _Module32Next);
118433965Sjdp  return _has_toolhelp;
118533965Sjdp}
118633965Sjdp
118733965Sjdp#ifdef _WIN64
118833965Sjdp// Helper routine which returns true if address in
118933965Sjdp// within the NTDLL address space.
119033965Sjdp//
119133965Sjdpstatic bool _addr_in_ntdll( address addr )
119233965Sjdp{
119360484Sobrien  HMODULE hmod;
119460484Sobrien  MODULEINFO minfo;
119533965Sjdp
119633965Sjdp  hmod = GetModuleHandle("NTDLL.DLL");
119733965Sjdp  if ( hmod == NULL ) return false;
119833965Sjdp  if ( !_GetModuleInformation( GetCurrentProcess(), hmod,
119933965Sjdp                               &minfo, sizeof(MODULEINFO)) )
120033965Sjdp    return false;
120133965Sjdp
120238889Sjdp  if ( (addr >= minfo.lpBaseOfDll) &&
120333965Sjdp       (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage)))
120438889Sjdp    return true;
120538889Sjdp  else
120633965Sjdp    return false;
120738889Sjdp}
120838889Sjdp#endif
120960484Sobrien
1210104834Sobrien
121160484Sobrien// Enumerate all modules for a given process ID
121238889Sjdp//
121338889Sjdp// Notice that Windows 95/98/Me and Windows NT/2000/XP have
121460484Sobrien// different API for doing this. We use PSAPI.DLL on NT based
1215104834Sobrien// Windows and ToolHelp on 95/98/Me.
121638889Sjdp
121733965Sjdp// Callback function that is called by enumerate_modules() on
121860484Sobrien// every DLL module.
121960484Sobrien// Input parameters:
122033965Sjdp//    int       pid,
122138889Sjdp//    char*     module_file_name,
122233965Sjdp//    address   module_base_addr,
122360484Sobrien//    unsigned  module_size,
122460484Sobrien//    void*     param
122533965Sjdptypedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *);
122638889Sjdp
122733965Sjdp// enumerate_modules for Windows NT, using PSAPI
122838889Sjdpstatic int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param)
122960484Sobrien{
123060484Sobrien  HANDLE   hProcess ;
123160484Sobrien
123233965Sjdp# define MAX_NUM_MODULES 128
123338889Sjdp  HMODULE     modules[MAX_NUM_MODULES];
123438889Sjdp  static char filename[ MAX_PATH ];
123533965Sjdp  int         result = 0;
123633965Sjdp
123760484Sobrien  if (!_has_psapi && (_psapi_init || !_init_psapi())) return 0;
123860484Sobrien
123960484Sobrien  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
124033965Sjdp                         FALSE, pid ) ;
1241130561Sobrien  if (hProcess == NULL) return 0;
124233965Sjdp
124360484Sobrien  DWORD size_needed;
124460484Sobrien  if (!_EnumProcessModules(hProcess, modules,
124560484Sobrien                           sizeof(modules), &size_needed)) {
124660484Sobrien      CloseHandle( hProcess );
124760484Sobrien      return 0;
124833965Sjdp  }
124933965Sjdp
125060484Sobrien  // number of modules that are currently loaded
1251104834Sobrien  int num_modules = size_needed / sizeof(HMODULE);
125260484Sobrien
125360484Sobrien  for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {
1254104834Sobrien    // Get Full pathname:
1255218822Sdim    if(!_GetModuleFileNameEx(hProcess, modules[i],
125660484Sobrien                             filename, sizeof(filename))) {
125760484Sobrien        filename[0] = '\0';
125860484Sobrien    }
1259104834Sobrien
126060484Sobrien    MODULEINFO modinfo;
126160484Sobrien    if (!_GetModuleInformation(hProcess, modules[i],
126260484Sobrien                               &modinfo, sizeof(modinfo))) {
126360484Sobrien        modinfo.lpBaseOfDll = NULL;
126460484Sobrien        modinfo.SizeOfImage = 0;
126560484Sobrien    }
126660484Sobrien
126760484Sobrien    // Invoke callback function
126860484Sobrien    result = func(pid, filename, (address)modinfo.lpBaseOfDll,
126960484Sobrien                  modinfo.SizeOfImage, param);
127033965Sjdp    if (result) break;
127160484Sobrien  }
1272218822Sdim
127333965Sjdp  CloseHandle( hProcess ) ;
127460484Sobrien  return result;
127560484Sobrien}
127660484Sobrien
1277104834Sobrien
127860484Sobrien// enumerate_modules for Windows 95/98/ME, using TOOLHELP
127960484Sobrienstatic int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param)
128060484Sobrien{
128160484Sobrien  HANDLE                hSnapShot ;
128260484Sobrien  static MODULEENTRY32  modentry ;
128360484Sobrien  int                   result = 0;
128460484Sobrien
1285104834Sobrien  if (!_has_toolhelp) return 0;
128633965Sjdp
128760484Sobrien  // Get a handle to a Toolhelp snapshot of the system
128833965Sjdp  hSnapShot = _CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid ) ;
128933965Sjdp  if( hSnapShot == INVALID_HANDLE_VALUE ) {
1290218822Sdim      return FALSE ;
129160484Sobrien  }
129233965Sjdp
129360484Sobrien  // iterate through all modules
129460484Sobrien  modentry.dwSize = sizeof(MODULEENTRY32) ;
129560484Sobrien  bool not_done = _Module32First( hSnapShot, &modentry ) != 0;
129660484Sobrien
1297130561Sobrien  while( not_done ) {
129860484Sobrien    // invoke the callback
129960484Sobrien    result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr,
130060484Sobrien                modentry.modBaseSize, param);
1301130561Sobrien    if (result) break;
1302130561Sobrien
130360484Sobrien    modentry.dwSize = sizeof(MODULEENTRY32) ;
130460484Sobrien    not_done = _Module32Next( hSnapShot, &modentry ) != 0;
130560484Sobrien  }
1306130561Sobrien
130760484Sobrien  CloseHandle(hSnapShot);
130833965Sjdp  return result;
130960484Sobrien}
131060484Sobrien
131133965Sjdpint enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param )
131260484Sobrien{
131360484Sobrien  // Get current process ID if caller doesn't provide it.
131433965Sjdp  if (!pid) pid = os::current_process_id();
131560484Sobrien
131660484Sobrien  if (os::win32::is_nt()) return _enumerate_modules_winnt  (pid, func, param);
131733965Sjdp  else                    return _enumerate_modules_windows(pid, func, param);
131860484Sobrien}
1319130561Sobrien
1320130561Sobrienstruct _modinfo {
132160484Sobrien   address addr;
132260484Sobrien   char*   full_path;   // point to a char buffer
132360484Sobrien   int     buflen;      // size of the buffer
132460484Sobrien   address base_addr;
132560484Sobrien};
132660484Sobrien
132760484Sobrienstatic int _locate_module_by_addr(int pid, char * mod_fname, address base_addr,
132860484Sobrien                                  unsigned size, void * param) {
132960484Sobrien   struct _modinfo *pmod = (struct _modinfo *)param;
133060484Sobrien   if (!pmod) return -1;
133160484Sobrien
133260484Sobrien   if (base_addr     <= pmod->addr &&
133360484Sobrien       base_addr+size > pmod->addr) {
133460484Sobrien     // if a buffer is provided, copy path name to the buffer
133560484Sobrien     if (pmod->full_path) {
1336130561Sobrien       jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname);
133760484Sobrien     }
133860484Sobrien     pmod->base_addr = base_addr;
133960484Sobrien     return 1;
134060484Sobrien   }
134160484Sobrien   return 0;
134260484Sobrien}
134360484Sobrien
134460484Sobrienbool os::dll_address_to_library_name(address addr, char* buf,
1345130561Sobrien                                     int buflen, int* offset) {
134660484Sobrien// NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always
134760484Sobrien//       return the full path to the DLL file, sometimes it returns path
134860484Sobrien//       to the corresponding PDB file (debug info); sometimes it only
1349130561Sobrien//       returns partial path, which makes life painful.
1350130561Sobrien
135160484Sobrien   struct _modinfo mi;
135260484Sobrien   mi.addr      = addr;
1353104834Sobrien   mi.full_path = buf;
1354130561Sobrien   mi.buflen    = buflen;
135560484Sobrien   int pid = os::current_process_id();
135660484Sobrien   if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {
135733965Sjdp      // buf already contains path name
135833965Sjdp      if (offset) *offset = addr - mi.base_addr;
135960484Sobrien      return true;
136060484Sobrien   } else {
136138889Sjdp      if (buf) buf[0] = '\0';
1362130561Sobrien      if (offset) *offset = -1;
136360484Sobrien      return false;
136460484Sobrien   }
136560484Sobrien}
136660484Sobrien
136760484Sobrienbool os::dll_address_to_function_name(address addr, char *buf,
136860484Sobrien                                      int buflen, int *offset) {
136960484Sobrien  if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
137060484Sobrien    return true;
137160484Sobrien  }
137260484Sobrien  if (offset != NULL)  *offset  = -1;
1373104834Sobrien  if (buf != NULL) buf[0] = '\0';
137460484Sobrien  return false;
137560484Sobrien}
137660484Sobrien
1377130561Sobrien// save the start and end address of jvm.dll into param[0] and param[1]
1378130561Sobrienstatic int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,
1379130561Sobrien                    unsigned size, void * param) {
1380130561Sobrien   if (!param) return -1;
1381130561Sobrien
138260484Sobrien   if (base_addr     <= (address)_locate_jvm_dll &&
138360484Sobrien       base_addr+size > (address)_locate_jvm_dll) {
138460484Sobrien         ((address*)param)[0] = base_addr;
138560484Sobrien         ((address*)param)[1] = base_addr + size;
138660484Sobrien         return 1;
138760484Sobrien   }
138860484Sobrien   return 0;
138960484Sobrien}
139060484Sobrien
139160484Sobrienaddress vm_lib_location[2];    // start and end address of jvm.dll
139260484Sobrien
139360484Sobrien// check if addr is inside jvm.dll
1394130561Sobrienbool os::address_is_in_vm(address addr) {
1395130561Sobrien  if (!vm_lib_location[0] || !vm_lib_location[1]) {
139660484Sobrien    int pid = os::current_process_id();
139760484Sobrien    if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) {
139860484Sobrien      assert(false, "Can't find jvm module.");
139960484Sobrien      return false;
140060484Sobrien    }
1401130561Sobrien  }
1402130561Sobrien
140360484Sobrien  return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]);
140460484Sobrien}
140560484Sobrien
140660484Sobrien// print module info; param is outputStream*
140760484Sobrienstatic int _print_module(int pid, char* fname, address base,
140860484Sobrien                         unsigned size, void* param) {
140960484Sobrien   if (!param) return -1;
141060484Sobrien
141160484Sobrien   outputStream* st = (outputStream*)param;
141260484Sobrien
141360484Sobrien   address end_addr = base + size;
141460484Sobrien   st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname);
141560484Sobrien   return 0;
1416130561Sobrien}
141760484Sobrien
141860484Sobrien// Loads .dll/.so and
141960484Sobrien// in case of error it checks if .dll/.so was built for the
142060484Sobrien// same architecture as Hotspot is running on
142160484Sobrienvoid * os::dll_load(const char *name, char *ebuf, int ebuflen)
142260484Sobrien{
142360484Sobrien  void * result = LoadLibrary(name);
142460484Sobrien  if (result != NULL)
142560484Sobrien  {
142660484Sobrien    return result;
142760484Sobrien  }
142860484Sobrien
142960484Sobrien  long errcode = GetLastError();
143060484Sobrien  if (errcode == ERROR_MOD_NOT_FOUND) {
143160484Sobrien    strncpy(ebuf, "Can't find dependent libraries", ebuflen-1);
143260484Sobrien    ebuf[ebuflen-1]='\0';
143360484Sobrien    return NULL;
1434130561Sobrien  }
143560484Sobrien
143660484Sobrien  // Parsing dll below
143760484Sobrien  // If we can read dll-info and find that dll was built
143860484Sobrien  // for an architecture other than Hotspot is running in
143960484Sobrien  // - then print to buffer "DLL was built for a different architecture"
144060484Sobrien  // else call getLastErrorString to obtain system error message
144160484Sobrien
144260484Sobrien  // Read system error message into ebuf
1443104834Sobrien  // It may or may not be overwritten below (in the for loop and just above)
144460484Sobrien  getLastErrorString(ebuf, (size_t) ebuflen);
144560484Sobrien  ebuf[ebuflen-1]='\0';
144660484Sobrien  int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0);
144760484Sobrien  if (file_descriptor<0)
144860484Sobrien  {
144960484Sobrien    return NULL;
145060484Sobrien  }
145160484Sobrien
145260484Sobrien  uint32_t signature_offset;
145360484Sobrien  uint16_t lib_arch=0;
145460484Sobrien  bool failed_to_get_lib_arch=
145560484Sobrien  (
145660484Sobrien    //Go to position 3c in the dll
145760484Sobrien    (os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0)
145860484Sobrien    ||
145960484Sobrien    // Read loacation of signature
1460130561Sobrien    (sizeof(signature_offset)!=
146160484Sobrien      (os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset))))
146260484Sobrien    ||
1463130561Sobrien    //Go to COFF File Header in dll
146460484Sobrien    //that is located after"signature" (4 bytes long)
146560484Sobrien    (os::seek_to_file_offset(file_descriptor,
146660484Sobrien      signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0)
146760484Sobrien    ||
146860484Sobrien    //Read field that contains code of architecture
146960484Sobrien    // that dll was build for
147060484Sobrien    (sizeof(lib_arch)!=
147160484Sobrien      (os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch))))
147260484Sobrien  );
147360484Sobrien
147460484Sobrien  ::close(file_descriptor);
147560484Sobrien  if (failed_to_get_lib_arch)
147660484Sobrien  {
147760484Sobrien    // file i/o error - report getLastErrorString(...) msg
147860484Sobrien    return NULL;
1479130561Sobrien  }
148060484Sobrien
148160484Sobrien  typedef struct
148260484Sobrien  {
148360484Sobrien    uint16_t arch_code;
148460484Sobrien    char* arch_name;
148560484Sobrien  } arch_t;
148660484Sobrien
148760484Sobrien  static const arch_t arch_array[]={
148860484Sobrien    {IMAGE_FILE_MACHINE_I386,      (char*)"IA 32"},
148960484Sobrien    {IMAGE_FILE_MACHINE_AMD64,     (char*)"AMD 64"},
149060484Sobrien    {IMAGE_FILE_MACHINE_IA64,      (char*)"IA 64"}
149160484Sobrien  };
149260484Sobrien  #if   (defined _M_IA64)
149360484Sobrien    static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64;
149460484Sobrien  #elif (defined _M_AMD64)
149560484Sobrien    static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64;
149660484Sobrien  #elif (defined _M_IX86)
149760484Sobrien    static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386;
149860484Sobrien  #else
149960484Sobrien    #error Method os::dll_load requires that one of following \
150060484Sobrien           is defined :_M_IA64,_M_AMD64 or _M_IX86
150160484Sobrien  #endif
1502130561Sobrien
150360484Sobrien
150460484Sobrien  // Obtain a string for printf operation
150560484Sobrien  // lib_arch_str shall contain string what platform this .dll was built for
150660484Sobrien  // running_arch_str shall string contain what platform Hotspot was built for
150760484Sobrien  char *running_arch_str=NULL,*lib_arch_str=NULL;
1508104834Sobrien  for (unsigned int i=0;i<ARRAY_SIZE(arch_array);i++)
1509130561Sobrien  {
151060484Sobrien    if (lib_arch==arch_array[i].arch_code)
151160484Sobrien      lib_arch_str=arch_array[i].arch_name;
151260484Sobrien    if (running_arch==arch_array[i].arch_code)
151360484Sobrien      running_arch_str=arch_array[i].arch_name;
151460484Sobrien  }
151560484Sobrien
1516130561Sobrien  assert(running_arch_str,
151733965Sjdp    "Didn't find runing architecture code in arch_array");
151860484Sobrien
151933965Sjdp  // If the architure is right
152033965Sjdp  // but some other error took place - report getLastErrorString(...) msg
152160484Sobrien  if (lib_arch == running_arch)
152260484Sobrien  {
152360484Sobrien    return NULL;
152460484Sobrien  }
152560484Sobrien
1526104834Sobrien  if (lib_arch_str!=NULL)
152733965Sjdp  {
152833965Sjdp    ::_snprintf(ebuf, ebuflen-1,
152933965Sjdp      "Can't load %s-bit .dll on a %s-bit platform",
153033965Sjdp      lib_arch_str,running_arch_str);
153133965Sjdp  }
153233965Sjdp  else
153333965Sjdp  {
153433965Sjdp    // don't know what architecture this dll was build for
153533965Sjdp    ::_snprintf(ebuf, ebuflen-1,
153633965Sjdp      "Can't load this .dll (machine code=0x%x) on a %s-bit platform",
1537104834Sobrien      lib_arch,running_arch_str);
153860484Sobrien  }
153960484Sobrien
154060484Sobrien  return NULL;
154160484Sobrien}
154233965Sjdp
154333965Sjdp
154433965Sjdpvoid os::print_dll_info(outputStream *st) {
154533965Sjdp   int pid = os::current_process_id();
154660484Sobrien   st->print_cr("Dynamic libraries:");
154760484Sobrien   enumerate_modules(pid, _print_module, (void *)st);
154860484Sobrien}
154960484Sobrien
155060484Sobrien// function pointer to Windows API "GetNativeSystemInfo".
155133965Sjdptypedef void (WINAPI *GetNativeSystemInfo_func_type)(LPSYSTEM_INFO);
155233965Sjdpstatic GetNativeSystemInfo_func_type _GetNativeSystemInfo;
155333965Sjdp
155433965Sjdpvoid os::print_os_info(outputStream* st) {
155533965Sjdp  st->print("OS:");
155633965Sjdp
155733965Sjdp  OSVERSIONINFOEX osvi;
155838889Sjdp  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
1559130561Sobrien  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
156033965Sjdp
156133965Sjdp  if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
156233965Sjdp    st->print_cr("N/A");
156333965Sjdp    return;
156433965Sjdp  }
156533965Sjdp
156633965Sjdp  int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
156733965Sjdp  if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
156833965Sjdp    switch (os_vers) {
1569130561Sobrien    case 3051: st->print(" Windows NT 3.51"); break;
157033965Sjdp    case 4000: st->print(" Windows NT 4.0"); break;
157133965Sjdp    case 5000: st->print(" Windows 2000"); break;
157233965Sjdp    case 5001: st->print(" Windows XP"); break;
157333965Sjdp    case 5002:
157433965Sjdp    case 6000:
157533965Sjdp    case 6001: {
1576130561Sobrien      // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
157738889Sjdp      // find out whether we are running on 64 bit processor or not.
157838889Sjdp      SYSTEM_INFO si;
157933965Sjdp      ZeroMemory(&si, sizeof(SYSTEM_INFO));
158033965Sjdp      // Check to see if _GetNativeSystemInfo has been initialized.
158138889Sjdp      if (_GetNativeSystemInfo == NULL) {
1582130561Sobrien        HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
158333965Sjdp        _GetNativeSystemInfo =
158438889Sjdp            CAST_TO_FN_PTR(GetNativeSystemInfo_func_type,
1585130561Sobrien                           GetProcAddress(hKernel32,
158633965Sjdp                                          "GetNativeSystemInfo"));
158738889Sjdp        if (_GetNativeSystemInfo == NULL)
158833965Sjdp          GetSystemInfo(&si);
158933965Sjdp      } else {
159033965Sjdp        _GetNativeSystemInfo(&si);
1591130561Sobrien      }
159233965Sjdp      if (os_vers == 5002) {
159333965Sjdp        if (osvi.wProductType == VER_NT_WORKSTATION &&
159433965Sjdp            si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
1595130561Sobrien          st->print(" Windows XP x64 Edition");
159633965Sjdp        else
159733965Sjdp            st->print(" Windows Server 2003 family");
159833965Sjdp      } else if (os_vers == 6000) {
159933965Sjdp        if (osvi.wProductType == VER_NT_WORKSTATION)
160033965Sjdp            st->print(" Windows Vista");
160133965Sjdp        else
160233965Sjdp            st->print(" Windows Server 2008");
160333965Sjdp        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
1604104834Sobrien            st->print(" , 64 bit");
160533965Sjdp      } else if (os_vers == 6001) {
160633965Sjdp        if (osvi.wProductType == VER_NT_WORKSTATION) {
160760484Sobrien            st->print(" Windows 7");
1608104834Sobrien        } else {
160960484Sobrien            // Unrecognized windows, print out its major and minor versions
161060484Sobrien            st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
1611104834Sobrien        }
161260484Sobrien        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
161333965Sjdp            st->print(" , 64 bit");
1614104834Sobrien      } else { // future os
161533965Sjdp        // Unrecognized windows, print out its major and minor versions
161633965Sjdp        st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
161733965Sjdp        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
161833965Sjdp            st->print(" , 64 bit");
161933965Sjdp      }
162038889Sjdp      break;
1621130561Sobrien    }
162233965Sjdp    default: // future windows, print out its major and minor versions
162333965Sjdp      st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
162433965Sjdp    }
162533965Sjdp  } else {
162660484Sobrien    switch (os_vers) {
1627104834Sobrien    case 4000: st->print(" Windows 95"); break;
162833965Sjdp    case 4010: st->print(" Windows 98"); break;
162933965Sjdp    case 4090: st->print(" Windows Me"); break;
163033965Sjdp    default: // future windows, print out its major and minor versions
163133965Sjdp      st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
163233965Sjdp    }
163333965Sjdp  }
163433965Sjdp  st->print(" Build %d", osvi.dwBuildNumber);
163533965Sjdp  st->print(" %s", osvi.szCSDVersion);           // service pack
163633965Sjdp  st->cr();
163760484Sobrien}
163860484Sobrien
1639130561Sobrienvoid os::print_memory_info(outputStream* st) {
1640130561Sobrien  st->print("Memory:");
1641130561Sobrien  st->print(" %dk page", os::vm_page_size()>>10);
1642130561Sobrien
1643130561Sobrien  // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
1644130561Sobrien  // value if total memory is larger than 4GB
164560484Sobrien  MEMORYSTATUSEX ms;
1646104834Sobrien  ms.dwLength = sizeof(ms);
1647130561Sobrien  GlobalMemoryStatusEx(&ms);
164860484Sobrien
164960484Sobrien  st->print(", physical %uk", os::physical_memory() >> 10);
165060484Sobrien  st->print("(%uk free)", os::available_memory() >> 10);
165160484Sobrien
165260484Sobrien  st->print(", swap %uk", ms.ullTotalPageFile >> 10);
1653130561Sobrien  st->print("(%uk free)", ms.ullAvailPageFile >> 10);
1654130561Sobrien  st->cr();
165560484Sobrien}
1656104834Sobrien
1657104834Sobrienvoid os::print_siginfo(outputStream *st, void *siginfo) {
1658130561Sobrien  EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;
165960484Sobrien  st->print("siginfo:");
1660130561Sobrien  st->print(" ExceptionCode=0x%x", er->ExceptionCode);
166160484Sobrien
166260484Sobrien  if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
166360484Sobrien      er->NumberParameters >= 2) {
166460484Sobrien      switch (er->ExceptionInformation[0]) {
166560484Sobrien      case 0: st->print(", reading address"); break;
166660484Sobrien      case 1: st->print(", writing address"); break;
166760484Sobrien      default: st->print(", ExceptionInformation=" INTPTR_FORMAT,
166860484Sobrien                            er->ExceptionInformation[0]);
1669130561Sobrien      }
1670130561Sobrien      st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);
167160484Sobrien  } else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR &&
167233965Sjdp             er->NumberParameters >= 2 && UseSharedSpaces) {
1673104834Sobrien    FileMapInfo* mapinfo = FileMapInfo::current_info();
167460484Sobrien    if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {
167533965Sjdp      st->print("\n\nError accessing class data sharing archive."       \
167638889Sjdp                " Mapped file inaccessible during execution, "          \
167760484Sobrien                " possible disk/network problem.");
167860484Sobrien    }
167960484Sobrien  } else {
168060484Sobrien    int num = er->NumberParameters;
168138889Sjdp    if (num > 0) {
1682130561Sobrien      st->print(", ExceptionInformation=");
168333965Sjdp      for (int i = 0; i < num; i++) {
168460484Sobrien        st->print(INTPTR_FORMAT " ", er->ExceptionInformation[i]);
168560484Sobrien      }
168660484Sobrien    }
168760484Sobrien  }
168860484Sobrien  st->cr();
168933965Sjdp}
169060484Sobrien
169160484Sobrienvoid os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
169233965Sjdp  // do nothing
169360484Sobrien}
169460484Sobrien
169560484Sobrienstatic char saved_jvm_path[MAX_PATH] = {0};
169660484Sobrien
169733965Sjdp// Find the full path to the current module, jvm.dll or jvm_g.dll
169860484Sobrienvoid os::jvm_path(char *buf, jint buflen) {
169960484Sobrien  // Error checking.
170060484Sobrien  if (buflen < MAX_PATH) {
170160484Sobrien    assert(false, "must use a large-enough buffer");
170260484Sobrien    buf[0] = '\0';
170360484Sobrien    return;
170460484Sobrien  }
170560484Sobrien  // Lazy resolve the path to current module.
170660484Sobrien  if (saved_jvm_path[0] != 0) {
170760484Sobrien    strcpy(buf, saved_jvm_path);
170860484Sobrien    return;
170960484Sobrien  }
171060484Sobrien
171160484Sobrien  buf[0] = '\0';
171233965Sjdp  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
171360484Sobrien     // Support for the gamma launcher. Check for an
171460484Sobrien     // JAVA_HOME environment variable
171560484Sobrien     // and fix up the path so it looks like
171660484Sobrien     // libjvm.so is installed there (append a fake suffix
171760484Sobrien     // hotspot/libjvm.so).
171860484Sobrien     char* java_home_var = ::getenv("JAVA_HOME");
171960484Sobrien     if (java_home_var != NULL && java_home_var[0] != 0) {
172060484Sobrien
172160484Sobrien        strncpy(buf, java_home_var, buflen);
172233965Sjdp
172360484Sobrien        // determine if this is a legacy image or modules image
1724218822Sdim        // modules image doesn't have "jre" subdirectory
1725218822Sdim        size_t len = strlen(buf);
1726218822Sdim        char* jrebin_p = buf + len;
1727218822Sdim        jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\");
1728218822Sdim        if (0 != _access(buf, 0)) {
172960484Sobrien          jio_snprintf(jrebin_p, buflen-len, "\\bin\\");
173060484Sobrien        }
1731218822Sdim        len = strlen(buf);
1732218822Sdim        jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll");
1733218822Sdim     }
1734218822Sdim  }
1735218822Sdim
1736218822Sdim  if(buf[0] == '\0') {
173760484Sobrien  GetModuleFileName(vm_lib_handle, buf, buflen);
173833965Sjdp  }
173960484Sobrien  strcpy(saved_jvm_path, buf);
174060484Sobrien}
174160484Sobrien
174260484Sobrien
174333965Sjdpvoid os::print_jni_name_prefix_on(outputStream* st, int args_size) {
174460484Sobrien#ifndef _WIN64
1745218822Sdim  st->print("_");
1746218822Sdim#endif
1747218822Sdim}
1748218822Sdim
1749218822Sdim
175060484Sobrienvoid os::print_jni_name_suffix_on(outputStream* st, int args_size) {
175160484Sobrien#ifndef _WIN64
1752218822Sdim  st->print("@%d", args_size  * sizeof(int));
1753218822Sdim#endif
1754218822Sdim}
1755218822Sdim
1756218822Sdim// This method is a copy of JDK's sysGetLastErrorString
1757218822Sdim// from src/windows/hpi/src/system_md.c
175860484Sobrien
175933965Sjdpsize_t os::lasterror(char *buf, size_t len) {
176033965Sjdp  long errval;
176160484Sobrien
176260484Sobrien  if ((errval = GetLastError()) != 0) {
176360484Sobrien      /* DOS error */
176460484Sobrien    int n = (int)FormatMessage(
176560484Sobrien          FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
176660484Sobrien          NULL,
176760484Sobrien          errval,
176860484Sobrien          0,
176960484Sobrien          buf,
177060484Sobrien          (DWORD)len,
177160484Sobrien          NULL);
177260484Sobrien    if (n > 3) {
177360484Sobrien      /* Drop final '.', CR, LF */
177460484Sobrien      if (buf[n - 1] == '\n') n--;
177560484Sobrien      if (buf[n - 1] == '\r') n--;
177660484Sobrien      if (buf[n - 1] == '.') n--;
177760484Sobrien      buf[n] = '\0';
177860484Sobrien    }
177960484Sobrien    return n;
178060484Sobrien  }
178160484Sobrien
178260484Sobrien  if (errno != 0) {
178360484Sobrien    /* C runtime error that has no corresponding DOS error code */
178460484Sobrien    const char *s = strerror(errno);
178560484Sobrien    size_t n = strlen(s);
178660484Sobrien    if (n >= len) n = len - 1;
178760484Sobrien    strncpy(buf, s, n);
178860484Sobrien    buf[n] = '\0';
178960484Sobrien    return n;
1790104834Sobrien  }
179160484Sobrien  return 0;
1792130561Sobrien}
179360484Sobrien
179460484Sobrien// sun.misc.Signal
1795104834Sobrien// NOTE that this is a workaround for an apparent kernel bug where if
179660484Sobrien// a signal handler for SIGBREAK is installed then that signal handler
179760484Sobrien// takes priority over the console control handler for CTRL_CLOSE_EVENT.
179860484Sobrien// See bug 4416763.
179960484Sobrienstatic void (*sigbreakHandler)(int) = NULL;
180060484Sobrien
180160484Sobrienstatic void UserHandler(int sig, void *siginfo, void *context) {
180260484Sobrien  os::signal_notify(sig);
180360484Sobrien  // We need to reinstate the signal handler each time...
180460484Sobrien  os::signal(sig, (void*)UserHandler);
1805130561Sobrien}
180660484Sobrien
180760484Sobrienvoid* os::user_handler() {
180860484Sobrien  return (void*) UserHandler;
180960484Sobrien}
181060484Sobrien
181160484Sobrienvoid* os::signal(int signal_number, void* handler) {
181260484Sobrien  if ((signal_number == SIGBREAK) && (!ReduceSignalUsage)) {
181360484Sobrien    void (*oldHandler)(int) = sigbreakHandler;
1814104834Sobrien    sigbreakHandler = (void (*)(int)) handler;
181560484Sobrien    return (void*) oldHandler;
181660484Sobrien  } else {
181760484Sobrien    return (void*)::signal(signal_number, (void (*)(int))handler);
181860484Sobrien  }
1819104834Sobrien}
182060484Sobrien
182160484Sobrienvoid os::signal_raise(int signal_number) {
182260484Sobrien  raise(signal_number);
182333965Sjdp}
1824104834Sobrien
182533965Sjdp// The Win32 C runtime library maps all console control events other than ^C
182633965Sjdp// into SIGBREAK, which makes it impossible to distinguish ^BREAK from close,
182733965Sjdp// logoff, and shutdown events.  We therefore install our own console handler
182833965Sjdp// that raises SIGTERM for the latter cases.
182938889Sjdp//
183038889Sjdpstatic BOOL WINAPI consoleHandler(DWORD event) {
183133965Sjdp  switch(event) {
183233965Sjdp    case CTRL_C_EVENT:
183333965Sjdp      if (is_error_reported()) {
183433965Sjdp        // Ctrl-C is pressed during error reporting, likely because the error
183533965Sjdp        // handler fails to abort. Let VM die immediately.
183633965Sjdp        os::die();
183733965Sjdp      }
183833965Sjdp
183933965Sjdp      os::signal_raise(SIGINT);
184033965Sjdp      return TRUE;
184133965Sjdp      break;
184233965Sjdp    case CTRL_BREAK_EVENT:
184333965Sjdp      if (sigbreakHandler != NULL) {
184460484Sobrien        (*sigbreakHandler)(SIGBREAK);
184533965Sjdp      }
184633965Sjdp      return TRUE;
184733965Sjdp      break;
184833965Sjdp    case CTRL_CLOSE_EVENT:
184933965Sjdp    case CTRL_LOGOFF_EVENT:
185033965Sjdp    case CTRL_SHUTDOWN_EVENT:
185133965Sjdp      os::signal_raise(SIGTERM);
185233965Sjdp      return TRUE;
185333965Sjdp      break;
185433965Sjdp    default:
185533965Sjdp      break;
185633965Sjdp  }
185733965Sjdp  return FALSE;
185833965Sjdp}
185933965Sjdp
186033965Sjdp/*
186133965Sjdp * The following code is moved from os.cpp for making this
186233965Sjdp * code platform specific, which it is by its very nature.
186333965Sjdp */
186433965Sjdp
186533965Sjdp// Return maximum OS signal used + 1 for internal use only
186633965Sjdp// Used as exit signal for signal_thread
186789857Sobrienint os::sigexitnum_pd(){
186889857Sobrien  return NSIG;
1869130561Sobrien}
1870130561Sobrien
1871130561Sobrien// a counter for each possible signal value, including signal_thread exit signal
1872130561Sobrienstatic volatile jint pending_signals[NSIG+1] = { 0 };
1873130561Sobrienstatic HANDLE sig_sem;
1874130561Sobrien
1875218822Sdimvoid os::signal_init_pd() {
1876130561Sobrien  // Initialize signal structures
1877130561Sobrien  memset((void*)pending_signals, 0, sizeof(pending_signals));
187889857Sobrien
187989857Sobrien  sig_sem = ::CreateSemaphore(NULL, 0, NSIG+1, NULL);
188089857Sobrien
188133965Sjdp  // Programs embedding the VM do not want it to attempt to receive
188233965Sjdp  // events like CTRL_LOGOFF_EVENT, which are used to implement the
188333965Sjdp  // shutdown hooks mechanism introduced in 1.3.  For example, when
188433965Sjdp  // the VM is run as part of a Windows NT service (i.e., a servlet
188533965Sjdp  // engine in a web server), the correct behavior is for any console
188633965Sjdp  // control handler to return FALSE, not TRUE, because the OS's
188733965Sjdp  // "final" handler for such events allows the process to continue if
188833965Sjdp  // it is a service (while terminating it if it is not a service).
188933965Sjdp  // To make this behavior uniform and the mechanism simpler, we
189060484Sobrien  // completely disable the VM's usage of these console events if -Xrs
189160484Sobrien  // (=ReduceSignalUsage) is specified.  This means, for example, that
189233965Sjdp  // the CTRL-BREAK thread dump mechanism is also disabled in this
189333965Sjdp  // case.  See bugs 4323062, 4345157, and related bugs.
189433965Sjdp
189533965Sjdp  if (!ReduceSignalUsage) {
189633965Sjdp    // Add a CTRL-C handler
189733965Sjdp    SetConsoleCtrlHandler(consoleHandler, TRUE);
189833965Sjdp  }
189933965Sjdp}
190033965Sjdp
190133965Sjdpvoid os::signal_notify(int signal_number) {
190233965Sjdp  BOOL ret;
190333965Sjdp
1904130561Sobrien  Atomic::inc(&pending_signals[signal_number]);
1905130561Sobrien  ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
190689857Sobrien  assert(ret != 0, "ReleaseSemaphore() failed");
190799461Sobrien}
1908130561Sobrien
1909130561Sobrienstatic int check_pending_signals(bool wait_for_signal) {
1910130561Sobrien  DWORD ret;
1911130561Sobrien  while (true) {
191233965Sjdp    for (int i = 0; i < NSIG + 1; i++) {
191333965Sjdp      jint n = pending_signals[i];
191433965Sjdp      if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
191560484Sobrien        return i;
191633965Sjdp      }
191733965Sjdp    }
191833965Sjdp    if (!wait_for_signal) {
191933965Sjdp      return -1;
192033965Sjdp    }
1921104834Sobrien
192233965Sjdp    JavaThread *thread = JavaThread::current();
192333965Sjdp
192433965Sjdp    ThreadBlockInVM tbivm(thread);
192533965Sjdp
192633965Sjdp    bool threadIsSuspended;
192733965Sjdp    do {
192833965Sjdp      thread->set_suspend_equivalent();
1929104834Sobrien      // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
193060484Sobrien      ret = ::WaitForSingleObject(sig_sem, INFINITE);
193160484Sobrien      assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed");
193233965Sjdp
193333965Sjdp      // were we externally suspended while we were waiting?
193433965Sjdp      threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
193533965Sjdp      if (threadIsSuspended) {
193633965Sjdp        //
193733965Sjdp        // The semaphore has been incremented, but while we were waiting
193833965Sjdp        // another thread suspended us. We don't want to continue running
193933965Sjdp        // while suspended because that would surprise the thread that
194033965Sjdp        // suspended us.
194133965Sjdp        //
194233965Sjdp        ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
194333965Sjdp        assert(ret != 0, "ReleaseSemaphore() failed");
194433965Sjdp
194533965Sjdp        thread->java_suspend_self();
194633965Sjdp      }
194733965Sjdp    } while (threadIsSuspended);
194833965Sjdp  }
194933965Sjdp}
195033965Sjdp
195133965Sjdpint os::signal_lookup() {
195233965Sjdp  return check_pending_signals(false);
195333965Sjdp}
195433965Sjdp
195533965Sjdpint os::signal_wait() {
195633965Sjdp  return check_pending_signals(true);
195760484Sobrien}
195833965Sjdp
195933965Sjdp// Implicit OS exception handling
196033965Sjdp
196133965SjdpLONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {
196233965Sjdp  JavaThread* thread = JavaThread::current();
196333965Sjdp  // Save pc in thread
196438889Sjdp#ifdef _M_IA64
196538889Sjdp  thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP);
196638889Sjdp  // Set pc to handler
196760484Sobrien  exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;
196860484Sobrien#elif _M_AMD64
196938889Sjdp  thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip);
197060484Sobrien  // Set pc to handler
197160484Sobrien  exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
197238889Sjdp#else
197333965Sjdp  thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip);
197433965Sjdp  // Set pc to handler
197533965Sjdp  exceptionInfo->ContextRecord->Eip = (LONG)handler;
197633965Sjdp#endif
1977130561Sobrien
197833965Sjdp  // Continue the execution
197933965Sjdp  return EXCEPTION_CONTINUE_EXECUTION;
198033965Sjdp}
198133965Sjdp
198233965Sjdp
198333965Sjdp// Used for PostMortemDump
198433965Sjdpextern "C" void safepoints();
198533965Sjdpextern "C" void find(int x);
198633965Sjdpextern "C" void events();
198733965Sjdp
198833965Sjdp// According to Windows API documentation, an illegal instruction sequence should generate
198933965Sjdp// the 0xC000001C exception code. However, real world experience shows that occasionnaly
199033965Sjdp// the execution of an illegal instruction can generate the exception code 0xC000001E. This
199133965Sjdp// seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
199233965Sjdp
199333965Sjdp#define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
199433965Sjdp
199533965Sjdp// From "Execution Protection in the Windows Operating System" draft 0.35
199633965Sjdp// Once a system header becomes available, the "real" define should be
199733965Sjdp// included or copied here.
199833965Sjdp#define EXCEPTION_INFO_EXEC_VIOLATION 0x08
199933965Sjdp
200033965Sjdp#define def_excpt(val) #val, val
200133965Sjdp
200233965Sjdpstruct siglabel {
200333965Sjdp  char *name;
200433965Sjdp  int   number;
200533965Sjdp};
2006130561Sobrien
200733965Sjdpstruct siglabel exceptlabels[] = {
200833965Sjdp    def_excpt(EXCEPTION_ACCESS_VIOLATION),
200960484Sobrien    def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
201033965Sjdp    def_excpt(EXCEPTION_BREAKPOINT),
201133965Sjdp    def_excpt(EXCEPTION_SINGLE_STEP),
201233965Sjdp    def_excpt(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
201333965Sjdp    def_excpt(EXCEPTION_FLT_DENORMAL_OPERAND),
201433965Sjdp    def_excpt(EXCEPTION_FLT_DIVIDE_BY_ZERO),
201533965Sjdp    def_excpt(EXCEPTION_FLT_INEXACT_RESULT),
201633965Sjdp    def_excpt(EXCEPTION_FLT_INVALID_OPERATION),
201733965Sjdp    def_excpt(EXCEPTION_FLT_OVERFLOW),
201833965Sjdp    def_excpt(EXCEPTION_FLT_STACK_CHECK),
201933965Sjdp    def_excpt(EXCEPTION_FLT_UNDERFLOW),
202033965Sjdp    def_excpt(EXCEPTION_INT_DIVIDE_BY_ZERO),
202133965Sjdp    def_excpt(EXCEPTION_INT_OVERFLOW),
202233965Sjdp    def_excpt(EXCEPTION_PRIV_INSTRUCTION),
202333965Sjdp    def_excpt(EXCEPTION_IN_PAGE_ERROR),
202433965Sjdp    def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION),
202533965Sjdp    def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION_2),
202633965Sjdp    def_excpt(EXCEPTION_NONCONTINUABLE_EXCEPTION),
202733965Sjdp    def_excpt(EXCEPTION_STACK_OVERFLOW),
202833965Sjdp    def_excpt(EXCEPTION_INVALID_DISPOSITION),
202933965Sjdp    def_excpt(EXCEPTION_GUARD_PAGE),
203033965Sjdp    def_excpt(EXCEPTION_INVALID_HANDLE),
203133965Sjdp    NULL, 0
203233965Sjdp};
203360484Sobrien
203460484Sobrienconst char* os::exception_name(int exception_code, char *buf, size_t size) {
203533965Sjdp  for (int i = 0; exceptlabels[i].name != NULL; i++) {
203633965Sjdp    if (exceptlabels[i].number == exception_code) {
2037130561Sobrien       jio_snprintf(buf, size, "%s", exceptlabels[i].name);
203860484Sobrien       return buf;
203960484Sobrien    }
204033965Sjdp  }
204160484Sobrien
2042104834Sobrien  return NULL;
204360484Sobrien}
204433965Sjdp
204533965Sjdp//-----------------------------------------------------------------------------
204638889SjdpLONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2047130561Sobrien  // handle exception caused by idiv; should only happen for -MinInt/-1
204833965Sjdp  // (division by zero is handled explicitly)
2049130561Sobrien#ifdef _M_IA64
2050130561Sobrien  assert(0, "Fix Handle_IDiv_Exception");
2051218822Sdim#elif _M_AMD64
2052218822Sdim  PCONTEXT ctx = exceptionInfo->ContextRecord;
2053218822Sdim  address pc = (address)ctx->Rip;
205433965Sjdp  NOT_PRODUCT(Events::log("idiv overflow exception at " INTPTR_FORMAT , pc));
205533965Sjdp  assert(pc[0] == 0xF7, "not an idiv opcode");
2056130561Sobrien  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
205733965Sjdp  assert(ctx->Rax == min_jint, "unexpected idiv exception");
205833965Sjdp  // set correct result values and continue after idiv instruction
205933965Sjdp  ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
206033965Sjdp  ctx->Rax = (DWORD)min_jint;      // result
206133965Sjdp  ctx->Rdx = (DWORD)0;             // remainder
206233965Sjdp  // Continue the execution
206333965Sjdp#else
206433965Sjdp  PCONTEXT ctx = exceptionInfo->ContextRecord;
2065130561Sobrien  address pc = (address)ctx->Eip;
2066130561Sobrien  NOT_PRODUCT(Events::log("idiv overflow exception at " INTPTR_FORMAT , pc));
206733965Sjdp  assert(pc[0] == 0xF7, "not an idiv opcode");
206833965Sjdp  assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
206933965Sjdp  assert(ctx->Eax == min_jint, "unexpected idiv exception");
207033965Sjdp  // set correct result values and continue after idiv instruction
207133965Sjdp  ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
207233965Sjdp  ctx->Eax = (DWORD)min_jint;      // result
207333965Sjdp  ctx->Edx = (DWORD)0;             // remainder
207460484Sobrien  // Continue the execution
207533965Sjdp#endif
207633965Sjdp  return EXCEPTION_CONTINUE_EXECUTION;
207733965Sjdp}
207833965Sjdp
207933965Sjdp#ifndef  _WIN64
208033965Sjdp//-----------------------------------------------------------------------------
208133965SjdpLONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
208233965Sjdp  // handle exception caused by native method modifying control word
208333965Sjdp  PCONTEXT ctx = exceptionInfo->ContextRecord;
2084130561Sobrien  DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
208533965Sjdp
208633965Sjdp  switch (exception_code) {
208733965Sjdp    case EXCEPTION_FLT_DENORMAL_OPERAND:
208833965Sjdp    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
208933965Sjdp    case EXCEPTION_FLT_INEXACT_RESULT:
209033965Sjdp    case EXCEPTION_FLT_INVALID_OPERATION:
209133965Sjdp    case EXCEPTION_FLT_OVERFLOW:
209233965Sjdp    case EXCEPTION_FLT_STACK_CHECK:
209333965Sjdp    case EXCEPTION_FLT_UNDERFLOW:
209433965Sjdp      jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
209533965Sjdp      if (fp_control_word != ctx->FloatSave.ControlWord) {
209633965Sjdp        // Restore FPCW and mask out FLT exceptions
209733965Sjdp        ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;
209833965Sjdp        // Mask out pending FLT exceptions
209989857Sobrien        ctx->FloatSave.StatusWord &=  0xffffff00;
210089857Sobrien        return EXCEPTION_CONTINUE_EXECUTION;
210189857Sobrien      }
210289857Sobrien  }
210389857Sobrien
210489857Sobrien  if (prev_uef_handler != NULL) {
210589857Sobrien    // We didn't handle this exception so pass it to the previous
210660484Sobrien    // UnhandledExceptionFilter.
210733965Sjdp    return (prev_uef_handler)(exceptionInfo);
210889857Sobrien  }
210989857Sobrien
211089857Sobrien  return EXCEPTION_CONTINUE_SEARCH;
211189857Sobrien}
211289857Sobrien#else //_WIN64
211389857Sobrien/*
211489857Sobrien  On Windows, the mxcsr control bits are non-volatile across calls
211533965Sjdp  See also CR 6192333
211633965Sjdp  If EXCEPTION_FLT_* happened after some native method modified
211760484Sobrien  mxcsr - it is not a jvm fault.
211833965Sjdp  However should we decide to restore of mxcsr after a faulty
2119130561Sobrien  native method we can uncomment following code
2120130561Sobrien      jint MxCsr = INITIAL_MXCSR;
212133965Sjdp        // we can't use StubRoutines::addr_mxcsr_std()
212233965Sjdp        // because in Win64 mxcsr is not saved there
212333965Sjdp      if (MxCsr != ctx->MxCsr) {
212433965Sjdp        ctx->MxCsr = MxCsr;
212533965Sjdp        return EXCEPTION_CONTINUE_EXECUTION;
212633965Sjdp      }
212733965Sjdp
212833965Sjdp*/
212933965Sjdp#endif //_WIN64
213033965Sjdp
213133965Sjdp
213233965Sjdp// Fatal error reporting is single threaded so we can make this a
213360484Sobrien// static and preallocated.  If it's more than MAX_PATH silently ignore
213433965Sjdp// it.
213533965Sjdpstatic char saved_error_file[MAX_PATH] = {0};
213633965Sjdp
213733965Sjdpvoid os::set_error_file(const char *logfile) {
213833965Sjdp  if (strlen(logfile) <= MAX_PATH) {
213933965Sjdp    strncpy(saved_error_file, logfile, MAX_PATH);
214033965Sjdp  }
214133965Sjdp}
214233965Sjdp
214333965Sjdpstatic inline void report_error(Thread* t, DWORD exception_code,
214433965Sjdp                                address addr, void* siginfo, void* context) {
214533965Sjdp  VMError err(t, exception_code, addr, siginfo, context);
214633965Sjdp  err.report_and_die();
214733965Sjdp
2148130561Sobrien  // If UseOsErrorReporting, this will return here and save the error file
2149130561Sobrien  // somewhere where we can find it in the minidump.
215033965Sjdp}
215133965Sjdp
215233965Sjdp//-----------------------------------------------------------------------------
215333965SjdpLONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
215433965Sjdp  if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
215533965Sjdp  DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
215633965Sjdp#ifdef _M_IA64
215733965Sjdp  address pc = (address) exceptionInfo->ContextRecord->StIIP;
215833965Sjdp#elif _M_AMD64
215933965Sjdp  address pc = (address) exceptionInfo->ContextRecord->Rip;
216033965Sjdp#else
216133965Sjdp  address pc = (address) exceptionInfo->ContextRecord->Eip;
216233965Sjdp#endif
216333965Sjdp  Thread* t = ThreadLocalStorage::get_thread_slow();          // slow & steady
216433965Sjdp
216533965Sjdp#ifndef _WIN64
216633965Sjdp  // Execution protection violation - win32 running on AMD64 only
216733965Sjdp  // Handled first to avoid misdiagnosis as a "normal" access violation;
216833965Sjdp  // This is safe to do because we have a new/unique ExceptionInformation
216933965Sjdp  // code for this condition.
217033965Sjdp  if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
217133965Sjdp    PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2172130561Sobrien    int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];
217333965Sjdp    address addr = (address) exceptionRecord->ExceptionInformation[1];
217460484Sobrien
217533965Sjdp    if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {
217633965Sjdp      int page_size = os::vm_page_size();
217733965Sjdp
217833965Sjdp      // Make sure the pc and the faulting address are sane.
217933965Sjdp      //
218033965Sjdp      // If an instruction spans a page boundary, and the page containing
218133965Sjdp      // the beginning of the instruction is executable but the following
218233965Sjdp      // page is not, the pc and the faulting address might be slightly
2183130561Sobrien      // different - we still want to unguard the 2nd page in this case.
218433965Sjdp      //
218533965Sjdp      // 15 bytes seems to be a (very) safe value for max instruction size.
2186130561Sobrien      bool pc_is_near_addr =
218733965Sjdp        (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
2188218822Sdim      bool instr_spans_page_boundary =
2189218822Sdim        (align_size_down((intptr_t) pc ^ (intptr_t) addr,
2190130561Sobrien                         (intptr_t) page_size) > 0);
2191218822Sdim
219233965Sjdp      if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
219333965Sjdp        static volatile address last_addr =
219433965Sjdp          (address) os::non_memory_address_word();
219533965Sjdp
219633965Sjdp        // In conservative mode, don't unguard unless the address is in the VM
2197130561Sobrien        if (UnguardOnExecutionViolation > 0 && addr != last_addr &&
2198130561Sobrien            (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
2199130561Sobrien
2200130561Sobrien          // Set memory to RWX and retry
2201130561Sobrien          address page_start =
2202130561Sobrien            (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
2203130561Sobrien          bool res = os::protect_memory((char*) page_start, page_size,
2204130561Sobrien                                        os::MEM_PROT_RWX);
2205130561Sobrien
2206130561Sobrien          if (PrintMiscellaneous && Verbose) {
2207130561Sobrien            char buf[256];
2208130561Sobrien            jio_snprintf(buf, sizeof(buf), "Execution protection violation "
2209130561Sobrien                         "at " INTPTR_FORMAT
2210130561Sobrien                         ", unguarding " INTPTR_FORMAT ": %s", addr,
2211130561Sobrien                         page_start, (res ? "success" : strerror(errno)));
2212218822Sdim            tty->print_raw_cr(buf);
2213130561Sobrien          }
2214130561Sobrien
2215218822Sdim          // Set last_addr so if we fault again at the same address, we don't
2216130561Sobrien          // end up in an endless loop.
2217130561Sobrien          //
2218130561Sobrien          // There are two potential complications here.  Two threads trapping
2219130561Sobrien          // at the same address at the same time could cause one of the
2220130561Sobrien          // threads to think it already unguarded, and abort the VM.  Likely
222133965Sjdp          // very rare.
2222130561Sobrien          //
222333965Sjdp          // The other race involves two threads alternately trapping at
2224218822Sdim          // different addresses and failing to unguard the page, resulting in
2225218822Sdim          // an endless loop.  This condition is probably even more unlikely
2226218822Sdim          // than the first.
2227218822Sdim          //
2228218822Sdim          // Although both cases could be avoided by using locks or thread
2229218822Sdim          // local last_addr, these solutions are unnecessary complication:
2230218822Sdim          // this handler is a best-effort safety net, not a complete solution.
223133965Sjdp          // It is disabled by default and should only be used as a workaround
2232218822Sdim          // in case we missed any no-execute-unsafe VM code.
2233218822Sdim
223460484Sobrien          last_addr = addr;
223533965Sjdp
223660484Sobrien          return EXCEPTION_CONTINUE_EXECUTION;
223760484Sobrien        }
223838889Sjdp      }
2239218822Sdim
2240218822Sdim      // Last unguard failed or not unguarding
2241218822Sdim      tty->print_raw_cr("Execution protection violation");
2242218822Sdim      report_error(t, exception_code, addr, exceptionInfo->ExceptionRecord,
224333965Sjdp                   exceptionInfo->ContextRecord);
224433965Sjdp      return EXCEPTION_CONTINUE_SEARCH;
2245218822Sdim    }
2246104834Sobrien  }
2247218822Sdim#endif // _WIN64
2248104834Sobrien
2249218822Sdim  // Check to see if we caught the safepoint code in the
2250218822Sdim  // process of write protecting the memory serialization page.
2251218822Sdim  // It write enables the page immediately after protecting it
2252104834Sobrien  // so just return.
2253218822Sdim  if ( exception_code == EXCEPTION_ACCESS_VIOLATION ) {
2254218822Sdim    JavaThread* thread = (JavaThread*) t;
225533965Sjdp    PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2256218822Sdim    address addr = (address) exceptionRecord->ExceptionInformation[1];
2257218822Sdim    if ( os::is_memory_serialize_page(thread, addr) ) {
2258104834Sobrien      // Block current thread until the memory serialize page permission restored.
225960484Sobrien      os::block_on_serialize_page_trap();
2260218822Sdim      return EXCEPTION_CONTINUE_EXECUTION;
2261218822Sdim    }
226260484Sobrien  }
2263104834Sobrien
2264218822Sdim
2265104834Sobrien  if (t != NULL && t->is_Java_thread()) {
2266218822Sdim    JavaThread* thread = (JavaThread*) t;
2267218822Sdim    bool in_java = thread->thread_state() == _thread_in_Java;
2268218822Sdim
2269218822Sdim    // Handle potential stack overflows up front.
227060484Sobrien    if (exception_code == EXCEPTION_STACK_OVERFLOW) {
2271218822Sdim      if (os::uses_stack_guard_pages()) {
2272218822Sdim#ifdef _M_IA64
2273218822Sdim        //
2274218822Sdim        // If it's a legal stack address continue, Windows will map it in.
2275218822Sdim        //
2276218822Sdim        PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
227733965Sjdp        address addr = (address) exceptionRecord->ExceptionInformation[1];
2278218822Sdim        if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() )
2279218822Sdim          return EXCEPTION_CONTINUE_EXECUTION;
2280218822Sdim
2281218822Sdim        // The register save area is the same size as the memory stack
2282218822Sdim        // and starts at the page just above the start of the memory stack.
2283218822Sdim        // If we get a fault in this area, we've run out of register
2284218822Sdim        // stack.  If we are in java, try throwing a stack overflow exception.
2285218822Sdim        if (addr > thread->stack_base() &&
2286218822Sdim                      addr <= (thread->stack_base()+thread->stack_size()) ) {
2287218822Sdim          char buf[256];
2288218822Sdim          jio_snprintf(buf, sizeof(buf),
228933965Sjdp                       "Register stack overflow, addr:%p, stack_base:%p\n",
2290218822Sdim                       addr, thread->stack_base() );
2291218822Sdim          tty->print_raw_cr(buf);
229233965Sjdp          // If not in java code, return and hope for the best.
2293218822Sdim          return in_java ? Handle_Exception(exceptionInfo,
2294218822Sdim            SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
2295218822Sdim            :  EXCEPTION_CONTINUE_EXECUTION;
2296218822Sdim        }
2297218822Sdim#endif
2298218822Sdim        if (thread->stack_yellow_zone_enabled()) {
2299218822Sdim          // Yellow zone violation.  The o/s has unprotected the first yellow
2300218822Sdim          // zone page for us.  Note:  must call disable_stack_yellow_zone to
2301218822Sdim          // update the enabled status, even if the zone contains only one page.
230238889Sjdp          thread->disable_stack_yellow_zone();
2303218822Sdim          // If not in java code, return and hope for the best.
2304218822Sdim          return in_java ? Handle_Exception(exceptionInfo,
2305218822Sdim            SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
230638889Sjdp            :  EXCEPTION_CONTINUE_EXECUTION;
2307218822Sdim        } else {
230833965Sjdp          // Fatal red zone violation.
2309218822Sdim          thread->disable_stack_red_zone();
2310218822Sdim          tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
231133965Sjdp          report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
231260484Sobrien                       exceptionInfo->ContextRecord);
2313218822Sdim          return EXCEPTION_CONTINUE_SEARCH;
2314218822Sdim        }
231560484Sobrien      } else if (in_java) {
2316218822Sdim        // JVM-managed guard pages cannot be used on win95/98.  The o/s provides
2317218822Sdim        // a one-time-only guard page, which it has released to us.  The next
231833965Sjdp        // stack overflow on this thread will result in an ACCESS_VIOLATION.
2319218822Sdim        return Handle_Exception(exceptionInfo,
2320218822Sdim          SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
2321218822Sdim      } else {
2322218822Sdim        // Can only return and hope for the best.  Further stack growth will
2323218822Sdim        // result in an ACCESS_VIOLATION.
2324218822Sdim        return EXCEPTION_CONTINUE_EXECUTION;
2325218822Sdim      }
2326218822Sdim    } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2327218822Sdim      // Either stack overflow or null pointer exception.
2328218822Sdim      if (in_java) {
2329218822Sdim        PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
233033965Sjdp        address addr = (address) exceptionRecord->ExceptionInformation[1];
2331218822Sdim        address stack_end = thread->stack_base() - thread->stack_size();
2332218822Sdim        if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {
2333218822Sdim          // Stack overflow.
2334218822Sdim          assert(!os::uses_stack_guard_pages(),
2335218822Sdim            "should be caught by red zone code above.");
233633965Sjdp          return Handle_Exception(exceptionInfo,
2337218822Sdim            SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
233833965Sjdp        }
2339218822Sdim        //
2340218822Sdim        // Check for safepoint polling and implicit null
2341218822Sdim        // We only expect null pointers in the stubs (vtable)
2342218822Sdim        // the rest are checked explicitly now.
234333965Sjdp        //
2344218822Sdim        CodeBlob* cb = CodeCache::find_blob(pc);
2345218822Sdim        if (cb != NULL) {
2346218822Sdim          if (os::is_poll_address(addr)) {
2347218822Sdim            address stub = SharedRuntime::get_poll_stub(pc);
234833965Sjdp            return Handle_Exception(exceptionInfo, stub);
2349218822Sdim          }
2350218822Sdim        }
235133965Sjdp        {
235233965Sjdp#ifdef _WIN64
2353218822Sdim          //
2354218822Sdim          // If it's a legal stack address map the entire region in
2355218822Sdim          //
235633965Sjdp          PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2357218822Sdim          address addr = (address) exceptionRecord->ExceptionInformation[1];
2358218822Sdim          if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {
2359218822Sdim                  addr = (address)((uintptr_t)addr &
2360218822Sdim                         (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
2361218822Sdim                  os::commit_memory((char *)addr, thread->stack_base() - addr,
236233965Sjdp                                    false );
2363218822Sdim                  return EXCEPTION_CONTINUE_EXECUTION;
2364218822Sdim          }
2365218822Sdim          else
236638889Sjdp#endif
2367218822Sdim          {
2368218822Sdim            // Null pointer exception.
2369218822Sdim#ifdef _M_IA64
237033965Sjdp            // We catch register stack overflows in compiled code by doing
2371218822Sdim            // an explicit compare and executing a st8(G0, G0) if the
2372218822Sdim            // BSP enters into our guard area.  We test for the overflow
2373218822Sdim            // condition and fall into the normal null pointer exception
2374218822Sdim            // code if BSP hasn't overflowed.
2375218822Sdim            if ( in_java ) {
237638889Sjdp              if(thread->register_stack_overflow()) {
2377218822Sdim                assert((address)exceptionInfo->ContextRecord->IntS3 ==
2378218822Sdim                                thread->register_stack_limit(),
2379218822Sdim                               "GR7 doesn't contain register_stack_limit");
238033965Sjdp                // Disable the yellow zone which sets the state that
2381104834Sobrien                // we've got a stack overflow problem.
2382218822Sdim                if (thread->stack_yellow_zone_enabled()) {
238333965Sjdp                  thread->disable_stack_yellow_zone();
2384218822Sdim                }
2385218822Sdim                // Give us some room to process the exception
2386218822Sdim                thread->disable_register_stack_guard();
2387218822Sdim                // Update GR7 with the new limit so we can continue running
2388218822Sdim                // compiled code.
2389218822Sdim                exceptionInfo->ContextRecord->IntS3 =
2390218822Sdim                               (ULONGLONG)thread->register_stack_limit();
2391218822Sdim                return Handle_Exception(exceptionInfo,
239233965Sjdp                       SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
2393218822Sdim              } else {
2394218822Sdim                //
239533965Sjdp                // Check for implicit null
2396218822Sdim                // We only expect null pointers in the stubs (vtable)
2397218822Sdim                // the rest are checked explicitly now.
2398218822Sdim                //
239960484Sobrien                if (((uintptr_t)addr) < os::vm_page_size() ) {
2400218822Sdim                  // an access to the first page of VM--assume it is a null pointer
2401218822Sdim                  address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
2402104834Sobrien                  if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
2403218822Sdim                }
2404218822Sdim              }
2405218822Sdim            } // in_java
2406104834Sobrien
2407218822Sdim            // IA64 doesn't use implicit null checking yet. So we shouldn't
2408218822Sdim            // get here.
240933965Sjdp            tty->print_raw_cr("Access violation, possible null pointer exception");
2410218822Sdim            report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2411218822Sdim                         exceptionInfo->ContextRecord);
2412218822Sdim            return EXCEPTION_CONTINUE_SEARCH;
2413218822Sdim#else /* !IA64 */
2414218822Sdim
241533965Sjdp            // Windows 98 reports faulting addresses incorrectly
2416218822Sdim            if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
241733965Sjdp                !os::win32::is_nt()) {
2418218822Sdim              address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
2419218822Sdim              if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
2420218822Sdim            }
242133965Sjdp            report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
242260484Sobrien                         exceptionInfo->ContextRecord);
242333965Sjdp            return EXCEPTION_CONTINUE_SEARCH;
2424218822Sdim#endif
2425218822Sdim          }
242633965Sjdp        }
2427218822Sdim      }
2428218822Sdim
2429218822Sdim#ifdef _WIN64
2430218822Sdim      // Special care for fast JNI field accessors.
2431218822Sdim      // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks
2432218822Sdim      // in and the heap gets shrunk before the field access.
2433218822Sdim      if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2434218822Sdim        address addr = JNI_FastGetField::find_slowcase_pc(pc);
243533965Sjdp        if (addr != (address)-1) {
2436218822Sdim          return Handle_Exception(exceptionInfo, addr);
2437218822Sdim        }
2438218822Sdim      }
243933965Sjdp#endif
2440218822Sdim
2441218822Sdim#ifdef _WIN64
2442218822Sdim      // Windows will sometimes generate an access violation
2443218822Sdim      // when we call malloc.  Since we use VectoredExceptions
2444218822Sdim      // on 64 bit platforms, we see this exception.  We must
2445218822Sdim      // pass this exception on so Windows can recover.
2446218822Sdim      // We check to see if the pc of the fault is in NTDLL.DLL
2447218822Sdim      // if so, we pass control on to Windows for handling.
2448218822Sdim      if (UseVectoredExceptions && _addr_in_ntdll(pc)) return EXCEPTION_CONTINUE_SEARCH;
2449218822Sdim#endif
2450218822Sdim
2451218822Sdim      // Stack overflow or null pointer exception in native code.
2452218822Sdim      report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2453218822Sdim                   exceptionInfo->ContextRecord);
245433965Sjdp      return EXCEPTION_CONTINUE_SEARCH;
245533965Sjdp    }
245633965Sjdp
245733965Sjdp    if (in_java) {
2458218822Sdim      switch (exception_code) {
245933965Sjdp      case EXCEPTION_INT_DIVIDE_BY_ZERO:
246033965Sjdp        return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
246133965Sjdp
2462218822Sdim      case EXCEPTION_INT_OVERFLOW:
246333965Sjdp        return Handle_IDiv_Exception(exceptionInfo);
2464218822Sdim
2465218822Sdim      } // switch
2466218822Sdim    }
2467218822Sdim#ifndef _WIN64
2468218822Sdim    if ((thread->thread_state() == _thread_in_Java) ||
2469218822Sdim        (thread->thread_state() == _thread_in_native) )
2470218822Sdim    {
2471218822Sdim      LONG result=Handle_FLT_Exception(exceptionInfo);
2472218822Sdim      if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
2473218822Sdim    }
2474218822Sdim#endif //_WIN64
2475218822Sdim  }
2476218822Sdim
2477218822Sdim  if (exception_code != EXCEPTION_BREAKPOINT) {
247833965Sjdp#ifndef _WIN64
2479218822Sdim    report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2480218822Sdim                 exceptionInfo->ContextRecord);
2481218822Sdim#else
2482218822Sdim    // Itanium Windows uses a VectoredExceptionHandler
2483218822Sdim    // Which means that C++ programatic exception handlers (try/except)
2484218822Sdim    // will get here.  Continue the search for the right except block if
2485218822Sdim    // the exception code is not a fatal code.
2486218822Sdim    switch ( exception_code ) {
2487218822Sdim      case EXCEPTION_ACCESS_VIOLATION:
2488218822Sdim      case EXCEPTION_STACK_OVERFLOW:
2489218822Sdim      case EXCEPTION_ILLEGAL_INSTRUCTION:
2490218822Sdim      case EXCEPTION_ILLEGAL_INSTRUCTION_2:
2491218822Sdim      case EXCEPTION_INT_OVERFLOW:
249233965Sjdp      case EXCEPTION_INT_DIVIDE_BY_ZERO:
2493218822Sdim      {  report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2494218822Sdim                       exceptionInfo->ContextRecord);
2495218822Sdim      }
2496218822Sdim        break;
2497218822Sdim      default:
2498218822Sdim        break;
2499218822Sdim    }
2500218822Sdim#endif
2501218822Sdim  }
2502218822Sdim  return EXCEPTION_CONTINUE_SEARCH;
2503218822Sdim}
2504218822Sdim
2505218822Sdim#ifndef _WIN64
2506218822Sdim// Special care for fast JNI accessors.
2507218822Sdim// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
2508218822Sdim// the heap gets shrunk before the field access.
2509218822Sdim// Need to install our own structured exception handler since native code may
2510218822Sdim// install its own.
2511218822SdimLONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2512218822Sdim  DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2513218822Sdim  if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2514218822Sdim    address pc = (address) exceptionInfo->ContextRecord->Eip;
2515218822Sdim    address addr = JNI_FastGetField::find_slowcase_pc(pc);
2516218822Sdim    if (addr != (address)-1) {
2517218822Sdim      return Handle_Exception(exceptionInfo, addr);
2518218822Sdim    }
2519218822Sdim  }
2520218822Sdim  return EXCEPTION_CONTINUE_SEARCH;
2521218822Sdim}
252238889Sjdp
2523218822Sdim#define DEFINE_FAST_GETFIELD(Return,Fieldname,Result) \
2524218822SdimReturn JNICALL jni_fast_Get##Result##Field_wrapper(JNIEnv *env, jobject obj, jfieldID fieldID) { \
2525218822Sdim  __try { \
2526218822Sdim    return (*JNI_FastGetField::jni_fast_Get##Result##Field_fp)(env, obj, fieldID); \
2527218822Sdim  } __except(fastJNIAccessorExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { \
2528218822Sdim  } \
2529218822Sdim  return 0; \
2530218822Sdim}
2531218822Sdim
2532218822SdimDEFINE_FAST_GETFIELD(jboolean, bool,   Boolean)
2533218822SdimDEFINE_FAST_GETFIELD(jbyte,    byte,   Byte)
2534218822SdimDEFINE_FAST_GETFIELD(jchar,    char,   Char)
253533965SjdpDEFINE_FAST_GETFIELD(jshort,   short,  Short)
2536218822SdimDEFINE_FAST_GETFIELD(jint,     int,    Int)
2537218822SdimDEFINE_FAST_GETFIELD(jlong,    long,   Long)
2538218822SdimDEFINE_FAST_GETFIELD(jfloat,   float,  Float)
253933965SjdpDEFINE_FAST_GETFIELD(jdouble,  double, Double)
2540218822Sdim
2541218822Sdimaddress os::win32::fast_jni_accessor_wrapper(BasicType type) {
2542218822Sdim  switch (type) {
2543218822Sdim    case T_BOOLEAN: return (address)jni_fast_GetBooleanField_wrapper;
2544218822Sdim    case T_BYTE:    return (address)jni_fast_GetByteField_wrapper;
2545218822Sdim    case T_CHAR:    return (address)jni_fast_GetCharField_wrapper;
2546218822Sdim    case T_SHORT:   return (address)jni_fast_GetShortField_wrapper;
254733965Sjdp    case T_INT:     return (address)jni_fast_GetIntField_wrapper;
2548218822Sdim    case T_LONG:    return (address)jni_fast_GetLongField_wrapper;
2549218822Sdim    case T_FLOAT:   return (address)jni_fast_GetFloatField_wrapper;
2550218822Sdim    case T_DOUBLE:  return (address)jni_fast_GetDoubleField_wrapper;
255133965Sjdp    default:        ShouldNotReachHere();
2552218822Sdim  }
2553218822Sdim  return (address)-1;
255433965Sjdp}
2555218822Sdim#endif
2556218822Sdim
2557218822Sdim// Virtual Memory
2558218822Sdim
2559218822Sdimint os::vm_page_size() { return os::win32::vm_page_size(); }
2560218822Sdimint os::vm_allocation_granularity() {
2561218822Sdim  return os::win32::vm_allocation_granularity();
2562218822Sdim}
2563218822Sdim
256433965Sjdp// Windows large page support is available on Windows 2003. In order to use
2565218822Sdim// large page memory, the administrator must first assign additional privilege
2566218822Sdim// to the user:
256733965Sjdp//   + select Control Panel -> Administrative Tools -> Local Security Policy
2568218822Sdim//   + select Local Policies -> User Rights Assignment
2569218822Sdim//   + double click "Lock pages in memory", add users and/or groups
2570218822Sdim//   + reboot
2571218822Sdim// Note the above steps are needed for administrator as well, as administrators
257233965Sjdp// by default do not have the privilege to lock pages in memory.
2573218822Sdim//
2574218822Sdim// Note about Windows 2003: although the API supports committing large page
2575218822Sdim// memory on a page-by-page basis and VirtualAlloc() returns success under this
2576218822Sdim// scenario, I found through experiment it only uses large page if the entire
257733965Sjdp// memory region is reserved and committed in a single VirtualAlloc() call.
2578218822Sdim// This makes Windows large page support more or less like Solaris ISM, in
2579218822Sdim// that the entire heap must be committed upfront. This probably will change
2580218822Sdim// in the future, if so the code below needs to be revisited.
2581218822Sdim
2582218822Sdim#ifndef MEM_LARGE_PAGES
258333965Sjdp#define MEM_LARGE_PAGES 0x20000000
2584218822Sdim#endif
2585218822Sdim
258633965Sjdp// GetLargePageMinimum is only available on Windows 2003. The other functions
2587218822Sdim// are available on NT but not on Windows 98/Me. We have to resolve them at
2588218822Sdim// runtime.
2589218822Sdimtypedef SIZE_T (WINAPI *GetLargePageMinimum_func_type) (void);
2590218822Sdimtypedef BOOL (WINAPI *AdjustTokenPrivileges_func_type)
2591218822Sdim             (HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
2592218822Sdimtypedef BOOL (WINAPI *OpenProcessToken_func_type) (HANDLE, DWORD, PHANDLE);
259333965Sjdptypedef BOOL (WINAPI *LookupPrivilegeValue_func_type) (LPCTSTR, LPCTSTR, PLUID);
2594218822Sdim
2595218822Sdimstatic GetLargePageMinimum_func_type   _GetLargePageMinimum;
2596218822Sdimstatic AdjustTokenPrivileges_func_type _AdjustTokenPrivileges;
2597218822Sdimstatic OpenProcessToken_func_type      _OpenProcessToken;
2598218822Sdimstatic LookupPrivilegeValue_func_type  _LookupPrivilegeValue;
2599218822Sdim
2600218822Sdimstatic HINSTANCE _kernel32;
2601218822Sdimstatic HINSTANCE _advapi32;
2602218822Sdimstatic HANDLE    _hProcess;
2603218822Sdimstatic HANDLE    _hToken;
2604218822Sdim
2605218822Sdimstatic size_t _large_page_size = 0;
2606218822Sdim
260733965Sjdpstatic bool resolve_functions_for_large_page_init() {
2608218822Sdim  _kernel32 = LoadLibrary("kernel32.dll");
2609218822Sdim  if (_kernel32 == NULL) return false;
2610218822Sdim
2611218822Sdim  _GetLargePageMinimum   = CAST_TO_FN_PTR(GetLargePageMinimum_func_type,
261233965Sjdp                            GetProcAddress(_kernel32, "GetLargePageMinimum"));
2613218822Sdim  if (_GetLargePageMinimum == NULL) return false;
2614218822Sdim
2615218822Sdim  _advapi32 = LoadLibrary("advapi32.dll");
2616218822Sdim  if (_advapi32 == NULL) return false;
261733965Sjdp
2618218822Sdim  _AdjustTokenPrivileges = CAST_TO_FN_PTR(AdjustTokenPrivileges_func_type,
261933965Sjdp                            GetProcAddress(_advapi32, "AdjustTokenPrivileges"));
2620218822Sdim  _OpenProcessToken      = CAST_TO_FN_PTR(OpenProcessToken_func_type,
2621218822Sdim                            GetProcAddress(_advapi32, "OpenProcessToken"));
2622218822Sdim  _LookupPrivilegeValue  = CAST_TO_FN_PTR(LookupPrivilegeValue_func_type,
2623218822Sdim                            GetProcAddress(_advapi32, "LookupPrivilegeValueA"));
262433965Sjdp  return _AdjustTokenPrivileges != NULL &&
2625218822Sdim         _OpenProcessToken      != NULL &&
2626218822Sdim         _LookupPrivilegeValue  != NULL;
2627218822Sdim}
262838889Sjdp
262933965Sjdpstatic bool request_lock_memory_privilege() {
2630218822Sdim  _hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
263133965Sjdp                                os::current_process_id());
2632218822Sdim
2633218822Sdim  LUID luid;
2634218822Sdim  if (_hProcess != NULL &&
2635218822Sdim      _OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) &&
263633965Sjdp      _LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) {
2637218822Sdim
263833965Sjdp    TOKEN_PRIVILEGES tp;
2639218822Sdim    tp.PrivilegeCount = 1;
2640218822Sdim    tp.Privileges[0].Luid = luid;
264133965Sjdp    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
2642218822Sdim
2643218822Sdim    // AdjustTokenPrivileges() may return TRUE even when it couldn't change the
2644218822Sdim    // privilege. Check GetLastError() too. See MSDN document.
2645218822Sdim    if (_AdjustTokenPrivileges(_hToken, false, &tp, sizeof(tp), NULL, NULL) &&
2646218822Sdim        (GetLastError() == ERROR_SUCCESS)) {
264733965Sjdp      return true;
2648218822Sdim    }
2649218822Sdim  }
265033965Sjdp
2651218822Sdim  return false;
2652218822Sdim}
265333965Sjdp
2654218822Sdimstatic void cleanup_after_large_page_init() {
2655218822Sdim  _GetLargePageMinimum = NULL;
2656218822Sdim  _AdjustTokenPrivileges = NULL;
2657218822Sdim  _OpenProcessToken = NULL;
265833965Sjdp  _LookupPrivilegeValue = NULL;
2659218822Sdim  if (_kernel32) FreeLibrary(_kernel32);
2660218822Sdim  _kernel32 = NULL;
2661218822Sdim  if (_advapi32) FreeLibrary(_advapi32);
2662218822Sdim  _advapi32 = NULL;
266333965Sjdp  if (_hProcess) CloseHandle(_hProcess);
266433965Sjdp  _hProcess = NULL;
266533965Sjdp  if (_hToken) CloseHandle(_hToken);
2666130561Sobrien  _hToken = NULL;
266733965Sjdp}
266860484Sobrien
266933965Sjdpbool os::large_page_init() {
267060484Sobrien  if (!UseLargePages) return false;
267160484Sobrien
267260484Sobrien  // print a warning if any large page related flag is specified on command line
267360484Sobrien  bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||
267460484Sobrien                         !FLAG_IS_DEFAULT(LargePageSizeInBytes);
2675104834Sobrien  bool success = false;
267633965Sjdp
267733965Sjdp# define WARN(msg) if (warn_on_failure) { warning(msg); }
267833965Sjdp  if (resolve_functions_for_large_page_init()) {
267933965Sjdp    if (request_lock_memory_privilege()) {
268033965Sjdp      size_t s = _GetLargePageMinimum();
268133965Sjdp      if (s) {
268233965Sjdp#if defined(IA32) || defined(AMD64)
268333965Sjdp        if (s > 4*M || LargePageSizeInBytes > 4*M) {
268433965Sjdp          WARN("JVM cannot use large pages bigger than 4mb.");
268533965Sjdp        } else {
268633965Sjdp#endif
268733965Sjdp          if (LargePageSizeInBytes && LargePageSizeInBytes % s == 0) {
268833965Sjdp            _large_page_size = LargePageSizeInBytes;
268933965Sjdp          } else {
269033965Sjdp            _large_page_size = s;
269133965Sjdp          }
269233965Sjdp          success = true;
269333965Sjdp#if defined(IA32) || defined(AMD64)
269433965Sjdp        }
269533965Sjdp#endif
269633965Sjdp      } else {
269733965Sjdp        WARN("Large page is not supported by the processor.");
269833965Sjdp      }
269933965Sjdp    } else {
270033965Sjdp      WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory.");
270160484Sobrien    }
270233965Sjdp  } else {
270333965Sjdp    WARN("Large page is not supported by the operating system.");
2704218822Sdim  }
2705218822Sdim#undef WARN
2706218822Sdim
2707218822Sdim  const size_t default_page_size = (size_t) vm_page_size();
2708218822Sdim  if (success && _large_page_size > default_page_size) {
270933965Sjdp    _page_sizes[0] = _large_page_size;
271033965Sjdp    _page_sizes[1] = default_page_size;
2711104834Sobrien    _page_sizes[2] = 0;
271260484Sobrien  }
271333965Sjdp
271433965Sjdp  cleanup_after_large_page_init();
271533965Sjdp  return success;
271633965Sjdp}
271733965Sjdp
271833965Sjdp// On win32, one cannot release just a part of reserved memory, it's an
2719104834Sobrien// all or nothing deal.  When we split a reservation, we must break the
272033965Sjdp// reservation into two reservations.
272133965Sjdpvoid os::split_reserved_memory(char *base, size_t size, size_t split,
272260484Sobrien                              bool realloc) {
272333965Sjdp  if (size > 0) {
272460484Sobrien    release_memory(base, size);
272533965Sjdp    if (realloc) {
272633965Sjdp      reserve_memory(split, base);
272760484Sobrien    }
2728130561Sobrien    if (size != split) {
272933965Sjdp      reserve_memory(size - split, base + split);
273060484Sobrien    }
273133965Sjdp  }
273260484Sobrien}
273333965Sjdp
273460484Sobrienchar* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
273560484Sobrien  assert((size_t)addr % os::vm_allocation_granularity() == 0,
273660484Sobrien         "reserve alignment");
2737104834Sobrien  assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
273860484Sobrien  char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
273960484Sobrien  assert(res == NULL || addr == NULL || addr == res,
274033965Sjdp         "Unexpected address from reserve.");
2741218822Sdim  return res;
2742218822Sdim}
2743218822Sdim
2744218822Sdim// Reserve memory at an arbitrary address, only if that area is
2745218822Sdim// available (and not reserved for something else).
274633965Sjdpchar* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
2747104834Sobrien  // Windows os::reserve_memory() fails of the requested address range is
274860484Sobrien  // not avilable.
274933965Sjdp  return reserve_memory(bytes, requested_addr);
275033965Sjdp}
2751218822Sdim
2752218822Sdimsize_t os::large_page_size() {
2753218822Sdim  return _large_page_size;
2754218822Sdim}
2755218822Sdim
275633965Sjdpbool os::can_commit_large_page_memory() {
275733965Sjdp  // Windows only uses large page memory when the entire region is reserved
275833965Sjdp  // and committed in a single VirtualAlloc() call. This may change in the
275933965Sjdp  // future, but with Windows 2003 it's not possible to commit on demand.
276033965Sjdp  return false;
276133965Sjdp}
276233965Sjdp
276333965Sjdpbool os::can_execute_large_page_memory() {
2764130561Sobrien  return true;
276533965Sjdp}
276633965Sjdp
276733965Sjdpchar* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
276833965Sjdp
276933965Sjdp  const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
277033965Sjdp
277133965Sjdp  if (UseLargePagesIndividualAllocation) {
277233965Sjdp    if (TracePageSizes && Verbose) {
277333965Sjdp       tty->print_cr("Reserving large pages individually.");
277433965Sjdp    }
277533965Sjdp    char * p_buf;
2776130561Sobrien    // first reserve enough address space in advance since we want to be
277733965Sjdp    // able to break a single contiguous virtual address range into multiple
277833965Sjdp    // large page commits but WS2003 does not allow reserving large page space
277933965Sjdp    // so we just use 4K pages for reserve, this gives us a legal contiguous
278033965Sjdp    // address space. then we will deallocate that reservation, and re alloc
278133965Sjdp    // using large pages
278233965Sjdp    const size_t size_of_reserve = bytes + _large_page_size;
278333965Sjdp    if (bytes > size_of_reserve) {
278433965Sjdp      // Overflowed.
278533965Sjdp      warning("Individually allocated large pages failed, "
278633965Sjdp        "use -XX:-UseLargePagesIndividualAllocation to turn off");
278733965Sjdp      return NULL;
278860484Sobrien    }
2789104834Sobrien    p_buf = (char *) VirtualAlloc(addr,
2790130561Sobrien                                 size_of_reserve,  // size of Reserve
279133965Sjdp                                 MEM_RESERVE,
279233965Sjdp                                 PAGE_READWRITE);
279333965Sjdp    // If reservation failed, return NULL
2794130561Sobrien    if (p_buf == NULL) return NULL;
279533965Sjdp
279633965Sjdp    release_memory(p_buf, bytes + _large_page_size);
279733965Sjdp    // round up to page boundary.  If the size_of_reserve did not
279833965Sjdp    // overflow and the reservation did not fail, this align up
279933965Sjdp    // should not overflow.
280033965Sjdp    p_buf = (char *) align_size_up((size_t)p_buf, _large_page_size);
280133965Sjdp
280233965Sjdp    // now go through and allocate one page at a time until all bytes are
280333965Sjdp    // allocated
280433965Sjdp    size_t  bytes_remaining = align_size_up(bytes, _large_page_size);
280560484Sobrien    // An overflow of align_size_up() would have been caught above
280633965Sjdp    // in the calculation of size_of_reserve.
280733965Sjdp    char * next_alloc_addr = p_buf;
280860484Sobrien
280960484Sobrien#ifdef ASSERT
281060484Sobrien    // Variable for the failure injection
281160484Sobrien    long ran_num = os::random();
281260484Sobrien    size_t fail_after = ran_num % bytes;
2813104834Sobrien#endif
281433965Sjdp
281533965Sjdp    while (bytes_remaining) {
281633965Sjdp      size_t bytes_to_rq = MIN2(bytes_remaining, _large_page_size);
2817104834Sobrien      // Note allocate and commit
281833965Sjdp      char * p_new;
281933965Sjdp
282033965Sjdp#ifdef ASSERT
282160484Sobrien      bool inject_error = LargePagesIndividualAllocationInjectError &&
282260484Sobrien          (bytes_remaining <= fail_after);
2823104834Sobrien#else
282433965Sjdp      const bool inject_error = false;
282533965Sjdp#endif
2826130561Sobrien
2827130561Sobrien      if (inject_error) {
2828130561Sobrien        p_new = NULL;
2829130561Sobrien      } else {
2830130561Sobrien        p_new = (char *) VirtualAlloc(next_alloc_addr,
2831218822Sdim                                    bytes_to_rq,
283233965Sjdp                                    MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
2833218822Sdim                                    prot);
2834218822Sdim      }
2835218822Sdim
2836218822Sdim      if (p_new == NULL) {
2837218822Sdim        // Free any allocated pages
2838218822Sdim        if (next_alloc_addr > p_buf) {
2839218822Sdim          // Some memory was committed so release it.
2840218822Sdim          size_t bytes_to_release = bytes - bytes_remaining;
2841218822Sdim          release_memory(p_buf, bytes_to_release);
2842218822Sdim        }
2843218822Sdim#ifdef ASSERT
2844218822Sdim        if (UseLargePagesIndividualAllocation &&
2845218822Sdim            LargePagesIndividualAllocationInjectError) {
2846218822Sdim          if (TracePageSizes && Verbose) {
2847218822Sdim             tty->print_cr("Reserving large pages individually failed.");
2848218822Sdim          }
2849218822Sdim        }
2850218822Sdim#endif
2851218822Sdim        return NULL;
2852218822Sdim      }
285333965Sjdp      bytes_remaining -= bytes_to_rq;
285433965Sjdp      next_alloc_addr += bytes_to_rq;
2855130561Sobrien    }
2856218822Sdim
2857218822Sdim    return p_buf;
285833965Sjdp
285933965Sjdp  } else {
286038889Sjdp    // normal policy just allocate it all at once
286138889Sjdp    DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
2862104834Sobrien    char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot);
286338889Sjdp    return res;
286438889Sjdp  }
286533965Sjdp}
286638889Sjdp
286738889Sjdpbool os::release_memory_special(char* base, size_t bytes) {
2868218822Sdim  return release_memory(base, bytes);
286938889Sjdp}
287038889Sjdp
287138889Sjdpvoid os::print_statistics() {
287238889Sjdp}
2873130561Sobrien
287433965Sjdpbool os::commit_memory(char* addr, size_t bytes, bool exec) {
287533965Sjdp  if (bytes == 0) {
287660484Sobrien    // Don't bother the OS with noops.
287760484Sobrien    return true;
287860484Sobrien  }
287960484Sobrien  assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");
288033965Sjdp  assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
288133965Sjdp  // Don't attempt to print anything if the OS call fails. We're
288233965Sjdp  // probably low on resources, so the print itself may cause crashes.
288338889Sjdp  bool result = VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) != 0;
288460484Sobrien  if (result != NULL && exec) {
288560484Sobrien    DWORD oldprot;
2886130561Sobrien    // Windows doc says to use VirtualProtect to get execute permissions
2887130561Sobrien    return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot) != 0;
288838889Sjdp  } else {
2889130561Sobrien    return result;
2890130561Sobrien  }
2891130561Sobrien}
289260484Sobrien
289360484Sobrienbool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
289460484Sobrien                       bool exec) {
289560484Sobrien  return commit_memory(addr, size, exec);
2896218822Sdim}
2897218822Sdim
2898218822Sdimbool os::uncommit_memory(char* addr, size_t bytes) {
2899218822Sdim  if (bytes == 0) {
2900218822Sdim    // Don't bother the OS with noops.
2901218822Sdim    return true;
2902218822Sdim  }
290338889Sjdp  assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
290438889Sjdp  assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
2905104834Sobrien  return VirtualFree(addr, bytes, MEM_DECOMMIT) != 0;
290660484Sobrien}
290738889Sjdp
290833965Sjdpbool os::release_memory(char* addr, size_t bytes) {
2909130561Sobrien  return VirtualFree(addr, 0, MEM_RELEASE) != 0;
2910130561Sobrien}
291133965Sjdp
291238889Sjdpbool os::create_stack_guard_pages(char* addr, size_t size) {
2913130561Sobrien  return os::commit_memory(addr, size);
291433965Sjdp}
291533965Sjdp
291633965Sjdpbool os::remove_stack_guard_pages(char* addr, size_t size) {
291733965Sjdp  return os::uncommit_memory(addr, size);
291833965Sjdp}
291933965Sjdp
2920130561Sobrien// Set protections specified
292133965Sjdpbool os::protect_memory(char* addr, size_t bytes, ProtType prot,
292233965Sjdp                        bool is_committed) {
292333965Sjdp  unsigned int p = 0;
292433965Sjdp  switch (prot) {
292533965Sjdp  case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
292633965Sjdp  case MEM_PROT_READ: p = PAGE_READONLY; break;
292733965Sjdp  case MEM_PROT_RW:   p = PAGE_READWRITE; break;
292838889Sjdp  case MEM_PROT_RWX:  p = PAGE_EXECUTE_READWRITE; break;
2929130561Sobrien  default:
293033965Sjdp    ShouldNotReachHere();
293133965Sjdp  }
293233965Sjdp
2933218822Sdim  DWORD old_status;
2934218822Sdim
293533965Sjdp  // Strange enough, but on Win32 one can change protection only for committed
2936218822Sdim  // memory, not a big deal anyway, as bytes less or equal than 64K
2937218822Sdim  if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) {
2938218822Sdim    fatal("cannot commit protection page");
2939218822Sdim  }
2940218822Sdim  // One cannot use os::guard_memory() here, as on Win32 guard page
2941218822Sdim  // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
2942218822Sdim  //
294333965Sjdp  // Pages in the region become guard pages. Any attempt to access a guard page
294433965Sjdp  // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
294538889Sjdp  // the guard page status. Guard pages thus act as a one-time access alarm.
2946130561Sobrien  return VirtualProtect(addr, bytes, p, &old_status) != 0;
294733965Sjdp}
294833965Sjdp
294933965Sjdpbool os::guard_memory(char* addr, size_t bytes) {
2950130561Sobrien  DWORD old_status;
295133965Sjdp  return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;
295233965Sjdp}
295333965Sjdp
295433965Sjdpbool os::unguard_memory(char* addr, size_t bytes) {
295533965Sjdp  DWORD old_status;
295633965Sjdp  return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
295733965Sjdp}
295833965Sjdp
295933965Sjdpvoid os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
296033965Sjdpvoid os::free_memory(char *addr, size_t bytes)         { }
296133965Sjdpvoid os::numa_make_global(char *addr, size_t bytes)    { }
296233965Sjdpvoid os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
2963130561Sobrienbool os::numa_topology_changed()                       { return false; }
296433965Sjdpsize_t os::numa_get_groups_num()                       { return 1; }
296533965Sjdpint os::numa_get_group_id()                            { return 0; }
296660484Sobriensize_t os::numa_get_leaf_groups(int *ids, size_t size) {
2967130561Sobrien  if (size > 0) {
296833965Sjdp    ids[0] = 0;
296933965Sjdp    return 1;
297033965Sjdp  }
2971130561Sobrien  return 0;
297233965Sjdp}
297333965Sjdp
297433965Sjdpbool os::get_page_info(char *start, page_info* info) {
297533965Sjdp  return false;
297633965Sjdp}
297733965Sjdp
297833965Sjdpchar *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
297933965Sjdp  return end;
298033965Sjdp}
298133965Sjdp
298233965Sjdpchar* os::non_memory_address_word() {
2983104834Sobrien  // Must never look like an address returned by reserve_memory,
298460484Sobrien  // even in its subfields (as defined by the CPU immediate fields,
298560484Sobrien  // if the CPU splits constants across multiple instructions).
298660484Sobrien  return (char*)-1;
2987104834Sobrien}
298833965Sjdp
298933965Sjdp#define MAX_ERROR_COUNT 100
299060484Sobrien#define SYS_THREAD_ERROR 0xffffffffUL
299160484Sobrien
299260484Sobrienvoid os::pd_start_thread(Thread* thread) {
299333965Sjdp  DWORD ret = ResumeThread(thread->osthread()->thread_handle());
2994130561Sobrien  // Returns previous suspend state:
299533965Sjdp  // 0:  Thread was not suspended
299633965Sjdp  // 1:  Thread is running now
299733965Sjdp  // >1: Thread is still suspended.
299838889Sjdp  assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back
299933965Sjdp}
300033965Sjdp
300133965Sjdpclass HighResolutionInterval {
300233965Sjdp  // The default timer resolution seems to be 10 milliseconds.
300333965Sjdp  // (Where is this written down?)
300433965Sjdp  // If someone wants to sleep for only a fraction of the default,
300533965Sjdp  // then we set the timer resolution down to 1 millisecond for
3006130561Sobrien  // the duration of their interval.
300733965Sjdp  // We carefully set the resolution back, since otherwise we
3008130561Sobrien  // seem to incur an overhead (3%?) that we don't need.
3009130561Sobrien  // CONSIDER: if ms is small, say 3, then we should run with a high resolution time.
301033965Sjdp  // Buf if ms is large, say 500, or 503, we should avoid the call to timeBeginPeriod().
301133965Sjdp  // Alternatively, we could compute the relative error (503/500 = .6%) and only use
301233965Sjdp  // timeBeginPeriod() if the relative error exceeded some threshold.
3013130561Sobrien  // timeBeginPeriod() has been linked to problems with clock drift on win32 systems and
301433965Sjdp  // to decreased efficiency related to increased timer "tick" rates.  We want to minimize
301533965Sjdp  // (a) calls to timeBeginPeriod() and timeEndPeriod() and (b) time spent with high
301633965Sjdp  // resolution timers running.
301733965Sjdpprivate:
301833965Sjdp    jlong resolution;
301933965Sjdppublic:
302033965Sjdp  HighResolutionInterval(jlong ms) {
302133965Sjdp    resolution = ms % 10L;
3022130561Sobrien    if (resolution != 0) {
302333965Sjdp      MMRESULT result = timeBeginPeriod(1L);
302433965Sjdp    }
302533965Sjdp  }
302633965Sjdp  ~HighResolutionInterval() {
3027130561Sobrien    if (resolution != 0) {
302833965Sjdp      MMRESULT result = timeEndPeriod(1L);
302933965Sjdp    }
303033965Sjdp    resolution = 0L;
303133965Sjdp  }
303233965Sjdp};
3033130561Sobrien
303433965Sjdpint os::sleep(Thread* thread, jlong ms, bool interruptable) {
3035130561Sobrien  jlong limit = (jlong) MAXDWORD;
303633965Sjdp
303733965Sjdp  while(ms > limit) {
303833965Sjdp    int res;
303933965Sjdp    if ((res = sleep(thread, limit, interruptable)) != OS_TIMEOUT)
304033965Sjdp      return res;
304133965Sjdp    ms -= limit;
304233965Sjdp  }
3043104834Sobrien
304433965Sjdp  assert(thread == Thread::current(),  "thread consistency check");
304533965Sjdp  OSThread* osthread = thread->osthread();
304633965Sjdp  OSThreadWaitState osts(osthread, false /* not Object.wait() */);
304733965Sjdp  int result;
3048130561Sobrien  if (interruptable) {
304933965Sjdp    assert(thread->is_Java_thread(), "must be java thread");
3050104834Sobrien    JavaThread *jt = (JavaThread *) thread;
305133965Sjdp    ThreadBlockInVM tbivm(jt);
305233965Sjdp
305333965Sjdp    jt->set_suspend_equivalent();
305433965Sjdp    // cleared by handle_special_suspend_equivalent_condition() or
305533965Sjdp    // java_suspend_self() via check_and_wait_while_suspended()
305633965Sjdp
305733965Sjdp    HANDLE events[1];
305833965Sjdp    events[0] = osthread->interrupt_event();
3059104834Sobrien    HighResolutionInterval *phri=NULL;
306033965Sjdp    if(!ForceTimeHighResolution)
306133965Sjdp      phri = new HighResolutionInterval( ms );
306233965Sjdp    if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) {
306333965Sjdp      result = OS_TIMEOUT;
306433965Sjdp    } else {
306533965Sjdp      ResetEvent(osthread->interrupt_event());
306633965Sjdp      osthread->set_interrupted(false);
306733965Sjdp      result = OS_INTRPT;
306833965Sjdp    }
306933965Sjdp    delete phri; //if it is NULL, harmless
307033965Sjdp
307133965Sjdp    // were we externally suspended while we were waiting?
307233965Sjdp    jt->check_and_wait_while_suspended();
3073130561Sobrien  } else {
307433965Sjdp    assert(!thread->is_Java_thread(), "must not be java thread");
307533965Sjdp    Sleep((long) ms);
307633965Sjdp    result = OS_TIMEOUT;
307760484Sobrien  }
307833965Sjdp  return result;
307933965Sjdp}
308033965Sjdp
308133965Sjdp// Sleep forever; naked call to OS-specific sleep; use with CAUTION
308233965Sjdpvoid os::infinite_sleep() {
308333965Sjdp  while (true) {    // sleep forever ...
308433965Sjdp    Sleep(100000);  // ... 100 seconds at a time
308533965Sjdp  }
308638889Sjdp}
3087130561Sobrien
308833965Sjdptypedef BOOL (WINAPI * STTSignature)(void) ;
3089130561Sobrien
309033965Sjdpos::YieldResult os::NakedYield() {
309133965Sjdp  // Use either SwitchToThread() or Sleep(0)
309233965Sjdp  // Consider passing back the return value from SwitchToThread().
309333965Sjdp  // We use GetProcAddress() as ancient Win9X versions of windows doen't support SwitchToThread.
3094130561Sobrien  // In that case we revert to Sleep(0).
309533965Sjdp  static volatile STTSignature stt = (STTSignature) 1 ;
309660484Sobrien
3097104834Sobrien  if (stt == ((STTSignature) 1)) {
309833965Sjdp    stt = (STTSignature) ::GetProcAddress (LoadLibrary ("Kernel32.dll"), "SwitchToThread") ;
3099130561Sobrien    // It's OK if threads race during initialization as the operation above is idempotent.
310033965Sjdp  }
310133965Sjdp  if (stt != NULL) {
310233965Sjdp    return (*stt)() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
310333965Sjdp  } else {
3104130561Sobrien    Sleep (0) ;
310533965Sjdp  }
310633965Sjdp  return os::YIELD_UNKNOWN ;
310733965Sjdp}
310833965Sjdp
310933965Sjdpvoid os::yield() {  os::NakedYield(); }
311033965Sjdp
311133965Sjdpvoid os::yield_all(int attempts) {
3112130561Sobrien  // Yields to all threads, including threads with lower priorities
311360484Sobrien  Sleep(1);
311460484Sobrien}
311533965Sjdp
311633965Sjdp// Win32 only gives you access to seven real priorities at a time,
3117130561Sobrien// so we compress Java's ten down to seven.  It would be better
3118130561Sobrien// if we dynamically adjusted relative priorities.
311933965Sjdp
312033965Sjdpint os::java_to_os_priority[MaxPriority + 1] = {
3121218822Sdim  THREAD_PRIORITY_IDLE,                         // 0  Entry should never be used
312233965Sjdp  THREAD_PRIORITY_LOWEST,                       // 1  MinPriority
3123130561Sobrien  THREAD_PRIORITY_LOWEST,                       // 2
312433965Sjdp  THREAD_PRIORITY_BELOW_NORMAL,                 // 3
3125130561Sobrien  THREAD_PRIORITY_BELOW_NORMAL,                 // 4
3126130561Sobrien  THREAD_PRIORITY_NORMAL,                       // 5  NormPriority
3127104834Sobrien  THREAD_PRIORITY_NORMAL,                       // 6
312860484Sobrien  THREAD_PRIORITY_ABOVE_NORMAL,                 // 7
312933965Sjdp  THREAD_PRIORITY_ABOVE_NORMAL,                 // 8
313033965Sjdp  THREAD_PRIORITY_HIGHEST,                      // 9  NearMaxPriority
313138889Sjdp  THREAD_PRIORITY_HIGHEST                       // 10 MaxPriority
3132130561Sobrien};
313333965Sjdp
313460484Sobrienint prio_policy1[MaxPriority + 1] = {
313589857Sobrien  THREAD_PRIORITY_IDLE,                         // 0  Entry should never be used
313660484Sobrien  THREAD_PRIORITY_LOWEST,                       // 1  MinPriority
313760484Sobrien  THREAD_PRIORITY_LOWEST,                       // 2
313860484Sobrien  THREAD_PRIORITY_BELOW_NORMAL,                 // 3
313960484Sobrien  THREAD_PRIORITY_BELOW_NORMAL,                 // 4
314060484Sobrien  THREAD_PRIORITY_NORMAL,                       // 5  NormPriority
314160484Sobrien  THREAD_PRIORITY_ABOVE_NORMAL,                 // 6
314260484Sobrien  THREAD_PRIORITY_ABOVE_NORMAL,                 // 7
314360484Sobrien  THREAD_PRIORITY_HIGHEST,                      // 8
314460484Sobrien  THREAD_PRIORITY_HIGHEST,                      // 9  NearMaxPriority
314560484Sobrien  THREAD_PRIORITY_TIME_CRITICAL                 // 10 MaxPriority
314660484Sobrien};
314760484Sobrien
314860484Sobrienstatic int prio_init() {
314960484Sobrien  // If ThreadPriorityPolicy is 1, switch tables
315060484Sobrien  if (ThreadPriorityPolicy == 1) {
315160484Sobrien    int i;
3152218822Sdim    for (i = 0; i < MaxPriority + 1; i++) {
3153218822Sdim      os::java_to_os_priority[i] = prio_policy1[i];
315460484Sobrien    }
315560484Sobrien  }
3156218822Sdim  return 0;
315760484Sobrien}
315860484Sobrien
315960484SobrienOSReturn os::set_native_priority(Thread* thread, int priority) {
316060484Sobrien  if (!UseThreadPriorities) return OS_OK;
3161130561Sobrien  bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0;
316260484Sobrien  return ret ? OS_OK : OS_ERR;
316360484Sobrien}
316460484Sobrien
3165218822SdimOSReturn os::get_native_priority(const Thread* const thread, int* priority_ptr) {
316660484Sobrien  if ( !UseThreadPriorities ) {
316760484Sobrien    *priority_ptr = java_to_os_priority[NormPriority];
316860484Sobrien    return OS_OK;
316960484Sobrien  }
317060484Sobrien  int os_prio = GetThreadPriority(thread->osthread()->thread_handle());
3171218822Sdim  if (os_prio == THREAD_PRIORITY_ERROR_RETURN) {
3172218822Sdim    assert(false, "GetThreadPriority failed");
317333965Sjdp    return OS_ERR;
317433965Sjdp  }
317533965Sjdp  *priority_ptr = os_prio;
317660484Sobrien  return OS_OK;
317760484Sobrien}
317860484Sobrien
317960484Sobrien
3180218822Sdim// Hint to the underlying OS that a task switch would not be good.
318160484Sobrien// Void return because it's a hint and can fail.
318238889Sjdpvoid os::hint_no_preempt() {}
318333965Sjdp
318460484Sobrienvoid os::interrupt(Thread* thread) {
318533965Sjdp  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
318660484Sobrien         "possibility of dangling Thread pointer");
318760484Sobrien
318833965Sjdp  OSThread* osthread = thread->osthread();
318933965Sjdp  osthread->set_interrupted(true);
319060484Sobrien  // More than one thread can get here with the same value of osthread,
319160484Sobrien  // resulting in multiple notifications.  We do, however, want the store
319260484Sobrien  // to interrupted() to be visible to other threads before we post
319360484Sobrien  // the interrupt event.
319433965Sjdp  OrderAccess::release();
3195130561Sobrien  SetEvent(osthread->interrupt_event());
319660484Sobrien  // For JSR166:  unpark after setting status
319733965Sjdp  if (thread->is_Java_thread())
3198218822Sdim    ((JavaThread*)thread)->parker()->unpark();
319960484Sobrien
320060484Sobrien  ParkEvent * ev = thread->_ParkEvent ;
3201218822Sdim  if (ev != NULL) ev->unpark() ;
320260484Sobrien
320360484Sobrien}
320433965Sjdp
320533965Sjdp
320633965Sjdpbool os::is_interrupted(Thread* thread, bool clear_interrupted) {
320733965Sjdp  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
320833965Sjdp         "possibility of dangling Thread pointer");
320960484Sobrien
321060484Sobrien  OSThread* osthread = thread->osthread();
321160484Sobrien  bool interrupted;
3212130561Sobrien  interrupted = osthread->interrupted();
321360484Sobrien  if (clear_interrupted == true) {
321433965Sjdp    osthread->set_interrupted(false);
321533965Sjdp    ResetEvent(osthread->interrupt_event());
3216130561Sobrien  } // Otherwise leave the interrupted state alone
321799461Sobrien
321833965Sjdp  return interrupted;
3219130561Sobrien}
322033965Sjdp
322133965Sjdp// Get's a pc (hint) for a running thread. Currently used only for profiling.
322233965SjdpExtendedPC os::get_thread_pc(Thread* thread) {
322333965Sjdp  CONTEXT context;
322433965Sjdp  context.ContextFlags = CONTEXT_CONTROL;
322533965Sjdp  HANDLE handle = thread->osthread()->thread_handle();
322633965Sjdp#ifdef _M_IA64
322760484Sobrien  assert(0, "Fix get_thread_pc");
322860484Sobrien  return ExtendedPC(NULL);
322960484Sobrien#else
323089857Sobrien  if (GetThreadContext(handle, &context)) {
323189857Sobrien#ifdef _M_AMD64
323289857Sobrien    return ExtendedPC((address) context.Rip);
323360484Sobrien#else
323460484Sobrien    return ExtendedPC((address) context.Eip);
323560484Sobrien#endif
3236218822Sdim  } else {
3237218822Sdim    return ExtendedPC(NULL);
323860484Sobrien  }
3239104834Sobrien#endif
3240218822Sdim}
324160484Sobrien
3242218822Sdim// GetCurrentThreadId() returns DWORD
324360484Sobrienintx os::current_thread_id()          { return GetCurrentThreadId(); }
324460484Sobrien
324533965Sjdpstatic int _initial_pid = 0;
324633965Sjdp
324733965Sjdpint os::current_process_id()
324833965Sjdp{
324960484Sobrien  return (_initial_pid ? _initial_pid : _getpid());
3250130561Sobrien}
325160484Sobrien
325260484Sobrienint    os::win32::_vm_page_size       = 0;
3253130561Sobrienint    os::win32::_vm_allocation_granularity = 0;
325460484Sobrienint    os::win32::_processor_type     = 0;
325560484Sobrien// Processor level is not available on non-NT systems, use vm_version instead
325660484Sobrienint    os::win32::_processor_level    = 0;
325760484Sobrienjulong os::win32::_physical_memory    = 0;
325860484Sobriensize_t os::win32::_default_stack_size = 0;
3259130561Sobrien
326060484Sobrien         intx os::win32::_os_thread_limit    = 0;
3261218822Sdimvolatile intx os::win32::_os_thread_count    = 0;
3262218822Sdim
3263218822Sdimbool   os::win32::_is_nt              = false;
326460484Sobrienbool   os::win32::_is_windows_2003    = false;
326533965Sjdp
326633965Sjdp
326760484Sobrienvoid os::win32::initialize_system_info() {
326833965Sjdp  SYSTEM_INFO si;
326933965Sjdp  GetSystemInfo(&si);
327033965Sjdp  _vm_page_size    = si.dwPageSize;
327133965Sjdp  _vm_allocation_granularity = si.dwAllocationGranularity;
327233965Sjdp  _processor_type  = si.dwProcessorType;
3273130561Sobrien  _processor_level = si.wProcessorLevel;
3274130561Sobrien  set_processor_count(si.dwNumberOfProcessors);
3275130561Sobrien
327660484Sobrien  MEMORYSTATUSEX ms;
327760484Sobrien  ms.dwLength = sizeof(ms);
327860484Sobrien
327933965Sjdp  // also returns dwAvailPhys (free physical memory bytes), dwTotalVirtual, dwAvailVirtual,
3280130561Sobrien  // dwMemoryLoad (% of memory in use)
328133965Sjdp  GlobalMemoryStatusEx(&ms);
328233965Sjdp  _physical_memory = ms.ullTotalPhys;
328333965Sjdp
328433965Sjdp  OSVERSIONINFO oi;
328533965Sjdp  oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
328633965Sjdp  GetVersionEx(&oi);
328733965Sjdp  switch(oi.dwPlatformId) {
328833965Sjdp    case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break;
328933965Sjdp    case VER_PLATFORM_WIN32_NT:
3290218822Sdim      _is_nt = true;
3291218822Sdim      {
3292218822Sdim        int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;
3293218822Sdim        if (os_vers == 5002) {
329433965Sjdp          _is_windows_2003 = true;
329533965Sjdp        }
329633965Sjdp      }
329733965Sjdp      break;
329833965Sjdp    default: fatal("Unknown platform");
329933965Sjdp  }
330033965Sjdp
330189857Sobrien  _default_stack_size = os::current_stack_size();
330233965Sjdp  assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");
330360484Sobrien  assert((_default_stack_size & (_vm_page_size - 1)) == 0,
330433965Sjdp    "stack size not a multiple of page size");
330533965Sjdp
330633965Sjdp  initialize_performance_counter();
330733965Sjdp
330833965Sjdp  // Win95/Win98 scheduler bug work-around. The Win95/98 scheduler is
330933965Sjdp  // known to deadlock the system, if the VM issues to thread operations with
331033965Sjdp  // a too high frequency, e.g., such as changing the priorities.
331160484Sobrien  // The 6000 seems to work well - no deadlocks has been notices on the test
331260484Sobrien  // programs that we have seen experience this problem.
331333965Sjdp  if (!os::win32::is_nt()) {
331433965Sjdp    StarvationMonitorInterval = 6000;
331533965Sjdp  }
331633965Sjdp}
331733965Sjdp
331833965Sjdp
331933965Sjdpvoid os::win32::setmode_streams() {
332060484Sobrien  _setmode(_fileno(stdin), _O_BINARY);
332160484Sobrien  _setmode(_fileno(stdout), _O_BINARY);
332260484Sobrien  _setmode(_fileno(stderr), _O_BINARY);
3323218822Sdim}
3324218822Sdim
3325218822Sdim
332633965Sjdpint os::message_box(const char* title, const char* message) {
332733965Sjdp  int result = MessageBox(NULL, message, title,
332833965Sjdp                          MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);
332933965Sjdp  return result == IDYES;
333033965Sjdp}
333133965Sjdp
333233965Sjdpint os::allocate_thread_local_storage() {
333333965Sjdp  return TlsAlloc();
3334104834Sobrien}
333533965Sjdp
333660484Sobrien
333760484Sobrienvoid os::free_thread_local_storage(int index) {
333860484Sobrien  TlsFree(index);
333933965Sjdp}
334060484Sobrien
334160484Sobrien
334260484Sobrienvoid os::thread_local_storage_at_put(int index, void* value) {
334360484Sobrien  TlsSetValue(index, value);
334460484Sobrien  assert(thread_local_storage_at(index) == value, "Just checking");
334560484Sobrien}
334660484Sobrien
334760484Sobrien
334860484Sobrienvoid* os::thread_local_storage_at(int index) {
334960484Sobrien  return TlsGetValue(index);
335060484Sobrien}
335160484Sobrien
335260484Sobrien
335360484Sobrien#ifndef PRODUCT
335433965Sjdp#ifndef _WIN64
335533965Sjdp// Helpers to check whether NX protection is enabled
335660484Sobrienint nx_exception_filter(_EXCEPTION_POINTERS *pex) {
335733965Sjdp  if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
335833965Sjdp      pex->ExceptionRecord->NumberParameters > 0 &&
335933965Sjdp      pex->ExceptionRecord->ExceptionInformation[0] ==
3360130561Sobrien      EXCEPTION_INFO_EXEC_VIOLATION) {
3361130561Sobrien    return EXCEPTION_EXECUTE_HANDLER;
3362130561Sobrien  }
336333965Sjdp  return EXCEPTION_CONTINUE_SEARCH;
336460484Sobrien}
336560484Sobrien
336633965Sjdpvoid nx_check_protection() {
336733965Sjdp  // If NX is enabled we'll get an exception calling into code on the stack
336860484Sobrien  char code[] = { (char)0xC3 }; // ret
336960484Sobrien  void *code_ptr = (void *)code;
337060484Sobrien  __try {
337133965Sjdp    __asm call code_ptr
337233965Sjdp  } __except(nx_exception_filter((_EXCEPTION_POINTERS*)_exception_info())) {
337333965Sjdp    tty->print_raw_cr("NX protection detected.");
337433965Sjdp  }
3375218822Sdim}
3376218822Sdim#endif // _WIN64
3377218822Sdim#endif // PRODUCT
3378218822Sdim
3379218822Sdim// this is called _before_ the global arguments have been parsed
338033965Sjdpvoid os::init(void) {
3381218822Sdim  _initial_pid = _getpid();
338233965Sjdp
338333965Sjdp  init_random(1234567);
338433965Sjdp
338560484Sobrien  win32::initialize_system_info();
338660484Sobrien  win32::setmode_streams();
3387104834Sobrien  init_page_sizes((size_t) win32::vm_page_size());
338860484Sobrien
338960484Sobrien  // For better scalability on MP systems (must be called after initialize_system_info)
339060484Sobrien#ifndef PRODUCT
339160484Sobrien  if (is_MP()) {
3392130561Sobrien    NoYieldsInMicrolock = true;
3393104834Sobrien  }
339460484Sobrien#endif
339560484Sobrien  // This may be overridden later when argument processing is done.
339660484Sobrien  FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation,
339733965Sjdp    os::win32::is_windows_2003());
339860484Sobrien
339960484Sobrien  // Initialize main_process and main_thread
340033965Sjdp  main_process = GetCurrentProcess();  // Remember main_process is a pseudo handle
340133965Sjdp if (!DuplicateHandle(main_process, GetCurrentThread(), main_process,
340233965Sjdp                       &main_thread, THREAD_ALL_ACCESS, false, 0)) {
340333965Sjdp    fatal("DuplicateHandle failed\n");
340433965Sjdp  }
340533965Sjdp  main_thread_id = (int) GetCurrentThreadId();
340633965Sjdp}
340733965Sjdp
340833965Sjdp// To install functions for atexit processing
340933965Sjdpextern "C" {
341033965Sjdp  static void perfMemory_exit_helper() {
341133965Sjdp    perfMemory_exit();
3412104834Sobrien  }
341333965Sjdp}
341433965Sjdp
3415104834Sobrien// this is called _after_ the global arguments have been parsed
341633965Sjdpjint os::init_2(void) {
341738889Sjdp  // Allocate a single page and mark it as readable for safepoint polling
341838889Sjdp  address polling_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READONLY);
341938889Sjdp  guarantee( polling_page != NULL, "Reserve Failed for polling page");
342033965Sjdp
342189857Sobrien  address return_page  = (address)VirtualAlloc(polling_page, os::vm_page_size(), MEM_COMMIT, PAGE_READONLY);
342233965Sjdp  guarantee( return_page != NULL, "Commit Failed for polling page");
342333965Sjdp
342433965Sjdp  os::set_polling_page( polling_page );
342533965Sjdp
342633965Sjdp#ifndef PRODUCT
3427104834Sobrien  if( Verbose && PrintMiscellaneous )
342833965Sjdp    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
342933965Sjdp#endif
3430104834Sobrien
343160484Sobrien  if (!UseMembar) {
343260484Sobrien    address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);
343360484Sobrien    guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page");
343460484Sobrien
3435104834Sobrien    return_page  = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_READWRITE);
343633965Sjdp    guarantee( return_page != NULL, "Commit Failed for memory serialize page");
343733965Sjdp
343860484Sobrien    os::set_memory_serialize_page( mem_serialize_page );
343960484Sobrien
344060484Sobrien#ifndef PRODUCT
344160484Sobrien    if(Verbose && PrintMiscellaneous)
344260484Sobrien      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
344360484Sobrien#endif
344460484Sobrien}
3445130561Sobrien
344660484Sobrien  FLAG_SET_DEFAULT(UseLargePages, os::large_page_init());
344760484Sobrien
344860484Sobrien  // Setup Windows Exceptions
344960484Sobrien
3450104834Sobrien  // On Itanium systems, Structured Exception Handling does not
3451104834Sobrien  // work since stack frames must be walkable by the OS.  Since
345260484Sobrien  // much of our code is dynamically generated, and we do not have
3453104834Sobrien  // proper unwind .xdata sections, the system simply exits
345460484Sobrien  // rather than delivering the exception.  To work around
345560484Sobrien  // this we use VectorExceptions instead.
345660484Sobrien#ifdef _WIN64
345760484Sobrien  if (UseVectoredExceptions) {
345860484Sobrien    topLevelVectoredExceptionHandler = AddVectoredExceptionHandler( 1, topLevelExceptionFilter);
345960484Sobrien  }
346060484Sobrien#endif
346160484Sobrien
346260484Sobrien  // for debugging float code generation bugs
346360484Sobrien  if (ForceFloatExceptions) {
346460484Sobrien#ifndef  _WIN64
346560484Sobrien    static long fp_control_word = 0;
3466104834Sobrien    __asm { fstcw fp_control_word }
346760484Sobrien    // see Intel PPro Manual, Vol. 2, p 7-16
346860484Sobrien    const long precision = 0x20;
346960484Sobrien    const long underflow = 0x10;
347060484Sobrien    const long overflow  = 0x08;
3471104834Sobrien    const long zero_div  = 0x04;
347260484Sobrien    const long denorm    = 0x02;
347360484Sobrien    const long invalid   = 0x01;
347460484Sobrien    fp_control_word |= invalid;
347560484Sobrien    __asm { fldcw fp_control_word }
347660484Sobrien#endif
347760484Sobrien  }
347860484Sobrien
347960484Sobrien  // If stack_commit_size is 0, windows will reserve the default size,
348060484Sobrien  // but only commit a small portion of it.
348160484Sobrien  size_t stack_commit_size = round_to(ThreadStackSize*K, os::vm_page_size());
348260484Sobrien  size_t default_reserve_size = os::win32::default_stack_size();
348360484Sobrien  size_t actual_reserve_size = stack_commit_size;
348460484Sobrien  if (stack_commit_size < default_reserve_size) {
348560484Sobrien    // If stack_commit_size == 0, we want this too
348660484Sobrien    actual_reserve_size = default_reserve_size;
348760484Sobrien  }
3488104834Sobrien
348960484Sobrien  // Check minimum allowable stack size for thread creation and to initialize
349060484Sobrien  // the java system classes, including StackOverflowError - depends on page
349160484Sobrien  // size.  Add a page for compiler2 recursion in main thread.
349260484Sobrien  // Add in 2*BytesPerWord times page size to account for VM stack during
349360484Sobrien  // class initialization depending on 32 or 64 bit VM.
3494104834Sobrien  size_t min_stack_allowed =
349560484Sobrien            (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
349660484Sobrien            2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size();
349760484Sobrien  if (actual_reserve_size < min_stack_allowed) {
349860484Sobrien    tty->print_cr("\nThe stack size specified is too small, "
3499104834Sobrien                  "Specify at least %dk",
350060484Sobrien                  min_stack_allowed / K);
350160484Sobrien    return JNI_ERR;
350260484Sobrien  }
350360484Sobrien
350460484Sobrien  JavaThread::set_stack_size_at_create(stack_commit_size);
3505104834Sobrien
350660484Sobrien  // Calculate theoretical max. size of Threads to guard gainst artifical
350760484Sobrien  // out-of-memory situations, where all available address-space has been
350860484Sobrien  // reserved by thread stacks.
350960484Sobrien  assert(actual_reserve_size != 0, "Must have a stack");
351060484Sobrien
3511130561Sobrien  // Calculate the thread limit when we should start doing Virtual Memory
351260484Sobrien  // banging. Currently when the threads will have used all but 200Mb of space.
351360484Sobrien  //
351460484Sobrien  // TODO: consider performing a similar calculation for commit size instead
351560484Sobrien  // as reserve size, since on a 64-bit platform we'll run into that more
351660484Sobrien  // often than running out of virtual memory space.  We can use the
351760484Sobrien  // lower value of the two calculations as the os_thread_limit.
351860484Sobrien  size_t max_address_space = ((size_t)1 << (BitsPerWord - 1)) - (200 * K * K);
351960484Sobrien  win32::_os_thread_limit = (intx)(max_address_space / actual_reserve_size);
352060484Sobrien
352160484Sobrien  // at exit methods are called in the reverse order of their registration.
352260484Sobrien  // there is no limit to the number of functions registered. atexit does
352360484Sobrien  // not set errno.
352460484Sobrien
352560484Sobrien  if (PerfAllowAtExitRegistration) {
352660484Sobrien    // only register atexit functions if PerfAllowAtExitRegistration is set.
352760484Sobrien    // atexit functions can be delayed until process exit time, which
352860484Sobrien    // can be problematic for embedded VM situations. Embedded VMs should
352960484Sobrien    // call DestroyJavaVM() to assure that VM resources are released.
353060484Sobrien
353160484Sobrien    // note: perfMemory_exit_helper atexit function may be removed in
353260484Sobrien    // the future if the appropriate cleanup code can be added to the
353360484Sobrien    // VM_Exit VMOperation's doit method.
353460484Sobrien    if (atexit(perfMemory_exit_helper) != 0) {
353560484Sobrien      warning("os::init_2 atexit(perfMemory_exit_helper) failed");
353660484Sobrien    }
353760484Sobrien  }
353860484Sobrien
353960484Sobrien  // initialize PSAPI or ToolHelp for fatal error handler
354060484Sobrien  if (win32::is_nt()) _init_psapi();
354160484Sobrien  else _init_toolhelp();
354260484Sobrien
354360484Sobrien#ifndef _WIN64
354460484Sobrien  // Print something if NX is enabled (win32 on AMD64)
354560484Sobrien  NOT_PRODUCT(if (PrintMiscellaneous && Verbose) nx_check_protection());
354660484Sobrien#endif
354760484Sobrien
354860484Sobrien  // initialize thread priority policy
354960484Sobrien  prio_init();
355060484Sobrien
355160484Sobrien  if (UseNUMA && !ForceNUMA) {
355260484Sobrien    UseNUMA = false; // Currently unsupported.
355360484Sobrien  }
355460484Sobrien
355560484Sobrien  return JNI_OK;
355660484Sobrien}
355760484Sobrien
355860484Sobrienvoid os::init_3(void) {
355960484Sobrien  return;
356060484Sobrien}
356160484Sobrien
356260484Sobrien// Mark the polling page as unreadable
356360484Sobrienvoid os::make_polling_page_unreadable(void) {
356460484Sobrien  DWORD old_status;
356560484Sobrien  if( !VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_NOACCESS, &old_status) )
356660484Sobrien    fatal("Could not disable polling page");
356760484Sobrien};
356860484Sobrien
356960484Sobrien// Mark the polling page as readable
357060484Sobrienvoid os::make_polling_page_readable(void) {
357160484Sobrien  DWORD old_status;
357260484Sobrien  if( !VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_READONLY, &old_status) )
357360484Sobrien    fatal("Could not enable polling page");
357460484Sobrien};
357560484Sobrien
357660484Sobrien
357760484Sobrienint os::stat(const char *path, struct stat *sbuf) {
357860484Sobrien  char pathbuf[MAX_PATH];
357960484Sobrien  if (strlen(path) > MAX_PATH - 1) {
358060484Sobrien    errno = ENAMETOOLONG;
358160484Sobrien    return -1;
358260484Sobrien  }
358360484Sobrien  os::native_path(strcpy(pathbuf, path));
358460484Sobrien  int ret = ::stat(pathbuf, sbuf);
358560484Sobrien  if (sbuf != NULL && UseUTCFileTimestamp) {
358660484Sobrien    // Fix for 6539723.  st_mtime returned from stat() is dependent on
358760484Sobrien    // the system timezone and so can return different values for the
358860484Sobrien    // same file if/when daylight savings time changes.  This adjustment
358960484Sobrien    // makes sure the same timestamp is returned regardless of the TZ.
359060484Sobrien    //
359160484Sobrien    // See:
359260484Sobrien    // http://msdn.microsoft.com/library/
359360484Sobrien    //   default.asp?url=/library/en-us/sysinfo/base/
359460484Sobrien    //   time_zone_information_str.asp
359560484Sobrien    // and
359660484Sobrien    // http://msdn.microsoft.com/library/default.asp?url=
359760484Sobrien    //   /library/en-us/sysinfo/base/settimezoneinformation.asp
359860484Sobrien    //
3599130561Sobrien    // NOTE: there is a insidious bug here:  If the timezone is changed
360060484Sobrien    // after the call to stat() but before 'GetTimeZoneInformation()', then
360160484Sobrien    // the adjustment we do here will be wrong and we'll return the wrong
3602130561Sobrien    // value (which will likely end up creating an invalid class data
3603104834Sobrien    // archive).  Absent a better API for this, or some time zone locking
360460484Sobrien    // mechanism, we'll have to live with this risk.
360560484Sobrien    TIME_ZONE_INFORMATION tz;
3606130561Sobrien    DWORD tzid = GetTimeZoneInformation(&tz);
3607130561Sobrien    int daylightBias =
360860484Sobrien      (tzid == TIME_ZONE_ID_DAYLIGHT) ?  tz.DaylightBias : tz.StandardBias;
360960484Sobrien    sbuf->st_mtime += (tz.Bias + daylightBias) * 60;
361060484Sobrien  }
361160484Sobrien  return ret;
3612130561Sobrien}
3613130561Sobrien
361460484Sobrien
361560484Sobrien#define FT2INT64(ft) \
361660484Sobrien  ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))
3617104834Sobrien
361860484Sobrien
361960484Sobrien// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
362060484Sobrien// are used by JVM M&M and JVMTI to get user+sys or user CPU time
362160484Sobrien// of a thread.
3622104834Sobrien//
3623130561Sobrien// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
362460484Sobrien// the fast estimate available on the platform.
362560484Sobrien
3626130561Sobrien// current_thread_cpu_time() is not optimized for Windows yet
3627130561Sobrienjlong os::current_thread_cpu_time() {
3628104834Sobrien  // return user + sys since the cost is the same
3629130561Sobrien  return os::thread_cpu_time(Thread::current(), true /* user+sys */);
3630130561Sobrien}
3631130561Sobrien
3632130561Sobrienjlong os::thread_cpu_time(Thread* thread) {
3633130561Sobrien  // consistent with what current_thread_cpu_time() returns.
3634130561Sobrien  return os::thread_cpu_time(thread, true /* user+sys */);
363560484Sobrien}
363660484Sobrien
3637130561Sobrienjlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
3638104834Sobrien  return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
363960484Sobrien}
364060484Sobrien
3641130561Sobrienjlong os::thread_cpu_time(Thread* thread, bool user_sys_cpu_time) {
3642104834Sobrien  // This code is copy from clasic VM -> hpi::sysThreadCPUTime
364360484Sobrien  // If this function changes, os::is_thread_cpu_time_supported() should too
3644130561Sobrien  if (os::win32::is_nt()) {
364560484Sobrien    FILETIME CreationTime;
364660484Sobrien    FILETIME ExitTime;
364760484Sobrien    FILETIME KernelTime;
364860484Sobrien    FILETIME UserTime;
364960484Sobrien
365060484Sobrien    if ( GetThreadTimes(thread->osthread()->thread_handle(),
365160484Sobrien                    &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0)
365260484Sobrien      return -1;
365360484Sobrien    else
365460484Sobrien      if (user_sys_cpu_time) {
3655130561Sobrien        return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100;
365660484Sobrien      } else {
365760484Sobrien        return FT2INT64(UserTime) * 100;
3658130561Sobrien      }
365960484Sobrien  } else {
3660130561Sobrien    return (jlong) timeGetTime() * 1000000;
3661130561Sobrien  }
3662130561Sobrien}
3663130561Sobrien
3664130561Sobrienvoid os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
3665130561Sobrien  info_ptr->max_value = ALL_64_BITS;        // the max value -- all 64 bits
366660484Sobrien  info_ptr->may_skip_backward = false;      // GetThreadTimes returns absolute time
366760484Sobrien  info_ptr->may_skip_forward = false;       // GetThreadTimes returns absolute time
366860484Sobrien  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;   // user+system time is returned
366960484Sobrien}
367060484Sobrien
367160484Sobrienvoid os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
367260484Sobrien  info_ptr->max_value = ALL_64_BITS;        // the max value -- all 64 bits
367360484Sobrien  info_ptr->may_skip_backward = false;      // GetThreadTimes returns absolute time
367460484Sobrien  info_ptr->may_skip_forward = false;       // GetThreadTimes returns absolute time
367560484Sobrien  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;   // user+system time is returned
367660484Sobrien}
367760484Sobrien
3678bool os::is_thread_cpu_time_supported() {
3679  // see os::thread_cpu_time
3680  if (os::win32::is_nt()) {
3681    FILETIME CreationTime;
3682    FILETIME ExitTime;
3683    FILETIME KernelTime;
3684    FILETIME UserTime;
3685
3686    if ( GetThreadTimes(GetCurrentThread(),
3687                    &CreationTime, &ExitTime, &KernelTime, &UserTime) == 0)
3688      return false;
3689    else
3690      return true;
3691  } else {
3692    return false;
3693  }
3694}
3695
3696// Windows does't provide a loadavg primitive so this is stubbed out for now.
3697// It does have primitives (PDH API) to get CPU usage and run queue length.
3698// "\\Processor(_Total)\\% Processor Time", "\\System\\Processor Queue Length"
3699// If we wanted to implement loadavg on Windows, we have a few options:
3700//
3701// a) Query CPU usage and run queue length and "fake" an answer by
3702//    returning the CPU usage if it's under 100%, and the run queue
3703//    length otherwise.  It turns out that querying is pretty slow
3704//    on Windows, on the order of 200 microseconds on a fast machine.
3705//    Note that on the Windows the CPU usage value is the % usage
3706//    since the last time the API was called (and the first call
3707//    returns 100%), so we'd have to deal with that as well.
3708//
3709// b) Sample the "fake" answer using a sampling thread and store
3710//    the answer in a global variable.  The call to loadavg would
3711//    just return the value of the global, avoiding the slow query.
3712//
3713// c) Sample a better answer using exponential decay to smooth the
3714//    value.  This is basically the algorithm used by UNIX kernels.
3715//
3716// Note that sampling thread starvation could affect both (b) and (c).
3717int os::loadavg(double loadavg[], int nelem) {
3718  return -1;
3719}
3720
3721
3722// DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield()
3723bool os::dont_yield() {
3724  return DontYieldALot;
3725}
3726
3727// This method is a slightly reworked copy of JDK's sysOpen
3728// from src/windows/hpi/src/sys_api_md.c
3729
3730int os::open(const char *path, int oflag, int mode) {
3731  char pathbuf[MAX_PATH];
3732
3733  if (strlen(path) > MAX_PATH - 1) {
3734    errno = ENAMETOOLONG;
3735          return -1;
3736  }
3737  os::native_path(strcpy(pathbuf, path));
3738  return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);
3739}
3740
3741// Is a (classpath) directory empty?
3742bool os::dir_is_empty(const char* path) {
3743  WIN32_FIND_DATA fd;
3744  HANDLE f = FindFirstFile(path, &fd);
3745  if (f == INVALID_HANDLE_VALUE) {
3746    return true;
3747  }
3748  FindClose(f);
3749  return false;
3750}
3751
3752// create binary file, rewriting existing file if required
3753int os::create_binary_file(const char* path, bool rewrite_existing) {
3754  int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;
3755  if (!rewrite_existing) {
3756    oflags |= _O_EXCL;
3757  }
3758  return ::open(path, oflags, _S_IREAD | _S_IWRITE);
3759}
3760
3761// return current position of file pointer
3762jlong os::current_file_offset(int fd) {
3763  return (jlong)::_lseeki64(fd, (__int64)0L, SEEK_CUR);
3764}
3765
3766// move file pointer to the specified offset
3767jlong os::seek_to_file_offset(int fd, jlong offset) {
3768  return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET);
3769}
3770
3771
3772jlong os::lseek(int fd, jlong offset, int whence) {
3773  return (jlong) ::_lseeki64(fd, offset, whence);
3774}
3775
3776// This method is a slightly reworked copy of JDK's sysNativePath
3777// from src/windows/hpi/src/path_md.c
3778
3779/* Convert a pathname to native format.  On win32, this involves forcing all
3780   separators to be '\\' rather than '/' (both are legal inputs, but Win95
3781   sometimes rejects '/') and removing redundant separators.  The input path is
3782   assumed to have been converted into the character encoding used by the local
3783   system.  Because this might be a double-byte encoding, care is taken to
3784   treat double-byte lead characters correctly.
3785
3786   This procedure modifies the given path in place, as the result is never
3787   longer than the original.  There is no error return; this operation always
3788   succeeds. */
3789char * os::native_path(char *path) {
3790  char *src = path, *dst = path, *end = path;
3791  char *colon = NULL;           /* If a drive specifier is found, this will
3792                                        point to the colon following the drive
3793                                        letter */
3794
3795  /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */
3796  assert(((!::IsDBCSLeadByte('/'))
3797    && (!::IsDBCSLeadByte('\\'))
3798    && (!::IsDBCSLeadByte(':'))),
3799    "Illegal lead byte");
3800
3801  /* Check for leading separators */
3802#define isfilesep(c) ((c) == '/' || (c) == '\\')
3803  while (isfilesep(*src)) {
3804    src++;
3805  }
3806
3807  if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') {
3808    /* Remove leading separators if followed by drive specifier.  This
3809      hack is necessary to support file URLs containing drive
3810      specifiers (e.g., "file://c:/path").  As a side effect,
3811      "/c:/path" can be used as an alternative to "c:/path". */
3812    *dst++ = *src++;
3813    colon = dst;
3814    *dst++ = ':';
3815    src++;
3816  } else {
3817    src = path;
3818    if (isfilesep(src[0]) && isfilesep(src[1])) {
3819      /* UNC pathname: Retain first separator; leave src pointed at
3820         second separator so that further separators will be collapsed
3821         into the second separator.  The result will be a pathname
3822         beginning with "\\\\" followed (most likely) by a host name. */
3823      src = dst = path + 1;
3824      path[0] = '\\';     /* Force first separator to '\\' */
3825    }
3826  }
3827
3828  end = dst;
3829
3830  /* Remove redundant separators from remainder of path, forcing all
3831      separators to be '\\' rather than '/'. Also, single byte space
3832      characters are removed from the end of the path because those
3833      are not legal ending characters on this operating system.
3834  */
3835  while (*src != '\0') {
3836    if (isfilesep(*src)) {
3837      *dst++ = '\\'; src++;
3838      while (isfilesep(*src)) src++;
3839      if (*src == '\0') {
3840        /* Check for trailing separator */
3841        end = dst;
3842        if (colon == dst - 2) break;                      /* "z:\\" */
3843        if (dst == path + 1) break;                       /* "\\" */
3844        if (dst == path + 2 && isfilesep(path[0])) {
3845          /* "\\\\" is not collapsed to "\\" because "\\\\" marks the
3846            beginning of a UNC pathname.  Even though it is not, by
3847            itself, a valid UNC pathname, we leave it as is in order
3848            to be consistent with the path canonicalizer as well
3849            as the win32 APIs, which treat this case as an invalid
3850            UNC pathname rather than as an alias for the root
3851            directory of the current drive. */
3852          break;
3853        }
3854        end = --dst;  /* Path does not denote a root directory, so
3855                                    remove trailing separator */
3856        break;
3857      }
3858      end = dst;
3859    } else {
3860      if (::IsDBCSLeadByte(*src)) { /* Copy a double-byte character */
3861        *dst++ = *src++;
3862        if (*src) *dst++ = *src++;
3863        end = dst;
3864      } else {         /* Copy a single-byte character */
3865        char c = *src++;
3866        *dst++ = c;
3867        /* Space is not a legal ending character */
3868        if (c != ' ') end = dst;
3869      }
3870    }
3871  }
3872
3873  *end = '\0';
3874
3875  /* For "z:", add "." to work around a bug in the C runtime library */
3876  if (colon == dst - 1) {
3877          path[2] = '.';
3878          path[3] = '\0';
3879  }
3880
3881  #ifdef DEBUG
3882    jio_fprintf(stderr, "sysNativePath: %s\n", path);
3883  #endif DEBUG
3884  return path;
3885}
3886
3887// This code is a copy of JDK's sysSetLength
3888// from src/windows/hpi/src/sys_api_md.c
3889
3890int os::ftruncate(int fd, jlong length) {
3891  HANDLE h = (HANDLE)::_get_osfhandle(fd);
3892  long high = (long)(length >> 32);
3893  DWORD ret;
3894
3895  if (h == (HANDLE)(-1)) {
3896    return -1;
3897  }
3898
3899  ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN);
3900  if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) {
3901      return -1;
3902  }
3903
3904  if (::SetEndOfFile(h) == FALSE) {
3905    return -1;
3906  }
3907
3908  return 0;
3909}
3910
3911
3912// This code is a copy of JDK's sysSync
3913// from src/windows/hpi/src/sys_api_md.c
3914// except for the legacy workaround for a bug in Win 98
3915
3916int os::fsync(int fd) {
3917  HANDLE handle = (HANDLE)::_get_osfhandle(fd);
3918
3919  if ( (!::FlushFileBuffers(handle)) &&
3920         (GetLastError() != ERROR_ACCESS_DENIED) ) {
3921    /* from winerror.h */
3922    return -1;
3923  }
3924  return 0;
3925}
3926
3927static int nonSeekAvailable(int, long *);
3928static int stdinAvailable(int, long *);
3929
3930#define S_ISCHR(mode)   (((mode) & _S_IFCHR) == _S_IFCHR)
3931#define S_ISFIFO(mode)  (((mode) & _S_IFIFO) == _S_IFIFO)
3932
3933// This code is a copy of JDK's sysAvailable
3934// from src/windows/hpi/src/sys_api_md.c
3935
3936int os::available(int fd, jlong *bytes) {
3937  jlong cur, end;
3938  struct _stati64 stbuf64;
3939
3940  if (::_fstati64(fd, &stbuf64) >= 0) {
3941    int mode = stbuf64.st_mode;
3942    if (S_ISCHR(mode) || S_ISFIFO(mode)) {
3943      int ret;
3944      long lpbytes;
3945      if (fd == 0) {
3946        ret = stdinAvailable(fd, &lpbytes);
3947      } else {
3948        ret = nonSeekAvailable(fd, &lpbytes);
3949      }
3950      (*bytes) = (jlong)(lpbytes);
3951      return ret;
3952    }
3953    if ((cur = ::_lseeki64(fd, 0L, SEEK_CUR)) == -1) {
3954      return FALSE;
3955    } else if ((end = ::_lseeki64(fd, 0L, SEEK_END)) == -1) {
3956      return FALSE;
3957    } else if (::_lseeki64(fd, cur, SEEK_SET) == -1) {
3958      return FALSE;
3959    }
3960    *bytes = end - cur;
3961    return TRUE;
3962  } else {
3963    return FALSE;
3964  }
3965}
3966
3967// This code is a copy of JDK's nonSeekAvailable
3968// from src/windows/hpi/src/sys_api_md.c
3969
3970static int nonSeekAvailable(int fd, long *pbytes) {
3971  /* This is used for available on non-seekable devices
3972    * (like both named and anonymous pipes, such as pipes
3973    *  connected to an exec'd process).
3974    * Standard Input is a special case.
3975    *
3976    */
3977  HANDLE han;
3978
3979  if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) {
3980    return FALSE;
3981  }
3982
3983  if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) {
3984        /* PeekNamedPipe fails when at EOF.  In that case we
3985         * simply make *pbytes = 0 which is consistent with the
3986         * behavior we get on Solaris when an fd is at EOF.
3987         * The only alternative is to raise an Exception,
3988         * which isn't really warranted.
3989         */
3990    if (::GetLastError() != ERROR_BROKEN_PIPE) {
3991      return FALSE;
3992    }
3993    *pbytes = 0;
3994  }
3995  return TRUE;
3996}
3997
3998#define MAX_INPUT_EVENTS 2000
3999
4000// This code is a copy of JDK's stdinAvailable
4001// from src/windows/hpi/src/sys_api_md.c
4002
4003static int stdinAvailable(int fd, long *pbytes) {
4004  HANDLE han;
4005  DWORD numEventsRead = 0;      /* Number of events read from buffer */
4006  DWORD numEvents = 0;  /* Number of events in buffer */
4007  DWORD i = 0;          /* Loop index */
4008  DWORD curLength = 0;  /* Position marker */
4009  DWORD actualLength = 0;       /* Number of bytes readable */
4010  BOOL error = FALSE;         /* Error holder */
4011  INPUT_RECORD *lpBuffer;     /* Pointer to records of input events */
4012
4013  if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
4014        return FALSE;
4015  }
4016
4017  /* Construct an array of input records in the console buffer */
4018  error = ::GetNumberOfConsoleInputEvents(han, &numEvents);
4019  if (error == 0) {
4020    return nonSeekAvailable(fd, pbytes);
4021  }
4022
4023  /* lpBuffer must fit into 64K or else PeekConsoleInput fails */
4024  if (numEvents > MAX_INPUT_EVENTS) {
4025    numEvents = MAX_INPUT_EVENTS;
4026  }
4027
4028  lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD));
4029  if (lpBuffer == NULL) {
4030    return FALSE;
4031  }
4032
4033  error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);
4034  if (error == 0) {
4035    os::free(lpBuffer);
4036    return FALSE;
4037  }
4038
4039  /* Examine input records for the number of bytes available */
4040  for(i=0; i<numEvents; i++) {
4041    if (lpBuffer[i].EventType == KEY_EVENT) {
4042
4043      KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *)
4044                                      &(lpBuffer[i].Event);
4045      if (keyRecord->bKeyDown == TRUE) {
4046        CHAR *keyPressed = (CHAR *) &(keyRecord->uChar);
4047        curLength++;
4048        if (*keyPressed == '\r') {
4049          actualLength = curLength;
4050        }
4051      }
4052    }
4053  }
4054
4055  if(lpBuffer != NULL) {
4056    os::free(lpBuffer);
4057  }
4058
4059  *pbytes = (long) actualLength;
4060  return TRUE;
4061}
4062
4063// Map a block of memory.
4064char* os::map_memory(int fd, const char* file_name, size_t file_offset,
4065                     char *addr, size_t bytes, bool read_only,
4066                     bool allow_exec) {
4067  HANDLE hFile;
4068  char* base;
4069
4070  hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
4071                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
4072  if (hFile == NULL) {
4073    if (PrintMiscellaneous && Verbose) {
4074      DWORD err = GetLastError();
4075      tty->print_cr("CreateFile() failed: GetLastError->%ld.");
4076    }
4077    return NULL;
4078  }
4079
4080  if (allow_exec) {
4081    // CreateFileMapping/MapViewOfFileEx can't map executable memory
4082    // unless it comes from a PE image (which the shared archive is not.)
4083    // Even VirtualProtect refuses to give execute access to mapped memory
4084    // that was not previously executable.
4085    //
4086    // Instead, stick the executable region in anonymous memory.  Yuck.
4087    // Penalty is that ~4 pages will not be shareable - in the future
4088    // we might consider DLLizing the shared archive with a proper PE
4089    // header so that mapping executable + sharing is possible.
4090
4091    base = (char*) VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE,
4092                                PAGE_READWRITE);
4093    if (base == NULL) {
4094      if (PrintMiscellaneous && Verbose) {
4095        DWORD err = GetLastError();
4096        tty->print_cr("VirtualAlloc() failed: GetLastError->%ld.", err);
4097      }
4098      CloseHandle(hFile);
4099      return NULL;
4100    }
4101
4102    DWORD bytes_read;
4103    OVERLAPPED overlapped;
4104    overlapped.Offset = (DWORD)file_offset;
4105    overlapped.OffsetHigh = 0;
4106    overlapped.hEvent = NULL;
4107    // ReadFile guarantees that if the return value is true, the requested
4108    // number of bytes were read before returning.
4109    bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0;
4110    if (!res) {
4111      if (PrintMiscellaneous && Verbose) {
4112        DWORD err = GetLastError();
4113        tty->print_cr("ReadFile() failed: GetLastError->%ld.", err);
4114      }
4115      release_memory(base, bytes);
4116      CloseHandle(hFile);
4117      return NULL;
4118    }
4119  } else {
4120    HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0,
4121                                    NULL /*file_name*/);
4122    if (hMap == NULL) {
4123      if (PrintMiscellaneous && Verbose) {
4124        DWORD err = GetLastError();
4125        tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.");
4126      }
4127      CloseHandle(hFile);
4128      return NULL;
4129    }
4130
4131    DWORD access = read_only ? FILE_MAP_READ : FILE_MAP_COPY;
4132    base = (char*)MapViewOfFileEx(hMap, access, 0, (DWORD)file_offset,
4133                                  (DWORD)bytes, addr);
4134    if (base == NULL) {
4135      if (PrintMiscellaneous && Verbose) {
4136        DWORD err = GetLastError();
4137        tty->print_cr("MapViewOfFileEx() failed: GetLastError->%ld.", err);
4138      }
4139      CloseHandle(hMap);
4140      CloseHandle(hFile);
4141      return NULL;
4142    }
4143
4144    if (CloseHandle(hMap) == 0) {
4145      if (PrintMiscellaneous && Verbose) {
4146        DWORD err = GetLastError();
4147        tty->print_cr("CloseHandle(hMap) failed: GetLastError->%ld.", err);
4148      }
4149      CloseHandle(hFile);
4150      return base;
4151    }
4152  }
4153
4154  if (allow_exec) {
4155    DWORD old_protect;
4156    DWORD exec_access = read_only ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE;
4157    bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0;
4158
4159    if (!res) {
4160      if (PrintMiscellaneous && Verbose) {
4161        DWORD err = GetLastError();
4162        tty->print_cr("VirtualProtect() failed: GetLastError->%ld.", err);
4163      }
4164      // Don't consider this a hard error, on IA32 even if the
4165      // VirtualProtect fails, we should still be able to execute
4166      CloseHandle(hFile);
4167      return base;
4168    }
4169  }
4170
4171  if (CloseHandle(hFile) == 0) {
4172    if (PrintMiscellaneous && Verbose) {
4173      DWORD err = GetLastError();
4174      tty->print_cr("CloseHandle(hFile) failed: GetLastError->%ld.", err);
4175    }
4176    return base;
4177  }
4178
4179  return base;
4180}
4181
4182
4183// Remap a block of memory.
4184char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
4185                       char *addr, size_t bytes, bool read_only,
4186                       bool allow_exec) {
4187  // This OS does not allow existing memory maps to be remapped so we
4188  // have to unmap the memory before we remap it.
4189  if (!os::unmap_memory(addr, bytes)) {
4190    return NULL;
4191  }
4192
4193  // There is a very small theoretical window between the unmap_memory()
4194  // call above and the map_memory() call below where a thread in native
4195  // code may be able to access an address that is no longer mapped.
4196
4197  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
4198                        allow_exec);
4199}
4200
4201
4202// Unmap a block of memory.
4203// Returns true=success, otherwise false.
4204
4205bool os::unmap_memory(char* addr, size_t bytes) {
4206  BOOL result = UnmapViewOfFile(addr);
4207  if (result == 0) {
4208    if (PrintMiscellaneous && Verbose) {
4209      DWORD err = GetLastError();
4210      tty->print_cr("UnmapViewOfFile() failed: GetLastError->%ld.", err);
4211    }
4212    return false;
4213  }
4214  return true;
4215}
4216
4217void os::pause() {
4218  char filename[MAX_PATH];
4219  if (PauseAtStartupFile && PauseAtStartupFile[0]) {
4220    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
4221  } else {
4222    jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
4223  }
4224
4225  int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4226  if (fd != -1) {
4227    struct stat buf;
4228    ::close(fd);
4229    while (::stat(filename, &buf) == 0) {
4230      Sleep(100);
4231    }
4232  } else {
4233    jio_fprintf(stderr,
4234      "Could not open pause file '%s', continuing immediately.\n", filename);
4235  }
4236}
4237
4238// An Event wraps a win32 "CreateEvent" kernel handle.
4239//
4240// We have a number of choices regarding "CreateEvent" win32 handle leakage:
4241//
4242// 1:  When a thread dies return the Event to the EventFreeList, clear the ParkHandle
4243//     field, and call CloseHandle() on the win32 event handle.  Unpark() would
4244//     need to be modified to tolerate finding a NULL (invalid) win32 event handle.
4245//     In addition, an unpark() operation might fetch the handle field, but the
4246//     event could recycle between the fetch and the SetEvent() operation.
4247//     SetEvent() would either fail because the handle was invalid, or inadvertently work,
4248//     as the win32 handle value had been recycled.  In an ideal world calling SetEvent()
4249//     on an stale but recycled handle would be harmless, but in practice this might
4250//     confuse other non-Sun code, so it's not a viable approach.
4251//
4252// 2:  Once a win32 event handle is associated with an Event, it remains associated
4253//     with the Event.  The event handle is never closed.  This could be construed
4254//     as handle leakage, but only up to the maximum # of threads that have been extant
4255//     at any one time.  This shouldn't be an issue, as windows platforms typically
4256//     permit a process to have hundreds of thousands of open handles.
4257//
4258// 3:  Same as (1), but periodically, at stop-the-world time, rundown the EventFreeList
4259//     and release unused handles.
4260//
4261// 4:  Add a CRITICAL_SECTION to the Event to protect LD+SetEvent from LD;ST(null);CloseHandle.
4262//     It's not clear, however, that we wouldn't be trading one type of leak for another.
4263//
4264// 5.  Use an RCU-like mechanism (Read-Copy Update).
4265//     Or perhaps something similar to Maged Michael's "Hazard pointers".
4266//
4267// We use (2).
4268//
4269// TODO-FIXME:
4270// 1.  Reconcile Doug's JSR166 j.u.c park-unpark with the objectmonitor implementation.
4271// 2.  Consider wrapping the WaitForSingleObject(Ex) calls in SEH try/finally blocks
4272//     to recover from (or at least detect) the dreaded Windows 841176 bug.
4273// 3.  Collapse the interrupt_event, the JSR166 parker event, and the objectmonitor ParkEvent
4274//     into a single win32 CreateEvent() handle.
4275//
4276// _Event transitions in park()
4277//   -1 => -1 : illegal
4278//    1 =>  0 : pass - return immediately
4279//    0 => -1 : block
4280//
4281// _Event serves as a restricted-range semaphore :
4282//    -1 : thread is blocked
4283//     0 : neutral  - thread is running or ready
4284//     1 : signaled - thread is running or ready
4285//
4286// Another possible encoding of _Event would be
4287// with explicit "PARKED" and "SIGNALED" bits.
4288
4289int os::PlatformEvent::park (jlong Millis) {
4290    guarantee (_ParkHandle != NULL , "Invariant") ;
4291    guarantee (Millis > 0          , "Invariant") ;
4292    int v ;
4293
4294    // CONSIDER: defer assigning a CreateEvent() handle to the Event until
4295    // the initial park() operation.
4296
4297    for (;;) {
4298        v = _Event ;
4299        if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
4300    }
4301    guarantee ((v == 0) || (v == 1), "invariant") ;
4302    if (v != 0) return OS_OK ;
4303
4304    // Do this the hard way by blocking ...
4305    // TODO: consider a brief spin here, gated on the success of recent
4306    // spin attempts by this thread.
4307    //
4308    // We decompose long timeouts into series of shorter timed waits.
4309    // Evidently large timo values passed in WaitForSingleObject() are problematic on some
4310    // versions of Windows.  See EventWait() for details.  This may be superstition.  Or not.
4311    // We trust the WAIT_TIMEOUT indication and don't track the elapsed wait time
4312    // with os::javaTimeNanos().  Furthermore, we assume that spurious returns from
4313    // ::WaitForSingleObject() caused by latent ::setEvent() operations will tend
4314    // to happen early in the wait interval.  Specifically, after a spurious wakeup (rv ==
4315    // WAIT_OBJECT_0 but _Event is still < 0) we don't bother to recompute Millis to compensate
4316    // for the already waited time.  This policy does not admit any new outcomes.
4317    // In the future, however, we might want to track the accumulated wait time and
4318    // adjust Millis accordingly if we encounter a spurious wakeup.
4319
4320    const int MAXTIMEOUT = 0x10000000 ;
4321    DWORD rv = WAIT_TIMEOUT ;
4322    while (_Event < 0 && Millis > 0) {
4323       DWORD prd = Millis ;     // set prd = MAX (Millis, MAXTIMEOUT)
4324       if (Millis > MAXTIMEOUT) {
4325          prd = MAXTIMEOUT ;
4326       }
4327       rv = ::WaitForSingleObject (_ParkHandle, prd) ;
4328       assert (rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT, "WaitForSingleObject failed") ;
4329       if (rv == WAIT_TIMEOUT) {
4330           Millis -= prd ;
4331       }
4332    }
4333    v = _Event ;
4334    _Event = 0 ;
4335    OrderAccess::fence() ;
4336    // If we encounter a nearly simultanous timeout expiry and unpark()
4337    // we return OS_OK indicating we awoke via unpark().
4338    // Implementor's license -- returning OS_TIMEOUT would be equally valid, however.
4339    return (v >= 0) ? OS_OK : OS_TIMEOUT ;
4340}
4341
4342void os::PlatformEvent::park () {
4343    guarantee (_ParkHandle != NULL, "Invariant") ;
4344    // Invariant: Only the thread associated with the Event/PlatformEvent
4345    // may call park().
4346    int v ;
4347    for (;;) {
4348        v = _Event ;
4349        if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
4350    }
4351    guarantee ((v == 0) || (v == 1), "invariant") ;
4352    if (v != 0) return ;
4353
4354    // Do this the hard way by blocking ...
4355    // TODO: consider a brief spin here, gated on the success of recent
4356    // spin attempts by this thread.
4357    while (_Event < 0) {
4358       DWORD rv = ::WaitForSingleObject (_ParkHandle, INFINITE) ;
4359       assert (rv == WAIT_OBJECT_0, "WaitForSingleObject failed") ;
4360    }
4361
4362    // Usually we'll find _Event == 0 at this point, but as
4363    // an optional optimization we clear it, just in case can
4364    // multiple unpark() operations drove _Event up to 1.
4365    _Event = 0 ;
4366    OrderAccess::fence() ;
4367    guarantee (_Event >= 0, "invariant") ;
4368}
4369
4370void os::PlatformEvent::unpark() {
4371  guarantee (_ParkHandle != NULL, "Invariant") ;
4372  int v ;
4373  for (;;) {
4374      v = _Event ;      // Increment _Event if it's < 1.
4375      if (v > 0) {
4376         // If it's already signaled just return.
4377         // The LD of _Event could have reordered or be satisfied
4378         // by a read-aside from this processor's write buffer.
4379         // To avoid problems execute a barrier and then
4380         // ratify the value.  A degenerate CAS() would also work.
4381         // Viz., CAS (v+0, &_Event, v) == v).
4382         OrderAccess::fence() ;
4383         if (_Event == v) return ;
4384         continue ;
4385      }
4386      if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
4387  }
4388  if (v < 0) {
4389     ::SetEvent (_ParkHandle) ;
4390  }
4391}
4392
4393
4394// JSR166
4395// -------------------------------------------------------
4396
4397/*
4398 * The Windows implementation of Park is very straightforward: Basic
4399 * operations on Win32 Events turn out to have the right semantics to
4400 * use them directly. We opportunistically resuse the event inherited
4401 * from Monitor.
4402 */
4403
4404
4405void Parker::park(bool isAbsolute, jlong time) {
4406  guarantee (_ParkEvent != NULL, "invariant") ;
4407  // First, demultiplex/decode time arguments
4408  if (time < 0) { // don't wait
4409    return;
4410  }
4411  else if (time == 0 && !isAbsolute) {
4412    time = INFINITE;
4413  }
4414  else if  (isAbsolute) {
4415    time -= os::javaTimeMillis(); // convert to relative time
4416    if (time <= 0) // already elapsed
4417      return;
4418  }
4419  else { // relative
4420    time /= 1000000; // Must coarsen from nanos to millis
4421    if (time == 0)   // Wait for the minimal time unit if zero
4422      time = 1;
4423  }
4424
4425  JavaThread* thread = (JavaThread*)(Thread::current());
4426  assert(thread->is_Java_thread(), "Must be JavaThread");
4427  JavaThread *jt = (JavaThread *)thread;
4428
4429  // Don't wait if interrupted or already triggered
4430  if (Thread::is_interrupted(thread, false) ||
4431    WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) {
4432    ResetEvent(_ParkEvent);
4433    return;
4434  }
4435  else {
4436    ThreadBlockInVM tbivm(jt);
4437    OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
4438    jt->set_suspend_equivalent();
4439
4440    WaitForSingleObject(_ParkEvent,  time);
4441    ResetEvent(_ParkEvent);
4442
4443    // If externally suspended while waiting, re-suspend
4444    if (jt->handle_special_suspend_equivalent_condition()) {
4445      jt->java_suspend_self();
4446    }
4447  }
4448}
4449
4450void Parker::unpark() {
4451  guarantee (_ParkEvent != NULL, "invariant") ;
4452  SetEvent(_ParkEvent);
4453}
4454
4455// Run the specified command in a separate process. Return its exit value,
4456// or -1 on failure (e.g. can't create a new process).
4457int os::fork_and_exec(char* cmd) {
4458  STARTUPINFO si;
4459  PROCESS_INFORMATION pi;
4460
4461  memset(&si, 0, sizeof(si));
4462  si.cb = sizeof(si);
4463  memset(&pi, 0, sizeof(pi));
4464  BOOL rslt = CreateProcess(NULL,   // executable name - use command line
4465                            cmd,    // command line
4466                            NULL,   // process security attribute
4467                            NULL,   // thread security attribute
4468                            TRUE,   // inherits system handles
4469                            0,      // no creation flags
4470                            NULL,   // use parent's environment block
4471                            NULL,   // use parent's starting directory
4472                            &si,    // (in) startup information
4473                            &pi);   // (out) process information
4474
4475  if (rslt) {
4476    // Wait until child process exits.
4477    WaitForSingleObject(pi.hProcess, INFINITE);
4478
4479    DWORD exit_code;
4480    GetExitCodeProcess(pi.hProcess, &exit_code);
4481
4482    // Close process and thread handles.
4483    CloseHandle(pi.hProcess);
4484    CloseHandle(pi.hThread);
4485
4486    return (int)exit_code;
4487  } else {
4488    return -1;
4489  }
4490}
4491
4492//--------------------------------------------------------------------------------------------------
4493// Non-product code
4494
4495static int mallocDebugIntervalCounter = 0;
4496static int mallocDebugCounter = 0;
4497bool os::check_heap(bool force) {
4498  if (++mallocDebugCounter < MallocVerifyStart && !force) return true;
4499  if (++mallocDebugIntervalCounter >= MallocVerifyInterval || force) {
4500    // Note: HeapValidate executes two hardware breakpoints when it finds something
4501    // wrong; at these points, eax contains the address of the offending block (I think).
4502    // To get to the exlicit error message(s) below, just continue twice.
4503    HANDLE heap = GetProcessHeap();
4504    { HeapLock(heap);
4505      PROCESS_HEAP_ENTRY phe;
4506      phe.lpData = NULL;
4507      while (HeapWalk(heap, &phe) != 0) {
4508        if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) &&
4509            !HeapValidate(heap, 0, phe.lpData)) {
4510          tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter);
4511          tty->print_cr("corrupted block near address %#x, length %d", phe.lpData, phe.cbData);
4512          fatal("corrupted C heap");
4513        }
4514      }
4515      int err = GetLastError();
4516      if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) {
4517        fatal(err_msg("heap walk aborted with error %d", err));
4518      }
4519      HeapUnlock(heap);
4520    }
4521    mallocDebugIntervalCounter = 0;
4522  }
4523  return true;
4524}
4525
4526
4527bool os::find(address addr, outputStream* st) {
4528  // Nothing yet
4529  return false;
4530}
4531
4532LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
4533  DWORD exception_code = e->ExceptionRecord->ExceptionCode;
4534
4535  if ( exception_code == EXCEPTION_ACCESS_VIOLATION ) {
4536    JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
4537    PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;
4538    address addr = (address) exceptionRecord->ExceptionInformation[1];
4539
4540    if (os::is_memory_serialize_page(thread, addr))
4541      return EXCEPTION_CONTINUE_EXECUTION;
4542  }
4543
4544  return EXCEPTION_CONTINUE_SEARCH;
4545}
4546
4547static int getLastErrorString(char *buf, size_t len)
4548{
4549    long errval;
4550
4551    if ((errval = GetLastError()) != 0)
4552    {
4553      /* DOS error */
4554      size_t n = (size_t)FormatMessage(
4555            FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
4556            NULL,
4557            errval,
4558            0,
4559            buf,
4560            (DWORD)len,
4561            NULL);
4562      if (n > 3) {
4563        /* Drop final '.', CR, LF */
4564        if (buf[n - 1] == '\n') n--;
4565        if (buf[n - 1] == '\r') n--;
4566        if (buf[n - 1] == '.') n--;
4567        buf[n] = '\0';
4568      }
4569      return (int)n;
4570    }
4571
4572    if (errno != 0)
4573    {
4574      /* C runtime error that has no corresponding DOS error code */
4575      const char *s = strerror(errno);
4576      size_t n = strlen(s);
4577      if (n >= len) n = len - 1;
4578      strncpy(buf, s, n);
4579      buf[n] = '\0';
4580      return (int)n;
4581    }
4582    return 0;
4583}
4584
4585
4586// We don't build a headless jre for Windows
4587bool os::is_headless_jre() { return false; }
4588
4589// OS_SocketInterface
4590// Not used on Windows
4591
4592// OS_SocketInterface
4593typedef struct hostent * (PASCAL FAR *ws2_ifn_ptr_t)(...);
4594ws2_ifn_ptr_t *get_host_by_name_fn = NULL;
4595
4596typedef CRITICAL_SECTION mutex_t;
4597#define mutexInit(m)    InitializeCriticalSection(m)
4598#define mutexDestroy(m) DeleteCriticalSection(m)
4599#define mutexLock(m)    EnterCriticalSection(m)
4600#define mutexUnlock(m)  LeaveCriticalSection(m)
4601
4602static bool sockfnptrs_initialized = FALSE;
4603static mutex_t sockFnTableMutex;
4604
4605/* is Winsock2 loaded? better to be explicit than to rely on sockfnptrs */
4606static bool winsock2Available = FALSE;
4607
4608
4609static void initSockFnTable() {
4610  int (PASCAL FAR* WSAStartupPtr)(WORD, LPWSADATA);
4611  WSADATA wsadata;
4612
4613  ::mutexInit(&sockFnTableMutex);
4614  ::mutexLock(&sockFnTableMutex);
4615
4616  if (sockfnptrs_initialized == FALSE) {
4617        HMODULE hWinsock;
4618
4619          /* try to load Winsock2, and if that fails, load Winsock */
4620    hWinsock = ::LoadLibrary("ws2_32.dll");
4621
4622    if (hWinsock == NULL) {
4623      jio_fprintf(stderr, "Could not load Winsock 2 (error: %d)\n",
4624      ::GetLastError());
4625      return;
4626    }
4627
4628    /* If we loaded a DLL, then we might as well initialize it.  */
4629    WSAStartupPtr = (int (PASCAL FAR *)(WORD, LPWSADATA))
4630    ::GetProcAddress(hWinsock, "WSAStartup");
4631
4632    if (WSAStartupPtr(MAKEWORD(1,1), &wsadata) != 0) {
4633        jio_fprintf(stderr, "Could not initialize Winsock\n");
4634    }
4635
4636    get_host_by_name_fn
4637        = (ws2_ifn_ptr_t*) GetProcAddress(hWinsock, "gethostbyname");
4638  }
4639
4640  assert(get_host_by_name_fn != NULL,
4641    "gethostbyname function not found");
4642  sockfnptrs_initialized = TRUE;
4643  ::mutexUnlock(&sockFnTableMutex);
4644}
4645
4646struct hostent*  os::get_host_by_name(char* name) {
4647  if (!sockfnptrs_initialized) {
4648    initSockFnTable();
4649  }
4650
4651  assert(sockfnptrs_initialized == TRUE && get_host_by_name_fn != NULL,
4652    "sockfnptrs is not initialized or pointer to gethostbyname function is NULL");
4653  return (*get_host_by_name_fn)(name);
4654}
4655
4656
4657int os::socket_close(int fd) {
4658  ShouldNotReachHere();
4659  return 0;
4660}
4661
4662int os::socket_available(int fd, jint *pbytes) {
4663  ShouldNotReachHere();
4664  return 0;
4665}
4666
4667int os::socket(int domain, int type, int protocol) {
4668  ShouldNotReachHere();
4669  return 0;
4670}
4671
4672int os::listen(int fd, int count) {
4673  ShouldNotReachHere();
4674  return 0;
4675}
4676
4677int os::connect(int fd, struct sockaddr *him, int len) {
4678  ShouldNotReachHere();
4679  return 0;
4680}
4681
4682int os::accept(int fd, struct sockaddr *him, int *len) {
4683  ShouldNotReachHere();
4684  return 0;
4685}
4686
4687int os::sendto(int fd, char *buf, int len, int flags,
4688                        struct sockaddr *to, int tolen) {
4689  ShouldNotReachHere();
4690  return 0;
4691}
4692
4693int os::recvfrom(int fd, char *buf, int nBytes, int flags,
4694                         sockaddr *from, int *fromlen) {
4695  ShouldNotReachHere();
4696  return 0;
4697}
4698
4699int os::recv(int fd, char *buf, int nBytes, int flags) {
4700  ShouldNotReachHere();
4701  return 0;
4702}
4703
4704int os::send(int fd, char *buf, int nBytes, int flags) {
4705  ShouldNotReachHere();
4706  return 0;
4707}
4708
4709int os::raw_send(int fd, char *buf, int nBytes, int flags) {
4710  ShouldNotReachHere();
4711  return 0;
4712}
4713
4714int os::timeout(int fd, long timeout) {
4715  ShouldNotReachHere();
4716  return 0;
4717}
4718
4719int os::get_host_name(char* name, int namelen) {
4720  ShouldNotReachHere();
4721  return 0;
4722}
4723
4724int os::socket_shutdown(int fd, int howto) {
4725  ShouldNotReachHere();
4726  return 0;
4727}
4728
4729int os::bind(int fd, struct sockaddr *him, int len) {
4730  ShouldNotReachHere();
4731  return 0;
4732}
4733
4734int os::get_sock_name(int fd, struct sockaddr *him, int *len) {
4735  ShouldNotReachHere();
4736  return 0;
4737}
4738
4739int os::get_sock_opt(int fd, int level, int optname,
4740                             char *optval, int* optlen) {
4741  ShouldNotReachHere();
4742  return 0;
4743}
4744
4745int os::set_sock_opt(int fd, int level, int optname,
4746                             const char *optval, int optlen) {
4747  ShouldNotReachHere();
4748  return 0;
4749}
4750