< 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


  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 // Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce
  26 #define _WIN32_WINNT 0x0600
  27 
  28 // no precompiled headers
  29 #include "jvm.h"
  30 #include "classfile/classLoader.hpp"
  31 #include "classfile/systemDictionary.hpp"
  32 #include "classfile/vmSymbols.hpp"
  33 #include "code/codeCache.hpp"
  34 #include "code/icBuffer.hpp"

  35 #include "code/vtableStubs.hpp"
  36 #include "compiler/compileBroker.hpp"
  37 #include "compiler/disassembler.hpp"
  38 #include "interpreter/interpreter.hpp"
  39 #include "logging/log.hpp"
  40 #include "logging/logStream.hpp"
  41 #include "memory/allocation.inline.hpp"
  42 #include "memory/filemap.hpp"
  43 #include "oops/oop.inline.hpp"
  44 #include "os_share_windows.hpp"
  45 #include "os_windows.inline.hpp"
  46 #include "prims/jniFastGetField.hpp"
  47 #include "prims/jvm_misc.hpp"
  48 #include "runtime/arguments.hpp"
  49 #include "runtime/atomic.hpp"
  50 #include "runtime/globals.hpp"
  51 #include "runtime/interfaceSupport.inline.hpp"
  52 #include "runtime/java.hpp"
  53 #include "runtime/javaCalls.hpp"
  54 #include "runtime/mutexLocker.hpp"


 101 #include <mmsystem.h>
 102 #include <winsock2.h>
 103 
 104 // for timer info max values which include all bits
 105 #define ALL_64_BITS CONST64(-1)
 106 
 107 // For DLL loading/load error detection
 108 // Values of PE COFF
 109 #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
 110 #define IMAGE_FILE_SIGNATURE_LENGTH 4
 111 
 112 static HANDLE main_process;
 113 static HANDLE main_thread;
 114 static int    main_thread_id;
 115 
 116 static FILETIME process_creation_time;
 117 static FILETIME process_exit_time;
 118 static FILETIME process_user_time;
 119 static FILETIME process_kernel_time;
 120 
 121 #ifdef _M_AMD64


 122   #define __CPU__ amd64
 123 #else
 124   #define __CPU__ i486
 125 #endif
 126 
 127 #if INCLUDE_AOT



 128 PVOID  topLevelVectoredExceptionHandler = NULL;
 129 LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
 130 #endif
 131 
 132 // save DLL module handle, used by GetModuleFileName
 133 
 134 HINSTANCE vm_lib_handle;
 135 
 136 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
 137   switch (reason) {
 138   case DLL_PROCESS_ATTACH:
 139     vm_lib_handle = hinst;
 140     if (ForceTimeHighResolution) {
 141       timeBeginPeriod(1L);
 142     }
 143     WindowsDbgHelp::pre_initialize();
 144     SymbolEngine::pre_initialize();
 145     break;
 146   case DLL_PROCESS_DETACH:
 147     if (ForceTimeHighResolution) {
 148       timeEndPeriod(1L);
 149     }
 150 #if INCLUDE_AOT
 151     if (topLevelVectoredExceptionHandler != NULL) {
 152       RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
 153       topLevelVectoredExceptionHandler = NULL;
 154     }
 155 #endif
 156     break;
 157   default:
 158     break;
 159   }
 160   return true;
 161 }
 162 
 163 static inline double fileTimeAsDouble(FILETIME* time) {
 164   const double high  = (double) ((unsigned int) ~0);
 165   const double split = 10000000.0;
 166   double result = (time->dwLowDateTime / split) +
 167                    time->dwHighDateTime * (high/split);
 168   return result;
 169 }
 170 


 439   thread->initialize_thread_current();
 440 
 441   OSThread* osthr = thread->osthread();
 442   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
 443 
 444   if (UseNUMA) {
 445     int lgrp_id = os::numa_get_group_id();
 446     if (lgrp_id != -1) {
 447       thread->set_lgrp_id(lgrp_id);
 448     }
 449   }
 450 
 451   // Diagnostic code to investigate JDK-6573254
 452   int res = 30115;  // non-java thread
 453   if (thread->is_Java_thread()) {
 454     res = 20115;    // java thread
 455   }
 456 
 457   log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
 458 






 459   // Install a win32 structured exception handler around every thread created
 460   // by VM, so VM can generate error dump when an exception occurred in non-
 461   // Java thread (e.g. VM thread).
 462   __try {
 463     thread->call_run();
 464   } __except(topLevelExceptionFilter(
 465                                      (_EXCEPTION_POINTERS*)_exception_info())) {
 466     // Nothing to do.
 467   }

 468 
 469   // Note: at this point the thread object may already have deleted itself.
 470   // Do not dereference it from here on out.
 471 
 472   log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
 473 
 474   // One less thread is executing
 475   // When the VMThread gets here, the main thread may have already exited
 476   // which frees the CodeHeap containing the Atomic::add code
 477   if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
 478     Atomic::dec(&os::win32::_os_thread_count);
 479   }
 480 
 481   // Thread must not return from exit_process_or_thread(), but if it does,
 482   // let it proceed to exit normally
 483   return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res);
 484 }
 485 
 486 static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle,
 487                                   int thread_id) {


1410      signature_offset + IMAGE_FILE_SIGNATURE_LENGTH) < 0)
1411      ||
1412      // Read field that contains code of architecture
1413      // that dll was built for
1414      (sizeof(lib_arch) != (os::read(fd, (void*)&lib_arch, sizeof(lib_arch))))
1415     );
1416 
1417   ::close(fd);
1418   if (failed_to_get_lib_arch) {
1419     // file i/o error - report os::lasterror(...) msg
1420     return NULL;
1421   }
1422 
1423   typedef struct {
1424     uint16_t arch_code;
1425     char* arch_name;
1426   } arch_t;
1427 
1428   static const arch_t arch_array[] = {
1429     {IMAGE_FILE_MACHINE_I386,      (char*)"IA 32"},
1430     {IMAGE_FILE_MACHINE_AMD64,     (char*)"AMD 64"}

1431   };
1432 #if (defined _M_AMD64)


1433   static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64;
1434 #elif (defined _M_IX86)
1435   static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386;
1436 #else
1437   #error Method os::dll_load requires that one of following \
1438          is defined :_M_AMD64 or _M_IX86
1439 #endif
1440 
1441 
1442   // Obtain a string for printf operation
1443   // lib_arch_str shall contain string what platform this .dll was built for
1444   // running_arch_str shall string contain what platform Hotspot was built for
1445   char *running_arch_str = NULL, *lib_arch_str = NULL;
1446   for (unsigned int i = 0; i < ARRAY_SIZE(arch_array); i++) {
1447     if (lib_arch == arch_array[i].arch_code) {
1448       lib_arch_str = arch_array[i].arch_name;
1449     }
1450     if (running_arch == arch_array[i].arch_code) {
1451       running_arch_str = arch_array[i].arch_name;
1452     }
1453   }
1454 
1455   assert(running_arch_str,
1456          "Didn't find running architecture code in arch_array");
1457 
1458   // If the architecture is right


1715       // Windows server 2019 GA 10/2018 build number is 17763
1716       if (build_number > 17762) {
1717         st->print("Server 2019");
1718       } else {
1719         st->print("Server 2016");
1720       }
1721     }
1722     break;
1723 
1724   default:
1725     // Unrecognized windows, print out its major and minor versions
1726     st->print("%d.%d", major_version, minor_version);
1727     break;
1728   }
1729 
1730   // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
1731   // find out whether we are running on 64 bit processor or not
1732   SYSTEM_INFO si;
1733   ZeroMemory(&si, sizeof(SYSTEM_INFO));
1734   GetNativeSystemInfo(&si);
1735   if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {

1736     st->print(" , 64 bit");
1737   }
1738 
1739   st->print(" Build %d", build_number);
1740   st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
1741   st->cr();
1742 }
1743 
1744 void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
1745   // Nothing to do for now.
1746 }
1747 
1748 void os::get_summary_cpu_info(char* buf, size_t buflen) {
1749   HKEY key;
1750   DWORD status = RegOpenKey(HKEY_LOCAL_MACHINE,
1751                "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key);
1752   if (status == ERROR_SUCCESS) {
1753     DWORD size = (DWORD)buflen;
1754     status = RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (byte*)buf, &size);
1755     if (status != ERROR_SUCCESS) {


2123         // while suspended because that would surprise the thread that
2124         // suspended us.
2125         sig_sem->signal();
2126 
2127         thread->java_suspend_self();
2128       }
2129     } while (threadIsSuspended);
2130   }
2131 }
2132 
2133 int os::signal_wait() {
2134   return check_pending_signals();
2135 }
2136 
2137 // Implicit OS exception handling
2138 
2139 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
2140                       address handler) {
2141   JavaThread* thread = (JavaThread*) Thread::current_or_null();
2142   // Save pc in thread
2143 #ifdef _M_AMD64







2144   // Do not blow up if no thread info available.
2145   if (thread) {
2146     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
2147   }
2148   // Set pc to handler
2149   exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
2150 #else
2151   // Do not blow up if no thread info available.
2152   if (thread) {
2153     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
2154   }
2155   // Set pc to handler
2156   exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
2157 #endif
2158 
2159   // Continue the execution
2160   return EXCEPTION_CONTINUE_EXECUTION;
2161 }
2162 
2163 


2221 };
2222 
2223 #undef def_excpt
2224 
2225 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2226   uint code = static_cast<uint>(exception_code);
2227   for (uint i = 0; i < ARRAY_SIZE(exceptlabels); ++i) {
2228     if (exceptlabels[i].number == code) {
2229       jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2230       return buf;
2231     }
2232   }
2233 
2234   return NULL;
2235 }
2236 
2237 //-----------------------------------------------------------------------------
2238 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2239   // handle exception caused by idiv; should only happen for -MinInt/-1
2240   // (division by zero is handled explicitly)
2241 #ifdef  _M_AMD64










2242   PCONTEXT ctx = exceptionInfo->ContextRecord;
2243   address pc = (address)ctx->Rip;
2244   assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
2245   assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2246   if (pc[0] == 0xF7) {
2247     // set correct result values and continue after idiv instruction
2248     ctx->Rip = (DWORD64)pc + 2;        // idiv reg, reg  is 2 bytes
2249   } else {
2250     ctx->Rip = (DWORD64)pc + 3;        // REX idiv reg, reg  is 3 bytes
2251   }
2252   // Do not set ctx->Rax as it already contains the correct value (either 32 or 64 bit, depending on the operation)
2253   // this is the case because the exception only happens for -MinValue/-1 and -MinValue is always in rax because of the
2254   // idiv opcode (0xF7).
2255   ctx->Rdx = (DWORD)0;             // remainder
2256   // Continue the execution
2257 #else
2258   PCONTEXT ctx = exceptionInfo->ContextRecord;
2259   address pc = (address)ctx->Eip;
2260   assert(pc[0] == 0xF7, "not an idiv opcode");
2261   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2262   assert(ctx->Eax == min_jint, "unexpected idiv exception");
2263   // set correct result values and continue after idiv instruction
2264   ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2265   ctx->Eax = (DWORD)min_jint;      // result
2266   ctx->Edx = (DWORD)0;             // remainder
2267   // Continue the execution
2268 #endif
2269   return EXCEPTION_CONTINUE_EXECUTION;
2270 }
2271 

2272 //-----------------------------------------------------------------------------
2273 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2274   PCONTEXT ctx = exceptionInfo->ContextRecord;
2275 #ifndef  _WIN64
2276   // handle exception caused by native method modifying control word
2277   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2278 
2279   switch (exception_code) {
2280   case EXCEPTION_FLT_DENORMAL_OPERAND:
2281   case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2282   case EXCEPTION_FLT_INEXACT_RESULT:
2283   case EXCEPTION_FLT_INVALID_OPERATION:
2284   case EXCEPTION_FLT_OVERFLOW:
2285   case EXCEPTION_FLT_STACK_CHECK:
2286   case EXCEPTION_FLT_UNDERFLOW:
2287     jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
2288     if (fp_control_word != ctx->FloatSave.ControlWord) {
2289       // Restore FPCW and mask out FLT exceptions
2290       ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;
2291       // Mask out pending FLT exceptions


2297   if (prev_uef_handler != NULL) {
2298     // We didn't handle this exception so pass it to the previous
2299     // UnhandledExceptionFilter.
2300     return (prev_uef_handler)(exceptionInfo);
2301   }
2302 #else // !_WIN64
2303   // On Windows, the mxcsr control bits are non-volatile across calls
2304   // See also CR 6192333
2305   //
2306   jint MxCsr = INITIAL_MXCSR;
2307   // we can't use StubRoutines::addr_mxcsr_std()
2308   // because in Win64 mxcsr is not saved there
2309   if (MxCsr != ctx->MxCsr) {
2310     ctx->MxCsr = MxCsr;
2311     return EXCEPTION_CONTINUE_EXECUTION;
2312   }
2313 #endif // !_WIN64
2314 
2315   return EXCEPTION_CONTINUE_SEARCH;
2316 }

2317 
2318 static inline void report_error(Thread* t, DWORD exception_code,
2319                                 address addr, void* siginfo, void* context) {
2320   VMError::report_and_die(t, exception_code, addr, siginfo, context);
2321 
2322   // If UseOsErrorReporting, this will return here and save the error file
2323   // somewhere where we can find it in the minidump.
2324 }
2325 
2326 bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
2327         struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
2328   PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2329   address addr = (address) exceptionRecord->ExceptionInformation[1];
2330   if (Interpreter::contains(pc)) {
2331     *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
2332     if (!fr->is_first_java_frame()) {
2333       // get_frame_at_stack_banging_point() is only called when we
2334       // have well defined stacks so java_sender() calls do not need
2335       // to assert safe_for_sender() first.
2336       *fr = fr->java_sender();
2337     }
2338   } else {
2339     // more complex code with compiled code
2340     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
2341     CodeBlob* cb = CodeCache::find_blob(pc);
2342     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
2343       // Not sure where the pc points to, fallback to default
2344       // stack overflow handling
2345       return false;
2346     } else {
2347       *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
2348       // in compiled code, the stack banging is performed just after the return pc
2349       // has been pushed on the stack
2350       *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
2351       if (!fr->is_java_frame()) {
2352         // See java_sender() comment above.
2353         *fr = fr->java_sender();
2354       }
2355     }
2356   }
2357   assert(fr->is_java_frame(), "Safety check");
2358   return true;
2359 }
2360 
2361 #if INCLUDE_AOT
2362 LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2363   PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2364   address addr = (address) exceptionRecord->ExceptionInformation[1];
2365   address pc = (address) exceptionInfo->ContextRecord->Rip;
2366 
2367   // Handle the case where we get an implicit exception in AOT generated
2368   // code.  AOT DLL's loaded are not registered for structured exceptions.
2369   // If the exception occurred in the codeCache or AOT code, pass control
2370   // to our normal exception handler.
2371   CodeBlob* cb = CodeCache::find_blob(pc);
2372   if (cb != NULL) {
2373     return topLevelExceptionFilter(exceptionInfo);
2374   }
2375 
2376   return EXCEPTION_CONTINUE_SEARCH;
2377 }
2378 #endif
2379 
2380 //-----------------------------------------------------------------------------
2381 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2382   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2383   PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord;
2384   DWORD exception_code = exception_record->ExceptionCode;
2385 #ifdef _M_AMD64


2386   address pc = (address) exceptionInfo->ContextRecord->Rip;
2387 #else
2388   address pc = (address) exceptionInfo->ContextRecord->Eip;
2389 #endif
2390   Thread* t = Thread::current_or_null_safe();
2391 
2392   // Handle SafeFetch32 and SafeFetchN exceptions.
2393   if (StubRoutines::is_safefetch_fault(pc)) {
2394     return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2395   }
2396 
2397 #ifndef _WIN64
2398   // Execution protection violation - win32 running on AMD64 only
2399   // Handled first to avoid misdiagnosis as a "normal" access violation;
2400   // This is safe to do because we have a new/unique ExceptionInformation
2401   // code for this condition.
2402   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2403     int exception_subcode = (int) exception_record->ExceptionInformation[0];
2404     address addr = (address) exception_record->ExceptionInformation[1];
2405 


2448           //
2449           // The other race involves two threads alternately trapping at
2450           // different addresses and failing to unguard the page, resulting in
2451           // an endless loop.  This condition is probably even more unlikely
2452           // than the first.
2453           //
2454           // Although both cases could be avoided by using locks or thread
2455           // local last_addr, these solutions are unnecessary complication:
2456           // this handler is a best-effort safety net, not a complete solution.
2457           // It is disabled by default and should only be used as a workaround
2458           // in case we missed any no-execute-unsafe VM code.
2459 
2460           last_addr = addr;
2461 
2462           return EXCEPTION_CONTINUE_EXECUTION;
2463         }
2464       }
2465 
2466       // Last unguard failed or not unguarding
2467       tty->print_raw_cr("Execution protection violation");

2468       report_error(t, exception_code, addr, exception_record,
2469                    exceptionInfo->ContextRecord);

2470       return EXCEPTION_CONTINUE_SEARCH;
2471     }
2472   }
2473 #endif // _WIN64
2474 

2475   if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
2476       VM_Version::is_cpuinfo_segv_addr(pc)) {
2477     // Verify that OS save/restore AVX registers.
2478     return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());
2479   }

2480 
2481   if (t != NULL && t->is_Java_thread()) {
2482     JavaThread* thread = (JavaThread*) t;
2483     bool in_java = thread->thread_state() == _thread_in_Java;
2484     bool in_native = thread->thread_state() == _thread_in_native;
2485     bool in_vm = thread->thread_state() == _thread_in_vm;
2486 
2487     // Handle potential stack overflows up front.
2488     if (exception_code == EXCEPTION_STACK_OVERFLOW) {
2489       if (thread->stack_guards_enabled()) {
2490         if (in_java) {
2491           frame fr;
2492           if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) {
2493             assert(fr.is_java_frame(), "Must be a Java frame");
2494             SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
2495           }
2496         }
2497         // Yellow zone violation.  The o/s has unprotected the first yellow
2498         // zone page for us.  Note:  must call disable_stack_yellow_zone to
2499         // update the enabled status, even if the zone contains only one page.
2500         assert(!in_vm, "Undersized StackShadowPages");
2501         thread->disable_stack_yellow_reserved_zone();
2502         // If not in java code, return and hope for the best.
2503         return in_java
2504             ? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
2505             :  EXCEPTION_CONTINUE_EXECUTION;
2506       } else {
2507         // Fatal red zone violation.
2508         thread->disable_stack_red_zone();
2509         tty->print_raw_cr("An unrecoverable stack overflow has occurred.");

2510         report_error(t, exception_code, pc, exception_record,
2511                       exceptionInfo->ContextRecord);

2512         return EXCEPTION_CONTINUE_SEARCH;
2513       }
2514     } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2515       if (in_java) {
2516         // Either stack overflow or null pointer exception.
2517         address addr = (address) exception_record->ExceptionInformation[1];
2518         address stack_end = thread->stack_end();
2519         if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {
2520           // Stack overflow.
2521           assert(!os::uses_stack_guard_pages(),
2522                  "should be caught by red zone code above.");
2523           return Handle_Exception(exceptionInfo,
2524                                   SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
2525         }
2526         // Check for safepoint polling and implicit null
2527         // We only expect null pointers in the stubs (vtable)
2528         // the rest are checked explicitly now.
2529         CodeBlob* cb = CodeCache::find_blob(pc);
2530         if (cb != NULL) {
2531           if (SafepointMechanism::is_poll_address(addr)) {


2536 #ifdef _WIN64
2537         // If it's a legal stack address map the entire region in
2538         if (thread->is_in_usable_stack(addr)) {
2539           addr = (address)((uintptr_t)addr &
2540                             (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
2541           os::commit_memory((char *)addr, thread->stack_base() - addr,
2542                             !ExecMem);
2543           return EXCEPTION_CONTINUE_EXECUTION;
2544         }
2545 #endif
2546         // Null pointer exception.
2547         if (MacroAssembler::uses_implicit_null_check((void*)addr)) {
2548           address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
2549           if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
2550         }
2551         report_error(t, exception_code, pc, exception_record,
2552                       exceptionInfo->ContextRecord);
2553         return EXCEPTION_CONTINUE_SEARCH;
2554       }
2555 





















2556 #ifdef _WIN64
2557       // Special care for fast JNI field accessors.
2558       // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks
2559       // in and the heap gets shrunk before the field access.
2560       address slowcase_pc = JNI_FastGetField::find_slowcase_pc(pc);
2561       if (slowcase_pc != (address)-1) {
2562         return Handle_Exception(exceptionInfo, slowcase_pc);
2563       }
2564 #endif
2565 
2566       // Stack overflow or null pointer exception in native code.

2567       report_error(t, exception_code, pc, exception_record,
2568                    exceptionInfo->ContextRecord);

2569       return EXCEPTION_CONTINUE_SEARCH;
2570     } // /EXCEPTION_ACCESS_VIOLATION
2571     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2572 
2573     if (exception_code == EXCEPTION_IN_PAGE_ERROR) {
2574       CompiledMethod* nm = NULL;
2575       JavaThread* thread = (JavaThread*)t;
2576       if (in_java) {
2577         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
2578         nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
2579       }
2580 
2581       bool is_unsafe_arraycopy = (in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);
2582       if (((in_vm || in_native || is_unsafe_arraycopy) && thread->doing_unsafe_access()) ||
2583           (nm != NULL && nm->has_unsafe_access())) {
2584         address next_pc =  Assembler::locate_next_instruction(pc);
2585         if (is_unsafe_arraycopy) {
2586           next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
2587         }
2588         return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
2589       }
2590     }
2591 













2592     if (in_java) {
2593       switch (exception_code) {
2594       case EXCEPTION_INT_DIVIDE_BY_ZERO:
2595         return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
2596 
2597       case EXCEPTION_INT_OVERFLOW:
2598         return Handle_IDiv_Exception(exceptionInfo);
2599 
2600       } // switch
2601     }


2602     if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) {
2603       LONG result=Handle_FLT_Exception(exceptionInfo);
2604       if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
2605     }

2606   }
2607 

2608   if (exception_code != EXCEPTION_BREAKPOINT) {
2609     report_error(t, exception_code, pc, exception_record,
2610                  exceptionInfo->ContextRecord);
2611   }





























2612   return EXCEPTION_CONTINUE_SEARCH;
2613 }























2614 
2615 #ifndef _WIN64
2616 // Special care for fast JNI accessors.
2617 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
2618 // the heap gets shrunk before the field access.
2619 // Need to install our own structured exception handler since native code may
2620 // install its own.
2621 LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2622   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2623   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2624     address pc = (address) exceptionInfo->ContextRecord->Eip;
2625     address addr = JNI_FastGetField::find_slowcase_pc(pc);
2626     if (addr != (address)-1) {
2627       return Handle_Exception(exceptionInfo, addr);
2628     }
2629   }
2630   return EXCEPTION_CONTINUE_SEARCH;
2631 }
2632 
2633 #define DEFINE_FAST_GETFIELD(Return, Fieldname, Result)                     \


3593   }
3594 }
3595 
3596 int os::numa_get_group_id_for_address(const void* address) {
3597   return 0;
3598 }
3599 
3600 bool os::get_page_info(char *start, page_info* info) {
3601   return false;
3602 }
3603 
3604 char *os::scan_pages(char *start, char* end, page_info* page_expected,
3605                      page_info* page_found) {
3606   return end;
3607 }
3608 
3609 char* os::non_memory_address_word() {
3610   // Must never look like an address returned by reserve_memory,
3611   // even in its subfields (as defined by the CPU immediate fields,
3612   // if the CPU splits constants across multiple instructions).




3613   return (char*)-1;

3614 }
3615 
3616 #define MAX_ERROR_COUNT 100
3617 #define SYS_THREAD_ERROR 0xffffffffUL
3618 
3619 void os::pd_start_thread(Thread* thread) {
3620   DWORD ret = ResumeThread(thread->osthread()->thread_handle());
3621   // Returns previous suspend state:
3622   // 0:  Thread was not suspended
3623   // 1:  Thread is running now
3624   // >1: Thread is still suspended.
3625   assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back
3626 }
3627 
3628 
3629 // Short sleep, direct OS call.
3630 //
3631 // ms = 0, means allow others (if any) to run.
3632 //
3633 void os::naked_short_sleep(jlong ms) {


3789   case VER_PLATFORM_WIN32_NT:
3790     {
3791       int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;
3792       if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER ||
3793           oi.wProductType == VER_NT_SERVER) {
3794         _is_windows_server = true;
3795       }
3796     }
3797     break;
3798   default: fatal("Unknown platform");
3799   }
3800 
3801   _default_stack_size = os::current_stack_size();
3802   assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");
3803   assert((_default_stack_size & (_vm_page_size - 1)) == 0,
3804          "stack size not a multiple of page size");
3805 
3806   initialize_performance_counter();
3807 }
3808 




























3809 
3810 HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
3811                                       int ebuflen) {
3812   char path[MAX_PATH];
3813   DWORD size;
3814   DWORD pathLen = (DWORD)sizeof(path);
3815   HINSTANCE result = NULL;
3816 
3817   // only allow library name without path component
3818   assert(strchr(name, '\\') == NULL, "path not allowed");
3819   assert(strchr(name, ':') == NULL, "path not allowed");
3820   if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) {
3821     jio_snprintf(ebuf, ebuflen,
3822                  "Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name);
3823     return NULL;
3824   }
3825 
3826   // search system directory
3827   if ((size = GetSystemDirectory(path, pathLen)) > 0) {
3828     if (size >= pathLen) {


4117 }
4118 
4119 // To install functions for atexit processing
4120 extern "C" {
4121   static void perfMemory_exit_helper() {
4122     perfMemory_exit();
4123   }
4124 }
4125 
4126 static jint initSock();
4127 
4128 // this is called _after_ the global arguments have been parsed
4129 jint os::init_2(void) {
4130 
4131   // This could be set any time but all platforms
4132   // have to set it the same so we have to mirror Solaris.
4133   DEBUG_ONLY(os::set_mutex_init_done();)
4134 
4135   // Setup Windows Exceptions
4136 
4137 #if INCLUDE_AOT



4138   // If AOT is enabled we need to install a vectored exception handler
4139   // in order to forward implicit exceptions from code in AOT
4140   // generated DLLs.  This is necessary since these DLLs are not
4141   // registered for structured exceptions like codecache methods are.
4142   if (AOTLibrary != NULL && (UseAOT || FLAG_IS_DEFAULT(UseAOT))) {
4143     topLevelVectoredExceptionHandler = AddVectoredExceptionHandler( 1, topLevelVectoredExceptionFilter);
4144   }
4145 #endif
4146 
4147   // for debugging float code generation bugs
4148   if (ForceFloatExceptions) {
4149 #ifndef  _WIN64
4150     static long fp_control_word = 0;
4151     __asm { fstcw fp_control_word }
4152     // see Intel PPro Manual, Vol. 2, p 7-16
4153     const long precision = 0x20;
4154     const long underflow = 0x10;
4155     const long overflow  = 0x08;
4156     const long zero_div  = 0x04;
4157     const long denorm    = 0x02;


5574 
5575 int os::connect(int fd, struct sockaddr* him, socklen_t len) {
5576   return ::connect(fd, him, len);
5577 }
5578 
5579 int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
5580   return ::recv(fd, buf, (int)nBytes, flags);
5581 }
5582 
5583 int os::send(int fd, char* buf, size_t nBytes, uint flags) {
5584   return ::send(fd, buf, (int)nBytes, flags);
5585 }
5586 
5587 int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
5588   return ::send(fd, buf, (int)nBytes, flags);
5589 }
5590 
5591 // WINDOWS CONTEXT Flags for THREAD_SAMPLING
5592 #if defined(IA32)
5593   #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
5594 #elif defined (AMD64)
5595   #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
5596 #endif
5597 
5598 // returns true if thread could be suspended,
5599 // false otherwise
5600 static bool do_suspend(HANDLE* h) {
5601   if (h != NULL) {
5602     if (SuspendThread(*h) != ~0) {
5603       return true;
5604     }
5605   }
5606   return false;
5607 }
5608 
5609 // resume the thread
5610 // calling resume on an active thread is a no-op
5611 static void do_resume(HANDLE* h) {
5612   if (h != NULL) {
5613     ResumeThread(*h);
5614   }




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 // Must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce
  26 #define _WIN32_WINNT 0x0600
  27 
  28 // no precompiled headers
  29 #include "jvm.h"
  30 #include "classfile/classLoader.hpp"
  31 #include "classfile/systemDictionary.hpp"
  32 #include "classfile/vmSymbols.hpp"
  33 #include "code/codeCache.hpp"
  34 #include "code/icBuffer.hpp"
  35 #include "code/nativeInst.hpp"
  36 #include "code/vtableStubs.hpp"
  37 #include "compiler/compileBroker.hpp"
  38 #include "compiler/disassembler.hpp"
  39 #include "interpreter/interpreter.hpp"
  40 #include "logging/log.hpp"
  41 #include "logging/logStream.hpp"
  42 #include "memory/allocation.inline.hpp"
  43 #include "memory/filemap.hpp"
  44 #include "oops/oop.inline.hpp"
  45 #include "os_share_windows.hpp"
  46 #include "os_windows.inline.hpp"
  47 #include "prims/jniFastGetField.hpp"
  48 #include "prims/jvm_misc.hpp"
  49 #include "runtime/arguments.hpp"
  50 #include "runtime/atomic.hpp"
  51 #include "runtime/globals.hpp"
  52 #include "runtime/interfaceSupport.inline.hpp"
  53 #include "runtime/java.hpp"
  54 #include "runtime/javaCalls.hpp"
  55 #include "runtime/mutexLocker.hpp"


 102 #include <mmsystem.h>
 103 #include <winsock2.h>
 104 
 105 // for timer info max values which include all bits
 106 #define ALL_64_BITS CONST64(-1)
 107 
 108 // For DLL loading/load error detection
 109 // Values of PE COFF
 110 #define IMAGE_FILE_PTR_TO_SIGNATURE 0x3c
 111 #define IMAGE_FILE_SIGNATURE_LENGTH 4
 112 
 113 static HANDLE main_process;
 114 static HANDLE main_thread;
 115 static int    main_thread_id;
 116 
 117 static FILETIME process_creation_time;
 118 static FILETIME process_exit_time;
 119 static FILETIME process_user_time;
 120 static FILETIME process_kernel_time;
 121 
 122 #if defined(_M_ARM64)
 123   #define __CPU__ aarch64
 124 #elif defined(_M_AMD64)
 125   #define __CPU__ amd64
 126 #else
 127   #define __CPU__ i486
 128 #endif
 129 
 130 #if defined(USE_VECTORED_EXCEPTION_HANDLING)
 131 PVOID  topLevelVectoredExceptionHandler = NULL;
 132 LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL;
 133 #elif INCLUDE_AOT
 134 PVOID  topLevelVectoredExceptionHandler = NULL;
 135 LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
 136 #endif
 137 
 138 // save DLL module handle, used by GetModuleFileName
 139 
 140 HINSTANCE vm_lib_handle;
 141 
 142 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
 143   switch (reason) {
 144   case DLL_PROCESS_ATTACH:
 145     vm_lib_handle = hinst;
 146     if (ForceTimeHighResolution) {
 147       timeBeginPeriod(1L);
 148     }
 149     WindowsDbgHelp::pre_initialize();
 150     SymbolEngine::pre_initialize();
 151     break;
 152   case DLL_PROCESS_DETACH:
 153     if (ForceTimeHighResolution) {
 154       timeEndPeriod(1L);
 155     }
 156 #if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT
 157     if (topLevelVectoredExceptionHandler != NULL) {
 158       RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
 159       topLevelVectoredExceptionHandler = NULL;
 160     }
 161 #endif
 162     break;
 163   default:
 164     break;
 165   }
 166   return true;
 167 }
 168 
 169 static inline double fileTimeAsDouble(FILETIME* time) {
 170   const double high  = (double) ((unsigned int) ~0);
 171   const double split = 10000000.0;
 172   double result = (time->dwLowDateTime / split) +
 173                    time->dwHighDateTime * (high/split);
 174   return result;
 175 }
 176 


 445   thread->initialize_thread_current();
 446 
 447   OSThread* osthr = thread->osthread();
 448   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
 449 
 450   if (UseNUMA) {
 451     int lgrp_id = os::numa_get_group_id();
 452     if (lgrp_id != -1) {
 453       thread->set_lgrp_id(lgrp_id);
 454     }
 455   }
 456 
 457   // Diagnostic code to investigate JDK-6573254
 458   int res = 30115;  // non-java thread
 459   if (thread->is_Java_thread()) {
 460     res = 20115;    // java thread
 461   }
 462 
 463   log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
 464 
 465 #ifdef USE_VECTORED_EXCEPTION_HANDLING
 466   // Any exception is caught by the Vectored Exception Handler, so VM can
 467   // generate error dump when an exception occurred in non-Java thread
 468   // (e.g. VM thread).
 469   thread->call_run();
 470 #else
 471   // Install a win32 structured exception handler around every thread created
 472   // by VM, so VM can generate error dump when an exception occurred in non-
 473   // Java thread (e.g. VM thread).
 474   __try {
 475     thread->call_run();
 476   } __except(topLevelExceptionFilter(
 477                                      (_EXCEPTION_POINTERS*)_exception_info())) {
 478     // Nothing to do.
 479   }
 480 #endif
 481 
 482   // Note: at this point the thread object may already have deleted itself.
 483   // Do not dereference it from here on out.
 484 
 485   log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
 486 
 487   // One less thread is executing
 488   // When the VMThread gets here, the main thread may have already exited
 489   // which frees the CodeHeap containing the Atomic::add code
 490   if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
 491     Atomic::dec(&os::win32::_os_thread_count);
 492   }
 493 
 494   // Thread must not return from exit_process_or_thread(), but if it does,
 495   // let it proceed to exit normally
 496   return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res);
 497 }
 498 
 499 static OSThread* create_os_thread(Thread* thread, HANDLE thread_handle,
 500                                   int thread_id) {


1423      signature_offset + IMAGE_FILE_SIGNATURE_LENGTH) < 0)
1424      ||
1425      // Read field that contains code of architecture
1426      // that dll was built for
1427      (sizeof(lib_arch) != (os::read(fd, (void*)&lib_arch, sizeof(lib_arch))))
1428     );
1429 
1430   ::close(fd);
1431   if (failed_to_get_lib_arch) {
1432     // file i/o error - report os::lasterror(...) msg
1433     return NULL;
1434   }
1435 
1436   typedef struct {
1437     uint16_t arch_code;
1438     char* arch_name;
1439   } arch_t;
1440 
1441   static const arch_t arch_array[] = {
1442     {IMAGE_FILE_MACHINE_I386,      (char*)"IA 32"},
1443     {IMAGE_FILE_MACHINE_AMD64,     (char*)"AMD 64"},
1444     {IMAGE_FILE_MACHINE_ARM64,     (char*)"ARM 64"}
1445   };
1446 #if (defined _M_ARM64)
1447   static const uint16_t running_arch = IMAGE_FILE_MACHINE_ARM64;
1448 #elif (defined _M_AMD64)
1449   static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64;
1450 #elif (defined _M_IX86)
1451   static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386;
1452 #else
1453   #error Method os::dll_load requires that one of following \
1454          is defined :_M_AMD64 or _M_IX86 or _M_ARM64
1455 #endif
1456 
1457 
1458   // Obtain a string for printf operation
1459   // lib_arch_str shall contain string what platform this .dll was built for
1460   // running_arch_str shall string contain what platform Hotspot was built for
1461   char *running_arch_str = NULL, *lib_arch_str = NULL;
1462   for (unsigned int i = 0; i < ARRAY_SIZE(arch_array); i++) {
1463     if (lib_arch == arch_array[i].arch_code) {
1464       lib_arch_str = arch_array[i].arch_name;
1465     }
1466     if (running_arch == arch_array[i].arch_code) {
1467       running_arch_str = arch_array[i].arch_name;
1468     }
1469   }
1470 
1471   assert(running_arch_str,
1472          "Didn't find running architecture code in arch_array");
1473 
1474   // If the architecture is right


1731       // Windows server 2019 GA 10/2018 build number is 17763
1732       if (build_number > 17762) {
1733         st->print("Server 2019");
1734       } else {
1735         st->print("Server 2016");
1736       }
1737     }
1738     break;
1739 
1740   default:
1741     // Unrecognized windows, print out its major and minor versions
1742     st->print("%d.%d", major_version, minor_version);
1743     break;
1744   }
1745 
1746   // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
1747   // find out whether we are running on 64 bit processor or not
1748   SYSTEM_INFO si;
1749   ZeroMemory(&si, sizeof(SYSTEM_INFO));
1750   GetNativeSystemInfo(&si);
1751   if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
1752       (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) {
1753     st->print(" , 64 bit");
1754   }
1755 
1756   st->print(" Build %d", build_number);
1757   st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
1758   st->cr();
1759 }
1760 
1761 void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
1762   // Nothing to do for now.
1763 }
1764 
1765 void os::get_summary_cpu_info(char* buf, size_t buflen) {
1766   HKEY key;
1767   DWORD status = RegOpenKey(HKEY_LOCAL_MACHINE,
1768                "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key);
1769   if (status == ERROR_SUCCESS) {
1770     DWORD size = (DWORD)buflen;
1771     status = RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (byte*)buf, &size);
1772     if (status != ERROR_SUCCESS) {


2140         // while suspended because that would surprise the thread that
2141         // suspended us.
2142         sig_sem->signal();
2143 
2144         thread->java_suspend_self();
2145       }
2146     } while (threadIsSuspended);
2147   }
2148 }
2149 
2150 int os::signal_wait() {
2151   return check_pending_signals();
2152 }
2153 
2154 // Implicit OS exception handling
2155 
2156 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
2157                       address handler) {
2158   JavaThread* thread = (JavaThread*) Thread::current_or_null();
2159   // Save pc in thread
2160 #if defined(_M_ARM64)
2161   // Do not blow up if no thread info available.
2162   if (thread) {
2163     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Pc);
2164   }
2165   // Set pc to handler
2166   exceptionInfo->ContextRecord->Pc = (DWORD64)handler;
2167 #elif defined(_M_AMD64)
2168   // Do not blow up if no thread info available.
2169   if (thread) {
2170     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
2171   }
2172   // Set pc to handler
2173   exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
2174 #else
2175   // Do not blow up if no thread info available.
2176   if (thread) {
2177     thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
2178   }
2179   // Set pc to handler
2180   exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
2181 #endif
2182 
2183   // Continue the execution
2184   return EXCEPTION_CONTINUE_EXECUTION;
2185 }
2186 
2187 


2245 };
2246 
2247 #undef def_excpt
2248 
2249 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2250   uint code = static_cast<uint>(exception_code);
2251   for (uint i = 0; i < ARRAY_SIZE(exceptlabels); ++i) {
2252     if (exceptlabels[i].number == code) {
2253       jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2254       return buf;
2255     }
2256   }
2257 
2258   return NULL;
2259 }
2260 
2261 //-----------------------------------------------------------------------------
2262 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2263   // handle exception caused by idiv; should only happen for -MinInt/-1
2264   // (division by zero is handled explicitly)
2265 #if defined(_M_ARM64)
2266   PCONTEXT ctx = exceptionInfo->ContextRecord;
2267   address pc = (address)ctx->Sp;
2268   assert(pc[0] == 0x83, "not an sdiv opcode"); //Fixme did i get the right opcode?
2269   assert(ctx->X4 == min_jint, "unexpected idiv exception");
2270   // set correct result values and continue after idiv instruction
2271   ctx->Pc = (uint64_t)pc + 4;        // idiv reg, reg, reg  is 4 bytes
2272   ctx->X4 = (uint64_t)min_jint;      // result
2273   ctx->X5 = (uint64_t)0;             // remainder
2274   // Continue the execution
2275 #elif defined(_M_AMD64)
2276   PCONTEXT ctx = exceptionInfo->ContextRecord;
2277   address pc = (address)ctx->Rip;
2278   assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode");
2279   assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && (pc[2] & ~0x7) == 0xF8 || (pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2280   if (pc[0] == 0xF7) {
2281     // set correct result values and continue after idiv instruction
2282     ctx->Rip = (DWORD64)pc + 2;        // idiv reg, reg  is 2 bytes
2283   } else {
2284     ctx->Rip = (DWORD64)pc + 3;        // REX idiv reg, reg  is 3 bytes
2285   }
2286   // Do not set ctx->Rax as it already contains the correct value (either 32 or 64 bit, depending on the operation)
2287   // this is the case because the exception only happens for -MinValue/-1 and -MinValue is always in rax because of the
2288   // idiv opcode (0xF7).
2289   ctx->Rdx = (DWORD)0;             // remainder
2290   // Continue the execution
2291 #else
2292   PCONTEXT ctx = exceptionInfo->ContextRecord;
2293   address pc = (address)ctx->Eip;
2294   assert(pc[0] == 0xF7, "not an idiv opcode");
2295   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2296   assert(ctx->Eax == min_jint, "unexpected idiv exception");
2297   // set correct result values and continue after idiv instruction
2298   ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2299   ctx->Eax = (DWORD)min_jint;      // result
2300   ctx->Edx = (DWORD)0;             // remainder
2301   // Continue the execution
2302 #endif
2303   return EXCEPTION_CONTINUE_EXECUTION;
2304 }
2305 
2306 #if defined(_M_AMD64) || defined(_M_IX86)
2307 //-----------------------------------------------------------------------------
2308 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2309   PCONTEXT ctx = exceptionInfo->ContextRecord;
2310 #ifndef  _WIN64
2311   // handle exception caused by native method modifying control word
2312   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2313 
2314   switch (exception_code) {
2315   case EXCEPTION_FLT_DENORMAL_OPERAND:
2316   case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2317   case EXCEPTION_FLT_INEXACT_RESULT:
2318   case EXCEPTION_FLT_INVALID_OPERATION:
2319   case EXCEPTION_FLT_OVERFLOW:
2320   case EXCEPTION_FLT_STACK_CHECK:
2321   case EXCEPTION_FLT_UNDERFLOW:
2322     jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
2323     if (fp_control_word != ctx->FloatSave.ControlWord) {
2324       // Restore FPCW and mask out FLT exceptions
2325       ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;
2326       // Mask out pending FLT exceptions


2332   if (prev_uef_handler != NULL) {
2333     // We didn't handle this exception so pass it to the previous
2334     // UnhandledExceptionFilter.
2335     return (prev_uef_handler)(exceptionInfo);
2336   }
2337 #else // !_WIN64
2338   // On Windows, the mxcsr control bits are non-volatile across calls
2339   // See also CR 6192333
2340   //
2341   jint MxCsr = INITIAL_MXCSR;
2342   // we can't use StubRoutines::addr_mxcsr_std()
2343   // because in Win64 mxcsr is not saved there
2344   if (MxCsr != ctx->MxCsr) {
2345     ctx->MxCsr = MxCsr;
2346     return EXCEPTION_CONTINUE_EXECUTION;
2347   }
2348 #endif // !_WIN64
2349 
2350   return EXCEPTION_CONTINUE_SEARCH;
2351 }
2352 #endif
2353 
2354 static inline void report_error(Thread* t, DWORD exception_code,
2355                                 address addr, void* siginfo, void* context) {
2356   VMError::report_and_die(t, exception_code, addr, siginfo, context);
2357 
2358   // If UseOsErrorReporting, this will return here and save the error file
2359   // somewhere where we can find it in the minidump.
2360 }
2361 






















































2362 //-----------------------------------------------------------------------------
2363 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2364   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
2365   PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord;
2366   DWORD exception_code = exception_record->ExceptionCode;
2367 #if defined(_M_ARM64)
2368   address pc = (address) exceptionInfo->ContextRecord->Pc;
2369 #elif defined(_M_AMD64)
2370   address pc = (address) exceptionInfo->ContextRecord->Rip;
2371 #else
2372   address pc = (address) exceptionInfo->ContextRecord->Eip;
2373 #endif
2374   Thread* t = Thread::current_or_null_safe();
2375 
2376   // Handle SafeFetch32 and SafeFetchN exceptions.
2377   if (StubRoutines::is_safefetch_fault(pc)) {
2378     return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
2379   }
2380 
2381 #ifndef _WIN64
2382   // Execution protection violation - win32 running on AMD64 only
2383   // Handled first to avoid misdiagnosis as a "normal" access violation;
2384   // This is safe to do because we have a new/unique ExceptionInformation
2385   // code for this condition.
2386   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2387     int exception_subcode = (int) exception_record->ExceptionInformation[0];
2388     address addr = (address) exception_record->ExceptionInformation[1];
2389 


2432           //
2433           // The other race involves two threads alternately trapping at
2434           // different addresses and failing to unguard the page, resulting in
2435           // an endless loop.  This condition is probably even more unlikely
2436           // than the first.
2437           //
2438           // Although both cases could be avoided by using locks or thread
2439           // local last_addr, these solutions are unnecessary complication:
2440           // this handler is a best-effort safety net, not a complete solution.
2441           // It is disabled by default and should only be used as a workaround
2442           // in case we missed any no-execute-unsafe VM code.
2443 
2444           last_addr = addr;
2445 
2446           return EXCEPTION_CONTINUE_EXECUTION;
2447         }
2448       }
2449 
2450       // Last unguard failed or not unguarding
2451       tty->print_raw_cr("Execution protection violation");
2452 #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2453       report_error(t, exception_code, addr, exception_record,
2454                    exceptionInfo->ContextRecord);
2455 #endif
2456       return EXCEPTION_CONTINUE_SEARCH;
2457     }
2458   }
2459 #endif // _WIN64
2460 
2461 #if defined(_M_AMD64) || defined(_M_IX86)
2462   if ((exception_code == EXCEPTION_ACCESS_VIOLATION) &&
2463       VM_Version::is_cpuinfo_segv_addr(pc)) {
2464     // Verify that OS save/restore AVX registers.
2465     return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr());
2466   }
2467 #endif
2468 
2469   if (t != NULL && t->is_Java_thread()) {
2470     JavaThread* thread = (JavaThread*) t;
2471     bool in_java = thread->thread_state() == _thread_in_Java;
2472     bool in_native = thread->thread_state() == _thread_in_native;
2473     bool in_vm = thread->thread_state() == _thread_in_vm;
2474 
2475     // Handle potential stack overflows up front.
2476     if (exception_code == EXCEPTION_STACK_OVERFLOW) {
2477       if (thread->stack_guards_enabled()) {
2478         if (in_java) {
2479           frame fr;
2480           if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) {
2481             assert(fr.is_java_frame(), "Must be a Java frame");
2482             SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
2483           }
2484         }
2485         // Yellow zone violation.  The o/s has unprotected the first yellow
2486         // zone page for us.  Note:  must call disable_stack_yellow_zone to
2487         // update the enabled status, even if the zone contains only one page.
2488         assert(!in_vm, "Undersized StackShadowPages");
2489         thread->disable_stack_yellow_reserved_zone();
2490         // If not in java code, return and hope for the best.
2491         return in_java
2492             ? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
2493             :  EXCEPTION_CONTINUE_EXECUTION;
2494       } else {
2495         // Fatal red zone violation.
2496         thread->disable_stack_red_zone();
2497         tty->print_raw_cr("An unrecoverable stack overflow has occurred.");
2498 #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2499         report_error(t, exception_code, pc, exception_record,
2500                       exceptionInfo->ContextRecord);
2501 #endif
2502         return EXCEPTION_CONTINUE_SEARCH;
2503       }
2504     } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2505       if (in_java) {
2506         // Either stack overflow or null pointer exception.
2507         address addr = (address) exception_record->ExceptionInformation[1];
2508         address stack_end = thread->stack_end();
2509         if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {
2510           // Stack overflow.
2511           assert(!os::uses_stack_guard_pages(),
2512                  "should be caught by red zone code above.");
2513           return Handle_Exception(exceptionInfo,
2514                                   SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
2515         }
2516         // Check for safepoint polling and implicit null
2517         // We only expect null pointers in the stubs (vtable)
2518         // the rest are checked explicitly now.
2519         CodeBlob* cb = CodeCache::find_blob(pc);
2520         if (cb != NULL) {
2521           if (SafepointMechanism::is_poll_address(addr)) {


2526 #ifdef _WIN64
2527         // If it's a legal stack address map the entire region in
2528         if (thread->is_in_usable_stack(addr)) {
2529           addr = (address)((uintptr_t)addr &
2530                             (~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
2531           os::commit_memory((char *)addr, thread->stack_base() - addr,
2532                             !ExecMem);
2533           return EXCEPTION_CONTINUE_EXECUTION;
2534         }
2535 #endif
2536         // Null pointer exception.
2537         if (MacroAssembler::uses_implicit_null_check((void*)addr)) {
2538           address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
2539           if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
2540         }
2541         report_error(t, exception_code, pc, exception_record,
2542                       exceptionInfo->ContextRecord);
2543         return EXCEPTION_CONTINUE_SEARCH;
2544       }
2545 
2546 #ifdef _M_ARM64
2547       // Unsafe memory access
2548       CompiledMethod* nm = NULL;
2549       JavaThread* thread = (JavaThread*)t;
2550       if (in_java) {
2551         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
2552         nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
2553       }
2554 
2555       bool is_unsafe_arraycopy = (in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);
2556       if (is_unsafe_arraycopy ||
2557           ((in_vm || in_native) && thread->doing_unsafe_access()) ||
2558           (nm != NULL && nm->has_unsafe_access())) {
2559         address next_pc =  Assembler::locate_next_instruction(pc);
2560         if (is_unsafe_arraycopy) {
2561           next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
2562         }
2563         return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
2564       }
2565 #endif
2566 
2567 #ifdef _WIN64
2568       // Special care for fast JNI field accessors.
2569       // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks
2570       // in and the heap gets shrunk before the field access.
2571       address slowcase_pc = JNI_FastGetField::find_slowcase_pc(pc);
2572       if (slowcase_pc != (address)-1) {
2573         return Handle_Exception(exceptionInfo, slowcase_pc);
2574       }
2575 #endif
2576 
2577       // Stack overflow or null pointer exception in native code.
2578 #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2579       report_error(t, exception_code, pc, exception_record,
2580                    exceptionInfo->ContextRecord);
2581 #endif
2582       return EXCEPTION_CONTINUE_SEARCH;
2583     } // /EXCEPTION_ACCESS_VIOLATION
2584     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2585 
2586     if (exception_code == EXCEPTION_IN_PAGE_ERROR) {
2587       CompiledMethod* nm = NULL;
2588       JavaThread* thread = (JavaThread*)t;
2589       if (in_java) {
2590         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
2591         nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
2592       }
2593 
2594       bool is_unsafe_arraycopy = (in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);
2595       if (((in_vm || in_native || is_unsafe_arraycopy) && thread->doing_unsafe_access()) ||
2596           (nm != NULL && nm->has_unsafe_access())) {
2597         address next_pc =  Assembler::locate_next_instruction(pc);
2598         if (is_unsafe_arraycopy) {
2599           next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
2600         }
2601         return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
2602       }
2603     }
2604 
2605 #ifdef _M_ARM64
2606     if (in_java &&
2607         (exception_code == EXCEPTION_ILLEGAL_INSTRUCTION ||
2608           exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) {
2609       if (nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) {
2610         if (TraceTraps) {
2611           tty->print_cr("trap: zombie_not_entrant");
2612         }
2613         return Handle_Exception(exceptionInfo, SharedRuntime::get_handle_wrong_method_stub());
2614       }
2615     }
2616 #endif
2617 
2618     if (in_java) {
2619       switch (exception_code) {
2620       case EXCEPTION_INT_DIVIDE_BY_ZERO:
2621         return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
2622 
2623       case EXCEPTION_INT_OVERFLOW:
2624         return Handle_IDiv_Exception(exceptionInfo);
2625 
2626       } // switch
2627     }
2628 
2629 #if defined(_M_AMD64) || defined(_M_IX86)
2630     if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) {
2631       LONG result=Handle_FLT_Exception(exceptionInfo);
2632       if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
2633     }
2634 #endif
2635   }
2636 
2637 #if !defined(USE_VECTORED_EXCEPTION_HANDLING)
2638   if (exception_code != EXCEPTION_BREAKPOINT) {
2639     report_error(t, exception_code, pc, exception_record,
2640                  exceptionInfo->ContextRecord);
2641   }
2642 #endif
2643   return EXCEPTION_CONTINUE_SEARCH;
2644 }
2645 
2646 #if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT
2647 LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2648   PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
2649 #if defined(_M_ARM64)
2650   address pc = (address) exceptionInfo->ContextRecord->Pc;
2651 #elif defined(_M_AMD64)
2652   address pc = (address) exceptionInfo->ContextRecord->Rip;
2653 #else
2654   address pc = (address) exceptionInfo->ContextRecord->Eip;
2655 #endif
2656 
2657   // Fast path for code part of the code cache
2658   if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) {
2659     return topLevelExceptionFilter(exceptionInfo);
2660   }
2661 
2662   // Handle the case where we get an implicit exception in AOT generated
2663   // code.  AOT DLL's loaded are not registered for structured exceptions.
2664   // If the exception occurred in the codeCache or AOT code, pass control
2665   // to our normal exception handler.
2666   CodeBlob* cb = CodeCache::find_blob(pc);
2667   if (cb != NULL) {
2668     return topLevelExceptionFilter(exceptionInfo);
2669   }
2670 
2671   return EXCEPTION_CONTINUE_SEARCH;
2672 }
2673 #endif
2674 
2675 #if defined(USE_VECTORED_EXCEPTION_HANDLING)
2676 LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2677   if (InterceptOSException) goto exit;
2678   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2679 #if defined(_M_ARM64)
2680   address pc = (address)exceptionInfo->ContextRecord->Pc;
2681 #elif defined(_M_AMD64)
2682   address pc = (address) exceptionInfo->ContextRecord->Rip;
2683 #else
2684   address pc = (address) exceptionInfo->ContextRecord->Eip;
2685 #endif
2686   Thread* t = Thread::current_or_null_safe();
2687 
2688   if (exception_code != EXCEPTION_BREAKPOINT) {
2689     report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2690                 exceptionInfo->ContextRecord);
2691   }
2692 exit:
2693   return previousUnhandledExceptionFilter ? previousUnhandledExceptionFilter(exceptionInfo) : EXCEPTION_CONTINUE_SEARCH;
2694 }
2695 #endif
2696 
2697 #ifndef _WIN64
2698 // Special care for fast JNI accessors.
2699 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
2700 // the heap gets shrunk before the field access.
2701 // Need to install our own structured exception handler since native code may
2702 // install its own.
2703 LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2704   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2705   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2706     address pc = (address) exceptionInfo->ContextRecord->Eip;
2707     address addr = JNI_FastGetField::find_slowcase_pc(pc);
2708     if (addr != (address)-1) {
2709       return Handle_Exception(exceptionInfo, addr);
2710     }
2711   }
2712   return EXCEPTION_CONTINUE_SEARCH;
2713 }
2714 
2715 #define DEFINE_FAST_GETFIELD(Return, Fieldname, Result)                     \


3675   }
3676 }
3677 
3678 int os::numa_get_group_id_for_address(const void* address) {
3679   return 0;
3680 }
3681 
3682 bool os::get_page_info(char *start, page_info* info) {
3683   return false;
3684 }
3685 
3686 char *os::scan_pages(char *start, char* end, page_info* page_expected,
3687                      page_info* page_found) {
3688   return end;
3689 }
3690 
3691 char* os::non_memory_address_word() {
3692   // Must never look like an address returned by reserve_memory,
3693   // even in its subfields (as defined by the CPU immediate fields,
3694   // if the CPU splits constants across multiple instructions).
3695 #ifdef _M_ARM64
3696   // AArch64 has a maximum addressable space of 48-bits
3697   return (char*)((1ull << 48) - 1);
3698 #else
3699   return (char*)-1;
3700 #endif
3701 }
3702 
3703 #define MAX_ERROR_COUNT 100
3704 #define SYS_THREAD_ERROR 0xffffffffUL
3705 
3706 void os::pd_start_thread(Thread* thread) {
3707   DWORD ret = ResumeThread(thread->osthread()->thread_handle());
3708   // Returns previous suspend state:
3709   // 0:  Thread was not suspended
3710   // 1:  Thread is running now
3711   // >1: Thread is still suspended.
3712   assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back
3713 }
3714 
3715 
3716 // Short sleep, direct OS call.
3717 //
3718 // ms = 0, means allow others (if any) to run.
3719 //
3720 void os::naked_short_sleep(jlong ms) {


3876   case VER_PLATFORM_WIN32_NT:
3877     {
3878       int os_vers = oi.dwMajorVersion * 1000 + oi.dwMinorVersion;
3879       if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER ||
3880           oi.wProductType == VER_NT_SERVER) {
3881         _is_windows_server = true;
3882       }
3883     }
3884     break;
3885   default: fatal("Unknown platform");
3886   }
3887 
3888   _default_stack_size = os::current_stack_size();
3889   assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");
3890   assert((_default_stack_size & (_vm_page_size - 1)) == 0,
3891          "stack size not a multiple of page size");
3892 
3893   initialize_performance_counter();
3894 }
3895 
3896 int os::win32::get_cacheline_size() {
3897   PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
3898   DWORD returnLength = 0;
3899 
3900   // See https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
3901 
3902   GetLogicalProcessorInformation(NULL, &returnLength);
3903   assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return from GetLogicalProcessorInformation");
3904 
3905   buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)os::malloc(returnLength, mtInternal);
3906   BOOL rc = GetLogicalProcessorInformation(buffer, &returnLength);
3907   assert(rc, "Unexpected return from GetLogicalProcessorInformation");
3908 
3909   int line_sz = -1;
3910   for (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; ptr < buffer + returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++) {
3911     switch (ptr->Relationship) {
3912     case RelationCache:
3913       // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
3914       PCACHE_DESCRIPTOR Cache = &ptr->Cache;
3915       if (Cache->Level == 1) {
3916         line_sz = Cache->LineSize;
3917       }
3918       break;
3919     }
3920   }
3921   os::free(buffer);
3922   return line_sz;
3923 }
3924 
3925 HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
3926                                       int ebuflen) {
3927   char path[MAX_PATH];
3928   DWORD size;
3929   DWORD pathLen = (DWORD)sizeof(path);
3930   HINSTANCE result = NULL;
3931 
3932   // only allow library name without path component
3933   assert(strchr(name, '\\') == NULL, "path not allowed");
3934   assert(strchr(name, ':') == NULL, "path not allowed");
3935   if (strchr(name, '\\') != NULL || strchr(name, ':') != NULL) {
3936     jio_snprintf(ebuf, ebuflen,
3937                  "Invalid parameter while calling os::win32::load_windows_dll(): cannot take path: %s", name);
3938     return NULL;
3939   }
3940 
3941   // search system directory
3942   if ((size = GetSystemDirectory(path, pathLen)) > 0) {
3943     if (size >= pathLen) {


4232 }
4233 
4234 // To install functions for atexit processing
4235 extern "C" {
4236   static void perfMemory_exit_helper() {
4237     perfMemory_exit();
4238   }
4239 }
4240 
4241 static jint initSock();
4242 
4243 // this is called _after_ the global arguments have been parsed
4244 jint os::init_2(void) {
4245 
4246   // This could be set any time but all platforms
4247   // have to set it the same so we have to mirror Solaris.
4248   DEBUG_ONLY(os::set_mutex_init_done();)
4249 
4250   // Setup Windows Exceptions
4251 
4252 #if defined(USE_VECTORED_EXCEPTION_HANDLING)
4253   topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter);
4254   previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter);
4255 #elif INCLUDE_AOT
4256   // If AOT is enabled we need to install a vectored exception handler
4257   // in order to forward implicit exceptions from code in AOT
4258   // generated DLLs.  This is necessary since these DLLs are not
4259   // registered for structured exceptions like codecache methods are.
4260   if (AOTLibrary != NULL && (UseAOT || FLAG_IS_DEFAULT(UseAOT))) {
4261     topLevelVectoredExceptionHandler = AddVectoredExceptionHandler( 1, topLevelVectoredExceptionFilter);
4262   }
4263 #endif
4264 
4265   // for debugging float code generation bugs
4266   if (ForceFloatExceptions) {
4267 #ifndef  _WIN64
4268     static long fp_control_word = 0;
4269     __asm { fstcw fp_control_word }
4270     // see Intel PPro Manual, Vol. 2, p 7-16
4271     const long precision = 0x20;
4272     const long underflow = 0x10;
4273     const long overflow  = 0x08;
4274     const long zero_div  = 0x04;
4275     const long denorm    = 0x02;


5692 
5693 int os::connect(int fd, struct sockaddr* him, socklen_t len) {
5694   return ::connect(fd, him, len);
5695 }
5696 
5697 int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
5698   return ::recv(fd, buf, (int)nBytes, flags);
5699 }
5700 
5701 int os::send(int fd, char* buf, size_t nBytes, uint flags) {
5702   return ::send(fd, buf, (int)nBytes, flags);
5703 }
5704 
5705 int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
5706   return ::send(fd, buf, (int)nBytes, flags);
5707 }
5708 
5709 // WINDOWS CONTEXT Flags for THREAD_SAMPLING
5710 #if defined(IA32)
5711   #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
5712 #elif defined(AMD64) || defined(_M_ARM64)
5713   #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
5714 #endif
5715 
5716 // returns true if thread could be suspended,
5717 // false otherwise
5718 static bool do_suspend(HANDLE* h) {
5719   if (h != NULL) {
5720     if (SuspendThread(*h) != ~0) {
5721       return true;
5722     }
5723   }
5724   return false;
5725 }
5726 
5727 // resume the thread
5728 // calling resume on an active thread is a no-op
5729 static void do_resume(HANDLE* h) {
5730   if (h != NULL) {
5731     ResumeThread(*h);
5732   }


< prev index next >