418 |
418 |
419 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo); |
419 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo); |
420 |
420 |
421 // Thread start routine for all newly created threads |
421 // Thread start routine for all newly created threads |
422 static unsigned __stdcall thread_native_entry(Thread* thread) { |
422 static unsigned __stdcall thread_native_entry(Thread* thread) { |
|
423 |
|
424 thread->record_stack_base_and_size(); |
|
425 |
423 // Try to randomize the cache line index of hot stack frames. |
426 // Try to randomize the cache line index of hot stack frames. |
424 // This helps when threads of the same stack traces evict each other's |
427 // This helps when threads of the same stack traces evict each other's |
425 // cache lines. The threads can be either from the same JVM instance, or |
428 // cache lines. The threads can be either from the same JVM instance, or |
426 // from different JVM instances. The benefit is especially true for |
429 // from different JVM instances. The benefit is especially true for |
427 // processors with hyperthreading technology. |
430 // processors with hyperthreading technology. |
451 |
454 |
452 // Install a win32 structured exception handler around every thread created |
455 // Install a win32 structured exception handler around every thread created |
453 // by VM, so VM can generate error dump when an exception occurred in non- |
456 // by VM, so VM can generate error dump when an exception occurred in non- |
454 // Java thread (e.g. VM thread). |
457 // Java thread (e.g. VM thread). |
455 __try { |
458 __try { |
456 thread->run(); |
459 thread->call_run(); |
457 } __except(topLevelExceptionFilter( |
460 } __except(topLevelExceptionFilter( |
458 (_EXCEPTION_POINTERS*)_exception_info())) { |
461 (_EXCEPTION_POINTERS*)_exception_info())) { |
459 // Nothing to do. |
462 // Nothing to do. |
460 } |
463 } |
|
464 |
|
465 // Note: at this point the thread object may already have deleted itself. |
|
466 // Do not dereference it from here on out. |
461 |
467 |
462 log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); |
468 log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); |
463 |
469 |
464 // One less thread is executing |
470 // One less thread is executing |
465 // When the VMThread gets here, the main thread may have already exited |
471 // When the VMThread gets here, the main thread may have already exited |
466 // which frees the CodeHeap containing the Atomic::add code |
472 // which frees the CodeHeap containing the Atomic::add code |
467 if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) { |
473 if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) { |
468 Atomic::dec(&os::win32::_os_thread_count); |
474 Atomic::dec(&os::win32::_os_thread_count); |
469 } |
|
470 |
|
471 // If a thread has not deleted itself ("delete this") as part of its |
|
472 // termination sequence, we have to ensure thread-local-storage is |
|
473 // cleared before we actually terminate. No threads should ever be |
|
474 // deleted asynchronously with respect to their termination. |
|
475 if (Thread::current_or_null_safe() != NULL) { |
|
476 assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); |
|
477 thread->clear_thread_current(); |
|
478 } |
475 } |
479 |
476 |
480 // Thread must not return from exit_process_or_thread(), but if it does, |
477 // Thread must not return from exit_process_or_thread(), but if it does, |
481 // let it proceed to exit normally |
478 // let it proceed to exit normally |
482 return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res); |
479 return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res); |