Path: blob/master/src/hotspot/os/windows/os_windows.cpp
64441 views
/*1* Copyright (c) 1997, 2021, 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 Vista or Server 2008 to use InitOnceExecuteOnce25#define _WIN32_WINNT 0x06002627// no precompiled headers28#include "jvm.h"29#include "classfile/vmSymbols.hpp"30#include "code/codeCache.hpp"31#include "code/icBuffer.hpp"32#include "code/nativeInst.hpp"33#include "code/vtableStubs.hpp"34#include "compiler/compileBroker.hpp"35#include "compiler/disassembler.hpp"36#include "interpreter/interpreter.hpp"37#include "jvmtifiles/jvmti.h"38#include "logging/log.hpp"39#include "logging/logStream.hpp"40#include "memory/allocation.inline.hpp"41#include "oops/oop.inline.hpp"42#include "os_share_windows.hpp"43#include "os_windows.inline.hpp"44#include "prims/jniFastGetField.hpp"45#include "prims/jvm_misc.hpp"46#include "runtime/arguments.hpp"47#include "runtime/atomic.hpp"48#include "runtime/globals.hpp"49#include "runtime/globals_extension.hpp"50#include "runtime/interfaceSupport.inline.hpp"51#include "runtime/java.hpp"52#include "runtime/javaCalls.hpp"53#include "runtime/mutexLocker.hpp"54#include "runtime/objectMonitor.hpp"55#include "runtime/orderAccess.hpp"56#include "runtime/osThread.hpp"57#include "runtime/perfMemory.hpp"58#include "runtime/safefetch.inline.hpp"59#include "runtime/safepointMechanism.hpp"60#include "runtime/semaphore.inline.hpp"61#include "runtime/sharedRuntime.hpp"62#include "runtime/statSampler.hpp"63#include "runtime/thread.inline.hpp"64#include "runtime/threadCritical.hpp"65#include "runtime/timer.hpp"66#include "runtime/vm_version.hpp"67#include "services/attachListener.hpp"68#include "services/memTracker.hpp"69#include "services/runtimeService.hpp"70#include "utilities/align.hpp"71#include "utilities/decoder.hpp"72#include "utilities/defaultStream.hpp"73#include "utilities/events.hpp"74#include "utilities/macros.hpp"75#include "utilities/vmError.hpp"76#include "symbolengine.hpp"77#include "windbghelp.hpp"7879#ifdef _DEBUG80#include <crtdbg.h>81#endif8283#include <windows.h>84#include <sys/types.h>85#include <sys/stat.h>86#include <sys/timeb.h>87#include <objidl.h>88#include <shlobj.h>8990#include <malloc.h>91#include <signal.h>92#include <direct.h>93#include <errno.h>94#include <fcntl.h>95#include <io.h>96#include <process.h> // For _beginthreadex(), _endthreadex()97#include <imagehlp.h> // For os::dll_address_to_function_name98// for enumerating dll libraries99#include <vdmdbg.h>100#include <psapi.h>101#include <mmsystem.h>102#include <winsock2.h>103104// for timer info max values which include all bits105#define ALL_64_BITS CONST64(-1)106107// For DLL loading/load error detection108// Values of PE COFF109#define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c110#define IMAGE_FILE_SIGNATURE_LENGTH 4111112static HANDLE main_process;113static HANDLE main_thread;114static int main_thread_id;115116static FILETIME process_creation_time;117static FILETIME process_exit_time;118static FILETIME process_user_time;119static FILETIME process_kernel_time;120121#if defined(_M_ARM64)122#define __CPU__ aarch64123#elif defined(_M_AMD64)124#define __CPU__ amd64125#else126#define __CPU__ i486127#endif128129#if defined(USE_VECTORED_EXCEPTION_HANDLING)130PVOID topLevelVectoredExceptionHandler = NULL;131LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL;132#endif133134// save DLL module handle, used by GetModuleFileName135136HINSTANCE vm_lib_handle;137138BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {139switch (reason) {140case DLL_PROCESS_ATTACH:141vm_lib_handle = hinst;142if (ForceTimeHighResolution) {143timeBeginPeriod(1L);144}145WindowsDbgHelp::pre_initialize();146SymbolEngine::pre_initialize();147break;148case DLL_PROCESS_DETACH:149if (ForceTimeHighResolution) {150timeEndPeriod(1L);151}152#if defined(USE_VECTORED_EXCEPTION_HANDLING)153if (topLevelVectoredExceptionHandler != NULL) {154RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);155topLevelVectoredExceptionHandler = NULL;156}157#endif158break;159default:160break;161}162return true;163}164165static inline double fileTimeAsDouble(FILETIME* time) {166const double high = (double) ((unsigned int) ~0);167const double split = 10000000.0;168double result = (time->dwLowDateTime / split) +169time->dwHighDateTime * (high/split);170return result;171}172173// Implementation of os174175#define RANGE_FORMAT "[" PTR_FORMAT "-" PTR_FORMAT ")"176#define RANGE_FORMAT_ARGS(p, len) p2i(p), p2i((address)p + len)177178// A number of wrappers for more frequently used system calls, to add standard logging.179180struct PreserveLastError {181const DWORD v;182PreserveLastError() : v(::GetLastError()) {}183~PreserveLastError() { ::SetLastError(v); }184};185186// Logging wrapper for VirtualAlloc187static LPVOID virtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {188LPVOID result = ::VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);189if (result != NULL) {190log_trace(os)("VirtualAlloc(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x) returned " PTR_FORMAT "%s.",191p2i(lpAddress), dwSize, flAllocationType, flProtect, p2i(result),192((lpAddress != NULL && result != lpAddress) ? " <different base!>" : ""));193} else {194PreserveLastError ple;195log_info(os)("VirtualAlloc(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x) failed (%u).",196p2i(lpAddress), dwSize, flAllocationType, flProtect, ple.v);197}198return result;199}200201// Logging wrapper for VirtualFree202static BOOL virtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {203BOOL result = ::VirtualFree(lpAddress, dwSize, dwFreeType);204if (result != FALSE) {205log_trace(os)("VirtualFree(" PTR_FORMAT ", " SIZE_FORMAT ", %x) succeeded",206p2i(lpAddress), dwSize, dwFreeType);207} else {208PreserveLastError ple;209log_info(os)("VirtualFree(" PTR_FORMAT ", " SIZE_FORMAT ", %x) failed (%u).",210p2i(lpAddress), dwSize, dwFreeType, ple.v);211}212return result;213}214215// Logging wrapper for VirtualAllocExNuma216static LPVOID virtualAllocExNuma(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType,217DWORD flProtect, DWORD nndPreferred) {218LPVOID result = ::VirtualAllocExNuma(hProcess, lpAddress, dwSize, flAllocationType, flProtect, nndPreferred);219if (result != NULL) {220log_trace(os)("VirtualAllocExNuma(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x, %x) returned " PTR_FORMAT "%s.",221p2i(lpAddress), dwSize, flAllocationType, flProtect, nndPreferred, p2i(result),222((lpAddress != NULL && result != lpAddress) ? " <different base!>" : ""));223} else {224PreserveLastError ple;225log_info(os)("VirtualAllocExNuma(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x, %x) failed (%u).",226p2i(lpAddress), dwSize, flAllocationType, flProtect, nndPreferred, ple.v);227}228return result;229}230231// Logging wrapper for MapViewOfFileEx232static LPVOID mapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,233DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) {234LPVOID result = ::MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,235dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress);236if (result != NULL) {237log_trace(os)("MapViewOfFileEx(" PTR_FORMAT ", " SIZE_FORMAT ") returned " PTR_FORMAT "%s.",238p2i(lpBaseAddress), dwNumberOfBytesToMap, p2i(result),239((lpBaseAddress != NULL && result != lpBaseAddress) ? " <different base!>" : ""));240} else {241PreserveLastError ple;242log_info(os)("MapViewOfFileEx(" PTR_FORMAT ", " SIZE_FORMAT ") failed (%u).",243p2i(lpBaseAddress), dwNumberOfBytesToMap, ple.v);244}245return result;246}247248// Logging wrapper for UnmapViewOfFile249static BOOL unmapViewOfFile(LPCVOID lpBaseAddress) {250BOOL result = ::UnmapViewOfFile(lpBaseAddress);251if (result != FALSE) {252log_trace(os)("UnmapViewOfFile(" PTR_FORMAT ") succeeded", p2i(lpBaseAddress));253} else {254PreserveLastError ple;255log_info(os)("UnmapViewOfFile(" PTR_FORMAT ") failed (%u).", p2i(lpBaseAddress), ple.v);256}257return result;258}259260bool os::unsetenv(const char* name) {261assert(name != NULL, "Null pointer");262return (SetEnvironmentVariable(name, NULL) == TRUE);263}264265char** os::get_environ() { return _environ; }266267// No setuid programs under Windows.268bool os::have_special_privileges() {269return false;270}271272273// This method is a periodic task to check for misbehaving JNI applications274// under CheckJNI, we can add any periodic checks here.275// For Windows at the moment does nothing276void os::run_periodic_checks() {277return;278}279280// previous UnhandledExceptionFilter, if there is one281static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;282283LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);284285void os::init_system_properties_values() {286// sysclasspath, java_home, dll_dir287{288char *home_path;289char *dll_path;290char *pslash;291const char *bin = "\\bin";292char home_dir[MAX_PATH + 1];293char *alt_home_dir = ::getenv("_ALT_JAVA_HOME_DIR");294295if (alt_home_dir != NULL) {296strncpy(home_dir, alt_home_dir, MAX_PATH + 1);297home_dir[MAX_PATH] = '\0';298} else {299os::jvm_path(home_dir, sizeof(home_dir));300// Found the full path to jvm.dll.301// Now cut the path to <java_home>/jre if we can.302*(strrchr(home_dir, '\\')) = '\0'; // get rid of \jvm.dll303pslash = strrchr(home_dir, '\\');304if (pslash != NULL) {305*pslash = '\0'; // get rid of \{client|server}306pslash = strrchr(home_dir, '\\');307if (pslash != NULL) {308*pslash = '\0'; // get rid of \bin309}310}311}312313home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal);314strcpy(home_path, home_dir);315Arguments::set_java_home(home_path);316FREE_C_HEAP_ARRAY(char, home_path);317318dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1,319mtInternal);320strcpy(dll_path, home_dir);321strcat(dll_path, bin);322Arguments::set_dll_dir(dll_path);323FREE_C_HEAP_ARRAY(char, dll_path);324325if (!set_boot_path('\\', ';')) {326vm_exit_during_initialization("Failed setting boot class path.", NULL);327}328}329330// library_path331#define EXT_DIR "\\lib\\ext"332#define BIN_DIR "\\bin"333#define PACKAGE_DIR "\\Sun\\Java"334{335// Win32 library search order (See the documentation for LoadLibrary):336//337// 1. The directory from which application is loaded.338// 2. The system wide Java Extensions directory (Java only)339// 3. System directory (GetSystemDirectory)340// 4. Windows directory (GetWindowsDirectory)341// 5. The PATH environment variable342// 6. The current directory343344char *library_path;345char tmp[MAX_PATH];346char *path_str = ::getenv("PATH");347348library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +349sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal);350351library_path[0] = '\0';352353GetModuleFileName(NULL, tmp, sizeof(tmp));354*(strrchr(tmp, '\\')) = '\0';355strcat(library_path, tmp);356357GetWindowsDirectory(tmp, sizeof(tmp));358strcat(library_path, ";");359strcat(library_path, tmp);360strcat(library_path, PACKAGE_DIR BIN_DIR);361362GetSystemDirectory(tmp, sizeof(tmp));363strcat(library_path, ";");364strcat(library_path, tmp);365366GetWindowsDirectory(tmp, sizeof(tmp));367strcat(library_path, ";");368strcat(library_path, tmp);369370if (path_str) {371strcat(library_path, ";");372strcat(library_path, path_str);373}374375strcat(library_path, ";.");376377Arguments::set_library_path(library_path);378FREE_C_HEAP_ARRAY(char, library_path);379}380381// Default extensions directory382{383char path[MAX_PATH];384char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1];385GetWindowsDirectory(path, MAX_PATH);386sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR,387path, PACKAGE_DIR, EXT_DIR);388Arguments::set_ext_dirs(buf);389}390#undef EXT_DIR391#undef BIN_DIR392#undef PACKAGE_DIR393394#ifndef _WIN64395// set our UnhandledExceptionFilter and save any previous one396prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);397#endif398399// Done400return;401}402403void os::breakpoint() {404DebugBreak();405}406407// Invoked from the BREAKPOINT Macro408extern "C" void breakpoint() {409os::breakpoint();410}411412// RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP.413// So far, this method is only used by Native Memory Tracking, which is414// only supported on Windows XP or later.415//416int os::get_native_stack(address* stack, int frames, int toSkip) {417int captured = RtlCaptureStackBackTrace(toSkip + 1, frames, (PVOID*)stack, NULL);418for (int index = captured; index < frames; index ++) {419stack[index] = NULL;420}421return captured;422}423424// os::current_stack_base()425//426// Returns the base of the stack, which is the stack's427// starting address. This function must be called428// while running on the stack of the thread being queried.429430address os::current_stack_base() {431MEMORY_BASIC_INFORMATION minfo;432address stack_bottom;433size_t stack_size;434435VirtualQuery(&minfo, &minfo, sizeof(minfo));436stack_bottom = (address)minfo.AllocationBase;437stack_size = minfo.RegionSize;438439// Add up the sizes of all the regions with the same440// AllocationBase.441while (1) {442VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));443if (stack_bottom == (address)minfo.AllocationBase) {444stack_size += minfo.RegionSize;445} else {446break;447}448}449return stack_bottom + stack_size;450}451452size_t os::current_stack_size() {453size_t sz;454MEMORY_BASIC_INFORMATION minfo;455VirtualQuery(&minfo, &minfo, sizeof(minfo));456sz = (size_t)os::current_stack_base() - (size_t)minfo.AllocationBase;457return sz;458}459460bool os::committed_in_range(address start, size_t size, address& committed_start, size_t& committed_size) {461MEMORY_BASIC_INFORMATION minfo;462committed_start = NULL;463committed_size = 0;464address top = start + size;465const address start_addr = start;466while (start < top) {467VirtualQuery(start, &minfo, sizeof(minfo));468if ((minfo.State & MEM_COMMIT) == 0) { // not committed469if (committed_start != NULL) {470break;471}472} else { // committed473if (committed_start == NULL) {474committed_start = start;475}476size_t offset = start - (address)minfo.BaseAddress;477committed_size += minfo.RegionSize - offset;478}479start = (address)minfo.BaseAddress + minfo.RegionSize;480}481482if (committed_start == NULL) {483assert(committed_size == 0, "Sanity");484return false;485} else {486assert(committed_start >= start_addr && committed_start < top, "Out of range");487// current region may go beyond the limit, trim to the limit488committed_size = MIN2(committed_size, size_t(top - committed_start));489return true;490}491}492493struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {494const struct tm* time_struct_ptr = localtime(clock);495if (time_struct_ptr != NULL) {496*res = *time_struct_ptr;497return res;498}499return NULL;500}501502struct tm* os::gmtime_pd(const time_t* clock, struct tm* res) {503const struct tm* time_struct_ptr = gmtime(clock);504if (time_struct_ptr != NULL) {505*res = *time_struct_ptr;506return res;507}508return NULL;509}510511JNIEXPORT512LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);513514// Thread start routine for all newly created threads515static unsigned __stdcall thread_native_entry(Thread* thread) {516517thread->record_stack_base_and_size();518thread->initialize_thread_current();519520OSThread* osthr = thread->osthread();521assert(osthr->get_state() == RUNNABLE, "invalid os thread state");522523if (UseNUMA) {524int lgrp_id = os::numa_get_group_id();525if (lgrp_id != -1) {526thread->set_lgrp_id(lgrp_id);527}528}529530// Diagnostic code to investigate JDK-6573254531int res = 30115; // non-java thread532if (thread->is_Java_thread()) {533res = 20115; // java thread534}535536log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());537538#ifdef USE_VECTORED_EXCEPTION_HANDLING539// Any exception is caught by the Vectored Exception Handler, so VM can540// generate error dump when an exception occurred in non-Java thread541// (e.g. VM thread).542thread->call_run();543#else544// Install a win32 structured exception handler around every thread created545// by VM, so VM can generate error dump when an exception occurred in non-546// Java thread (e.g. VM thread).547__try {548thread->call_run();549} __except(topLevelExceptionFilter(550(_EXCEPTION_POINTERS*)_exception_info())) {551// Nothing to do.552}553#endif554555// Note: at this point the thread object may already have deleted itself.556// Do not dereference it from here on out.557558log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());559560// One less thread is executing561// When the VMThread gets here, the main thread may have already exited562// which frees the CodeHeap containing the Atomic::add code563if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {564Atomic::dec(&os::win32::_os_thread_count);565}566567// Thread must not return from exit_process_or_thread(), but if it does,568// let it proceed to exit normally569return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res);570}571572static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle,573int thread_id) {574// Allocate the OSThread object575OSThread* osthread = new OSThread(NULL, NULL);576if (osthread == NULL) return NULL;577578// Initialize the JDK library's interrupt event.579// This should really be done when OSThread is constructed,580// but there is no way for a constructor to report failure to581// allocate the event.582HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);583if (interrupt_event == NULL) {584delete osthread;585return NULL;586}587osthread->set_interrupt_event(interrupt_event);588589// Store info on the Win32 thread into the OSThread590osthread->set_thread_handle(thread_handle);591osthread->set_thread_id(thread_id);592593if (UseNUMA) {594int lgrp_id = os::numa_get_group_id();595if (lgrp_id != -1) {596thread->set_lgrp_id(lgrp_id);597}598}599600// Initial thread state is INITIALIZED, not SUSPENDED601osthread->set_state(INITIALIZED);602603return osthread;604}605606607bool os::create_attached_thread(JavaThread* thread) {608#ifdef ASSERT609thread->verify_not_published();610#endif611HANDLE thread_h;612if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),613&thread_h, THREAD_ALL_ACCESS, false, 0)) {614fatal("DuplicateHandle failed\n");615}616OSThread* osthread = create_os_thread(thread, thread_h,617(int)current_thread_id());618if (osthread == NULL) {619return false;620}621622// Initial thread state is RUNNABLE623osthread->set_state(RUNNABLE);624625thread->set_osthread(osthread);626627log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").",628os::current_thread_id());629630return true;631}632633bool os::create_main_thread(JavaThread* thread) {634#ifdef ASSERT635thread->verify_not_published();636#endif637if (_starting_thread == NULL) {638_starting_thread = create_os_thread(thread, main_thread, main_thread_id);639if (_starting_thread == NULL) {640return false;641}642}643644// The primordial thread is runnable from the start)645_starting_thread->set_state(RUNNABLE);646647thread->set_osthread(_starting_thread);648return true;649}650651// Helper function to trace _beginthreadex attributes,652// similar to os::Posix::describe_pthread_attr()653static char* describe_beginthreadex_attributes(char* buf, size_t buflen,654size_t stacksize, unsigned initflag) {655stringStream ss(buf, buflen);656if (stacksize == 0) {657ss.print("stacksize: default, ");658} else {659ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024);660}661ss.print("flags: ");662#define PRINT_FLAG(f) if (initflag & f) ss.print( #f " ");663#define ALL(X) \664X(CREATE_SUSPENDED) \665X(STACK_SIZE_PARAM_IS_A_RESERVATION)666ALL(PRINT_FLAG)667#undef ALL668#undef PRINT_FLAG669return buf;670}671672// Allocate and initialize a new OSThread673bool os::create_thread(Thread* thread, ThreadType thr_type,674size_t stack_size) {675unsigned thread_id;676677// Allocate the OSThread object678OSThread* osthread = new OSThread(NULL, NULL);679if (osthread == NULL) {680return false;681}682683// Initial state is ALLOCATED but not INITIALIZED684osthread->set_state(ALLOCATED);685686// Initialize the JDK library's interrupt event.687// This should really be done when OSThread is constructed,688// but there is no way for a constructor to report failure to689// allocate the event.690HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);691if (interrupt_event == NULL) {692delete osthread;693return false;694}695osthread->set_interrupt_event(interrupt_event);696// We don't call set_interrupted(false) as it will trip the assert in there697// as we are not operating on the current thread. We don't need to call it698// because the initial state is already correct.699700thread->set_osthread(osthread);701702if (stack_size == 0) {703switch (thr_type) {704case os::java_thread:705// Java threads use ThreadStackSize which default value can be changed with the flag -Xss706if (JavaThread::stack_size_at_create() > 0) {707stack_size = JavaThread::stack_size_at_create();708}709break;710case os::compiler_thread:711if (CompilerThreadStackSize > 0) {712stack_size = (size_t)(CompilerThreadStackSize * K);713break;714} // else fall through:715// use VMThreadStackSize if CompilerThreadStackSize is not defined716case os::vm_thread:717case os::pgc_thread:718case os::cgc_thread:719case os::asynclog_thread:720case os::watcher_thread:721if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);722break;723}724}725726// Create the Win32 thread727//728// Contrary to what MSDN document says, "stack_size" in _beginthreadex()729// does not specify stack size. Instead, it specifies the size of730// initially committed space. The stack size is determined by731// PE header in the executable. If the committed "stack_size" is larger732// than default value in the PE header, the stack is rounded up to the733// nearest multiple of 1MB. For example if the launcher has default734// stack size of 320k, specifying any size less than 320k does not735// affect the actual stack size at all, it only affects the initial736// commitment. On the other hand, specifying 'stack_size' larger than737// default value may cause significant increase in memory usage, because738// not only the stack space will be rounded up to MB, but also the739// entire space is committed upfront.740//741// Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'742// for CreateThread() that can treat 'stack_size' as stack size. However we743// are not supposed to call CreateThread() directly according to MSDN744// document because JVM uses C runtime library. The good news is that the745// flag appears to work with _beginthredex() as well.746747const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;748HANDLE thread_handle;749int limit = 3;750do {751thread_handle =752(HANDLE)_beginthreadex(NULL,753(unsigned)stack_size,754(unsigned (__stdcall *)(void*)) thread_native_entry,755thread,756initflag,757&thread_id);758} while (thread_handle == NULL && errno == EAGAIN && limit-- > 0);759760ResourceMark rm;761char buf[64];762if (thread_handle != NULL) {763log_info(os, thread)("Thread \"%s\" started (tid: %u, attributes: %s)",764thread->name(), thread_id,765describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));766} else {767log_warning(os, thread)("Failed to start thread \"%s\" - _beginthreadex failed (%s) for attributes: %s.",768thread->name(), os::errno_name(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));769// Log some OS information which might explain why creating the thread failed.770log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());771LogStream st(Log(os, thread)::info());772os::print_memory_info(&st);773}774775if (thread_handle == NULL) {776// Need to clean up stuff we've allocated so far777thread->set_osthread(NULL);778delete osthread;779return false;780}781782Atomic::inc(&os::win32::_os_thread_count);783784// Store info on the Win32 thread into the OSThread785osthread->set_thread_handle(thread_handle);786osthread->set_thread_id(thread_id);787788// Thread state now is INITIALIZED, not SUSPENDED789osthread->set_state(INITIALIZED);790791// The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain792return true;793}794795796// Free Win32 resources related to the OSThread797void os::free_thread(OSThread* osthread) {798assert(osthread != NULL, "osthread not set");799800// We are told to free resources of the argument thread,801// but we can only really operate on the current thread.802assert(Thread::current()->osthread() == osthread,803"os::free_thread but not current thread");804805CloseHandle(osthread->thread_handle());806delete osthread;807}808809static jlong first_filetime;810static jlong initial_performance_count;811static jlong performance_frequency;812813814jlong as_long(LARGE_INTEGER x) {815jlong result = 0; // initialization to avoid warning816set_high(&result, x.HighPart);817set_low(&result, x.LowPart);818return result;819}820821822jlong os::elapsed_counter() {823LARGE_INTEGER count;824QueryPerformanceCounter(&count);825return as_long(count) - initial_performance_count;826}827828829jlong os::elapsed_frequency() {830return performance_frequency;831}832833834julong os::available_memory() {835return win32::available_memory();836}837838julong os::win32::available_memory() {839// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect840// value if total memory is larger than 4GB841MEMORYSTATUSEX ms;842ms.dwLength = sizeof(ms);843GlobalMemoryStatusEx(&ms);844845return (julong)ms.ullAvailPhys;846}847848julong os::physical_memory() {849return win32::physical_memory();850}851852bool os::has_allocatable_memory_limit(size_t* limit) {853MEMORYSTATUSEX ms;854ms.dwLength = sizeof(ms);855GlobalMemoryStatusEx(&ms);856#ifdef _LP64857*limit = (size_t)ms.ullAvailVirtual;858return true;859#else860// Limit to 1400m because of the 2gb address space wall861*limit = MIN2((size_t)1400*M, (size_t)ms.ullAvailVirtual);862return true;863#endif864}865866int os::active_processor_count() {867// User has overridden the number of active processors868if (ActiveProcessorCount > 0) {869log_trace(os)("active_processor_count: "870"active processor count set by user : %d",871ActiveProcessorCount);872return ActiveProcessorCount;873}874875DWORD_PTR lpProcessAffinityMask = 0;876DWORD_PTR lpSystemAffinityMask = 0;877int proc_count = processor_count();878if (proc_count <= sizeof(UINT_PTR) * BitsPerByte &&879GetProcessAffinityMask(GetCurrentProcess(), &lpProcessAffinityMask, &lpSystemAffinityMask)) {880// Nof active processors is number of bits in process affinity mask881int bitcount = 0;882while (lpProcessAffinityMask != 0) {883lpProcessAffinityMask = lpProcessAffinityMask & (lpProcessAffinityMask-1);884bitcount++;885}886return bitcount;887} else {888return proc_count;889}890}891892uint os::processor_id() {893return (uint)GetCurrentProcessorNumber();894}895896// For dynamic lookup of SetThreadDescription API897typedef HRESULT (WINAPI *SetThreadDescriptionFnPtr)(HANDLE, PCWSTR);898typedef HRESULT (WINAPI *GetThreadDescriptionFnPtr)(HANDLE, PWSTR*);899static SetThreadDescriptionFnPtr _SetThreadDescription = NULL;900DEBUG_ONLY(static GetThreadDescriptionFnPtr _GetThreadDescription = NULL;)901902// forward decl.903static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path);904905void os::set_native_thread_name(const char *name) {906907// From Windows 10 and Windows 2016 server, we have a direct API908// for setting the thread name/description:909// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription910911if (_SetThreadDescription != NULL) {912// SetThreadDescription takes a PCWSTR but we have conversion routines that produce913// LPWSTR. The only difference is that PCWSTR is a pointer to const WCHAR.914LPWSTR unicode_name;915errno_t err = convert_to_unicode(name, &unicode_name);916if (err == ERROR_SUCCESS) {917HANDLE current = GetCurrentThread();918HRESULT hr = _SetThreadDescription(current, unicode_name);919if (FAILED(hr)) {920log_debug(os, thread)("set_native_thread_name: SetThreadDescription failed - falling back to debugger method");921FREE_C_HEAP_ARRAY(WCHAR, unicode_name);922} else {923log_trace(os, thread)("set_native_thread_name: SetThreadDescription succeeded - new name: %s", name);924925#ifdef ASSERT926// For verification purposes in a debug build we read the thread name back and check it.927PWSTR thread_name;928HRESULT hr2 = _GetThreadDescription(current, &thread_name);929if (FAILED(hr2)) {930log_debug(os, thread)("set_native_thread_name: GetThreadDescription failed!");931} else {932int res = CompareStringW(LOCALE_USER_DEFAULT,9330, // no special comparison rules934unicode_name,935-1, // null-terminated936thread_name,937-1 // null-terminated938);939assert(res == CSTR_EQUAL,940"Name strings were not the same - set: %ls, but read: %ls", unicode_name, thread_name);941LocalFree(thread_name);942}943#endif944FREE_C_HEAP_ARRAY(WCHAR, unicode_name);945return;946}947} else {948log_debug(os, thread)("set_native_thread_name: convert_to_unicode failed - falling back to debugger method");949}950}951952// See: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx953//954// Note that unfortunately this only works if the process955// is already attached to a debugger; debugger must observe956// the exception below to show the correct name.957958// If there is no debugger attached skip raising the exception959if (!IsDebuggerPresent()) {960log_debug(os, thread)("set_native_thread_name: no debugger present so unable to set thread name");961return;962}963964const DWORD MS_VC_EXCEPTION = 0x406D1388;965struct {966DWORD dwType; // must be 0x1000967LPCSTR szName; // pointer to name (in user addr space)968DWORD dwThreadID; // thread ID (-1=caller thread)969DWORD dwFlags; // reserved for future use, must be zero970} info;971972info.dwType = 0x1000;973info.szName = name;974info.dwThreadID = -1;975info.dwFlags = 0;976977__try {978RaiseException (MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info );979} __except(EXCEPTION_EXECUTE_HANDLER) {}980}981982bool os::bind_to_processor(uint processor_id) {983// Not yet implemented.984return false;985}986987void os::win32::initialize_performance_counter() {988LARGE_INTEGER count;989QueryPerformanceFrequency(&count);990performance_frequency = as_long(count);991QueryPerformanceCounter(&count);992initial_performance_count = as_long(count);993}994995996double os::elapsedTime() {997return (double) elapsed_counter() / (double) elapsed_frequency();998}99910001001// Windows format:1002// The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.1003// Java format:1004// Java standards require the number of milliseconds since 1/1/197010051006// Constant offset - calculated using offset()1007static jlong _offset = 116444736000000000;1008// Fake time counter for reproducible results when debugging1009static jlong fake_time = 0;10101011#ifdef ASSERT1012// Just to be safe, recalculate the offset in debug mode1013static jlong _calculated_offset = 0;1014static int _has_calculated_offset = 0;10151016jlong offset() {1017if (_has_calculated_offset) return _calculated_offset;1018SYSTEMTIME java_origin;1019java_origin.wYear = 1970;1020java_origin.wMonth = 1;1021java_origin.wDayOfWeek = 0; // ignored1022java_origin.wDay = 1;1023java_origin.wHour = 0;1024java_origin.wMinute = 0;1025java_origin.wSecond = 0;1026java_origin.wMilliseconds = 0;1027FILETIME jot;1028if (!SystemTimeToFileTime(&java_origin, &jot)) {1029fatal("Error = %d\nWindows error", GetLastError());1030}1031_calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);1032_has_calculated_offset = 1;1033assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");1034return _calculated_offset;1035}1036#else1037jlong offset() {1038return _offset;1039}1040#endif10411042jlong windows_to_java_time(FILETIME wt) {1043jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);1044return (a - offset()) / 10000;1045}10461047// Returns time ticks in (10th of micro seconds)1048jlong windows_to_time_ticks(FILETIME wt) {1049jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);1050return (a - offset());1051}10521053FILETIME java_to_windows_time(jlong l) {1054jlong a = (l * 10000) + offset();1055FILETIME result;1056result.dwHighDateTime = high(a);1057result.dwLowDateTime = low(a);1058return result;1059}10601061bool os::supports_vtime() { return true; }10621063double os::elapsedVTime() {1064FILETIME created;1065FILETIME exited;1066FILETIME kernel;1067FILETIME user;1068if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {1069// the resolution of windows_to_java_time() should be sufficient (ms)1070return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;1071} else {1072return elapsedTime();1073}1074}10751076jlong os::javaTimeMillis() {1077FILETIME wt;1078GetSystemTimeAsFileTime(&wt);1079return windows_to_java_time(wt);1080}10811082void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {1083FILETIME wt;1084GetSystemTimeAsFileTime(&wt);1085jlong ticks = windows_to_time_ticks(wt); // 10th of micros1086jlong secs = jlong(ticks / 10000000); // 10000 * 10001087seconds = secs;1088nanos = jlong(ticks - (secs*10000000)) * 100;1089}10901091jlong os::javaTimeNanos() {1092LARGE_INTEGER current_count;1093QueryPerformanceCounter(¤t_count);1094double current = as_long(current_count);1095double freq = performance_frequency;1096jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);1097return time;1098}10991100void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {1101jlong freq = performance_frequency;1102if (freq < NANOSECS_PER_SEC) {1103// the performance counter is 64 bits and we will1104// be multiplying it -- so no wrap in 64 bits1105info_ptr->max_value = ALL_64_BITS;1106} else if (freq > NANOSECS_PER_SEC) {1107// use the max value the counter can reach to1108// determine the max value which could be returned1109julong max_counter = (julong)ALL_64_BITS;1110info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));1111} else {1112// the performance counter is 64 bits and we will1113// be using it directly -- so no wrap in 64 bits1114info_ptr->max_value = ALL_64_BITS;1115}11161117// using a counter, so no skipping1118info_ptr->may_skip_backward = false;1119info_ptr->may_skip_forward = false;11201121info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time1122}11231124char* os::local_time_string(char *buf, size_t buflen) {1125SYSTEMTIME st;1126GetLocalTime(&st);1127jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",1128st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);1129return buf;1130}11311132bool os::getTimesSecs(double* process_real_time,1133double* process_user_time,1134double* process_system_time) {1135HANDLE h_process = GetCurrentProcess();1136FILETIME create_time, exit_time, kernel_time, user_time;1137BOOL result = GetProcessTimes(h_process,1138&create_time,1139&exit_time,1140&kernel_time,1141&user_time);1142if (result != 0) {1143FILETIME wt;1144GetSystemTimeAsFileTime(&wt);1145jlong rtc_millis = windows_to_java_time(wt);1146*process_real_time = ((double) rtc_millis) / ((double) MILLIUNITS);1147*process_user_time =1148(double) jlong_from(user_time.dwHighDateTime, user_time.dwLowDateTime) / (10 * MICROUNITS);1149*process_system_time =1150(double) jlong_from(kernel_time.dwHighDateTime, kernel_time.dwLowDateTime) / (10 * MICROUNITS);1151return true;1152} else {1153return false;1154}1155}11561157void os::shutdown() {1158// allow PerfMemory to attempt cleanup of any persistent resources1159perfMemory_exit();11601161// flush buffered output, finish log files1162ostream_abort();11631164// Check for abort hook1165abort_hook_t abort_hook = Arguments::abort_hook();1166if (abort_hook != NULL) {1167abort_hook();1168}1169}117011711172static HANDLE dumpFile = NULL;11731174// Check if dump file can be created.1175void os::check_dump_limit(char* buffer, size_t buffsz) {1176bool status = true;1177if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {1178jio_snprintf(buffer, buffsz, "CreateCoredumpOnCrash is disabled from command line");1179status = false;1180}11811182#ifndef ASSERT1183if (!os::win32::is_windows_server() && FLAG_IS_DEFAULT(CreateCoredumpOnCrash)) {1184jio_snprintf(buffer, buffsz, "Minidumps are not enabled by default on client versions of Windows");1185status = false;1186}1187#endif11881189if (status) {1190const char* cwd = get_current_directory(NULL, 0);1191int pid = current_process_id();1192if (cwd != NULL) {1193jio_snprintf(buffer, buffsz, "%s\\hs_err_pid%u.mdmp", cwd, pid);1194} else {1195jio_snprintf(buffer, buffsz, ".\\hs_err_pid%u.mdmp", pid);1196}11971198if (dumpFile == NULL &&1199(dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))1200== INVALID_HANDLE_VALUE) {1201jio_snprintf(buffer, buffsz, "Failed to create minidump file (0x%x).", GetLastError());1202status = false;1203}1204}1205VMError::record_coredump_status(buffer, status);1206}12071208void os::abort(bool dump_core, void* siginfo, const void* context) {1209EXCEPTION_POINTERS ep;1210MINIDUMP_EXCEPTION_INFORMATION mei;1211MINIDUMP_EXCEPTION_INFORMATION* pmei;12121213HANDLE hProcess = GetCurrentProcess();1214DWORD processId = GetCurrentProcessId();1215MINIDUMP_TYPE dumpType;12161217shutdown();1218if (!dump_core || dumpFile == NULL) {1219if (dumpFile != NULL) {1220CloseHandle(dumpFile);1221}1222win32::exit_process_or_thread(win32::EPT_PROCESS, 1);1223}12241225dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData |1226MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules);12271228if (siginfo != NULL && context != NULL) {1229ep.ContextRecord = (PCONTEXT) context;1230ep.ExceptionRecord = (PEXCEPTION_RECORD) siginfo;12311232mei.ThreadId = GetCurrentThreadId();1233mei.ExceptionPointers = &ep;1234pmei = &mei;1235} else {1236pmei = NULL;1237}12381239// Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all1240// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.1241if (!WindowsDbgHelp::miniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) &&1242!WindowsDbgHelp::miniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL)) {1243jio_fprintf(stderr, "Call to MiniDumpWriteDump() failed (Error 0x%x)\n", GetLastError());1244}1245CloseHandle(dumpFile);1246win32::exit_process_or_thread(win32::EPT_PROCESS, 1);1247}12481249// Die immediately, no exit hook, no abort hook, no cleanup.1250void os::die() {1251win32::exit_process_or_thread(win32::EPT_PROCESS_DIE, -1);1252}12531254const char* os::dll_file_extension() { return ".dll"; }12551256void os::dll_unload(void *lib) {1257char name[MAX_PATH];1258if (::GetModuleFileName((HMODULE)lib, name, sizeof(name)) == 0) {1259snprintf(name, MAX_PATH, "<not available>");1260}1261if (::FreeLibrary((HMODULE)lib)) {1262Events::log_dll_message(NULL, "Unloaded dll \"%s\" [" INTPTR_FORMAT "]", name, p2i(lib));1263log_info(os)("Unloaded dll \"%s\" [" INTPTR_FORMAT "]", name, p2i(lib));1264} else {1265const DWORD errcode = ::GetLastError();1266Events::log_dll_message(NULL, "Attempt to unload dll \"%s\" [" INTPTR_FORMAT "] failed (error code %d)", name, p2i(lib), errcode);1267log_info(os)("Attempt to unload dll \"%s\" [" INTPTR_FORMAT "] failed (error code %d)", name, p2i(lib), errcode);1268}1269}12701271void* os::dll_lookup(void *lib, const char *name) {1272return (void*)::GetProcAddress((HMODULE)lib, name);1273}12741275// Directory routines copied from src/win32/native/java/io/dirent_md.c1276// * dirent_md.c 1.15 00/02/021277//1278// The declarations for DIR and struct dirent are in jvm_win32.h.12791280// Caller must have already run dirname through JVM_NativePath, which removes1281// duplicate slashes and converts all instances of '/' into '\\'.12821283DIR * os::opendir(const char *dirname) {1284assert(dirname != NULL, "just checking"); // hotspot change1285DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal);1286DWORD fattr; // hotspot change1287char alt_dirname[4] = { 0, 0, 0, 0 };12881289if (dirp == 0) {1290errno = ENOMEM;1291return 0;1292}12931294// Win32 accepts "\" in its POSIX stat(), but refuses to treat it1295// as a directory in FindFirstFile(). We detect this case here and1296// prepend the current drive name.1297//1298if (dirname[1] == '\0' && dirname[0] == '\\') {1299alt_dirname[0] = _getdrive() + 'A' - 1;1300alt_dirname[1] = ':';1301alt_dirname[2] = '\\';1302alt_dirname[3] = '\0';1303dirname = alt_dirname;1304}13051306dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);1307if (dirp->path == 0) {1308free(dirp);1309errno = ENOMEM;1310return 0;1311}1312strcpy(dirp->path, dirname);13131314fattr = GetFileAttributes(dirp->path);1315if (fattr == 0xffffffff) {1316free(dirp->path);1317free(dirp);1318errno = ENOENT;1319return 0;1320} else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {1321free(dirp->path);1322free(dirp);1323errno = ENOTDIR;1324return 0;1325}13261327// Append "*.*", or possibly "\\*.*", to path1328if (dirp->path[1] == ':' &&1329(dirp->path[2] == '\0' ||1330(dirp->path[2] == '\\' && dirp->path[3] == '\0'))) {1331// No '\\' needed for cases like "Z:" or "Z:\"1332strcat(dirp->path, "*.*");1333} else {1334strcat(dirp->path, "\\*.*");1335}13361337dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);1338if (dirp->handle == INVALID_HANDLE_VALUE) {1339if (GetLastError() != ERROR_FILE_NOT_FOUND) {1340free(dirp->path);1341free(dirp);1342errno = EACCES;1343return 0;1344}1345}1346return dirp;1347}13481349struct dirent * os::readdir(DIR *dirp) {1350assert(dirp != NULL, "just checking"); // hotspot change1351if (dirp->handle == INVALID_HANDLE_VALUE) {1352return NULL;1353}13541355strcpy(dirp->dirent.d_name, dirp->find_data.cFileName);13561357if (!FindNextFile(dirp->handle, &dirp->find_data)) {1358if (GetLastError() == ERROR_INVALID_HANDLE) {1359errno = EBADF;1360return NULL;1361}1362FindClose(dirp->handle);1363dirp->handle = INVALID_HANDLE_VALUE;1364}13651366return &dirp->dirent;1367}13681369int os::closedir(DIR *dirp) {1370assert(dirp != NULL, "just checking"); // hotspot change1371if (dirp->handle != INVALID_HANDLE_VALUE) {1372if (!FindClose(dirp->handle)) {1373errno = EBADF;1374return -1;1375}1376dirp->handle = INVALID_HANDLE_VALUE;1377}1378free(dirp->path);1379free(dirp);1380return 0;1381}13821383// This must be hard coded because it's the system's temporary1384// directory not the java application's temp directory, ala java.io.tmpdir.1385const char* os::get_temp_directory() {1386static char path_buf[MAX_PATH];1387if (GetTempPath(MAX_PATH, path_buf) > 0) {1388return path_buf;1389} else {1390path_buf[0] = '\0';1391return path_buf;1392}1393}13941395// Needs to be in os specific directory because windows requires another1396// header file <direct.h>1397const char* os::get_current_directory(char *buf, size_t buflen) {1398int n = static_cast<int>(buflen);1399if (buflen > INT_MAX) n = INT_MAX;1400return _getcwd(buf, n);1401}14021403//-----------------------------------------------------------1404// Helper functions for fatal error handler1405#ifdef _WIN641406// Helper routine which returns true if address in1407// within the NTDLL address space.1408//1409static bool _addr_in_ntdll(address addr) {1410HMODULE hmod;1411MODULEINFO minfo;14121413hmod = GetModuleHandle("NTDLL.DLL");1414if (hmod == NULL) return false;1415if (!GetModuleInformation(GetCurrentProcess(), hmod,1416&minfo, sizeof(MODULEINFO))) {1417return false;1418}14191420if ((addr >= minfo.lpBaseOfDll) &&1421(addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage))) {1422return true;1423} else {1424return false;1425}1426}1427#endif14281429struct _modinfo {1430address addr;1431char* full_path; // point to a char buffer1432int buflen; // size of the buffer1433address base_addr;1434};14351436static int _locate_module_by_addr(const char * mod_fname, address base_addr,1437address top_address, void * param) {1438struct _modinfo *pmod = (struct _modinfo *)param;1439if (!pmod) return -1;14401441if (base_addr <= pmod->addr &&1442top_address > pmod->addr) {1443// if a buffer is provided, copy path name to the buffer1444if (pmod->full_path) {1445jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname);1446}1447pmod->base_addr = base_addr;1448return 1;1449}1450return 0;1451}14521453bool os::dll_address_to_library_name(address addr, char* buf,1454int buflen, int* offset) {1455// buf is not optional, but offset is optional1456assert(buf != NULL, "sanity check");14571458// NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always1459// return the full path to the DLL file, sometimes it returns path1460// to the corresponding PDB file (debug info); sometimes it only1461// returns partial path, which makes life painful.14621463struct _modinfo mi;1464mi.addr = addr;1465mi.full_path = buf;1466mi.buflen = buflen;1467if (get_loaded_modules_info(_locate_module_by_addr, (void *)&mi)) {1468// buf already contains path name1469if (offset) *offset = addr - mi.base_addr;1470return true;1471}14721473buf[0] = '\0';1474if (offset) *offset = -1;1475return false;1476}14771478bool os::dll_address_to_function_name(address addr, char *buf,1479int buflen, int *offset,1480bool demangle) {1481// buf is not optional, but offset is optional1482assert(buf != NULL, "sanity check");14831484if (Decoder::decode(addr, buf, buflen, offset, demangle)) {1485return true;1486}1487if (offset != NULL) *offset = -1;1488buf[0] = '\0';1489return false;1490}14911492// save the start and end address of jvm.dll into param[0] and param[1]1493static int _locate_jvm_dll(const char* mod_fname, address base_addr,1494address top_address, void * param) {1495if (!param) return -1;14961497if (base_addr <= (address)_locate_jvm_dll &&1498top_address > (address)_locate_jvm_dll) {1499((address*)param)[0] = base_addr;1500((address*)param)[1] = top_address;1501return 1;1502}1503return 0;1504}15051506address vm_lib_location[2]; // start and end address of jvm.dll15071508// check if addr is inside jvm.dll1509bool os::address_is_in_vm(address addr) {1510if (!vm_lib_location[0] || !vm_lib_location[1]) {1511if (!get_loaded_modules_info(_locate_jvm_dll, (void *)vm_lib_location)) {1512assert(false, "Can't find jvm module.");1513return false;1514}1515}15161517return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]);1518}15191520// print module info; param is outputStream*1521static int _print_module(const char* fname, address base_address,1522address top_address, void* param) {1523if (!param) return -1;15241525outputStream* st = (outputStream*)param;15261527st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base_address, top_address, fname);1528return 0;1529}15301531// Loads .dll/.so and1532// in case of error it checks if .dll/.so was built for the1533// same architecture as Hotspot is running on1534void * os::dll_load(const char *name, char *ebuf, int ebuflen) {1535log_info(os)("attempting shared library load of %s", name);15361537void * result = LoadLibrary(name);1538if (result != NULL) {1539Events::log_dll_message(NULL, "Loaded shared library %s", name);1540// Recalculate pdb search path if a DLL was loaded successfully.1541SymbolEngine::recalc_search_path();1542log_info(os)("shared library load of %s was successful", name);1543return result;1544}1545DWORD errcode = GetLastError();1546// Read system error message into ebuf1547// It may or may not be overwritten below (in the for loop and just above)1548lasterror(ebuf, (size_t) ebuflen);1549ebuf[ebuflen - 1] = '\0';1550Events::log_dll_message(NULL, "Loading shared library %s failed, error code %lu", name, errcode);1551log_info(os)("shared library load of %s failed, error code %lu", name, errcode);15521553if (errcode == ERROR_MOD_NOT_FOUND) {1554strncpy(ebuf, "Can't find dependent libraries", ebuflen - 1);1555ebuf[ebuflen - 1] = '\0';1556return NULL;1557}15581559// Parsing dll below1560// If we can read dll-info and find that dll was built1561// for an architecture other than Hotspot is running in1562// - then print to buffer "DLL was built for a different architecture"1563// else call os::lasterror to obtain system error message1564int fd = ::open(name, O_RDONLY | O_BINARY, 0);1565if (fd < 0) {1566return NULL;1567}15681569uint32_t signature_offset;1570uint16_t lib_arch = 0;1571bool failed_to_get_lib_arch =1572( // Go to position 3c in the dll1573(os::seek_to_file_offset(fd, IMAGE_FILE_PTR_TO_SIGNATURE) < 0)1574||1575// Read location of signature1576(sizeof(signature_offset) !=1577(os::read(fd, (void*)&signature_offset, sizeof(signature_offset))))1578||1579// Go to COFF File Header in dll1580// that is located after "signature" (4 bytes long)1581(os::seek_to_file_offset(fd,1582signature_offset + IMAGE_FILE_SIGNATURE_LENGTH) < 0)1583||1584// Read field that contains code of architecture1585// that dll was built for1586(sizeof(lib_arch) != (os::read(fd, (void*)&lib_arch, sizeof(lib_arch))))1587);15881589::close(fd);1590if (failed_to_get_lib_arch) {1591// file i/o error - report os::lasterror(...) msg1592return NULL;1593}15941595typedef struct {1596uint16_t arch_code;1597char* arch_name;1598} arch_t;15991600static const arch_t arch_array[] = {1601{IMAGE_FILE_MACHINE_I386, (char*)"IA 32"},1602{IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"},1603{IMAGE_FILE_MACHINE_ARM64, (char*)"ARM 64"}1604};1605#if (defined _M_ARM64)1606static const uint16_t running_arch = IMAGE_FILE_MACHINE_ARM64;1607#elif (defined _M_AMD64)1608static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64;1609#elif (defined _M_IX86)1610static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386;1611#else1612#error Method os::dll_load requires that one of following \1613is defined :_M_AMD64 or _M_IX86 or _M_ARM641614#endif161516161617// Obtain a string for printf operation1618// lib_arch_str shall contain string what platform this .dll was built for1619// running_arch_str shall string contain what platform Hotspot was built for1620char *running_arch_str = NULL, *lib_arch_str = NULL;1621for (unsigned int i = 0; i < ARRAY_SIZE(arch_array); i++) {1622if (lib_arch == arch_array[i].arch_code) {1623lib_arch_str = arch_array[i].arch_name;1624}1625if (running_arch == arch_array[i].arch_code) {1626running_arch_str = arch_array[i].arch_name;1627}1628}16291630assert(running_arch_str,1631"Didn't find running architecture code in arch_array");16321633// If the architecture is right1634// but some other error took place - report os::lasterror(...) msg1635if (lib_arch == running_arch) {1636return NULL;1637}16381639if (lib_arch_str != NULL) {1640::_snprintf(ebuf, ebuflen - 1,1641"Can't load %s-bit .dll on a %s-bit platform",1642lib_arch_str, running_arch_str);1643} else {1644// don't know what architecture this dll was build for1645::_snprintf(ebuf, ebuflen - 1,1646"Can't load this .dll (machine code=0x%x) on a %s-bit platform",1647lib_arch, running_arch_str);1648}16491650return NULL;1651}16521653void os::print_dll_info(outputStream *st) {1654st->print_cr("Dynamic libraries:");1655get_loaded_modules_info(_print_module, (void *)st);1656}16571658int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {1659HANDLE hProcess;16601661# define MAX_NUM_MODULES 1281662HMODULE modules[MAX_NUM_MODULES];1663static char filename[MAX_PATH];1664int result = 0;16651666int pid = os::current_process_id();1667hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,1668FALSE, pid);1669if (hProcess == NULL) return 0;16701671DWORD size_needed;1672if (!EnumProcessModules(hProcess, modules, sizeof(modules), &size_needed)) {1673CloseHandle(hProcess);1674return 0;1675}16761677// number of modules that are currently loaded1678int num_modules = size_needed / sizeof(HMODULE);16791680for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {1681// Get Full pathname:1682if (!GetModuleFileNameEx(hProcess, modules[i], filename, sizeof(filename))) {1683filename[0] = '\0';1684}16851686MODULEINFO modinfo;1687if (!GetModuleInformation(hProcess, modules[i], &modinfo, sizeof(modinfo))) {1688modinfo.lpBaseOfDll = NULL;1689modinfo.SizeOfImage = 0;1690}16911692// Invoke callback function1693result = callback(filename, (address)modinfo.lpBaseOfDll,1694(address)((u8)modinfo.lpBaseOfDll + (u8)modinfo.SizeOfImage), param);1695if (result) break;1696}16971698CloseHandle(hProcess);1699return result;1700}17011702bool os::get_host_name(char* buf, size_t buflen) {1703DWORD size = (DWORD)buflen;1704return (GetComputerNameEx(ComputerNameDnsHostname, buf, &size) == TRUE);1705}17061707void os::get_summary_os_info(char* buf, size_t buflen) {1708stringStream sst(buf, buflen);1709os::win32::print_windows_version(&sst);1710// chop off newline character1711char* nl = strchr(buf, '\n');1712if (nl != NULL) *nl = '\0';1713}17141715int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) {1716#if _MSC_VER >= 19001717// Starting with Visual Studio 2015, vsnprint is C99 compliant.1718int result = ::vsnprintf(buf, len, fmt, args);1719// If an encoding error occurred (result < 0) then it's not clear1720// whether the buffer is NUL terminated, so ensure it is.1721if ((result < 0) && (len > 0)) {1722buf[len - 1] = '\0';1723}1724return result;1725#else1726// Before Visual Studio 2015, vsnprintf is not C99 compliant, so use1727// _vsnprintf, whose behavior seems to be *mostly* consistent across1728// versions. However, when len == 0, avoid _vsnprintf too, and just1729// go straight to _vscprintf. The output is going to be truncated in1730// that case, except in the unusual case of empty output. More1731// importantly, the documentation for various versions of Visual Studio1732// are inconsistent about the behavior of _vsnprintf when len == 0,1733// including it possibly being an error.1734int result = -1;1735if (len > 0) {1736result = _vsnprintf(buf, len, fmt, args);1737// If output (including NUL terminator) is truncated, the buffer1738// won't be NUL terminated. Add the trailing NUL specified by C99.1739if ((result < 0) || ((size_t)result >= len)) {1740buf[len - 1] = '\0';1741}1742}1743if (result < 0) {1744result = _vscprintf(fmt, args);1745}1746return result;1747#endif // _MSC_VER dispatch1748}17491750static inline time_t get_mtime(const char* filename) {1751struct stat st;1752int ret = os::stat(filename, &st);1753assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno));1754return st.st_mtime;1755}17561757int os::compare_file_modified_times(const char* file1, const char* file2) {1758time_t t1 = get_mtime(file1);1759time_t t2 = get_mtime(file2);1760return t1 - t2;1761}17621763void os::print_os_info_brief(outputStream* st) {1764os::print_os_info(st);1765}17661767void os::win32::print_uptime_info(outputStream* st) {1768unsigned long long ticks = GetTickCount64();1769os::print_dhm(st, "OS uptime:", ticks/1000);1770}17711772void os::print_os_info(outputStream* st) {1773#ifdef ASSERT1774char buffer[1024];1775st->print("HostName: ");1776if (get_host_name(buffer, sizeof(buffer))) {1777st->print_cr(buffer);1778} else {1779st->print_cr("N/A");1780}1781#endif1782st->print_cr("OS:");1783os::win32::print_windows_version(st);17841785os::win32::print_uptime_info(st);17861787VM_Version::print_platform_virtualization_info(st);1788}17891790void os::win32::print_windows_version(outputStream* st) {1791OSVERSIONINFOEX osvi;1792VS_FIXEDFILEINFO *file_info;1793TCHAR kernel32_path[MAX_PATH];1794UINT len, ret;17951796// Use the GetVersionEx information to see if we're on a server or1797// workstation edition of Windows. Starting with Windows 8.1 we can't1798// trust the OS version information returned by this API.1799ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));1800osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);1801if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {1802st->print_cr("Call to GetVersionEx failed");1803return;1804}1805bool is_workstation = (osvi.wProductType == VER_NT_WORKSTATION);18061807// Get the full path to \Windows\System32\kernel32.dll and use that for1808// determining what version of Windows we're running on.1809len = MAX_PATH - (UINT)strlen("\\kernel32.dll") - 1;1810ret = GetSystemDirectory(kernel32_path, len);1811if (ret == 0 || ret > len) {1812st->print_cr("Call to GetSystemDirectory failed");1813return;1814}1815strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);18161817DWORD version_size = GetFileVersionInfoSize(kernel32_path, NULL);1818if (version_size == 0) {1819st->print_cr("Call to GetFileVersionInfoSize failed");1820return;1821}18221823LPTSTR version_info = (LPTSTR)os::malloc(version_size, mtInternal);1824if (version_info == NULL) {1825st->print_cr("Failed to allocate version_info");1826return;1827}18281829if (!GetFileVersionInfo(kernel32_path, NULL, version_size, version_info)) {1830os::free(version_info);1831st->print_cr("Call to GetFileVersionInfo failed");1832return;1833}18341835if (!VerQueryValue(version_info, TEXT("\\"), (LPVOID*)&file_info, &len)) {1836os::free(version_info);1837st->print_cr("Call to VerQueryValue failed");1838return;1839}18401841int major_version = HIWORD(file_info->dwProductVersionMS);1842int minor_version = LOWORD(file_info->dwProductVersionMS);1843int build_number = HIWORD(file_info->dwProductVersionLS);1844int build_minor = LOWORD(file_info->dwProductVersionLS);1845int os_vers = major_version * 1000 + minor_version;1846os::free(version_info);18471848st->print(" Windows ");1849switch (os_vers) {18501851case 6000:1852if (is_workstation) {1853st->print("Vista");1854} else {1855st->print("Server 2008");1856}1857break;18581859case 6001:1860if (is_workstation) {1861st->print("7");1862} else {1863st->print("Server 2008 R2");1864}1865break;18661867case 6002:1868if (is_workstation) {1869st->print("8");1870} else {1871st->print("Server 2012");1872}1873break;18741875case 6003:1876if (is_workstation) {1877st->print("8.1");1878} else {1879st->print("Server 2012 R2");1880}1881break;18821883case 10000:1884if (is_workstation) {1885if (build_number >= 22000) {1886st->print("11");1887} else {1888st->print("10");1889}1890} else {1891// distinguish Windows Server by build number1892// - 2016 GA 10/2016 build: 143931893// - 2019 GA 11/2018 build: 177631894// - 2022 GA 08/2021 build: 203481895if (build_number > 20347) {1896st->print("Server 2022");1897} else if (build_number > 17762) {1898st->print("Server 2019");1899} else {1900st->print("Server 2016");1901}1902}1903break;19041905default:1906// Unrecognized windows, print out its major and minor versions1907st->print("%d.%d", major_version, minor_version);1908break;1909}19101911// Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could1912// find out whether we are running on 64 bit processor or not1913SYSTEM_INFO si;1914ZeroMemory(&si, sizeof(SYSTEM_INFO));1915GetNativeSystemInfo(&si);1916if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||1917(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) {1918st->print(" , 64 bit");1919}19201921st->print(" Build %d", build_number);1922st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);1923st->cr();1924}19251926void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {1927// Nothing to do for now.1928}19291930void os::get_summary_cpu_info(char* buf, size_t buflen) {1931HKEY key;1932DWORD status = RegOpenKey(HKEY_LOCAL_MACHINE,1933"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key);1934if (status == ERROR_SUCCESS) {1935DWORD size = (DWORD)buflen;1936status = RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (byte*)buf, &size);1937if (status != ERROR_SUCCESS) {1938strncpy(buf, "## __CPU__", buflen);1939}1940RegCloseKey(key);1941} else {1942// Put generic cpu info to return1943strncpy(buf, "## __CPU__", buflen);1944}1945}19461947void os::print_memory_info(outputStream* st) {1948st->print("Memory:");1949st->print(" %dk page", os::vm_page_size()>>10);19501951// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect1952// value if total memory is larger than 4GB1953MEMORYSTATUSEX ms;1954ms.dwLength = sizeof(ms);1955int r1 = GlobalMemoryStatusEx(&ms);19561957if (r1 != 0) {1958st->print(", system-wide physical " INT64_FORMAT "M ",1959(int64_t) ms.ullTotalPhys >> 20);1960st->print("(" INT64_FORMAT "M free)\n", (int64_t) ms.ullAvailPhys >> 20);19611962st->print("TotalPageFile size " INT64_FORMAT "M ",1963(int64_t) ms.ullTotalPageFile >> 20);1964st->print("(AvailPageFile size " INT64_FORMAT "M)",1965(int64_t) ms.ullAvailPageFile >> 20);19661967// on 32bit Total/AvailVirtual are interesting (show us how close we get to 2-4 GB per process borders)1968#if defined(_M_IX86)1969st->print(", user-mode portion of virtual address-space " INT64_FORMAT "M ",1970(int64_t) ms.ullTotalVirtual >> 20);1971st->print("(" INT64_FORMAT "M free)", (int64_t) ms.ullAvailVirtual >> 20);1972#endif1973} else {1974st->print(", GlobalMemoryStatusEx did not succeed so we miss some memory values.");1975}19761977// extended memory statistics for a process1978PROCESS_MEMORY_COUNTERS_EX pmex;1979ZeroMemory(&pmex, sizeof(PROCESS_MEMORY_COUNTERS_EX));1980pmex.cb = sizeof(pmex);1981int r2 = GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmex, sizeof(pmex));19821983if (r2 != 0) {1984st->print("\ncurrent process WorkingSet (physical memory assigned to process): " INT64_FORMAT "M, ",1985(int64_t) pmex.WorkingSetSize >> 20);1986st->print("peak: " INT64_FORMAT "M\n", (int64_t) pmex.PeakWorkingSetSize >> 20);19871988st->print("current process commit charge (\"private bytes\"): " INT64_FORMAT "M, ",1989(int64_t) pmex.PrivateUsage >> 20);1990st->print("peak: " INT64_FORMAT "M", (int64_t) pmex.PeakPagefileUsage >> 20);1991} else {1992st->print("\nGetProcessMemoryInfo did not succeed so we miss some memory values.");1993}19941995st->cr();1996}19971998bool os::signal_sent_by_kill(const void* siginfo) {1999// TODO: Is this possible?2000return false;2001}20022003void os::print_siginfo(outputStream *st, const void* siginfo) {2004const EXCEPTION_RECORD* const er = (EXCEPTION_RECORD*)siginfo;2005st->print("siginfo:");20062007char tmp[64];2008if (os::exception_name(er->ExceptionCode, tmp, sizeof(tmp)) == NULL) {2009strcpy(tmp, "EXCEPTION_??");2010}2011st->print(" %s (0x%x)", tmp, er->ExceptionCode);20122013if ((er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||2014er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) &&2015er->NumberParameters >= 2) {2016switch (er->ExceptionInformation[0]) {2017case 0: st->print(", reading address"); break;2018case 1: st->print(", writing address"); break;2019case 8: st->print(", data execution prevention violation at address"); break;2020default: st->print(", ExceptionInformation=" INTPTR_FORMAT,2021er->ExceptionInformation[0]);2022}2023st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);2024} else {2025int num = er->NumberParameters;2026if (num > 0) {2027st->print(", ExceptionInformation=");2028for (int i = 0; i < num; i++) {2029st->print(INTPTR_FORMAT " ", er->ExceptionInformation[i]);2030}2031}2032}2033st->cr();2034}20352036bool os::signal_thread(Thread* thread, int sig, const char* reason) {2037// TODO: Can we kill thread?2038return false;2039}20402041void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {2042// do nothing2043}20442045static char saved_jvm_path[MAX_PATH] = {0};20462047// Find the full path to the current module, jvm.dll2048void os::jvm_path(char *buf, jint buflen) {2049// Error checking.2050if (buflen < MAX_PATH) {2051assert(false, "must use a large-enough buffer");2052buf[0] = '\0';2053return;2054}2055// Lazy resolve the path to current module.2056if (saved_jvm_path[0] != 0) {2057strcpy(buf, saved_jvm_path);2058return;2059}20602061buf[0] = '\0';2062if (Arguments::sun_java_launcher_is_altjvm()) {2063// Support for the java launcher's '-XXaltjvm=<path>' option. Check2064// for a JAVA_HOME environment variable and fix up the path so it2065// looks like jvm.dll is installed there (append a fake suffix2066// hotspot/jvm.dll).2067char* java_home_var = ::getenv("JAVA_HOME");2068if (java_home_var != NULL && java_home_var[0] != 0 &&2069strlen(java_home_var) < (size_t)buflen) {2070strncpy(buf, java_home_var, buflen);20712072// determine if this is a legacy image or modules image2073// modules image doesn't have "jre" subdirectory2074size_t len = strlen(buf);2075char* jrebin_p = buf + len;2076jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\");2077if (0 != _access(buf, 0)) {2078jio_snprintf(jrebin_p, buflen-len, "\\bin\\");2079}2080len = strlen(buf);2081jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll");2082}2083}20842085if (buf[0] == '\0') {2086GetModuleFileName(vm_lib_handle, buf, buflen);2087}2088strncpy(saved_jvm_path, buf, MAX_PATH);2089saved_jvm_path[MAX_PATH - 1] = '\0';2090}209120922093void os::print_jni_name_prefix_on(outputStream* st, int args_size) {2094#ifndef _WIN642095st->print("_");2096#endif2097}209820992100void os::print_jni_name_suffix_on(outputStream* st, int args_size) {2101#ifndef _WIN642102st->print("@%d", args_size * sizeof(int));2103#endif2104}21052106// This method is a copy of JDK's sysGetLastErrorString2107// from src/windows/hpi/src/system_md.c21082109size_t os::lasterror(char* buf, size_t len) {2110DWORD errval;21112112if ((errval = GetLastError()) != 0) {2113// DOS error2114size_t n = (size_t)FormatMessage(2115FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,2116NULL,2117errval,21180,2119buf,2120(DWORD)len,2121NULL);2122if (n > 3) {2123// Drop final '.', CR, LF2124if (buf[n - 1] == '\n') n--;2125if (buf[n - 1] == '\r') n--;2126if (buf[n - 1] == '.') n--;2127buf[n] = '\0';2128}2129return n;2130}21312132if (errno != 0) {2133// C runtime error that has no corresponding DOS error code2134const char* s = os::strerror(errno);2135size_t n = strlen(s);2136if (n >= len) n = len - 1;2137strncpy(buf, s, n);2138buf[n] = '\0';2139return n;2140}21412142return 0;2143}21442145int os::get_last_error() {2146DWORD error = GetLastError();2147if (error == 0) {2148error = errno;2149}2150return (int)error;2151}21522153// sun.misc.Signal2154// NOTE that this is a workaround for an apparent kernel bug where if2155// a signal handler for SIGBREAK is installed then that signal handler2156// takes priority over the console control handler for CTRL_CLOSE_EVENT.2157// See bug 4416763.2158static void (*sigbreakHandler)(int) = NULL;21592160static void UserHandler(int sig, void *siginfo, void *context) {2161os::signal_notify(sig);2162// We need to reinstate the signal handler each time...2163os::signal(sig, (void*)UserHandler);2164}21652166void* os::user_handler() {2167return (void*) UserHandler;2168}21692170void* os::signal(int signal_number, void* handler) {2171if ((signal_number == SIGBREAK) && (!ReduceSignalUsage)) {2172void (*oldHandler)(int) = sigbreakHandler;2173sigbreakHandler = (void (*)(int)) handler;2174return (void*) oldHandler;2175} else {2176return (void*)::signal(signal_number, (void (*)(int))handler);2177}2178}21792180void os::signal_raise(int signal_number) {2181raise(signal_number);2182}21832184// The Win32 C runtime library maps all console control events other than ^C2185// into SIGBREAK, which makes it impossible to distinguish ^BREAK from close,2186// logoff, and shutdown events. We therefore install our own console handler2187// that raises SIGTERM for the latter cases.2188//2189static BOOL WINAPI consoleHandler(DWORD event) {2190switch (event) {2191case CTRL_C_EVENT:2192if (VMError::is_error_reported()) {2193// Ctrl-C is pressed during error reporting, likely because the error2194// handler fails to abort. Let VM die immediately.2195os::die();2196}21972198os::signal_raise(SIGINT);2199return TRUE;2200break;2201case CTRL_BREAK_EVENT:2202if (sigbreakHandler != NULL) {2203(*sigbreakHandler)(SIGBREAK);2204}2205return TRUE;2206break;2207case CTRL_LOGOFF_EVENT: {2208// Don't terminate JVM if it is running in a non-interactive session,2209// such as a service process.2210USEROBJECTFLAGS flags;2211HANDLE handle = GetProcessWindowStation();2212if (handle != NULL &&2213GetUserObjectInformation(handle, UOI_FLAGS, &flags,2214sizeof(USEROBJECTFLAGS), NULL)) {2215// If it is a non-interactive session, let next handler to deal2216// with it.2217if ((flags.dwFlags & WSF_VISIBLE) == 0) {2218return FALSE;2219}2220}2221}2222case CTRL_CLOSE_EVENT:2223case CTRL_SHUTDOWN_EVENT:2224os::signal_raise(SIGTERM);2225return TRUE;2226break;2227default:2228break;2229}2230return FALSE;2231}22322233// The following code is moved from os.cpp for making this2234// code platform specific, which it is by its very nature.22352236// Return maximum OS signal used + 1 for internal use only2237// Used as exit signal for signal_thread2238int os::sigexitnum_pd() {2239return NSIG;2240}22412242// a counter for each possible signal value, including signal_thread exit signal2243static volatile jint pending_signals[NSIG+1] = { 0 };2244static Semaphore* sig_sem = NULL;22452246static void jdk_misc_signal_init() {2247// Initialize signal structures2248memset((void*)pending_signals, 0, sizeof(pending_signals));22492250// Initialize signal semaphore2251sig_sem = new Semaphore();22522253// Programs embedding the VM do not want it to attempt to receive2254// events like CTRL_LOGOFF_EVENT, which are used to implement the2255// shutdown hooks mechanism introduced in 1.3. For example, when2256// the VM is run as part of a Windows NT service (i.e., a servlet2257// engine in a web server), the correct behavior is for any console2258// control handler to return FALSE, not TRUE, because the OS's2259// "final" handler for such events allows the process to continue if2260// it is a service (while terminating it if it is not a service).2261// To make this behavior uniform and the mechanism simpler, we2262// completely disable the VM's usage of these console events if -Xrs2263// (=ReduceSignalUsage) is specified. This means, for example, that2264// the CTRL-BREAK thread dump mechanism is also disabled in this2265// case. See bugs 4323062, 4345157, and related bugs.22662267// Add a CTRL-C handler2268SetConsoleCtrlHandler(consoleHandler, TRUE);2269}22702271void os::signal_notify(int sig) {2272if (sig_sem != NULL) {2273Atomic::inc(&pending_signals[sig]);2274sig_sem->signal();2275} else {2276// Signal thread is not created with ReduceSignalUsage and jdk_misc_signal_init2277// initialization isn't called.2278assert(ReduceSignalUsage, "signal semaphore should be created");2279}2280}22812282static int check_pending_signals() {2283while (true) {2284for (int i = 0; i < NSIG + 1; i++) {2285jint n = pending_signals[i];2286if (n > 0 && n == Atomic::cmpxchg(&pending_signals[i], n, n - 1)) {2287return i;2288}2289}2290sig_sem->wait_with_safepoint_check(JavaThread::current());2291}2292ShouldNotReachHere();2293return 0; // Satisfy compiler2294}22952296int os::signal_wait() {2297return check_pending_signals();2298}22992300// Implicit OS exception handling23012302LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,2303address handler) {2304Thread* thread = Thread::current_or_null();23052306#if defined(_M_ARM64)2307#define PC_NAME Pc2308#elif defined(_M_AMD64)2309#define PC_NAME Rip2310#elif defined(_M_IX86)2311#define PC_NAME Eip2312#else2313#error unknown architecture2314#endif23152316// Save pc in thread2317if (thread != nullptr && thread->is_Java_thread()) {2318thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->PC_NAME);2319}23202321// Set pc to handler2322exceptionInfo->ContextRecord->PC_NAME = (DWORD64)handler;23232324// Continue the execution2325return EXCEPTION_CONTINUE_EXECUTION;2326}232723282329// Used for PostMortemDump2330extern "C" void safepoints();2331extern "C" void find(int x);2332extern "C" void events();23332334// According to Windows API documentation, an illegal instruction sequence should generate2335// the 0xC000001C exception code. However, real world experience shows that occasionnaly2336// the execution of an illegal instruction can generate the exception code 0xC000001E. This2337// seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).23382339#define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E23402341// From "Execution Protection in the Windows Operating System" draft 0.352342// Once a system header becomes available, the "real" define should be2343// included or copied here.2344#define EXCEPTION_INFO_EXEC_VIOLATION 0x0823452346// Windows Vista/2008 heap corruption check2347#define EXCEPTION_HEAP_CORRUPTION 0xC000037423482349// All Visual C++ exceptions thrown from code generated by the Microsoft Visual2350// C++ compiler contain this error code. Because this is a compiler-generated2351// error, the code is not listed in the Win32 API header files.2352// The code is actually a cryptic mnemonic device, with the initial "E"2353// standing for "exception" and the final 3 bytes (0x6D7363) representing the2354// ASCII values of "msc".23552356#define EXCEPTION_UNCAUGHT_CXX_EXCEPTION 0xE06D736323572358#define def_excpt(val) { #val, (val) }23592360static const struct { const char* name; uint number; } exceptlabels[] = {2361def_excpt(EXCEPTION_ACCESS_VIOLATION),2362def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),2363def_excpt(EXCEPTION_BREAKPOINT),2364def_excpt(EXCEPTION_SINGLE_STEP),2365def_excpt(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),2366def_excpt(EXCEPTION_FLT_DENORMAL_OPERAND),2367def_excpt(EXCEPTION_FLT_DIVIDE_BY_ZERO),2368def_excpt(EXCEPTION_FLT_INEXACT_RESULT),2369def_excpt(EXCEPTION_FLT_INVALID_OPERATION),2370def_excpt(EXCEPTION_FLT_OVERFLOW),2371def_excpt(EXCEPTION_FLT_STACK_CHECK),2372def_excpt(EXCEPTION_FLT_UNDERFLOW),2373def_excpt(EXCEPTION_INT_DIVIDE_BY_ZERO),2374def_excpt(EXCEPTION_INT_OVERFLOW),2375def_excpt(EXCEPTION_PRIV_INSTRUCTION),2376def_excpt(EXCEPTION_IN_PAGE_ERROR),2377def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION),2378def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION_2),2379def_excpt(EXCEPTION_NONCONTINUABLE_EXCEPTION),2380def_excpt(EXCEPTION_STACK_OVERFLOW),2381def_excpt(EXCEPTION_INVALID_DISPOSITION),2382def_excpt(EXCEPTION_GUARD_PAGE),2383def_excpt(EXCEPTION_INVALID_HANDLE),2384def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),2385def_excpt(EXCEPTION_HEAP_CORRUPTION)2386};23872388#undef def_excpt23892390const char* os::exception_name(int exception_code, char *buf, size_t size) {2391uint code = static_cast<uint>(exception_code);2392for (uint i = 0; i < ARRAY_SIZE(exceptlabels); ++i) {2393if (exceptlabels[i].number == code) {2394jio_snprintf(buf, size, "%s", exceptlabels[i].name);2395return buf;2396}2397}23982399return NULL;2400}24012402//-----------------------------------------------------------------------------2403LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {2404// handle exception caused by idiv; should only happen for -MinInt/-12405// (division by zero is handled explicitly)2406#if defined(_M_ARM64)2407PCONTEXT ctx = exceptionInfo->ContextRecord;2408address pc = (address)ctx->Sp;2409assert(pc[0] == 0x83, "not an sdiv opcode"); //Fixme did i get the right opcode?2410assert(ctx->X4 == min_jint, "unexpected idiv exception");2411// set correct result values and continue after idiv instruction2412ctx->Pc = (uint64_t)pc + 4; // idiv reg, reg, reg is 4 bytes2413ctx->X4 = (uint64_t)min_jint; // result2414ctx->X5 = (uint64_t)0; // remainder2415// Continue the execution2416#elif defined(_M_AMD64)2417PCONTEXT ctx = exceptionInfo->ContextRecord;2418address pc = (address)ctx->Rip;2419assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");2420assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");2421if (pc[0] == 0xF7) {2422// set correct result values and continue after idiv instruction2423ctx->Rip = (DWORD64)pc + 2; // idiv reg, reg is 2 bytes2424} else {2425ctx->Rip = (DWORD64)pc + 3; // REX idiv reg, reg is 3 bytes2426}2427// Do not set ctx->Rax as it already contains the correct value (either 32 or 64 bit, depending on the operation)2428// this is the case because the exception only happens for -MinValue/-1 and -MinValue is always in rax because of the2429// idiv opcode (0xF7).2430ctx->Rdx = (DWORD)0; // remainder2431// Continue the execution2432#else2433PCONTEXT ctx = exceptionInfo->ContextRecord;2434address pc = (address)ctx->Eip;2435assert(pc[0] == 0xF7, "not an idiv opcode");2436assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");2437assert(ctx->Eax == min_jint, "unexpected idiv exception");2438// set correct result values and continue after idiv instruction2439ctx->Eip = (DWORD)pc + 2; // idiv reg, reg is 2 bytes2440ctx->Eax = (DWORD)min_jint; // result2441ctx->Edx = (DWORD)0; // remainder2442// Continue the execution2443#endif2444return EXCEPTION_CONTINUE_EXECUTION;2445}24462447#if defined(_M_AMD64) || defined(_M_IX86)2448//-----------------------------------------------------------------------------2449LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {2450PCONTEXT ctx = exceptionInfo->ContextRecord;2451#ifndef _WIN642452// handle exception caused by native method modifying control word2453DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;24542455switch (exception_code) {2456case EXCEPTION_FLT_DENORMAL_OPERAND:2457case EXCEPTION_FLT_DIVIDE_BY_ZERO:2458case EXCEPTION_FLT_INEXACT_RESULT:2459case EXCEPTION_FLT_INVALID_OPERATION:2460case EXCEPTION_FLT_OVERFLOW:2461case EXCEPTION_FLT_STACK_CHECK:2462case EXCEPTION_FLT_UNDERFLOW:2463jint fp_control_word = (* (jint*) StubRoutines::x86::addr_fpu_cntrl_wrd_std());2464if (fp_control_word != ctx->FloatSave.ControlWord) {2465// Restore FPCW and mask out FLT exceptions2466ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;2467// Mask out pending FLT exceptions2468ctx->FloatSave.StatusWord &= 0xffffff00;2469return EXCEPTION_CONTINUE_EXECUTION;2470}2471}24722473if (prev_uef_handler != NULL) {2474// We didn't handle this exception so pass it to the previous2475// UnhandledExceptionFilter.2476return (prev_uef_handler)(exceptionInfo);2477}2478#else // !_WIN642479// On Windows, the mxcsr control bits are non-volatile across calls2480// See also CR 61923332481//2482jint MxCsr = INITIAL_MXCSR;2483// we can't use StubRoutines::x86::addr_mxcsr_std()2484// because in Win64 mxcsr is not saved there2485if (MxCsr != ctx->MxCsr) {2486ctx->MxCsr = MxCsr;2487return EXCEPTION_CONTINUE_EXECUTION;2488}2489#endif // !_WIN6424902491return EXCEPTION_CONTINUE_SEARCH;2492}2493#endif24942495static inline void report_error(Thread* t, DWORD exception_code,2496address addr, void* siginfo, void* context) {2497VMError::report_and_die(t, exception_code, addr, siginfo, context);24982499// If UseOSErrorReporting, this will return here and save the error file2500// somewhere where we can find it in the minidump.2501}25022503//-----------------------------------------------------------------------------2504JNIEXPORT2505LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {2506if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;2507PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord;2508DWORD exception_code = exception_record->ExceptionCode;2509#if defined(_M_ARM64)2510address pc = (address) exceptionInfo->ContextRecord->Pc;2511#elif defined(_M_AMD64)2512address pc = (address) exceptionInfo->ContextRecord->Rip;2513#else2514address pc = (address) exceptionInfo->ContextRecord->Eip;2515#endif2516Thread* t = Thread::current_or_null_safe();25172518// Handle SafeFetch32 and SafeFetchN exceptions.2519if (StubRoutines::is_safefetch_fault(pc)) {2520return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));2521}25222523#ifndef _WIN642524// Execution protection violation - win32 running on AMD64 only2525// Handled first to avoid misdiagnosis as a "normal" access violation;2526// This is safe to do because we have a new/unique ExceptionInformation2527// code for this condition.2528if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2529int exception_subcode = (int) exception_record->ExceptionInformation[0];2530address addr = (address) exception_record->ExceptionInformation[1];25312532if (exception_subcode == EXCEPTION_INFO_EXEC_VIOLATION) {2533int page_size = os::vm_page_size();25342535// Make sure the pc and the faulting address are sane.2536//2537// If an instruction spans a page boundary, and the page containing2538// the beginning of the instruction is executable but the following2539// page is not, the pc and the faulting address might be slightly2540// different - we still want to unguard the 2nd page in this case.2541//2542// 15 bytes seems to be a (very) safe value for max instruction size.2543bool pc_is_near_addr =2544(pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);2545bool instr_spans_page_boundary =2546(align_down((intptr_t) pc ^ (intptr_t) addr,2547(intptr_t) page_size) > 0);25482549if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {2550static volatile address last_addr =2551(address) os::non_memory_address_word();25522553// In conservative mode, don't unguard unless the address is in the VM2554if (UnguardOnExecutionViolation > 0 && addr != last_addr &&2555(UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {25562557// Set memory to RWX and retry2558address page_start = align_down(addr, page_size);2559bool res = os::protect_memory((char*) page_start, page_size,2560os::MEM_PROT_RWX);25612562log_debug(os)("Execution protection violation "2563"at " INTPTR_FORMAT2564", unguarding " INTPTR_FORMAT ": %s", p2i(addr),2565p2i(page_start), (res ? "success" : os::strerror(errno)));25662567// Set last_addr so if we fault again at the same address, we don't2568// end up in an endless loop.2569//2570// There are two potential complications here. Two threads trapping2571// at the same address at the same time could cause one of the2572// threads to think it already unguarded, and abort the VM. Likely2573// very rare.2574//2575// The other race involves two threads alternately trapping at2576// different addresses and failing to unguard the page, resulting in2577// an endless loop. This condition is probably even more unlikely2578// than the first.2579//2580// Although both cases could be avoided by using locks or thread2581// local last_addr, these solutions are unnecessary complication:2582// this handler is a best-effort safety net, not a complete solution.2583// It is disabled by default and should only be used as a workaround2584// in case we missed any no-execute-unsafe VM code.25852586last_addr = addr;25872588return EXCEPTION_CONTINUE_EXECUTION;2589}2590}25912592// Last unguard failed or not unguarding2593tty->print_raw_cr("Execution protection violation");2594#if !defined(USE_VECTORED_EXCEPTION_HANDLING)2595report_error(t, exception_code, addr, exception_record,2596exceptionInfo->ContextRecord);2597#endif2598return EXCEPTION_CONTINUE_SEARCH;2599}2600}2601#endif // _WIN6426022603#if defined(_M_AMD64) || defined(_M_IX86)2604if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&2605VM_Version::is_cpuinfo_segv_addr(pc)) {2606// Verify that OS save/restore AVX registers.2607return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());2608}2609#endif26102611if (t != NULL && t->is_Java_thread()) {2612JavaThread* thread = t->as_Java_thread();2613bool in_java = thread->thread_state() == _thread_in_Java;2614bool in_native = thread->thread_state() == _thread_in_native;2615bool in_vm = thread->thread_state() == _thread_in_vm;26162617// Handle potential stack overflows up front.2618if (exception_code == EXCEPTION_STACK_OVERFLOW) {2619StackOverflow* overflow_state = thread->stack_overflow_state();2620if (overflow_state->stack_guards_enabled()) {2621if (in_java) {2622frame fr;2623if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) {2624assert(fr.is_java_frame(), "Must be a Java frame");2625SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);2626}2627}2628// Yellow zone violation. The o/s has unprotected the first yellow2629// zone page for us. Note: must call disable_stack_yellow_zone to2630// update the enabled status, even if the zone contains only one page.2631assert(!in_vm, "Undersized StackShadowPages");2632overflow_state->disable_stack_yellow_reserved_zone();2633// If not in java code, return and hope for the best.2634return in_java2635? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))2636: EXCEPTION_CONTINUE_EXECUTION;2637} else {2638// Fatal red zone violation.2639overflow_state->disable_stack_red_zone();2640tty->print_raw_cr("An unrecoverable stack overflow has occurred.");2641#if !defined(USE_VECTORED_EXCEPTION_HANDLING)2642report_error(t, exception_code, pc, exception_record,2643exceptionInfo->ContextRecord);2644#endif2645return EXCEPTION_CONTINUE_SEARCH;2646}2647} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2648if (in_java) {2649// Either stack overflow or null pointer exception.2650address addr = (address) exception_record->ExceptionInformation[1];2651address stack_end = thread->stack_end();2652if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {2653// Stack overflow.2654assert(!os::uses_stack_guard_pages(),2655"should be caught by red zone code above.");2656return Handle_Exception(exceptionInfo,2657SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));2658}2659// Check for safepoint polling and implicit null2660// We only expect null pointers in the stubs (vtable)2661// the rest are checked explicitly now.2662CodeBlob* cb = CodeCache::find_blob(pc);2663if (cb != NULL) {2664if (SafepointMechanism::is_poll_address(addr)) {2665address stub = SharedRuntime::get_poll_stub(pc);2666return Handle_Exception(exceptionInfo, stub);2667}2668}2669#ifdef _WIN642670// If it's a legal stack address map the entire region in2671if (thread->is_in_usable_stack(addr)) {2672addr = (address)((uintptr_t)addr &2673(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));2674os::commit_memory((char *)addr, thread->stack_base() - addr,2675!ExecMem);2676return EXCEPTION_CONTINUE_EXECUTION;2677}2678#endif2679// Null pointer exception.2680if (MacroAssembler::uses_implicit_null_check((void*)addr)) {2681address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);2682if (stub != NULL) return Handle_Exception(exceptionInfo, stub);2683}2684report_error(t, exception_code, pc, exception_record,2685exceptionInfo->ContextRecord);2686return EXCEPTION_CONTINUE_SEARCH;2687}26882689#ifdef _WIN642690// Special care for fast JNI field accessors.2691// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks2692// in and the heap gets shrunk before the field access.2693address slowcase_pc = JNI_FastGetField::find_slowcase_pc(pc);2694if (slowcase_pc != (address)-1) {2695return Handle_Exception(exceptionInfo, slowcase_pc);2696}2697#endif26982699// Stack overflow or null pointer exception in native code.2700#if !defined(USE_VECTORED_EXCEPTION_HANDLING)2701report_error(t, exception_code, pc, exception_record,2702exceptionInfo->ContextRecord);2703#endif2704return EXCEPTION_CONTINUE_SEARCH;2705} // /EXCEPTION_ACCESS_VIOLATION2706// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -27072708if (exception_code == EXCEPTION_IN_PAGE_ERROR) {2709CompiledMethod* nm = NULL;2710if (in_java) {2711CodeBlob* cb = CodeCache::find_blob_unsafe(pc);2712nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;2713}27142715bool is_unsafe_arraycopy = (in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);2716if (((in_vm || in_native || is_unsafe_arraycopy) && thread->doing_unsafe_access()) ||2717(nm != NULL && nm->has_unsafe_access())) {2718address next_pc = Assembler::locate_next_instruction(pc);2719if (is_unsafe_arraycopy) {2720next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);2721}2722return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));2723}2724}27252726#ifdef _M_ARM642727if (in_java &&2728(exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||2729exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {2730if (nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) {2731if (TraceTraps) {2732tty->print_cr("trap: zombie_not_entrant");2733}2734return Handle_Exception(exceptionInfo, SharedRuntime::get_handle_wrong_method_stub());2735}2736}2737#endif27382739if (in_java) {2740switch (exception_code) {2741case EXCEPTION_INT_DIVIDE_BY_ZERO:2742return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));27432744case EXCEPTION_INT_OVERFLOW:2745return Handle_IDiv_Exception(exceptionInfo);27462747} // switch2748}27492750#if defined(_M_AMD64) || defined(_M_IX86)2751if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) {2752LONG result=Handle_FLT_Exception(exceptionInfo);2753if (result==EXCEPTION_CONTINUE_EXECUTION) return result;2754}2755#endif2756}27572758#if !defined(USE_VECTORED_EXCEPTION_HANDLING)2759if (exception_code != EXCEPTION_BREAKPOINT) {2760report_error(t, exception_code, pc, exception_record,2761exceptionInfo->ContextRecord);2762}2763#endif2764return EXCEPTION_CONTINUE_SEARCH;2765}27662767#if defined(USE_VECTORED_EXCEPTION_HANDLING)2768LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {2769PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;2770#if defined(_M_ARM64)2771address pc = (address) exceptionInfo->ContextRecord->Pc;2772#elif defined(_M_AMD64)2773address pc = (address) exceptionInfo->ContextRecord->Rip;2774#else2775address pc = (address) exceptionInfo->ContextRecord->Eip;2776#endif27772778// Fast path for code part of the code cache2779if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) {2780return topLevelExceptionFilter(exceptionInfo);2781}27822783// If the exception occurred in the codeCache, pass control2784// to our normal exception handler.2785CodeBlob* cb = CodeCache::find_blob(pc);2786if (cb != NULL) {2787return topLevelExceptionFilter(exceptionInfo);2788}27892790return EXCEPTION_CONTINUE_SEARCH;2791}2792#endif27932794#if defined(USE_VECTORED_EXCEPTION_HANDLING)2795LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {2796if (InterceptOSException) goto exit;2797DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;2798#if defined(_M_ARM64)2799address pc = (address)exceptionInfo->ContextRecord->Pc;2800#elif defined(_M_AMD64)2801address pc = (address) exceptionInfo->ContextRecord->Rip;2802#else2803address pc = (address) exceptionInfo->ContextRecord->Eip;2804#endif2805Thread* t = Thread::current_or_null_safe();28062807if (exception_code != EXCEPTION_BREAKPOINT) {2808report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,2809exceptionInfo->ContextRecord);2810}2811exit:2812return previousUnhandledExceptionFilter ? previousUnhandledExceptionFilter(exceptionInfo) : EXCEPTION_CONTINUE_SEARCH;2813}2814#endif28152816#ifndef _WIN642817// Special care for fast JNI accessors.2818// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and2819// the heap gets shrunk before the field access.2820// Need to install our own structured exception handler since native code may2821// install its own.2822LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {2823DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;2824if (exception_code == EXCEPTION_ACCESS_VIOLATION) {2825address pc = (address) exceptionInfo->ContextRecord->Eip;2826address addr = JNI_FastGetField::find_slowcase_pc(pc);2827if (addr != (address)-1) {2828return Handle_Exception(exceptionInfo, addr);2829}2830}2831return EXCEPTION_CONTINUE_SEARCH;2832}28332834#define DEFINE_FAST_GETFIELD(Return, Fieldname, Result) \2835Return JNICALL jni_fast_Get##Result##Field_wrapper(JNIEnv *env, \2836jobject obj, \2837jfieldID fieldID) { \2838__try { \2839return (*JNI_FastGetField::jni_fast_Get##Result##Field_fp)(env, \2840obj, \2841fieldID); \2842} __except(fastJNIAccessorExceptionFilter((_EXCEPTION_POINTERS*) \2843_exception_info())) { \2844} \2845return 0; \2846}28472848DEFINE_FAST_GETFIELD(jboolean, bool, Boolean)2849DEFINE_FAST_GETFIELD(jbyte, byte, Byte)2850DEFINE_FAST_GETFIELD(jchar, char, Char)2851DEFINE_FAST_GETFIELD(jshort, short, Short)2852DEFINE_FAST_GETFIELD(jint, int, Int)2853DEFINE_FAST_GETFIELD(jlong, long, Long)2854DEFINE_FAST_GETFIELD(jfloat, float, Float)2855DEFINE_FAST_GETFIELD(jdouble, double, Double)28562857address os::win32::fast_jni_accessor_wrapper(BasicType type) {2858switch (type) {2859case T_BOOLEAN: return (address)jni_fast_GetBooleanField_wrapper;2860case T_BYTE: return (address)jni_fast_GetByteField_wrapper;2861case T_CHAR: return (address)jni_fast_GetCharField_wrapper;2862case T_SHORT: return (address)jni_fast_GetShortField_wrapper;2863case T_INT: return (address)jni_fast_GetIntField_wrapper;2864case T_LONG: return (address)jni_fast_GetLongField_wrapper;2865case T_FLOAT: return (address)jni_fast_GetFloatField_wrapper;2866case T_DOUBLE: return (address)jni_fast_GetDoubleField_wrapper;2867default: ShouldNotReachHere();2868}2869return (address)-1;2870}2871#endif28722873// Virtual Memory28742875int os::vm_page_size() { return os::win32::vm_page_size(); }2876int os::vm_allocation_granularity() {2877return os::win32::vm_allocation_granularity();2878}28792880// Windows large page support is available on Windows 2003. In order to use2881// large page memory, the administrator must first assign additional privilege2882// to the user:2883// + select Control Panel -> Administrative Tools -> Local Security Policy2884// + select Local Policies -> User Rights Assignment2885// + double click "Lock pages in memory", add users and/or groups2886// + reboot2887// Note the above steps are needed for administrator as well, as administrators2888// by default do not have the privilege to lock pages in memory.2889//2890// Note about Windows 2003: although the API supports committing large page2891// memory on a page-by-page basis and VirtualAlloc() returns success under this2892// scenario, I found through experiment it only uses large page if the entire2893// memory region is reserved and committed in a single VirtualAlloc() call.2894// This makes Windows large page support more or less like Solaris ISM, in2895// that the entire heap must be committed upfront. This probably will change2896// in the future, if so the code below needs to be revisited.28972898#ifndef MEM_LARGE_PAGES2899#define MEM_LARGE_PAGES 0x200000002900#endif29012902// Container for NUMA node list info2903class NUMANodeListHolder {2904private:2905int *_numa_used_node_list; // allocated below2906int _numa_used_node_count;29072908void free_node_list() {2909FREE_C_HEAP_ARRAY(int, _numa_used_node_list);2910}29112912public:2913NUMANodeListHolder() {2914_numa_used_node_count = 0;2915_numa_used_node_list = NULL;2916// do rest of initialization in build routine (after function pointers are set up)2917}29182919~NUMANodeListHolder() {2920free_node_list();2921}29222923bool build() {2924DWORD_PTR proc_aff_mask;2925DWORD_PTR sys_aff_mask;2926if (!GetProcessAffinityMask(GetCurrentProcess(), &proc_aff_mask, &sys_aff_mask)) return false;2927ULONG highest_node_number;2928if (!GetNumaHighestNodeNumber(&highest_node_number)) return false;2929free_node_list();2930_numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1, mtInternal);2931for (unsigned int i = 0; i <= highest_node_number; i++) {2932ULONGLONG proc_mask_numa_node;2933if (!GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;2934if ((proc_aff_mask & proc_mask_numa_node)!=0) {2935_numa_used_node_list[_numa_used_node_count++] = i;2936}2937}2938return (_numa_used_node_count > 1);2939}29402941int get_count() { return _numa_used_node_count; }2942int get_node_list_entry(int n) {2943// for indexes out of range, returns -12944return (n < _numa_used_node_count ? _numa_used_node_list[n] : -1);2945}29462947} numa_node_list_holder;29482949static size_t _large_page_size = 0;29502951static bool request_lock_memory_privilege() {2952HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,2953os::current_process_id());29542955bool success = false;2956HANDLE hToken = NULL;2957LUID luid;2958if (hProcess != NULL &&2959OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) &&2960LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &luid)) {29612962TOKEN_PRIVILEGES tp;2963tp.PrivilegeCount = 1;2964tp.Privileges[0].Luid = luid;2965tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;29662967// AdjustTokenPrivileges() may return TRUE even when it couldn't change the2968// privilege. Check GetLastError() too. See MSDN document.2969if (AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), NULL, NULL) &&2970(GetLastError() == ERROR_SUCCESS)) {2971success = true;2972}2973}29742975// Cleanup2976if (hProcess != NULL) {2977CloseHandle(hProcess);2978}2979if (hToken != NULL) {2980CloseHandle(hToken);2981}29822983return success;2984}29852986static bool numa_interleaving_init() {2987bool success = false;29882989// print a warning if UseNUMAInterleaving flag is specified on command line2990bool warn_on_failure = !FLAG_IS_DEFAULT(UseNUMAInterleaving);29912992#define WARN(msg) if (warn_on_failure) { warning(msg); }29932994// NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages)2995size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity();2996NUMAInterleaveGranularity = align_up(NUMAInterleaveGranularity, min_interleave_granularity);29972998if (!numa_node_list_holder.build()) {2999WARN("Process does not cover multiple NUMA nodes.");3000WARN("...Ignoring UseNUMAInterleaving flag.");3001return false;3002}30033004if (log_is_enabled(Debug, os, cpu)) {3005Log(os, cpu) log;3006log.debug("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());3007for (int i = 0; i < numa_node_list_holder.get_count(); i++) {3008log.debug(" %d ", numa_node_list_holder.get_node_list_entry(i));3009}3010}30113012#undef WARN30133014return true;3015}30163017// this routine is used whenever we need to reserve a contiguous VA range3018// but we need to make separate VirtualAlloc calls for each piece of the range3019// Reasons for doing this:3020// * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise)3021// * UseNUMAInterleaving requires a separate node for each piece3022static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,3023DWORD prot,3024bool should_inject_error = false) {3025char * p_buf;3026// note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size3027size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity();3028size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size;30293030// first reserve enough address space in advance since we want to be3031// able to break a single contiguous virtual address range into multiple3032// large page commits but WS2003 does not allow reserving large page space3033// so we just use 4K pages for reserve, this gives us a legal contiguous3034// address space. then we will deallocate that reservation, and re alloc3035// using large pages3036const size_t size_of_reserve = bytes + chunk_size;3037if (bytes > size_of_reserve) {3038// Overflowed.3039return NULL;3040}3041p_buf = (char *) virtualAlloc(addr,3042size_of_reserve, // size of Reserve3043MEM_RESERVE,3044PAGE_READWRITE);3045// If reservation failed, return NULL3046if (p_buf == NULL) return NULL;3047MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);3048os::release_memory(p_buf, bytes + chunk_size);30493050// we still need to round up to a page boundary (in case we are using large pages)3051// but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size)3052// instead we handle this in the bytes_to_rq computation below3053p_buf = align_up(p_buf, page_size);30543055// now go through and allocate one chunk at a time until all bytes are3056// allocated3057size_t bytes_remaining = bytes;3058// An overflow of align_up() would have been caught above3059// in the calculation of size_of_reserve.3060char * next_alloc_addr = p_buf;3061HANDLE hProc = GetCurrentProcess();30623063#ifdef ASSERT3064// Variable for the failure injection3065int ran_num = os::random();3066size_t fail_after = ran_num % bytes;3067#endif30683069int count=0;3070while (bytes_remaining) {3071// select bytes_to_rq to get to the next chunk_size boundary30723073size_t bytes_to_rq = MIN2(bytes_remaining, chunk_size - ((size_t)next_alloc_addr % chunk_size));3074// Note allocate and commit3075char * p_new;30763077#ifdef ASSERT3078bool inject_error_now = should_inject_error && (bytes_remaining <= fail_after);3079#else3080const bool inject_error_now = false;3081#endif30823083if (inject_error_now) {3084p_new = NULL;3085} else {3086if (!UseNUMAInterleaving) {3087p_new = (char *) virtualAlloc(next_alloc_addr,3088bytes_to_rq,3089flags,3090prot);3091} else {3092// get the next node to use from the used_node_list3093assert(numa_node_list_holder.get_count() > 0, "Multiple NUMA nodes expected");3094DWORD node = numa_node_list_holder.get_node_list_entry(count % numa_node_list_holder.get_count());3095p_new = (char *)virtualAllocExNuma(hProc, next_alloc_addr, bytes_to_rq, flags, prot, node);3096}3097}30983099if (p_new == NULL) {3100// Free any allocated pages3101if (next_alloc_addr > p_buf) {3102// Some memory was committed so release it.3103size_t bytes_to_release = bytes - bytes_remaining;3104// NMT has yet to record any individual blocks, so it3105// need to create a dummy 'reserve' record to match3106// the release.3107MemTracker::record_virtual_memory_reserve((address)p_buf,3108bytes_to_release, CALLER_PC);3109os::release_memory(p_buf, bytes_to_release);3110}3111#ifdef ASSERT3112if (should_inject_error) {3113log_develop_debug(pagesize)("Reserving pages individually failed.");3114}3115#endif3116return NULL;3117}31183119bytes_remaining -= bytes_to_rq;3120next_alloc_addr += bytes_to_rq;3121count++;3122}3123// Although the memory is allocated individually, it is returned as one.3124// NMT records it as one block.3125if ((flags & MEM_COMMIT) != 0) {3126MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, CALLER_PC);3127} else {3128MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, CALLER_PC);3129}31303131// made it this far, success3132return p_buf;3133}31343135static size_t large_page_init_decide_size() {3136// print a warning if any large page related flag is specified on command line3137bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||3138!FLAG_IS_DEFAULT(LargePageSizeInBytes);31393140#define WARN(msg) if (warn_on_failure) { warning(msg); }31413142if (!request_lock_memory_privilege()) {3143WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory.");3144return 0;3145}31463147size_t size = GetLargePageMinimum();3148if (size == 0) {3149WARN("Large page is not supported by the processor.");3150return 0;3151}31523153#if defined(IA32) || defined(AMD64)3154if (size > 4*M || LargePageSizeInBytes > 4*M) {3155WARN("JVM cannot use large pages bigger than 4mb.");3156return 0;3157}3158#endif31593160if (LargePageSizeInBytes > 0 && LargePageSizeInBytes % size == 0) {3161size = LargePageSizeInBytes;3162}31633164#undef WARN31653166return size;3167}31683169void os::large_page_init() {3170if (!UseLargePages) {3171return;3172}31733174_large_page_size = large_page_init_decide_size();3175const size_t default_page_size = (size_t) vm_page_size();3176if (_large_page_size > default_page_size) {3177_page_sizes.add(_large_page_size);3178}31793180UseLargePages = _large_page_size != 0;3181}31823183int os::create_file_for_heap(const char* dir) {31843185const char name_template[] = "/jvmheap.XXXXXX";31863187size_t fullname_len = strlen(dir) + strlen(name_template);3188char *fullname = (char*)os::malloc(fullname_len + 1, mtInternal);3189if (fullname == NULL) {3190vm_exit_during_initialization(err_msg("Malloc failed during creation of backing file for heap (%s)", os::strerror(errno)));3191return -1;3192}3193int n = snprintf(fullname, fullname_len + 1, "%s%s", dir, name_template);3194assert((size_t)n == fullname_len, "Unexpected number of characters in string");31953196os::native_path(fullname);31973198char *path = _mktemp(fullname);3199if (path == NULL) {3200warning("_mktemp could not create file name from template %s (%s)", fullname, os::strerror(errno));3201os::free(fullname);3202return -1;3203}32043205int fd = _open(path, O_RDWR | O_CREAT | O_TEMPORARY | O_EXCL, S_IWRITE | S_IREAD);32063207os::free(fullname);3208if (fd < 0) {3209warning("Problem opening file for heap (%s)", os::strerror(errno));3210return -1;3211}3212return fd;3213}32143215// If 'base' is not NULL, function will return NULL if it cannot get 'base'3216char* os::map_memory_to_file(char* base, size_t size, int fd) {3217assert(fd != -1, "File descriptor is not valid");32183219HANDLE fh = (HANDLE)_get_osfhandle(fd);3220#ifdef _LP643221HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,3222(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), NULL);3223#else3224HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,32250, (DWORD)size, NULL);3226#endif3227if (fileMapping == NULL) {3228if (GetLastError() == ERROR_DISK_FULL) {3229vm_exit_during_initialization(err_msg("Could not allocate sufficient disk space for Java heap"));3230}3231else {3232vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));3233}32343235return NULL;3236}32373238LPVOID addr = mapViewOfFileEx(fileMapping, FILE_MAP_WRITE, 0, 0, size, base);32393240CloseHandle(fileMapping);32413242return (char*)addr;3243}32443245char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd) {3246assert(fd != -1, "File descriptor is not valid");3247assert(base != NULL, "Base address cannot be NULL");32483249release_memory(base, size);3250return map_memory_to_file(base, size, fd);3251}32523253// Multiple threads can race in this code but it's not possible to unmap small sections of3254// virtual space to get requested alignment, like posix-like os's.3255// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.3256static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {3257assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,3258"Alignment must be a multiple of allocation granularity (page size)");3259assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");32603261size_t extra_size = size + alignment;3262assert(extra_size >= size, "overflow, size is too large to allow alignment");32633264char* aligned_base = NULL;3265static const int max_attempts = 20;32663267for (int attempt = 0; attempt < max_attempts && aligned_base == NULL; attempt ++) {3268char* extra_base = file_desc != -1 ? os::map_memory_to_file(extra_size, file_desc) :3269os::reserve_memory(extra_size);3270if (extra_base == NULL) {3271return NULL;3272}3273// Do manual alignment3274aligned_base = align_up(extra_base, alignment);32753276bool rc = (file_desc != -1) ? os::unmap_memory(extra_base, extra_size) :3277os::release_memory(extra_base, extra_size);3278assert(rc, "release failed");3279if (!rc) {3280return NULL;3281}32823283// Attempt to map, into the just vacated space, the slightly smaller aligned area.3284// Which may fail, hence the loop.3285aligned_base = file_desc != -1 ? os::attempt_map_memory_to_file_at(aligned_base, size, file_desc) :3286os::attempt_reserve_memory_at(aligned_base, size);3287}32883289assert(aligned_base != NULL, "Did not manage to re-map after %d attempts?", max_attempts);32903291return aligned_base;3292}32933294char* os::reserve_memory_aligned(size_t size, size_t alignment, bool exec) {3295// exec can be ignored3296return map_or_reserve_memory_aligned(size, alignment, -1 /* file_desc */);3297}32983299char* os::map_memory_to_file_aligned(size_t size, size_t alignment, int fd) {3300return map_or_reserve_memory_aligned(size, alignment, fd);3301}33023303char* os::pd_reserve_memory(size_t bytes, bool exec) {3304return pd_attempt_reserve_memory_at(NULL /* addr */, bytes, exec);3305}33063307// Reserve memory at an arbitrary address, only if that area is3308// available (and not reserved for something else).3309char* os::pd_attempt_reserve_memory_at(char* addr, size_t bytes, bool exec) {3310assert((size_t)addr % os::vm_allocation_granularity() == 0,3311"reserve alignment");3312assert(bytes % os::vm_page_size() == 0, "reserve page size");3313char* res;3314// note that if UseLargePages is on, all the areas that require interleaving3315// will go thru reserve_memory_special rather than thru here.3316bool use_individual = (UseNUMAInterleaving && !UseLargePages);3317if (!use_individual) {3318res = (char*)virtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);3319} else {3320elapsedTimer reserveTimer;3321if (Verbose && PrintMiscellaneous) reserveTimer.start();3322// in numa interleaving, we have to allocate pages individually3323// (well really chunks of NUMAInterleaveGranularity size)3324res = allocate_pages_individually(bytes, addr, MEM_RESERVE, PAGE_READWRITE);3325if (res == NULL) {3326warning("NUMA page allocation failed");3327}3328if (Verbose && PrintMiscellaneous) {3329reserveTimer.stop();3330tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,3331reserveTimer.milliseconds(), reserveTimer.ticks());3332}3333}3334assert(res == NULL || addr == NULL || addr == res,3335"Unexpected address from reserve.");33363337return res;3338}33393340char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {3341assert(file_desc >= 0, "file_desc is not valid");3342return map_memory_to_file(requested_addr, bytes, file_desc);3343}33443345size_t os::large_page_size() {3346return _large_page_size;3347}33483349bool os::can_commit_large_page_memory() {3350// Windows only uses large page memory when the entire region is reserved3351// and committed in a single VirtualAlloc() call. This may change in the3352// future, but with Windows 2003 it's not possible to commit on demand.3353return false;3354}33553356bool os::can_execute_large_page_memory() {3357return true;3358}33593360static char* reserve_large_pages_individually(size_t size, char* req_addr, bool exec) {3361log_debug(pagesize)("Reserving large pages individually.");33623363const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;3364const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;33653366char * p_buf = allocate_pages_individually(size, req_addr, flags, prot, LargePagesIndividualAllocationInjectError);3367if (p_buf == NULL) {3368// give an appropriate warning message3369if (UseNUMAInterleaving) {3370warning("NUMA large page allocation failed, UseLargePages flag ignored");3371}3372if (UseLargePagesIndividualAllocation) {3373warning("Individually allocated large pages failed, "3374"use -XX:-UseLargePagesIndividualAllocation to turn off");3375}3376return NULL;3377}3378return p_buf;3379}33803381static char* reserve_large_pages_single_range(size_t size, char* req_addr, bool exec) {3382log_debug(pagesize)("Reserving large pages in a single large chunk.");33833384const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;3385const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;33863387return (char *) virtualAlloc(req_addr, size, flags, prot);3388}33893390static char* reserve_large_pages(size_t size, char* req_addr, bool exec) {3391// with large pages, there are two cases where we need to use Individual Allocation3392// 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)3393// 2) NUMA Interleaving is enabled, in which case we use a different node for each page3394if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {3395return reserve_large_pages_individually(size, req_addr, exec);3396}3397return reserve_large_pages_single_range(size, req_addr, exec);3398}33993400static char* find_aligned_address(size_t size, size_t alignment) {3401// Temporary reserve memory large enough to ensure we can get the requested3402// alignment and still fit the reservation.3403char* addr = (char*) virtualAlloc(NULL, size + alignment, MEM_RESERVE, PAGE_NOACCESS);3404// Align the address to the requested alignment.3405char* aligned_addr = align_up(addr, alignment);3406// Free the temporary reservation.3407virtualFree(addr, 0, MEM_RELEASE);34083409return aligned_addr;3410}34113412static char* reserve_large_pages_aligned(size_t size, size_t alignment, bool exec) {3413log_debug(pagesize)("Reserving large pages at an aligned address, alignment=" SIZE_FORMAT "%s",3414byte_size_in_exact_unit(alignment), exact_unit_for_byte_size(alignment));34153416// Will try to find a suitable address at most 20 times. The reason we need to try3417// multiple times is that between finding the aligned address and trying to commit3418// the large pages another thread might have reserved an overlapping region.3419const int attempts_limit = 20;3420for (int attempts = 0; attempts < attempts_limit; attempts++) {3421// Find aligned address.3422char* aligned_address = find_aligned_address(size, alignment);34233424// Try to do the large page reservation using the aligned address.3425aligned_address = reserve_large_pages(size, aligned_address, exec);3426if (aligned_address != NULL) {3427// Reservation at the aligned address succeeded.3428guarantee(is_aligned(aligned_address, alignment), "Must be aligned");3429return aligned_address;3430}3431}34323433log_debug(pagesize)("Failed reserving large pages at aligned address");3434return NULL;3435}34363437char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* addr,3438bool exec) {3439assert(UseLargePages, "only for large pages");3440assert(page_size == os::large_page_size(), "Currently only support one large page size on Windows");3441assert(is_aligned(addr, alignment), "Must be");3442assert(is_aligned(addr, page_size), "Must be");34433444if (!is_aligned(bytes, page_size)) {3445// Fallback to small pages, Windows does not support mixed mappings.3446return NULL;3447}34483449// The requested alignment can be larger than the page size, for example with G13450// the alignment is bound to the heap region size. So this reservation needs to3451// ensure that the requested alignment is met. When there is a requested address3452// this solves it self, since it must be properly aligned already.3453if (addr == NULL && alignment > page_size) {3454return reserve_large_pages_aligned(bytes, alignment, exec);3455}34563457// No additional requirements, just reserve the large pages.3458return reserve_large_pages(bytes, addr, exec);3459}34603461bool os::pd_release_memory_special(char* base, size_t bytes) {3462assert(base != NULL, "Sanity check");3463return pd_release_memory(base, bytes);3464}34653466void os::print_statistics() {3467}34683469static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) {3470int err = os::get_last_error();3471char buf[256];3472size_t buf_len = os::lasterror(buf, sizeof(buf));3473warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT3474", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes,3475exec, buf_len != 0 ? buf : "<no_error_string>", err);3476}34773478bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {3479if (bytes == 0) {3480// Don't bother the OS with noops.3481return true;3482}3483assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");3484assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");3485// Don't attempt to print anything if the OS call fails. We're3486// probably low on resources, so the print itself may cause crashes.34873488// unless we have NUMAInterleaving enabled, the range of a commit3489// is always within a reserve covered by a single VirtualAlloc3490// in that case we can just do a single commit for the requested size3491if (!UseNUMAInterleaving) {3492if (virtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) {3493NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)3494return false;3495}3496if (exec) {3497DWORD oldprot;3498// Windows doc says to use VirtualProtect to get execute permissions3499if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) {3500NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)3501return false;3502}3503}3504return true;3505} else {35063507// when NUMAInterleaving is enabled, the commit might cover a range that3508// came from multiple VirtualAlloc reserves (using allocate_pages_individually).3509// VirtualQuery can help us determine that. The RegionSize that VirtualQuery3510// returns represents the number of bytes that can be committed in one step.3511size_t bytes_remaining = bytes;3512char * next_alloc_addr = addr;3513while (bytes_remaining > 0) {3514MEMORY_BASIC_INFORMATION alloc_info;3515VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));3516size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);3517if (virtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT,3518PAGE_READWRITE) == NULL) {3519NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,3520exec);)3521return false;3522}3523if (exec) {3524DWORD oldprot;3525if (!VirtualProtect(next_alloc_addr, bytes_to_rq,3526PAGE_EXECUTE_READWRITE, &oldprot)) {3527NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,3528exec);)3529return false;3530}3531}3532bytes_remaining -= bytes_to_rq;3533next_alloc_addr += bytes_to_rq;3534}3535}3536// if we made it this far, return true3537return true;3538}35393540bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,3541bool exec) {3542// alignment_hint is ignored on this OS3543return pd_commit_memory(addr, size, exec);3544}35453546void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,3547const char* mesg) {3548assert(mesg != NULL, "mesg must be specified");3549if (!pd_commit_memory(addr, size, exec)) {3550warn_fail_commit_memory(addr, size, exec);3551vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);3552}3553}35543555void os::pd_commit_memory_or_exit(char* addr, size_t size,3556size_t alignment_hint, bool exec,3557const char* mesg) {3558// alignment_hint is ignored on this OS3559pd_commit_memory_or_exit(addr, size, exec, mesg);3560}35613562bool os::pd_uncommit_memory(char* addr, size_t bytes, bool exec) {3563if (bytes == 0) {3564// Don't bother the OS with noops.3565return true;3566}3567assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");3568assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");3569return (virtualFree(addr, bytes, MEM_DECOMMIT) == TRUE);3570}35713572bool os::pd_release_memory(char* addr, size_t bytes) {3573// Given a range we are to release, we require a mapping to start at the beginning of that range;3574// if NUMA or LP we allow the range to contain multiple mappings, which have to cover the range3575// completely; otherwise the range must match an OS mapping exactly.3576address start = (address)addr;3577address end = start + bytes;3578os::win32::mapping_info_t mi;3579const bool multiple_mappings_allowed = UseLargePagesIndividualAllocation || UseNUMAInterleaving;3580address p = start;3581bool first_mapping = true;35823583do {3584// Find mapping and check it3585const char* err = NULL;3586if (!os::win32::find_mapping(p, &mi)) {3587err = "no mapping found";3588} else {3589if (first_mapping) {3590if (mi.base != start) {3591err = "base address mismatch";3592}3593if (multiple_mappings_allowed ? (mi.size > bytes) : (mi.size != bytes)) {3594err = "size mismatch";3595}3596} else {3597assert(p == mi.base && mi.size > 0, "Sanity");3598if (mi.base + mi.size > end) {3599err = "mapping overlaps end";3600}3601if (mi.size == 0) {3602err = "zero length mapping?"; // Should never happen; just to prevent endlessly looping in release.3603}3604}3605}3606// Handle mapping error. We assert in debug, unconditionally print a warning in release.3607if (err != NULL) {3608log_warning(os)("bad release: [" PTR_FORMAT "-" PTR_FORMAT "): %s", p2i(start), p2i(end), err);3609#ifdef ASSERT3610os::print_memory_mappings((char*)start, bytes, tty);3611assert(false, "bad release: [" PTR_FORMAT "-" PTR_FORMAT "): %s", p2i(start), p2i(end), err);3612#endif3613return false;3614}3615// Free this range3616if (virtualFree(p, 0, MEM_RELEASE) == FALSE) {3617return false;3618}3619first_mapping = false;3620p = mi.base + mi.size;3621} while (p < end);36223623return true;3624}36253626bool os::pd_create_stack_guard_pages(char* addr, size_t size) {3627return os::commit_memory(addr, size, !ExecMem);3628}36293630bool os::remove_stack_guard_pages(char* addr, size_t size) {3631return os::uncommit_memory(addr, size);3632}36333634static bool protect_pages_individually(char* addr, size_t bytes, unsigned int p, DWORD *old_status) {3635uint count = 0;3636bool ret = false;3637size_t bytes_remaining = bytes;3638char * next_protect_addr = addr;36393640// Use VirtualQuery() to get the chunk size.3641while (bytes_remaining) {3642MEMORY_BASIC_INFORMATION alloc_info;3643if (VirtualQuery(next_protect_addr, &alloc_info, sizeof(alloc_info)) == 0) {3644return false;3645}36463647size_t bytes_to_protect = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);3648// We used different API at allocate_pages_individually() based on UseNUMAInterleaving,3649// but we don't distinguish here as both cases are protected by same API.3650ret = VirtualProtect(next_protect_addr, bytes_to_protect, p, old_status) != 0;3651warning("Failed protecting pages individually for chunk #%u", count);3652if (!ret) {3653return false;3654}36553656bytes_remaining -= bytes_to_protect;3657next_protect_addr += bytes_to_protect;3658count++;3659}3660return ret;3661}36623663// Set protections specified3664bool os::protect_memory(char* addr, size_t bytes, ProtType prot,3665bool is_committed) {3666unsigned int p = 0;3667switch (prot) {3668case MEM_PROT_NONE: p = PAGE_NOACCESS; break;3669case MEM_PROT_READ: p = PAGE_READONLY; break;3670case MEM_PROT_RW: p = PAGE_READWRITE; break;3671case MEM_PROT_RWX: p = PAGE_EXECUTE_READWRITE; break;3672default:3673ShouldNotReachHere();3674}36753676DWORD old_status;36773678// Strange enough, but on Win32 one can change protection only for committed3679// memory, not a big deal anyway, as bytes less or equal than 64K3680if (!is_committed) {3681commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,3682"cannot commit protection page");3683}3684// One cannot use os::guard_memory() here, as on Win32 guard page3685// have different (one-shot) semantics, from MSDN on PAGE_GUARD:3686//3687// Pages in the region become guard pages. Any attempt to access a guard page3688// causes the system to raise a STATUS_GUARD_PAGE exception and turn off3689// the guard page status. Guard pages thus act as a one-time access alarm.3690bool ret;3691if (UseNUMAInterleaving) {3692// If UseNUMAInterleaving is enabled, the pages may have been allocated a chunk at a time,3693// so we must protect the chunks individually.3694ret = protect_pages_individually(addr, bytes, p, &old_status);3695} else {3696ret = VirtualProtect(addr, bytes, p, &old_status) != 0;3697}3698#ifdef ASSERT3699if (!ret) {3700int err = os::get_last_error();3701char buf[256];3702size_t buf_len = os::lasterror(buf, sizeof(buf));3703warning("INFO: os::protect_memory(" PTR_FORMAT ", " SIZE_FORMAT3704") failed; error='%s' (DOS error/errno=%d)", addr, bytes,3705buf_len != 0 ? buf : "<no_error_string>", err);3706}3707#endif3708return ret;3709}37103711bool os::guard_memory(char* addr, size_t bytes) {3712DWORD old_status;3713return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;3714}37153716bool os::unguard_memory(char* addr, size_t bytes) {3717DWORD old_status;3718return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;3719}37203721void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }3722void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }3723void os::numa_make_global(char *addr, size_t bytes) { }3724void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { }3725bool os::numa_topology_changed() { return false; }3726size_t os::numa_get_groups_num() { return MAX2(numa_node_list_holder.get_count(), 1); }3727int os::numa_get_group_id() { return 0; }3728size_t os::numa_get_leaf_groups(int *ids, size_t size) {3729if (numa_node_list_holder.get_count() == 0 && size > 0) {3730// Provide an answer for UMA systems3731ids[0] = 0;3732return 1;3733} else {3734// check for size bigger than actual groups_num3735size = MIN2(size, numa_get_groups_num());3736for (int i = 0; i < (int)size; i++) {3737ids[i] = numa_node_list_holder.get_node_list_entry(i);3738}3739return size;3740}3741}37423743int os::numa_get_group_id_for_address(const void* address) {3744return 0;3745}37463747bool os::get_page_info(char *start, page_info* info) {3748return false;3749}37503751char *os::scan_pages(char *start, char* end, page_info* page_expected,3752page_info* page_found) {3753return end;3754}37553756char* os::non_memory_address_word() {3757// Must never look like an address returned by reserve_memory,3758// even in its subfields (as defined by the CPU immediate fields,3759// if the CPU splits constants across multiple instructions).3760#ifdef _M_ARM643761// AArch64 has a maximum addressable space of 48-bits3762return (char*)((1ull << 48) - 1);3763#else3764return (char*)-1;3765#endif3766}37673768#define MAX_ERROR_COUNT 1003769#define SYS_THREAD_ERROR 0xffffffffUL37703771void os::pd_start_thread(Thread* thread) {3772DWORD ret = ResumeThread(thread->osthread()->thread_handle());3773// Returns previous suspend state:3774// 0: Thread was not suspended3775// 1: Thread is running now3776// >1: Thread is still suspended.3777assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back3778}377937803781// Short sleep, direct OS call.3782//3783// ms = 0, means allow others (if any) to run.3784//3785void os::naked_short_sleep(jlong ms) {3786assert(ms < 1000, "Un-interruptable sleep, short time use only");3787Sleep(ms);3788}37893790// Windows does not provide sleep functionality with nanosecond resolution, so we3791// try to approximate this with spinning combined with yielding if another thread3792// is ready to run on the current processor.3793void os::naked_short_nanosleep(jlong ns) {3794assert(ns > -1 && ns < NANOUNITS, "Un-interruptable sleep, short time use only");37953796int64_t start = os::javaTimeNanos();3797do {3798if (SwitchToThread() == 0) {3799// Nothing else is ready to run on this cpu, spin a little3800SpinPause();3801}3802} while (os::javaTimeNanos() - start < ns);3803}38043805// Sleep forever; naked call to OS-specific sleep; use with CAUTION3806void os::infinite_sleep() {3807while (true) { // sleep forever ...3808Sleep(100000); // ... 100 seconds at a time3809}3810}38113812typedef BOOL (WINAPI * STTSignature)(void);38133814void os::naked_yield() {3815// Consider passing back the return value from SwitchToThread().3816SwitchToThread();3817}38183819// Win32 only gives you access to seven real priorities at a time,3820// so we compress Java's ten down to seven. It would be better3821// if we dynamically adjusted relative priorities.38223823int os::java_to_os_priority[CriticalPriority + 1] = {3824THREAD_PRIORITY_IDLE, // 0 Entry should never be used3825THREAD_PRIORITY_LOWEST, // 1 MinPriority3826THREAD_PRIORITY_LOWEST, // 23827THREAD_PRIORITY_BELOW_NORMAL, // 33828THREAD_PRIORITY_BELOW_NORMAL, // 43829THREAD_PRIORITY_NORMAL, // 5 NormPriority3830THREAD_PRIORITY_NORMAL, // 63831THREAD_PRIORITY_ABOVE_NORMAL, // 73832THREAD_PRIORITY_ABOVE_NORMAL, // 83833THREAD_PRIORITY_HIGHEST, // 9 NearMaxPriority3834THREAD_PRIORITY_HIGHEST, // 10 MaxPriority3835THREAD_PRIORITY_HIGHEST // 11 CriticalPriority3836};38373838int prio_policy1[CriticalPriority + 1] = {3839THREAD_PRIORITY_IDLE, // 0 Entry should never be used3840THREAD_PRIORITY_LOWEST, // 1 MinPriority3841THREAD_PRIORITY_LOWEST, // 23842THREAD_PRIORITY_BELOW_NORMAL, // 33843THREAD_PRIORITY_BELOW_NORMAL, // 43844THREAD_PRIORITY_NORMAL, // 5 NormPriority3845THREAD_PRIORITY_ABOVE_NORMAL, // 63846THREAD_PRIORITY_ABOVE_NORMAL, // 73847THREAD_PRIORITY_HIGHEST, // 83848THREAD_PRIORITY_HIGHEST, // 9 NearMaxPriority3849THREAD_PRIORITY_TIME_CRITICAL, // 10 MaxPriority3850THREAD_PRIORITY_TIME_CRITICAL // 11 CriticalPriority3851};38523853static int prio_init() {3854// If ThreadPriorityPolicy is 1, switch tables3855if (ThreadPriorityPolicy == 1) {3856int i;3857for (i = 0; i < CriticalPriority + 1; i++) {3858os::java_to_os_priority[i] = prio_policy1[i];3859}3860}3861if (UseCriticalJavaThreadPriority) {3862os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];3863}3864return 0;3865}38663867OSReturn os::set_native_priority(Thread* thread, int priority) {3868if (!UseThreadPriorities) return OS_OK;3869bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0;3870return ret ? OS_OK : OS_ERR;3871}38723873OSReturn os::get_native_priority(const Thread* const thread,3874int* priority_ptr) {3875if (!UseThreadPriorities) {3876*priority_ptr = java_to_os_priority[NormPriority];3877return OS_OK;3878}3879int os_prio = GetThreadPriority(thread->osthread()->thread_handle());3880if (os_prio == THREAD_PRIORITY_ERROR_RETURN) {3881assert(false, "GetThreadPriority failed");3882return OS_ERR;3883}3884*priority_ptr = os_prio;3885return OS_OK;3886}38873888// GetCurrentThreadId() returns DWORD3889intx os::current_thread_id() { return GetCurrentThreadId(); }38903891static int _initial_pid = 0;38923893int os::current_process_id() {3894return (_initial_pid ? _initial_pid : _getpid());3895}38963897int os::win32::_vm_page_size = 0;3898int os::win32::_vm_allocation_granularity = 0;3899int os::win32::_processor_type = 0;3900// Processor level is not available on non-NT systems, use vm_version instead3901int os::win32::_processor_level = 0;3902julong os::win32::_physical_memory = 0;3903size_t os::win32::_default_stack_size = 0;39043905intx os::win32::_os_thread_limit = 0;3906volatile intx os::win32::_os_thread_count = 0;39073908bool os::win32::_is_windows_server = false;39093910// 65732543911// Currently, the bug is observed across all the supported Windows releases,3912// including the latest one (as of this writing - Windows Server 2012 R2)3913bool os::win32::_has_exit_bug = true;39143915void os::win32::initialize_system_info() {3916SYSTEM_INFO si;3917GetSystemInfo(&si);3918_vm_page_size = si.dwPageSize;3919_vm_allocation_granularity = si.dwAllocationGranularity;3920_processor_type = si.dwProcessorType;3921_processor_level = si.wProcessorLevel;3922set_processor_count(si.dwNumberOfProcessors);39233924MEMORYSTATUSEX ms;3925ms.dwLength = sizeof(ms);39263927// also returns dwAvailPhys (free physical memory bytes), dwTotalVirtual, dwAvailVirtual,3928// dwMemoryLoad (% of memory in use)3929GlobalMemoryStatusEx(&ms);3930_physical_memory = ms.ullTotalPhys;39313932if (FLAG_IS_DEFAULT(MaxRAM)) {3933// Adjust MaxRAM according to the maximum virtual address space available.3934FLAG_SET_DEFAULT(MaxRAM, MIN2(MaxRAM, (uint64_t) ms.ullTotalVirtual));3935}39363937OSVERSIONINFOEX oi;3938oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);3939GetVersionEx((OSVERSIONINFO*)&oi);3940switch (oi.dwPlatformId) {3941case VER_PLATFORM_WIN32_NT:3942{3943int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;3944if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER ||3945oi.wProductType == VER_NT_SERVER) {3946_is_windows_server = true;3947}3948}3949break;3950default: fatal("Unknown platform");3951}39523953_default_stack_size = os::current_stack_size();3954assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");3955assert((_default_stack_size & (_vm_page_size - 1)) == 0,3956"stack size not a multiple of page size");39573958initialize_performance_counter();3959}396039613962HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,3963int ebuflen) {3964char path[MAX_PATH];3965DWORD size;3966DWORD pathLen = (DWORD)sizeof(path);3967HINSTANCE result = NULL;39683969// only allow library name without path component3970assert(strchr(name, '\\') == NULL, "path not allowed");3971assert(strchr(name, ':') == NULL, "path not allowed");3972if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) {3973jio_snprintf(ebuf, ebuflen,3974"Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name);3975return NULL;3976}39773978// search system directory3979if ((size = GetSystemDirectory(path, pathLen)) > 0) {3980if (size >= pathLen) {3981return NULL; // truncated3982}3983if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {3984return NULL; // truncated3985}3986if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {3987return result;3988}3989}39903991// try Windows directory3992if ((size = GetWindowsDirectory(path, pathLen)) > 0) {3993if (size >= pathLen) {3994return NULL; // truncated3995}3996if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {3997return NULL; // truncated3998}3999if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {4000return result;4001}4002}40034004jio_snprintf(ebuf, ebuflen,4005"os::win32::load_windows_dll() cannot load %s from system directories.", name);4006return NULL;4007}40084009#define MAXIMUM_THREADS_TO_KEEP (16 * MAXIMUM_WAIT_OBJECTS)4010#define EXIT_TIMEOUT 300000 /* 5 minutes */40114012static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {4013InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);4014return TRUE;4015}40164017int os::win32::exit_process_or_thread(Ept what, int exit_code) {4018// Basic approach:4019// - Each exiting thread registers its intent to exit and then does so.4020// - A thread trying to terminate the process must wait for all4021// threads currently exiting to complete their exit.40224023if (os::win32::has_exit_bug()) {4024// The array holds handles of the threads that have started exiting by calling4025// _endthreadex().4026// Should be large enough to avoid blocking the exiting thread due to lack of4027// a free slot.4028static HANDLE handles[MAXIMUM_THREADS_TO_KEEP];4029static int handle_count = 0;40304031static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;4032static CRITICAL_SECTION crit_sect;4033static volatile DWORD process_exiting = 0;4034int i, j;4035DWORD res;4036HANDLE hproc, hthr;40374038// We only attempt to register threads until a process exiting4039// thread manages to set the process_exiting flag. Any threads4040// that come through here after the process_exiting flag is set4041// are unregistered and will be caught in the SuspendThread()4042// infinite loop below.4043bool registered = false;40444045// The first thread that reached this point, initializes the critical section.4046if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {4047warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);4048} else if (Atomic::load_acquire(&process_exiting) == 0) {4049if (what != EPT_THREAD) {4050// Atomically set process_exiting before the critical section4051// to increase the visibility between racing threads.4052Atomic::cmpxchg(&process_exiting, (DWORD)0, GetCurrentThreadId());4053}4054EnterCriticalSection(&crit_sect);40554056if (what == EPT_THREAD && Atomic::load_acquire(&process_exiting) == 0) {4057// Remove from the array those handles of the threads that have completed exiting.4058for (i = 0, j = 0; i < handle_count; ++i) {4059res = WaitForSingleObject(handles[i], 0 /* don't wait */);4060if (res == WAIT_TIMEOUT) {4061handles[j++] = handles[i];4062} else {4063if (res == WAIT_FAILED) {4064warning("WaitForSingleObject failed (%u) in %s: %d\n",4065GetLastError(), __FILE__, __LINE__);4066}4067// Don't keep the handle, if we failed waiting for it.4068CloseHandle(handles[i]);4069}4070}40714072// If there's no free slot in the array of the kept handles, we'll have to4073// wait until at least one thread completes exiting.4074if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) {4075// Raise the priority of the oldest exiting thread to increase its chances4076// to complete sooner.4077SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);4078res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);4079if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {4080i = (res - WAIT_OBJECT_0);4081handle_count = MAXIMUM_THREADS_TO_KEEP - 1;4082for (; i < handle_count; ++i) {4083handles[i] = handles[i + 1];4084}4085} else {4086warning("WaitForMultipleObjects %s (%u) in %s: %d\n",4087(res == WAIT_FAILED ? "failed" : "timed out"),4088GetLastError(), __FILE__, __LINE__);4089// Don't keep handles, if we failed waiting for them.4090for (i = 0; i < MAXIMUM_THREADS_TO_KEEP; ++i) {4091CloseHandle(handles[i]);4092}4093handle_count = 0;4094}4095}40964097// Store a duplicate of the current thread handle in the array of handles.4098hproc = GetCurrentProcess();4099hthr = GetCurrentThread();4100if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],41010, FALSE, DUPLICATE_SAME_ACCESS)) {4102warning("DuplicateHandle failed (%u) in %s: %d\n",4103GetLastError(), __FILE__, __LINE__);41044105// We can't register this thread (no more handles) so this thread4106// may be racing with a thread that is calling exit(). If the thread4107// that is calling exit() has managed to set the process_exiting4108// flag, then this thread will be caught in the SuspendThread()4109// infinite loop below which closes that race. A small timing4110// window remains before the process_exiting flag is set, but it4111// is only exposed when we are out of handles.4112} else {4113++handle_count;4114registered = true;41154116// The current exiting thread has stored its handle in the array, and now4117// should leave the critical section before calling _endthreadex().4118}41194120} else if (what != EPT_THREAD && handle_count > 0) {4121jlong start_time, finish_time, timeout_left;4122// Before ending the process, make sure all the threads that had called4123// _endthreadex() completed.41244125// Set the priority level of the current thread to the same value as4126// the priority level of exiting threads.4127// This is to ensure it will be given a fair chance to execute if4128// the timeout expires.4129hthr = GetCurrentThread();4130SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL);4131start_time = os::javaTimeNanos();4132finish_time = start_time + ((jlong)EXIT_TIMEOUT * 1000000L);4133for (i = 0; ; ) {4134int portion_count = handle_count - i;4135if (portion_count > MAXIMUM_WAIT_OBJECTS) {4136portion_count = MAXIMUM_WAIT_OBJECTS;4137}4138for (j = 0; j < portion_count; ++j) {4139SetThreadPriority(handles[i + j], THREAD_PRIORITY_ABOVE_NORMAL);4140}4141timeout_left = (finish_time - start_time) / 1000000L;4142if (timeout_left < 0) {4143timeout_left = 0;4144}4145res = WaitForMultipleObjects(portion_count, handles + i, TRUE, timeout_left);4146if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {4147warning("WaitForMultipleObjects %s (%u) in %s: %d\n",4148(res == WAIT_FAILED ? "failed" : "timed out"),4149GetLastError(), __FILE__, __LINE__);4150// Reset portion_count so we close the remaining4151// handles due to this error.4152portion_count = handle_count - i;4153}4154for (j = 0; j < portion_count; ++j) {4155CloseHandle(handles[i + j]);4156}4157if ((i += portion_count) >= handle_count) {4158break;4159}4160start_time = os::javaTimeNanos();4161}4162handle_count = 0;4163}41644165LeaveCriticalSection(&crit_sect);4166}41674168if (!registered &&4169Atomic::load_acquire(&process_exiting) != 0 &&4170process_exiting != GetCurrentThreadId()) {4171// Some other thread is about to call exit(), so we don't let4172// the current unregistered thread proceed to exit() or _endthreadex()4173while (true) {4174SuspendThread(GetCurrentThread());4175// Avoid busy-wait loop, if SuspendThread() failed.4176Sleep(EXIT_TIMEOUT);4177}4178}4179}41804181// We are here if either4182// - there's no 'race at exit' bug on this OS release;4183// - initialization of the critical section failed (unlikely);4184// - the current thread has registered itself and left the critical section;4185// - the process-exiting thread has raised the flag and left the critical section.4186if (what == EPT_THREAD) {4187_endthreadex((unsigned)exit_code);4188} else if (what == EPT_PROCESS) {4189::exit(exit_code);4190} else {4191_exit(exit_code);4192}41934194// Should not reach here4195return exit_code;4196}41974198#undef EXIT_TIMEOUT41994200void os::win32::setmode_streams() {4201_setmode(_fileno(stdin), _O_BINARY);4202_setmode(_fileno(stdout), _O_BINARY);4203_setmode(_fileno(stderr), _O_BINARY);4204}42054206void os::wait_for_keypress_at_exit(void) {4207if (PauseAtExit) {4208fprintf(stderr, "Press any key to continue...\n");4209fgetc(stdin);4210}4211}421242134214bool os::message_box(const char* title, const char* message) {4215int result = MessageBox(NULL, message, title,4216MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);4217return result == IDYES;4218}42194220#ifndef PRODUCT4221#ifndef _WIN644222// Helpers to check whether NX protection is enabled4223int nx_exception_filter(_EXCEPTION_POINTERS *pex) {4224if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&4225pex->ExceptionRecord->NumberParameters > 0 &&4226pex->ExceptionRecord->ExceptionInformation[0] ==4227EXCEPTION_INFO_EXEC_VIOLATION) {4228return EXCEPTION_EXECUTE_HANDLER;4229}4230return EXCEPTION_CONTINUE_SEARCH;4231}42324233void nx_check_protection() {4234// If NX is enabled we'll get an exception calling into code on the stack4235char code[] = { (char)0xC3 }; // ret4236void *code_ptr = (void *)code;4237__try {4238__asm call code_ptr4239} __except(nx_exception_filter((_EXCEPTION_POINTERS*)_exception_info())) {4240tty->print_raw_cr("NX protection detected.");4241}4242}4243#endif // _WIN644244#endif // PRODUCT42454246// This is called _before_ the global arguments have been parsed4247void os::init(void) {4248_initial_pid = _getpid();42494250win32::initialize_system_info();4251win32::setmode_streams();4252_page_sizes.add(win32::vm_page_size());42534254// This may be overridden later when argument processing is done.4255FLAG_SET_ERGO(UseLargePagesIndividualAllocation, false);42564257// Initialize main_process and main_thread4258main_process = GetCurrentProcess(); // Remember main_process is a pseudo handle4259if (!DuplicateHandle(main_process, GetCurrentThread(), main_process,4260&main_thread, THREAD_ALL_ACCESS, false, 0)) {4261fatal("DuplicateHandle failed\n");4262}4263main_thread_id = (int) GetCurrentThreadId();42644265// initialize fast thread access - only used for 32-bit4266win32::initialize_thread_ptr_offset();4267}42684269// To install functions for atexit processing4270extern "C" {4271static void perfMemory_exit_helper() {4272perfMemory_exit();4273}4274}42754276static jint initSock();427742784279// this is called _after_ the global arguments have been parsed4280jint os::init_2(void) {42814282// This could be set any time but all platforms4283// have to set it the same so we have to mirror Solaris.4284DEBUG_ONLY(os::set_mutex_init_done();)42854286// Setup Windows Exceptions42874288#if defined(USE_VECTORED_EXCEPTION_HANDLING)4289topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter);4290previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter);4291#endif42924293// for debugging float code generation bugs4294#if defined(ASSERT) && !defined(_WIN64)4295static long fp_control_word = 0;4296__asm { fstcw fp_control_word }4297// see Intel PPro Manual, Vol. 2, p 7-164298const long invalid = 0x01;4299fp_control_word |= invalid;4300__asm { fldcw fp_control_word }4301#endif43024303// If stack_commit_size is 0, windows will reserve the default size,4304// but only commit a small portion of it.4305size_t stack_commit_size = align_up(ThreadStackSize*K, os::vm_page_size());4306size_t default_reserve_size = os::win32::default_stack_size();4307size_t actual_reserve_size = stack_commit_size;4308if (stack_commit_size < default_reserve_size) {4309// If stack_commit_size == 0, we want this too4310actual_reserve_size = default_reserve_size;4311}43124313// Check minimum allowable stack size for thread creation and to initialize4314// the java system classes, including StackOverflowError - depends on page4315// size. Add two 4K pages for compiler2 recursion in main thread.4316// Add in 4*BytesPerWord 4K pages to account for VM stack during4317// class initialization depending on 32 or 64 bit VM.4318size_t min_stack_allowed =4319(size_t)(StackOverflow::stack_guard_zone_size() +4320StackOverflow::stack_shadow_zone_size() +4321(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);43224323min_stack_allowed = align_up(min_stack_allowed, os::vm_page_size());43244325if (actual_reserve_size < min_stack_allowed) {4326tty->print_cr("\nThe Java thread stack size specified is too small. "4327"Specify at least %dk",4328min_stack_allowed / K);4329return JNI_ERR;4330}43314332JavaThread::set_stack_size_at_create(stack_commit_size);43334334// Calculate theoretical max. size of Threads to guard gainst artifical4335// out-of-memory situations, where all available address-space has been4336// reserved by thread stacks.4337assert(actual_reserve_size != 0, "Must have a stack");43384339// Calculate the thread limit when we should start doing Virtual Memory4340// banging. Currently when the threads will have used all but 200Mb of space.4341//4342// TODO: consider performing a similar calculation for commit size instead4343// as reserve size, since on a 64-bit platform we'll run into that more4344// often than running out of virtual memory space. We can use the4345// lower value of the two calculations as the os_thread_limit.4346size_t max_address_space = ((size_t)1 << (BitsPerWord - 1)) - (200 * K * K);4347win32::_os_thread_limit = (intx)(max_address_space / actual_reserve_size);43484349// at exit methods are called in the reverse order of their registration.4350// there is no limit to the number of functions registered. atexit does4351// not set errno.43524353if (PerfAllowAtExitRegistration) {4354// only register atexit functions if PerfAllowAtExitRegistration is set.4355// atexit functions can be delayed until process exit time, which4356// can be problematic for embedded VM situations. Embedded VMs should4357// call DestroyJavaVM() to assure that VM resources are released.43584359// note: perfMemory_exit_helper atexit function may be removed in4360// the future if the appropriate cleanup code can be added to the4361// VM_Exit VMOperation's doit method.4362if (atexit(perfMemory_exit_helper) != 0) {4363warning("os::init_2 atexit(perfMemory_exit_helper) failed");4364}4365}43664367#ifndef _WIN644368// Print something if NX is enabled (win32 on AMD64)4369NOT_PRODUCT(if (PrintMiscellaneous && Verbose) nx_check_protection());4370#endif43714372// initialize thread priority policy4373prio_init();43744375UseNUMA = false; // We don't fully support this yet43764377if (UseNUMAInterleaving || (UseNUMA && FLAG_IS_DEFAULT(UseNUMAInterleaving))) {4378if (!numa_interleaving_init()) {4379FLAG_SET_ERGO(UseNUMAInterleaving, false);4380} else if (!UseNUMAInterleaving) {4381// When NUMA requested, not-NUMA-aware allocations default to interleaving.4382FLAG_SET_ERGO(UseNUMAInterleaving, true);4383}4384}43854386if (initSock() != JNI_OK) {4387return JNI_ERR;4388}43894390SymbolEngine::recalc_search_path();43914392// Initialize data for jdk.internal.misc.Signal4393if (!ReduceSignalUsage) {4394jdk_misc_signal_init();4395}43964397// Lookup SetThreadDescription - the docs state we must use runtime-linking of4398// kernelbase.dll, so that is what we do.4399HINSTANCE _kernelbase = LoadLibrary(TEXT("kernelbase.dll"));4400if (_kernelbase != NULL) {4401_SetThreadDescription =4402reinterpret_cast<SetThreadDescriptionFnPtr>(4403GetProcAddress(_kernelbase,4404"SetThreadDescription"));4405#ifdef ASSERT4406_GetThreadDescription =4407reinterpret_cast<GetThreadDescriptionFnPtr>(4408GetProcAddress(_kernelbase,4409"GetThreadDescription"));4410#endif4411}4412log_info(os, thread)("The SetThreadDescription API is%s available.", _SetThreadDescription == NULL ? " not" : "");441344144415return JNI_OK;4416}44174418// combine the high and low DWORD into a ULONGLONG4419static ULONGLONG make_double_word(DWORD high_word, DWORD low_word) {4420ULONGLONG value = high_word;4421value <<= sizeof(high_word) * 8;4422value |= low_word;4423return value;4424}44254426// Transfers data from WIN32_FILE_ATTRIBUTE_DATA structure to struct stat4427static void file_attribute_data_to_stat(struct stat* sbuf, WIN32_FILE_ATTRIBUTE_DATA file_data) {4428::memset((void*)sbuf, 0, sizeof(struct stat));4429sbuf->st_size = (_off_t)make_double_word(file_data.nFileSizeHigh, file_data.nFileSizeLow);4430sbuf->st_mtime = make_double_word(file_data.ftLastWriteTime.dwHighDateTime,4431file_data.ftLastWriteTime.dwLowDateTime);4432sbuf->st_ctime = make_double_word(file_data.ftCreationTime.dwHighDateTime,4433file_data.ftCreationTime.dwLowDateTime);4434sbuf->st_atime = make_double_word(file_data.ftLastAccessTime.dwHighDateTime,4435file_data.ftLastAccessTime.dwLowDateTime);4436if ((file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {4437sbuf->st_mode |= S_IFDIR;4438} else {4439sbuf->st_mode |= S_IFREG;4440}4441}44424443static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path) {4444// Get required buffer size to convert to Unicode4445int unicode_path_len = MultiByteToWideChar(CP_ACP,4446MB_ERR_INVALID_CHARS,4447char_path, -1,4448NULL, 0);4449if (unicode_path_len == 0) {4450return EINVAL;4451}44524453*unicode_path = NEW_C_HEAP_ARRAY(WCHAR, unicode_path_len, mtInternal);44544455int result = MultiByteToWideChar(CP_ACP,4456MB_ERR_INVALID_CHARS,4457char_path, -1,4458*unicode_path, unicode_path_len);4459assert(result == unicode_path_len, "length already checked above");44604461return ERROR_SUCCESS;4462}44634464static errno_t get_full_path(LPCWSTR unicode_path, LPWSTR* full_path) {4465// Get required buffer size to convert to full path. The return4466// value INCLUDES the terminating null character.4467DWORD full_path_len = GetFullPathNameW(unicode_path, 0, NULL, NULL);4468if (full_path_len == 0) {4469return EINVAL;4470}44714472*full_path = NEW_C_HEAP_ARRAY(WCHAR, full_path_len, mtInternal);44734474// When the buffer has sufficient size, the return value EXCLUDES the4475// terminating null character4476DWORD result = GetFullPathNameW(unicode_path, full_path_len, *full_path, NULL);4477assert(result <= full_path_len, "length already checked above");44784479return ERROR_SUCCESS;4480}44814482static void set_path_prefix(char* buf, LPWSTR* prefix, int* prefix_off, bool* needs_fullpath) {4483*prefix_off = 0;4484*needs_fullpath = true;44854486if (::isalpha(buf[0]) && !::IsDBCSLeadByte(buf[0]) && buf[1] == ':' && buf[2] == '\\') {4487*prefix = L"\\\\?\\";4488} else if (buf[0] == '\\' && buf[1] == '\\') {4489if (buf[2] == '?' && buf[3] == '\\') {4490*prefix = L"";4491*needs_fullpath = false;4492} else {4493*prefix = L"\\\\?\\UNC";4494*prefix_off = 1; // Overwrite the first char with the prefix, so \\share\path becomes \\?\UNC\share\path4495}4496} else {4497*prefix = L"\\\\?\\";4498}4499}45004501// Returns the given path as an absolute wide path in unc format. The returned path is NULL4502// on error (with err being set accordingly) and should be freed via os::free() otherwise.4503// additional_space is the size of space, in wchar_t, the function will additionally add to4504// the allocation of return buffer (such that the size of the returned buffer is at least4505// wcslen(buf) + 1 + additional_space).4506static wchar_t* wide_abs_unc_path(char const* path, errno_t & err, int additional_space = 0) {4507if ((path == NULL) || (path[0] == '\0')) {4508err = ENOENT;4509return NULL;4510}45114512// Need to allocate at least room for 3 characters, since os::native_path transforms C: to C:.4513size_t buf_len = 1 + MAX2((size_t)3, strlen(path));4514char* buf = NEW_C_HEAP_ARRAY(char, buf_len, mtInternal);4515strncpy(buf, path, buf_len);4516os::native_path(buf);45174518LPWSTR prefix = NULL;4519int prefix_off = 0;4520bool needs_fullpath = true;4521set_path_prefix(buf, &prefix, &prefix_off, &needs_fullpath);45224523LPWSTR unicode_path = NULL;4524err = convert_to_unicode(buf, &unicode_path);4525FREE_C_HEAP_ARRAY(char, buf);4526if (err != ERROR_SUCCESS) {4527return NULL;4528}45294530LPWSTR converted_path = NULL;4531if (needs_fullpath) {4532err = get_full_path(unicode_path, &converted_path);4533} else {4534converted_path = unicode_path;4535}45364537LPWSTR result = NULL;4538if (converted_path != NULL) {4539size_t prefix_len = wcslen(prefix);4540size_t result_len = prefix_len - prefix_off + wcslen(converted_path) + additional_space + 1;4541result = NEW_C_HEAP_ARRAY(WCHAR, result_len, mtInternal);4542_snwprintf(result, result_len, L"%s%s", prefix, &converted_path[prefix_off]);45434544// Remove trailing pathsep (not for \\?\<DRIVE>:\, since it would make it relative)4545result_len = wcslen(result);4546if ((result[result_len - 1] == L'\\') &&4547!(::iswalpha(result[4]) && result[5] == L':' && result_len == 7)) {4548result[result_len - 1] = L'\0';4549}4550}45514552if (converted_path != unicode_path) {4553FREE_C_HEAP_ARRAY(WCHAR, converted_path);4554}4555FREE_C_HEAP_ARRAY(WCHAR, unicode_path);45564557return static_cast<wchar_t*>(result); // LPWSTR and wchat_t* are the same type on Windows.4558}45594560int os::stat(const char *path, struct stat *sbuf) {4561errno_t err;4562wchar_t* wide_path = wide_abs_unc_path(path, err);45634564if (wide_path == NULL) {4565errno = err;4566return -1;4567}45684569WIN32_FILE_ATTRIBUTE_DATA file_data;;4570BOOL bret = ::GetFileAttributesExW(wide_path, GetFileExInfoStandard, &file_data);4571os::free(wide_path);45724573if (!bret) {4574errno = ::GetLastError();4575return -1;4576}45774578file_attribute_data_to_stat(sbuf, file_data);4579return 0;4580}45814582static HANDLE create_read_only_file_handle(const char* file) {4583errno_t err;4584wchar_t* wide_path = wide_abs_unc_path(file, err);45854586if (wide_path == NULL) {4587errno = err;4588return INVALID_HANDLE_VALUE;4589}45904591HANDLE handle = ::CreateFileW(wide_path, 0, FILE_SHARE_READ,4592NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);4593os::free(wide_path);45944595return handle;4596}45974598bool os::same_files(const char* file1, const char* file2) {45994600if (file1 == NULL && file2 == NULL) {4601return true;4602}46034604if (file1 == NULL || file2 == NULL) {4605return false;4606}46074608if (strcmp(file1, file2) == 0) {4609return true;4610}46114612char* native_file1 = os::strdup_check_oom(file1);4613native_file1 = os::native_path(native_file1);4614char* native_file2 = os::strdup_check_oom(file2);4615native_file2 = os::native_path(native_file2);4616if (strcmp(native_file1, native_file2) == 0) {4617os::free(native_file1);4618os::free(native_file2);4619return true;4620}46214622HANDLE handle1 = create_read_only_file_handle(native_file1);4623HANDLE handle2 = create_read_only_file_handle(native_file2);4624bool result = false;46254626// if we could open both paths...4627if (handle1 != INVALID_HANDLE_VALUE && handle2 != INVALID_HANDLE_VALUE) {4628BY_HANDLE_FILE_INFORMATION fileInfo1;4629BY_HANDLE_FILE_INFORMATION fileInfo2;4630if (::GetFileInformationByHandle(handle1, &fileInfo1) &&4631::GetFileInformationByHandle(handle2, &fileInfo2)) {4632// the paths are the same if they refer to the same file (fileindex) on the same volume (volume serial number)4633if (fileInfo1.dwVolumeSerialNumber == fileInfo2.dwVolumeSerialNumber &&4634fileInfo1.nFileIndexHigh == fileInfo2.nFileIndexHigh &&4635fileInfo1.nFileIndexLow == fileInfo2.nFileIndexLow) {4636result = true;4637}4638}4639}46404641//free the handles4642if (handle1 != INVALID_HANDLE_VALUE) {4643::CloseHandle(handle1);4644}46454646if (handle2 != INVALID_HANDLE_VALUE) {4647::CloseHandle(handle2);4648}46494650os::free(native_file1);4651os::free(native_file2);46524653return result;4654}46554656#define FT2INT64(ft) \4657((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))465846594660// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)4661// are used by JVM M&M and JVMTI to get user+sys or user CPU time4662// of a thread.4663//4664// current_thread_cpu_time() and thread_cpu_time(Thread*) returns4665// the fast estimate available on the platform.46664667// current_thread_cpu_time() is not optimized for Windows yet4668jlong os::current_thread_cpu_time() {4669// return user + sys since the cost is the same4670return os::thread_cpu_time(Thread::current(), true /* user+sys */);4671}46724673jlong os::thread_cpu_time(Thread* thread) {4674// consistent with what current_thread_cpu_time() returns.4675return os::thread_cpu_time(thread, true /* user+sys */);4676}46774678jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {4679return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);4680}46814682jlong os::thread_cpu_time(Thread* thread, bool user_sys_cpu_time) {4683// This code is copy from clasic VM -> hpi::sysThreadCPUTime4684// If this function changes, os::is_thread_cpu_time_supported() should too4685FILETIME CreationTime;4686FILETIME ExitTime;4687FILETIME KernelTime;4688FILETIME UserTime;46894690if (GetThreadTimes(thread->osthread()->thread_handle(), &CreationTime,4691&ExitTime, &KernelTime, &UserTime) == 0) {4692return -1;4693} else if (user_sys_cpu_time) {4694return (FT2INT64(UserTime) + FT2INT64(KernelTime)) * 100;4695} else {4696return FT2INT64(UserTime) * 100;4697}4698}46994700void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {4701info_ptr->max_value = ALL_64_BITS; // the max value -- all 64 bits4702info_ptr->may_skip_backward = false; // GetThreadTimes returns absolute time4703info_ptr->may_skip_forward = false; // GetThreadTimes returns absolute time4704info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned4705}47064707void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {4708info_ptr->max_value = ALL_64_BITS; // the max value -- all 64 bits4709info_ptr->may_skip_backward = false; // GetThreadTimes returns absolute time4710info_ptr->may_skip_forward = false; // GetThreadTimes returns absolute time4711info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned4712}47134714bool os::is_thread_cpu_time_supported() {4715// see os::thread_cpu_time4716FILETIME CreationTime;4717FILETIME ExitTime;4718FILETIME KernelTime;4719FILETIME UserTime;47204721if (GetThreadTimes(GetCurrentThread(), &CreationTime, &ExitTime,4722&KernelTime, &UserTime) == 0) {4723return false;4724} else {4725return true;4726}4727}47284729// Windows does't provide a loadavg primitive so this is stubbed out for now.4730// It does have primitives (PDH API) to get CPU usage and run queue length.4731// "\\Processor(_Total)\\% Processor Time", "\\System\\Processor Queue Length"4732// If we wanted to implement loadavg on Windows, we have a few options:4733//4734// a) Query CPU usage and run queue length and "fake" an answer by4735// returning the CPU usage if it's under 100%, and the run queue4736// length otherwise. It turns out that querying is pretty slow4737// on Windows, on the order of 200 microseconds on a fast machine.4738// Note that on the Windows the CPU usage value is the % usage4739// since the last time the API was called (and the first call4740// returns 100%), so we'd have to deal with that as well.4741//4742// b) Sample the "fake" answer using a sampling thread and store4743// the answer in a global variable. The call to loadavg would4744// just return the value of the global, avoiding the slow query.4745//4746// c) Sample a better answer using exponential decay to smooth the4747// value. This is basically the algorithm used by UNIX kernels.4748//4749// Note that sampling thread starvation could affect both (b) and (c).4750int os::loadavg(double loadavg[], int nelem) {4751return -1;4752}475347544755// DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield()4756bool os::dont_yield() {4757return DontYieldALot;4758}47594760int os::open(const char *path, int oflag, int mode) {4761errno_t err;4762wchar_t* wide_path = wide_abs_unc_path(path, err);47634764if (wide_path == NULL) {4765errno = err;4766return -1;4767}4768int fd = ::_wopen(wide_path, oflag | O_BINARY | O_NOINHERIT, mode);4769os::free(wide_path);47704771if (fd == -1) {4772errno = ::GetLastError();4773}47744775return fd;4776}47774778FILE* os::open(int fd, const char* mode) {4779return ::_fdopen(fd, mode);4780}47814782size_t os::write(int fd, const void *buf, unsigned int nBytes) {4783return ::write(fd, buf, nBytes);4784}47854786int os::close(int fd) {4787return ::close(fd);4788}47894790void os::exit(int num) {4791win32::exit_process_or_thread(win32::EPT_PROCESS, num);4792}47934794// Is a (classpath) directory empty?4795bool os::dir_is_empty(const char* path) {4796errno_t err;4797wchar_t* wide_path = wide_abs_unc_path(path, err, 2);47984799if (wide_path == NULL) {4800errno = err;4801return false;4802}48034804// Make sure we end with "\\*"4805if (wide_path[wcslen(wide_path) - 1] == L'\\') {4806wcscat(wide_path, L"*");4807} else {4808wcscat(wide_path, L"\\*");4809}48104811WIN32_FIND_DATAW fd;4812HANDLE f = ::FindFirstFileW(wide_path, &fd);4813os::free(wide_path);4814bool is_empty = true;48154816if (f != INVALID_HANDLE_VALUE) {4817while (is_empty && ::FindNextFileW(f, &fd)) {4818// An empty directory contains only the current directory file4819// and the previous directory file.4820if ((wcscmp(fd.cFileName, L".") != 0) &&4821(wcscmp(fd.cFileName, L"..") != 0)) {4822is_empty = false;4823}4824}4825FindClose(f);4826} else {4827errno = ::GetLastError();4828}48294830return is_empty;4831}48324833// create binary file, rewriting existing file if required4834int os::create_binary_file(const char* path, bool rewrite_existing) {4835int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;4836oflags |= rewrite_existing ? _O_TRUNC : _O_EXCL;4837return ::open(path, oflags, _S_IREAD | _S_IWRITE);4838}48394840// return current position of file pointer4841jlong os::current_file_offset(int fd) {4842return (jlong)::_lseeki64(fd, (__int64)0L, SEEK_CUR);4843}48444845// move file pointer to the specified offset4846jlong os::seek_to_file_offset(int fd, jlong offset) {4847return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET);4848}484948504851jlong os::lseek(int fd, jlong offset, int whence) {4852return (jlong) ::_lseeki64(fd, offset, whence);4853}48544855ssize_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) {4856OVERLAPPED ov;4857DWORD nread;4858BOOL result;48594860ZeroMemory(&ov, sizeof(ov));4861ov.Offset = (DWORD)offset;4862ov.OffsetHigh = (DWORD)(offset >> 32);48634864HANDLE h = (HANDLE)::_get_osfhandle(fd);48654866result = ReadFile(h, (LPVOID)buf, nBytes, &nread, &ov);48674868return result ? nread : 0;4869}487048714872// This method is a slightly reworked copy of JDK's sysNativePath4873// from src/windows/hpi/src/path_md.c48744875// Convert a pathname to native format. On win32, this involves forcing all4876// separators to be '\\' rather than '/' (both are legal inputs, but Win954877// sometimes rejects '/') and removing redundant separators. The input path is4878// assumed to have been converted into the character encoding used by the local4879// system. Because this might be a double-byte encoding, care is taken to4880// treat double-byte lead characters correctly.4881//4882// This procedure modifies the given path in place, as the result is never4883// longer than the original. There is no error return; this operation always4884// succeeds.4885char * os::native_path(char *path) {4886char *src = path, *dst = path, *end = path;4887char *colon = NULL; // If a drive specifier is found, this will4888// point to the colon following the drive letter48894890// Assumption: '/', '\\', ':', and drive letters are never lead bytes4891assert(((!::IsDBCSLeadByte('/')) && (!::IsDBCSLeadByte('\\'))4892&& (!::IsDBCSLeadByte(':'))), "Illegal lead byte");48934894// Check for leading separators4895#define isfilesep(c) ((c) == '/' || (c) == '\\')4896while (isfilesep(*src)) {4897src++;4898}48994900if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') {4901// Remove leading separators if followed by drive specifier. This4902// hack is necessary to support file URLs containing drive4903// specifiers (e.g., "file://c:/path"). As a side effect,4904// "/c:/path" can be used as an alternative to "c:/path".4905*dst++ = *src++;4906colon = dst;4907*dst++ = ':';4908src++;4909} else {4910src = path;4911if (isfilesep(src[0]) && isfilesep(src[1])) {4912// UNC pathname: Retain first separator; leave src pointed at4913// second separator so that further separators will be collapsed4914// into the second separator. The result will be a pathname4915// beginning with "\\\\" followed (most likely) by a host name.4916src = dst = path + 1;4917path[0] = '\\'; // Force first separator to '\\'4918}4919}49204921end = dst;49224923// Remove redundant separators from remainder of path, forcing all4924// separators to be '\\' rather than '/'. Also, single byte space4925// characters are removed from the end of the path because those4926// are not legal ending characters on this operating system.4927//4928while (*src != '\0') {4929if (isfilesep(*src)) {4930*dst++ = '\\'; src++;4931while (isfilesep(*src)) src++;4932if (*src == '\0') {4933// Check for trailing separator4934end = dst;4935if (colon == dst - 2) break; // "z:\\"4936if (dst == path + 1) break; // "\\"4937if (dst == path + 2 && isfilesep(path[0])) {4938// "\\\\" is not collapsed to "\\" because "\\\\" marks the4939// beginning of a UNC pathname. Even though it is not, by4940// itself, a valid UNC pathname, we leave it as is in order4941// to be consistent with the path canonicalizer as well4942// as the win32 APIs, which treat this case as an invalid4943// UNC pathname rather than as an alias for the root4944// directory of the current drive.4945break;4946}4947end = --dst; // Path does not denote a root directory, so4948// remove trailing separator4949break;4950}4951end = dst;4952} else {4953if (::IsDBCSLeadByte(*src)) { // Copy a double-byte character4954*dst++ = *src++;4955if (*src) *dst++ = *src++;4956end = dst;4957} else { // Copy a single-byte character4958char c = *src++;4959*dst++ = c;4960// Space is not a legal ending character4961if (c != ' ') end = dst;4962}4963}4964}49654966*end = '\0';49674968// For "z:", add "." to work around a bug in the C runtime library4969if (colon == dst - 1) {4970path[2] = '.';4971path[3] = '\0';4972}49734974return path;4975}49764977// This code is a copy of JDK's sysSetLength4978// from src/windows/hpi/src/sys_api_md.c49794980int os::ftruncate(int fd, jlong length) {4981HANDLE h = (HANDLE)::_get_osfhandle(fd);4982long high = (long)(length >> 32);4983DWORD ret;49844985if (h == (HANDLE)(-1)) {4986return -1;4987}49884989ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN);4990if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) {4991return -1;4992}49934994if (::SetEndOfFile(h) == FALSE) {4995return -1;4996}49974998return 0;4999}50005001int os::get_fileno(FILE* fp) {5002return _fileno(fp);5003}50045005// This code is a copy of JDK's sysSync5006// from src/windows/hpi/src/sys_api_md.c5007// except for the legacy workaround for a bug in Win 9850085009int os::fsync(int fd) {5010HANDLE handle = (HANDLE)::_get_osfhandle(fd);50115012if ((!::FlushFileBuffers(handle)) &&5013(GetLastError() != ERROR_ACCESS_DENIED)) {5014// from winerror.h5015return -1;5016}5017return 0;5018}50195020static int nonSeekAvailable(int, long *);5021static int stdinAvailable(int, long *);50225023// This code is a copy of JDK's sysAvailable5024// from src/windows/hpi/src/sys_api_md.c50255026int os::available(int fd, jlong *bytes) {5027jlong cur, end;5028struct _stati64 stbuf64;50295030if (::_fstati64(fd, &stbuf64) >= 0) {5031int mode = stbuf64.st_mode;5032if (S_ISCHR(mode) || S_ISFIFO(mode)) {5033int ret;5034long lpbytes;5035if (fd == 0) {5036ret = stdinAvailable(fd, &lpbytes);5037} else {5038ret = nonSeekAvailable(fd, &lpbytes);5039}5040(*bytes) = (jlong)(lpbytes);5041return ret;5042}5043if ((cur = ::_lseeki64(fd, 0L, SEEK_CUR)) == -1) {5044return FALSE;5045} else if ((end = ::_lseeki64(fd, 0L, SEEK_END)) == -1) {5046return FALSE;5047} else if (::_lseeki64(fd, cur, SEEK_SET) == -1) {5048return FALSE;5049}5050*bytes = end - cur;5051return TRUE;5052} else {5053return FALSE;5054}5055}50565057void os::flockfile(FILE* fp) {5058_lock_file(fp);5059}50605061void os::funlockfile(FILE* fp) {5062_unlock_file(fp);5063}50645065// This code is a copy of JDK's nonSeekAvailable5066// from src/windows/hpi/src/sys_api_md.c50675068static int nonSeekAvailable(int fd, long *pbytes) {5069// This is used for available on non-seekable devices5070// (like both named and anonymous pipes, such as pipes5071// connected to an exec'd process).5072// Standard Input is a special case.5073HANDLE han;50745075if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) {5076return FALSE;5077}50785079if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) {5080// PeekNamedPipe fails when at EOF. In that case we5081// simply make *pbytes = 0 which is consistent with the5082// behavior we get on Solaris when an fd is at EOF.5083// The only alternative is to raise an Exception,5084// which isn't really warranted.5085//5086if (::GetLastError() != ERROR_BROKEN_PIPE) {5087return FALSE;5088}5089*pbytes = 0;5090}5091return TRUE;5092}50935094#define MAX_INPUT_EVENTS 200050955096// This code is a copy of JDK's stdinAvailable5097// from src/windows/hpi/src/sys_api_md.c50985099static int stdinAvailable(int fd, long *pbytes) {5100HANDLE han;5101DWORD numEventsRead = 0; // Number of events read from buffer5102DWORD numEvents = 0; // Number of events in buffer5103DWORD i = 0; // Loop index5104DWORD curLength = 0; // Position marker5105DWORD actualLength = 0; // Number of bytes readable5106BOOL error = FALSE; // Error holder5107INPUT_RECORD *lpBuffer; // Pointer to records of input events51085109if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {5110return FALSE;5111}51125113// Construct an array of input records in the console buffer5114error = ::GetNumberOfConsoleInputEvents(han, &numEvents);5115if (error == 0) {5116return nonSeekAvailable(fd, pbytes);5117}51185119// lpBuffer must fit into 64K or else PeekConsoleInput fails5120if (numEvents > MAX_INPUT_EVENTS) {5121numEvents = MAX_INPUT_EVENTS;5122}51235124lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal);5125if (lpBuffer == NULL) {5126return FALSE;5127}51285129error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);5130if (error == 0) {5131os::free(lpBuffer);5132return FALSE;5133}51345135// Examine input records for the number of bytes available5136for (i=0; i<numEvents; i++) {5137if (lpBuffer[i].EventType == KEY_EVENT) {51385139KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *)5140&(lpBuffer[i].Event);5141if (keyRecord->bKeyDown == TRUE) {5142CHAR *keyPressed = (CHAR *) &(keyRecord->uChar);5143curLength++;5144if (*keyPressed == '\r') {5145actualLength = curLength;5146}5147}5148}5149}51505151if (lpBuffer != NULL) {5152os::free(lpBuffer);5153}51545155*pbytes = (long) actualLength;5156return TRUE;5157}51585159// Map a block of memory.5160char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,5161char *addr, size_t bytes, bool read_only,5162bool allow_exec) {51635164errno_t err;5165wchar_t* wide_path = wide_abs_unc_path(file_name, err);51665167if (wide_path == NULL) {5168return NULL;5169}51705171HANDLE hFile;5172char* base;51735174hFile = CreateFileW(wide_path, GENERIC_READ, FILE_SHARE_READ, NULL,5175OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);5176if (hFile == INVALID_HANDLE_VALUE) {5177log_info(os)("CreateFileW() failed: GetLastError->%ld.", GetLastError());5178os::free(wide_path);5179return NULL;5180}5181os::free(wide_path);51825183if (allow_exec) {5184// CreateFileMapping/MapViewOfFileEx can't map executable memory5185// unless it comes from a PE image (which the shared archive is not.)5186// Even VirtualProtect refuses to give execute access to mapped memory5187// that was not previously executable.5188//5189// Instead, stick the executable region in anonymous memory. Yuck.5190// Penalty is that ~4 pages will not be shareable - in the future5191// we might consider DLLizing the shared archive with a proper PE5192// header so that mapping executable + sharing is possible.51935194base = (char*) virtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE,5195PAGE_READWRITE);5196if (base == NULL) {5197CloseHandle(hFile);5198return NULL;5199}52005201// Record virtual memory allocation5202MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, CALLER_PC);52035204DWORD bytes_read;5205OVERLAPPED overlapped;5206overlapped.Offset = (DWORD)file_offset;5207overlapped.OffsetHigh = 0;5208overlapped.hEvent = NULL;5209// ReadFile guarantees that if the return value is true, the requested5210// number of bytes were read before returning.5211bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0;5212if (!res) {5213log_info(os)("ReadFile() failed: GetLastError->%ld.", GetLastError());5214release_memory(base, bytes);5215CloseHandle(hFile);5216return NULL;5217}5218} else {5219HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0,5220NULL /* file_name */);5221if (hMap == NULL) {5222log_info(os)("CreateFileMapping() failed: GetLastError->%ld.", GetLastError());5223CloseHandle(hFile);5224return NULL;5225}52265227DWORD access = read_only ? FILE_MAP_READ : FILE_MAP_COPY;5228base = (char*)mapViewOfFileEx(hMap, access, 0, (DWORD)file_offset,5229(DWORD)bytes, addr);5230if (base == NULL) {5231CloseHandle(hMap);5232CloseHandle(hFile);5233return NULL;5234}52355236if (CloseHandle(hMap) == 0) {5237log_info(os)("CloseHandle(hMap) failed: GetLastError->%ld.", GetLastError());5238CloseHandle(hFile);5239return base;5240}5241}52425243if (allow_exec) {5244DWORD old_protect;5245DWORD exec_access = read_only ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE;5246bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0;52475248if (!res) {5249log_info(os)("VirtualProtect() failed: GetLastError->%ld.", GetLastError());5250// Don't consider this a hard error, on IA32 even if the5251// VirtualProtect fails, we should still be able to execute5252CloseHandle(hFile);5253return base;5254}5255}52565257if (CloseHandle(hFile) == 0) {5258log_info(os)("CloseHandle(hFile) failed: GetLastError->%ld.", GetLastError());5259return base;5260}52615262return base;5263}526452655266// Remap a block of memory.5267char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,5268char *addr, size_t bytes, bool read_only,5269bool allow_exec) {5270// This OS does not allow existing memory maps to be remapped so we5271// would have to unmap the memory before we remap it.52725273// Because there is a small window between unmapping memory and mapping5274// it in again with different protections, CDS archives are mapped RW5275// on windows, so this function isn't called.5276ShouldNotReachHere();5277return NULL;5278}527952805281// Unmap a block of memory.5282// Returns true=success, otherwise false.52835284bool os::pd_unmap_memory(char* addr, size_t bytes) {5285MEMORY_BASIC_INFORMATION mem_info;5286if (VirtualQuery(addr, &mem_info, sizeof(mem_info)) == 0) {5287log_info(os)("VirtualQuery() failed: GetLastError->%ld.", GetLastError());5288return false;5289}52905291// Executable memory was not mapped using CreateFileMapping/MapViewOfFileEx.5292// Instead, executable region was allocated using VirtualAlloc(). See5293// pd_map_memory() above.5294//5295// The following flags should match the 'exec_access' flages used for5296// VirtualProtect() in pd_map_memory().5297if (mem_info.Protect == PAGE_EXECUTE_READ ||5298mem_info.Protect == PAGE_EXECUTE_READWRITE) {5299return pd_release_memory(addr, bytes);5300}53015302BOOL result = unmapViewOfFile(addr);5303if (result == 0) {5304return false;5305}5306return true;5307}53085309void os::pause() {5310char filename[MAX_PATH];5311if (PauseAtStartupFile && PauseAtStartupFile[0]) {5312jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);5313} else {5314jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());5315}53165317int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);5318if (fd != -1) {5319struct stat buf;5320::close(fd);5321while (::stat(filename, &buf) == 0) {5322Sleep(100);5323}5324} else {5325jio_fprintf(stderr,5326"Could not open pause file '%s', continuing immediately.\n", filename);5327}5328}53295330Thread* os::ThreadCrashProtection::_protected_thread = NULL;5331os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;53325333os::ThreadCrashProtection::ThreadCrashProtection() {5334_protected_thread = Thread::current();5335assert(_protected_thread->is_JfrSampler_thread(), "should be JFRSampler");5336}53375338// See the caveats for this class in os_windows.hpp5339// Protects the callback call so that raised OS EXCEPTIONS causes a jump back5340// into this method and returns false. If no OS EXCEPTION was raised, returns5341// true.5342// The callback is supposed to provide the method that should be protected.5343//5344bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) {5345bool success = true;5346__try {5347_crash_protection = this;5348cb.call();5349} __except(EXCEPTION_EXECUTE_HANDLER) {5350// only for protection, nothing to do5351success = false;5352}5353_crash_protection = NULL;5354_protected_thread = NULL;5355return success;5356}535753585359class HighResolutionInterval : public CHeapObj<mtThread> {5360// The default timer resolution seems to be 10 milliseconds.5361// (Where is this written down?)5362// If someone wants to sleep for only a fraction of the default,5363// then we set the timer resolution down to 1 millisecond for5364// the duration of their interval.5365// We carefully set the resolution back, since otherwise we5366// seem to incur an overhead (3%?) that we don't need.5367// CONSIDER: if ms is small, say 3, then we should run with a high resolution time.5368// Buf if ms is large, say 500, or 503, we should avoid the call to timeBeginPeriod().5369// Alternatively, we could compute the relative error (503/500 = .6%) and only use5370// timeBeginPeriod() if the relative error exceeded some threshold.5371// timeBeginPeriod() has been linked to problems with clock drift on win32 systems and5372// to decreased efficiency related to increased timer "tick" rates. We want to minimize5373// (a) calls to timeBeginPeriod() and timeEndPeriod() and (b) time spent with high5374// resolution timers running.5375private:5376jlong resolution;5377public:5378HighResolutionInterval(jlong ms) {5379resolution = ms % 10L;5380if (resolution != 0) {5381MMRESULT result = timeBeginPeriod(1L);5382}5383}5384~HighResolutionInterval() {5385if (resolution != 0) {5386MMRESULT result = timeEndPeriod(1L);5387}5388resolution = 0L;5389}5390};53915392// An Event wraps a win32 "CreateEvent" kernel handle.5393//5394// We have a number of choices regarding "CreateEvent" win32 handle leakage:5395//5396// 1: When a thread dies return the Event to the EventFreeList, clear the ParkHandle5397// field, and call CloseHandle() on the win32 event handle. Unpark() would5398// need to be modified to tolerate finding a NULL (invalid) win32 event handle.5399// In addition, an unpark() operation might fetch the handle field, but the5400// event could recycle between the fetch and the SetEvent() operation.5401// SetEvent() would either fail because the handle was invalid, or inadvertently work,5402// as the win32 handle value had been recycled. In an ideal world calling SetEvent()5403// on an stale but recycled handle would be harmless, but in practice this might5404// confuse other non-Sun code, so it's not a viable approach.5405//5406// 2: Once a win32 event handle is associated with an Event, it remains associated5407// with the Event. The event handle is never closed. This could be construed5408// as handle leakage, but only up to the maximum # of threads that have been extant5409// at any one time. This shouldn't be an issue, as windows platforms typically5410// permit a process to have hundreds of thousands of open handles.5411//5412// 3: Same as (1), but periodically, at stop-the-world time, rundown the EventFreeList5413// and release unused handles.5414//5415// 4: Add a CRITICAL_SECTION to the Event to protect LD+SetEvent from LD;ST(null);CloseHandle.5416// It's not clear, however, that we wouldn't be trading one type of leak for another.5417//5418// 5. Use an RCU-like mechanism (Read-Copy Update).5419// Or perhaps something similar to Maged Michael's "Hazard pointers".5420//5421// We use (2).5422//5423// TODO-FIXME:5424// 1. Reconcile Doug's JSR166 j.u.c park-unpark with the objectmonitor implementation.5425// 2. Consider wrapping the WaitForSingleObject(Ex) calls in SEH try/finally blocks5426// to recover from (or at least detect) the dreaded Windows 841176 bug.5427// 3. Collapse the JSR166 parker event, and the objectmonitor ParkEvent5428// into a single win32 CreateEvent() handle.5429//5430// Assumption:5431// Only one parker can exist on an event, which is why we allocate5432// them per-thread. Multiple unparkers can coexist.5433//5434// _Event transitions in park()5435// -1 => -1 : illegal5436// 1 => 0 : pass - return immediately5437// 0 => -1 : block; then set _Event to 0 before returning5438//5439// _Event transitions in unpark()5440// 0 => 1 : just return5441// 1 => 1 : just return5442// -1 => either 0 or 1; must signal target thread5443// That is, we can safely transition _Event from -1 to either5444// 0 or 1.5445//5446// _Event serves as a restricted-range semaphore.5447// -1 : thread is blocked, i.e. there is a waiter5448// 0 : neutral: thread is running or ready,5449// could have been signaled after a wait started5450// 1 : signaled - thread is running or ready5451//5452// Another possible encoding of _Event would be with5453// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.5454//54555456int os::PlatformEvent::park(jlong Millis) {5457// Transitions for _Event:5458// -1 => -1 : illegal5459// 1 => 0 : pass - return immediately5460// 0 => -1 : block; then set _Event to 0 before returning54615462guarantee(_ParkHandle != NULL , "Invariant");5463guarantee(Millis > 0 , "Invariant");54645465// CONSIDER: defer assigning a CreateEvent() handle to the Event until5466// the initial park() operation.5467// Consider: use atomic decrement instead of CAS-loop54685469int v;5470for (;;) {5471v = _Event;5472if (Atomic::cmpxchg(&_Event, v, v-1) == v) break;5473}5474guarantee((v == 0) || (v == 1), "invariant");5475if (v != 0) return OS_OK;54765477// Do this the hard way by blocking ...5478// TODO: consider a brief spin here, gated on the success of recent5479// spin attempts by this thread.5480//5481// We decompose long timeouts into series of shorter timed waits.5482// Evidently large timo values passed in WaitForSingleObject() are problematic on some5483// versions of Windows. See EventWait() for details. This may be superstition. Or not.5484// We trust the WAIT_TIMEOUT indication and don't track the elapsed wait time5485// with os::javaTimeNanos(). Furthermore, we assume that spurious returns from5486// ::WaitForSingleObject() caused by latent ::setEvent() operations will tend5487// to happen early in the wait interval. Specifically, after a spurious wakeup (rv ==5488// WAIT_OBJECT_0 but _Event is still < 0) we don't bother to recompute Millis to compensate5489// for the already waited time. This policy does not admit any new outcomes.5490// In the future, however, we might want to track the accumulated wait time and5491// adjust Millis accordingly if we encounter a spurious wakeup.54925493const int MAXTIMEOUT = 0x10000000;5494DWORD rv = WAIT_TIMEOUT;5495while (_Event < 0 && Millis > 0) {5496DWORD prd = Millis; // set prd = MAX (Millis, MAXTIMEOUT)5497if (Millis > MAXTIMEOUT) {5498prd = MAXTIMEOUT;5499}5500HighResolutionInterval *phri = NULL;5501if (!ForceTimeHighResolution) {5502phri = new HighResolutionInterval(prd);5503}5504rv = ::WaitForSingleObject(_ParkHandle, prd);5505assert(rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT, "WaitForSingleObject failed");5506if (rv == WAIT_TIMEOUT) {5507Millis -= prd;5508}5509delete phri; // if it is NULL, harmless5510}5511v = _Event;5512_Event = 0;5513// see comment at end of os::PlatformEvent::park() below:5514OrderAccess::fence();5515// If we encounter a nearly simultanous timeout expiry and unpark()5516// we return OS_OK indicating we awoke via unpark().5517// Implementor's license -- returning OS_TIMEOUT would be equally valid, however.5518return (v >= 0) ? OS_OK : OS_TIMEOUT;5519}55205521void os::PlatformEvent::park() {5522// Transitions for _Event:5523// -1 => -1 : illegal5524// 1 => 0 : pass - return immediately5525// 0 => -1 : block; then set _Event to 0 before returning55265527guarantee(_ParkHandle != NULL, "Invariant");5528// Invariant: Only the thread associated with the Event/PlatformEvent5529// may call park().5530// Consider: use atomic decrement instead of CAS-loop5531int v;5532for (;;) {5533v = _Event;5534if (Atomic::cmpxchg(&_Event, v, v-1) == v) break;5535}5536guarantee((v == 0) || (v == 1), "invariant");5537if (v != 0) return;55385539// Do this the hard way by blocking ...5540// TODO: consider a brief spin here, gated on the success of recent5541// spin attempts by this thread.5542while (_Event < 0) {5543DWORD rv = ::WaitForSingleObject(_ParkHandle, INFINITE);5544assert(rv == WAIT_OBJECT_0, "WaitForSingleObject failed");5545}55465547// Usually we'll find _Event == 0 at this point, but as5548// an optional optimization we clear it, just in case can5549// multiple unpark() operations drove _Event up to 1.5550_Event = 0;5551OrderAccess::fence();5552guarantee(_Event >= 0, "invariant");5553}55545555void os::PlatformEvent::unpark() {5556guarantee(_ParkHandle != NULL, "Invariant");55575558// Transitions for _Event:5559// 0 => 1 : just return5560// 1 => 1 : just return5561// -1 => either 0 or 1; must signal target thread5562// That is, we can safely transition _Event from -1 to either5563// 0 or 1.5564// See also: "Semaphores in Plan 9" by Mullender & Cox5565//5566// Note: Forcing a transition from "-1" to "1" on an unpark() means5567// that it will take two back-to-back park() calls for the owning5568// thread to block. This has the benefit of forcing a spurious return5569// from the first park() call after an unpark() call which will help5570// shake out uses of park() and unpark() without condition variables.55715572if (Atomic::xchg(&_Event, 1) >= 0) return;55735574::SetEvent(_ParkHandle);5575}557655775578// JSR1665579// -------------------------------------------------------55805581// The Windows implementation of Park is very straightforward: Basic5582// operations on Win32 Events turn out to have the right semantics to5583// use them directly.55845585void Parker::park(bool isAbsolute, jlong time) {5586guarantee(_ParkHandle != NULL, "invariant");5587// First, demultiplex/decode time arguments5588if (time < 0) { // don't wait5589return;5590} else if (time == 0 && !isAbsolute) {5591time = INFINITE;5592} else if (isAbsolute) {5593time -= os::javaTimeMillis(); // convert to relative time5594if (time <= 0) { // already elapsed5595return;5596}5597} else { // relative5598time /= 1000000; // Must coarsen from nanos to millis5599if (time == 0) { // Wait for the minimal time unit if zero5600time = 1;5601}5602}56035604JavaThread* thread = JavaThread::current();56055606// Don't wait if interrupted or already triggered5607if (thread->is_interrupted(false) ||5608WaitForSingleObject(_ParkHandle, 0) == WAIT_OBJECT_0) {5609ResetEvent(_ParkHandle);5610return;5611} else {5612ThreadBlockInVM tbivm(thread);5613OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);56145615WaitForSingleObject(_ParkHandle, time);5616ResetEvent(_ParkHandle);5617}5618}56195620void Parker::unpark() {5621guarantee(_ParkHandle != NULL, "invariant");5622SetEvent(_ParkHandle);5623}56245625// Platform Monitor implementation56265627// Must already be locked5628int os::PlatformMonitor::wait(jlong millis) {5629assert(millis >= 0, "negative timeout");5630int ret = OS_TIMEOUT;5631int status = SleepConditionVariableCS(&_cond, &_mutex,5632millis == 0 ? INFINITE : millis);5633if (status != 0) {5634ret = OS_OK;5635}5636#ifndef PRODUCT5637else {5638DWORD err = GetLastError();5639assert(err == ERROR_TIMEOUT, "SleepConditionVariableCS: %ld:", err);5640}5641#endif5642return ret;5643}56445645// Run the specified command in a separate process. Return its exit value,5646// or -1 on failure (e.g. can't create a new process).5647int os::fork_and_exec(const char* cmd, bool dummy /* ignored */) {5648STARTUPINFO si;5649PROCESS_INFORMATION pi;5650DWORD exit_code;56515652char * cmd_string;5653const char * cmd_prefix = "cmd /C ";5654size_t len = strlen(cmd) + strlen(cmd_prefix) + 1;5655cmd_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtInternal);5656if (cmd_string == NULL) {5657return -1;5658}5659cmd_string[0] = '\0';5660strcat(cmd_string, cmd_prefix);5661strcat(cmd_string, cmd);56625663// now replace all '\n' with '&'5664char * substring = cmd_string;5665while ((substring = strchr(substring, '\n')) != NULL) {5666substring[0] = '&';5667substring++;5668}5669memset(&si, 0, sizeof(si));5670si.cb = sizeof(si);5671memset(&pi, 0, sizeof(pi));5672BOOL rslt = CreateProcess(NULL, // executable name - use command line5673cmd_string, // command line5674NULL, // process security attribute5675NULL, // thread security attribute5676TRUE, // inherits system handles56770, // no creation flags5678NULL, // use parent's environment block5679NULL, // use parent's starting directory5680&si, // (in) startup information5681&pi); // (out) process information56825683if (rslt) {5684// Wait until child process exits.5685WaitForSingleObject(pi.hProcess, INFINITE);56865687GetExitCodeProcess(pi.hProcess, &exit_code);56885689// Close process and thread handles.5690CloseHandle(pi.hProcess);5691CloseHandle(pi.hThread);5692} else {5693exit_code = -1;5694}56955696FREE_C_HEAP_ARRAY(char, cmd_string);5697return (int)exit_code;5698}56995700bool os::find(address addr, outputStream* st) {5701int offset = -1;5702bool result = false;5703char buf[256];5704if (os::dll_address_to_library_name(addr, buf, sizeof(buf), &offset)) {5705st->print(PTR_FORMAT " ", addr);5706if (strlen(buf) < sizeof(buf) - 1) {5707char* p = strrchr(buf, '\\');5708if (p) {5709st->print("%s", p + 1);5710} else {5711st->print("%s", buf);5712}5713} else {5714// The library name is probably truncated. Let's omit the library name.5715// See also JDK-8147512.5716}5717if (os::dll_address_to_function_name(addr, buf, sizeof(buf), &offset)) {5718st->print("::%s + 0x%x", buf, offset);5719}5720st->cr();5721result = true;5722}5723return result;5724}57255726static jint initSock() {5727WSADATA wsadata;57285729if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0) {5730jio_fprintf(stderr, "Could not initialize Winsock (error: %d)\n",5731::GetLastError());5732return JNI_ERR;5733}5734return JNI_OK;5735}57365737struct hostent* os::get_host_by_name(char* name) {5738return (struct hostent*)gethostbyname(name);5739}57405741int os::socket_close(int fd) {5742return ::closesocket(fd);5743}57445745int os::socket(int domain, int type, int protocol) {5746return ::socket(domain, type, protocol);5747}57485749int os::connect(int fd, struct sockaddr* him, socklen_t len) {5750return ::connect(fd, him, len);5751}57525753int os::recv(int fd, char* buf, size_t nBytes, uint flags) {5754return ::recv(fd, buf, (int)nBytes, flags);5755}57565757int os::send(int fd, char* buf, size_t nBytes, uint flags) {5758return ::send(fd, buf, (int)nBytes, flags);5759}57605761int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {5762return ::send(fd, buf, (int)nBytes, flags);5763}57645765// WINDOWS CONTEXT Flags for THREAD_SAMPLING5766#if defined(IA32)5767#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)5768#elif defined(AMD64) || defined(_M_ARM64)5769#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)5770#endif57715772// returns true if thread could be suspended,5773// false otherwise5774static bool do_suspend(HANDLE* h) {5775if (h != NULL) {5776if (SuspendThread(*h) != ~0) {5777return true;5778}5779}5780return false;5781}57825783// resume the thread5784// calling resume on an active thread is a no-op5785static void do_resume(HANDLE* h) {5786if (h != NULL) {5787ResumeThread(*h);5788}5789}57905791// retrieve a suspend/resume context capable handle5792// from the tid. Caller validates handle return value.5793void get_thread_handle_for_extended_context(HANDLE* h,5794OSThread::thread_id_t tid) {5795if (h != NULL) {5796*h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);5797}5798}57995800// Thread sampling implementation5801//5802void os::SuspendedThreadTask::internal_do_task() {5803CONTEXT ctxt;5804HANDLE h = NULL;58055806// get context capable handle for thread5807get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());58085809// sanity5810if (h == NULL || h == INVALID_HANDLE_VALUE) {5811return;5812}58135814// suspend the thread5815if (do_suspend(&h)) {5816ctxt.ContextFlags = sampling_context_flags;5817// get thread context5818GetThreadContext(h, &ctxt);5819SuspendedThreadTaskContext context(_thread, &ctxt);5820// pass context to Thread Sampling impl5821do_task(context);5822// resume thread5823do_resume(&h);5824}58255826// close handle5827CloseHandle(h);5828}58295830bool os::start_debugging(char *buf, int buflen) {5831int len = (int)strlen(buf);5832char *p = &buf[len];58335834jio_snprintf(p, buflen-len,5835"\n\n"5836"Do you want to debug the problem?\n\n"5837"To debug, attach Visual Studio to process %d; then switch to thread 0x%x\n"5838"Select 'Yes' to launch Visual Studio automatically (PATH must include msdev)\n"5839"Otherwise, select 'No' to abort...",5840os::current_process_id(), os::current_thread_id());58415842bool yes = os::message_box("Unexpected Error", buf);58435844if (yes) {5845// os::breakpoint() calls DebugBreak(), which causes a breakpoint5846// exception. If VM is running inside a debugger, the debugger will5847// catch the exception. Otherwise, the breakpoint exception will reach5848// the default windows exception handler, which can spawn a debugger and5849// automatically attach to the dying VM.5850os::breakpoint();5851yes = false;5852}5853return yes;5854}58555856void* os::get_default_process_handle() {5857return (void*)GetModuleHandle(NULL);5858}58595860// Builds a platform dependent Agent_OnLoad_<lib_name> function name5861// which is used to find statically linked in agents.5862// Additionally for windows, takes into account __stdcall names.5863// Parameters:5864// sym_name: Symbol in library we are looking for5865// lib_name: Name of library to look in, NULL for shared libs.5866// is_absolute_path == true if lib_name is absolute path to agent5867// such as "C:/a/b/L.dll"5868// == false if only the base name of the library is passed in5869// such as "L"5870char* os::build_agent_function_name(const char *sym_name, const char *lib_name,5871bool is_absolute_path) {5872char *agent_entry_name;5873size_t len;5874size_t name_len;5875size_t prefix_len = strlen(JNI_LIB_PREFIX);5876size_t suffix_len = strlen(JNI_LIB_SUFFIX);5877const char *start;58785879if (lib_name != NULL) {5880len = name_len = strlen(lib_name);5881if (is_absolute_path) {5882// Need to strip path, prefix and suffix5883if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {5884lib_name = ++start;5885} else {5886// Need to check for drive prefix5887if ((start = strchr(lib_name, ':')) != NULL) {5888lib_name = ++start;5889}5890}5891if (len <= (prefix_len + suffix_len)) {5892return NULL;5893}5894lib_name += prefix_len;5895name_len = strlen(lib_name) - suffix_len;5896}5897}5898len = (lib_name != NULL ? name_len : 0) + strlen(sym_name) + 2;5899agent_entry_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtThread);5900if (agent_entry_name == NULL) {5901return NULL;5902}5903if (lib_name != NULL) {5904const char *p = strrchr(sym_name, '@');5905if (p != NULL && p != sym_name) {5906// sym_name == _Agent_OnLoad@XX5907strncpy(agent_entry_name, sym_name, (p - sym_name));5908agent_entry_name[(p-sym_name)] = '\0';5909// agent_entry_name == _Agent_OnLoad5910strcat(agent_entry_name, "_");5911strncat(agent_entry_name, lib_name, name_len);5912strcat(agent_entry_name, p);5913// agent_entry_name == _Agent_OnLoad_lib_name@XX5914} else {5915strcpy(agent_entry_name, sym_name);5916strcat(agent_entry_name, "_");5917strncat(agent_entry_name, lib_name, name_len);5918}5919} else {5920strcpy(agent_entry_name, sym_name);5921}5922return agent_entry_name;5923}59245925/*5926All the defined signal names for Windows.59275928NOTE that not all of these names are accepted by FindSignal!59295930For various reasons some of these may be rejected at runtime.59315932Here are the names currently accepted by a user of sun.misc.Signal with59331.4.1 (ignoring potential interaction with use of chaining, etc):59345935(LIST TBD)59365937*/5938int os::get_signal_number(const char* name) {5939static const struct {5940const char* name;5941int number;5942} siglabels [] =5943// derived from version 6.0 VC98/include/signal.h5944{"ABRT", SIGABRT, // abnormal termination triggered by abort cl5945"FPE", SIGFPE, // floating point exception5946"SEGV", SIGSEGV, // segment violation5947"INT", SIGINT, // interrupt5948"TERM", SIGTERM, // software term signal from kill5949"BREAK", SIGBREAK, // Ctrl-Break sequence5950"ILL", SIGILL}; // illegal instruction5951for (unsigned i = 0; i < ARRAY_SIZE(siglabels); ++i) {5952if (strcmp(name, siglabels[i].name) == 0) {5953return siglabels[i].number;5954}5955}5956return -1;5957}59585959// Fast current thread access59605961int os::win32::_thread_ptr_offset = 0;59625963static void call_wrapper_dummy() {}59645965// We need to call the os_exception_wrapper once so that it sets5966// up the offset from FS of the thread pointer.5967void os::win32::initialize_thread_ptr_offset() {5968os::os_exception_wrapper((java_call_t)call_wrapper_dummy,5969NULL, methodHandle(), NULL, NULL);5970}59715972bool os::supports_map_sync() {5973return false;5974}59755976#ifdef ASSERT5977static void check_meminfo(MEMORY_BASIC_INFORMATION* minfo) {5978assert(minfo->State == MEM_FREE || minfo->State == MEM_COMMIT || minfo->State == MEM_RESERVE, "Invalid state");5979if (minfo->State != MEM_FREE) {5980assert(minfo->AllocationBase != NULL && minfo->BaseAddress >= minfo->AllocationBase, "Invalid pointers");5981assert(minfo->RegionSize > 0, "Invalid region size");5982}5983}5984#endif598559865987static bool checkedVirtualQuery(address addr, MEMORY_BASIC_INFORMATION* minfo) {5988ZeroMemory(minfo, sizeof(MEMORY_BASIC_INFORMATION));5989if (::VirtualQuery(addr, minfo, sizeof(MEMORY_BASIC_INFORMATION)) == sizeof(MEMORY_BASIC_INFORMATION)) {5990DEBUG_ONLY(check_meminfo(minfo);)5991return true;5992}5993return false;5994}59955996// Given a pointer pointing into an allocation (an area allocated with VirtualAlloc),5997// return information about that allocation.5998bool os::win32::find_mapping(address addr, mapping_info_t* mi) {5999// Query at addr to find allocation base; then, starting at allocation base,6000// query all regions, until we either find the next allocation or a free area.6001ZeroMemory(mi, sizeof(mapping_info_t));6002MEMORY_BASIC_INFORMATION minfo;6003address allocation_base = NULL;6004address allocation_end = NULL;6005bool rc = false;6006if (checkedVirtualQuery(addr, &minfo)) {6007if (minfo.State != MEM_FREE) {6008allocation_base = (address)minfo.AllocationBase;6009allocation_end = allocation_base;6010// Iterate through all regions in this allocation to find its end. While we are here, also count things.6011for (;;) {6012bool rc = checkedVirtualQuery(allocation_end, &minfo);6013if (rc == false || // VirtualQuery error, end of allocation?6014minfo.State == MEM_FREE || // end of allocation, free memory follows6015(address)minfo.AllocationBase != allocation_base) // end of allocation, a new one starts6016{6017break;6018}6019const size_t region_size = minfo.RegionSize;6020mi->regions ++;6021if (minfo.State == MEM_COMMIT) {6022mi->committed_size += minfo.RegionSize;6023}6024allocation_end += region_size;6025}6026if (allocation_base != NULL && allocation_end > allocation_base) {6027mi->base = allocation_base;6028mi->size = allocation_end - allocation_base;6029rc = true;6030}6031}6032}6033#ifdef ASSERT6034if (rc) {6035assert(mi->size > 0 && mi->size >= mi->committed_size, "Sanity");6036assert(addr >= mi->base && addr < mi->base + mi->size, "Sanity");6037assert(mi->regions > 0, "Sanity");6038}6039#endif6040return rc;6041}60426043// Helper for print_one_mapping: print n words, both as hex and ascii.6044// Use Safefetch for all values.6045static void print_snippet(const void* p, outputStream* st) {6046static const int num_words = LP64_ONLY(3) NOT_LP64(6);6047static const int num_bytes = num_words * sizeof(int);6048intptr_t v[num_words];6049const int errval = 0xDE210244;6050for (int i = 0; i < num_words; i++) {6051v[i] = SafeFetchN((intptr_t*)p + i, errval);6052if (v[i] == errval &&6053SafeFetchN((intptr_t*)p + i, ~errval) == ~errval) {6054return;6055}6056}6057st->put('[');6058for (int i = 0; i < num_words; i++) {6059st->print(INTPTR_FORMAT " ", v[i]);6060}6061const char* b = (char*)v;6062st->put('\"');6063for (int i = 0; i < num_bytes; i++) {6064st->put(::isgraph(b[i]) ? b[i] : '.');6065}6066st->put('\"');6067st->put(']');6068}60696070// Helper function for print_memory_mappings:6071// Given a MEMORY_BASIC_INFORMATION, containing information about a non-free region:6072// print out all regions in that allocation. If any of those regions6073// fall outside the given range [start, end), indicate that in the output.6074// Return the pointer to the end of the allocation.6075static address print_one_mapping(MEMORY_BASIC_INFORMATION* minfo, address start, address end, outputStream* st) {6076// Print it like this:6077//6078// Base: <xxxxx>: [xxxx - xxxx], state=MEM_xxx, prot=x, type=MEM_xxx (region 1)6079// [xxxx - xxxx], state=MEM_xxx, prot=x, type=MEM_xxx (region 2)6080assert(minfo->State != MEM_FREE, "Not inside an allocation.");6081address allocation_base = (address)minfo->AllocationBase;6082#define IS_IN(p) (p >= start && p < end)6083bool first_line = true;6084bool is_dll = false;6085for(;;) {6086if (first_line) {6087st->print("Base " PTR_FORMAT ": ", p2i(allocation_base));6088} else {6089st->print_raw(NOT_LP64 (" ")6090LP64_ONLY(" "));6091}6092address region_start = (address)minfo->BaseAddress;6093address region_end = region_start + minfo->RegionSize;6094assert(region_end > region_start, "Sanity");6095if (region_end <= start) {6096st->print("<outside range> ");6097} else if (region_start >= end) {6098st->print("<outside range> ");6099} else if (!IS_IN(region_start) || !IS_IN(region_end - 1)) {6100st->print("<partly outside range> ");6101}6102st->print("[" PTR_FORMAT "-" PTR_FORMAT "), state=", p2i(region_start), p2i(region_end));6103switch (minfo->State) {6104case MEM_COMMIT: st->print_raw("MEM_COMMIT "); break;6105case MEM_FREE: st->print_raw("MEM_FREE "); break;6106case MEM_RESERVE: st->print_raw("MEM_RESERVE"); break;6107default: st->print("%x?", (unsigned)minfo->State);6108}6109st->print(", prot=%3x, type=", (unsigned)minfo->Protect);6110switch (minfo->Type) {6111case MEM_IMAGE: st->print_raw("MEM_IMAGE "); break;6112case MEM_MAPPED: st->print_raw("MEM_MAPPED "); break;6113case MEM_PRIVATE: st->print_raw("MEM_PRIVATE"); break;6114default: st->print("%x?", (unsigned)minfo->State);6115}6116// At the start of every allocation, print some more information about this mapping.6117// Notes:6118// - this could be beefed up a lot, similar to os::print_location6119// - for now we just query the allocation start point. This may be confusing for cases where6120// the kernel merges multiple mappings.6121if (first_line) {6122char buf[MAX_PATH];6123if (os::dll_address_to_library_name(allocation_base, buf, sizeof(buf), nullptr)) {6124st->print(", %s", buf);6125is_dll = true;6126}6127}6128// If memory is accessible, and we do not know anything else about it, print a snippet6129if (!is_dll &&6130minfo->State == MEM_COMMIT &&6131!(minfo->Protect & PAGE_NOACCESS || minfo->Protect & PAGE_GUARD)) {6132st->print_raw(", ");6133print_snippet(region_start, st);6134}6135st->cr();6136// Next region...6137bool rc = checkedVirtualQuery(region_end, minfo);6138if (rc == false || // VirtualQuery error, end of allocation?6139(minfo->State == MEM_FREE) || // end of allocation, free memory follows6140((address)minfo->AllocationBase != allocation_base) || // end of allocation, a new one starts6141(region_end > end)) // end of range to print.6142{6143return region_end;6144}6145first_line = false;6146}6147#undef IS_IN6148ShouldNotReachHere();6149return NULL;6150}61516152void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {6153MEMORY_BASIC_INFORMATION minfo;6154address start = (address)addr;6155address end = start + bytes;6156address p = start;6157if (p == nullptr) { // Lets skip the zero pages.6158p += os::vm_allocation_granularity();6159}6160address p2 = p; // guard against wraparounds6161int fuse = 0;61626163while (p < end && p >= p2) {6164p2 = p;6165// Probe for the next mapping.6166if (checkedVirtualQuery(p, &minfo)) {6167if (minfo.State != MEM_FREE) {6168// Found one. Print it out.6169address p2 = print_one_mapping(&minfo, start, end, st);6170assert(p2 > p, "Sanity");6171p = p2;6172} else {6173// Note: for free regions, most of MEMORY_BASIC_INFORMATION is undefined.6174// Only region dimensions are not: use those to jump to the end of6175// the free range.6176address region_start = (address)minfo.BaseAddress;6177address region_end = region_start + minfo.RegionSize;6178assert(p >= region_start && p < region_end, "Sanity");6179p = region_end;6180}6181} else {6182// MSDN doc on VirtualQuery is unclear about what it means if it returns an error.6183// In particular, whether querying an address outside any mappings would report6184// a MEM_FREE region or just return an error. From experiments, it seems to return6185// a MEM_FREE region for unmapped areas in valid address space and an error if we6186// are outside valid address space.6187// Here, we advance the probe pointer by alloc granularity. But if the range to print6188// is large, this may take a long time. Therefore lets stop right away if the address6189// is outside of what we know are valid addresses on Windows. Also, add a loop fuse.6190static const address end_virt = (address)(LP64_ONLY(0x7ffffffffffULL) NOT_LP64(3*G));6191if (p >= end_virt) {6192break;6193} else {6194// Advance probe pointer, but with a fuse to break long loops.6195if (fuse++ == 100000) {6196break;6197}6198p += os::vm_allocation_granularity();6199}6200}6201}6202}620362046205