310 }
311 ~ThreadInVMfromJavaNoAsyncException() {
312 if (_thread->stack_yellow_reserved_zone_disabled()) {
313 _thread->enable_stack_yellow_reserved_zone();
314 }
315 trans(_thread_in_vm, _thread_in_Java);
316 // NOTE: We do not check for pending. async. exceptions.
317 // If we did and moved the pending async exception over into the
318 // pending exception field, we would need to deopt (currently C2
319 // only). However, to do so would require that we transition back
320 // to the _thread_in_vm state. Instead we postpone the handling of
321 // the async exception.
322
323
324 // Check for pending. suspends only.
325 if (_thread->has_special_runtime_exit_condition())
326 _thread->handle_special_runtime_exit_condition(false);
327 }
328 };
329
330 // Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.
331 // Can be used to verify properties on enter/exit of the VM.
332
333 #ifdef ASSERT
334 class VMEntryWrapper {
335 public:
336 VMEntryWrapper();
337 ~VMEntryWrapper();
338 };
339
340
341 class VMNativeEntryWrapper {
342 public:
343 VMNativeEntryWrapper() {
344 if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
345 }
346
347 ~VMNativeEntryWrapper() {
348 if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
349 }
350 };
351
352 #endif
353
354
355 // VM-internal runtime interface support
356
357 // Definitions for JRT (Java (Compiler/Shared) Runtime)
358
359 // JRT_LEAF currently can be called from either _thread_in_Java or
360 // _thread_in_native mode. In _thread_in_native, it is ok
361 // for another thread to trigger GC. The rest of the JRT_LEAF
362 // rules apply.
363 class JRTLeafVerifier : public NoSafepointVerifier {
364 static bool should_verify_GC();
365 public:
366 #ifdef ASSERT
367 JRTLeafVerifier();
368 ~JRTLeafVerifier();
369 #else
370 JRTLeafVerifier() {}
371 ~JRTLeafVerifier() {}
372 #endif
373 };
374
375 #ifdef ASSERT
376
377 class RuntimeHistogramElement : public HistogramElement {
378 public:
379 RuntimeHistogramElement(const char* name);
380 };
381
382 #define TRACE_CALL(result_type, header) \
383 InterfaceSupport::_number_of_calls++; \
384 if (CountRuntimeCalls) { \
385 static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
386 if (e != NULL) e->increment_count(); \
387 }
388 #else
389 #define TRACE_CALL(result_type, header) \
390 /* do nothing */
391 #endif
392
393
394 // LEAF routines do not lock, GC or throw exceptions
395
396 #define VM_LEAF_BASE(result_type, header) \
397 TRACE_CALL(result_type, header) \
398 debug_only(NoHandleMark __hm;) \
399 os::verify_stack_alignment(); \
400 /* begin of body */
401
402 #define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \
403 TRACE_CALL(result_type, header) \
404 debug_only(ResetNoHandleMark __rnhm;) \
405 HandleMarkCleaner __hm(thread); \
406 Thread* THREAD = thread; \
407 os::verify_stack_alignment(); \
408 /* begin of body */
409
410
411 // ENTRY routines may lock, GC and throw exceptions
417 os::verify_stack_alignment(); \
418 /* begin of body */
419
420
421 // QUICK_ENTRY routines behave like ENTRY but without a handle mark
422
423 #define VM_QUICK_ENTRY_BASE(result_type, header, thread) \
424 TRACE_CALL(result_type, header) \
425 debug_only(NoHandleMark __hm;) \
426 Thread* THREAD = thread; \
427 os::verify_stack_alignment(); \
428 /* begin of body */
429
430
431 #define JRT_ENTRY(result_type, header) \
432 result_type header { \
433 ThreadInVMfromJava __tiv(thread); \
434 VM_ENTRY_BASE(result_type, header, thread) \
435 debug_only(VMEntryWrapper __vew;)
436
437
438 #define JRT_LEAF(result_type, header) \
439 result_type header { \
440 VM_LEAF_BASE(result_type, header) \
441 debug_only(JRTLeafVerifier __jlv;)
442
443
444 #define JRT_ENTRY_NO_ASYNC(result_type, header) \
445 result_type header { \
446 ThreadInVMfromJavaNoAsyncException __tiv(thread); \
447 VM_ENTRY_BASE(result_type, header, thread) \
448 debug_only(VMEntryWrapper __vew;)
449
450 // Same as JRT Entry but allows for return value after the safepoint
451 // to get back into Java from the VM
452 #define JRT_BLOCK_ENTRY(result_type, header) \
453 result_type header { \
454 TRACE_CALL(result_type, header) \
455 HandleMarkCleaner __hm(thread);
456
457 #define JRT_BLOCK \
458 { \
459 ThreadInVMfromJava __tiv(thread); \
460 Thread* THREAD = thread; \
461 debug_only(VMEntryWrapper __vew;)
|
310 }
311 ~ThreadInVMfromJavaNoAsyncException() {
312 if (_thread->stack_yellow_reserved_zone_disabled()) {
313 _thread->enable_stack_yellow_reserved_zone();
314 }
315 trans(_thread_in_vm, _thread_in_Java);
316 // NOTE: We do not check for pending. async. exceptions.
317 // If we did and moved the pending async exception over into the
318 // pending exception field, we would need to deopt (currently C2
319 // only). However, to do so would require that we transition back
320 // to the _thread_in_vm state. Instead we postpone the handling of
321 // the async exception.
322
323
324 // Check for pending. suspends only.
325 if (_thread->has_special_runtime_exit_condition())
326 _thread->handle_special_runtime_exit_condition(false);
327 }
328 };
329
330 // Debug class instantiated in JRT_ENTRY macro.
331 // Can be used to verify properties on enter/exit of the VM.
332
333 #ifdef ASSERT
334 class VMEntryWrapper {
335 public:
336 VMEntryWrapper();
337 ~VMEntryWrapper();
338 };
339
340
341 class VMNativeEntryWrapper {
342 public:
343 VMNativeEntryWrapper();
344 ~VMNativeEntryWrapper();
345 };
346
347 class RuntimeHistogramElement : public HistogramElement {
348 public:
349 RuntimeHistogramElement(const char* name);
350 };
351 #endif // ASSERT
352
353 #ifdef ASSERT
354 #define TRACE_CALL(result_type, header) \
355 InterfaceSupport::_number_of_calls++; \
356 if (CountRuntimeCalls) { \
357 static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
358 if (e != NULL) e->increment_count(); \
359 }
360 #else
361 #define TRACE_CALL(result_type, header) \
362 /* do nothing */
363 #endif // ASSERT
364
365
366 // LEAF routines do not lock, GC or throw exceptions
367
368 #define VM_LEAF_BASE(result_type, header) \
369 TRACE_CALL(result_type, header) \
370 debug_only(NoHandleMark __hm;) \
371 os::verify_stack_alignment(); \
372 /* begin of body */
373
374 #define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \
375 TRACE_CALL(result_type, header) \
376 debug_only(ResetNoHandleMark __rnhm;) \
377 HandleMarkCleaner __hm(thread); \
378 Thread* THREAD = thread; \
379 os::verify_stack_alignment(); \
380 /* begin of body */
381
382
383 // ENTRY routines may lock, GC and throw exceptions
389 os::verify_stack_alignment(); \
390 /* begin of body */
391
392
393 // QUICK_ENTRY routines behave like ENTRY but without a handle mark
394
395 #define VM_QUICK_ENTRY_BASE(result_type, header, thread) \
396 TRACE_CALL(result_type, header) \
397 debug_only(NoHandleMark __hm;) \
398 Thread* THREAD = thread; \
399 os::verify_stack_alignment(); \
400 /* begin of body */
401
402
403 #define JRT_ENTRY(result_type, header) \
404 result_type header { \
405 ThreadInVMfromJava __tiv(thread); \
406 VM_ENTRY_BASE(result_type, header, thread) \
407 debug_only(VMEntryWrapper __vew;)
408
409 // JRT_LEAF currently can be called from either _thread_in_Java or
410 // _thread_in_native mode.
411 //
412 // JRT_LEAF rules:
413 // A JRT_LEAF method may not interfere with safepointing by
414 // 1) acquiring or blocking on a Mutex or JavaLock - checked
415 // 2) allocating heap memory - checked
416 // 3) executing a VM operation - checked
417 // 4) executing a system call (including malloc) that could block or grab a lock
418 // 5) invoking GC
419 // 6) reaching a safepoint
420 // 7) running too long
421 // Nor may any method it calls.
422
423 #define JRT_LEAF(result_type, header) \
424 result_type header { \
425 VM_LEAF_BASE(result_type, header) \
426 debug_only(NoSafepointVerifier __nsv;)
427
428
429 #define JRT_ENTRY_NO_ASYNC(result_type, header) \
430 result_type header { \
431 ThreadInVMfromJavaNoAsyncException __tiv(thread); \
432 VM_ENTRY_BASE(result_type, header, thread) \
433 debug_only(VMEntryWrapper __vew;)
434
435 // Same as JRT Entry but allows for return value after the safepoint
436 // to get back into Java from the VM
437 #define JRT_BLOCK_ENTRY(result_type, header) \
438 result_type header { \
439 TRACE_CALL(result_type, header) \
440 HandleMarkCleaner __hm(thread);
441
442 #define JRT_BLOCK \
443 { \
444 ThreadInVMfromJava __tiv(thread); \
445 Thread* THREAD = thread; \
446 debug_only(VMEntryWrapper __vew;)
|