src/os/windows/vm/os_windows.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot Sdiff src/os/windows/vm

src/os/windows/vm/os_windows.cpp

Print this page




 149 
 150 bool os::getenv(const char* name, char* buffer, int len) {
 151  int result = GetEnvironmentVariable(name, buffer, len);
 152  return result > 0 && result < len;
 153 }
 154 
 155 
 156 // No setuid programs under Windows.
 157 bool os::have_special_privileges() {
 158   return false;
 159 }
 160 
 161 
 162 // This method is  a periodic task to check for misbehaving JNI applications
 163 // under CheckJNI, we can add any periodic checks here.
 164 // For Windows at the moment does nothing
 165 void os::run_periodic_checks() {
 166   return;
 167 }
 168 
 169 #ifndef _WIN64
 170 // previous UnhandledExceptionFilter, if there is one
 171 static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;
 172 
 173 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);
 174 #endif
 175 void os::init_system_properties_values() {
 176   /* sysclasspath, java_home, dll_dir */
 177   {
 178       char *home_path;
 179       char *dll_path;
 180       char *pslash;
 181       char *bin = "\\bin";
 182       char home_dir[MAX_PATH];
 183 
 184       if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {
 185           os::jvm_path(home_dir, sizeof(home_dir));
 186           // Found the full path to jvm.dll.
 187           // Now cut the path to <java_home>/jre if we can.
 188           *(strrchr(home_dir, '\\')) = '\0';  /* get rid of \jvm.dll */
 189           pslash = strrchr(home_dir, '\\');
 190           if (pslash != NULL) {
 191               *pslash = '\0';                 /* get rid of \{client|server} */
 192               pslash = strrchr(home_dir, '\\');
 193               if (pslash != NULL)
 194                   *pslash = '\0';             /* get rid of \bin */


2223   // set correct result values and continue after idiv instruction
2224   ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2225   ctx->Rax = (DWORD)min_jint;      // result
2226   ctx->Rdx = (DWORD)0;             // remainder
2227   // Continue the execution
2228 #else
2229   PCONTEXT ctx = exceptionInfo->ContextRecord;
2230   address pc = (address)ctx->Eip;
2231   assert(pc[0] == 0xF7, "not an idiv opcode");
2232   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2233   assert(ctx->Eax == min_jint, "unexpected idiv exception");
2234   // set correct result values and continue after idiv instruction
2235   ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2236   ctx->Eax = (DWORD)min_jint;      // result
2237   ctx->Edx = (DWORD)0;             // remainder
2238   // Continue the execution
2239 #endif
2240   return EXCEPTION_CONTINUE_EXECUTION;
2241 }
2242 
2243 #ifndef  _WIN64
2244 //-----------------------------------------------------------------------------
2245 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {

2246   // handle exception caused by native method modifying control word
2247   PCONTEXT ctx = exceptionInfo->ContextRecord;
2248   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2249 
2250   switch (exception_code) {
2251     case EXCEPTION_FLT_DENORMAL_OPERAND:
2252     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2253     case EXCEPTION_FLT_INEXACT_RESULT:
2254     case EXCEPTION_FLT_INVALID_OPERATION:
2255     case EXCEPTION_FLT_OVERFLOW:
2256     case EXCEPTION_FLT_STACK_CHECK:
2257     case EXCEPTION_FLT_UNDERFLOW:
2258       jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
2259       if (fp_control_word != ctx->FloatSave.ControlWord) {
2260         // Restore FPCW and mask out FLT exceptions
2261         ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;
2262         // Mask out pending FLT exceptions
2263         ctx->FloatSave.StatusWord &=  0xffffff00;
2264         return EXCEPTION_CONTINUE_EXECUTION;
2265       }
2266   }
2267 
2268   if (prev_uef_handler != NULL) {
2269     // We didn't handle this exception so pass it to the previous
2270     // UnhandledExceptionFilter.
2271     return (prev_uef_handler)(exceptionInfo);
2272   }
2273 
2274   return EXCEPTION_CONTINUE_SEARCH;
2275 }
2276 #else //_WIN64
2277 /*
2278   On Windows, the mxcsr control bits are non-volatile across calls
2279   See also CR 6192333
2280   If EXCEPTION_FLT_* happened after some native method modified
2281   mxcsr - it is not a jvm fault.
2282   However should we decide to restore of mxcsr after a faulty
2283   native method we can uncomment following code
2284       jint MxCsr = INITIAL_MXCSR;
2285         // we can't use StubRoutines::addr_mxcsr_std()
2286         // because in Win64 mxcsr is not saved there
2287       if (MxCsr != ctx->MxCsr) {
2288         ctx->MxCsr = MxCsr;
2289         return EXCEPTION_CONTINUE_EXECUTION;
2290       }

2291 
2292 */
2293 #endif //_WIN64
2294 
2295 
2296 // Fatal error reporting is single threaded so we can make this a
2297 // static and preallocated.  If it's more than MAX_PATH silently ignore
2298 // it.
2299 static char saved_error_file[MAX_PATH] = {0};
2300 
2301 void os::set_error_file(const char *logfile) {
2302   if (strlen(logfile) <= MAX_PATH) {
2303     strncpy(saved_error_file, logfile, MAX_PATH);
2304   }
2305 }
2306 
2307 static inline void report_error(Thread* t, DWORD exception_code,
2308                                 address addr, void* siginfo, void* context) {
2309   VMError err(t, exception_code, addr, siginfo, context);
2310   err.report_and_die();
2311 
2312   // If UseOsErrorReporting, this will return here and save the error file
2313   // somewhere where we can find it in the minidump.
2314 }


2623       // 2. must be a break instruction with appropriate code
2624       if((((uint64_t) pc & 0x0F) == 0) &&
2625          (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {
2626         return Handle_Exception(exceptionInfo,
2627                                 (address)SharedRuntime::get_handle_wrong_method_stub());
2628       }
2629     } // /EXCEPTION_ILLEGAL_INSTRUCTION
2630 #endif
2631 
2632 
2633     if (in_java) {
2634       switch (exception_code) {
2635       case EXCEPTION_INT_DIVIDE_BY_ZERO:
2636         return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
2637 
2638       case EXCEPTION_INT_OVERFLOW:
2639         return Handle_IDiv_Exception(exceptionInfo);
2640 
2641       } // switch
2642     }
2643 #ifndef _WIN64
2644     if (((thread->thread_state() == _thread_in_Java) ||
2645         (thread->thread_state() == _thread_in_native)) &&
2646         exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION)
2647     {
2648       LONG result=Handle_FLT_Exception(exceptionInfo);
2649       if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
2650     }
2651 #endif //_WIN64
2652   }
2653 
2654   if (exception_code != EXCEPTION_BREAKPOINT) {
2655     report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2656                  exceptionInfo->ContextRecord);
2657   }
2658   return EXCEPTION_CONTINUE_SEARCH;
2659 }
2660 
2661 #ifndef _WIN64
2662 // Special care for fast JNI accessors.
2663 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
2664 // the heap gets shrunk before the field access.
2665 // Need to install our own structured exception handler since native code may
2666 // install its own.
2667 LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2668   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2669   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2670     address pc = (address) exceptionInfo->ContextRecord->Eip;
2671     address addr = JNI_FastGetField::find_slowcase_pc(pc);




 149 
 150 bool os::getenv(const char* name, char* buffer, int len) {
 151  int result = GetEnvironmentVariable(name, buffer, len);
 152  return result > 0 && result < len;
 153 }
 154 
 155 
 156 // No setuid programs under Windows.
 157 bool os::have_special_privileges() {
 158   return false;
 159 }
 160 
 161 
 162 // This method is  a periodic task to check for misbehaving JNI applications
 163 // under CheckJNI, we can add any periodic checks here.
 164 // For Windows at the moment does nothing
 165 void os::run_periodic_checks() {
 166   return;
 167 }
 168 

 169 // previous UnhandledExceptionFilter, if there is one
 170 static LPTOP_LEVEL_EXCEPTION_FILTER prev_uef_handler = NULL;
 171 
 172 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo);

 173 void os::init_system_properties_values() {
 174   /* sysclasspath, java_home, dll_dir */
 175   {
 176       char *home_path;
 177       char *dll_path;
 178       char *pslash;
 179       char *bin = "\\bin";
 180       char home_dir[MAX_PATH];
 181 
 182       if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) {
 183           os::jvm_path(home_dir, sizeof(home_dir));
 184           // Found the full path to jvm.dll.
 185           // Now cut the path to <java_home>/jre if we can.
 186           *(strrchr(home_dir, '\\')) = '\0';  /* get rid of \jvm.dll */
 187           pslash = strrchr(home_dir, '\\');
 188           if (pslash != NULL) {
 189               *pslash = '\0';                 /* get rid of \{client|server} */
 190               pslash = strrchr(home_dir, '\\');
 191               if (pslash != NULL)
 192                   *pslash = '\0';             /* get rid of \bin */


2221   // set correct result values and continue after idiv instruction
2222   ctx->Rip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2223   ctx->Rax = (DWORD)min_jint;      // result
2224   ctx->Rdx = (DWORD)0;             // remainder
2225   // Continue the execution
2226 #else
2227   PCONTEXT ctx = exceptionInfo->ContextRecord;
2228   address pc = (address)ctx->Eip;
2229   assert(pc[0] == 0xF7, "not an idiv opcode");
2230   assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
2231   assert(ctx->Eax == min_jint, "unexpected idiv exception");
2232   // set correct result values and continue after idiv instruction
2233   ctx->Eip = (DWORD)pc + 2;        // idiv reg, reg  is 2 bytes
2234   ctx->Eax = (DWORD)min_jint;      // result
2235   ctx->Edx = (DWORD)0;             // remainder
2236   // Continue the execution
2237 #endif
2238   return EXCEPTION_CONTINUE_EXECUTION;
2239 }
2240 

2241 //-----------------------------------------------------------------------------
2242 LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2243 #ifndef  _WIN64
2244   // handle exception caused by native method modifying control word
2245   PCONTEXT ctx = exceptionInfo->ContextRecord;
2246   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2247 
2248   switch (exception_code) {
2249     case EXCEPTION_FLT_DENORMAL_OPERAND:
2250     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2251     case EXCEPTION_FLT_INEXACT_RESULT:
2252     case EXCEPTION_FLT_INVALID_OPERATION:
2253     case EXCEPTION_FLT_OVERFLOW:
2254     case EXCEPTION_FLT_STACK_CHECK:
2255     case EXCEPTION_FLT_UNDERFLOW:
2256       jint fp_control_word = (* (jint*) StubRoutines::addr_fpu_cntrl_wrd_std());
2257       if (fp_control_word != ctx->FloatSave.ControlWord) {
2258         // Restore FPCW and mask out FLT exceptions
2259         ctx->FloatSave.ControlWord = fp_control_word | 0xffffffc0;
2260         // Mask out pending FLT exceptions
2261         ctx->FloatSave.StatusWord &=  0xffffff00;
2262         return EXCEPTION_CONTINUE_EXECUTION;
2263       }
2264   }
2265 
2266   if (prev_uef_handler != NULL) {
2267     // We didn't handle this exception so pass it to the previous
2268     // UnhandledExceptionFilter.
2269     return (prev_uef_handler)(exceptionInfo);
2270   }
2271 #else // !_WIN64



2272 /*
2273   On Windows, the mxcsr control bits are non-volatile across calls
2274   See also CR 6192333
2275 */
2276    PCONTEXT ctx = exceptionInfo->ContextRecord;


2277    jint MxCsr = INITIAL_MXCSR;
2278    // we can't use StubRoutines::addr_mxcsr_std()
2279    // because in Win64 mxcsr is not saved there
2280    if (MxCsr != ctx->MxCsr) {
2281      ctx->MxCsr = MxCsr;
2282      return EXCEPTION_CONTINUE_EXECUTION;
2283    }
2284 #endif // !_WIN64
2285 
2286   return EXCEPTION_CONTINUE_SEARCH;
2287 }

2288 
2289 // Fatal error reporting is single threaded so we can make this a
2290 // static and preallocated.  If it's more than MAX_PATH silently ignore
2291 // it.
2292 static char saved_error_file[MAX_PATH] = {0};
2293 
2294 void os::set_error_file(const char *logfile) {
2295   if (strlen(logfile) <= MAX_PATH) {
2296     strncpy(saved_error_file, logfile, MAX_PATH);
2297   }
2298 }
2299 
2300 static inline void report_error(Thread* t, DWORD exception_code,
2301                                 address addr, void* siginfo, void* context) {
2302   VMError err(t, exception_code, addr, siginfo, context);
2303   err.report_and_die();
2304 
2305   // If UseOsErrorReporting, this will return here and save the error file
2306   // somewhere where we can find it in the minidump.
2307 }


2616       // 2. must be a break instruction with appropriate code
2617       if((((uint64_t) pc & 0x0F) == 0) &&
2618          (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) {
2619         return Handle_Exception(exceptionInfo,
2620                                 (address)SharedRuntime::get_handle_wrong_method_stub());
2621       }
2622     } // /EXCEPTION_ILLEGAL_INSTRUCTION
2623 #endif
2624 
2625 
2626     if (in_java) {
2627       switch (exception_code) {
2628       case EXCEPTION_INT_DIVIDE_BY_ZERO:
2629         return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO));
2630 
2631       case EXCEPTION_INT_OVERFLOW:
2632         return Handle_IDiv_Exception(exceptionInfo);
2633 
2634       } // switch
2635     }

2636     if (((thread->thread_state() == _thread_in_Java) ||
2637         (thread->thread_state() == _thread_in_native)) &&
2638         exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION)
2639     {
2640       LONG result=Handle_FLT_Exception(exceptionInfo);
2641       if (result==EXCEPTION_CONTINUE_EXECUTION) return result;
2642     }

2643   }
2644 
2645   if (exception_code != EXCEPTION_BREAKPOINT) {
2646     report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
2647                  exceptionInfo->ContextRecord);
2648   }
2649   return EXCEPTION_CONTINUE_SEARCH;
2650 }
2651 
2652 #ifndef _WIN64
2653 // Special care for fast JNI accessors.
2654 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in and
2655 // the heap gets shrunk before the field access.
2656 // Need to install our own structured exception handler since native code may
2657 // install its own.
2658 LONG WINAPI fastJNIAccessorExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
2659   DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2660   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
2661     address pc = (address) exceptionInfo->ContextRecord->Eip;
2662     address addr = JNI_FastGetField::find_slowcase_pc(pc);


src/os/windows/vm/os_windows.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File