Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/os/windows/vm/os_windows.cpp
32284 views
/*1* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324// Must be at least Windows 2000 or XP to use IsDebuggerPresent25#define _WIN32_WINNT 0x5002627// no precompiled headers28#include "classfile/classLoader.hpp"29#include "classfile/systemDictionary.hpp"30#include "classfile/vmSymbols.hpp"31#include "code/icBuffer.hpp"32#include "code/vtableStubs.hpp"33#include "compiler/compileBroker.hpp"34#include "compiler/disassembler.hpp"35#include "interpreter/interpreter.hpp"36#include "jvm_windows.h"37#include "memory/allocation.inline.hpp"38#include "memory/filemap.hpp"39#include "mutex_windows.inline.hpp"40#include "oops/oop.inline.hpp"41#include "os_share_windows.hpp"42#include "prims/jniFastGetField.hpp"43#include "prims/jvm.h"44#include "prims/jvm_misc.hpp"45#include "runtime/arguments.hpp"46#include "runtime/extendedPC.hpp"47#include "runtime/globals.hpp"48#include "runtime/interfaceSupport.hpp"49#include "runtime/java.hpp"50#include "runtime/javaCalls.hpp"51#include "runtime/mutexLocker.hpp"52#include "runtime/objectMonitor.hpp"53#include "runtime/orderAccess.inline.hpp"54#include "runtime/osThread.hpp"55#include "runtime/perfMemory.hpp"56#include "runtime/sharedRuntime.hpp"57#include "runtime/statSampler.hpp"58#include "runtime/stubRoutines.hpp"59#include "runtime/thread.inline.hpp"60#include "runtime/threadCritical.hpp"61#include "runtime/timer.hpp"62#include "services/attachListener.hpp"63#include "services/memTracker.hpp"64#include "services/runtimeService.hpp"65#include "utilities/decoder.hpp"66#include "utilities/defaultStream.hpp"67#include "utilities/events.hpp"68#include "utilities/growableArray.hpp"69#include "utilities/vmError.hpp"7071#ifdef _DEBUG72#include <crtdbg.h>73#endif747576#include <windows.h>77#include <sys/types.h>78#include <sys/stat.h>79#include <sys/timeb.h>80#include <objidl.h>81#include <shlobj.h>8283#include <malloc.h>84#include <signal.h>85#include <direct.h>86#include <errno.h>87#include <fcntl.h>88#include <io.h>89#include <process.h> // For _beginthreadex(), _endthreadex()90#include <imagehlp.h> // For os::dll_address_to_function_name91/* for enumerating dll libraries */92#include <vdmdbg.h>9394// for timer info max values which include all bits95#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)9697// For DLL loading/load error detection98// Values of PE COFF99#define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c100#define IMAGE_FILE_SIGNATURE_LENGTH 4101102static HANDLE main_process;103static HANDLE main_thread;104static int main_thread_id;105106static FILETIME process_creation_time;107static FILETIME process_exit_time;108static FILETIME process_user_time;109static FILETIME process_kernel_time;110111#ifdef _M_IA64112#define __CPU__ ia64113#else114#ifdef _M_AMD64115#define __CPU__ amd64116#else117#define __CPU__ i486118#endif119#endif120121// save DLL module handle, used by GetModuleFileName122123HINSTANCE vm_lib_handle;124125BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {126switch (reason) {127case DLL_PROCESS_ATTACH:128vm_lib_handle = hinst;129if(ForceTimeHighResolution)130timeBeginPeriod(1L);131break;132case DLL_PROCESS_DETACH:133if(ForceTimeHighResolution)134timeEndPeriod(1L);135136break;137default:138break;139}140return true;141}142143static inline double fileTimeAsDouble(FILETIME* time) {144const double high = (double) ((unsigned int) ~0);145const double split = 10000000.0;146double result = (time->dwLowDateTime / split) +147time->dwHighDateTime * (high/split);148return result;149}150151// Implementation of os152153bool os::getenv(const char* name, char* buffer, int len) {154int result = GetEnvironmentVariable(name, buffer, len);155return result > 0 && result < len;156}157158bool os::unsetenv(const char* name) {159assert(name != NULL, "Null pointer");160return (SetEnvironmentVariable(name, NULL) == TRUE);161}162163// No setuid programs under Windows.164bool os::have_special_privileges() {165return false;166}167168169// This method is a periodic task to check for misbehaving JNI applications170// under CheckJNI, we can add any periodic checks here.171// For Windows at the moment does nothing172void os::run_periodic_checks() {173return;174}175176#ifndef _WIN64177// previous UnhandledExceptionFilter, if there is one178static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;179180LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);181#endif182void os::init_system_properties_values() {183/* sysclasspath, java_home, dll_dir */184{185char *home_path;186char *dll_path;187char *pslash;188char *bin = "\\bin";189char home_dir[MAX_PATH];190191if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {192os::jvm_path(home_dir, sizeof(home_dir));193// Found the full path to jvm.dll.194// Now cut the path to <java_home>/jre if we can.195*(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */196pslash = strrchr(home_dir, '\\');197if (pslash != NULL) {198*pslash = '\0'; /* get rid of \{client|server} */199pslash = strrchr(home_dir, '\\');200if (pslash != NULL)201*pslash = '\0'; /* get rid of \bin */202}203}204205home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal);206if (home_path == NULL)207return;208strcpy(home_path, home_dir);209Arguments::set_java_home(home_path);210211dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal);212if (dll_path == NULL)213return;214strcpy(dll_path, home_dir);215strcat(dll_path, bin);216Arguments::set_dll_dir(dll_path);217218if (!set_boot_path('\\', ';'))219return;220}221222/* library_path */223#define EXT_DIR "\\lib\\ext"224#define BIN_DIR "\\bin"225#define PACKAGE_DIR "\\Sun\\Java"226{227/* Win32 library search order (See the documentation for LoadLibrary):228*229* 1. The directory from which application is loaded.230* 2. The system wide Java Extensions directory (Java only)231* 3. System directory (GetSystemDirectory)232* 4. Windows directory (GetWindowsDirectory)233* 5. The PATH environment variable234* 6. The current directory235*/236237char *library_path;238char tmp[MAX_PATH];239char *path_str = ::getenv("PATH");240241library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +242sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal);243244library_path[0] = '\0';245246GetModuleFileName(NULL, tmp, sizeof(tmp));247*(strrchr(tmp, '\\')) = '\0';248strcat(library_path, tmp);249250GetWindowsDirectory(tmp, sizeof(tmp));251strcat(library_path, ";");252strcat(library_path, tmp);253strcat(library_path, PACKAGE_DIR BIN_DIR);254255GetSystemDirectory(tmp, sizeof(tmp));256strcat(library_path, ";");257strcat(library_path, tmp);258259GetWindowsDirectory(tmp, sizeof(tmp));260strcat(library_path, ";");261strcat(library_path, tmp);262263if (path_str) {264strcat(library_path, ";");265strcat(library_path, path_str);266}267268strcat(library_path, ";.");269270Arguments::set_library_path(library_path);271FREE_C_HEAP_ARRAY(char, library_path, mtInternal);272}273274/* Default extensions directory */275{276char path[MAX_PATH];277char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1];278GetWindowsDirectory(path, MAX_PATH);279sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR,280path, PACKAGE_DIR, EXT_DIR);281Arguments::set_ext_dirs(buf);282}283#undef EXT_DIR284#undef BIN_DIR285#undef PACKAGE_DIR286287/* Default endorsed standards directory. */288{289#define ENDORSED_DIR "\\lib\\endorsed"290size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);291char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);292sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);293Arguments::set_endorsed_dirs(buf);294#undef ENDORSED_DIR295}296297#ifndef _WIN64298// set our UnhandledExceptionFilter and save any previous one299prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);300#endif301302// Done303return;304}305306void os::breakpoint() {307DebugBreak();308}309310// Invoked from the BREAKPOINT Macro311extern "C" void breakpoint() {312os::breakpoint();313}314315/*316* RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP.317* So far, this method is only used by Native Memory Tracking, which is318* only supported on Windows XP or later.319*/320321int os::get_native_stack(address* stack, int frames, int toSkip) {322#ifdef _NMT_NOINLINE_323toSkip ++;324#endif325int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames,326(PVOID*)stack, NULL);327for (int index = captured; index < frames; index ++) {328stack[index] = NULL;329}330return captured;331}332333334// os::current_stack_base()335//336// Returns the base of the stack, which is the stack's337// starting address. This function must be called338// while running on the stack of the thread being queried.339340address os::current_stack_base() {341MEMORY_BASIC_INFORMATION minfo;342address stack_bottom;343size_t stack_size;344345VirtualQuery(&minfo, &minfo, sizeof(minfo));346stack_bottom = (address)minfo.AllocationBase;347stack_size = minfo.RegionSize;348349// Add up the sizes of all the regions with the same350// AllocationBase.351while( 1 )352{353VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));354if ( stack_bottom == (address)minfo.AllocationBase )355stack_size += minfo.RegionSize;356else357break;358}359360#ifdef _M_IA64361// IA64 has memory and register stacks362//363// This is the stack layout you get on NT/IA64 if you specify 1MB stack limit364// at thread creation (1MB backing store growing upwards, 1MB memory stack365// growing downwards, 2MB summed up)366//367// ...368// ------- top of stack (high address) -----369// |370// | 1MB371// | Backing Store (Register Stack)372// |373// | / \374// | |375// | |376// | |377// ------------------------ stack base -----378// | 1MB379// | Memory Stack380// |381// | |382// | |383// | |384// | \ /385// |386// ----- bottom of stack (low address) -----387// ...388389stack_size = stack_size / 2;390#endif391return stack_bottom + stack_size;392}393394size_t os::current_stack_size() {395size_t sz;396MEMORY_BASIC_INFORMATION minfo;397VirtualQuery(&minfo, &minfo, sizeof(minfo));398sz = (size_t)os::current_stack_base() - (size_t)minfo.AllocationBase;399return sz;400}401402struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {403const struct tm* time_struct_ptr = localtime(clock);404if (time_struct_ptr != NULL) {405*res = *time_struct_ptr;406return res;407}408return NULL;409}410411LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);412413// Thread start routine for all new Java threads414static unsigned __stdcall java_start(Thread* thread) {415// Try to randomize the cache line index of hot stack frames.416// This helps when threads of the same stack traces evict each other's417// cache lines. The threads can be either from the same JVM instance, or418// from different JVM instances. The benefit is especially true for419// processors with hyperthreading technology.420static int counter = 0;421int pid = os::current_process_id();422_alloca(((pid ^ counter++) & 7) * 128);423424OSThread* osthr = thread->osthread();425assert(osthr->get_state() == RUNNABLE, "invalid os thread state");426427if (UseNUMA) {428int lgrp_id = os::numa_get_group_id();429if (lgrp_id != -1) {430thread->set_lgrp_id(lgrp_id);431}432}433434435// Install a win32 structured exception handler around every thread created436// by VM, so VM can genrate error dump when an exception occurred in non-437// Java thread (e.g. VM thread).438__try {439thread->run();440} __except(topLevelExceptionFilter(441(_EXCEPTION_POINTERS*)_exception_info())) {442// Nothing to do.443}444445// One less thread is executing446// When the VMThread gets here, the main thread may have already exited447// which frees the CodeHeap containing the Atomic::add code448if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {449Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);450}451452return 0;453}454455static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) {456// Allocate the OSThread object457OSThread* osthread = new OSThread(NULL, NULL);458if (osthread == NULL) return NULL;459460// Initialize support for Java interrupts461HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);462if (interrupt_event == NULL) {463delete osthread;464return NULL;465}466osthread->set_interrupt_event(interrupt_event);467468// Store info on the Win32 thread into the OSThread469osthread->set_thread_handle(thread_handle);470osthread->set_thread_id(thread_id);471472if (UseNUMA) {473int lgrp_id = os::numa_get_group_id();474if (lgrp_id != -1) {475thread->set_lgrp_id(lgrp_id);476}477}478479// Initial thread state is INITIALIZED, not SUSPENDED480osthread->set_state(INITIALIZED);481482return osthread;483}484485486bool os::create_attached_thread(JavaThread* thread) {487#ifdef ASSERT488thread->verify_not_published();489#endif490HANDLE thread_h;491if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),492&thread_h, THREAD_ALL_ACCESS, false, 0)) {493fatal("DuplicateHandle failed\n");494}495OSThread* osthread = create_os_thread(thread, thread_h,496(int)current_thread_id());497if (osthread == NULL) {498return false;499}500501// Initial thread state is RUNNABLE502osthread->set_state(RUNNABLE);503504thread->set_osthread(osthread);505return true;506}507508bool os::create_main_thread(JavaThread* thread) {509#ifdef ASSERT510thread->verify_not_published();511#endif512if (_starting_thread == NULL) {513_starting_thread = create_os_thread(thread, main_thread, main_thread_id);514if (_starting_thread == NULL) {515return false;516}517}518519// The primordial thread is runnable from the start)520_starting_thread->set_state(RUNNABLE);521522thread->set_osthread(_starting_thread);523return true;524}525526// Allocate and initialize a new OSThread527bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {528unsigned thread_id;529530// Allocate the OSThread object531OSThread* osthread = new OSThread(NULL, NULL);532if (osthread == NULL) {533return false;534}535536// Initialize support for Java interrupts537HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);538if (interrupt_event == NULL) {539delete osthread;540return NULL;541}542osthread->set_interrupt_event(interrupt_event);543osthread->set_interrupted(false);544545thread->set_osthread(osthread);546547if (stack_size == 0) {548switch (thr_type) {549case os::java_thread:550// Java threads use ThreadStackSize which default value can be changed with the flag -Xss551if (JavaThread::stack_size_at_create() > 0)552stack_size = JavaThread::stack_size_at_create();553break;554case os::compiler_thread:555if (CompilerThreadStackSize > 0) {556stack_size = (size_t)(CompilerThreadStackSize * K);557break;558} // else fall through:559// use VMThreadStackSize if CompilerThreadStackSize is not defined560case os::vm_thread:561case os::pgc_thread:562case os::cgc_thread:563case os::watcher_thread:564if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);565break;566}567}568569// Create the Win32 thread570//571// Contrary to what MSDN document says, "stack_size" in _beginthreadex()572// does not specify stack size. Instead, it specifies the size of573// initially committed space. The stack size is determined by574// PE header in the executable. If the committed "stack_size" is larger575// than default value in the PE header, the stack is rounded up to the576// nearest multiple of 1MB. For example if the launcher has default577// stack size of 320k, specifying any size less than 320k does not578// affect the actual stack size at all, it only affects the initial579// commitment. On the other hand, specifying 'stack_size' larger than580// default value may cause significant increase in memory usage, because581// not only the stack space will be rounded up to MB, but also the582// entire space is committed upfront.583//584// Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'585// for CreateThread() that can treat 'stack_size' as stack size. However we586// are not supposed to call CreateThread() directly according to MSDN587// document because JVM uses C runtime library. The good news is that the588// flag appears to work with _beginthredex() as well.589590#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION591#define STACK_SIZE_PARAM_IS_A_RESERVATION (0x10000)592#endif593594HANDLE thread_handle =595(HANDLE)_beginthreadex(NULL,596(unsigned)stack_size,597(unsigned (__stdcall *)(void*)) java_start,598thread,599CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,600&thread_id);601if (thread_handle == NULL) {602// perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again603// without the flag.604thread_handle =605(HANDLE)_beginthreadex(NULL,606(unsigned)stack_size,607(unsigned (__stdcall *)(void*)) java_start,608thread,609CREATE_SUSPENDED,610&thread_id);611}612if (thread_handle == NULL) {613// Need to clean up stuff we've allocated so far614CloseHandle(osthread->interrupt_event());615thread->set_osthread(NULL);616delete osthread;617return NULL;618}619620Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);621622// Store info on the Win32 thread into the OSThread623osthread->set_thread_handle(thread_handle);624osthread->set_thread_id(thread_id);625626// Initial thread state is INITIALIZED, not SUSPENDED627osthread->set_state(INITIALIZED);628629// The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain630return true;631}632633634// Free Win32 resources related to the OSThread635void os::free_thread(OSThread* osthread) {636assert(osthread != NULL, "osthread not set");637CloseHandle(osthread->thread_handle());638CloseHandle(osthread->interrupt_event());639delete osthread;640}641642643static int has_performance_count = 0;644static jlong first_filetime;645static jlong initial_performance_count;646static jlong performance_frequency;647648649jlong as_long(LARGE_INTEGER x) {650jlong result = 0; // initialization to avoid warning651set_high(&result, x.HighPart);652set_low(&result, x.LowPart);653return result;654}655656657jlong os::elapsed_counter() {658LARGE_INTEGER count;659if (has_performance_count) {660QueryPerformanceCounter(&count);661return as_long(count) - initial_performance_count;662} else {663FILETIME wt;664GetSystemTimeAsFileTime(&wt);665return (jlong_from(wt.dwHighDateTime, wt.dwLowDateTime) - first_filetime);666}667}668669670jlong os::elapsed_frequency() {671if (has_performance_count) {672return performance_frequency;673} else {674// the FILETIME time is the number of 100-nanosecond intervals since January 1,1601.675return 10000000;676}677}678679680julong os::available_memory() {681return win32::available_memory();682}683684julong os::win32::available_memory() {685// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect686// value if total memory is larger than 4GB687MEMORYSTATUSEX ms;688ms.dwLength = sizeof(ms);689GlobalMemoryStatusEx(&ms);690691return (julong)ms.ullAvailPhys;692}693694julong os::physical_memory() {695return win32::physical_memory();696}697698bool os::has_allocatable_memory_limit(julong* limit) {699MEMORYSTATUSEX ms;700ms.dwLength = sizeof(ms);701GlobalMemoryStatusEx(&ms);702#ifdef _LP64703*limit = (julong)ms.ullAvailVirtual;704return true;705#else706// Limit to 1400m because of the 2gb address space wall707*limit = MIN2((julong)1400*M, (julong)ms.ullAvailVirtual);708return true;709#endif710}711712// VC6 lacks DWORD_PTR713#if _MSC_VER < 1300714typedef UINT_PTR DWORD_PTR;715#endif716717int os::active_processor_count() {718// User has overridden the number of active processors719if (ActiveProcessorCount > 0) {720if (PrintActiveCpus) {721tty->print_cr("active_processor_count: "722"active processor count set by user : %d",723ActiveProcessorCount);724}725return ActiveProcessorCount;726}727728DWORD_PTR lpProcessAffinityMask = 0;729DWORD_PTR lpSystemAffinityMask = 0;730int proc_count = processor_count();731if (proc_count <= sizeof(UINT_PTR) * BitsPerByte &&732GetProcessAffinityMask(GetCurrentProcess(), &lpProcessAffinityMask, &lpSystemAffinityMask)) {733// Nof active processors is number of bits in process affinity mask734int bitcount = 0;735while (lpProcessAffinityMask != 0) {736lpProcessAffinityMask = lpProcessAffinityMask & (lpProcessAffinityMask-1);737bitcount++;738}739return bitcount;740} else {741return proc_count;742}743}744745void os::set_native_thread_name(const char *name) {746747// See: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx748//749// Note that unfortunately this only works if the process750// is already attached to a debugger; debugger must observe751// the exception below to show the correct name.752753const DWORD MS_VC_EXCEPTION = 0x406D1388;754struct {755DWORD dwType; // must be 0x1000756LPCSTR szName; // pointer to name (in user addr space)757DWORD dwThreadID; // thread ID (-1=caller thread)758DWORD dwFlags; // reserved for future use, must be zero759} info;760761info.dwType = 0x1000;762info.szName = name;763info.dwThreadID = -1;764info.dwFlags = 0;765766__try {767RaiseException (MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info );768} __except(EXCEPTION_CONTINUE_EXECUTION) {}769}770771bool os::distribute_processes(uint length, uint* distribution) {772// Not yet implemented.773return false;774}775776bool os::bind_to_processor(uint processor_id) {777// Not yet implemented.778return false;779}780781static void initialize_performance_counter() {782LARGE_INTEGER count;783if (QueryPerformanceFrequency(&count)) {784has_performance_count = 1;785performance_frequency = as_long(count);786QueryPerformanceCounter(&count);787initial_performance_count = as_long(count);788} else {789has_performance_count = 0;790FILETIME wt;791GetSystemTimeAsFileTime(&wt);792first_filetime = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);793}794}795796797double os::elapsedTime() {798return (double) elapsed_counter() / (double) elapsed_frequency();799}800801802// Windows format:803// The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.804// Java format:805// Java standards require the number of milliseconds since 1/1/1970806807// Constant offset - calculated using offset()808static jlong _offset = 116444736000000000;809// Fake time counter for reproducible results when debugging810static jlong fake_time = 0;811812#ifdef ASSERT813// Just to be safe, recalculate the offset in debug mode814static jlong _calculated_offset = 0;815static int _has_calculated_offset = 0;816817jlong offset() {818if (_has_calculated_offset) return _calculated_offset;819SYSTEMTIME java_origin;820java_origin.wYear = 1970;821java_origin.wMonth = 1;822java_origin.wDayOfWeek = 0; // ignored823java_origin.wDay = 1;824java_origin.wHour = 0;825java_origin.wMinute = 0;826java_origin.wSecond = 0;827java_origin.wMilliseconds = 0;828FILETIME jot;829if (!SystemTimeToFileTime(&java_origin, &jot)) {830fatal(err_msg("Error = %d\nWindows error", GetLastError()));831}832_calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);833_has_calculated_offset = 1;834assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");835return _calculated_offset;836}837#else838jlong offset() {839return _offset;840}841#endif842843jlong windows_to_java_time(FILETIME wt) {844jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);845return (a - offset()) / 10000;846}847848FILETIME java_to_windows_time(jlong l) {849jlong a = (l * 10000) + offset();850FILETIME result;851result.dwHighDateTime = high(a);852result.dwLowDateTime = low(a);853return result;854}855856bool os::supports_vtime() { return true; }857bool os::enable_vtime() { return false; }858bool os::vtime_enabled() { return false; }859860double os::elapsedVTime() {861FILETIME created;862FILETIME exited;863FILETIME kernel;864FILETIME user;865if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {866// the resolution of windows_to_java_time() should be sufficient (ms)867return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;868} else {869return elapsedTime();870}871}872873jlong os::javaTimeMillis() {874if (UseFakeTimers) {875return fake_time++;876} else {877FILETIME wt;878GetSystemTimeAsFileTime(&wt);879return windows_to_java_time(wt);880}881}882883jlong os::javaTimeNanos() {884if (!has_performance_count) {885return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.886} else {887LARGE_INTEGER current_count;888QueryPerformanceCounter(¤t_count);889double current = as_long(current_count);890double freq = performance_frequency;891jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);892return time;893}894}895896void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {897if (!has_performance_count) {898// javaTimeMillis() doesn't have much percision,899// but it is not going to wrap -- so all 64 bits900info_ptr->max_value = ALL_64_BITS;901902// this is a wall clock timer, so may skip903info_ptr->may_skip_backward = true;904info_ptr->may_skip_forward = true;905} else {906jlong freq = performance_frequency;907if (freq < NANOSECS_PER_SEC) {908// the performance counter is 64 bits and we will909// be multiplying it -- so no wrap in 64 bits910info_ptr->max_value = ALL_64_BITS;911} else if (freq > NANOSECS_PER_SEC) {912// use the max value the counter can reach to913// determine the max value which could be returned914julong max_counter = (julong)ALL_64_BITS;915info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));916} else {917// the performance counter is 64 bits and we will918// be using it directly -- so no wrap in 64 bits919info_ptr->max_value = ALL_64_BITS;920}921922// using a counter, so no skipping923info_ptr->may_skip_backward = false;924info_ptr->may_skip_forward = false;925}926info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time927}928929char* os::local_time_string(char *buf, size_t buflen) {930SYSTEMTIME st;931GetLocalTime(&st);932jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",933st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);934return buf;935}936937bool os::getTimesSecs(double* process_real_time,938double* process_user_time,939double* process_system_time) {940HANDLE h_process = GetCurrentProcess();941FILETIME create_time, exit_time, kernel_time, user_time;942BOOL result = GetProcessTimes(h_process,943&create_time,944&exit_time,945&kernel_time,946&user_time);947if (result != 0) {948FILETIME wt;949GetSystemTimeAsFileTime(&wt);950jlong rtc_millis = windows_to_java_time(wt);951jlong user_millis = windows_to_java_time(user_time);952jlong system_millis = windows_to_java_time(kernel_time);953*process_real_time = ((double) rtc_millis) / ((double) MILLIUNITS);954*process_user_time = ((double) user_millis) / ((double) MILLIUNITS);955*process_system_time = ((double) system_millis) / ((double) MILLIUNITS);956return true;957} else {958return false;959}960}961962void os::shutdown() {963964// allow PerfMemory to attempt cleanup of any persistent resources965perfMemory_exit();966967// flush buffered output, finish log files968ostream_abort();969970// Check for abort hook971abort_hook_t abort_hook = Arguments::abort_hook();972if (abort_hook != NULL) {973abort_hook();974}975}976977978static BOOL (WINAPI *_MiniDumpWriteDump) ( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,979PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);980981void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {982HINSTANCE dbghelp;983EXCEPTION_POINTERS ep;984MINIDUMP_EXCEPTION_INFORMATION mei;985MINIDUMP_EXCEPTION_INFORMATION* pmei;986987HANDLE hProcess = GetCurrentProcess();988DWORD processId = GetCurrentProcessId();989HANDLE dumpFile;990MINIDUMP_TYPE dumpType;991static const char* cwd;992993// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.994#ifndef ASSERT995// If running on a client version of Windows and user has not explicitly enabled dumping996if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {997VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);998return;999// If running on a server version of Windows and user has explictly disabled dumping1000} else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {1001VMError::report_coredump_status("Minidump has been disabled from the command line", false);1002return;1003}1004#else1005if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {1006VMError::report_coredump_status("Minidump has been disabled from the command line", false);1007return;1008}1009#endif10101011dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);10121013if (dbghelp == NULL) {1014VMError::report_coredump_status("Failed to load dbghelp.dll", false);1015return;1016}10171018_MiniDumpWriteDump = CAST_TO_FN_PTR(1019BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,1020PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION),1021GetProcAddress(dbghelp, "MiniDumpWriteDump"));10221023if (_MiniDumpWriteDump == NULL) {1024VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false);1025return;1026}10271028dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData);10291030// Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with1031// API_VERSION_NUMBER 11 or higher contains the ones we want though1032#if API_VERSION_NUMBER >= 111033dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo |1034MiniDumpWithUnloadedModules);1035#endif10361037cwd = get_current_directory(NULL, 0);1038jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp",cwd, current_process_id());1039dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);10401041if (dumpFile == INVALID_HANDLE_VALUE) {1042VMError::report_coredump_status("Failed to create file for dumping", false);1043return;1044}1045if (exceptionRecord != NULL && contextRecord != NULL) {1046ep.ContextRecord = (PCONTEXT) contextRecord;1047ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord;10481049mei.ThreadId = GetCurrentThreadId();1050mei.ExceptionPointers = &ep;1051pmei = &mei;1052} else {1053pmei = NULL;1054}105510561057// Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all1058// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.1059if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&1060_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {1061DWORD error = GetLastError();1062LPTSTR msgbuf = NULL;10631064if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |1065FORMAT_MESSAGE_FROM_SYSTEM |1066FORMAT_MESSAGE_IGNORE_INSERTS,1067NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {10681069jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);1070LocalFree(msgbuf);1071} else {1072// Call to FormatMessage failed, just include the result from GetLastError1073jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);1074}1075VMError::report_coredump_status(buffer, false);1076} else {1077VMError::report_coredump_status(buffer, true);1078}10791080CloseHandle(dumpFile);1081}1082108310841085void os::abort(bool dump_core)1086{1087os::shutdown();1088// no core dump on Windows1089::exit(1);1090}10911092// Die immediately, no exit hook, no abort hook, no cleanup.1093void os::die() {1094_exit(-1);1095}10961097// Directory routines copied from src/win32/native/java/io/dirent_md.c1098// * dirent_md.c 1.15 00/02/021099//1100// The declarations for DIR and struct dirent are in jvm_win32.h.11011102/* Caller must have already run dirname through JVM_NativePath, which removes1103duplicate slashes and converts all instances of '/' into '\\'. */11041105DIR *1106os::opendir(const char *dirname)1107{1108assert(dirname != NULL, "just checking"); // hotspot change1109DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal);1110DWORD fattr; // hotspot change1111char alt_dirname[4] = { 0, 0, 0, 0 };11121113if (dirp == 0) {1114errno = ENOMEM;1115return 0;1116}11171118/*1119* Win32 accepts "\" in its POSIX stat(), but refuses to treat it1120* as a directory in FindFirstFile(). We detect this case here and1121* prepend the current drive name.1122*/1123if (dirname[1] == '\0' && dirname[0] == '\\') {1124alt_dirname[0] = _getdrive() + 'A' - 1;1125alt_dirname[1] = ':';1126alt_dirname[2] = '\\';1127alt_dirname[3] = '\0';1128dirname = alt_dirname;1129}11301131dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);1132if (dirp->path == 0) {1133free(dirp, mtInternal);1134errno = ENOMEM;1135return 0;1136}1137strcpy(dirp->path, dirname);11381139fattr = GetFileAttributes(dirp->path);1140if (fattr == 0xffffffff) {1141free(dirp->path, mtInternal);1142free(dirp, mtInternal);1143errno = ENOENT;1144return 0;1145} else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {1146free(dirp->path, mtInternal);1147free(dirp, mtInternal);1148errno = ENOTDIR;1149return 0;1150}11511152/* Append "*.*", or possibly "\\*.*", to path */1153if (dirp->path[1] == ':'1154&& (dirp->path[2] == '\0'1155|| (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) {1156/* No '\\' needed for cases like "Z:" or "Z:\" */1157strcat(dirp->path, "*.*");1158} else {1159strcat(dirp->path, "\\*.*");1160}11611162dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);1163if (dirp->handle == INVALID_HANDLE_VALUE) {1164if (GetLastError() != ERROR_FILE_NOT_FOUND) {1165free(dirp->path, mtInternal);1166free(dirp, mtInternal);1167errno = EACCES;1168return 0;1169}1170}1171return dirp;1172}11731174struct dirent *1175os::readdir(DIR *dirp)1176{1177assert(dirp != NULL, "just checking"); // hotspot change1178if (dirp->handle == INVALID_HANDLE_VALUE) {1179return NULL;1180}11811182strcpy(dirp->dirent.d_name, dirp->find_data.cFileName);11831184if (!FindNextFile(dirp->handle, &dirp->find_data)) {1185if (GetLastError() == ERROR_INVALID_HANDLE) {1186errno = EBADF;1187return NULL;1188}1189FindClose(dirp->handle);1190dirp->handle = INVALID_HANDLE_VALUE;1191}11921193return &dirp->dirent;1194}11951196int1197os::closedir(DIR *dirp)1198{1199assert(dirp != NULL, "just checking"); // hotspot change1200if (dirp->handle != INVALID_HANDLE_VALUE) {1201if (!FindClose(dirp->handle)) {1202errno = EBADF;1203return -1;1204}1205dirp->handle = INVALID_HANDLE_VALUE;1206}1207free(dirp->path, mtInternal);1208free(dirp, mtInternal);1209return 0;1210}12111212// This must be hard coded because it's the system's temporary1213// directory not the java application's temp directory, ala java.io.tmpdir.1214const char* os::get_temp_directory() {1215static char path_buf[MAX_PATH];1216if (GetTempPath(MAX_PATH, path_buf)>0)1217return path_buf;1218else{1219path_buf[0]='\0';1220return path_buf;1221}1222}12231224static bool file_exists(const char* filename) {1225if (filename == NULL || strlen(filename) == 0) {1226return false;1227}1228return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;1229}12301231bool os::dll_build_name(char *buffer, size_t buflen,1232const char* pname, const char* fname) {1233bool retval = false;1234const size_t pnamelen = pname ? strlen(pname) : 0;1235const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;12361237// Return error on buffer overflow.1238if (pnamelen + strlen(fname) + 10 > buflen) {1239return retval;1240}12411242if (pnamelen == 0) {1243jio_snprintf(buffer, buflen, "%s.dll", fname);1244retval = true;1245} else if (c == ':' || c == '\\') {1246jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);1247retval = true;1248} else if (strchr(pname, *os::path_separator()) != NULL) {1249int n;1250char** pelements = split_path(pname, &n);1251if (pelements == NULL) {1252return false;1253}1254for (int i = 0 ; i < n ; i++) {1255char* path = pelements[i];1256// Really shouldn't be NULL, but check can't hurt1257size_t plen = (path == NULL) ? 0 : strlen(path);1258if (plen == 0) {1259continue; // skip the empty path values1260}1261const char lastchar = path[plen - 1];1262if (lastchar == ':' || lastchar == '\\') {1263jio_snprintf(buffer, buflen, "%s%s.dll", path, fname);1264} else {1265jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);1266}1267if (file_exists(buffer)) {1268retval = true;1269break;1270}1271}1272// release the storage1273for (int i = 0 ; i < n ; i++) {1274if (pelements[i] != NULL) {1275FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);1276}1277}1278if (pelements != NULL) {1279FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);1280}1281} else {1282jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);1283retval = true;1284}1285return retval;1286}12871288// Needs to be in os specific directory because windows requires another1289// header file <direct.h>1290const char* os::get_current_directory(char *buf, size_t buflen) {1291int n = static_cast<int>(buflen);1292if (buflen > INT_MAX) n = INT_MAX;1293return _getcwd(buf, n);1294}12951296//-----------------------------------------------------------1297// Helper functions for fatal error handler1298#ifdef _WIN641299// Helper routine which returns true if address in1300// within the NTDLL address space.1301//1302static bool _addr_in_ntdll( address addr )1303{1304HMODULE hmod;1305MODULEINFO minfo;13061307hmod = GetModuleHandle("NTDLL.DLL");1308if ( hmod == NULL ) return false;1309if ( !os::PSApiDll::GetModuleInformation( GetCurrentProcess(), hmod,1310&minfo, sizeof(MODULEINFO)) )1311return false;13121313if ( (addr >= minfo.lpBaseOfDll) &&1314(addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage)))1315return true;1316else1317return false;1318}1319#endif132013211322// Enumerate all modules for a given process ID1323//1324// Notice that Windows 95/98/Me and Windows NT/2000/XP have1325// different API for doing this. We use PSAPI.DLL on NT based1326// Windows and ToolHelp on 95/98/Me.13271328// Callback function that is called by enumerate_modules() on1329// every DLL module.1330// Input parameters:1331// int pid,1332// char* module_file_name,1333// address module_base_addr,1334// unsigned module_size,1335// void* param1336typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *);13371338// enumerate_modules for Windows NT, using PSAPI1339static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param)1340{1341HANDLE hProcess ;13421343# define MAX_NUM_MODULES 1281344HMODULE modules[MAX_NUM_MODULES];1345static char filename[ MAX_PATH ];1346int result = 0;13471348if (!os::PSApiDll::PSApiAvailable()) {1349return 0;1350}13511352hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,1353FALSE, pid ) ;1354if (hProcess == NULL) return 0;13551356DWORD size_needed;1357if (!os::PSApiDll::EnumProcessModules(hProcess, modules,1358sizeof(modules), &size_needed)) {1359CloseHandle( hProcess );1360return 0;1361}13621363// number of modules that are currently loaded1364int num_modules = size_needed / sizeof(HMODULE);13651366for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {1367// Get Full pathname:1368if(!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i],1369filename, sizeof(filename))) {1370filename[0] = '\0';1371}13721373MODULEINFO modinfo;1374if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i],1375&modinfo, sizeof(modinfo))) {1376modinfo.lpBaseOfDll = NULL;1377modinfo.SizeOfImage = 0;1378}13791380// Invoke callback function1381result = func(pid, filename, (address)modinfo.lpBaseOfDll,1382modinfo.SizeOfImage, param);1383if (result) break;1384}13851386CloseHandle( hProcess ) ;1387return result;1388}138913901391// enumerate_modules for Windows 95/98/ME, using TOOLHELP1392static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param)1393{1394HANDLE hSnapShot ;1395static MODULEENTRY32 modentry ;1396int result = 0;13971398if (!os::Kernel32Dll::HelpToolsAvailable()) {1399return 0;1400}14011402// Get a handle to a Toolhelp snapshot of the system1403hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid ) ;1404if( hSnapShot == INVALID_HANDLE_VALUE ) {1405return FALSE ;1406}14071408// iterate through all modules1409modentry.dwSize = sizeof(MODULEENTRY32) ;1410bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0;14111412while( not_done ) {1413// invoke the callback1414result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr,1415modentry.modBaseSize, param);1416if (result) break;14171418modentry.dwSize = sizeof(MODULEENTRY32) ;1419not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0;1420}14211422CloseHandle(hSnapShot);1423return result;1424}14251426int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param )1427{1428// Get current process ID if caller doesn't provide it.1429if (!pid) pid = os::current_process_id();14301431if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param);1432else return _enumerate_modules_windows(pid, func, param);1433}14341435struct _modinfo {1436address addr;1437char* full_path; // point to a char buffer1438int buflen; // size of the buffer1439address base_addr;1440};14411442static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr,1443unsigned size, void * param) {1444struct _modinfo *pmod = (struct _modinfo *)param;1445if (!pmod) return -1;14461447if (base_addr <= pmod->addr &&1448base_addr+size > pmod->addr) {1449// if a buffer is provided, copy path name to the buffer1450if (pmod->full_path) {1451jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname);1452}1453pmod->base_addr = base_addr;1454return 1;1455}1456return 0;1457}14581459bool os::dll_address_to_library_name(address addr, char* buf,1460int buflen, int* offset) {1461// buf is not optional, but offset is optional1462assert(buf != NULL, "sanity check");14631464// NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always1465// return the full path to the DLL file, sometimes it returns path1466// to the corresponding PDB file (debug info); sometimes it only1467// returns partial path, which makes life painful.14681469struct _modinfo mi;1470mi.addr = addr;1471mi.full_path = buf;1472mi.buflen = buflen;1473int pid = os::current_process_id();1474if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {1475// buf already contains path name1476if (offset) *offset = addr - mi.base_addr;1477return true;1478}14791480buf[0] = '\0';1481if (offset) *offset = -1;1482return false;1483}14841485bool os::dll_address_to_function_name(address addr, char *buf,1486int buflen, int *offset) {1487// buf is not optional, but offset is optional1488assert(buf != NULL, "sanity check");14891490if (Decoder::decode(addr, buf, buflen, offset)) {1491return true;1492}1493if (offset != NULL) *offset = -1;1494buf[0] = '\0';1495return false;1496}14971498// save the start and end address of jvm.dll into param[0] and param[1]1499static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,1500unsigned size, void * param) {1501if (!param) return -1;15021503if (base_addr <= (address)_locate_jvm_dll &&1504base_addr+size > (address)_locate_jvm_dll) {1505((address*)param)[0] = base_addr;1506((address*)param)[1] = base_addr + size;1507return 1;1508}1509return 0;1510}15111512address vm_lib_location[2]; // start and end address of jvm.dll15131514// check if addr is inside jvm.dll1515bool os::address_is_in_vm(address addr) {1516if (!vm_lib_location[0] || !vm_lib_location[1]) {1517int pid = os::current_process_id();1518if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) {1519assert(false, "Can't find jvm module.");1520return false;1521}1522}15231524return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]);1525}15261527// print module info; param is outputStream*1528static int _print_module(int pid, char* fname, address base,1529unsigned size, void* param) {1530if (!param) return -1;15311532outputStream* st = (outputStream*)param;15331534address end_addr = base + size;1535st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname);1536return 0;1537}15381539// Loads .dll/.so and1540// in case of error it checks if .dll/.so was built for the1541// same architecture as Hotspot is running on1542void * os::dll_load(const char *name, char *ebuf, int ebuflen)1543{1544void * result = LoadLibrary(name);1545if (result != NULL)1546{1547return result;1548}15491550DWORD errcode = GetLastError();1551if (errcode == ERROR_MOD_NOT_FOUND) {1552strncpy(ebuf, "Can't find dependent libraries", ebuflen-1);1553ebuf[ebuflen-1]='\0';1554return NULL;1555}15561557// Parsing dll below1558// If we can read dll-info and find that dll was built1559// for an architecture other than Hotspot is running in1560// - then print to buffer "DLL was built for a different architecture"1561// else call os::lasterror to obtain system error message15621563// Read system error message into ebuf1564// It may or may not be overwritten below (in the for loop and just above)1565lasterror(ebuf, (size_t) ebuflen);1566ebuf[ebuflen-1]='\0';1567int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0);1568if (file_descriptor<0)1569{1570return NULL;1571}15721573uint32_t signature_offset;1574uint16_t lib_arch=0;1575bool failed_to_get_lib_arch=1576(1577//Go to position 3c in the dll1578(os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0)1579||1580// Read loacation of signature1581(sizeof(signature_offset)!=1582(os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset))))1583||1584//Go to COFF File Header in dll1585//that is located after"signature" (4 bytes long)1586(os::seek_to_file_offset(file_descriptor,1587signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0)1588||1589//Read field that contains code of architecture1590// that dll was build for1591(sizeof(lib_arch)!=1592(os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch))))1593);15941595::close(file_descriptor);1596if (failed_to_get_lib_arch)1597{1598// file i/o error - report os::lasterror(...) msg1599return NULL;1600}16011602typedef struct1603{1604uint16_t arch_code;1605char* arch_name;1606} arch_t;16071608static const arch_t arch_array[]={1609{IMAGE_FILE_MACHINE_I386, (char*)"IA 32"},1610{IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"},1611{IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"}1612};1613#if (defined _M_IA64)1614static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64;1615#elif (defined _M_AMD64)1616static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64;1617#elif (defined _M_IX86)1618static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386;1619#else1620#error Method os::dll_load requires that one of following \1621is defined :_M_IA64,_M_AMD64 or _M_IX861622#endif162316241625// Obtain a string for printf operation1626// lib_arch_str shall contain string what platform this .dll was built for1627// running_arch_str shall string contain what platform Hotspot was built for1628char *running_arch_str=NULL,*lib_arch_str=NULL;1629for (unsigned int i=0;i<ARRAY_SIZE(arch_array);i++)1630{1631if (lib_arch==arch_array[i].arch_code)1632lib_arch_str=arch_array[i].arch_name;1633if (running_arch==arch_array[i].arch_code)1634running_arch_str=arch_array[i].arch_name;1635}16361637assert(running_arch_str,1638"Didn't find runing architecture code in arch_array");16391640// If the architure is right1641// but some other error took place - report os::lasterror(...) msg1642if (lib_arch == running_arch)1643{1644return NULL;1645}16461647if (lib_arch_str!=NULL)1648{1649::_snprintf(ebuf, ebuflen-1,1650"Can't load %s-bit .dll on a %s-bit platform",1651lib_arch_str,running_arch_str);1652}1653else1654{1655// don't know what architecture this dll was build for1656::_snprintf(ebuf, ebuflen-1,1657"Can't load this .dll (machine code=0x%x) on a %s-bit platform",1658lib_arch,running_arch_str);1659}16601661return NULL;1662}166316641665void os::print_dll_info(outputStream *st) {1666int pid = os::current_process_id();1667st->print_cr("Dynamic libraries:");1668enumerate_modules(pid, _print_module, (void *)st);1669}16701671int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {1672HANDLE hProcess;16731674# define MAX_NUM_MODULES 1281675HMODULE modules[MAX_NUM_MODULES];1676static char filename[MAX_PATH];1677int result = 0;16781679int pid = os::current_process_id();1680hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,1681FALSE, pid);1682if (hProcess == NULL) return 0;16831684DWORD size_needed;1685if (!EnumProcessModules(hProcess, modules, sizeof(modules), &size_needed)) {1686CloseHandle(hProcess);1687return 0;1688}16891690// number of modules that are currently loaded1691int num_modules = size_needed / sizeof(HMODULE);16921693for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {1694// Get Full pathname:1695if (!GetModuleFileNameEx(hProcess, modules[i], filename, sizeof(filename))) {1696filename[0] = '\0';1697}16981699MODULEINFO modinfo;1700if (!GetModuleInformation(hProcess, modules[i], &modinfo, sizeof(modinfo))) {1701modinfo.lpBaseOfDll = NULL;1702modinfo.SizeOfImage = 0;1703}17041705// Invoke callback function1706result = callback(filename, (address)modinfo.lpBaseOfDll,1707(address)((u8)modinfo.lpBaseOfDll + (u8)modinfo.SizeOfImage), param);1708if (result) break;1709}17101711CloseHandle(hProcess);1712return result;1713}17141715void os::print_os_info_brief(outputStream* st) {1716os::print_os_info(st);1717}17181719void os::print_os_info(outputStream* st) {1720st->print("OS:");17211722os::win32::print_windows_version(st);1723}17241725void os::win32::print_windows_version(outputStream* st) {1726OSVERSIONINFOEX osvi;1727VS_FIXEDFILEINFO *file_info;1728TCHAR kernel32_path[MAX_PATH];1729UINT len, ret;17301731// Use the GetVersionEx information to see if we're on a server or1732// workstation edition of Windows. Starting with Windows 8.1 we can't1733// trust the OS version information returned by this API.1734ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));1735osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);1736if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {1737st->print_cr("Call to GetVersionEx failed");1738return;1739}1740bool is_workstation = (osvi.wProductType == VER_NT_WORKSTATION);17411742// Get the full path to \Windows\System32\kernel32.dll and use that for1743// determining what version of Windows we're running on.1744len = MAX_PATH - (UINT)strlen("\\kernel32.dll") - 1;1745ret = GetSystemDirectory(kernel32_path, len);1746if (ret == 0 || ret > len) {1747st->print_cr("Call to GetSystemDirectory failed");1748return;1749}1750strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);17511752DWORD version_size = GetFileVersionInfoSize(kernel32_path, NULL);1753if (version_size == 0) {1754st->print_cr("Call to GetFileVersionInfoSize failed");1755return;1756}17571758LPTSTR version_info = (LPTSTR)os::malloc(version_size, mtInternal);1759if (version_info == NULL) {1760st->print_cr("Failed to allocate version_info");1761return;1762}17631764if (!GetFileVersionInfo(kernel32_path, NULL, version_size, version_info)) {1765os::free(version_info);1766st->print_cr("Call to GetFileVersionInfo failed");1767return;1768}17691770if (!VerQueryValue(version_info, TEXT("\\"), (LPVOID*)&file_info, &len)) {1771os::free(version_info);1772st->print_cr("Call to VerQueryValue failed");1773return;1774}17751776int major_version = HIWORD(file_info->dwProductVersionMS);1777int minor_version = LOWORD(file_info->dwProductVersionMS);1778int build_number = HIWORD(file_info->dwProductVersionLS);1779int build_minor = LOWORD(file_info->dwProductVersionLS);1780int os_vers = major_version * 1000 + minor_version;1781os::free(version_info);17821783st->print(" Windows ");1784switch (os_vers) {17851786case 6000:1787if (is_workstation) {1788st->print("Vista");1789} else {1790st->print("Server 2008");1791}1792break;17931794case 6001:1795if (is_workstation) {1796st->print("7");1797} else {1798st->print("Server 2008 R2");1799}1800break;18011802case 6002:1803if (is_workstation) {1804st->print("8");1805} else {1806st->print("Server 2012");1807}1808break;18091810case 6003:1811if (is_workstation) {1812st->print("8.1");1813} else {1814st->print("Server 2012 R2");1815}1816break;18171818case 6004:1819if (is_workstation) {1820st->print("10");1821} else {1822// distinguish Windows Server 2016 and 2019 by build number1823// Windows server 2019 GA 10/2018 build number is 177631824if (build_number > 17762) {1825st->print("Server 2019");1826} else {1827st->print("Server 2016");1828}1829}1830break;18311832default:1833// Unrecognized windows, print out its major and minor versions1834st->print("%d.%d", major_version, minor_version);1835break;1836}18371838// Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could1839// find out whether we are running on 64 bit processor or not1840SYSTEM_INFO si;1841ZeroMemory(&si, sizeof(SYSTEM_INFO));1842os::Kernel32Dll::GetNativeSystemInfo(&si);1843if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {1844st->print(" , 64 bit");1845}18461847st->print(" Build %d", build_number);1848st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);1849st->cr();1850}18511852void os::pd_print_cpu_info(outputStream* st) {1853// Nothing to do for now.1854}18551856void os::print_memory_info(outputStream* st) {1857st->print("Memory:");1858st->print(" %dk page", os::vm_page_size()>>10);18591860// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect1861// value if total memory is larger than 4GB1862MEMORYSTATUSEX ms;1863ms.dwLength = sizeof(ms);1864GlobalMemoryStatusEx(&ms);18651866st->print(", physical %uk", os::physical_memory() >> 10);1867st->print("(%uk free)", os::available_memory() >> 10);18681869st->print(", swap %uk", ms.ullTotalPageFile >> 10);1870st->print("(%uk free)", ms.ullAvailPageFile >> 10);1871st->cr();1872}18731874void os::print_siginfo(outputStream *st, void *siginfo) {1875EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;1876st->print("siginfo:");1877st->print(" ExceptionCode=0x%x", er->ExceptionCode);18781879if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&1880er->NumberParameters >= 2) {1881switch (er->ExceptionInformation[0]) {1882case 0: st->print(", reading address"); break;1883case 1: st->print(", writing address"); break;1884default: st->print(", ExceptionInformation=" INTPTR_FORMAT,1885er->ExceptionInformation[0]);1886}1887st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);1888} else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR &&1889er->NumberParameters >= 2 && UseSharedSpaces) {1890FileMapInfo* mapinfo = FileMapInfo::current_info();1891if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {1892st->print("\n\nError accessing class data sharing archive." \1893" Mapped file inaccessible during execution, " \1894" possible disk/network problem.");1895}1896} else {1897int num = er->NumberParameters;1898if (num > 0) {1899st->print(", ExceptionInformation=");1900for (int i = 0; i < num; i++) {1901st->print(INTPTR_FORMAT " ", er->ExceptionInformation[i]);1902}1903}1904}1905st->cr();1906}190719081909int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {1910#if _MSC_VER >= 19001911// Starting with Visual Studio 2015, vsnprint is C99 compliant.1912int result = ::vsnprintf(buf, len, fmt, args);1913// If an encoding error occurred (result < 0) then it's not clear1914// whether the buffer is NUL terminated, so ensure it is.1915if ((result < 0) && (len > 0)) {1916buf[len - 1] = '\0';1917}1918return result;1919#else1920// Before Visual Studio 2015, vsnprintf is not C99 compliant, so use1921// _vsnprintf, whose behavior seems to be *mostly* consistent across1922// versions. However, when len == 0, avoid _vsnprintf too, and just1923// go straight to _vscprintf. The output is going to be truncated in1924// that case, except in the unusual case of empty output. More1925// importantly, the documentation for various versions of Visual Studio1926// are inconsistent about the behavior of _vsnprintf when len == 0,1927// including it possibly being an error.1928int result = -1;1929if (len > 0) {1930result = _vsnprintf(buf, len, fmt, args);1931// If output (including NUL terminator) is truncated, the buffer1932// won't be NUL terminated. Add the trailing NUL specified by C99.1933if ((result < 0) || (result >= (int) len)) {1934buf[len - 1] = '\0';1935}1936}1937if (result < 0) {1938result = _vscprintf(fmt, args);1939}1940return result;1941#endif // _MSC_VER dispatch1942}19431944void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {1945// do nothing1946}19471948static char saved_jvm_path[MAX_PATH] = {0};19491950// Find the full path to the current module, jvm.dll1951void os::jvm_path(char *buf, jint buflen) {1952// Error checking.1953if (buflen < MAX_PATH) {1954assert(false, "must use a large-enough buffer");1955buf[0] = '\0';1956return;1957}1958// Lazy resolve the path to current module.1959if (saved_jvm_path[0] != 0) {1960strcpy(buf, saved_jvm_path);1961return;1962}19631964buf[0] = '\0';1965if (Arguments::created_by_gamma_launcher()) {1966// Support for the gamma launcher. Check for an1967// JAVA_HOME environment variable1968// and fix up the path so it looks like1969// libjvm.so is installed there (append a fake suffix1970// hotspot/libjvm.so).1971char* java_home_var = ::getenv("JAVA_HOME");1972if (java_home_var != NULL && java_home_var[0] != 0 &&1973strlen(java_home_var) < (size_t)buflen) {19741975strncpy(buf, java_home_var, buflen);19761977// determine if this is a legacy image or modules image1978// modules image doesn't have "jre" subdirectory1979size_t len = strlen(buf);1980char* jrebin_p = buf + len;1981jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\");1982if (0 != _access(buf, 0)) {1983jio_snprintf(jrebin_p, buflen-len, "\\bin\\");1984}1985len = strlen(buf);1986jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll");1987}1988}19891990if(buf[0] == '\0') {1991GetModuleFileName(vm_lib_handle, buf, buflen);1992}1993strncpy(saved_jvm_path, buf, MAX_PATH);1994}199519961997void os::print_jni_name_prefix_on(outputStream* st, int args_size) {1998#ifndef _WIN641999st->print("_");2000#endif2001}200220032004void os::print_jni_name_suffix_on(outputStream* st, int args_size) {2005#ifndef _WIN642006st->print("@%d", args_size * sizeof(int));2007#endif2008}20092010// This method is a copy of JDK's sysGetLastErrorString2011// from src/windows/hpi/src/system_md.c20122013size_t os::lasterror(char* buf, size_t len) {2014DWORD errval;20152016if ((errval = GetLastError()) != 0) {2017// DOS error2018size_t n = (size_t)FormatMessage(2019FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,2020NULL,2021errval,20220,2023buf,2024(DWORD)len,2025NULL);2026if (n > 3) {2027// Drop final '.', CR, LF2028if (buf[n - 1] == '\n') n--;2029if (buf[n - 1] == '\r') n--;2030if (buf[n - 1] == '.') n--;2031buf[n] = '\0';2032}2033return n;2034}20352036if (errno != 0) {2037// C runtime error that has no corresponding DOS error code2038const char* s = strerror(errno);2039size_t n = strlen(s);2040if (n >= len) n = len - 1;2041strncpy(buf, s, n);2042buf[n] = '\0';2043return n;2044}20452046return 0;2047}20482049int os::get_last_error() {2050DWORD error = GetLastError();2051if (error == 0)2052error = errno;2053return (int)error;2054}20552056// sun.misc.Signal2057// NOTE that this is a workaround for an apparent kernel bug where if2058// a signal handler for SIGBREAK is installed then that signal handler2059// takes priority over the console control handler for CTRL_CLOSE_EVENT.2060// See bug 4416763.2061static void (*sigbreakHandler)(int) = NULL;20622063static void UserHandler(int sig, void *siginfo, void *context) {2064os::signal_notify(sig);2065// We need to reinstate the signal handler each time...2066os::signal(sig, (void*)UserHandler);2067}20682069void* os::user_handler() {2070return (void*) UserHandler;2071}20722073void* os::signal(int signal_number, void* handler) {2074if ((signal_number == SIGBREAK) && (!ReduceSignalUsage)) {2075void (*oldHandler)(int) = sigbreakHandler;2076sigbreakHandler = (void (*)(int)) handler;2077return (void*) oldHandler;2078} else {2079return (void*)::signal(signal_number, (void (*)(int))handler);2080}2081}20822083void os::signal_raise(int signal_number) {2084raise(signal_number);2085}20862087// The Win32 C runtime library maps all console control events other than ^C2088// into SIGBREAK, which makes it impossible to distinguish ^BREAK from close,2089// logoff, and shutdown events. We therefore install our own console handler2090// that raises SIGTERM for the latter cases.2091//2092static BOOL WINAPI consoleHandler(DWORD event) {2093switch(event) {2094case CTRL_C_EVENT:2095if (is_error_reported()) {2096// Ctrl-C is pressed during error reporting, likely because the error2097// handler fails to abort. Let VM die immediately.2098os::die();2099}21002101os::signal_raise(SIGINT);2102return TRUE;2103break;2104case CTRL_BREAK_EVENT:2105if (sigbreakHandler != NULL) {2106(*sigbreakHandler)(SIGBREAK);2107}2108return TRUE;2109break;2110case CTRL_LOGOFF_EVENT: {2111// Don't terminate JVM if it is running in a non-interactive session,2112// such as a service process.2113USEROBJECTFLAGS flags;2114HANDLE handle = GetProcessWindowStation();2115if (handle != NULL &&2116GetUserObjectInformation(handle, UOI_FLAGS, &flags,2117sizeof( USEROBJECTFLAGS), NULL)) {2118// If it is a non-interactive session, let next handler to deal2119// with it.2120if ((flags.dwFlags & WSF_VISIBLE) == 0) {2121return FALSE;2122}2123}2124}2125case CTRL_CLOSE_EVENT:2126case CTRL_SHUTDOWN_EVENT:2127os::signal_raise(SIGTERM);2128return TRUE;2129break;2130default:2131break;2132}2133return FALSE;2134}21352136/*2137* The following code is moved from os.cpp for making this2138* code platform specific, which it is by its very nature.2139*/21402141// Return maximum OS signal used + 1 for internal use only2142// Used as exit signal for signal_thread2143int os::sigexitnum_pd(){2144return NSIG;2145}21462147// a counter for each possible signal value, including signal_thread exit signal2148static volatile jint pending_signals[NSIG+1] = { 0 };2149static HANDLE sig_sem = NULL;21502151void os::signal_init_pd() {2152// Initialize signal structures2153memset((void*)pending_signals, 0, sizeof(pending_signals));21542155sig_sem = ::CreateSemaphore(NULL, 0, NSIG+1, NULL);21562157// Programs embedding the VM do not want it to attempt to receive2158// events like CTRL_LOGOFF_EVENT, which are used to implement the2159// shutdown hooks mechanism introduced in 1.3. For example, when2160// the VM is run as part of a Windows NT service (i.e., a servlet2161// engine in a web server), the correct behavior is for any console2162// control handler to return FALSE, not TRUE, because the OS's2163// "final" handler for such events allows the process to continue if2164// it is a service (while terminating it if it is not a service).2165// To make this behavior uniform and the mechanism simpler, we2166// completely disable the VM's usage of these console events if -Xrs2167// (=ReduceSignalUsage) is specified. This means, for example, that2168// the CTRL-BREAK thread dump mechanism is also disabled in this2169// case. See bugs 4323062, 4345157, and related bugs.21702171if (!ReduceSignalUsage) {2172// Add a CTRL-C handler2173SetConsoleCtrlHandler(consoleHandler, TRUE);2174}2175}21762177void os::signal_notify(int signal_number) {2178BOOL ret;2179if (sig_sem != NULL) {2180Atomic::inc(&pending_signals[signal_number]);2181ret = ::ReleaseSemaphore(sig_sem, 1, NULL);2182assert(ret != 0, "ReleaseSemaphore() failed");2183}2184}21852186static int check_pending_signals(bool wait_for_signal) {2187DWORD ret;2188while (true) {2189for (int i = 0; i < NSIG + 1; i++) {2190jint n = pending_signals[i];2191if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {2192return i;2193}2194}2195if (!wait_for_signal) {2196return -1;2197}21982199JavaThread *thread = JavaThread::current();22002201ThreadBlockInVM tbivm(thread);22022203bool threadIsSuspended;2204do {2205thread->set_suspend_equivalent();2206// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()2207ret = ::WaitForSingleObject(sig_sem, INFINITE);2208assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed");22092210// were we externally suspended while we were waiting?2211threadIsSuspended = thread->handle_special_suspend_equivalent_condition();2212if (threadIsSuspended) {2213//2214// The semaphore has been incremented, but while we were waiting2215// another thread suspended us. We don't want to continue running2216// while suspended because that would surprise the thread that2217// suspended us.2218//2219ret = ::ReleaseSemaphore(sig_sem, 1, NULL);2220assert(ret != 0, "ReleaseSemaphore() failed");22212222thread->java_suspend_self();2223}2224} while (threadIsSuspended);2225}2226}22272228int os::signal_lookup() {2229return check_pending_signals(false);2230}22312232int os::signal_wait() {2233return check_pending_signals(true);2234}22352236// Implicit OS exception handling22372238LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) {2239JavaThread* thread = JavaThread::current();2240// Save pc in thread2241#ifdef _M_IA642242// Do not blow up if no thread info available.2243if (thread) {2244// Saving PRECISE pc (with slot information) in thread.2245uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress;2246// Convert precise PC into "Unix" format2247precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2);2248thread->set_saved_exception_pc((address)precise_pc);2249}2250// Set pc to handler2251exceptionInfo->ContextRecord->StIIP = (DWORD64)handler;2252// Clear out psr.ri (= Restart Instruction) in order to continue2253// at the beginning of the target bundle.2254exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF;2255assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!");2256#else2257#ifdef _M_AMD642258// Do not blow up if no thread info available.2259if (thread) {2260thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);2261}2262// Set pc to handler2263exceptionInfo->ContextRecord->Rip = (DWORD64)handler;2264#else2265// Do not blow up if no thread info available.2266if (thread) {2267thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);2268}2269// Set pc to handler2270exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;2271#endif2272#endif22732274// Continue the execution2275return EXCEPTION_CONTINUE_EXECUTION;2276}227722782279// Used for PostMortemDump2280extern "C" void safepoints();2281extern "C" void find(int x);2282extern "C" void events();22832284// According to Windows API documentation, an illegal instruction sequence should generate2285// the 0xC000001C exception code. However, real world experience shows that occasionnaly2286// the execution of an illegal instruction can generate the exception code 0xC000001E. This2287// seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).22882289#define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E22902291// From "Execution Protection in the Windows Operating System" draft 0.352292// Once a system header becomes available, the "real" define should be2293// included or copied here.2294#define EXCEPTION_INFO_EXEC_VIOLATION 0x0822952296// Handle NAT Bit consumption on IA64.2297#ifdef _M_IA642298#define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION2299#endif23002301// Windows Vista/2008 heap corruption check2302#define EXCEPTION_HEAP_CORRUPTION 0xC000037423032304// All Visual C++ exceptions thrown from code generated by the Microsoft Visual2305// C++ compiler contain this error code. Because this is a compiler-generated2306// error, the code is not listed in the Win32 API header files.2307// The code is actually a cryptic mnemonic device, with the initial "E"2308// standing for "exception" and the final 3 bytes (0x6D7363) representing the2309// ASCII values of "msc".23102311#define EXCEPTION_UNCAUGHT_CXX_EXCEPTION 0xE06D736323122313#define def_excpt(val) { #val, (val) }23142315static const struct { char* name; uint number; } exceptlabels[] = {2316def_excpt(EXCEPTION_ACCESS_VIOLATION),2317def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),2318def_excpt(EXCEPTION_BREAKPOINT),2319def_excpt(EXCEPTION_SINGLE_STEP),2320def_excpt(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),2321def_excpt(EXCEPTION_FLT_DENORMAL_OPERAND),2322def_excpt(EXCEPTION_FLT_DIVIDE_BY_ZERO),2323def_excpt(EXCEPTION_FLT_INEXACT_RESULT),2324def_excpt(EXCEPTION_FLT_INVALID_OPERATION),2325def_excpt(EXCEPTION_FLT_OVERFLOW),2326def_excpt(EXCEPTION_FLT_STACK_CHECK),2327def_excpt(EXCEPTION_FLT_UNDERFLOW),2328def_excpt(EXCEPTION_INT_DIVIDE_BY_ZERO),2329def_excpt(EXCEPTION_INT_OVERFLOW),2330def_excpt(EXCEPTION_PRIV_INSTRUCTION),2331def_excpt(EXCEPTION_IN_PAGE_ERROR),2332def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION),2333def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION_2),2334def_excpt(EXCEPTION_NONCONTINUABLE_EXCEPTION),2335def_excpt(EXCEPTION_STACK_OVERFLOW),2336def_excpt(EXCEPTION_INVALID_DISPOSITION),2337def_excpt(EXCEPTION_GUARD_PAGE),2338def_excpt(EXCEPTION_INVALID_HANDLE),2339def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),2340def_excpt(EXCEPTION_HEAP_CORRUPTION)2341#ifdef _M_IA642342, def_excpt(EXCEPTION_REG_NAT_CONSUMPTION)2343#endif2344};23452346const char* os::exception_name(int exception_code, char *buf, size_t size) {2347uint code = static_cast<uint>(exception_code);2348for (uint i = 0; i < ARRAY_SIZE(exceptlabels); ++i) {2349if (exceptlabels[i].number == code) {2350jio_snprintf(buf, size, "%s", exceptlabels[i].name);2351return buf;2352}2353}23542355return NULL;2356}23572358//-----------------------------------------------------------------------------2359LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {2360// handle exception caused by idiv; should only happen for -MinInt/-12361// (division by zero is handled explicitly)2362#ifdef _M_IA642363assert(0, "Fix Handle_IDiv_Exception");2364#else2365#ifdef _M_AMD642366PCONTEXT ctx = exceptionInfo->ContextRecord;2367address pc = (address)ctx->Rip;2368assert(pc[0] == 0xF7, "not an idiv opcode");2369assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");2370assert(ctx->Rax == min_jint, "unexpected idiv exception");2371// set correct result values and continue after idiv instruction2372ctx->Rip = (DWORD64)pc + 2; // idiv reg, reg is 2 bytes2373ctx->Rax = (DWORD64)min_jint; // result2374ctx->Rdx = (DWORD64)0; // remainder2375// Continue the execution2376#else2377PCONTEXT ctx = exceptionInfo->ContextRecord;2378address pc = (address)ctx->Eip;2379assert(pc[0] == 0xF7, "not an idiv opcode");2380assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");2381assert(ctx->Eax == min_jint, "unexpected idiv exception");2382// set correct result values and continue after idiv instruction2383ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes2384ctx->Eax = (DWORD)min_jint; // result2385ctx->Edx = (DWORD)0; // remainder2386// Continue the execution2387#endif2388#endif2389return EXCEPTION_CONTINUE_EXECUTION;2390}23912392#ifndef _WIN642393//-----------------------------------------------------------------------------2394LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {2395// handle exception caused by native method modifying control word2396PCONTEXT ctx = exceptionInfo->ContextRecord;2397DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;23982399switch (exception_code) {2400case EXCEPTION_FLT_DENORMAL_OPERAND:2401case EXCEPTION_FLT_DIVIDE_BY_ZERO:2402case EXCEPTION_FLT_INEXACT_RESULT:2403case EXCEPTION_FLT_INVALID_OPERATION:2404case EXCEPTION_FLT_OVERFLOW:2405case EXCEPTION_FLT_STACK_CHECK:2406case EXCEPTION_FLT_UNDERFLOW:2407jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());2408if (fp_control_word != ctx->FloatSave.ControlWord) {2409// Restore FPCW and mask out FLT exceptions2410ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;2411// Mask out pending FLT exceptions2412ctx->FloatSave.StatusWord &= 0xffffff00;2413return EXCEPTION_CONTINUE_EXECUTION;2414}2415}24162417if (prev_uef_handler != NULL) {2418// We didn't handle this exception so pass it to the previous2419// UnhandledExceptionFilter.2420return (prev_uef_handler)(exceptionInfo);2421}24222423return EXCEPTION_CONTINUE_SEARCH;2424}2425#else //_WIN642426/*2427On Windows, the mxcsr control bits are non-volatile across calls2428See also CR 61923332429If EXCEPTION_FLT_* happened after some native method modified2430mxcsr - it is not a jvm fault.2431However should we decide to restore of mxcsr after a faulty2432native method we can uncomment following code2433jint MxCsr = INITIAL_MXCSR;2434// we can't use StubRoutines::addr_mxcsr_std()2435// because in Win64 mxcsr is not saved there2436if (MxCsr != ctx->MxCsr) {2437ctx->MxCsr = MxCsr;2438return EXCEPTION_CONTINUE_EXECUTION;2439}24402441*/2442#endif // _WIN64244324442445static inline void report_error(Thread* t, DWORD exception_code,2446address addr, void* siginfo, void* context) {2447VMError err(t, exception_code, addr, siginfo, context);2448err.report_and_die();24492450// If UseOsErrorReporting, this will return here and save the error file2451// somewhere where we can find it in the minidump.2452}24532454//-----------------------------------------------------------------------------2455LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {2456if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;2457DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;2458#ifdef _M_IA642459// On Itanium, we need the "precise pc", which has the slot number coded2460// into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format).2461address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress;2462// Convert the pc to "Unix format", which has the slot number coded2463// into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot22464// This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction"2465// information is saved in the Unix format.2466address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2));2467#else2468#ifdef _M_AMD642469address pc = (address) exceptionInfo->ContextRecord->Rip;2470#else2471address pc = (address) exceptionInfo->ContextRecord->Eip;2472#endif2473#endif2474Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady24752476// Handle SafeFetch32 and SafeFetchN exceptions.2477if (StubRoutines::is_safefetch_fault(pc)) {2478return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));2479}24802481#ifndef _WIN642482// Execution protection violation - win32 running on AMD64 only2483// Handled first to avoid misdiagnosis as a "normal" access violation;2484// This is safe to do because we have a new/unique ExceptionInformation2485// code for this condition.2486if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2487PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;2488int exception_subcode = (int) exceptionRecord->ExceptionInformation[0];2489address addr = (address) exceptionRecord->ExceptionInformation[1];24902491if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {2492int page_size = os::vm_page_size();24932494// Make sure the pc and the faulting address are sane.2495//2496// If an instruction spans a page boundary, and the page containing2497// the beginning of the instruction is executable but the following2498// page is not, the pc and the faulting address might be slightly2499// different - we still want to unguard the 2nd page in this case.2500//2501// 15 bytes seems to be a (very) safe value for max instruction size.2502bool pc_is_near_addr =2503(pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);2504bool instr_spans_page_boundary =2505(align_size_down((intptr_t) pc ^ (intptr_t) addr,2506(intptr_t) page_size) > 0);25072508if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {2509static volatile address last_addr =2510(address) os::non_memory_address_word();25112512// In conservative mode, don't unguard unless the address is in the VM2513if (UnguardOnExecutionViolation > 0 && addr != last_addr &&2514(UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {25152516// Set memory to RWX and retry2517address page_start =2518(address) align_size_down((intptr_t) addr, (intptr_t) page_size);2519bool res = os::protect_memory((char*) page_start, page_size,2520os::MEM_PROT_RWX);25212522if (PrintMiscellaneous && Verbose) {2523char buf[256];2524jio_snprintf(buf, sizeof(buf), "Execution protection violation "2525"at " INTPTR_FORMAT2526", unguarding " INTPTR_FORMAT ": %s", addr,2527page_start, (res ? "success" : strerror(errno)));2528tty->print_raw_cr(buf);2529}25302531// Set last_addr so if we fault again at the same address, we don't2532// end up in an endless loop.2533//2534// There are two potential complications here. Two threads trapping2535// at the same address at the same time could cause one of the2536// threads to think it already unguarded, and abort the VM. Likely2537// very rare.2538//2539// The other race involves two threads alternately trapping at2540// different addresses and failing to unguard the page, resulting in2541// an endless loop. This condition is probably even more unlikely2542// than the first.2543//2544// Although both cases could be avoided by using locks or thread2545// local last_addr, these solutions are unnecessary complication:2546// this handler is a best-effort safety net, not a complete solution.2547// It is disabled by default and should only be used as a workaround2548// in case we missed any no-execute-unsafe VM code.25492550last_addr = addr;25512552return EXCEPTION_CONTINUE_EXECUTION;2553}2554}25552556// Last unguard failed or not unguarding2557tty->print_raw_cr("Execution protection violation");2558report_error(t, exception_code, addr, exceptionInfo->ExceptionRecord,2559exceptionInfo->ContextRecord);2560return EXCEPTION_CONTINUE_SEARCH;2561}2562}2563#endif // _WIN6425642565// Check to see if we caught the safepoint code in the2566// process of write protecting the memory serialization page.2567// It write enables the page immediately after protecting it2568// so just return.2569if ( exception_code == EXCEPTION_ACCESS_VIOLATION ) {2570JavaThread* thread = (JavaThread*) t;2571PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;2572address addr = (address) exceptionRecord->ExceptionInformation[1];2573if ( os::is_memory_serialize_page(thread, addr) ) {2574// Block current thread until the memory serialize page permission restored.2575os::block_on_serialize_page_trap();2576return EXCEPTION_CONTINUE_EXECUTION;2577}2578}25792580if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&2581VM_Version::is_cpuinfo_segv_addr(pc)) {2582// Verify that OS save/restore AVX registers.2583return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());2584}25852586if (t != NULL && t->is_Java_thread()) {2587JavaThread* thread = (JavaThread*) t;2588bool in_java = thread->thread_state() == _thread_in_Java;25892590// Handle potential stack overflows up front.2591if (exception_code == EXCEPTION_STACK_OVERFLOW) {2592if (os::uses_stack_guard_pages()) {2593#ifdef _M_IA642594// Use guard page for register stack.2595PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;2596address addr = (address) exceptionRecord->ExceptionInformation[1];2597// Check for a register stack overflow on Itanium2598if (thread->addr_inside_register_stack_red_zone(addr)) {2599// Fatal red zone violation happens if the Java program2600// catches a StackOverflow error and does so much processing2601// that it runs beyond the unprotected yellow guard zone. As2602// a result, we are out of here.2603fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit.");2604} else if(thread->addr_inside_register_stack(addr)) {2605// Disable the yellow zone which sets the state that2606// we've got a stack overflow problem.2607if (thread->stack_yellow_zone_enabled()) {2608thread->disable_stack_yellow_zone();2609}2610// Give us some room to process the exception.2611thread->disable_register_stack_guard();2612// Tracing with +Verbose.2613if (Verbose) {2614tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc);2615tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr);2616tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base());2617tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]",2618thread->register_stack_base(),2619thread->register_stack_base() + thread->stack_size());2620}26212622// Reguard the permanent register stack red zone just to be sure.2623// We saw Windows silently disabling this without telling us.2624thread->enable_register_stack_red_zone();26252626return Handle_Exception(exceptionInfo,2627SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));2628}2629#endif2630if (thread->stack_yellow_zone_enabled()) {2631// Yellow zone violation. The o/s has unprotected the first yellow2632// zone page for us. Note: must call disable_stack_yellow_zone to2633// update the enabled status, even if the zone contains only one page.2634thread->disable_stack_yellow_zone();2635// If not in java code, return and hope for the best.2636return in_java ? Handle_Exception(exceptionInfo,2637SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))2638: EXCEPTION_CONTINUE_EXECUTION;2639} else {2640// Fatal red zone violation.2641thread->disable_stack_red_zone();2642tty->print_raw_cr("An unrecoverable stack overflow has occurred.");2643report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,2644exceptionInfo->ContextRecord);2645return EXCEPTION_CONTINUE_SEARCH;2646}2647} else if (in_java) {2648// JVM-managed guard pages cannot be used on win95/98. The o/s provides2649// a one-time-only guard page, which it has released to us. The next2650// stack overflow on this thread will result in an ACCESS_VIOLATION.2651return Handle_Exception(exceptionInfo,2652SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));2653} else {2654// Can only return and hope for the best. Further stack growth will2655// result in an ACCESS_VIOLATION.2656return EXCEPTION_CONTINUE_EXECUTION;2657}2658} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2659// Either stack overflow or null pointer exception.2660if (in_java) {2661PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;2662address addr = (address) exceptionRecord->ExceptionInformation[1];2663address stack_end = thread->stack_base() - thread->stack_size();2664if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {2665// Stack overflow.2666assert(!os::uses_stack_guard_pages(),2667"should be caught by red zone code above.");2668return Handle_Exception(exceptionInfo,2669SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));2670}2671//2672// Check for safepoint polling and implicit null2673// We only expect null pointers in the stubs (vtable)2674// the rest are checked explicitly now.2675//2676CodeBlob* cb = CodeCache::find_blob(pc);2677if (cb != NULL) {2678if (os::is_poll_address(addr)) {2679address stub = SharedRuntime::get_poll_stub(pc);2680return Handle_Exception(exceptionInfo, stub);2681}2682}2683{2684#ifdef _WIN642685//2686// If it's a legal stack address map the entire region in2687//2688PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;2689address addr = (address) exceptionRecord->ExceptionInformation[1];2690if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) {2691addr = (address)((uintptr_t)addr &2692(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));2693os::commit_memory((char *)addr, thread->stack_base() - addr,2694!ExecMem);2695return EXCEPTION_CONTINUE_EXECUTION;2696}2697else2698#endif2699{2700// Null pointer exception.2701#ifdef _M_IA642702// Process implicit null checks in compiled code. Note: Implicit null checks2703// can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs.2704if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) {2705CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format);2706// Handle implicit null check in UEP method entry2707if (cb && (cb->is_frame_complete_at(pc) ||2708(cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) {2709if (Verbose) {2710intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0);2711tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format);2712tty->print_cr(" to addr " INTPTR_FORMAT, addr);2713tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)",2714*(bundle_start + 1), *bundle_start);2715}2716return Handle_Exception(exceptionInfo,2717SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL));2718}2719}27202721// Implicit null checks were processed above. Hence, we should not reach2722// here in the usual case => die!2723if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception");2724report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,2725exceptionInfo->ContextRecord);2726return EXCEPTION_CONTINUE_SEARCH;27272728#else // !IA6427292730// Windows 98 reports faulting addresses incorrectly2731if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||2732!os::win32::is_nt()) {2733address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);2734if (stub != NULL) return Handle_Exception(exceptionInfo, stub);2735}2736report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,2737exceptionInfo->ContextRecord);2738return EXCEPTION_CONTINUE_SEARCH;2739#endif2740}2741}2742}27432744#ifdef _WIN642745// Special care for fast JNI field accessors.2746// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks2747// in and the heap gets shrunk before the field access.2748if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2749address addr = JNI_FastGetField::find_slowcase_pc(pc);2750if (addr != (address)-1) {2751return Handle_Exception(exceptionInfo, addr);2752}2753}2754#endif27552756// Stack overflow or null pointer exception in native code.2757report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,2758exceptionInfo->ContextRecord);2759return EXCEPTION_CONTINUE_SEARCH;2760} // /EXCEPTION_ACCESS_VIOLATION2761// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -2762#if defined _M_IA642763else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||2764exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {2765M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0);27662767// Compiled method patched to be non entrant? Following conditions must apply:2768// 1. must be first instruction in bundle2769// 2. must be a break instruction with appropriate code2770if((((uint64_t) pc & 0x0F) == 0) &&2771(((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {2772return Handle_Exception(exceptionInfo,2773(address)SharedRuntime::get_handle_wrong_method_stub());2774}2775} // /EXCEPTION_ILLEGAL_INSTRUCTION2776#endif277727782779if (in_java) {2780switch (exception_code) {2781case EXCEPTION_INT_DIVIDE_BY_ZERO:2782return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));27832784case EXCEPTION_INT_OVERFLOW:2785return Handle_IDiv_Exception(exceptionInfo);27862787} // switch2788}2789#ifndef _WIN642790if (((thread->thread_state() == _thread_in_Java) ||2791(thread->thread_state() == _thread_in_native)) &&2792exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION)2793{2794LONG result=Handle_FLT_Exception(exceptionInfo);2795if (result==EXCEPTION_CONTINUE_EXECUTION) return result;2796}2797#endif //_WIN642798}27992800if (exception_code != EXCEPTION_BREAKPOINT) {2801report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,2802exceptionInfo->ContextRecord);2803}2804return EXCEPTION_CONTINUE_SEARCH;2805}28062807#ifndef _WIN642808// Special care for fast JNI accessors.2809// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and2810// the heap gets shrunk before the field access.2811// Need to install our own structured exception handler since native code may2812// install its own.2813LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {2814DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;2815if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2816address pc = (address) exceptionInfo->ContextRecord->Eip;2817address addr = JNI_FastGetField::find_slowcase_pc(pc);2818if (addr != (address)-1) {2819return Handle_Exception(exceptionInfo, addr);2820}2821}2822return EXCEPTION_CONTINUE_SEARCH;2823}28242825#define DEFINE_FAST_GETFIELD(Return,Fieldname,Result) \2826Return JNICALL jni_fast_Get##Result##Field_wrapper(JNIEnv *env, jobject obj, jfieldID fieldID) { \2827__try { \2828return (*JNI_FastGetField::jni_fast_Get##Result##Field_fp)(env, obj, fieldID); \2829} __except(fastJNIAccessorExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { \2830} \2831return 0; \2832}28332834DEFINE_FAST_GETFIELD(jboolean, bool, Boolean)2835DEFINE_FAST_GETFIELD(jbyte, byte, Byte)2836DEFINE_FAST_GETFIELD(jchar, char, Char)2837DEFINE_FAST_GETFIELD(jshort, short, Short)2838DEFINE_FAST_GETFIELD(jint, int, Int)2839DEFINE_FAST_GETFIELD(jlong, long, Long)2840DEFINE_FAST_GETFIELD(jfloat, float, Float)2841DEFINE_FAST_GETFIELD(jdouble, double, Double)28422843address os::win32::fast_jni_accessor_wrapper(BasicType type) {2844switch (type) {2845case T_BOOLEAN: return (address)jni_fast_GetBooleanField_wrapper;2846case T_BYTE: return (address)jni_fast_GetByteField_wrapper;2847case T_CHAR: return (address)jni_fast_GetCharField_wrapper;2848case T_SHORT: return (address)jni_fast_GetShortField_wrapper;2849case T_INT: return (address)jni_fast_GetIntField_wrapper;2850case T_LONG: return (address)jni_fast_GetLongField_wrapper;2851case T_FLOAT: return (address)jni_fast_GetFloatField_wrapper;2852case T_DOUBLE: return (address)jni_fast_GetDoubleField_wrapper;2853default: ShouldNotReachHere();2854}2855return (address)-1;2856}2857#endif28582859void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {2860// Install a win32 structured exception handler around the test2861// function call so the VM can generate an error dump if needed.2862__try {2863(*funcPtr)();2864} __except(topLevelExceptionFilter(2865(_EXCEPTION_POINTERS*)_exception_info())) {2866// Nothing to do.2867}2868}28692870// Virtual Memory28712872int os::vm_page_size() { return os::win32::vm_page_size(); }2873int os::vm_allocation_granularity() {2874return os::win32::vm_allocation_granularity();2875}28762877// Windows large page support is available on Windows 2003. In order to use2878// large page memory, the administrator must first assign additional privilege2879// to the user:2880// + select Control Panel -> Administrative Tools -> Local Security Policy2881// + select Local Policies -> User Rights Assignment2882// + double click "Lock pages in memory", add users and/or groups2883// + reboot2884// Note the above steps are needed for administrator as well, as administrators2885// by default do not have the privilege to lock pages in memory.2886//2887// Note about Windows 2003: although the API supports committing large page2888// memory on a page-by-page basis and VirtualAlloc() returns success under this2889// scenario, I found through experiment it only uses large page if the entire2890// memory region is reserved and committed in a single VirtualAlloc() call.2891// This makes Windows large page support more or less like Solaris ISM, in2892// that the entire heap must be committed upfront. This probably will change2893// in the future, if so the code below needs to be revisited.28942895#ifndef MEM_LARGE_PAGES2896#define MEM_LARGE_PAGES 0x200000002897#endif28982899static HANDLE _hProcess;2900static HANDLE _hToken;29012902// Container for NUMA node list info2903class NUMANodeListHolder {2904private:2905int *_numa_used_node_list; // allocated below2906int _numa_used_node_count;29072908void free_node_list() {2909if (_numa_used_node_list != NULL) {2910FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal);2911}2912}29132914public:2915NUMANodeListHolder() {2916_numa_used_node_count = 0;2917_numa_used_node_list = NULL;2918// do rest of initialization in build routine (after function pointers are set up)2919}29202921~NUMANodeListHolder() {2922free_node_list();2923}29242925bool build() {2926DWORD_PTR proc_aff_mask;2927DWORD_PTR sys_aff_mask;2928if (!GetProcessAffinityMask(GetCurrentProcess(), &proc_aff_mask, &sys_aff_mask)) return false;2929ULONG highest_node_number;2930if (!os::Kernel32Dll::GetNumaHighestNodeNumber(&highest_node_number)) return false;2931free_node_list();2932_numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1, mtInternal);2933for (unsigned int i = 0; i <= highest_node_number; i++) {2934ULONGLONG proc_mask_numa_node;2935if (!os::Kernel32Dll::GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;2936if ((proc_aff_mask & proc_mask_numa_node)!=0) {2937_numa_used_node_list[_numa_used_node_count++] = i;2938}2939}2940return (_numa_used_node_count > 1);2941}29422943int get_count() {return _numa_used_node_count;}2944int get_node_list_entry(int n) {2945// for indexes out of range, returns -12946return (n < _numa_used_node_count ? _numa_used_node_list[n] : -1);2947}29482949} numa_node_list_holder;2950295129522953static size_t _large_page_size = 0;29542955static bool resolve_functions_for_large_page_init() {2956return os::Kernel32Dll::GetLargePageMinimumAvailable() &&2957os::Advapi32Dll::AdvapiAvailable();2958}29592960static bool request_lock_memory_privilege() {2961_hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,2962os::current_process_id());29632964LUID luid;2965if (_hProcess != NULL &&2966os::Advapi32Dll::OpenProcessToken(_hProcess, TOKEN_ADJUST_PRIVILEGES, &_hToken) &&2967os::Advapi32Dll::LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) {29682969TOKEN_PRIVILEGES tp;2970tp.PrivilegeCount = 1;2971tp.Privileges[0].Luid = luid;2972tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;29732974// AdjustTokenPrivileges() may return TRUE even when it couldn't change the2975// privilege. Check GetLastError() too. See MSDN document.2976if (os::Advapi32Dll::AdjustTokenPrivileges(_hToken, false, &tp, sizeof(tp), NULL, NULL) &&2977(GetLastError() == ERROR_SUCCESS)) {2978return true;2979}2980}29812982return false;2983}29842985static void cleanup_after_large_page_init() {2986if (_hProcess) CloseHandle(_hProcess);2987_hProcess = NULL;2988if (_hToken) CloseHandle(_hToken);2989_hToken = NULL;2990}29912992static bool numa_interleaving_init() {2993bool success = false;2994bool use_numa_interleaving_specified = !FLAG_IS_DEFAULT(UseNUMAInterleaving);29952996// print a warning if UseNUMAInterleaving flag is specified on command line2997bool warn_on_failure = use_numa_interleaving_specified;2998# define WARN(msg) if (warn_on_failure) { warning(msg); }29993000// NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages)3001size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity();3002NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity);30033004if (os::Kernel32Dll::NumaCallsAvailable()) {3005if (numa_node_list_holder.build()) {3006if (PrintMiscellaneous && Verbose) {3007tty->print("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());3008for (int i = 0; i < numa_node_list_holder.get_count(); i++) {3009tty->print("%d ", numa_node_list_holder.get_node_list_entry(i));3010}3011tty->print("\n");3012}3013success = true;3014} else {3015WARN("Process does not cover multiple NUMA nodes.");3016}3017} else {3018WARN("NUMA Interleaving is not supported by the operating system.");3019}3020if (!success) {3021if (use_numa_interleaving_specified) WARN("...Ignoring UseNUMAInterleaving flag.");3022}3023return success;3024#undef WARN3025}30263027// this routine is used whenever we need to reserve a contiguous VA range3028// but we need to make separate VirtualAlloc calls for each piece of the range3029// Reasons for doing this:3030// * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise)3031// * UseNUMAInterleaving requires a separate node for each piece3032static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, DWORD prot,3033bool should_inject_error=false) {3034char * p_buf;3035// note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size3036size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity();3037size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size;30383039// first reserve enough address space in advance since we want to be3040// able to break a single contiguous virtual address range into multiple3041// large page commits but WS2003 does not allow reserving large page space3042// so we just use 4K pages for reserve, this gives us a legal contiguous3043// address space. then we will deallocate that reservation, and re alloc3044// using large pages3045const size_t size_of_reserve = bytes + chunk_size;3046if (bytes > size_of_reserve) {3047// Overflowed.3048return NULL;3049}3050p_buf = (char *) VirtualAlloc(addr,3051size_of_reserve, // size of Reserve3052MEM_RESERVE,3053PAGE_READWRITE);3054// If reservation failed, return NULL3055if (p_buf == NULL) return NULL;3056MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);3057os::release_memory(p_buf, bytes + chunk_size);30583059// we still need to round up to a page boundary (in case we are using large pages)3060// but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size)3061// instead we handle this in the bytes_to_rq computation below3062p_buf = (char *) align_size_up((size_t)p_buf, page_size);30633064// now go through and allocate one chunk at a time until all bytes are3065// allocated3066size_t bytes_remaining = bytes;3067// An overflow of align_size_up() would have been caught above3068// in the calculation of size_of_reserve.3069char * next_alloc_addr = p_buf;3070HANDLE hProc = GetCurrentProcess();30713072#ifdef ASSERT3073// Variable for the failure injection3074long ran_num = os::random();3075size_t fail_after = ran_num % bytes;3076#endif30773078int count=0;3079while (bytes_remaining) {3080// select bytes_to_rq to get to the next chunk_size boundary30813082size_t bytes_to_rq = MIN2(bytes_remaining, chunk_size - ((size_t)next_alloc_addr % chunk_size));3083// Note allocate and commit3084char * p_new;30853086#ifdef ASSERT3087bool inject_error_now = should_inject_error && (bytes_remaining <= fail_after);3088#else3089const bool inject_error_now = false;3090#endif30913092if (inject_error_now) {3093p_new = NULL;3094} else {3095if (!UseNUMAInterleaving) {3096p_new = (char *) VirtualAlloc(next_alloc_addr,3097bytes_to_rq,3098flags,3099prot);3100} else {3101// get the next node to use from the used_node_list3102assert(numa_node_list_holder.get_count() > 0, "Multiple NUMA nodes expected");3103DWORD node = numa_node_list_holder.get_node_list_entry(count % numa_node_list_holder.get_count());3104p_new = (char *)os::Kernel32Dll::VirtualAllocExNuma(hProc,3105next_alloc_addr,3106bytes_to_rq,3107flags,3108prot,3109node);3110}3111}31123113if (p_new == NULL) {3114// Free any allocated pages3115if (next_alloc_addr > p_buf) {3116// Some memory was committed so release it.3117size_t bytes_to_release = bytes - bytes_remaining;3118// NMT has yet to record any individual blocks, so it3119// need to create a dummy 'reserve' record to match3120// the release.3121MemTracker::record_virtual_memory_reserve((address)p_buf,3122bytes_to_release, CALLER_PC);3123os::release_memory(p_buf, bytes_to_release);3124}3125#ifdef ASSERT3126if (should_inject_error) {3127if (TracePageSizes && Verbose) {3128tty->print_cr("Reserving pages individually failed.");3129}3130}3131#endif3132return NULL;3133}31343135bytes_remaining -= bytes_to_rq;3136next_alloc_addr += bytes_to_rq;3137count++;3138}3139// Although the memory is allocated individually, it is returned as one.3140// NMT records it as one block.3141if ((flags & MEM_COMMIT) != 0) {3142MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, CALLER_PC);3143} else {3144MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, CALLER_PC);3145}31463147// made it this far, success3148return p_buf;3149}3150315131523153void os::large_page_init() {3154if (!UseLargePages) return;31553156// print a warning if any large page related flag is specified on command line3157bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||3158!FLAG_IS_DEFAULT(LargePageSizeInBytes);3159bool success = false;31603161# define WARN(msg) if (warn_on_failure) { warning(msg); }3162if (resolve_functions_for_large_page_init()) {3163if (request_lock_memory_privilege()) {3164size_t s = os::Kernel32Dll::GetLargePageMinimum();3165if (s) {3166#if defined(IA32) || defined(AMD64)3167if (s > 4*M || LargePageSizeInBytes > 4*M) {3168WARN("JVM cannot use large pages bigger than 4mb.");3169} else {3170#endif3171if (LargePageSizeInBytes && LargePageSizeInBytes % s == 0) {3172_large_page_size = LargePageSizeInBytes;3173} else {3174_large_page_size = s;3175}3176success = true;3177#if defined(IA32) || defined(AMD64)3178}3179#endif3180} else {3181WARN("Large page is not supported by the processor.");3182}3183} else {3184WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory.");3185}3186} else {3187WARN("Large page is not supported by the operating system.");3188}3189#undef WARN31903191const size_t default_page_size = (size_t) vm_page_size();3192if (success && _large_page_size > default_page_size) {3193_page_sizes[0] = _large_page_size;3194_page_sizes[1] = default_page_size;3195_page_sizes[2] = 0;3196}31973198cleanup_after_large_page_init();3199UseLargePages = success;3200}32013202// On win32, one cannot release just a part of reserved memory, it's an3203// all or nothing deal. When we split a reservation, we must break the3204// reservation into two reservations.3205void os::pd_split_reserved_memory(char *base, size_t size, size_t split,3206bool realloc) {3207if (size > 0) {3208release_memory(base, size);3209if (realloc) {3210reserve_memory(split, base);3211}3212if (size != split) {3213reserve_memory(size - split, base + split);3214}3215}3216}32173218// Multiple threads can race in this code but it's not possible to unmap small sections of3219// virtual space to get requested alignment, like posix-like os's.3220// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.3221char* os::reserve_memory_aligned(size_t size, size_t alignment) {3222assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,3223"Alignment must be a multiple of allocation granularity (page size)");3224assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");32253226size_t extra_size = size + alignment;3227assert(extra_size >= size, "overflow, size is too large to allow alignment");32283229char* aligned_base = NULL;32303231do {3232char* extra_base = os::reserve_memory(extra_size, NULL, alignment);3233if (extra_base == NULL) {3234return NULL;3235}3236// Do manual alignment3237aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);32383239os::release_memory(extra_base, extra_size);32403241aligned_base = os::reserve_memory(size, aligned_base);32423243} while (aligned_base == NULL);32443245return aligned_base;3246}32473248char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {3249assert((size_t)addr % os::vm_allocation_granularity() == 0,3250"reserve alignment");3251assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");3252char* res;3253// note that if UseLargePages is on, all the areas that require interleaving3254// will go thru reserve_memory_special rather than thru here.3255bool use_individual = (UseNUMAInterleaving && !UseLargePages);3256if (!use_individual) {3257res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);3258} else {3259elapsedTimer reserveTimer;3260if( Verbose && PrintMiscellaneous ) reserveTimer.start();3261// in numa interleaving, we have to allocate pages individually3262// (well really chunks of NUMAInterleaveGranularity size)3263res = allocate_pages_individually(bytes, addr, MEM_RESERVE, PAGE_READWRITE);3264if (res == NULL) {3265warning("NUMA page allocation failed");3266}3267if( Verbose && PrintMiscellaneous ) {3268reserveTimer.stop();3269tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,3270reserveTimer.milliseconds(), reserveTimer.ticks());3271}3272}3273assert(res == NULL || addr == NULL || addr == res,3274"Unexpected address from reserve.");32753276return res;3277}32783279// Reserve memory at an arbitrary address, only if that area is3280// available (and not reserved for something else).3281char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {3282// Windows os::reserve_memory() fails of the requested address range is3283// not avilable.3284return reserve_memory(bytes, requested_addr);3285}32863287size_t os::large_page_size() {3288return _large_page_size;3289}32903291bool os::can_commit_large_page_memory() {3292// Windows only uses large page memory when the entire region is reserved3293// and committed in a single VirtualAlloc() call. This may change in the3294// future, but with Windows 2003 it's not possible to commit on demand.3295return false;3296}32973298bool os::can_execute_large_page_memory() {3299return true;3300}33013302char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, bool exec) {3303assert(UseLargePages, "only for large pages");33043305if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {3306return NULL; // Fallback to small pages.3307}33083309const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;3310const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;33113312// with large pages, there are two cases where we need to use Individual Allocation3313// 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)3314// 2) NUMA Interleaving is enabled, in which case we use a different node for each page3315if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {3316if (TracePageSizes && Verbose) {3317tty->print_cr("Reserving large pages individually.");3318}3319char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);3320if (p_buf == NULL) {3321// give an appropriate warning message3322if (UseNUMAInterleaving) {3323warning("NUMA large page allocation failed, UseLargePages flag ignored");3324}3325if (UseLargePagesIndividualAllocation) {3326warning("Individually allocated large pages failed, "3327"use -XX:-UseLargePagesIndividualAllocation to turn off");3328}3329return NULL;3330}33313332return p_buf;33333334} else {3335if (TracePageSizes && Verbose) {3336tty->print_cr("Reserving large pages in a single large chunk.");3337}3338// normal policy just allocate it all at once3339DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;3340char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);3341if (res != NULL) {3342MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, CALLER_PC);3343}33443345return res;3346}3347}33483349bool os::release_memory_special(char* base, size_t bytes) {3350assert(base != NULL, "Sanity check");3351return release_memory(base, bytes);3352}33533354void os::print_statistics() {3355}33563357static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) {3358int err = os::get_last_error();3359char buf[256];3360size_t buf_len = os::lasterror(buf, sizeof(buf));3361warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT3362", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes,3363exec, buf_len != 0 ? buf : "<no_error_string>", err);3364}33653366bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {3367if (bytes == 0) {3368// Don't bother the OS with noops.3369return true;3370}3371assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");3372assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");3373// Don't attempt to print anything if the OS call fails. We're3374// probably low on resources, so the print itself may cause crashes.33753376// unless we have NUMAInterleaving enabled, the range of a commit3377// is always within a reserve covered by a single VirtualAlloc3378// in that case we can just do a single commit for the requested size3379if (!UseNUMAInterleaving) {3380if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) {3381NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)3382return false;3383}3384if (exec) {3385DWORD oldprot;3386// Windows doc says to use VirtualProtect to get execute permissions3387if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) {3388NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)3389return false;3390}3391}3392return true;3393} else {33943395// when NUMAInterleaving is enabled, the commit might cover a range that3396// came from multiple VirtualAlloc reserves (using allocate_pages_individually).3397// VirtualQuery can help us determine that. The RegionSize that VirtualQuery3398// returns represents the number of bytes that can be committed in one step.3399size_t bytes_remaining = bytes;3400char * next_alloc_addr = addr;3401while (bytes_remaining > 0) {3402MEMORY_BASIC_INFORMATION alloc_info;3403VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));3404size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);3405if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT,3406PAGE_READWRITE) == NULL) {3407NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,3408exec);)3409return false;3410}3411if (exec) {3412DWORD oldprot;3413if (!VirtualProtect(next_alloc_addr, bytes_to_rq,3414PAGE_EXECUTE_READWRITE, &oldprot)) {3415NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,3416exec);)3417return false;3418}3419}3420bytes_remaining -= bytes_to_rq;3421next_alloc_addr += bytes_to_rq;3422}3423}3424// if we made it this far, return true3425return true;3426}34273428bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,3429bool exec) {3430// alignment_hint is ignored on this OS3431return pd_commit_memory(addr, size, exec);3432}34333434void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,3435const char* mesg) {3436assert(mesg != NULL, "mesg must be specified");3437if (!pd_commit_memory(addr, size, exec)) {3438warn_fail_commit_memory(addr, size, exec);3439vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);3440}3441}34423443void os::pd_commit_memory_or_exit(char* addr, size_t size,3444size_t alignment_hint, bool exec,3445const char* mesg) {3446// alignment_hint is ignored on this OS3447pd_commit_memory_or_exit(addr, size, exec, mesg);3448}34493450bool os::pd_uncommit_memory(char* addr, size_t bytes) {3451if (bytes == 0) {3452// Don't bother the OS with noops.3453return true;3454}3455assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");3456assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");3457return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);3458}34593460bool os::pd_release_memory(char* addr, size_t bytes) {3461return VirtualFree(addr, 0, MEM_RELEASE) != 0;3462}34633464bool os::pd_create_stack_guard_pages(char* addr, size_t size) {3465return os::commit_memory(addr, size, !ExecMem);3466}34673468bool os::remove_stack_guard_pages(char* addr, size_t size) {3469return os::uncommit_memory(addr, size);3470}34713472// Set protections specified3473bool os::protect_memory(char* addr, size_t bytes, ProtType prot,3474bool is_committed) {3475unsigned int p = 0;3476switch (prot) {3477case MEM_PROT_NONE: p = PAGE_NOACCESS; break;3478case MEM_PROT_READ: p = PAGE_READONLY; break;3479case MEM_PROT_RW: p = PAGE_READWRITE; break;3480case MEM_PROT_RWX: p = PAGE_EXECUTE_READWRITE; break;3481default:3482ShouldNotReachHere();3483}34843485DWORD old_status;34863487// Strange enough, but on Win32 one can change protection only for committed3488// memory, not a big deal anyway, as bytes less or equal than 64K3489if (!is_committed) {3490commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,3491"cannot commit protection page");3492}3493// One cannot use os::guard_memory() here, as on Win32 guard page3494// have different (one-shot) semantics, from MSDN on PAGE_GUARD:3495//3496// Pages in the region become guard pages. Any attempt to access a guard page3497// causes the system to raise a STATUS_GUARD_PAGE exception and turn off3498// the guard page status. Guard pages thus act as a one-time access alarm.3499return VirtualProtect(addr, bytes, p, &old_status) != 0;3500}35013502bool os::guard_memory(char* addr, size_t bytes) {3503DWORD old_status;3504return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;3505}35063507bool os::unguard_memory(char* addr, size_t bytes) {3508DWORD old_status;3509return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;3510}35113512void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }3513void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }3514void os::numa_make_global(char *addr, size_t bytes) { }3515void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { }3516bool os::numa_topology_changed() { return false; }3517size_t os::numa_get_groups_num() { return MAX2(numa_node_list_holder.get_count(), 1); }3518int os::numa_get_group_id() { return 0; }3519size_t os::numa_get_leaf_groups(int *ids, size_t size) {3520if (numa_node_list_holder.get_count() == 0 && size > 0) {3521// Provide an answer for UMA systems3522ids[0] = 0;3523return 1;3524} else {3525// check for size bigger than actual groups_num3526size = MIN2(size, numa_get_groups_num());3527for (int i = 0; i < (int)size; i++) {3528ids[i] = numa_node_list_holder.get_node_list_entry(i);3529}3530return size;3531}3532}35333534bool os::get_page_info(char *start, page_info* info) {3535return false;3536}35373538char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {3539return end;3540}35413542char* os::non_memory_address_word() {3543// Must never look like an address returned by reserve_memory,3544// even in its subfields (as defined by the CPU immediate fields,3545// if the CPU splits constants across multiple instructions).3546return (char*)-1;3547}35483549#define MAX_ERROR_COUNT 1003550#define SYS_THREAD_ERROR 0xffffffffUL35513552void os::pd_start_thread(Thread* thread) {3553DWORD ret = ResumeThread(thread->osthread()->thread_handle());3554// Returns previous suspend state:3555// 0: Thread was not suspended3556// 1: Thread is running now3557// >1: Thread is still suspended.3558assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back3559}35603561class HighResolutionInterval : public CHeapObj<mtThread> {3562// The default timer resolution seems to be 10 milliseconds.3563// (Where is this written down?)3564// If someone wants to sleep for only a fraction of the default,3565// then we set the timer resolution down to 1 millisecond for3566// the duration of their interval.3567// We carefully set the resolution back, since otherwise we3568// seem to incur an overhead (3%?) that we don't need.3569// CONSIDER: if ms is small, say 3, then we should run with a high resolution time.3570// Buf if ms is large, say 500, or 503, we should avoid the call to timeBeginPeriod().3571// Alternatively, we could compute the relative error (503/500 = .6%) and only use3572// timeBeginPeriod() if the relative error exceeded some threshold.3573// timeBeginPeriod() has been linked to problems with clock drift on win32 systems and3574// to decreased efficiency related to increased timer "tick" rates. We want to minimize3575// (a) calls to timeBeginPeriod() and timeEndPeriod() and (b) time spent with high3576// resolution timers running.3577private:3578jlong resolution;3579public:3580HighResolutionInterval(jlong ms) {3581resolution = ms % 10L;3582if (resolution != 0) {3583MMRESULT result = timeBeginPeriod(1L);3584}3585}3586~HighResolutionInterval() {3587if (resolution != 0) {3588MMRESULT result = timeEndPeriod(1L);3589}3590resolution = 0L;3591}3592};35933594int os::sleep(Thread* thread, jlong ms, bool interruptable) {3595jlong limit = (jlong) MAXDWORD;35963597while(ms > limit) {3598int res;3599if ((res = sleep(thread, limit, interruptable)) != OS_TIMEOUT)3600return res;3601ms -= limit;3602}36033604assert(thread == Thread::current(), "thread consistency check");3605OSThread* osthread = thread->osthread();3606OSThreadWaitState osts(osthread, false /* not Object.wait() */);3607int result;3608if (interruptable) {3609assert(thread->is_Java_thread(), "must be java thread");3610JavaThread *jt = (JavaThread *) thread;3611ThreadBlockInVM tbivm(jt);36123613jt->set_suspend_equivalent();3614// cleared by handle_special_suspend_equivalent_condition() or3615// java_suspend_self() via check_and_wait_while_suspended()36163617HANDLE events[1];3618events[0] = osthread->interrupt_event();3619HighResolutionInterval *phri=NULL;3620if(!ForceTimeHighResolution)3621phri = new HighResolutionInterval( ms );3622if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) {3623result = OS_TIMEOUT;3624} else {3625ResetEvent(osthread->interrupt_event());3626osthread->set_interrupted(false);3627result = OS_INTRPT;3628}3629delete phri; //if it is NULL, harmless36303631// were we externally suspended while we were waiting?3632jt->check_and_wait_while_suspended();3633} else {3634assert(!thread->is_Java_thread(), "must not be java thread");3635Sleep((long) ms);3636result = OS_TIMEOUT;3637}3638return result;3639}36403641//3642// Short sleep, direct OS call.3643//3644// ms = 0, means allow others (if any) to run.3645//3646void os::naked_short_sleep(jlong ms) {3647assert(ms < 1000, "Un-interruptable sleep, short time use only");3648Sleep(ms);3649}36503651// Sleep forever; naked call to OS-specific sleep; use with CAUTION3652void os::infinite_sleep() {3653while (true) { // sleep forever ...3654Sleep(100000); // ... 100 seconds at a time3655}3656}36573658typedef BOOL (WINAPI * STTSignature)(void) ;36593660os::YieldResult os::NakedYield() {3661// Use either SwitchToThread() or Sleep(0)3662// Consider passing back the return value from SwitchToThread().3663if (os::Kernel32Dll::SwitchToThreadAvailable()) {3664return SwitchToThread() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;3665} else {3666Sleep(0);3667}3668return os::YIELD_UNKNOWN ;3669}36703671void os::yield() { os::NakedYield(); }36723673void os::yield_all(int attempts) {3674// Yields to all threads, including threads with lower priorities3675Sleep(1);3676}36773678// Win32 only gives you access to seven real priorities at a time,3679// so we compress Java's ten down to seven. It would be better3680// if we dynamically adjusted relative priorities.36813682int os::java_to_os_priority[CriticalPriority + 1] = {3683THREAD_PRIORITY_IDLE, // 0 Entry should never be used3684THREAD_PRIORITY_LOWEST, // 1 MinPriority3685THREAD_PRIORITY_LOWEST, // 23686THREAD_PRIORITY_BELOW_NORMAL, // 33687THREAD_PRIORITY_BELOW_NORMAL, // 43688THREAD_PRIORITY_NORMAL, // 5 NormPriority3689THREAD_PRIORITY_NORMAL, // 63690THREAD_PRIORITY_ABOVE_NORMAL, // 73691THREAD_PRIORITY_ABOVE_NORMAL, // 83692THREAD_PRIORITY_HIGHEST, // 9 NearMaxPriority3693THREAD_PRIORITY_HIGHEST, // 10 MaxPriority3694THREAD_PRIORITY_HIGHEST // 11 CriticalPriority3695};36963697int prio_policy1[CriticalPriority + 1] = {3698THREAD_PRIORITY_IDLE, // 0 Entry should never be used3699THREAD_PRIORITY_LOWEST, // 1 MinPriority3700THREAD_PRIORITY_LOWEST, // 23701THREAD_PRIORITY_BELOW_NORMAL, // 33702THREAD_PRIORITY_BELOW_NORMAL, // 43703THREAD_PRIORITY_NORMAL, // 5 NormPriority3704THREAD_PRIORITY_ABOVE_NORMAL, // 63705THREAD_PRIORITY_ABOVE_NORMAL, // 73706THREAD_PRIORITY_HIGHEST, // 83707THREAD_PRIORITY_HIGHEST, // 9 NearMaxPriority3708THREAD_PRIORITY_TIME_CRITICAL, // 10 MaxPriority3709THREAD_PRIORITY_TIME_CRITICAL // 11 CriticalPriority3710};37113712static int prio_init() {3713// If ThreadPriorityPolicy is 1, switch tables3714if (ThreadPriorityPolicy == 1) {3715int i;3716for (i = 0; i < CriticalPriority + 1; i++) {3717os::java_to_os_priority[i] = prio_policy1[i];3718}3719}3720if (UseCriticalJavaThreadPriority) {3721os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority] ;3722}3723return 0;3724}37253726OSReturn os::set_native_priority(Thread* thread, int priority) {3727if (!UseThreadPriorities) return OS_OK;3728bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0;3729return ret ? OS_OK : OS_ERR;3730}37313732OSReturn os::get_native_priority(const Thread* const thread, int* priority_ptr) {3733if ( !UseThreadPriorities ) {3734*priority_ptr = java_to_os_priority[NormPriority];3735return OS_OK;3736}3737int os_prio = GetThreadPriority(thread->osthread()->thread_handle());3738if (os_prio == THREAD_PRIORITY_ERROR_RETURN) {3739assert(false, "GetThreadPriority failed");3740return OS_ERR;3741}3742*priority_ptr = os_prio;3743return OS_OK;3744}374537463747// Hint to the underlying OS that a task switch would not be good.3748// Void return because it's a hint and can fail.3749void os::hint_no_preempt() {}37503751void os::interrupt(Thread* thread) {3752assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),3753"possibility of dangling Thread pointer");37543755OSThread* osthread = thread->osthread();3756osthread->set_interrupted(true);3757// More than one thread can get here with the same value of osthread,3758// resulting in multiple notifications. We do, however, want the store3759// to interrupted() to be visible to other threads before we post3760// the interrupt event.3761OrderAccess::release();3762SetEvent(osthread->interrupt_event());3763// For JSR166: unpark after setting status3764if (thread->is_Java_thread())3765((JavaThread*)thread)->parker()->unpark();37663767ParkEvent * ev = thread->_ParkEvent ;3768if (ev != NULL) ev->unpark() ;37693770}377137723773bool os::is_interrupted(Thread* thread, bool clear_interrupted) {3774assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),3775"possibility of dangling Thread pointer");37763777OSThread* osthread = thread->osthread();3778// There is no synchronization between the setting of the interrupt3779// and it being cleared here. It is critical - see 6535709 - that3780// we only clear the interrupt state, and reset the interrupt event,3781// if we are going to report that we were indeed interrupted - else3782// an interrupt can be "lost", leading to spurious wakeups or lost wakeups3783// depending on the timing. By checking thread interrupt event to see3784// if the thread gets real interrupt thus prevent spurious wakeup.3785bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0);3786if (interrupted && clear_interrupted) {3787osthread->set_interrupted(false);3788ResetEvent(osthread->interrupt_event());3789} // Otherwise leave the interrupted state alone37903791return interrupted;3792}37933794// Get's a pc (hint) for a running thread. Currently used only for profiling.3795ExtendedPC os::get_thread_pc(Thread* thread) {3796CONTEXT context;3797context.ContextFlags = CONTEXT_CONTROL;3798HANDLE handle = thread->osthread()->thread_handle();3799#ifdef _M_IA643800assert(0, "Fix get_thread_pc");3801return ExtendedPC(NULL);3802#else3803if (GetThreadContext(handle, &context)) {3804#ifdef _M_AMD643805return ExtendedPC((address) context.Rip);3806#else3807return ExtendedPC((address) context.Eip);3808#endif3809} else {3810return ExtendedPC(NULL);3811}3812#endif3813}38143815// GetCurrentThreadId() returns DWORD3816intx os::current_thread_id() { return GetCurrentThreadId(); }38173818static int _initial_pid = 0;38193820int os::current_process_id()3821{3822return (_initial_pid ? _initial_pid : _getpid());3823}38243825int os::win32::_vm_page_size = 0;3826int os::win32::_vm_allocation_granularity = 0;3827int os::win32::_processor_type = 0;3828// Processor level is not available on non-NT systems, use vm_version instead3829int os::win32::_processor_level = 0;3830julong os::win32::_physical_memory = 0;3831size_t os::win32::_default_stack_size = 0;38323833intx os::win32::_os_thread_limit = 0;3834volatile intx os::win32::_os_thread_count = 0;38353836bool os::win32::_is_nt = false;3837bool os::win32::_is_windows_2003 = false;3838bool os::win32::_is_windows_server = false;38393840void os::win32::initialize_system_info() {3841SYSTEM_INFO si;3842GetSystemInfo(&si);3843_vm_page_size = si.dwPageSize;3844_vm_allocation_granularity = si.dwAllocationGranularity;3845_processor_type = si.dwProcessorType;3846_processor_level = si.wProcessorLevel;3847set_processor_count(si.dwNumberOfProcessors);38483849MEMORYSTATUSEX ms;3850ms.dwLength = sizeof(ms);38513852// also returns dwAvailPhys (free physical memory bytes), dwTotalVirtual, dwAvailVirtual,3853// dwMemoryLoad (% of memory in use)3854GlobalMemoryStatusEx(&ms);3855_physical_memory = ms.ullTotalPhys;38563857OSVERSIONINFOEX oi;3858oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);3859GetVersionEx((OSVERSIONINFO*)&oi);3860switch(oi.dwPlatformId) {3861case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break;3862case VER_PLATFORM_WIN32_NT:3863_is_nt = true;3864{3865int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;3866if (os_vers == 5002) {3867_is_windows_2003 = true;3868}3869if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER ||3870oi.wProductType == VER_NT_SERVER) {3871_is_windows_server = true;3872}3873}3874break;3875default: fatal("Unknown platform");3876}38773878_default_stack_size = os::current_stack_size();3879assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");3880assert((_default_stack_size & (_vm_page_size - 1)) == 0,3881"stack size not a multiple of page size");38823883initialize_performance_counter();38843885// Win95/Win98 scheduler bug work-around. The Win95/98 scheduler is3886// known to deadlock the system, if the VM issues to thread operations with3887// a too high frequency, e.g., such as changing the priorities.3888// The 6000 seems to work well - no deadlocks has been notices on the test3889// programs that we have seen experience this problem.3890if (!os::win32::is_nt()) {3891StarvationMonitorInterval = 6000;3892}3893}389438953896HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf, int ebuflen) {3897char path[MAX_PATH];3898DWORD size;3899DWORD pathLen = (DWORD)sizeof(path);3900HINSTANCE result = NULL;39013902// only allow library name without path component3903assert(strchr(name, '\\') == NULL, "path not allowed");3904assert(strchr(name, ':') == NULL, "path not allowed");3905if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) {3906jio_snprintf(ebuf, ebuflen,3907"Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name);3908return NULL;3909}39103911// search system directory3912if ((size = GetSystemDirectory(path, pathLen)) > 0) {3913strcat(path, "\\");3914strcat(path, name);3915if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {3916return result;3917}3918}39193920// try Windows directory3921if ((size = GetWindowsDirectory(path, pathLen)) > 0) {3922strcat(path, "\\");3923strcat(path, name);3924if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {3925return result;3926}3927}39283929jio_snprintf(ebuf, ebuflen,3930"os::win32::load_windows_dll() cannot load %s from system directories.", name);3931return NULL;3932}39333934void os::win32::setmode_streams() {3935_setmode(_fileno(stdin), _O_BINARY);3936_setmode(_fileno(stdout), _O_BINARY);3937_setmode(_fileno(stderr), _O_BINARY);3938}393939403941bool os::is_debugger_attached() {3942return IsDebuggerPresent() ? true : false;3943}394439453946void os::wait_for_keypress_at_exit(void) {3947if (PauseAtExit) {3948fprintf(stderr, "Press any key to continue...\n");3949fgetc(stdin);3950}3951}395239533954int os::message_box(const char* title, const char* message) {3955int result = MessageBox(NULL, message, title,3956MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);3957return result == IDYES;3958}39593960int os::allocate_thread_local_storage() {3961return TlsAlloc();3962}396339643965void os::free_thread_local_storage(int index) {3966TlsFree(index);3967}396839693970void os::thread_local_storage_at_put(int index, void* value) {3971TlsSetValue(index, value);3972assert(thread_local_storage_at(index) == value, "Just checking");3973}397439753976void* os::thread_local_storage_at(int index) {3977return TlsGetValue(index);3978}397939803981#ifndef PRODUCT3982#ifndef _WIN643983// Helpers to check whether NX protection is enabled3984int nx_exception_filter(_EXCEPTION_POINTERS *pex) {3985if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&3986pex->ExceptionRecord->NumberParameters > 0 &&3987pex->ExceptionRecord->ExceptionInformation[0] ==3988EXCEPTION_INFO_EXEC_VIOLATION) {3989return EXCEPTION_EXECUTE_HANDLER;3990}3991return EXCEPTION_CONTINUE_SEARCH;3992}39933994void nx_check_protection() {3995// If NX is enabled we'll get an exception calling into code on the stack3996char code[] = { (char)0xC3 }; // ret3997void *code_ptr = (void *)code;3998__try {3999__asm call code_ptr4000} __except(nx_exception_filter((_EXCEPTION_POINTERS*)_exception_info())) {4001tty->print_raw_cr("NX protection detected.");4002}4003}4004#endif // _WIN644005#endif // PRODUCT40064007// this is called _before_ the global arguments have been parsed4008void os::init(void) {4009_initial_pid = _getpid();40104011init_random(1234567);40124013win32::initialize_system_info();4014win32::setmode_streams();4015init_page_sizes((size_t) win32::vm_page_size());40164017// For better scalability on MP systems (must be called after initialize_system_info)4018#ifndef PRODUCT4019if (is_MP()) {4020NoYieldsInMicrolock = true;4021}4022#endif4023// This may be overridden later when argument processing is done.4024FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation,4025os::win32::is_windows_2003());40264027// Initialize main_process and main_thread4028main_process = GetCurrentProcess(); // Remember main_process is a pseudo handle4029if (!DuplicateHandle(main_process, GetCurrentThread(), main_process,4030&main_thread, THREAD_ALL_ACCESS, false, 0)) {4031fatal("DuplicateHandle failed\n");4032}4033main_thread_id = (int) GetCurrentThreadId();4034}40354036// To install functions for atexit processing4037extern "C" {4038static void perfMemory_exit_helper() {4039perfMemory_exit();4040}4041}40424043static jint initSock();40444045// this is called _after_ the global arguments have been parsed4046jint os::init_2(void) {4047// Allocate a single page and mark it as readable for safepoint polling4048address polling_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READONLY);4049guarantee( polling_page != NULL, "Reserve Failed for polling page");40504051address return_page = (address)VirtualAlloc(polling_page, os::vm_page_size(), MEM_COMMIT, PAGE_READONLY);4052guarantee( return_page != NULL, "Commit Failed for polling page");40534054os::set_polling_page( polling_page );40554056#ifndef PRODUCT4057if( Verbose && PrintMiscellaneous )4058tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);4059#endif40604061if (!UseMembar) {4062address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE);4063guarantee( mem_serialize_page != NULL, "Reserve Failed for memory serialize page");40644065return_page = (address)VirtualAlloc(mem_serialize_page, os::vm_page_size(), MEM_COMMIT, PAGE_READWRITE);4066guarantee( return_page != NULL, "Commit Failed for memory serialize page");40674068os::set_memory_serialize_page( mem_serialize_page );40694070#ifndef PRODUCT4071if(Verbose && PrintMiscellaneous)4072tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);4073#endif4074}40754076// Setup Windows Exceptions40774078// for debugging float code generation bugs4079if (ForceFloatExceptions) {4080#ifndef _WIN644081static long fp_control_word = 0;4082__asm { fstcw fp_control_word }4083// see Intel PPro Manual, Vol. 2, p 7-164084const long precision = 0x20;4085const long underflow = 0x10;4086const long overflow = 0x08;4087const long zero_div = 0x04;4088const long denorm = 0x02;4089const long invalid = 0x01;4090fp_control_word |= invalid;4091__asm { fldcw fp_control_word }4092#endif4093}40944095// If stack_commit_size is 0, windows will reserve the default size,4096// but only commit a small portion of it.4097size_t stack_commit_size = round_to(ThreadStackSize*K, os::vm_page_size());4098size_t default_reserve_size = os::win32::default_stack_size();4099size_t actual_reserve_size = stack_commit_size;4100if (stack_commit_size < default_reserve_size) {4101// If stack_commit_size == 0, we want this too4102actual_reserve_size = default_reserve_size;4103}41044105// Check minimum allowable stack size for thread creation and to initialize4106// the java system classes, including StackOverflowError - depends on page4107// size. Add a page for compiler2 recursion in main thread.4108// Add in 2*BytesPerWord times page size to account for VM stack during4109// class initialization depending on 32 or 64 bit VM.4110size_t min_stack_allowed =4111(size_t)(StackYellowPages+StackRedPages+StackShadowPages+41122*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size();4113if (actual_reserve_size < min_stack_allowed) {4114tty->print_cr("\nThe stack size specified is too small, "4115"Specify at least %dk",4116min_stack_allowed / K);4117return JNI_ERR;4118}41194120JavaThread::set_stack_size_at_create(stack_commit_size);41214122// Calculate theoretical max. size of Threads to guard gainst artifical4123// out-of-memory situations, where all available address-space has been4124// reserved by thread stacks.4125assert(actual_reserve_size != 0, "Must have a stack");41264127// Calculate the thread limit when we should start doing Virtual Memory4128// banging. Currently when the threads will have used all but 200Mb of space.4129//4130// TODO: consider performing a similar calculation for commit size instead4131// as reserve size, since on a 64-bit platform we'll run into that more4132// often than running out of virtual memory space. We can use the4133// lower value of the two calculations as the os_thread_limit.4134size_t max_address_space = ((size_t)1 << (BitsPerWord - 1)) - (200 * K * K);4135win32::_os_thread_limit = (intx)(max_address_space / actual_reserve_size);41364137// at exit methods are called in the reverse order of their registration.4138// there is no limit to the number of functions registered. atexit does4139// not set errno.41404141if (PerfAllowAtExitRegistration) {4142// only register atexit functions if PerfAllowAtExitRegistration is set.4143// atexit functions can be delayed until process exit time, which4144// can be problematic for embedded VM situations. Embedded VMs should4145// call DestroyJavaVM() to assure that VM resources are released.41464147// note: perfMemory_exit_helper atexit function may be removed in4148// the future if the appropriate cleanup code can be added to the4149// VM_Exit VMOperation's doit method.4150if (atexit(perfMemory_exit_helper) != 0) {4151warning("os::init_2 atexit(perfMemory_exit_helper) failed");4152}4153}41544155#ifndef _WIN644156// Print something if NX is enabled (win32 on AMD64)4157NOT_PRODUCT(if (PrintMiscellaneous && Verbose) nx_check_protection());4158#endif41594160// initialize thread priority policy4161prio_init();41624163if (UseNUMA && !ForceNUMA) {4164UseNUMA = false; // We don't fully support this yet4165}41664167if (UseNUMAInterleaving) {4168// first check whether this Windows OS supports VirtualAllocExNuma, if not ignore this flag4169bool success = numa_interleaving_init();4170if (!success) UseNUMAInterleaving = false;4171}41724173if (initSock() != JNI_OK) {4174return JNI_ERR;4175}41764177return JNI_OK;4178}41794180// Mark the polling page as unreadable4181void os::make_polling_page_unreadable(void) {4182DWORD old_status;4183if( !VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_NOACCESS, &old_status) )4184fatal("Could not disable polling page");4185};41864187// Mark the polling page as readable4188void os::make_polling_page_readable(void) {4189DWORD old_status;4190if( !VirtualProtect((char *)_polling_page, os::vm_page_size(), PAGE_READONLY, &old_status) )4191fatal("Could not enable polling page");4192};419341944195int os::stat(const char *path, struct stat *sbuf) {4196char pathbuf[MAX_PATH];4197if (strlen(path) > MAX_PATH - 1) {4198errno = ENAMETOOLONG;4199return -1;4200}4201os::native_path(strcpy(pathbuf, path));4202int ret = ::stat(pathbuf, sbuf);4203if (sbuf != NULL && UseUTCFileTimestamp) {4204// Fix for 6539723. st_mtime returned from stat() is dependent on4205// the system timezone and so can return different values for the4206// same file if/when daylight savings time changes. This adjustment4207// makes sure the same timestamp is returned regardless of the TZ.4208//4209// See:4210// http://msdn.microsoft.com/library/4211// default.asp?url=/library/en-us/sysinfo/base/4212// time_zone_information_str.asp4213// and4214// http://msdn.microsoft.com/library/default.asp?url=4215// /library/en-us/sysinfo/base/settimezoneinformation.asp4216//4217// NOTE: there is a insidious bug here: If the timezone is changed4218// after the call to stat() but before 'GetTimeZoneInformation()', then4219// the adjustment we do here will be wrong and we'll return the wrong4220// value (which will likely end up creating an invalid class data4221// archive). Absent a better API for this, or some time zone locking4222// mechanism, we'll have to live with this risk.4223TIME_ZONE_INFORMATION tz;4224DWORD tzid = GetTimeZoneInformation(&tz);4225int daylightBias =4226(tzid == TIME_ZONE_ID_DAYLIGHT) ? tz.DaylightBias : tz.StandardBias;4227sbuf->st_mtime += (tz.Bias + daylightBias) * 60;4228}4229return ret;4230}423142324233#define FT2INT64(ft) \4234((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))423542364237// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)4238// are used by JVM M&M and JVMTI to get user+sys or user CPU time4239// of a thread.4240//4241// current_thread_cpu_time() and thread_cpu_time(Thread*) returns4242// the fast estimate available on the platform.42434244// current_thread_cpu_time() is not optimized for Windows yet4245jlong os::current_thread_cpu_time() {4246// return user + sys since the cost is the same4247return os::thread_cpu_time(Thread::current(), true /* user+sys */);4248}42494250jlong os::thread_cpu_time(Thread* thread) {4251// consistent with what current_thread_cpu_time() returns.4252return os::thread_cpu_time(thread, true /* user+sys */);4253}42544255jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {4256return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);4257}42584259jlong os::thread_cpu_time(Thread* thread, bool user_sys_cpu_time) {4260// This code is copy from clasic VM -> hpi::sysThreadCPUTime4261// If this function changes, os::is_thread_cpu_time_supported() should too4262if (os::win32::is_nt()) {4263FILETIME CreationTime;4264FILETIME ExitTime;4265FILETIME KernelTime;4266FILETIME UserTime;42674268if ( GetThreadTimes(thread->osthread()->thread_handle(),4269&CreationTime, &ExitTime, &KernelTime, &UserTime) == 0)4270return -1;4271else4272if (user_sys_cpu_time) {4273return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100;4274} else {4275return FT2INT64(UserTime) * 100;4276}4277} else {4278return (jlong) timeGetTime() * 1000000;4279}4280}42814282void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {4283info_ptr->max_value = ALL_64_BITS; // the max value -- all 64 bits4284info_ptr->may_skip_backward = false; // GetThreadTimes returns absolute time4285info_ptr->may_skip_forward = false; // GetThreadTimes returns absolute time4286info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned4287}42884289void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {4290info_ptr->max_value = ALL_64_BITS; // the max value -- all 64 bits4291info_ptr->may_skip_backward = false; // GetThreadTimes returns absolute time4292info_ptr->may_skip_forward = false; // GetThreadTimes returns absolute time4293info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned4294}42954296bool os::is_thread_cpu_time_supported() {4297// see os::thread_cpu_time4298if (os::win32::is_nt()) {4299FILETIME CreationTime;4300FILETIME ExitTime;4301FILETIME KernelTime;4302FILETIME UserTime;43034304if ( GetThreadTimes(GetCurrentThread(),4305&CreationTime, &ExitTime, &KernelTime, &UserTime) == 0)4306return false;4307else4308return true;4309} else {4310return false;4311}4312}43134314// Windows does't provide a loadavg primitive so this is stubbed out for now.4315// It does have primitives (PDH API) to get CPU usage and run queue length.4316// "\\Processor(_Total)\\% Processor Time", "\\System\\Processor Queue Length"4317// If we wanted to implement loadavg on Windows, we have a few options:4318//4319// a) Query CPU usage and run queue length and "fake" an answer by4320// returning the CPU usage if it's under 100%, and the run queue4321// length otherwise. It turns out that querying is pretty slow4322// on Windows, on the order of 200 microseconds on a fast machine.4323// Note that on the Windows the CPU usage value is the % usage4324// since the last time the API was called (and the first call4325// returns 100%), so we'd have to deal with that as well.4326//4327// b) Sample the "fake" answer using a sampling thread and store4328// the answer in a global variable. The call to loadavg would4329// just return the value of the global, avoiding the slow query.4330//4331// c) Sample a better answer using exponential decay to smooth the4332// value. This is basically the algorithm used by UNIX kernels.4333//4334// Note that sampling thread starvation could affect both (b) and (c).4335int os::loadavg(double loadavg[], int nelem) {4336return -1;4337}433843394340// DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield()4341bool os::dont_yield() {4342return DontYieldALot;4343}43444345// This method is a slightly reworked copy of JDK's sysOpen4346// from src/windows/hpi/src/sys_api_md.c43474348int os::open(const char *path, int oflag, int mode) {4349char pathbuf[MAX_PATH];43504351if (strlen(path) > MAX_PATH - 1) {4352errno = ENAMETOOLONG;4353return -1;4354}4355os::native_path(strcpy(pathbuf, path));4356return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);4357}43584359FILE* os::open(int fd, const char* mode) {4360return ::_fdopen(fd, mode);4361}43624363// Is a (classpath) directory empty?4364bool os::dir_is_empty(const char* path) {4365WIN32_FIND_DATA fd;4366HANDLE f = FindFirstFile(path, &fd);4367if (f == INVALID_HANDLE_VALUE) {4368return true;4369}4370FindClose(f);4371return false;4372}43734374// create binary file, rewriting existing file if required4375int os::create_binary_file(const char* path, bool rewrite_existing) {4376int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;4377if (!rewrite_existing) {4378oflags |= _O_EXCL;4379}4380return ::open(path, oflags, _S_IREAD | _S_IWRITE);4381}43824383// return current position of file pointer4384jlong os::current_file_offset(int fd) {4385return (jlong)::_lseeki64(fd, (__int64)0L, SEEK_CUR);4386}43874388// move file pointer to the specified offset4389jlong os::seek_to_file_offset(int fd, jlong offset) {4390return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET);4391}439243934394jlong os::lseek(int fd, jlong offset, int whence) {4395return (jlong) ::_lseeki64(fd, offset, whence);4396}43974398size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {4399OVERLAPPED ov;4400DWORD nread;4401BOOL result;44024403ZeroMemory(&ov, sizeof(ov));4404ov.Offset = (DWORD)offset;4405ov.OffsetHigh = (DWORD)(offset >> 32);44064407HANDLE h = (HANDLE)::_get_osfhandle(fd);44084409result = ReadFile(h, (LPVOID)buf, nBytes, &nread, &ov);44104411return result ? nread : 0;4412}44134414// This method is a slightly reworked copy of JDK's sysNativePath4415// from src/windows/hpi/src/path_md.c44164417/* Convert a pathname to native format. On win32, this involves forcing all4418separators to be '\\' rather than '/' (both are legal inputs, but Win954419sometimes rejects '/') and removing redundant separators. The input path is4420assumed to have been converted into the character encoding used by the local4421system. Because this might be a double-byte encoding, care is taken to4422treat double-byte lead characters correctly.44234424This procedure modifies the given path in place, as the result is never4425longer than the original. There is no error return; this operation always4426succeeds. */4427char * os::native_path(char *path) {4428char *src = path, *dst = path, *end = path;4429char *colon = NULL; /* If a drive specifier is found, this will4430point to the colon following the drive4431letter */44324433/* Assumption: '/', '\\', ':', and drive letters are never lead bytes */4434assert(((!::IsDBCSLeadByte('/'))4435&& (!::IsDBCSLeadByte('\\'))4436&& (!::IsDBCSLeadByte(':'))),4437"Illegal lead byte");44384439/* Check for leading separators */4440#define isfilesep(c) ((c) == '/' || (c) == '\\')4441while (isfilesep(*src)) {4442src++;4443}44444445if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') {4446/* Remove leading separators if followed by drive specifier. This4447hack is necessary to support file URLs containing drive4448specifiers (e.g., "file://c:/path"). As a side effect,4449"/c:/path" can be used as an alternative to "c:/path". */4450*dst++ = *src++;4451colon = dst;4452*dst++ = ':';4453src++;4454} else {4455src = path;4456if (isfilesep(src[0]) && isfilesep(src[1])) {4457/* UNC pathname: Retain first separator; leave src pointed at4458second separator so that further separators will be collapsed4459into the second separator. The result will be a pathname4460beginning with "\\\\" followed (most likely) by a host name. */4461src = dst = path + 1;4462path[0] = '\\'; /* Force first separator to '\\' */4463}4464}44654466end = dst;44674468/* Remove redundant separators from remainder of path, forcing all4469separators to be '\\' rather than '/'. Also, single byte space4470characters are removed from the end of the path because those4471are not legal ending characters on this operating system.4472*/4473while (*src != '\0') {4474if (isfilesep(*src)) {4475*dst++ = '\\'; src++;4476while (isfilesep(*src)) src++;4477if (*src == '\0') {4478/* Check for trailing separator */4479end = dst;4480if (colon == dst - 2) break; /* "z:\\" */4481if (dst == path + 1) break; /* "\\" */4482if (dst == path + 2 && isfilesep(path[0])) {4483/* "\\\\" is not collapsed to "\\" because "\\\\" marks the4484beginning of a UNC pathname. Even though it is not, by4485itself, a valid UNC pathname, we leave it as is in order4486to be consistent with the path canonicalizer as well4487as the win32 APIs, which treat this case as an invalid4488UNC pathname rather than as an alias for the root4489directory of the current drive. */4490break;4491}4492end = --dst; /* Path does not denote a root directory, so4493remove trailing separator */4494break;4495}4496end = dst;4497} else {4498if (::IsDBCSLeadByte(*src)) { /* Copy a double-byte character */4499*dst++ = *src++;4500if (*src) *dst++ = *src++;4501end = dst;4502} else { /* Copy a single-byte character */4503char c = *src++;4504*dst++ = c;4505/* Space is not a legal ending character */4506if (c != ' ') end = dst;4507}4508}4509}45104511*end = '\0';45124513/* For "z:", add "." to work around a bug in the C runtime library */4514if (colon == dst - 1) {4515path[2] = '.';4516path[3] = '\0';4517}45184519return path;4520}45214522// This code is a copy of JDK's sysSetLength4523// from src/windows/hpi/src/sys_api_md.c45244525int os::ftruncate(int fd, jlong length) {4526HANDLE h = (HANDLE)::_get_osfhandle(fd);4527long high = (long)(length >> 32);4528DWORD ret;45294530if (h == (HANDLE)(-1)) {4531return -1;4532}45334534ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN);4535if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) {4536return -1;4537}45384539if (::SetEndOfFile(h) == FALSE) {4540return -1;4541}45424543return 0;4544}454545464547// This code is a copy of JDK's sysSync4548// from src/windows/hpi/src/sys_api_md.c4549// except for the legacy workaround for a bug in Win 9845504551int os::fsync(int fd) {4552HANDLE handle = (HANDLE)::_get_osfhandle(fd);45534554if ( (!::FlushFileBuffers(handle)) &&4555(GetLastError() != ERROR_ACCESS_DENIED) ) {4556/* from winerror.h */4557return -1;4558}4559return 0;4560}45614562static int nonSeekAvailable(int, long *);4563static int stdinAvailable(int, long *);45644565#define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR)4566#define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO)45674568// This code is a copy of JDK's sysAvailable4569// from src/windows/hpi/src/sys_api_md.c45704571int os::available(int fd, jlong *bytes) {4572jlong cur, end;4573struct _stati64 stbuf64;45744575if (::_fstati64(fd, &stbuf64) >= 0) {4576int mode = stbuf64.st_mode;4577if (S_ISCHR(mode) || S_ISFIFO(mode)) {4578int ret;4579long lpbytes;4580if (fd == 0) {4581ret = stdinAvailable(fd, &lpbytes);4582} else {4583ret = nonSeekAvailable(fd, &lpbytes);4584}4585(*bytes) = (jlong)(lpbytes);4586return ret;4587}4588if ((cur = ::_lseeki64(fd, 0L, SEEK_CUR)) == -1) {4589return FALSE;4590} else if ((end = ::_lseeki64(fd, 0L, SEEK_END)) == -1) {4591return FALSE;4592} else if (::_lseeki64(fd, cur, SEEK_SET) == -1) {4593return FALSE;4594}4595*bytes = end - cur;4596return TRUE;4597} else {4598return FALSE;4599}4600}46014602// This code is a copy of JDK's nonSeekAvailable4603// from src/windows/hpi/src/sys_api_md.c46044605static int nonSeekAvailable(int fd, long *pbytes) {4606/* This is used for available on non-seekable devices4607* (like both named and anonymous pipes, such as pipes4608* connected to an exec'd process).4609* Standard Input is a special case.4610*4611*/4612HANDLE han;46134614if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) {4615return FALSE;4616}46174618if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) {4619/* PeekNamedPipe fails when at EOF. In that case we4620* simply make *pbytes = 0 which is consistent with the4621* behavior we get on Solaris when an fd is at EOF.4622* The only alternative is to raise an Exception,4623* which isn't really warranted.4624*/4625if (::GetLastError() != ERROR_BROKEN_PIPE) {4626return FALSE;4627}4628*pbytes = 0;4629}4630return TRUE;4631}46324633#define MAX_INPUT_EVENTS 200046344635// This code is a copy of JDK's stdinAvailable4636// from src/windows/hpi/src/sys_api_md.c46374638static int stdinAvailable(int fd, long *pbytes) {4639HANDLE han;4640DWORD numEventsRead = 0; /* Number of events read from buffer */4641DWORD numEvents = 0; /* Number of events in buffer */4642DWORD i = 0; /* Loop index */4643DWORD curLength = 0; /* Position marker */4644DWORD actualLength = 0; /* Number of bytes readable */4645BOOL error = FALSE; /* Error holder */4646INPUT_RECORD *lpBuffer; /* Pointer to records of input events */46474648if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {4649return FALSE;4650}46514652/* Construct an array of input records in the console buffer */4653error = ::GetNumberOfConsoleInputEvents(han, &numEvents);4654if (error == 0) {4655return nonSeekAvailable(fd, pbytes);4656}46574658/* lpBuffer must fit into 64K or else PeekConsoleInput fails */4659if (numEvents > MAX_INPUT_EVENTS) {4660numEvents = MAX_INPUT_EVENTS;4661}46624663lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal);4664if (lpBuffer == NULL) {4665return FALSE;4666}46674668error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);4669if (error == 0) {4670os::free(lpBuffer, mtInternal);4671return FALSE;4672}46734674/* Examine input records for the number of bytes available */4675for(i=0; i<numEvents; i++) {4676if (lpBuffer[i].EventType == KEY_EVENT) {46774678KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *)4679&(lpBuffer[i].Event);4680if (keyRecord->bKeyDown == TRUE) {4681CHAR *keyPressed = (CHAR *) &(keyRecord->uChar);4682curLength++;4683if (*keyPressed == '\r') {4684actualLength = curLength;4685}4686}4687}4688}46894690if(lpBuffer != NULL) {4691os::free(lpBuffer, mtInternal);4692}46934694*pbytes = (long) actualLength;4695return TRUE;4696}46974698// Map a block of memory.4699char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,4700char *addr, size_t bytes, bool read_only,4701bool allow_exec) {4702HANDLE hFile;4703char* base;47044705hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,4706OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);4707if (hFile == NULL) {4708if (PrintMiscellaneous && Verbose) {4709DWORD err = GetLastError();4710tty->print_cr("CreateFile() failed: GetLastError->%ld.", err);4711}4712return NULL;4713}47144715if (allow_exec) {4716// CreateFileMapping/MapViewOfFileEx can't map executable memory4717// unless it comes from a PE image (which the shared archive is not.)4718// Even VirtualProtect refuses to give execute access to mapped memory4719// that was not previously executable.4720//4721// Instead, stick the executable region in anonymous memory. Yuck.4722// Penalty is that ~4 pages will not be shareable - in the future4723// we might consider DLLizing the shared archive with a proper PE4724// header so that mapping executable + sharing is possible.47254726base = (char*) VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE,4727PAGE_READWRITE);4728if (base == NULL) {4729if (PrintMiscellaneous && Verbose) {4730DWORD err = GetLastError();4731tty->print_cr("VirtualAlloc() failed: GetLastError->%ld.", err);4732}4733CloseHandle(hFile);4734return NULL;4735}47364737DWORD bytes_read;4738OVERLAPPED overlapped;4739overlapped.Offset = (DWORD)file_offset;4740overlapped.OffsetHigh = 0;4741overlapped.hEvent = NULL;4742// ReadFile guarantees that if the return value is true, the requested4743// number of bytes were read before returning.4744bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0;4745if (!res) {4746if (PrintMiscellaneous && Verbose) {4747DWORD err = GetLastError();4748tty->print_cr("ReadFile() failed: GetLastError->%ld.", err);4749}4750release_memory(base, bytes);4751CloseHandle(hFile);4752return NULL;4753}4754} else {4755HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0,4756NULL /*file_name*/);4757if (hMap == NULL) {4758if (PrintMiscellaneous && Verbose) {4759DWORD err = GetLastError();4760tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err);4761}4762CloseHandle(hFile);4763return NULL;4764}47654766DWORD access = read_only ? FILE_MAP_READ : FILE_MAP_COPY;4767base = (char*)MapViewOfFileEx(hMap, access, 0, (DWORD)file_offset,4768(DWORD)bytes, addr);4769if (base == NULL) {4770if (PrintMiscellaneous && Verbose) {4771DWORD err = GetLastError();4772tty->print_cr("MapViewOfFileEx() failed: GetLastError->%ld.", err);4773}4774CloseHandle(hMap);4775CloseHandle(hFile);4776return NULL;4777}47784779if (CloseHandle(hMap) == 0) {4780if (PrintMiscellaneous && Verbose) {4781DWORD err = GetLastError();4782tty->print_cr("CloseHandle(hMap) failed: GetLastError->%ld.", err);4783}4784CloseHandle(hFile);4785return base;4786}4787}47884789if (allow_exec) {4790DWORD old_protect;4791DWORD exec_access = read_only ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE;4792bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0;47934794if (!res) {4795if (PrintMiscellaneous && Verbose) {4796DWORD err = GetLastError();4797tty->print_cr("VirtualProtect() failed: GetLastError->%ld.", err);4798}4799// Don't consider this a hard error, on IA32 even if the4800// VirtualProtect fails, we should still be able to execute4801CloseHandle(hFile);4802return base;4803}4804}48054806if (CloseHandle(hFile) == 0) {4807if (PrintMiscellaneous && Verbose) {4808DWORD err = GetLastError();4809tty->print_cr("CloseHandle(hFile) failed: GetLastError->%ld.", err);4810}4811return base;4812}48134814return base;4815}481648174818// Remap a block of memory.4819char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,4820char *addr, size_t bytes, bool read_only,4821bool allow_exec) {4822// This OS does not allow existing memory maps to be remapped so we4823// have to unmap the memory before we remap it.4824if (!os::unmap_memory(addr, bytes)) {4825return NULL;4826}48274828// There is a very small theoretical window between the unmap_memory()4829// call above and the map_memory() call below where a thread in native4830// code may be able to access an address that is no longer mapped.48314832return os::map_memory(fd, file_name, file_offset, addr, bytes,4833read_only, allow_exec);4834}483548364837// Unmap a block of memory.4838// Returns true=success, otherwise false.48394840bool os::pd_unmap_memory(char* addr, size_t bytes) {4841BOOL result = UnmapViewOfFile(addr);4842if (result == 0) {4843if (PrintMiscellaneous && Verbose) {4844DWORD err = GetLastError();4845tty->print_cr("UnmapViewOfFile() failed: GetLastError->%ld.", err);4846}4847return false;4848}4849return true;4850}48514852void os::pause() {4853char filename[MAX_PATH];4854if (PauseAtStartupFile && PauseAtStartupFile[0]) {4855jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);4856} else {4857jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());4858}48594860int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);4861if (fd != -1) {4862struct stat buf;4863::close(fd);4864while (::stat(filename, &buf) == 0) {4865Sleep(100);4866}4867} else {4868jio_fprintf(stderr,4869"Could not open pause file '%s', continuing immediately.\n", filename);4870}4871}48724873Thread* os::ThreadCrashProtection::_protected_thread = NULL;4874os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;4875volatile intptr_t os::ThreadCrashProtection::_crash_mux = 0;48764877os::ThreadCrashProtection::ThreadCrashProtection() {4878}48794880// See the caveats for this class in os_windows.hpp4881// Protects the callback call so that raised OS EXCEPTIONS causes a jump back4882// into this method and returns false. If no OS EXCEPTION was raised, returns4883// true.4884// The callback is supposed to provide the method that should be protected.4885//4886bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) {48874888Thread::muxAcquire(&_crash_mux, "CrashProtection");48894890_protected_thread = ThreadLocalStorage::thread();4891assert(_protected_thread != NULL, "Cannot crash protect a NULL thread");48924893bool success = true;4894__try {4895_crash_protection = this;4896cb.call();4897} __except(EXCEPTION_EXECUTE_HANDLER) {4898// only for protection, nothing to do4899success = false;4900}4901_crash_protection = NULL;4902_protected_thread = NULL;4903Thread::muxRelease(&_crash_mux);4904return success;4905}49064907// An Event wraps a win32 "CreateEvent" kernel handle.4908//4909// We have a number of choices regarding "CreateEvent" win32 handle leakage:4910//4911// 1: When a thread dies return the Event to the EventFreeList, clear the ParkHandle4912// field, and call CloseHandle() on the win32 event handle. Unpark() would4913// need to be modified to tolerate finding a NULL (invalid) win32 event handle.4914// In addition, an unpark() operation might fetch the handle field, but the4915// event could recycle between the fetch and the SetEvent() operation.4916// SetEvent() would either fail because the handle was invalid, or inadvertently work,4917// as the win32 handle value had been recycled. In an ideal world calling SetEvent()4918// on an stale but recycled handle would be harmless, but in practice this might4919// confuse other non-Sun code, so it's not a viable approach.4920//4921// 2: Once a win32 event handle is associated with an Event, it remains associated4922// with the Event. The event handle is never closed. This could be construed4923// as handle leakage, but only up to the maximum # of threads that have been extant4924// at any one time. This shouldn't be an issue, as windows platforms typically4925// permit a process to have hundreds of thousands of open handles.4926//4927// 3: Same as (1), but periodically, at stop-the-world time, rundown the EventFreeList4928// and release unused handles.4929//4930// 4: Add a CRITICAL_SECTION to the Event to protect LD+SetEvent from LD;ST(null);CloseHandle.4931// It's not clear, however, that we wouldn't be trading one type of leak for another.4932//4933// 5. Use an RCU-like mechanism (Read-Copy Update).4934// Or perhaps something similar to Maged Michael's "Hazard pointers".4935//4936// We use (2).4937//4938// TODO-FIXME:4939// 1. Reconcile Doug's JSR166 j.u.c park-unpark with the objectmonitor implementation.4940// 2. Consider wrapping the WaitForSingleObject(Ex) calls in SEH try/finally blocks4941// to recover from (or at least detect) the dreaded Windows 841176 bug.4942// 3. Collapse the interrupt_event, the JSR166 parker event, and the objectmonitor ParkEvent4943// into a single win32 CreateEvent() handle.4944//4945// _Event transitions in park()4946// -1 => -1 : illegal4947// 1 => 0 : pass - return immediately4948// 0 => -1 : block4949//4950// _Event serves as a restricted-range semaphore :4951// -1 : thread is blocked4952// 0 : neutral - thread is running or ready4953// 1 : signaled - thread is running or ready4954//4955// Another possible encoding of _Event would be4956// with explicit "PARKED" and "SIGNALED" bits.49574958int os::PlatformEvent::park (jlong Millis) {4959guarantee (_ParkHandle != NULL , "Invariant") ;4960guarantee (Millis > 0 , "Invariant") ;4961int v ;49624963// CONSIDER: defer assigning a CreateEvent() handle to the Event until4964// the initial park() operation.49654966for (;;) {4967v = _Event ;4968if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;4969}4970guarantee ((v == 0) || (v == 1), "invariant") ;4971if (v != 0) return OS_OK ;49724973// Do this the hard way by blocking ...4974// TODO: consider a brief spin here, gated on the success of recent4975// spin attempts by this thread.4976//4977// We decompose long timeouts into series of shorter timed waits.4978// Evidently large timo values passed in WaitForSingleObject() are problematic on some4979// versions of Windows. See EventWait() for details. This may be superstition. Or not.4980// We trust the WAIT_TIMEOUT indication and don't track the elapsed wait time4981// with os::javaTimeNanos(). Furthermore, we assume that spurious returns from4982// ::WaitForSingleObject() caused by latent ::setEvent() operations will tend4983// to happen early in the wait interval. Specifically, after a spurious wakeup (rv ==4984// WAIT_OBJECT_0 but _Event is still < 0) we don't bother to recompute Millis to compensate4985// for the already waited time. This policy does not admit any new outcomes.4986// In the future, however, we might want to track the accumulated wait time and4987// adjust Millis accordingly if we encounter a spurious wakeup.49884989const int MAXTIMEOUT = 0x10000000 ;4990DWORD rv = WAIT_TIMEOUT ;4991while (_Event < 0 && Millis > 0) {4992DWORD prd = Millis ; // set prd = MAX (Millis, MAXTIMEOUT)4993if (Millis > MAXTIMEOUT) {4994prd = MAXTIMEOUT ;4995}4996rv = ::WaitForSingleObject (_ParkHandle, prd) ;4997assert (rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT, "WaitForSingleObject failed") ;4998if (rv == WAIT_TIMEOUT) {4999Millis -= prd ;5000}5001}5002v = _Event ;5003_Event = 0 ;5004// see comment at end of os::PlatformEvent::park() below:5005OrderAccess::fence() ;5006// If we encounter a nearly simultanous timeout expiry and unpark()5007// we return OS_OK indicating we awoke via unpark().5008// Implementor's license -- returning OS_TIMEOUT would be equally valid, however.5009return (v >= 0) ? OS_OK : OS_TIMEOUT ;5010}50115012void os::PlatformEvent::park () {5013guarantee (_ParkHandle != NULL, "Invariant") ;5014// Invariant: Only the thread associated with the Event/PlatformEvent5015// may call park().5016int v ;5017for (;;) {5018v = _Event ;5019if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;5020}5021guarantee ((v == 0) || (v == 1), "invariant") ;5022if (v != 0) return ;50235024// Do this the hard way by blocking ...5025// TODO: consider a brief spin here, gated on the success of recent5026// spin attempts by this thread.5027while (_Event < 0) {5028DWORD rv = ::WaitForSingleObject (_ParkHandle, INFINITE) ;5029assert (rv == WAIT_OBJECT_0, "WaitForSingleObject failed") ;5030}50315032// Usually we'll find _Event == 0 at this point, but as5033// an optional optimization we clear it, just in case can5034// multiple unpark() operations drove _Event up to 1.5035_Event = 0 ;5036OrderAccess::fence() ;5037guarantee (_Event >= 0, "invariant") ;5038}50395040void os::PlatformEvent::unpark() {5041guarantee (_ParkHandle != NULL, "Invariant") ;50425043// Transitions for _Event:5044// 0 :=> 15045// 1 :=> 15046// -1 :=> either 0 or 1; must signal target thread5047// That is, we can safely transition _Event from -1 to either5048// 0 or 1. Forcing 1 is slightly more efficient for back-to-back5049// unpark() calls.5050// See also: "Semaphores in Plan 9" by Mullender & Cox5051//5052// Note: Forcing a transition from "-1" to "1" on an unpark() means5053// that it will take two back-to-back park() calls for the owning5054// thread to block. This has the benefit of forcing a spurious return5055// from the first park() call after an unpark() call which will help5056// shake out uses of park() and unpark() without condition variables.50575058if (Atomic::xchg(1, &_Event) >= 0) return;50595060::SetEvent(_ParkHandle);5061}506250635064// JSR1665065// -------------------------------------------------------50665067/*5068* The Windows implementation of Park is very straightforward: Basic5069* operations on Win32 Events turn out to have the right semantics to5070* use them directly. We opportunistically resuse the event inherited5071* from Monitor.5072*/507350745075void Parker::park(bool isAbsolute, jlong time) {5076guarantee (_ParkEvent != NULL, "invariant") ;5077// First, demultiplex/decode time arguments5078if (time < 0) { // don't wait5079return;5080}5081else if (time == 0 && !isAbsolute) {5082time = INFINITE;5083}5084else if (isAbsolute) {5085time -= os::javaTimeMillis(); // convert to relative time5086if (time <= 0) // already elapsed5087return;5088}5089else { // relative5090time /= 1000000; // Must coarsen from nanos to millis5091if (time == 0) // Wait for the minimal time unit if zero5092time = 1;5093}50945095JavaThread* thread = (JavaThread*)(Thread::current());5096assert(thread->is_Java_thread(), "Must be JavaThread");5097JavaThread *jt = (JavaThread *)thread;50985099// Don't wait if interrupted or already triggered5100if (Thread::is_interrupted(thread, false) ||5101WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) {5102ResetEvent(_ParkEvent);5103return;5104}5105else {5106ThreadBlockInVM tbivm(jt);5107OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);5108jt->set_suspend_equivalent();51095110WaitForSingleObject(_ParkEvent, time);5111ResetEvent(_ParkEvent);51125113// If externally suspended while waiting, re-suspend5114if (jt->handle_special_suspend_equivalent_condition()) {5115jt->java_suspend_self();5116}5117}5118}51195120void Parker::unpark() {5121guarantee (_ParkEvent != NULL, "invariant") ;5122SetEvent(_ParkEvent);5123}51245125// Run the specified command in a separate process. Return its exit value,5126// or -1 on failure (e.g. can't create a new process).5127int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {5128STARTUPINFO si;5129PROCESS_INFORMATION pi;51305131memset(&si, 0, sizeof(si));5132si.cb = sizeof(si);5133memset(&pi, 0, sizeof(pi));5134BOOL rslt = CreateProcess(NULL, // executable name - use command line5135cmd, // command line5136NULL, // process security attribute5137NULL, // thread security attribute5138TRUE, // inherits system handles51390, // no creation flags5140NULL, // use parent's environment block5141NULL, // use parent's starting directory5142&si, // (in) startup information5143&pi); // (out) process information51445145if (rslt) {5146// Wait until child process exits.5147WaitForSingleObject(pi.hProcess, INFINITE);51485149DWORD exit_code;5150GetExitCodeProcess(pi.hProcess, &exit_code);51515152// Close process and thread handles.5153CloseHandle(pi.hProcess);5154CloseHandle(pi.hThread);51555156return (int)exit_code;5157} else {5158return -1;5159}5160}51615162//--------------------------------------------------------------------------------------------------5163// Non-product code51645165static int mallocDebugIntervalCounter = 0;5166static int mallocDebugCounter = 0;5167bool os::check_heap(bool force) {5168if (++mallocDebugCounter < MallocVerifyStart && !force) return true;5169if (++mallocDebugIntervalCounter >= MallocVerifyInterval || force) {5170// Note: HeapValidate executes two hardware breakpoints when it finds something5171// wrong; at these points, eax contains the address of the offending block (I think).5172// To get to the exlicit error message(s) below, just continue twice.5173HANDLE heap = GetProcessHeap();5174{ HeapLock(heap);5175PROCESS_HEAP_ENTRY phe;5176phe.lpData = NULL;5177while (HeapWalk(heap, &phe) != 0) {5178if ((phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) &&5179!HeapValidate(heap, 0, phe.lpData)) {5180tty->print_cr("C heap has been corrupted (time: %d allocations)", mallocDebugCounter);5181tty->print_cr("corrupted block near address %#x, length %d", phe.lpData, phe.cbData);5182fatal("corrupted C heap");5183}5184}5185DWORD err = GetLastError();5186if (err != ERROR_NO_MORE_ITEMS && err != ERROR_CALL_NOT_IMPLEMENTED) {5187fatal(err_msg("heap walk aborted with error %d", err));5188}5189HeapUnlock(heap);5190}5191mallocDebugIntervalCounter = 0;5192}5193return true;5194}519551965197bool os::find(address addr, outputStream* st) {5198// Nothing yet5199return false;5200}52015202LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {5203DWORD exception_code = e->ExceptionRecord->ExceptionCode;52045205if ( exception_code == EXCEPTION_ACCESS_VIOLATION ) {5206JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();5207PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;5208address addr = (address) exceptionRecord->ExceptionInformation[1];52095210if (os::is_memory_serialize_page(thread, addr))5211return EXCEPTION_CONTINUE_EXECUTION;5212}52135214return EXCEPTION_CONTINUE_SEARCH;5215}52165217// We don't build a headless jre for Windows5218bool os::is_headless_jre() { return false; }52195220static jint initSock() {5221WSADATA wsadata;52225223if (!os::WinSock2Dll::WinSock2Available()) {5224jio_fprintf(stderr, "Could not load Winsock (error: %d)\n",5225::GetLastError());5226return JNI_ERR;5227}52285229if (os::WinSock2Dll::WSAStartup(MAKEWORD(2,2), &wsadata) != 0) {5230jio_fprintf(stderr, "Could not initialize Winsock (error: %d)\n",5231::GetLastError());5232return JNI_ERR;5233}5234return JNI_OK;5235}52365237struct hostent* os::get_host_by_name(char* name) {5238return (struct hostent*)os::WinSock2Dll::gethostbyname(name);5239}52405241int os::socket_close(int fd) {5242return ::closesocket(fd);5243}52445245int os::socket_available(int fd, jint *pbytes) {5246int ret = ::ioctlsocket(fd, FIONREAD, (u_long*)pbytes);5247return (ret < 0) ? 0 : 1;5248}52495250int os::socket(int domain, int type, int protocol) {5251return ::socket(domain, type, protocol);5252}52535254int os::listen(int fd, int count) {5255return ::listen(fd, count);5256}52575258int os::connect(int fd, struct sockaddr* him, socklen_t len) {5259return ::connect(fd, him, len);5260}52615262int os::accept(int fd, struct sockaddr* him, socklen_t* len) {5263return ::accept(fd, him, len);5264}52655266int os::sendto(int fd, char* buf, size_t len, uint flags,5267struct sockaddr* to, socklen_t tolen) {52685269return ::sendto(fd, buf, (int)len, flags, to, tolen);5270}52715272int os::recvfrom(int fd, char *buf, size_t nBytes, uint flags,5273sockaddr* from, socklen_t* fromlen) {52745275return ::recvfrom(fd, buf, (int)nBytes, flags, from, fromlen);5276}52775278int os::recv(int fd, char* buf, size_t nBytes, uint flags) {5279return ::recv(fd, buf, (int)nBytes, flags);5280}52815282int os::send(int fd, char* buf, size_t nBytes, uint flags) {5283return ::send(fd, buf, (int)nBytes, flags);5284}52855286int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {5287return ::send(fd, buf, (int)nBytes, flags);5288}52895290int os::timeout(int fd, long timeout) {5291fd_set tbl;5292struct timeval t;52935294t.tv_sec = timeout / 1000;5295t.tv_usec = (timeout % 1000) * 1000;52965297tbl.fd_count = 1;5298tbl.fd_array[0] = fd;52995300return ::select(1, &tbl, 0, 0, &t);5301}53025303int os::get_host_name(char* name, int namelen) {5304return ::gethostname(name, namelen);5305}53065307int os::socket_shutdown(int fd, int howto) {5308return ::shutdown(fd, howto);5309}53105311int os::bind(int fd, struct sockaddr* him, socklen_t len) {5312return ::bind(fd, him, len);5313}53145315int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {5316return ::getsockname(fd, him, len);5317}53185319int os::get_sock_opt(int fd, int level, int optname,5320char* optval, socklen_t* optlen) {5321return ::getsockopt(fd, level, optname, optval, optlen);5322}53235324int os::set_sock_opt(int fd, int level, int optname,5325const char* optval, socklen_t optlen) {5326return ::setsockopt(fd, level, optname, optval, optlen);5327}53285329// WINDOWS CONTEXT Flags for THREAD_SAMPLING5330#if defined(IA32)5331# define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)5332#elif defined (AMD64)5333# define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)5334#endif53355336// returns true if thread could be suspended,5337// false otherwise5338static bool do_suspend(HANDLE* h) {5339if (h != NULL) {5340if (SuspendThread(*h) != ~0) {5341return true;5342}5343}5344return false;5345}53465347// resume the thread5348// calling resume on an active thread is a no-op5349static void do_resume(HANDLE* h) {5350if (h != NULL) {5351ResumeThread(*h);5352}5353}53545355// retrieve a suspend/resume context capable handle5356// from the tid. Caller validates handle return value.5357void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) {5358if (h != NULL) {5359*h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);5360}5361}53625363//5364// Thread sampling implementation5365//5366void os::SuspendedThreadTask::internal_do_task() {5367CONTEXT ctxt;5368HANDLE h = NULL;53695370// get context capable handle for thread5371get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());53725373// sanity5374if (h == NULL || h == INVALID_HANDLE_VALUE) {5375return;5376}53775378// suspend the thread5379if (do_suspend(&h)) {5380ctxt.ContextFlags = sampling_context_flags;5381// get thread context5382GetThreadContext(h, &ctxt);5383SuspendedThreadTaskContext context(_thread, &ctxt);5384// pass context to Thread Sampling impl5385do_task(context);5386// resume thread5387do_resume(&h);5388}53895390// close handle5391CloseHandle(h);5392}539353945395// Kernel32 API5396typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);5397typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);5398typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);5399typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG);5400typedef USHORT (WINAPI* RtlCaptureStackBackTrace_Fn)(ULONG, ULONG, PVOID*, PULONG);54015402GetLargePageMinimum_Fn os::Kernel32Dll::_GetLargePageMinimum = NULL;5403VirtualAllocExNuma_Fn os::Kernel32Dll::_VirtualAllocExNuma = NULL;5404GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL;5405GetNumaNodeProcessorMask_Fn os::Kernel32Dll::_GetNumaNodeProcessorMask = NULL;5406RtlCaptureStackBackTrace_Fn os::Kernel32Dll::_RtlCaptureStackBackTrace = NULL;540754085409BOOL os::Kernel32Dll::initialized = FALSE;5410SIZE_T os::Kernel32Dll::GetLargePageMinimum() {5411assert(initialized && _GetLargePageMinimum != NULL,5412"GetLargePageMinimumAvailable() not yet called");5413return _GetLargePageMinimum();5414}54155416BOOL os::Kernel32Dll::GetLargePageMinimumAvailable() {5417if (!initialized) {5418initialize();5419}5420return _GetLargePageMinimum != NULL;5421}54225423BOOL os::Kernel32Dll::NumaCallsAvailable() {5424if (!initialized) {5425initialize();5426}5427return _VirtualAllocExNuma != NULL;5428}54295430LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) {5431assert(initialized && _VirtualAllocExNuma != NULL,5432"NUMACallsAvailable() not yet called");54335434return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node);5435}54365437BOOL os::Kernel32Dll::GetNumaHighestNodeNumber(PULONG ptr_highest_node_number) {5438assert(initialized && _GetNumaHighestNodeNumber != NULL,5439"NUMACallsAvailable() not yet called");54405441return _GetNumaHighestNodeNumber(ptr_highest_node_number);5442}54435444BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) {5445assert(initialized && _GetNumaNodeProcessorMask != NULL,5446"NUMACallsAvailable() not yet called");54475448return _GetNumaNodeProcessorMask(node, proc_mask);5449}54505451USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip,5452ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) {5453if (!initialized) {5454initialize();5455}54565457if (_RtlCaptureStackBackTrace != NULL) {5458return _RtlCaptureStackBackTrace(FrameToSkip, FrameToCapture,5459BackTrace, BackTraceHash);5460} else {5461return 0;5462}5463}54645465void os::Kernel32Dll::initializeCommon() {5466if (!initialized) {5467HMODULE handle = ::GetModuleHandle("Kernel32.dll");5468assert(handle != NULL, "Just check");5469_GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");5470_VirtualAllocExNuma = (VirtualAllocExNuma_Fn)::GetProcAddress(handle, "VirtualAllocExNuma");5471_GetNumaHighestNodeNumber = (GetNumaHighestNodeNumber_Fn)::GetProcAddress(handle, "GetNumaHighestNodeNumber");5472_GetNumaNodeProcessorMask = (GetNumaNodeProcessorMask_Fn)::GetProcAddress(handle, "GetNumaNodeProcessorMask");5473_RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_Fn)::GetProcAddress(handle, "RtlCaptureStackBackTrace");5474initialized = TRUE;5475}5476}5477547854795480#ifndef JDK6_OR_EARLIER54815482void os::Kernel32Dll::initialize() {5483initializeCommon();5484}548554865487// Kernel32 API5488inline BOOL os::Kernel32Dll::SwitchToThread() {5489return ::SwitchToThread();5490}54915492inline BOOL os::Kernel32Dll::SwitchToThreadAvailable() {5493return true;5494}54955496// Help tools5497inline BOOL os::Kernel32Dll::HelpToolsAvailable() {5498return true;5499}55005501inline HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) {5502return ::CreateToolhelp32Snapshot(dwFlags, th32ProcessId);5503}55045505inline BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {5506return ::Module32First(hSnapshot, lpme);5507}55085509inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {5510return ::Module32Next(hSnapshot, lpme);5511}55125513inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {5514::GetNativeSystemInfo(lpSystemInfo);5515}55165517// PSAPI API5518inline BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) {5519return ::EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);5520}55215522inline DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {5523return ::GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);5524}55255526inline BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) {5527return ::GetModuleInformation(hProcess, hModule, lpmodinfo, cb);5528}55295530inline BOOL os::PSApiDll::PSApiAvailable() {5531return true;5532}553355345535// WinSock2 API5536inline BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {5537return ::WSAStartup(wVersionRequested, lpWSAData);5538}55395540inline struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {5541return ::gethostbyname(name);5542}55435544inline BOOL os::WinSock2Dll::WinSock2Available() {5545return true;5546}55475548// Advapi API5549inline BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,5550BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,5551PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) {5552return ::AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,5553BufferLength, PreviousState, ReturnLength);5554}55555556inline BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess,5557PHANDLE TokenHandle) {5558return ::OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);5559}55605561inline BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) {5562return ::LookupPrivilegeValue(lpSystemName, lpName, lpLuid);5563}55645565inline BOOL os::Advapi32Dll::AdvapiAvailable() {5566return true;5567}55685569void* os::get_default_process_handle() {5570return (void*)GetModuleHandle(NULL);5571}55725573// Builds a platform dependent Agent_OnLoad_<lib_name> function name5574// which is used to find statically linked in agents.5575// Additionally for windows, takes into account __stdcall names.5576// Parameters:5577// sym_name: Symbol in library we are looking for5578// lib_name: Name of library to look in, NULL for shared libs.5579// is_absolute_path == true if lib_name is absolute path to agent5580// such as "C:/a/b/L.dll"5581// == false if only the base name of the library is passed in5582// such as "L"5583char* os::build_agent_function_name(const char *sym_name, const char *lib_name,5584bool is_absolute_path) {5585char *agent_entry_name;5586size_t len;5587size_t name_len;5588size_t prefix_len = strlen(JNI_LIB_PREFIX);5589size_t suffix_len = strlen(JNI_LIB_SUFFIX);5590const char *start;55915592if (lib_name != NULL) {5593len = name_len = strlen(lib_name);5594if (is_absolute_path) {5595// Need to strip path, prefix and suffix5596if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {5597lib_name = ++start;5598} else {5599// Need to check for drive prefix5600if ((start = strchr(lib_name, ':')) != NULL) {5601lib_name = ++start;5602}5603}5604if (len <= (prefix_len + suffix_len)) {5605return NULL;5606}5607lib_name += prefix_len;5608name_len = strlen(lib_name) - suffix_len;5609}5610}5611len = (lib_name != NULL ? name_len : 0) + strlen(sym_name) + 2;5612agent_entry_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtThread);5613if (agent_entry_name == NULL) {5614return NULL;5615}5616if (lib_name != NULL) {5617const char *p = strrchr(sym_name, '@');5618if (p != NULL && p != sym_name) {5619// sym_name == _Agent_OnLoad@XX5620strncpy(agent_entry_name, sym_name, (p - sym_name));5621agent_entry_name[(p-sym_name)] = '\0';5622// agent_entry_name == _Agent_OnLoad5623strcat(agent_entry_name, "_");5624strncat(agent_entry_name, lib_name, name_len);5625strcat(agent_entry_name, p);5626// agent_entry_name == _Agent_OnLoad_lib_name@XX5627} else {5628strcpy(agent_entry_name, sym_name);5629strcat(agent_entry_name, "_");5630strncat(agent_entry_name, lib_name, name_len);5631}5632} else {5633strcpy(agent_entry_name, sym_name);5634}5635return agent_entry_name;5636}56375638#else5639// Kernel32 API5640typedef BOOL (WINAPI* SwitchToThread_Fn)(void);5641typedef HANDLE (WINAPI* CreateToolhelp32Snapshot_Fn)(DWORD,DWORD);5642typedef BOOL (WINAPI* Module32First_Fn)(HANDLE,LPMODULEENTRY32);5643typedef BOOL (WINAPI* Module32Next_Fn)(HANDLE,LPMODULEENTRY32);5644typedef void (WINAPI* GetNativeSystemInfo_Fn)(LPSYSTEM_INFO);56455646SwitchToThread_Fn os::Kernel32Dll::_SwitchToThread = NULL;5647CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL;5648Module32First_Fn os::Kernel32Dll::_Module32First = NULL;5649Module32Next_Fn os::Kernel32Dll::_Module32Next = NULL;5650GetNativeSystemInfo_Fn os::Kernel32Dll::_GetNativeSystemInfo = NULL;56515652void os::Kernel32Dll::initialize() {5653if (!initialized) {5654HMODULE handle = ::GetModuleHandle("Kernel32.dll");5655assert(handle != NULL, "Just check");56565657_SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");5658_CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)5659::GetProcAddress(handle, "CreateToolhelp32Snapshot");5660_Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");5661_Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");5662_GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");5663initializeCommon(); // resolve the functions that always need resolving56645665initialized = TRUE;5666}5667}56685669BOOL os::Kernel32Dll::SwitchToThread() {5670assert(initialized && _SwitchToThread != NULL,5671"SwitchToThreadAvailable() not yet called");5672return _SwitchToThread();5673}567456755676BOOL os::Kernel32Dll::SwitchToThreadAvailable() {5677if (!initialized) {5678initialize();5679}5680return _SwitchToThread != NULL;5681}56825683// Help tools5684BOOL os::Kernel32Dll::HelpToolsAvailable() {5685if (!initialized) {5686initialize();5687}5688return _CreateToolhelp32Snapshot != NULL &&5689_Module32First != NULL &&5690_Module32Next != NULL;5691}56925693HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessId) {5694assert(initialized && _CreateToolhelp32Snapshot != NULL,5695"HelpToolsAvailable() not yet called");56965697return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId);5698}56995700BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {5701assert(initialized && _Module32First != NULL,5702"HelpToolsAvailable() not yet called");57035704return _Module32First(hSnapshot, lpme);5705}57065707inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {5708assert(initialized && _Module32Next != NULL,5709"HelpToolsAvailable() not yet called");57105711return _Module32Next(hSnapshot, lpme);5712}571357145715BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {5716if (!initialized) {5717initialize();5718}5719return _GetNativeSystemInfo != NULL;5720}57215722void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {5723assert(initialized && _GetNativeSystemInfo != NULL,5724"GetNativeSystemInfoAvailable() not yet called");57255726_GetNativeSystemInfo(lpSystemInfo);5727}57285729// PSAPI API573057315732typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD);5733typedef BOOL (WINAPI *GetModuleFileNameEx_Fn)(HANDLE, HMODULE, LPTSTR, DWORD);;5734typedef BOOL (WINAPI *GetModuleInformation_Fn)(HANDLE, HMODULE, LPMODULEINFO, DWORD);57355736EnumProcessModules_Fn os::PSApiDll::_EnumProcessModules = NULL;5737GetModuleFileNameEx_Fn os::PSApiDll::_GetModuleFileNameEx = NULL;5738GetModuleInformation_Fn os::PSApiDll::_GetModuleInformation = NULL;5739BOOL os::PSApiDll::initialized = FALSE;57405741void os::PSApiDll::initialize() {5742if (!initialized) {5743HMODULE handle = os::win32::load_Windows_dll("PSAPI.DLL", NULL, 0);5744if (handle != NULL) {5745_EnumProcessModules = (EnumProcessModules_Fn)::GetProcAddress(handle,5746"EnumProcessModules");5747_GetModuleFileNameEx = (GetModuleFileNameEx_Fn)::GetProcAddress(handle,5748"GetModuleFileNameExA");5749_GetModuleInformation = (GetModuleInformation_Fn)::GetProcAddress(handle,5750"GetModuleInformation");5751}5752initialized = TRUE;5753}5754}5755575657575758BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule, DWORD cb, LPDWORD lpcbNeeded) {5759assert(initialized && _EnumProcessModules != NULL,5760"PSApiAvailable() not yet called");5761return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);5762}57635764DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {5765assert(initialized && _GetModuleFileNameEx != NULL,5766"PSApiAvailable() not yet called");5767return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);5768}57695770BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb) {5771assert(initialized && _GetModuleInformation != NULL,5772"PSApiAvailable() not yet called");5773return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb);5774}57755776BOOL os::PSApiDll::PSApiAvailable() {5777if (!initialized) {5778initialize();5779}5780return _EnumProcessModules != NULL &&5781_GetModuleFileNameEx != NULL &&5782_GetModuleInformation != NULL;5783}578457855786// WinSock2 API5787typedef int (PASCAL FAR* WSAStartup_Fn)(WORD, LPWSADATA);5788typedef struct hostent *(PASCAL FAR *gethostbyname_Fn)(...);57895790WSAStartup_Fn os::WinSock2Dll::_WSAStartup = NULL;5791gethostbyname_Fn os::WinSock2Dll::_gethostbyname = NULL;5792BOOL os::WinSock2Dll::initialized = FALSE;57935794void os::WinSock2Dll::initialize() {5795if (!initialized) {5796HMODULE handle = os::win32::load_Windows_dll("ws2_32.dll", NULL, 0);5797if (handle != NULL) {5798_WSAStartup = (WSAStartup_Fn)::GetProcAddress(handle, "WSAStartup");5799_gethostbyname = (gethostbyname_Fn)::GetProcAddress(handle, "gethostbyname");5800}5801initialized = TRUE;5802}5803}580458055806BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {5807assert(initialized && _WSAStartup != NULL,5808"WinSock2Available() not yet called");5809return _WSAStartup(wVersionRequested, lpWSAData);5810}58115812struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {5813assert(initialized && _gethostbyname != NULL,5814"WinSock2Available() not yet called");5815return _gethostbyname(name);5816}58175818BOOL os::WinSock2Dll::WinSock2Available() {5819if (!initialized) {5820initialize();5821}5822return _WSAStartup != NULL &&5823_gethostbyname != NULL;5824}58255826typedef BOOL (WINAPI *AdjustTokenPrivileges_Fn)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);5827typedef BOOL (WINAPI *OpenProcessToken_Fn)(HANDLE, DWORD, PHANDLE);5828typedef BOOL (WINAPI *LookupPrivilegeValue_Fn)(LPCTSTR, LPCTSTR, PLUID);58295830AdjustTokenPrivileges_Fn os::Advapi32Dll::_AdjustTokenPrivileges = NULL;5831OpenProcessToken_Fn os::Advapi32Dll::_OpenProcessToken = NULL;5832LookupPrivilegeValue_Fn os::Advapi32Dll::_LookupPrivilegeValue = NULL;5833BOOL os::Advapi32Dll::initialized = FALSE;58345835void os::Advapi32Dll::initialize() {5836if (!initialized) {5837HMODULE handle = os::win32::load_Windows_dll("advapi32.dll", NULL, 0);5838if (handle != NULL) {5839_AdjustTokenPrivileges = (AdjustTokenPrivileges_Fn)::GetProcAddress(handle,5840"AdjustTokenPrivileges");5841_OpenProcessToken = (OpenProcessToken_Fn)::GetProcAddress(handle,5842"OpenProcessToken");5843_LookupPrivilegeValue = (LookupPrivilegeValue_Fn)::GetProcAddress(handle,5844"LookupPrivilegeValueA");5845}5846initialized = TRUE;5847}5848}58495850BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,5851BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,5852PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength) {5853assert(initialized && _AdjustTokenPrivileges != NULL,5854"AdvapiAvailable() not yet called");5855return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,5856BufferLength, PreviousState, ReturnLength);5857}58585859BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess,5860PHANDLE TokenHandle) {5861assert(initialized && _OpenProcessToken != NULL,5862"AdvapiAvailable() not yet called");5863return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);5864}58655866BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid) {5867assert(initialized && _LookupPrivilegeValue != NULL,5868"AdvapiAvailable() not yet called");5869return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid);5870}58715872BOOL os::Advapi32Dll::AdvapiAvailable() {5873if (!initialized) {5874initialize();5875}5876return _AdjustTokenPrivileges != NULL &&5877_OpenProcessToken != NULL &&5878_LookupPrivilegeValue != NULL;5879}58805881#endif58825883#ifndef PRODUCT58845885// test the code path in reserve_memory_special() that tries to allocate memory in a single5886// contiguous memory block at a particular address.5887// The test first tries to find a good approximate address to allocate at by using the same5888// method to allocate some memory at any address. The test then tries to allocate memory in5889// the vicinity (not directly after it to avoid possible by-chance use of that location)5890// This is of course only some dodgy assumption, there is no guarantee that the vicinity of5891// the previously allocated memory is available for allocation. The only actual failure5892// that is reported is when the test tries to allocate at a particular location but gets a5893// different valid one. A NULL return value at this point is not considered an error but may5894// be legitimate.5895// If -XX:+VerboseInternalVMTests is enabled, print some explanatory messages.5896void TestReserveMemorySpecial_test() {5897if (!UseLargePages) {5898if (VerboseInternalVMTests) {5899gclog_or_tty->print("Skipping test because large pages are disabled");5900}5901return;5902}5903// save current value of globals5904bool old_use_large_pages_individual_allocation = UseLargePagesIndividualAllocation;5905bool old_use_numa_interleaving = UseNUMAInterleaving;59065907// set globals to make sure we hit the correct code path5908UseLargePagesIndividualAllocation = UseNUMAInterleaving = false;59095910// do an allocation at an address selected by the OS to get a good one.5911const size_t large_allocation_size = os::large_page_size() * 4;5912char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);5913if (result == NULL) {5914if (VerboseInternalVMTests) {5915gclog_or_tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.",5916large_allocation_size);5917}5918} else {5919os::release_memory_special(result, large_allocation_size);59205921// allocate another page within the recently allocated memory area which seems to be a good location. At least5922// we managed to get it once.5923const size_t expected_allocation_size = os::large_page_size();5924char* expected_location = result + os::large_page_size();5925char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);5926if (actual_location == NULL) {5927if (VerboseInternalVMTests) {5928gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",5929expected_location, large_allocation_size);5930}5931} else {5932// release memory5933os::release_memory_special(actual_location, expected_allocation_size);5934// only now check, after releasing any memory to avoid any leaks.5935assert(actual_location == expected_location,5936err_msg("Failed to allocate memory at requested location " PTR_FORMAT " of size " SIZE_FORMAT ", is " PTR_FORMAT " instead",5937expected_location, expected_allocation_size, actual_location));5938}5939}59405941// restore globals5942UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation;5943UseNUMAInterleaving = old_use_numa_interleaving;5944}5945#endif // PRODUCT5946594759485949