RFR(10)(XS): JDK-8171365: nsk/jvmti/scenarios/events/EM04/em04t001: many errors for missed events
Ioi Lam
ioi.lam at oracle.com
Mon Jun 5 15:56:34 UTC 2017
Hi Chris,
On 6/2/17 11:54 AM, Chris Plummer wrote:
> Hello,
>
> [I'd like a compiler team member to comment on this, in addition to
> runtime or svc]
>
> Please review the following:
>
> https://bugs.openjdk.java.net/browse/JDK-8171365
> http://cr.openjdk.java.net/~cjplummer/8171365/webrev.00/
>
> The CR is closed, so I'll describe the issue here:
>
> The test is making sure that all |JVMTI_EVENT_DYNAMIC_CODE_GENERATED|
> events that occur during the agent's OnLoad phase also occur when
> later GenerateEvents() is called. GenerateEvents() is generating some
> of the events, but most are not sent. The problem is
> CodeCache::blobs_do() is only iterating over NMethod code heaps, not
> all of the code heaps, so many code blobs are missed. I changed it to
> iterate over all the code heaps, and now all the
> |JVMTI_EVENT_DYNAMIC_CODE_GENERATED|events are sent.
>
> Note there is another version of CodeCache::blobs_do() that takes a
> closure object instead of a function pointer. It is used by GC and I
> assume is working properly by only iterating over NMethod code heaps,
> so I did not change it. The version that takes a function pointer is
> only used by JVMTI for implementing GenerateEvents(), so this change
> should not impact any other part of the VM. However, I do wonder if
> these blobs_do() methods should be renamed to avoid confusion since
> they don't (and haven't in the past) iterated over the same set of
> code blobs.
>
Yes, I think these two function would indeed be confusing. The second
variant also does a liveness check which is missing from the first one:
621 void CodeCache::blobs_do(void f(CodeBlob* nm)) {
622 assert_locked_or_safepoint(CodeCache_lock);
623 FOR_ALL_HEAPS(heap) {
624 FOR_ALL_BLOBS(cb, *heap) {
625 f(cb);
626 }
627 }
628 }
664 void CodeCache::blobs_do(CodeBlobClosure* f) {
665 assert_locked_or_safepoint(CodeCache_lock);
666 FOR_ALL_NMETHOD_HEAPS(heap) {
667 FOR_ALL_BLOBS(cb, *heap) {
668 if (cb->is_alive()) {
669 f->do_code_blob(cb);
670 #ifdef ASSERT
671 if (cb->is_nmethod())
672 ((nmethod*)cb)->verify_scavenge_root_oops();
673 #endif //ASSERT
674 }
675 }
676 }
677 }
The two function's APIs are equivalent, since CodeBlobClosure has a
single function, so I think it's better to stick with one API, i.e.
replace the function pointer with CodeBlobClosure
class CodeBlobClosure : public Closure {
public:
// Called for each code blob.
virtual void do_code_blob(CodeBlob* cb) = 0;
};
For consistency, maybe we should change the first version to
CodeCache::all_blobs_do(CodeBlobClosure* f)
and the second to
CodeCache::live_nmethod_blobs_do(CodeBlobClosure* f)
Thanks
- Ioi
> thanks,
>
> Chris
>
> https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#DynamicCodeGenerated
>
More information about the hotspot-dev
mailing list