/hotspot/src/os/windows/vm/os_windows.cpp
C++ | 4760 lines | 3219 code | 644 blank | 897 comment | 805 complexity | bd0a29115bdf310e6738b41a729e50c5 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /*
- * CopyrighT (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
- #ifdef _WIN64
- // Must be at least Windows 2000 or XP to use VectoredExceptions
- #define _WIN32_WINNT 0x500
- #endif
- // no precompiled headers
- #include "classfile/classLoader.hpp"
- #include "classfile/systemDictionary.hpp"
- #include "classfile/vmSymbols.hpp"
- #include "code/icBuffer.hpp"
- #include "code/vtableStubs.hpp"
- #include "compiler/compileBroker.hpp"
- #include "interpreter/interpreter.hpp"
- #include "jvm_windows.h"
- #include "memory/allocation.inline.hpp"
- #include "memory/filemap.hpp"
- #include "mutex_windows.inline.hpp"
- #include "oops/oop.inline.hpp"
- #include "os_share_windows.hpp"
- #include "prims/jniFastGetField.hpp"
- #include "prims/jvm.h"
- #include "prims/jvm_misc.hpp"
- #include "runtime/arguments.hpp"
- #include "runtime/extendedPC.hpp"
- #include "runtime/globals.hpp"
- #include "runtime/interfaceSupport.hpp"
- #include "runtime/java.hpp"
- #include "runtime/javaCalls.hpp"
- #include "runtime/mutexLocker.hpp"
- #include "runtime/objectMonitor.hpp"
- #include "runtime/osThread.hpp"
- #include "runtime/perfMemory.hpp"
- #include "runtime/sharedRuntime.hpp"
- #include "runtime/statSampler.hpp"
- #include "runtime/stubRoutines.hpp"
- #include "runtime/threadCritical.hpp"
- #include "runtime/timer.hpp"
- #include "services/attachListener.hpp"
- #include "services/runtimeService.hpp"
- #include "thread_windows.inline.hpp"
- #include "utilities/decoder.hpp"
- #include "utilities/defaultStream.hpp"
- #include "utilities/events.hpp"
- #include "utilities/growableArray.hpp"
- #include "utilities/vmError.hpp"
- #ifdef TARGET_ARCH_x86
- # include "assembler_x86.inline.hpp"
- # include "nativeInst_x86.hpp"
- #endif
- #ifdef COMPILER1
- #include "c1/c1_Runtime1.hpp"
- #endif
- #ifdef COMPILER2
- #include "opto/runtime.hpp"
- #endif
- #ifdef _DEBUG
- #include <crtdbg.h>
- #endif
- #include <windows.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/timeb.h>
- #include <objidl.h>
- #include <shlobj.h>
- #include <malloc.h>
- #include <signal.h>
- #include <direct.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <io.h>
- #include <process.h> // For _beginthreadex(), _endthreadex()
- #include <imagehlp.h> // For os::dll_address_to_function_name
- /* for enumerating dll libraries */
- #include <tlhelp32.h>
- #include <vdmdbg.h>
- // for timer info max values which include all bits
- #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
- // For DLL loading/load error detection
- // Values of PE COFF
- #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
- #define IMAGE_FILE_SIGNATURE_LENGTH 4
- static HANDLE main_process;
- static HANDLE main_thread;
- static int main_thread_id;
- static FILETIME process_creation_time;
- static FILETIME process_exit_time;
- static FILETIME process_user_time;
- static FILETIME process_kernel_time;
- #ifdef _WIN64
- PVOID topLevelVectoredExceptionHandler = NULL;
- #endif
- #ifdef _M_IA64
- #define __CPU__ ia64
- #elif _M_AMD64
- #define __CPU__ amd64
- #else
- #define __CPU__ i486
- #endif
- // save DLL module handle, used by GetModuleFileName
- HINSTANCE vm_lib_handle;
- static int getLastErrorString(char *buf, size_t len);
- BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
- switch (reason) {
- case DLL_PROCESS_ATTACH:
- vm_lib_handle = hinst;
- if(ForceTimeHighResolution)
- timeBeginPeriod(1L);
- break;
- case DLL_PROCESS_DETACH:
- if(ForceTimeHighResolution)
- timeEndPeriod(1L);
- #ifdef _WIN64
- if (topLevelVectoredExceptionHandler != NULL) {
- RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
- topLevelVectoredExceptionHandler = NULL;
- }
- #endif
- break;
- default:
- break;
- }
- return true;
- }
- static inline double fileTimeAsDouble(FILETIME* time) {
- const double high = (double) ((unsigned int) ~0);
- const double split = 10000000.0;
- double result = (time->dwLowDateTime / split) +
- time->dwHighDateTime * (high/split);
- return result;
- }
- // Implementation of os
- bool os::getenv(const char* name, char* buffer, int len) {
- int result = GetEnvironmentVariable(name, buffer, len);
- return result > 0 && result < len;
- }
- // No setuid programs under Windows.
- bool os::have_special_privileges() {
- return false;
- }
- // This method is a periodic task to check for misbehaving JNI applications
- // under CheckJNI, we can add any periodic checks here.
- // For Windows at the moment does nothing
- void os::run_periodic_checks() {
- return;
- }
- #ifndef _WIN64
- // previous UnhandledExceptionFilter, if there is one
- static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;
- LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);
- #endif
- void os::init_system_properties_values() {
- /* sysclasspath, java_home, dll_dir */
- {
- char *home_path;
- char *dll_path;
- char *pslash;
- char *bin = "\\bin";
- char home_dir[MAX_PATH];
- if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {
- os::jvm_path(home_dir, sizeof(home_dir));
- // Found the full path to jvm[_g].dll.
- // Now cut the path to <java_home>/jre if we can.
- *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */
- pslash = strrchr(home_dir, '\\');
- if (pslash != NULL) {
- *pslash = '\0'; /* get rid of \{client|server} */
- pslash = strrchr(home_dir, '\\');
- if (pslash != NULL)
- *pslash = '\0'; /* get rid of \bin */
- }
- }
- home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1);
- if (home_path == NULL)
- return;
- strcpy(home_path, home_dir);
- Arguments::set_java_home(home_path);
- dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1);
- if (dll_path == NULL)
- return;
- strcpy(dll_path, home_dir);
- strcat(dll_path, bin);
- Arguments::set_dll_dir(dll_path);
- if (!set_boot_path('\\', ';'))
- return;
- }
- /* library_path */
- #define EXT_DIR "\\lib\\ext"
- #define BIN_DIR "\\bin"
- #define PACKAGE_DIR "\\Sun\\Java"
- {
- /* Win32 library search order (See the documentation for LoadLibrary):
- *
- * 1. The directory from which application is loaded.
- * 2. The current directory
- * 3. The system wide Java Extensions directory (Java only)
- * 4. System directory (GetSystemDirectory)
- * 5. Windows directory (GetWindowsDirectory)
- * 6. The PATH environment variable
- */
- char *library_path;
- char tmp[MAX_PATH];
- char *path_str = ::getenv("PATH");
- library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +
- sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10);
- library_path[0] = '\0';
- GetModuleFileName(NULL, tmp, sizeof(tmp));
- *(strrchr(tmp, '\\')) = '\0';
- strcat(library_path, tmp);
- strcat(library_path, ";.");
- GetWindowsDirectory(tmp, sizeof(tmp));
- strcat(library_path, ";");
- strcat(library_path, tmp);
- strcat(library_path, PACKAGE_DIR BIN_DIR);
- GetSystemDirectory(tmp, sizeof(tmp));
- strcat(library_path, ";");
- strcat(library_path, tmp);
- GetWindowsDirectory(tmp, sizeof(tmp));
- strcat(library_path, ";");
- strcat(library_path, tmp);
- if (path_str) {
- strcat(library_path, ";");
- strcat(library_path, path_str);
- }
- Arguments::set_library_path(library_path);
- FREE_C_HEAP_ARRAY(char, library_path);
- }
- /* Default extensions directory */
- {
- char path[MAX_PATH];
- char buf[2 * MAX_PATH + 2 * sizeof(EXT_DIR) + sizeof(PACKAGE_DIR) + 1];
- GetWindowsDirectory(path, MAX_PATH);
- sprintf(buf, "%s%s;%s%s%s", Arguments::get_java_home(), EXT_DIR,
- path, PACKAGE_DIR, EXT_DIR);
- Arguments::set_ext_dirs(buf);
- }
- #undef EXT_DIR
- #undef BIN_DIR
- #undef PACKAGE_DIR
- /* Default endorsed standards directory. */
- {
- #define ENDORSED_DIR "\\lib\\endorsed"
- size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);
- char * buf = NEW_C_HEAP_ARRAY(char, len);
- sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
- Arguments::set_endorsed_dirs(buf);
- #undef ENDORSED_DIR
- }
- #ifndef _WIN64
- // set our UnhandledExceptionFilter and save any previous one
- prev_uef_handler = SetUnhandledExceptionFilter(Handle_FLT_Exception);
- #endif
- // Done
- return;
- }
- void os::breakpoint() {
- DebugBreak();
- }
- // Invoked from the BREAKPOINT Macro
- extern "C" void breakpoint() {
- os::breakpoint();
- }
- // Returns an estimate of the current stack pointer. Result must be guaranteed
- // to point into the calling threads stack, and be no lower than the current
- // stack pointer.
- address os::current_stack_pointer() {
- int dummy;
- address sp = (address)&dummy;
- return sp;
- }
- // os::current_stack_base()
- //
- // Returns the base of the stack, which is the stack's
- // starting address. This function must be called
- // while running on the stack of the thread being queried.
- address os::current_stack_base() {
- MEMORY_BASIC_INFORMATION minfo;
- address stack_bottom;
- size_t stack_size;
- VirtualQuery(&minfo, &minfo, sizeof(minfo));
- stack_bottom = (address)minfo.AllocationBase;
- stack_size = minfo.RegionSize;
- // Add up the sizes of all the regions with the same
- // AllocationBase.
- while( 1 )
- {
- VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));
- if ( stack_bottom == (address)minfo.AllocationBase )
- stack_size += minfo.RegionSize;
- else
- break;
- }
- #ifdef _M_IA64
- // IA64 has memory and register stacks
- stack_size = stack_size / 2;
- #endif
- return stack_bottom + stack_size;
- }
- size_t os::current_stack_size() {
- size_t sz;
- MEMORY_BASIC_INFORMATION minfo;
- VirtualQuery(&minfo, &minfo, sizeof(minfo));
- sz = (size_t)os::current_stack_base() - (size_t)minfo.AllocationBase;
- return sz;
- }
- struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
- const struct tm* time_struct_ptr = localtime(clock);
- if (time_struct_ptr != NULL) {
- *res = *time_struct_ptr;
- return res;
- }
- return NULL;
- }
- LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
- // Thread start routine for all new Java threads
- static unsigned __stdcall java_start(Thread* thread) {
- // Try to randomize the cache line index of hot stack frames.
- // This helps when threads of the same stack traces evict each other's
- // cache lines. The threads can be either from the same JVM instance, or
- // from different JVM instances. The benefit is especially true for
- // processors with hyperthreading technology.
- static int counter = 0;
- int pid = os::current_process_id();
- _alloca(((pid ^ counter++) & 7) * 128);
- OSThread* osthr = thread->osthread();
- assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
- if (UseNUMA) {
- int lgrp_id = os::numa_get_group_id();
- if (lgrp_id != -1) {
- thread->set_lgrp_id(lgrp_id);
- }
- }
- if (UseVectoredExceptions) {
- // If we are using vectored exception we don't need to set a SEH
- thread->run();
- }
- else {
- // Install a win32 structured exception handler around every thread created
- // by VM, so VM can genrate error dump when an exception occurred in non-
- // Java thread (e.g. VM thread).
- __try {
- thread->run();
- } __except(topLevelExceptionFilter(
- (_EXCEPTION_POINTERS*)_exception_info())) {
- // Nothing to do.
- }
- }
- // One less thread is executing
- // When the VMThread gets here, the main thread may have already exited
- // which frees the CodeHeap containing the Atomic::add code
- if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
- Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
- }
- return 0;
- }
- static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle, int thread_id) {
- // Allocate the OSThread object
- OSThread* osthread = new OSThread(NULL, NULL);
- if (osthread == NULL) return NULL;
- // Initialize support for Java interrupts
- HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
- if (interrupt_event == NULL) {
- delete osthread;
- return NULL;
- }
- osthread->set_interrupt_event(interrupt_event);
- // Store info on the Win32 thread into the OSThread
- osthread->set_thread_handle(thread_handle);
- osthread->set_thread_id(thread_id);
- if (UseNUMA) {
- int lgrp_id = os::numa_get_group_id();
- if (lgrp_id != -1) {
- thread->set_lgrp_id(lgrp_id);
- }
- }
- // Initial thread state is INITIALIZED, not SUSPENDED
- osthread->set_state(INITIALIZED);
- return osthread;
- }
- bool os::create_attached_thread(JavaThread* thread) {
- #ifdef ASSERT
- thread->verify_not_published();
- #endif
- HANDLE thread_h;
- if (!DuplicateHandle(main_process, GetCurrentThread(), GetCurrentProcess(),
- &thread_h, THREAD_ALL_ACCESS, false, 0)) {
- fatal("DuplicateHandle failed\n");
- }
- OSThread* osthread = create_os_thread(thread, thread_h,
- (int)current_thread_id());
- if (osthread == NULL) {
- return false;
- }
- // Initial thread state is RUNNABLE
- osthread->set_state(RUNNABLE);
- thread->set_osthread(osthread);
- return true;
- }
- bool os::create_main_thread(JavaThread* thread) {
- #ifdef ASSERT
- thread->verify_not_published();
- #endif
- if (_starting_thread == NULL) {
- _starting_thread = create_os_thread(thread, main_thread, main_thread_id);
- if (_starting_thread == NULL) {
- return false;
- }
- }
- // The primordial thread is runnable from the start)
- _starting_thread->set_state(RUNNABLE);
- thread->set_osthread(_starting_thread);
- return true;
- }
- // Allocate and initialize a new OSThread
- bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
- unsigned thread_id;
- // Allocate the OSThread object
- OSThread* osthread = new OSThread(NULL, NULL);
- if (osthread == NULL) {
- return false;
- }
- // Initialize support for Java interrupts
- HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL);
- if (interrupt_event == NULL) {
- delete osthread;
- return NULL;
- }
- osthread->set_interrupt_event(interrupt_event);
- osthread->set_interrupted(false);
- thread->set_osthread(osthread);
- if (stack_size == 0) {
- switch (thr_type) {
- case os::java_thread:
- // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
- if (JavaThread::stack_size_at_create() > 0)
- stack_size = JavaThread::stack_size_at_create();
- break;
- case os::compiler_thread:
- if (CompilerThreadStackSize > 0) {
- stack_size = (size_t)(CompilerThreadStackSize * K);
- break;
- } // else fall through:
- // use VMThreadStackSize if CompilerThreadStackSize is not defined
- case os::vm_thread:
- case os::pgc_thread:
- case os::cgc_thread:
- case os::watcher_thread:
- if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
- break;
- }
- }
- // Create the Win32 thread
- //
- // Contrary to what MSDN document says, "stack_size" in _beginthreadex()
- // does not specify stack size. Instead, it specifies the size of
- // initially committed space. The stack size is determined by
- // PE header in the executable. If the committed "stack_size" is larger
- // than default value in the PE header, the stack is rounded up to the
- // nearest multiple of 1MB. For example if the launcher has default
- // stack size of 320k, specifying any size less than 320k does not
- // affect the actual stack size at all, it only affects the initial
- // commitment. On the other hand, specifying 'stack_size' larger than
- // default value may cause significant increase in memory usage, because
- // not only the stack space will be rounded up to MB, but also the
- // entire space is committed upfront.
- //
- // Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'
- // for CreateThread() that can treat 'stack_size' as stack size. However we
- // are not supposed to call CreateThread() directly according to MSDN
- // document because JVM uses C runtime library. The good news is that the
- // flag appears to work with _beginthredex() as well.
- #ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
- #define STACK_SIZE_PARAM_IS_A_RESERVATION (0x10000)
- #endif
- HANDLE thread_handle =
- (HANDLE)_beginthreadex(NULL,
- (unsigned)stack_size,
- (unsigned (__stdcall *)(void*)) java_start,
- thread,
- CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
- &thread_id);
- if (thread_handle == NULL) {
- // perhaps STACK_SIZE_PARAM_IS_A_RESERVATION is not supported, try again
- // without the flag.
- thread_handle =
- (HANDLE)_beginthreadex(NULL,
- (unsigned)stack_size,
- (unsigned (__stdcall *)(void*)) java_start,
- thread,
- CREATE_SUSPENDED,
- &thread_id);
- }
- if (thread_handle == NULL) {
- // Need to clean up stuff we've allocated so far
- CloseHandle(osthread->interrupt_event());
- thread->set_osthread(NULL);
- delete osthread;
- return NULL;
- }
- Atomic::inc_ptr((intptr_t*)&os::win32::_os_thread_count);
- // Store info on the Win32 thread into the OSThread
- osthread->set_thread_handle(thread_handle);
- osthread->set_thread_id(thread_id);
- // Initial thread state is INITIALIZED, not SUSPENDED
- osthread->set_state(INITIALIZED);
- // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
- return true;
- }
- // Free Win32 resources related to the OSThread
- void os::free_thread(OSThread* osthread) {
- assert(osthread != NULL, "osthread not set");
- CloseHandle(osthread->thread_handle());
- CloseHandle(osthread->interrupt_event());
- delete osthread;
- }
- static int has_performance_count = 0;
- static jlong first_filetime;
- static jlong initial_performance_count;
- static jlong performance_frequency;
- jlong as_long(LARGE_INTEGER x) {
- jlong result = 0; // initialization to avoid warning
- set_high(&result, x.HighPart);
- set_low(&result, x.LowPart);
- return result;
- }
- jlong os::elapsed_counter() {
- LARGE_INTEGER count;
- if (has_performance_count) {
- QueryPerformanceCounter(&count);
- return as_long(count) - initial_performance_count;
- } else {
- FILETIME wt;
- GetSystemTimeAsFileTime(&wt);
- return (jlong_from(wt.dwHighDateTime, wt.dwLowDateTime) - first_filetime);
- }
- }
- jlong os::elapsed_frequency() {
- if (has_performance_count) {
- return performance_frequency;
- } else {
- // the FILETIME time is the number of 100-nanosecond intervals since January 1,1601.
- return 10000000;
- }
- }
- julong os::available_memory() {
- return win32::available_memory();
- }
- julong os::win32::available_memory() {
- // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
- // value if total memory is larger than 4GB
- MEMORYSTATUSEX ms;
- ms.dwLength = sizeof(ms);
- GlobalMemoryStatusEx(&ms);
- return (julong)ms.ullAvailPhys;
- }
- julong os::physical_memory() {
- return win32::physical_memory();
- }
- julong os::allocatable_physical_memory(julong size) {
- #ifdef _LP64
- return size;
- #else
- // Limit to 1400m because of the 2gb address space wall
- return MIN2(size, (julong)1400*M);
- #endif
- }
- // VC6 lacks DWORD_PTR
- #if _MSC_VER < 1300
- typedef UINT_PTR DWORD_PTR;
- #endif
- int os::active_processor_count() {
- DWORD_PTR lpProcessAffinityMask = 0;
- DWORD_PTR lpSystemAffinityMask = 0;
- int proc_count = processor_count();
- if (proc_count <= sizeof(UINT_PTR) * BitsPerByte &&
- GetProcessAffinityMask(GetCurrentProcess(), &lpProcessAffinityMask, &lpSystemAffinityMask)) {
- // Nof active processors is number of bits in process affinity mask
- int bitcount = 0;
- while (lpProcessAffinityMask != 0) {
- lpProcessAffinityMask = lpProcessAffinityMask & (lpProcessAffinityMask-1);
- bitcount++;
- }
- return bitcount;
- } else {
- return proc_count;
- }
- }
- bool os::distribute_processes(uint length, uint* distribution) {
- // Not yet implemented.
- return false;
- }
- bool os::bind_to_processor(uint processor_id) {
- // Not yet implemented.
- return false;
- }
- static void initialize_performance_counter() {
- LARGE_INTEGER count;
- if (QueryPerformanceFrequency(&count)) {
- has_performance_count = 1;
- performance_frequency = as_long(count);
- QueryPerformanceCounter(&count);
- initial_performance_count = as_long(count);
- } else {
- has_performance_count = 0;
- FILETIME wt;
- GetSystemTimeAsFileTime(&wt);
- first_filetime = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
- }
- }
- double os::elapsedTime() {
- return (double) elapsed_counter() / (double) elapsed_frequency();
- }
- // Windows format:
- // The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.
- // Java format:
- // Java standards require the number of milliseconds since 1/1/1970
- // Constant offset - calculated using offset()
- static jlong _offset = 116444736000000000;
- // Fake time counter for reproducible results when debugging
- static jlong fake_time = 0;
- #ifdef ASSERT
- // Just to be safe, recalculate the offset in debug mode
- static jlong _calculated_offset = 0;
- static int _has_calculated_offset = 0;
- jlong offset() {
- if (_has_calculated_offset) return _calculated_offset;
- SYSTEMTIME java_origin;
- java_origin.wYear = 1970;
- java_origin.wMonth = 1;
- java_origin.wDayOfWeek = 0; // ignored
- java_origin.wDay = 1;
- java_origin.wHour = 0;
- java_origin.wMinute = 0;
- java_origin.wSecond = 0;
- java_origin.wMilliseconds = 0;
- FILETIME jot;
- if (!SystemTimeToFileTime(&java_origin, &jot)) {
- fatal(err_msg("Error = %d\nWindows error", GetLastError()));
- }
- _calculated_offset = jlong_from(jot.dwHighDateTime, jot.dwLowDateTime);
- _has_calculated_offset = 1;
- assert(_calculated_offset == _offset, "Calculated and constant time offsets must be equal");
- return _calculated_offset;
- }
- #else
- jlong offset() {
- return _offset;
- }
- #endif
- jlong windows_to_java_time(FILETIME wt) {
- jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime);
- return (a - offset()) / 10000;
- }
- FILETIME java_to_windows_time(jlong l) {
- jlong a = (l * 10000) + offset();
- FILETIME result;
- result.dwHighDateTime = high(a);
- result.dwLowDateTime = low(a);
- return result;
- }
- // For now, we say that Windows does not support vtime. I have no idea
- // whether it can actually be made to (DLD, 9/13/05).
- bool os::supports_vtime() { return false; }
- bool os::enable_vtime() { return false; }
- bool os::vtime_enabled() { return false; }
- double os::elapsedVTime() {
- // better than nothing, but not much
- return elapsedTime();
- }
- jlong os::javaTimeMillis() {
- if (UseFakeTimers) {
- return fake_time++;
- } else {
- FILETIME wt;
- GetSystemTimeAsFileTime(&wt);
- return windows_to_java_time(wt);
- }
- }
- #define NANOS_PER_SEC CONST64(1000000000)
- #define NANOS_PER_MILLISEC 1000000
- jlong os::javaTimeNanos() {
- if (!has_performance_count) {
- return javaTimeMillis() * NANOS_PER_MILLISEC; // the best we can do.
- } else {
- LARGE_INTEGER current_count;
- QueryPerformanceCounter(¤t_count);
- double current = as_long(current_count);
- double freq = performance_frequency;
- jlong time = (jlong)((current/freq) * NANOS_PER_SEC);
- return time;
- }
- }
- void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
- if (!has_performance_count) {
- // javaTimeMillis() doesn't have much percision,
- // but it is not going to wrap -- so all 64 bits
- info_ptr->max_value = ALL_64_BITS;
- // this is a wall clock timer, so may skip
- info_ptr->may_skip_backward = true;
- info_ptr->may_skip_forward = true;
- } else {
- jlong freq = performance_frequency;
- if (freq < NANOS_PER_SEC) {
- // the performance counter is 64 bits and we will
- // be multiplying it -- so no wrap in 64 bits
- info_ptr->max_value = ALL_64_BITS;
- } else if (freq > NANOS_PER_SEC) {
- // use the max value the counter can reach to
- // determine the max value which could be returned
- julong max_counter = (julong)ALL_64_BITS;
- info_ptr->max_value = (jlong)(max_counter / (freq / NANOS_PER_SEC));
- } else {
- // the performance counter is 64 bits and we will
- // be using it directly -- so no wrap in 64 bits
- info_ptr->max_value = ALL_64_BITS;
- }
- // using a counter, so no skipping
- info_ptr->may_skip_backward = false;
- info_ptr->may_skip_forward = false;
- }
- info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
- }
- char* os::local_time_string(char *buf, size_t buflen) {
- SYSTEMTIME st;
- GetLocalTime(&st);
- jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
- st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
- return buf;
- }
- bool os::getTimesSecs(double* process_real_time,
- double* process_user_time,
- double* process_system_time) {
- HANDLE h_process = GetCurrentProcess();
- FILETIME create_time, exit_time, kernel_time, user_time;
- BOOL result = GetProcessTimes(h_process,
- &create_time,
- &exit_time,
- &kernel_time,
- &user_time);
- if (result != 0) {
- FILETIME wt;
- GetSystemTimeAsFileTime(&wt);
- jlong rtc_millis = windows_to_java_time(wt);
- jlong user_millis = windows_to_java_time(user_time);
- jlong system_millis = windows_to_java_time(kernel_time);
- *process_real_time = ((double) rtc_millis) / ((double) MILLIUNITS);
- *process_user_time = ((double) user_millis) / ((double) MILLIUNITS);
- *process_system_time = ((double) system_millis) / ((double) MILLIUNITS);
- return true;
- } else {
- return false;
- }
- }
- void os::shutdown() {
- // allow PerfMemory to attempt cleanup of any persistent resources
- perfMemory_exit();
- // flush buffered output, finish log files
- ostream_abort();
- // Check for abort hook
- abort_hook_t abort_hook = Arguments::abort_hook();
- if (abort_hook != NULL) {
- abort_hook();
- }
- }
- void os::abort(bool dump_core)
- {
- os::shutdown();
- // no core dump on Windows
- ::exit(1);
- }
- // Die immediately, no exit hook, no abort hook, no cleanup.
- void os::die() {
- _exit(-1);
- }
- // Directory routines copied from src/win32/native/java/io/dirent_md.c
- // * dirent_md.c 1.15 00/02/02
- //
- // The declarations for DIR and struct dirent are in jvm_win32.h.
- /* Caller must have already run dirname through JVM_NativePath, which removes
- duplicate slashes and converts all instances of '/' into '\\'. */
- DIR *
- os::opendir(const char *dirname)
- {
- assert(dirname != NULL, "just checking"); // hotspot change
- DIR *dirp = (DIR *)malloc(sizeof(DIR));
- DWORD fattr; // hotspot change
- char alt_dirname[4] = { 0, 0, 0, 0 };
- if (dirp == 0) {
- errno = ENOMEM;
- return 0;
- }
- /*
- * Win32 accepts "\" in its POSIX stat(), but refuses to treat it
- * as a directory in FindFirstFile(). We detect this case here and
- * prepend the current drive name.
- */
- if (dirname[1] == '\0' && dirname[0] == '\\') {
- alt_dirname[0] = _getdrive() + 'A' - 1;
- alt_dirname[1] = ':';
- alt_dirname[2] = '\\';
- alt_dirname[3] = '\0';
- dirname = alt_dirname;
- }
- dirp->path = (char *)malloc(strlen(dirname) + 5);
- if (dirp->path == 0) {
- free(dirp);
- errno = ENOMEM;
- return 0;
- }
- strcpy(dirp->path, dirname);
- fattr = GetFileAttributes(dirp->path);
- if (fattr == 0xffffffff) {
- free(dirp->path);
- free(dirp);
- errno = ENOENT;
- return 0;
- } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- free(dirp->path);
- free(dirp);
- errno = ENOTDIR;
- return 0;
- }
- /* Append "*.*", or possibly "\\*.*", to path */
- if (dirp->path[1] == ':'
- && (dirp->path[2] == '\0'
- || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) {
- /* No '\\' needed for cases like "Z:" or "Z:\" */
- strcat(dirp->path, "*.*");
- } else {
- strcat(dirp->path, "\\*.*");
- }
- dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
- if (dirp->handle == INVALID_HANDLE_VALUE) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- free(dirp->path);
- free(dirp);
- errno = EACCES;
- return 0;
- }
- }
- return dirp;
- }
- /* parameter dbuf unused on Windows */
- struct dirent *
- os::readdir(DIR *dirp, dirent *dbuf)
- {
- assert(dirp != NULL, "just checking"); // hotspot change
- if (dirp->handle == INVALID_HANDLE_VALUE) {
- return 0;
- }
- strcpy(dirp->dirent.d_name, dirp->find_data.cFileName);
- if (!FindNextFile(dirp->handle, &dirp->find_data)) {
- if (GetLastError() == ERROR_INVALID_HANDLE) {
- errno = EBADF;
- return 0;
- }
- FindClose(dirp->handle);
- dirp->handle = INVALID_HANDLE_VALUE;
- }
- return &dirp->dirent;
- }
- int
- os::closedir(DIR *dirp)
- {
- assert(dirp != NULL, "just checking"); // hotspot change
- if (dirp->handle != INVALID_HANDLE_VALUE) {
- if (!FindClose(dirp->handle)) {
- errno = EBADF;
- return -1;
- }
- dirp->handle = INVALID_HANDLE_VALUE;
- }
- free(dirp->path);
- free(dirp);
- return 0;
- }
- // This must be hard coded because it's the system's temporary
- // directory not the java application's temp directory, ala java.io.tmpdir.
- const char* os::get_temp_directory() {
- static char path_buf[MAX_PATH];
- if (GetTempPath(MAX_PATH, path_buf)>0)
- return path_buf;
- else{
- path_buf[0]='\0';
- return path_buf;
- }
- }
- static bool file_exists(const char* filename) {
- if (filename == NULL || strlen(filename) == 0) {
- return false;
- }
- return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
- }
- void os::dll_build_name(char *buffer, size_t buflen,
- const char* pname, const char* fname) {
- const size_t pnamelen = pname ? strlen(pname) : 0;
- const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
- // Quietly truncates on buffer overflow. Should be an error.
- if (pnamelen + strlen(fname) + 10 > buflen) {
- *buffer = '\0';
- return;
- }
- if (pnamelen == 0) {
- jio_snprintf(buffer, buflen, "%s.dll", fname);
- } else if (c == ':' || c == '\\') {
- jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);
- } else if (strchr(pname, *os::path_separator()) != NULL) {
- int n;
- char** pelements = split_path(pname, &n);
- for (int i = 0 ; i < n ; i++) {
- char* path = pelements[i];
- // Really shouldn't be NULL, but check can't hurt
- size_t plen = (path == NULL) ? 0 : strlen(path);
- if (plen == 0) {
- continue; // skip the empty path values
- }
- const char lastchar = path[plen - 1];
- if (lastchar == ':' || lastchar == '\\') {
- jio_snprintf(buffer, buflen, "%s%s.dll", path, fname);
- } else {
- jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
- }
- if (file_exists(buffer)) {
- break;
- }
- }
- // release the storage
- for (int i = 0 ; i < n ; i++) {
- if (pelements[i] != NULL) {
- FREE_C_HEAP_ARRAY(char, pelements[i]);
- }
- }
- if (pelements != NULL) {
- FREE_C_HEAP_ARRAY(char*, pelements);
- }
- } else {
- jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
- }
- }
- // Needs to be in os specific directory because windows requires another
- // header file <direct.h>
- const char* os::get_current_directory(char *buf, int buflen) {
- return _getcwd(buf, buflen);
- }
- //-----------------------------------------------------------
- // Helper functions for fatal error handler
- // The following library functions are resolved dynamically at runtime:
- // PSAPI functions, for Windows NT, 2000, XP
- // psapi.h doesn't come with Visual Studio 6; it can be downloaded as Platform
- // SDK from Microsoft. Here are the definitions copied from psapi.h
- typedef struct _MODULEINFO {
- LPVOID lpBaseOfDll;
- DWORD SizeOfImage;
- LPVOID EntryPoint;
- } MODULEINFO, *LPMODULEINFO;
- static BOOL (WINAPI *_EnumProcessModules) ( HANDLE, HMODULE *, DWORD, LPDWORD );
- static DWORD (WINAPI *_GetModuleFileNameEx) ( HANDLE, HMODULE, LPTSTR, DWORD );
- static BOOL (WINAPI *_GetModuleInformation)( HANDLE, HMODULE, LPMODULEINFO, DWORD );
- // ToolHelp Functions, for Windows 95, 98 and ME
- static HANDLE(WINAPI *_CreateToolhelp32Snapshot)(DWORD,DWORD) ;
- static BOOL (WINAPI *_Module32First) (HANDLE,LPMODULEENTRY32) ;
- static BOOL (WINAPI *_Module32Next) (HANDLE,LPMODULEENTRY32) ;
- bool _has_psapi;
- bool _psapi_init = false;
- bool _has_toolhelp;
- static bool _init_psapi() {
- HINSTANCE psapi = LoadLibrary( "PSAPI.DLL" ) ;
- if( psapi == NULL ) return false ;
- _EnumProcessModules = CAST_TO_FN_PTR(
- BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD),
- GetProcAddress(psapi, "EnumProcessModules")) ;
- _GetModuleFileNameEx = CAST_TO_FN_PTR(
- DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD),
- GetProcAddress(psapi, "GetModuleFileNameExA"));
- _GetModuleInformation = CAST_TO_FN_PTR(
- BOOL (WINAPI *)(HANDLE, HMODULE, LPMODULEINFO, DWORD),
- GetProcAddress(psapi, "GetModuleInformation"));
- _has_psapi = (_EnumProcessModules && _GetModuleFileNameEx && _GetModuleInformation);
- _psapi_init = true;
- return _has_psapi;
- }
- static bool _init_toolhelp() {
- HINSTANCE kernel32 = LoadLibrary("Kernel32.DLL") ;
- if (kernel32 == NULL) return false ;
- _CreateToolhelp32Snapshot = CAST_TO_FN_PTR(
- HANDLE(WINAPI *)(DWORD,DWORD),
- GetProcAddress(kernel32, "CreateToolhelp32Snapshot"));
- _Module32First = CAST_TO_FN_PTR(
- BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32),
- GetProcAddress(kernel32, "Module32First" ));
- _Module32Next = CAST_TO_FN_PTR(
- BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32),
- GetProcAddress(kernel32, "Module32Next" ));
- _has_toolhelp = (_CreateToolhelp32Snapshot && _Module32First && _Module32Next);
- return _has_toolhelp;
- }
- #ifdef _WIN64
- // Helper routine which returns true if address in
- // within the NTDLL address space.
- //
- static bool _addr_in_ntdll( address addr )
- {
- HMODULE hmod;
- MODULEINFO minfo;
- hmod = GetModuleHandle("NTDLL.DLL");
- if ( hmod == NULL ) return false;
- if ( !_GetModuleInformation( GetCurrentProcess(), hmod,
- &minfo, sizeof(MODULEINFO)) )
- return false;
- if ( (addr >= minfo.lpBaseOfDll) &&
- (addr < (address)((uintptr_t)minfo.lpBaseOfDll + (uintptr_t)minfo.SizeOfImage)))
- return true;
- else
- return false;
- }
- #endif
- // Enumerate all modules for a given process ID
- //
- // Notice that Windows 95/98/Me and Windows NT/2000/XP have
- // different API for doing this. We use PSAPI.DLL on NT based
- // Windows and ToolHelp on 95/98/Me.
- // Callback function that is called by enumerate_modules() on
- // every DLL module.
- // Input parameters:
- // int pid,
- // char* module_file_name,
- // address module_base_addr,
- // unsigned module_size,
- // void* param
- typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *);
- // enumerate_modules for Windows NT, using PSAPI
- static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param)
- {
- HANDLE hProcess ;
- # define MAX_NUM_MODULES 128
- HMODULE modules[MAX_NUM_MODULES];
- static char filename[ MAX_PATH ];
- int result = 0;
- if (!_has_psapi && (_psapi_init || !_init_psapi())) return 0;
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, pid ) ;
- if (hProcess == NULL) return 0;
- DWORD size_needed;
- if (!_EnumProcessModules(hProcess, modules,
- sizeof(modules), &size_needed)) {
- CloseHandle( hProcess );
- return 0;
- }
- // number of modules that are currently loaded
- int num_modules = size_needed / sizeof(HMODULE);
- for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {
- // Get Full pathname:
- if(!_GetModuleFileNameEx(hProcess, modules[i],
- filename, sizeof(filename))) {
- filename[0] = '\0';
- }
- MODULEINFO modinfo;
- if (!_GetModuleInformation(hProcess, modules[i],
- &modinfo, sizeof(modinfo))) {
- modinfo.lpBaseOfDll = NULL;
- modinfo.SizeOfImage = 0;
- }
- // Invoke callback function
- result = func(pid, filename, (address)modinfo.lpBaseOfDll,
- modinfo.SizeOfImage, param);
- if (result) break;
- }
- CloseHandle( hProcess ) ;
- return result;
- }
- // enumerate_modules for Windows 95/98/ME, using TOOLHELP
- static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param)
- {
- HANDLE hSnapShot ;
- static MODULEENTRY32 modentry ;
- int result = 0;
- if (!_has_toolhelp) return 0;
- // Get a handle to a Toolhelp snapshot of the system
- hSnapShot = _CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid ) ;
- if( hSnapShot == INVALID_HANDLE_VALUE ) {
- return FALSE ;
- }
- // iterate through all modules
- modentry.dwSize = sizeof(MODULEENTRY32) ;
- bool not_done = _Module32First( hSnapShot, &modentry ) != 0;
- while( not_done ) {
- // invoke the callback
- result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr,
- modentry.modBaseSize, param);
- if (result) break;
- modentry.dwSize = sizeof(MODULEENTRY32) ;
- not_done = _Module32Next( hSnapShot, &modentry ) != 0;
- }
- CloseHandle(hSnapShot);
- return result;
- }
- int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param )
- {
- // Get current process ID if caller doesn't provide it.
- if (!pid) pid = os::current_process_id();
- if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param);
- else return _enumerate_modules_windows(pid, func, param);
- }
- struct _modinfo {
- address addr;
- char* full_path; // point to a char buffer
- int buflen; // size of the buffer
- address base_addr;
- };
- static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr,
- unsigned size, void * param) {
- struct _modinfo *pmod = (struct _modinfo *)param;
- if (!pmod) return -1;
- if (base_addr <= pmod->addr &&
- base_addr+size > pmod->addr) {
- // if a buffer is provided, copy path name to the buffer
- if (pmod->full_path) {
- jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname);
- }
- pmod->base_addr = base_addr;
- return 1;
- }
- return 0;
- }
- bool os::dll_address_to_library_name(address addr, char* buf,
- int buflen, int* offset) {
- // NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always
- // return the full path to the DLL file, sometimes it returns path
- // to the corresponding PDB file (debug info); sometimes it only
- // returns partial path, which makes life painful.
- struct _modinfo mi;
- mi.addr = addr;
- mi.full_path = buf;
- mi.buflen = buflen;
- int pid = os::current_process_id();
- if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {
- // buf already contains path name
- if (offset) *offset = addr - mi.base_addr;
- return true;
- } else {
- if (buf) buf[0] = '\0';
- if (offset) *offset = -1;
- return false;
- }
- }
- bool os::dll_address_to_function_name(address addr, char *buf,
- int buflen, int *offset) {
- if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
- return true;
- }
- if (offset != NULL) *offset = -1;
- if (buf != NULL) buf[0] = '\0';
- return false;
- }
- // save the start and end address of jvm.dll into param[0] and param[1]
- static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,
- unsigned size, void * param) {
- if (!param) return -1;
- if (base_addr <= (address)_locate_jvm_dll &&
- base_addr+size > (address)_locate_jvm_dll) {
- ((address*)param)[0] = base_addr;
- ((address*)param)[1] = base_addr + size;
- return 1;
- }
- return 0;
- }
- address vm_lib_location[2]; // start and end address of jvm.dll
- // check if addr is inside jvm.dll
- bool os::address_is_in_vm(address addr) {
- if (!vm_lib_location[0] || !vm_lib_location[1]) {
- int pid = os::current_process_id();
- if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) {
- assert(false, "Can't find jvm module.");
- return false;
- }
- }
- return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]);
- }
- // print module info; param is outputStream*
- static int _print_module(int pid, char* fname, address base,
- unsigned size, void* param) {
- if (!param) return -1;
- outputStream* st = (outputStream*)param;
- address end_addr = base + size;
- st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname);
- return 0;
- }
- // Loads .dll/.so and
- // in case of error it checks if .dll/.so was built for the
- // same architecture as Hotspot is running on
- void * os::dll_load(const char *name, char *ebuf, int ebuflen)
- {
- void * result = LoadLibrary(name);
- if (result != NULL)
- {
- return result;
- }
- long errcode = GetLastError();
- if (errcode == ERROR_MOD_NOT_FOUND) {
- strncpy(ebuf, "Can't find dependent libraries", ebuflen-1);
- ebuf[ebuflen-1]='\0';
- return NULL;
- }
- // Parsing dll below
- // If we can read dll-info and find that dll was built
- // for an architecture other than Hotspot is running in
- // - then print to buffer "DLL was built for a different architecture"
- // else call getLastErrorString to obtain system error message
- // Read system error message into ebuf
- // It may or may not be overwritten below (in the for loop and just above)
- getLastErrorString(ebuf, (size_t) ebuflen);
- ebuf[ebuflen-1]='\0';
- int file_descriptor=::open(name, O_RDONLY | O_BINARY, 0);
- if (file_descriptor<0)
- {
- return NULL;
- }
- uint32_t signature_offset;
- uint16_t lib_arch=0;
- bool failed_to_get_lib_arch=
- (
- //Go to position 3c in the dll
- (os::seek_to_file_offset(file_descriptor,IMAGE_FILE_PTR_TO_SIGNATURE)<0)
- ||
- // Read loacation of signature
- (sizeof(signature_offset)!=
- (os::read(file_descriptor, (void*)&signature_offset,sizeof(signature_offset))))
- ||
- //Go to COFF File Header in dll
- //that is located after"signature" (4 bytes long)
- (os::seek_to_file_offset(file_descriptor,
- signature_offset+IMAGE_FILE_SIGNATURE_LENGTH)<0)
- ||
- //Read field that contains code of architecture
- // that dll was build for
- (sizeof(lib_arch)!=
- (os::read(file_descriptor, (void*)&lib_arch,sizeof(lib_arch))))
- );
- ::close(file_descriptor);
- if (failed_to_get_lib_arch)
- {
- // file i/o error - report getLastErrorString(...) msg
- return NULL;
- }
- typedef struct
- {
- uint16_t arch_code;
- char* arch_name;
- } arch_t;
- static const arch_t arch_array[]={
- {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"},
- {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"},
- {IMAGE_FILE_MACHINE_IA64, (char*)"IA 64"}
- };
- #if (defined _M_IA64)
- static const uint16_t running_arch=IMAGE_FILE_MACHINE_IA64;
- #elif (defined _M_AMD64)
- static const uint16_t running_arch=IMAGE_FILE_MACHINE_AMD64;
- #elif (defined _M_IX86)
- static const uint16_t running_arch=IMAGE_FILE_MACHINE_I386;
- #else
- #error Method os::dll_load requires that one of following \
- is defined :_M_IA64,_M_AMD64 or _M_IX86
- #endif
- // Obtain a string for printf operation
- // lib_arch_str shall contain string what platform this .dll was built for
- // running_arch_str shall string contain what platform Hotspot was built for
- char *running_arch_str=NULL,*lib_arch_str=NULL;
- for (unsigned int i=0;i<ARRAY_SIZE(arch_array);i++)
- {
- if (lib_arch==arch_array[i].arch_code)
- lib_arch_str=arch_array[i].arch_name;
- if (running_arch==arch_array[i].arch_code)
- running_arch_str=arch_array[i].arch_name;
- }
- assert(running_arch_str,
- "Didn't find runing architecture code in arch_array");
- // If the architure is right
- // but some other error took place - report getLastErrorString(...) msg
- if (lib_arch == running_arch)
- {
- return NULL;
- }
- if (lib_arch_str!=NULL)
- {
- ::_snprintf(ebuf, ebuflen-1,
- "Can't load %s-bit .dll on a %s-bit platform",
- lib_arch_str,running_arch_str);
- }
- else
- {
- // don't know what architecture this dll was build for
- ::_snprintf(ebuf, ebuflen-1,
- "Can't load this .dll (machine code=0x%x) on a %s-bit platform",
- lib_arch,running_arch_str);
- }
- return NULL;
- }
- void os::print_dll_info(outputStream *st) {
- int pid = os::current_process_id();
- st->print_cr("Dynamic libraries:");
- enumerate_modules(pid, _print_module, (void *)st);
- }
- // function pointer to Windows API "GetNativeSystemInfo".
- typedef void (WINAPI *GetNativeSystemInfo_func_type)(LPSYSTEM_INFO);
- static GetNativeSystemInfo_func_type _GetNativeSystemInfo;
- void os::print_os_info(outputStream* st) {
- st->print("OS:");
- OSVERSIONINFOEX osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
- st->print_cr("N/A");
- return;
- }
- int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
- if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- switch (os_vers) {
- case 3051: st->print(" Windows NT 3.51"); break;
- case 4000: st->print(" Windows NT 4.0"); break;
- case 5000: st->print(" Windows 2000"); break;
- case 5001: st->print(" Windows XP"); break;
- case 5002:
- case 6000:
- case 6001: {
- // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
- // find out whether we are running on 64 bit processor or not.
- SYSTEM_INFO si;
- ZeroMemory(&si, sizeof(SYSTEM_INFO));
- // Check to see if _GetNativeSystemInfo has been initialized.
- if (_GetNativeSystemInfo == NULL) {
- HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
- _GetNativeSystemInfo =
- CAST_TO_FN_PTR(GetNativeSystemInfo_func_type,
- GetProcAddress(hKernel32,
- "GetNativeSystemInfo"));
- if (_GetNativeSystemInfo == NULL)
- GetSystemInfo(&si);
- } else {
- _GetNativeSystemInfo(&si);
- }
- if (os_vers == 5002) {
- if (osvi.wProductType == VER_NT_WORKSTATION &&
- si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
- st->print(" Windows XP x64 Edition");
- else
- st->print(" Windows Server 2003 family");
- } else if (os_vers == 6000) {
- if (osvi.wProductType == VER_NT_WORKSTATION)
- st->print(" Windows Vista");
- else
- st->print(" Windows Server 2008");
- if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
- st->print(" , 64 bit");
- } else if (os_vers == 6001) {
- if (osvi.wProductType == VER_NT_WORKSTATION) {
- st->print(" Windows 7");
- } else {
- st->print(" Windows Server 2008 R2");
- }
- if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
- st->print(" , 64 bit");
- } else { // future os
- // Unrecognized windows, print out its major and minor versions
- st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
- if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
- st->print(" , 64 bit");
- }
- break;
- }
- default: // future windows, print out its major and minor versions
- st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
- }
- } else {
- switch (os_vers) {
- case 4000: st->print(" Windows 95"); break;
- case 4010: st->print(" Windows 98"); break;
- case 4090: st->print(" Windows Me"); break;
- default: // future windows, print out its major and minor versions
- st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
- }
- }
- st->print(" Build %d", osvi.dwBuildNumber);
- st->print(" %s", osvi.szCSDVersion); // service pack
- st->cr();
- }
- void os::print_memory_info(outputStream* st) {
- st->print("Memory:");
- st->print(" %dk page", os::vm_page_size()>>10);
- // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
- // value if total memory is larger than 4GB
- MEMORYSTATUSEX ms;
- ms.dwLength = sizeof(ms);
- GlobalMemoryStatusEx(&ms);
- st->print(", physical %uk", os::phys…
Large files files are truncated, but you can click here to view the full file