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