|
1 | 1 | /* |
2 | | - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
@@ -534,6 +534,62 @@ synthesizeUnloadEvent(void *signatureVoid, void *envVoid) |
534 | 534 | /* Garbage Collection Happened */ |
535 | 535 | static unsigned int garbageCollected = 0; |
536 | 536 |
|
| 537 | +/* |
| 538 | + * Run the event through each HandlerNode's filter, and if it passes, call the HandlerNode's |
| 539 | + * HandlerFunction for the event, and then report all accumulated events to the debugger. |
| 540 | + */ |
| 541 | +static void |
| 542 | +filterAndHandleEvent(JNIEnv *env, EventInfo *evinfo, EventIndex ei, |
| 543 | + struct bag *eventBag, jbyte eventSessionID) |
| 544 | +{ |
| 545 | + debugMonitorEnter(handlerLock); |
| 546 | + { |
| 547 | + HandlerNode *node; |
| 548 | + char *classname; |
| 549 | + |
| 550 | + /* We must keep track of all classes prepared to know what's unloaded */ |
| 551 | + if (evinfo->ei == EI_CLASS_PREPARE) { |
| 552 | + classTrack_addPreparedClass(env, evinfo->clazz); |
| 553 | + } |
| 554 | + |
| 555 | + node = getHandlerChain(ei)->first; |
| 556 | + classname = getClassname(evinfo->clazz); |
| 557 | + |
| 558 | + /* Filter the event over each handler node. */ |
| 559 | + while (node != NULL) { |
| 560 | + /* Save next so handlers can remove themselves. */ |
| 561 | + HandlerNode *next = NEXT(node); |
| 562 | + jboolean shouldDelete; |
| 563 | + |
| 564 | + if (eventFilterRestricted_passesFilter(env, classname, |
| 565 | + evinfo, node, |
| 566 | + &shouldDelete)) { |
| 567 | + HandlerFunction func = HANDLER_FUNCTION(node); |
| 568 | + if (func == NULL) { |
| 569 | + EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL"); |
| 570 | + } |
| 571 | + /* Handle the event by calling the event handler. */ |
| 572 | + (*func)(env, evinfo, node, eventBag); |
| 573 | + } |
| 574 | + if (shouldDelete) { |
| 575 | + /* We can safely free the node now that we are done using it. */ |
| 576 | + (void)freeHandler(node); |
| 577 | + } |
| 578 | + node = next; |
| 579 | + } |
| 580 | + jvmtiDeallocate(classname); |
| 581 | + } |
| 582 | + debugMonitorExit(handlerLock); |
| 583 | + |
| 584 | + /* |
| 585 | + * The events destined for the debugger were accumulated in eventBag. Report all these events. |
| 586 | + */ |
| 587 | + if (eventBag != NULL) { |
| 588 | + reportEvents(env, eventSessionID, evinfo->thread, evinfo->ei, |
| 589 | + evinfo->clazz, evinfo->method, evinfo->location, eventBag); |
| 590 | + } |
| 591 | +} |
| 592 | + |
537 | 593 | /* |
538 | 594 | * The JVMTI generic event callback. Each event is passed to a sequence of |
539 | 595 | * handlers in a chain until the chain ends or one handler |
@@ -634,51 +690,7 @@ event_callback(JNIEnv *env, EventInfo *evinfo) |
634 | 690 | } |
635 | 691 | } |
636 | 692 |
|
637 | | - debugMonitorEnter(handlerLock); |
638 | | - { |
639 | | - HandlerNode *node; |
640 | | - char *classname; |
641 | | - |
642 | | - /* We must keep track of all classes prepared to know what's unloaded */ |
643 | | - if (evinfo->ei == EI_CLASS_PREPARE) { |
644 | | - classTrack_addPreparedClass(env, evinfo->clazz); |
645 | | - } |
646 | | - |
647 | | - node = getHandlerChain(evinfo->ei)->first; |
648 | | - classname = getClassname(evinfo->clazz); |
649 | | - |
650 | | - while (node != NULL) { |
651 | | - /* save next so handlers can remove themselves */ |
652 | | - HandlerNode *next = NEXT(node); |
653 | | - jboolean shouldDelete; |
654 | | - |
655 | | - if (eventFilterRestricted_passesFilter(env, classname, |
656 | | - evinfo, node, |
657 | | - &shouldDelete)) { |
658 | | - HandlerFunction func; |
659 | | - |
660 | | - func = HANDLER_FUNCTION(node); |
661 | | - if ( func == NULL ) { |
662 | | - EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL"); |
663 | | - } |
664 | | - (*func)(env, evinfo, node, eventBag); |
665 | | - } |
666 | | - if (shouldDelete) { |
667 | | - /* We can safely free the node now that we are done |
668 | | - * using it. |
669 | | - */ |
670 | | - (void)freeHandler(node); |
671 | | - } |
672 | | - node = next; |
673 | | - } |
674 | | - jvmtiDeallocate(classname); |
675 | | - } |
676 | | - debugMonitorExit(handlerLock); |
677 | | - |
678 | | - if (eventBag != NULL) { |
679 | | - reportEvents(env, eventSessionID, thread, evinfo->ei, |
680 | | - evinfo->clazz, evinfo->method, evinfo->location, eventBag); |
681 | | - } |
| 693 | + filterAndHandleEvent(env, evinfo, ei, eventBag, eventSessionID); |
682 | 694 |
|
683 | 695 | /* we are continuing after VMDeathEvent - now we are dead */ |
684 | 696 | if (evinfo->ei == EI_VM_DEATH) { |
|
0 commit comments