From 3a09a052bcc67a7994677fd2a73e7afcf331a89e Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 1 Dec 2023 20:54:35 +0000 Subject: [PATCH] 8313722: JFR: Avoid unnecessary calls to Events.from(Recording) Reviewed-by: mgronlun --- test/jdk/jdk/jfr/api/event/TestExtends.java | 18 ++++++++++-------- .../gc/detailed/TestZAllocationStallEvent.java | 4 ++-- .../gc/detailed/TestZPageAllocationEvent.java | 4 ++-- .../gc/heapsummary/HeapSummaryEventAllGcs.java | 11 ++++++----- .../objectcount/ObjectCountAfterGCEvent.java | 6 +++--- .../event/oldobject/TestMetadataRetention.java | 6 +++--- .../jfr/event/runtime/TestSafepointEvents.java | 7 ++++--- .../TestSyncOnValueBasedClassEvent.java | 4 ++-- .../jdk/jfr/event/runtime/TestVMOperation.java | 4 ++-- .../jdk/jfr/startupargs/TestRetransform.java | 9 ++++++--- test/lib/jdk/test/lib/jfr/Events.java | 7 ++++++- 11 files changed, 46 insertions(+), 34 deletions(-) diff --git a/test/jdk/jdk/jfr/api/event/TestExtends.java b/test/jdk/jdk/jfr/api/event/TestExtends.java index 294edf9f162..eae47911ba0 100644 --- a/test/jdk/jdk/jfr/api/event/TestExtends.java +++ b/test/jdk/jdk/jfr/api/event/TestExtends.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ package jdk.jfr.api.event; +import java.util.List; import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.Recording; @@ -88,7 +89,8 @@ public class TestExtends { m.commit(); r.stop(); - for (RecordedEvent re : Events.fromRecording(r)) { + List events = Events.fromRecording(r); + for (RecordedEvent re : events) { System.out.println(re); } // Grandpa @@ -127,18 +129,18 @@ public class TestExtends { verifyField(meType, "hiddenField"); verifyFieldCount(meType, 11); - for (RecordedEvent re : Events.fromRecording(r)) { + for (RecordedEvent re : events) { System.out.println(re); } - RecordedEvent grandpa = findEvent(r, GrandpaEvent.class.getName()); + RecordedEvent grandpa = findEvent(events, GrandpaEvent.class.getName()); Asserts.assertEquals(grandpa.getValue("gPublicField"), 4); Asserts.assertEquals(grandpa.getValue("gProtectedField"), 3); Asserts.assertEquals(grandpa.getValue("gPrivateField"), 2); Asserts.assertEquals(grandpa.getValue("gDefaultField"), 1); Asserts.assertEquals(grandpa.getValue("hiddenField"), 4711); - RecordedEvent parent = findEvent(r, ParentEvent.class.getName()); + RecordedEvent parent = findEvent(events, ParentEvent.class.getName()); Asserts.assertEquals(parent.getValue("gPublicField"), 4); Asserts.assertEquals(parent.getValue("gProtectedField"), 3); Asserts.assertEquals(parent.getValue("gDefaultField"), 1); @@ -148,7 +150,7 @@ public class TestExtends { Asserts.assertEquals(parent.getValue("pDefaultField"), 10); Asserts.assertEquals(parent.getValue("hiddenField"), true); - RecordedEvent me = findEvent(r, MeEvent.class.getName()); + RecordedEvent me = findEvent(events, MeEvent.class.getName()); Asserts.assertEquals(me.getValue("gPublicField"), 4); Asserts.assertEquals(me.getValue("gProtectedField"), 3); Asserts.assertEquals(me.getValue("gDefaultField"), 1); @@ -162,8 +164,8 @@ public class TestExtends { Asserts.assertEquals(me.getValue("hiddenField"), "Hidden"); } - private static RecordedEvent findEvent(Recording r, String name) throws Exception { - for (RecordedEvent re : Events.fromRecording(r)) { + private static RecordedEvent findEvent(List events, String name) throws Exception { + for (RecordedEvent re : events) { if (re.getEventType().getName().equals(name)) { return re; } diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java index 2306d33b651..7e0cc111733 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public class TestZAllocationStallEvent { List events = Events.fromRecording(recording); System.out.println("Events: " + events.size()); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { Events.assertField(event, "size").atLeast(2L * 1024 * 1024); } } diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java index 910fdd80eb4..182f7b3d509 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public class TestZPageAllocationEvent { List events = Events.fromRecording(recording); System.out.println("Events: " + events.size()); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { Events.assertField(event, "size").atLeast(2L * 1024 * 1024); } } diff --git a/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java b/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java index 8946df90f81..674270b0449 100644 --- a/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java +++ b/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,10 +48,11 @@ public class HeapSummaryEventAllGcs { GCHelper.callSystemGc(5, true); recording.stop(); - if (!checkCollectors(recording, expectedYoungCollector, expectedOldCollector)) { + List allEvents = Events.fromRecording(recording); + if (!checkCollectors(allEvents, expectedYoungCollector, expectedOldCollector)) { return; } - List events = GCHelper.removeFirstAndLastGC(Events.fromRecording(recording)); + List events = GCHelper.removeFirstAndLastGC(allEvents); for (RecordedEvent event : events) { System.out.println("Event:" + event); } @@ -190,8 +191,8 @@ public class HeapSummaryEventAllGcs { Asserts.assertEquals(size, end - start, "Size mismatch"); } - private static boolean checkCollectors(Recording recording, String expectedYoung, String expectedOld) throws Exception { - for (RecordedEvent event : Events.fromRecording(recording)) { + private static boolean checkCollectors(List events, String expectedYoung, String expectedOld) throws Exception { + for (RecordedEvent event : events) { if (Events.isEventType(event, EventNames.GCConfiguration)) { final String young = Events.assertField(event, "youngCollector").notEmpty().getValue(); final String old = Events.assertField(event, "oldCollector").notEmpty().getValue(); diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java b/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java index 4646992f464..f5ee4b73a5e 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,11 +53,11 @@ public class ObjectCountAfterGCEvent { recording.stop(); System.out.println("gcName=" + gcName); - for (RecordedEvent event : Events.fromRecording(recording)) { + List events = Events.fromRecording(recording); + for (RecordedEvent event : events) { System.out.println("Event: " + event); } - List events= Events.fromRecording(recording); Optional gcEvent = events.stream() .filter(e -> isMySystemGc(e, gcName)) .findFirst(); diff --git a/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java b/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java index 82d324f5b55..b84160a0ac5 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,10 +100,10 @@ public final class TestMetadataRetention { RecordedEvent chunkRotation = findChunkRotationEvent(events); try { // Sanity check that class was unloaded - Events.hasEvent(recording, EventNames.ClassUnload); + Events.hasEvent(events, EventNames.ClassUnload); validateClassUnloadEvent(events); // Validate that metadata for old object event has survived chunk rotation - Events.hasEvent(recording, EventNames.OldObjectSample); + Events.hasEvent(events, EventNames.OldObjectSample); validateOldObjectEvent(events, chunkRotation.getStartTime()); } catch (Throwable t) { t.printStackTrace(); diff --git a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java index f590ebed898..285592bce16 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,9 +68,10 @@ public class TestSafepointEvents { try { // Verify that each event type was seen at least once + List events = Events.fromRecording(recording); for (String name : EVENT_NAMES) { boolean found = false; - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { found = event.getEventType().getName().equals(name); if (found) { break; @@ -81,7 +82,7 @@ public class TestSafepointEvents { // Collect all events grouped by safepoint id SortedMap> safepointIds = new TreeMap<>(); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { Long safepointId = event.getValue("safepointId"); if (!safepointIds.containsKey(safepointId)) { safepointIds.put(safepointId, new HashSet<>()); diff --git a/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java b/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java index 36ef4bf29bf..f20175da37f 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ public class TestSyncOnValueBasedClassEvent { List classesFound = new ArrayList(); List events = Events.fromRecording(recording); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { String className = Events.assertField(event, "valueBasedClass.name").notEmpty().getValue(); RecordedThread jt = event.getThread(); if (Thread.currentThread().getName().equals(jt.getJavaName())) { diff --git a/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java b/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java index 61ec9677df6..ae6f1f27191 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ public class TestVMOperation { List events = Events.fromRecording(recording); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { String operation = Events.assertField(event, "operation").notEmpty().getValue(); if (operation.equals(VM_OPERATION)) { Events.assertField(event, "safepoint").equal(true); diff --git a/test/jdk/jdk/jfr/startupargs/TestRetransform.java b/test/jdk/jdk/jfr/startupargs/TestRetransform.java index 6e516afe7eb..2e4067ae544 100644 --- a/test/jdk/jdk/jfr/startupargs/TestRetransform.java +++ b/test/jdk/jdk/jfr/startupargs/TestRetransform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,11 @@ package jdk.jfr.startupargs; +import java.util.List; import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; import jdk.test.lib.Asserts; import jdk.test.lib.jfr.Events; import jdk.test.lib.jfr.SimpleEvent; @@ -58,8 +60,9 @@ public class TestRetransform { if (type.isEnabled()) { Asserts.fail("Expected event to be disabled after recording stopped"); } - Events.hasEvent(r, SimpleEvent.class.getName()); - Events.hasEvent(r, TestEvent.class.getName()); + List events = Events.fromRecording(r); + Events.hasEvent(events, SimpleEvent.class.getName()); + Events.hasEvent(events, TestEvent.class.getName()); } // Classes that are loaded during a recording diff --git a/test/lib/jdk/test/lib/jfr/Events.java b/test/lib/jdk/test/lib/jfr/Events.java index e3e59798179..5a180659f9f 100644 --- a/test/lib/jdk/test/lib/jfr/Events.java +++ b/test/lib/jdk/test/lib/jfr/Events.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -271,7 +271,12 @@ public class Events { * @throws IOException if an event set could not be created due to I/O * errors. */ + private static long lastId = -1; public static List fromRecording(Recording recording) throws IOException { + if (recording.getId() == lastId) { + throw new IOException("Recording with id " + lastId + " has already been dumped. Store the results in a List instead of dumping the recording again"); + } + lastId = recording.getId(); return RecordingFile.readAllEvents(makeCopy(recording)); }