< prev index next >
src/hotspot/os/windows/os_windows.cpp
Print this page
rev 60629 : 8248656: Add Windows AArch64 platform support code
Reviewed-by:
Contributed-by: mbeckwit, luhenry, burban
rev 60630 : 8248659: AArch64: Extend CPU Feature detection
Reviewed-by:
Contributed-by: mbeckwit, luhenry, burban
rev 60632 : 8248670: Windows: Exception handling support on AArch64
Reviewed-by:
Contributed-by: mbeckwit, luhenry, burban
*** 30,39 ****
--- 30,40 ----
#include "classfile/classLoader.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
+ #include "code/nativeInst.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
*** 116,132 ****
static FILETIME process_creation_time;
static FILETIME process_exit_time;
static FILETIME process_user_time;
static FILETIME process_kernel_time;
! #ifdef _M_AMD64
#define __CPU__ amd64
#else
#define __CPU__ i486
#endif
! #if INCLUDE_AOT
PVOID topLevelVectoredExceptionHandler = NULL;
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
#endif
// save DLL module handle, used by GetModuleFileName
--- 117,138 ----
static FILETIME process_creation_time;
static FILETIME process_exit_time;
static FILETIME process_user_time;
static FILETIME process_kernel_time;
! #if defined(_M_ARM64)
! #define __CPU__ aarch64
! #elif defined(_M_AMD64)
#define __CPU__ amd64
#else
#define __CPU__ i486
#endif
! #if defined(USE_VECTORED_EXCEPTION_HANDLING)
! PVOID topLevelVectoredExceptionHandler = NULL;
! LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL;
! #elif INCLUDE_AOT
PVOID topLevelVectoredExceptionHandler = NULL;
LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
#endif
// save DLL module handle, used by GetModuleFileName
*** 145,155 ****
break;
case DLL_PROCESS_DETACH:
if (ForceTimeHighResolution) {
timeEndPeriod(1L);
}
! #if INCLUDE_AOT
if (topLevelVectoredExceptionHandler != NULL) {
RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
topLevelVectoredExceptionHandler = NULL;
}
#endif
--- 151,161 ----
break;
case DLL_PROCESS_DETACH:
if (ForceTimeHighResolution) {
timeEndPeriod(1L);
}
! #if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT
if (topLevelVectoredExceptionHandler != NULL) {
RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
topLevelVectoredExceptionHandler = NULL;
}
#endif
*** 454,472 ****
--- 460,485 ----
res = 20115; // java thread
}
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
+ #ifdef USE_VECTORED_EXCEPTION_HANDLING
+ // Any exception is caught by the Vectored Exception Handler, so VM can
+ // generate error dump when an exception occurred in non-Java thread
+ // (e.g. VM thread).
+ thread->call_run();
+ #else
// Install a win32 structured exception handler around every thread created
// by VM, so VM can generate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
__try {
thread->call_run();
} __except(topLevelExceptionFilter(
(_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
+ #endif
// Note: at this point the thread object may already have deleted itself.
// Do not dereference it from here on out.
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
*** 1425,1443 ****
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"}
};
! #if (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_AMD64 or _M_IX86
#endif
// Obtain a string for printf operation
// lib_arch_str shall contain string what platform this .dll was built for
--- 1438,1459 ----
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_ARM64, (char*)"ARM 64"}
};
! #if (defined _M_ARM64)
! static const uint16_t running_arch = IMAGE_FILE_MACHINE_ARM64;
! #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_AMD64 or _M_IX86 or _M_ARM64
#endif
// Obtain a string for printf operation
// lib_arch_str shall contain string what platform this .dll was built for
*** 1730,1740 ****
// 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));
GetNativeSystemInfo(&si);
! if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
st->print(" , 64 bit");
}
st->print(" Build %d", build_number);
st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
--- 1746,1757 ----
// 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));
GetNativeSystemInfo(&si);
! if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
! (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) {
st->print(" , 64 bit");
}
st->print(" Build %d", build_number);
st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
*** 2138,2148 ****
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
address handler) {
JavaThread* thread = (JavaThread*) Thread::current_or_null();
// Save pc in thread
! #ifdef _M_AMD64
// Do not blow up if no thread info available.
if (thread) {
thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
}
// Set pc to handler
--- 2155,2172 ----
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
address handler) {
JavaThread* thread = (JavaThread*) Thread::current_or_null();
// Save pc in thread
! #if defined(_M_ARM64)
! // Do not blow up if no thread info available.
! if (thread) {
! thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Pc);
! }
! // Set pc to handler
! exceptionInfo->ContextRecord->Pc = (DWORD64)handler;
! #elif defined(_M_AMD64)
// Do not blow up if no thread info available.
if (thread) {
thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
}
// Set pc to handler
*** 2236,2246 ****
//-----------------------------------------------------------------------------
LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
// handle exception caused by idiv; should only happen for -MinInt/-1
// (division by zero is handled explicitly)
! #ifdef _M_AMD64
PCONTEXT ctx = exceptionInfo->ContextRecord;
address pc = (address)ctx->Rip;
assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
if (pc[0] == 0xF7) {
--- 2260,2280 ----
//-----------------------------------------------------------------------------
LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
// handle exception caused by idiv; should only happen for -MinInt/-1
// (division by zero is handled explicitly)
! #if defined(_M_ARM64)
! PCONTEXT ctx = exceptionInfo->ContextRecord;
! address pc = (address)ctx->Sp;
! assert(pc[0] == 0x83, "not an sdiv opcode"); //Fixme did i get the right opcode?
! assert(ctx->X4 == min_jint, "unexpected idiv exception");
! // set correct result values and continue after idiv instruction
! ctx->Pc = (uint64_t)pc + 4; // idiv reg, reg, reg is 4 bytes
! ctx->X4 = (uint64_t)min_jint; // result
! ctx->X5 = (uint64_t)0; // remainder
! // Continue the execution
! #elif defined(_M_AMD64)
PCONTEXT ctx = exceptionInfo->ContextRecord;
address pc = (address)ctx->Rip;
assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
if (pc[0] == 0xF7) {
*** 2267,2276 ****
--- 2301,2311 ----
// Continue the execution
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
+ #if defined(_M_AMD64) || defined(_M_IX86)
//-----------------------------------------------------------------------------
LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
PCONTEXT ctx = exceptionInfo->ContextRecord;
#ifndef _WIN64
// handle exception caused by native method modifying control word
*** 2312,2390 ****
}
#endif // !_WIN64
return EXCEPTION_CONTINUE_SEARCH;
}
static inline void report_error(Thread* t, DWORD exception_code,
address addr, void* siginfo, void* context) {
VMError::report_and_die(t, exception_code, addr, siginfo, context);
// If UseOsErrorReporting, this will return here and save the error file
// somewhere where we can find it in the minidump.
}
- bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
- struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
- PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
- address addr = (address) exceptionRecord->ExceptionInformation[1];
- if (Interpreter::contains(pc)) {
- *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
- if (!fr->is_first_java_frame()) {
- // get_frame_at_stack_banging_point() is only called when we
- // have well defined stacks so java_sender() calls do not need
- // to assert safe_for_sender() first.
- *fr = fr->java_sender();
- }
- } else {
- // more complex code with compiled code
- assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
- CodeBlob* cb = CodeCache::find_blob(pc);
- if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
- // Not sure where the pc points to, fallback to default
- // stack overflow handling
- return false;
- } else {
- *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
- // in compiled code, the stack banging is performed just after the return pc
- // has been pushed on the stack
- *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
- if (!fr->is_java_frame()) {
- // See java_sender() comment above.
- *fr = fr->java_sender();
- }
- }
- }
- assert(fr->is_java_frame(), "Safety check");
- return true;
- }
-
- #if INCLUDE_AOT
- LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
- PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
- address addr = (address) exceptionRecord->ExceptionInformation[1];
- address pc = (address) exceptionInfo->ContextRecord->Rip;
-
- // Handle the case where we get an implicit exception in AOT generated
- // code. AOT DLL's loaded are not registered for structured exceptions.
- // If the exception occurred in the codeCache or AOT code, pass control
- // to our normal exception handler.
- CodeBlob* cb = CodeCache::find_blob(pc);
- if (cb != NULL) {
- return topLevelExceptionFilter(exceptionInfo);
- }
-
- return EXCEPTION_CONTINUE_SEARCH;
- }
- #endif
-
//-----------------------------------------------------------------------------
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord;
DWORD exception_code = exception_record->ExceptionCode;
! #ifdef _M_AMD64
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
#endif
Thread* t = Thread::current_or_null_safe();
--- 2347,2374 ----
}
#endif // !_WIN64
return EXCEPTION_CONTINUE_SEARCH;
}
+ #endif
static inline void report_error(Thread* t, DWORD exception_code,
address addr, void* siginfo, void* context) {
VMError::report_and_die(t, exception_code, addr, siginfo, context);
// If UseOsErrorReporting, this will return here and save the error file
// somewhere where we can find it in the minidump.
}
//-----------------------------------------------------------------------------
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord;
DWORD exception_code = exception_record->ExceptionCode;
! #if defined(_M_ARM64)
! address pc = (address) exceptionInfo->ContextRecord->Pc;
! #elif defined(_M_AMD64)
address pc = (address) exceptionInfo->ContextRecord->Rip;
#else
address pc = (address) exceptionInfo->ContextRecord->Eip;
#endif
Thread* t = Thread::current_or_null_safe();
*** 2463,2484 ****
--- 2447,2472 ----
}
}
// Last unguard failed or not unguarding
tty->print_raw_cr("Execution protection violation");
+ #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, addr, exception_record,
exceptionInfo->ContextRecord);
+ #endif
return EXCEPTION_CONTINUE_SEARCH;
}
}
#endif // _WIN64
+ #if defined(_M_AMD64) || defined(_M_IX86)
if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
VM_Version::is_cpuinfo_segv_addr(pc)) {
// Verify that OS save/restore AVX registers.
return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());
}
+ #endif
if (t != NULL && t->is_Java_thread()) {
JavaThread* thread = (JavaThread*) t;
bool in_java = thread->thread_state() == _thread_in_Java;
bool in_native = thread->thread_state() == _thread_in_native;
*** 2505,2516 ****
--- 2493,2506 ----
: EXCEPTION_CONTINUE_EXECUTION;
} else {
// Fatal red zone violation.
thread->disable_stack_red_zone();
tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
+ #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
+ #endif
return EXCEPTION_CONTINUE_SEARCH;
}
} else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
if (in_java) {
// Either stack overflow or null pointer exception.
*** 2551,2560 ****
--- 2541,2571 ----
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH;
}
+ #ifdef _M_ARM64
+ // Unsafe memory access
+ CompiledMethod* nm = NULL;
+ JavaThread* thread = (JavaThread*)t;
+ if (in_java) {
+ CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
+ nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
+ }
+
+ bool is_unsafe_arraycopy = (in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);
+ if (is_unsafe_arraycopy ||
+ ((in_vm || in_native) && thread->doing_unsafe_access()) ||
+ (nm != NULL && nm->has_unsafe_access())) {
+ address next_pc = Assembler::locate_next_instruction(pc);
+ if (is_unsafe_arraycopy) {
+ next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+ }
+ return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
+ }
+ #endif
+
#ifdef _WIN64
// Special care for fast JNI field accessors.
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks
// in and the heap gets shrunk before the field access.
address slowcase_pc = JNI_FastGetField::find_slowcase_pc(pc);
*** 2562,2573 ****
--- 2573,2586 ----
return Handle_Exception(exceptionInfo, slowcase_pc);
}
#endif
// Stack overflow or null pointer exception in native code.
+ #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
+ #endif
return EXCEPTION_CONTINUE_SEARCH;
} // /EXCEPTION_ACCESS_VIOLATION
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (exception_code == EXCEPTION_IN_PAGE_ERROR) {
*** 2587,2618 ****
--- 2600,2700 ----
}
return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
}
}
+ #ifdef _M_ARM64
+ if (in_java &&
+ (exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
+ exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
+ if (nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) {
+ if (TraceTraps) {
+ tty->print_cr("trap: zombie_not_entrant");
+ }
+ return Handle_Exception(exceptionInfo, SharedRuntime::get_handle_wrong_method_stub());
+ }
+ }
+ #endif
+
if (in_java) {
switch (exception_code) {
case EXCEPTION_INT_DIVIDE_BY_ZERO:
return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
case EXCEPTION_INT_OVERFLOW:
return Handle_IDiv_Exception(exceptionInfo);
} // switch
}
+
+ #if defined(_M_AMD64) || defined(_M_IX86)
if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) {
LONG result=Handle_FLT_Exception(exceptionInfo);
if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
}
+ #endif
}
+ #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
if (exception_code != EXCEPTION_BREAKPOINT) {
report_error(t, exception_code, pc, exception_record,
exceptionInfo->ContextRecord);
}
+ #endif
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ #if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT
+ LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
+ PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
+ #if defined(_M_ARM64)
+ address pc = (address) exceptionInfo->ContextRecord->Pc;
+ #elif defined(_M_AMD64)
+ address pc = (address) exceptionInfo->ContextRecord->Rip;
+ #else
+ address pc = (address) exceptionInfo->ContextRecord->Eip;
+ #endif
+
+ // Fast path for code part of the code cache
+ if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) {
+ return topLevelExceptionFilter(exceptionInfo);
+ }
+
+ // Handle the case where we get an implicit exception in AOT generated
+ // code. AOT DLL's loaded are not registered for structured exceptions.
+ // If the exception occurred in the codeCache or AOT code, pass control
+ // to our normal exception handler.
+ CodeBlob* cb = CodeCache::find_blob(pc);
+ if (cb != NULL) {
+ return topLevelExceptionFilter(exceptionInfo);
+ }
+
return EXCEPTION_CONTINUE_SEARCH;
}
+ #endif
+
+ #if defined(USE_VECTORED_EXCEPTION_HANDLING)
+ LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
+ if (InterceptOSException) goto exit;
+ DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
+ #if defined(_M_ARM64)
+ address pc = (address)exceptionInfo->ContextRecord->Pc;
+ #elif defined(_M_AMD64)
+ address pc = (address) exceptionInfo->ContextRecord->Rip;
+ #else
+ address pc = (address) exceptionInfo->ContextRecord->Eip;
+ #endif
+ Thread* t = Thread::current_or_null_safe();
+
+ if (exception_code != EXCEPTION_BREAKPOINT) {
+ report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
+ exceptionInfo->ContextRecord);
+ }
+ exit:
+ return previousUnhandledExceptionFilter ? previousUnhandledExceptionFilter(exceptionInfo) : EXCEPTION_CONTINUE_SEARCH;
+ }
+ #endif
#ifndef _WIN64
// Special care for fast JNI accessors.
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
// the heap gets shrunk before the field access.
*** 3608,3618 ****
--- 3690,3705 ----
char* os::non_memory_address_word() {
// Must never look like an address returned by reserve_memory,
// even in its subfields (as defined by the CPU immediate fields,
// if the CPU splits constants across multiple instructions).
+ #ifdef _M_ARM64
+ // AArch64 has a maximum addressable space of 48-bits
+ return (char*)((1ull << 48) - 1);
+ #else
return (char*)-1;
+ #endif
}
#define MAX_ERROR_COUNT 100
#define SYS_THREAD_ERROR 0xffffffffUL
*** 3804,3813 ****
--- 3891,3928 ----
"stack size not a multiple of page size");
initialize_performance_counter();
}
+ int os::win32::get_cacheline_size() {
+ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
+ DWORD returnLength = 0;
+
+ // See https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
+
+ GetLogicalProcessorInformation(NULL, &returnLength);
+ assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return from GetLogicalProcessorInformation");
+
+ buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)os::malloc(returnLength, mtInternal);
+ BOOL rc = GetLogicalProcessorInformation(buffer, &returnLength);
+ assert(rc, "Unexpected return from GetLogicalProcessorInformation");
+
+ int line_sz = -1;
+ for (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; ptr < buffer + returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++) {
+ switch (ptr->Relationship) {
+ case RelationCache:
+ // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
+ PCACHE_DESCRIPTOR Cache = &ptr->Cache;
+ if (Cache->Level == 1) {
+ line_sz = Cache->LineSize;
+ }
+ break;
+ }
+ }
+ os::free(buffer);
+ return line_sz;
+ }
HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
int ebuflen) {
char path[MAX_PATH];
DWORD size;
*** 4132,4142 ****
// have to set it the same so we have to mirror Solaris.
DEBUG_ONLY(os::set_mutex_init_done();)
// Setup Windows Exceptions
! #if INCLUDE_AOT
// If AOT is enabled we need to install a vectored exception handler
// in order to forward implicit exceptions from code in AOT
// generated DLLs. This is necessary since these DLLs are not
// registered for structured exceptions like codecache methods are.
if (AOTLibrary != NULL && (UseAOT || FLAG_IS_DEFAULT(UseAOT))) {
--- 4247,4260 ----
// have to set it the same so we have to mirror Solaris.
DEBUG_ONLY(os::set_mutex_init_done();)
// Setup Windows Exceptions
! #if defined(USE_VECTORED_EXCEPTION_HANDLING)
! topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter);
! previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter);
! #elif INCLUDE_AOT
// If AOT is enabled we need to install a vectored exception handler
// in order to forward implicit exceptions from code in AOT
// generated DLLs. This is necessary since these DLLs are not
// registered for structured exceptions like codecache methods are.
if (AOTLibrary != NULL && (UseAOT || FLAG_IS_DEFAULT(UseAOT))) {
*** 5589,5599 ****
}
// WINDOWS CONTEXT Flags for THREAD_SAMPLING
#if defined(IA32)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
! #elif defined (AMD64)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
#endif
// returns true if thread could be suspended,
// false otherwise
--- 5707,5717 ----
}
// WINDOWS CONTEXT Flags for THREAD_SAMPLING
#if defined(IA32)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
! #elif defined(AMD64) || defined(_M_ARM64)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
#endif
// returns true if thread could be suspended,
// false otherwise
< prev index next >