From mgronlun at openjdk.java.net Sun Mar 6 13:29:25 2022 From: mgronlun at openjdk.java.net (Markus =?UTF-8?B?R3LDtm5sdW5k?=) Date: Sun, 6 Mar 2022 13:29:25 GMT Subject: RFR: 8276333: jdk/jfr/event/oldobject/TestLargeRootSet.java failed "assert(!contains(edge->reference())) failed: invariant" Message-ID: Greetings, This is a specific issue related to how the DFSClosure process roots. It traverses roots twice to avoid going sideways. To prevent premature termination during the second pass, a marker, "_ignore_root_set", is set to signal they have already been processed. It lets the recursion continue, but there is a problem with how the code is laid out. It skips the "is_marked" check, but it does not skip add_chain(). If the reference is a stack root, and the pointee is a leak sample candidate, it attempts to construct the reference chain twice. The assertion fires because a reference is only to be added once. It also includes stronger asserts to give more information for related issue tracked in [JDK-8282067](https://bugs.openjdk.java.net/browse/JDK-8282067) . Testing: jdk_jfr Thanks Markus ------------- Commit messages: - 8276333 Changes: https://git.openjdk.java.net/jdk/pull/7715/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7715&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8276333 Stats: 32 lines in 3 files changed: 19 ins; 10 del; 3 mod Patch: https://git.openjdk.java.net/jdk/pull/7715.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/7715/head:pull/7715 PR: https://git.openjdk.java.net/jdk/pull/7715 From egahlin at openjdk.java.net Mon Mar 7 15:29:03 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Mon, 7 Mar 2022 15:29:03 GMT Subject: RFR: 8276333: jdk/jfr/event/oldobject/TestLargeRootSet.java failed "assert(!contains(edge->reference())) failed: invariant" In-Reply-To: References: Message-ID: On Sun, 6 Mar 2022 13:23:01 GMT, Markus Gr?nlund wrote: > Greetings, > > This is a specific issue related to how the DFSClosure process roots. > > It traverses roots twice to avoid going sideways. To prevent premature termination during the second pass, a marker, "_ignore_root_set", is set to signal they have already been processed. It lets the recursion continue, but there is a problem with how the code is laid out. It skips the "is_marked" check, but it does not skip add_chain(). If the reference is a stack root, and the pointee is a leak sample candidate, it attempts to construct the reference chain twice. The assertion fires because a reference is only to be added once. > > It also includes stronger asserts to give more information for related issue tracked in [JDK-8282067](https://bugs.openjdk.java.net/browse/JDK-8282067) . > > Testing: jdk_jfr > > Thanks > Markus Marked as reviewed by egahlin (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/7715 From mgronlun at openjdk.java.net Tue Mar 8 09:32:03 2022 From: mgronlun at openjdk.java.net (Markus =?UTF-8?B?R3LDtm5sdW5k?=) Date: Tue, 8 Mar 2022 09:32:03 GMT Subject: Integrated: 8276333: jdk/jfr/event/oldobject/TestLargeRootSet.java failed "assert(!contains(edge->reference())) failed: invariant" In-Reply-To: References: Message-ID: On Sun, 6 Mar 2022 13:23:01 GMT, Markus Gr?nlund wrote: > Greetings, > > This is a specific issue related to how the DFSClosure process roots. > > It traverses roots twice to avoid going sideways. To prevent premature termination during the second pass, a marker, "_ignore_root_set", is set to signal they have already been processed. It lets the recursion continue, but there is a problem with how the code is laid out. It skips the "is_marked" check, but it does not skip add_chain(). If the reference is a stack root, and the pointee is a leak sample candidate, it attempts to construct the reference chain twice. The assertion fires because a reference is only to be added once. > > It also includes stronger asserts to give more information for related issue tracked in [JDK-8282067](https://bugs.openjdk.java.net/browse/JDK-8282067) . > > Testing: jdk_jfr > > Thanks > Markus This pull request has now been integrated. Changeset: 65ca0a57 Author: Markus Gr?nlund URL: https://git.openjdk.java.net/jdk/commit/65ca0a5776df229ee91f420585ca1e8f91e489c6 Stats: 32 lines in 3 files changed: 19 ins; 10 del; 3 mod 8276333: jdk/jfr/event/oldobject/TestLargeRootSet.java failed "assert(!contains(edge->reference())) failed: invariant" Reviewed-by: egahlin ------------- PR: https://git.openjdk.java.net/jdk/pull/7715 From cstein at openjdk.java.net Tue Mar 8 16:15:40 2022 From: cstein at openjdk.java.net (Christian Stein) Date: Tue, 8 Mar 2022 16:15:40 GMT Subject: RFR: JDK-8282811: Typo in IAE details message of `RecordedObject.getValueDescriptor` Message-ID: Remove superfluous `"` from the beginning of the illegal argument exception's details message. https://bugs.openjdk.java.net/browse/JDK-8282811 ------------- Commit messages: - Remove superfluous `\"` from details message Changes: https://git.openjdk.java.net/jdk/pull/7745/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7745&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8282811 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/7745.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/7745/head:pull/7745 PR: https://git.openjdk.java.net/jdk/pull/7745 From egahlin at openjdk.java.net Wed Mar 9 15:42:07 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Wed, 9 Mar 2022 15:42:07 GMT Subject: RFR: JDK-8282811: Typo in IAE details message of `RecordedObject.getValueDescriptor` In-Reply-To: References: Message-ID: <23iTiYam4WqTata_lR9zvJm_tMPtovh1sPc-o_r1rdU=.fb7042a1-3e04-4e4c-b129-80fd75db6290@github.com> On Tue, 8 Mar 2022 16:07:51 GMT, Christian Stein wrote: > Remove superfluous `"` from the beginning of the illegal argument exception's details message. > > https://bugs.openjdk.java.net/browse/JDK-8282811 Looks good. Have you run tests in test/jdk/jdk/jfr? ------------- Marked as reviewed by egahlin (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/7745 From cstein at openjdk.java.net Fri Mar 11 10:01:47 2022 From: cstein at openjdk.java.net (Christian Stein) Date: Fri, 11 Mar 2022 10:01:47 GMT Subject: Integrated: JDK-8282811: Typo in IAE details message of `RecordedObject.getValueDescriptor` In-Reply-To: References: Message-ID: On Tue, 8 Mar 2022 16:07:51 GMT, Christian Stein wrote: > Remove superfluous `"` from the beginning of the illegal argument exception's details message. > > https://bugs.openjdk.java.net/browse/JDK-8282811 This pull request has now been integrated. Changeset: f99193ae Author: Christian Stein Committer: Erik Gahlin URL: https://git.openjdk.java.net/jdk/commit/f99193ae3fe8b7bcba34a451890da37cab5ebffb Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod 8282811: Typo in IAE details message of `RecordedObject.getValueDescriptor` Reviewed-by: egahlin ------------- PR: https://git.openjdk.java.net/jdk/pull/7745 From egahlin at openjdk.java.net Wed Mar 16 23:15:03 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Wed, 16 Mar 2022 23:15:03 GMT Subject: RFR: 8283289 JFR: Rename CheckPoint Message-ID: Hi, Could I have a review of a fix that renames "CheckPoint" to "checkpoint". The only visible effect of the change is in the 'jfr summary' command where it now displays "jdk.Checkpoint". Testing: jdk/jdk/jfr Thanks Erik ------------- Commit messages: - Initial Changes: https://git.openjdk.java.net/jdk/pull/7847/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7847&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8283289 Stats: 35 lines in 6 files changed: 0 ins; 0 del; 35 mod Patch: https://git.openjdk.java.net/jdk/pull/7847.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/7847/head:pull/7847 PR: https://git.openjdk.java.net/jdk/pull/7847 From egahlin at openjdk.java.net Wed Mar 16 23:15:07 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Wed, 16 Mar 2022 23:15:07 GMT Subject: RFR: 8283202: Potential off-read when checking JFR's status in awaitFinished Message-ID: Hi, Could I have a review of a fix that prevents the JFR parser to read passed the file state byte in the chunk header. Testing: jdk/jdk/jfr Thanks Erik ------------- Commit messages: - Initial Changes: https://git.openjdk.java.net/jdk/pull/7845/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7845&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8283202 Stats: 19 lines in 1 file changed: 10 ins; 6 del; 3 mod Patch: https://git.openjdk.java.net/jdk/pull/7845.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/7845/head:pull/7845 PR: https://git.openjdk.java.net/jdk/pull/7845 From mgronlun at openjdk.java.net Thu Mar 17 09:22:36 2022 From: mgronlun at openjdk.java.net (Markus =?UTF-8?B?R3LDtm5sdW5k?=) Date: Thu, 17 Mar 2022 09:22:36 GMT Subject: RFR: 8283289 JFR: Rename CheckPoint In-Reply-To: References: Message-ID: <8N-yLJB1r_OjxAlBCfQBSPhxTQmXmAgh2rGwPm_q3-Q=.e6be5584-5b26-47c1-b760-42654daa7d37@github.com> On Wed, 16 Mar 2022 21:44:03 GMT, Erik Gahlin wrote: > Hi, > > Could I have a review of a fix that renames "CheckPoint" to "checkpoint". The only visible effect of the change is in the 'jfr summary' command where it now displays "jdk.Checkpoint". > > Testing: jdk/jdk/jfr > > Thanks > Erik Marked as reviewed by mgronlun (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/7847 From mgronlun at openjdk.java.net Thu Mar 17 09:33:33 2022 From: mgronlun at openjdk.java.net (Markus =?UTF-8?B?R3LDtm5sdW5k?=) Date: Thu, 17 Mar 2022 09:33:33 GMT Subject: RFR: 8283202: Potential off-read when checking JFR's status in awaitFinished In-Reply-To: References: Message-ID: On Wed, 16 Mar 2022 19:30:54 GMT, Erik Gahlin wrote: > Hi, > > Could I have a review of a fix that prevents the JFR parser to read passed the file state byte in the chunk header. > > Testing: jdk/jdk/jfr > > Thanks > Erik Marked as reviewed by mgronlun (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/7845 From johannes.bechberger at sap.com Fri Mar 18 09:43:58 2022 From: johannes.bechberger at sap.com (Bechberger, Johannes) Date: Fri, 18 Mar 2022 09:43:58 +0000 Subject: Proposal of a new version of AsyncGetCallTrace Message-ID: Hi, I would like propose to 1. Replace duplicated stack walking code with unified API 2. Create a new version of AsyncGetCallTrace, tentatively called "AsyncGetCallTrace2", with more information on more frames using the unified API A demo (as well as this text) is available at https://github.com/parttimenerd/asgct2-demo if you want to see a prototype of this proposal in action. Unify Stack Walking ================ There are currently multiple implementations of stack walking in JFR and for AsyncGetCallTrace. They each implement their own extension of vframeStream but with comparable features and check for problematic frames. My proposal is, therefore, to replace the stack walking code with a unified API that includes all error checking and vframeStream extensions in a single place. The prosposed new class is called StackWalker and could be part of `jfr/recorder/stacktrace` [1]. This class also supports getting information on C frames so it can be potentially used for walking stacks in VMError (used to create hs_err files), further reducing the amount of different stack walking code. AsyncGetCallTrace2 ================ The AsyncGetCallTrace call has seen increasing use in recent years in profilers like async-profiler. But it is not really an API (not exported in any header) and the information on frames it returns is pretty limited (only the method and bci for Java frames) which makes implementing profilers and other tooling harder. Tools like async-profiler have to resort to complicated code to partially obtain the information that the JVM already has. Information that is currently hidden and impossible to obtain is - whether a compiled frame is inlined (currently only obtainable for the topmost compiled frames) - although this can be obtained using JFR - C frames that are not at the top of the stack - compilation level (C1 or C2 compiled) This information is helpful when profiling and tuning the VM for a given application and also for profiling code that uses JNI heavily. Using the proposed StackWalker class, implementing a new API that returns more information on frames is possible as a thin wrapper over the StackWalker API [2]. This also improves the maintainability as the code used in this API is used in multiple places and is therefore also better tested than the previous implementation, see [1] for the implementation. The following describes the proposed API: ```cpp void AsyncGetCallTrace2(asgct2::CallTrace *trace, jint depth, void* ucontext); ``` The structure of `CallTrace` is the same as the original `ASGCT_CallTrace` with the same error codes encoded in <= 0 values of `num_frames`. ```cpp typedef struct { JNIEnv *env_id; // Env where trace was recorded jint num_frames; // number of frames in this trace CallFrame *frames; // frames void* frame_info; // more information on frames } CallTrace; ``` The only difference is that the `frames` array also contains information on C frames and the field `frame_info`. The `frame_info` is currently null and can later be used for extended information on each frame, being an array with an element for each frame. But the type of the elements in this array is implementation specific. This akin to `compile_info` field in JVMTI's CompiledMethodLoad [3] and used for extending the information returned by the API later. Protoype ------------ Currently `CallFrame` is implemented in the prototype [4] as ```cpp typedef struct { void *machine_pc; // program counter, for C and native frames (frames of native methods) uint8_t type; // frame type (single byte) uint8_t comp_level; // highest compilation level of a method related to a Java frame // information from original CallFrame jint bci; // bci for Java frames jmethodID method_id; // method ID for Java frames } CallFrame; ``` The `FrameTypeId` is based on the frame type in JFRStackFrame: ```cpp enum FrameTypeId { FRAME_INTERPRETED = 0, FRAME_JIT = 1, // JIT compiled FRAME_INLINE = 2, // inlined JITed methods FRAME_NATIVE = 3, // native wrapper to call C methods from Java FRAME_CPP = 4 // c/c++/... frames, stub frames have CompLevel_all }; ``` The `comp_level` states the compilation level of the method related to the frame with higher numbers representing "more" compilation. `0` is defined as interpreted. It is modeled after the `CompLevel` enum in `compiler/compilerDefinitions`: ```cpp // Enumeration to distinguish tiers of compilation enum CompLevel { // ... CompLevel_none = 0, // Interpreter CompLevel_simple = 1, // C1 CompLevel_limited_profile = 2, // C1, invocation & backedge counters CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo CompLevel_full_optimization = 4 // C2 or JVMCI }; ``` The traces produced by this prototype are fairly large (each frame requires 24 is instead of 16 bytes on 64 bit systems) and some data is duplicated. The reason for this is that it simplified the extension of async-profiler for the prototype, as it only extends the data structures of the original AsyncGetCallTrace API without changing the original fields. Proposal ------------ But packing the information and reducing duplication is of course possible if we step away from the former constraint: ```cpp enum FrameTypeId { FRAME_JAVA = 1, // JIT compiled and interpreted FRAME_JAVA_INLINED = 2, // inlined JIT compiled FRAME_NATIVE = 3, // native wrapper to call C methods from Java FRAME_STUB = 4, // VM generated stubs FRAME_CPP = 5 // C/C++/... frames }; typedef struct { uint8_t type; // frame type uint8_t comp_level; uint16_t bci; // 0 < bci < 65536 jmethodID method_id; } JavaFrame; // used for FRAME_JAVA and FRAME_JAVA_INLINED typedef struct { FrameTypeId type; // single byte type void *machine_pc; } NonJavaFrame; // used for FRAME_NATIVE, FRAME_STUB and FRAME_CPP typedef union { FrameTypeId type; // to distinguish between JavaFrame and NonJavaFrame JavaFrame java_frame; NonJavaFrame non_java_frame; } CallFrame; ``` This uses the same amount of space per frame (16 bytes) as the original but encodes far more information. Best regards Johannes [1] https://github.com/parttimenerd/jdk/blob/parttimenerd_asgct2/src/hotspot/share/jfr/recorder/stacktrace/stackWalker.hpp [2] https://github.com/parttimenerd/jdk/blob/parttimenerd_asgct2/src/hotspot/share/prims/asgct2.cpp**** [3] https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#CompiledMethodLoad [4] https://github.com/parttimenerd/jdk/blob/parttimenerd_asgct2/src/hotspot/share/prims/asgct2.hpp From egahlin at openjdk.java.net Fri Mar 18 13:22:33 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Fri, 18 Mar 2022 13:22:33 GMT Subject: Integrated: 8283202: Potential off-read when checking JFR's status in awaitFinished In-Reply-To: References: Message-ID: On Wed, 16 Mar 2022 19:30:54 GMT, Erik Gahlin wrote: > Hi, > > Could I have a review of a fix that prevents the JFR parser to read passed the file state byte in the chunk header. > > Testing: jdk/jdk/jfr > > Thanks > Erik This pull request has now been integrated. Changeset: 4b5079b9 Author: Erik Gahlin URL: https://git.openjdk.java.net/jdk/commit/4b5079b9836c1cc881f571d060b310f58c8a860c Stats: 19 lines in 1 file changed: 10 ins; 6 del; 3 mod 8283202: Potential off-read when checking JFR's status in awaitFinished Reviewed-by: mgronlun ------------- PR: https://git.openjdk.java.net/jdk/pull/7845 From egahlin at openjdk.java.net Fri Mar 18 13:31:34 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Fri, 18 Mar 2022 13:31:34 GMT Subject: Integrated: 8283289 JFR: Rename CheckPoint In-Reply-To: References: Message-ID: <_M7nCOw98moKcfX5i1sybB6lOYqa0WI0mlrFvLNxpRk=.ec70cd27-9195-4ba9-853c-c5c10f18a8d2@github.com> On Wed, 16 Mar 2022 21:44:03 GMT, Erik Gahlin wrote: > Hi, > > Could I have a review of a fix that renames "CheckPoint" to "checkpoint". The only visible effect of the change is in the 'jfr summary' command where it now displays "jdk.Checkpoint". > > Testing: jdk/jdk/jfr > > Thanks > Erik This pull request has now been integrated. Changeset: c72bcfc1 Author: Erik Gahlin URL: https://git.openjdk.java.net/jdk/commit/c72bcfc1b230d22137ac7f683cf46dc70b6e3d16 Stats: 35 lines in 6 files changed: 0 ins; 0 del; 35 mod 8283289: JFR: Rename CheckPoint Reviewed-by: mgronlun ------------- PR: https://git.openjdk.java.net/jdk/pull/7847 From egahlin at openjdk.java.net Fri Mar 18 14:42:59 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Fri, 18 Mar 2022 14:42:59 GMT Subject: RFR: 8283378: JFR: Checkpoint classes not renamed properly Message-ID: Hi, Could I have review of a change that renames two files to fix a build error. Testing: build locally on Mac. Thanks Erik ------------- Commit messages: - Initial Changes: https://git.openjdk.java.net/jdk/pull/7868/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7868&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8283378 Stats: 0 lines in 2 files changed: 0 ins; 0 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/7868.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/7868/head:pull/7868 PR: https://git.openjdk.java.net/jdk/pull/7868 From dcubed at openjdk.java.net Fri Mar 18 14:47:32 2022 From: dcubed at openjdk.java.net (Daniel D.Daugherty) Date: Fri, 18 Mar 2022 14:47:32 GMT Subject: RFR: 8283378: JFR: Checkpoint classes not renamed properly In-Reply-To: References: Message-ID: <7FLWvVw_BuwpND-3vccwUZLit2_h486XepMnRquq5Bk=.9469b1e2-ad06-4bce-a47a-56c62aeafe4e@github.com> On Fri, 18 Mar 2022 14:35:38 GMT, Erik Gahlin wrote: > Hi, > > Could I have review of a change that renames two files to fix a build error. > > Testing: build locally on Mac. > > Thanks > Erik Thumbs up. This is a trivial fix. ------------- Marked as reviewed by dcubed (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/7868 From egahlin at openjdk.java.net Fri Mar 18 14:58:29 2022 From: egahlin at openjdk.java.net (Erik Gahlin) Date: Fri, 18 Mar 2022 14:58:29 GMT Subject: Integrated: 8283378: JFR: Checkpoint classes not renamed properly In-Reply-To: References: Message-ID: On Fri, 18 Mar 2022 14:35:38 GMT, Erik Gahlin wrote: > Hi, > > Could I have review of a change that renames two files to fix a build error. > > Testing: build locally on Mac. > > Thanks > Erik This pull request has now been integrated. Changeset: b2aa085e Author: Erik Gahlin URL: https://git.openjdk.java.net/jdk/commit/b2aa085e67711a32e1679b68aabb092058dca044 Stats: 0 lines in 2 files changed: 0 ins; 0 del; 0 mod 8283378: JFR: Checkpoint classes not renamed properly Reviewed-by: dcubed ------------- PR: https://git.openjdk.java.net/jdk/pull/7868 From david.holmes at oracle.com Sun Mar 20 22:41:17 2022 From: david.holmes at oracle.com (David Holmes) Date: Mon, 21 Mar 2022 08:41:17 +1000 Subject: Proposal of a new version of AsyncGetCallTrace In-Reply-To: References: Message-ID: Hi Johannes, On 18/03/2022 7:43 pm, Bechberger, Johannes wrote: > Hi, > > I would like propose to > > 1. Replace duplicated stack walking code with unified API > 2. Create a new version of AsyncGetCallTrace, tentatively called "AsyncGetCallTrace2", with more information on more frames using the unified API > > A demo (as well as this text) is available at https://github.com/parttimenerd/asgct2-demo > if you want to see a prototype of this proposal in action. > > Unify Stack Walking > ================ > > There are currently multiple implementations of stack walking in JFR and for AsyncGetCallTrace. > They each implement their own extension of vframeStream but with comparable features > and check for problematic frames. > > My proposal is, therefore, to replace the stack walking code with a unified API that > includes all error checking and vframeStream extensions in a single place. > The prosposed new class is called StackWalker and could be part of > `jfr/recorder/stacktrace` [1]. So we already have the StackWalker API provided at the Java level and with the implementation in the VM in src/hotspot/share/prims/stackwalk.cpp. How does that fit in with what you propose? Cheers, David ----- > This class also supports getting information on C frames so it can be potentially > used for walking stacks in VMError (used to create hs_err files), further > reducing the amount of different stack walking code. > > AsyncGetCallTrace2 > ================ > > The AsyncGetCallTrace call has seen increasing use in recent years > in profilers like async-profiler. > But it is not really an API (not exported in any header) and > the information on frames it returns is pretty limited > (only the method and bci for Java frames) which makes implementing > profilers and other tooling harder. Tools like async-profiler > have to resort to complicated code to partially obtain the information > that the JVM already has. > Information that is currently hidden and impossible to obtain is > > - whether a compiled frame is inlined (currently only obtainable for the topmost compiled frames) > - although this can be obtained using JFR > - C frames that are not at the top of the stack > - compilation level (C1 or C2 compiled) > > This information is helpful when profiling and tuning the VM for > a given application and also for profiling code that uses > JNI heavily. > > Using the proposed StackWalker class, implementing a new API > that returns more information on frames is possible > as a thin wrapper over the StackWalker API [2]. > This also improves the maintainability as the code used > in this API is used in multiple places and is therefore > also better tested than the previous implementation, see > [1] for the implementation. > > The following describes the proposed API: > > ```cpp > void AsyncGetCallTrace2(asgct2::CallTrace *trace, jint depth, void* ucontext); > ``` > > The structure of `CallTrace` is the same as the original > `ASGCT_CallTrace` with the same error codes encoded in <= 0 > values of `num_frames`. > > ```cpp > typedef struct { > JNIEnv *env_id; // Env where trace was recorded > jint num_frames; // number of frames in this trace > CallFrame *frames; // frames > void* frame_info; // more information on frames > } CallTrace; > ``` > > The only difference is that the `frames` array also contains > information on C frames and the field `frame_info`. > The `frame_info` is currently null and can later be used > for extended information on each frame, being an array with > an element for each frame. But the type of the > elements in this array is implementation specific. > This akin to `compile_info` field in JVMTI's CompiledMethodLoad > [3] and used for extending the information returned by the > API later. > > Protoype > ------------ > > Currently `CallFrame` is implemented in the prototype [4] as > > ```cpp > typedef struct { > void *machine_pc; // program counter, for C and native frames (frames of native methods) > uint8_t type; // frame type (single byte) > uint8_t comp_level; // highest compilation level of a method related to a Java frame > // information from original CallFrame > jint bci; // bci for Java frames > jmethodID method_id; // method ID for Java frames > } CallFrame; > ``` > > The `FrameTypeId` is based on the frame type in JFRStackFrame: > > ```cpp > enum FrameTypeId { > FRAME_INTERPRETED = 0, > FRAME_JIT = 1, // JIT compiled > FRAME_INLINE = 2, // inlined JITed methods > FRAME_NATIVE = 3, // native wrapper to call C methods from Java > FRAME_CPP = 4 // c/c++/... frames, stub frames have CompLevel_all > }; > ``` > > The `comp_level` states the compilation level of the method related to the frame > with higher numbers representing "more" compilation. `0` is defined as > interpreted. It is modeled after the `CompLevel` enum in `compiler/compilerDefinitions`: > > ```cpp > // Enumeration to distinguish tiers of compilation > enum CompLevel { > // ... > CompLevel_none = 0, // Interpreter > CompLevel_simple = 1, // C1 > CompLevel_limited_profile = 2, // C1, invocation & backedge counters > CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo > CompLevel_full_optimization = 4 // C2 or JVMCI > }; > ``` > > The traces produced by this prototype are fairly large > (each frame requires 24 is instead of 16 bytes on 64 bit systems) and some data is > duplicated. > The reason for this is that it simplified the extension of async-profiler > for the prototype, as it only extends the data structures of > the original AsyncGetCallTrace API without changing the original fields. > > Proposal > ------------ > > But packing the information and reducing duplication is of course possible > if we step away from the former constraint: > > ```cpp > enum FrameTypeId { > FRAME_JAVA = 1, // JIT compiled and interpreted > FRAME_JAVA_INLINED = 2, // inlined JIT compiled > FRAME_NATIVE = 3, // native wrapper to call C methods from Java > FRAME_STUB = 4, // VM generated stubs > FRAME_CPP = 5 // C/C++/... frames > }; > > typedef struct { > uint8_t type; // frame type > uint8_t comp_level; > uint16_t bci; // 0 < bci < 65536 > jmethodID method_id; > } JavaFrame; // used for FRAME_JAVA and FRAME_JAVA_INLINED > > typedef struct { > FrameTypeId type; // single byte type > void *machine_pc; > } NonJavaFrame; // used for FRAME_NATIVE, FRAME_STUB and FRAME_CPP > > typedef union { > FrameTypeId type; // to distinguish between JavaFrame and NonJavaFrame > JavaFrame java_frame; > NonJavaFrame non_java_frame; > } CallFrame; > ``` > > This uses the same amount of space per frame (16 bytes) as the original but encodes far more information. > > Best regards > Johannes > > [1] https://github.com/parttimenerd/jdk/blob/parttimenerd_asgct2/src/hotspot/share/jfr/recorder/stacktrace/stackWalker.hpp > > [2] https://github.com/parttimenerd/jdk/blob/parttimenerd_asgct2/src/hotspot/share/prims/asgct2.cpp**** > > [3] https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#CompiledMethodLoad > > [4] https://github.com/parttimenerd/jdk/blob/parttimenerd_asgct2/src/hotspot/share/prims/asgct2.hpp > From johannes.bechberger at sap.com Mon Mar 21 11:42:10 2022 From: johannes.bechberger at sap.com (Bechberger, Johannes) Date: Mon, 21 Mar 2022 11:42:10 +0000 Subject: Proposal of a new version of AsyncGetCallTrace In-Reply-To: References: Message-ID: Hi David, the src/hotspot/share/prims/stackwalk.cpp has been made for another purpose: It is used in java.lang.StackWalker to obtain the Java frames and allocates memory on the heap. It is not used in the places that my proposed Stackwalker could be used: in profiling and error stack traces (hs_err file), where memory allocation might cause problems. The class in prims also lacks the ability to obtain the native frames. Best regards Johannes From: David Holmes Date: Sunday, 20. March 2022 at 23:41 To: Bechberger, Johannes , hotspot-dev at openjdk.java.net , hotspot-jfr-dev at openjdk.java.net , serviceability-dev at openjdk.java.net Subject: Re: Proposal of a new version of AsyncGetCallTrace Hi Johannes, On 18/03/2022 7:43 pm, Bechberger, Johannes wrote: > Hi, > > I would like propose to > > 1. Replace duplicated stack walking code with unified API > 2. Create a new version of AsyncGetCallTrace, tentatively called "AsyncGetCallTrace2", with more information on more frames using the unified API > > A demo (as well as this text) is available at https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fparttimenerd%2Fasgct2-demo&data=04%7C01%7Cjohannes.bechberger%40sap.com%7Ceb5ca380974b40d8ad1908da0ac2c949%7C42f7676cf455423c82f6dc2d99791af7%7C0%7C0%7C637834128980129964%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=WzQw1M5pnBdK5PxtohnURFAJeSJOZy1ZAuRGSaczjOU%3D&reserved=0 > if you want to see a prototype of this proposal in action. > > Unify Stack Walking > ================ > > There are currently multiple implementations of stack walking in JFR and for AsyncGetCallTrace. > They each implement their own extension of vframeStream but with comparable features > and check for problematic frames. > > My proposal is, therefore, to replace the stack walking code with a unified API that > includes all error checking and vframeStream extensions in a single place. > The prosposed new class is called StackWalker and could be part of > `jfr/recorder/stacktrace` [1]. So we already have the StackWalker API provided at the Java level and with the implementation in the VM in src/hotspot/share/prims/stackwalk.cpp. How does that fit in with what you propose? Cheers, David ----- > This class also supports getting information on C frames so it can be potentially > used for walking stacks in VMError (used to create hs_err files), further > reducing the amount of different stack walking code. > > AsyncGetCallTrace2 > ================ > > The AsyncGetCallTrace call has seen increasing use in recent years > in profilers like async-profiler. > But it is not really an API (not exported in any header) and > the information on frames it returns is pretty limited > (only the method and bci for Java frames) which makes implementing > profilers and other tooling harder. Tools like async-profiler > have to resort to complicated code to partially obtain the information > that the JVM already has. > Information that is currently hidden and impossible to obtain is > > - whether a compiled frame is inlined (currently only obtainable for the topmost compiled frames) > - although this can be obtained using JFR > - C frames that are not at the top of the stack > - compilation level (C1 or C2 compiled) > > This information is helpful when profiling and tuning the VM for > a given application and also for profiling code that uses > JNI heavily. > > Using the proposed StackWalker class, implementing a new API > that returns more information on frames is possible > as a thin wrapper over the StackWalker API [2]. > This also improves the maintainability as the code used > in this API is used in multiple places and is therefore > also better tested than the previous implementation, see > [1] for the implementation. > > The following describes the proposed API: > > ```cpp > void AsyncGetCallTrace2(asgct2::CallTrace *trace, jint depth, void* ucontext); > ``` > > The structure of `CallTrace` is the same as the original > `ASGCT_CallTrace` with the same error codes encoded in <= 0 > values of `num_frames`. > > ```cpp > typedef struct { > JNIEnv *env_id; // Env where trace was recorded > jint num_frames; // number of frames in this trace > CallFrame *frames; // frames > void* frame_info; // more information on frames > } CallTrace; > ``` > > The only difference is that the `frames` array also contains > information on C frames and the field `frame_info`. > The `frame_info` is currently null and can later be used > for extended information on each frame, being an array with > an element for each frame. But the type of the > elements in this array is implementation specific. > This akin to `compile_info` field in JVMTI's CompiledMethodLoad > [3] and used for extending the information returned by the > API later. > > Protoype > ------------ > > Currently `CallFrame` is implemented in the prototype [4] as > > ```cpp > typedef struct { > void *machine_pc; // program counter, for C and native frames (frames of native methods) > uint8_t type; // frame type (single byte) > uint8_t comp_level; // highest compilation level of a method related to a Java frame > // information from original CallFrame > jint bci; // bci for Java frames > jmethodID method_id; // method ID for Java frames > } CallFrame; > ``` > > The `FrameTypeId` is based on the frame type in JFRStackFrame: > > ```cpp > enum FrameTypeId { > FRAME_INTERPRETED = 0, > FRAME_JIT = 1, // JIT compiled > FRAME_INLINE = 2, // inlined JITed methods > FRAME_NATIVE = 3, // native wrapper to call C methods from Java > FRAME_CPP = 4 // c/c++/... frames, stub frames have CompLevel_all > }; > ``` > > The `comp_level` states the compilation level of the method related to the frame > with higher numbers representing "more" compilation. `0` is defined as > interpreted. It is modeled after the `CompLevel` enum in `compiler/compilerDefinitions`: > > ```cpp > // Enumeration to distinguish tiers of compilation > enum CompLevel { > // ... > CompLevel_none = 0, // Interpreter > CompLevel_simple = 1, // C1 > CompLevel_limited_profile = 2, // C1, invocation & backedge counters > CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo > CompLevel_full_optimization = 4 // C2 or JVMCI > }; > ``` > > The traces produced by this prototype are fairly large > (each frame requires 24 is instead of 16 bytes on 64 bit systems) and some data is > duplicated. > The reason for this is that it simplified the extension of async-profiler > for the prototype, as it only extends the data structures of > the original AsyncGetCallTrace API without changing the original fields. > > Proposal > ------------ > > But packing the information and reducing duplication is of course possible > if we step away from the former constraint: > > ```cpp > enum FrameTypeId { > FRAME_JAVA = 1, // JIT compiled and interpreted > FRAME_JAVA_INLINED = 2, // inlined JIT compiled > FRAME_NATIVE = 3, // native wrapper to call C methods from Java > FRAME_STUB = 4, // VM generated stubs > FRAME_CPP = 5 // C/C++/... frames > }; > > typedef struct { > uint8_t type; // frame type > uint8_t comp_level; > uint16_t bci; // 0 < bci < 65536 > jmethodID method_id; > } JavaFrame; // used for FRAME_JAVA and FRAME_JAVA_INLINED > > typedef struct { > FrameTypeId type; // single byte type > void *machine_pc; > } NonJavaFrame; // used for FRAME_NATIVE, FRAME_STUB and FRAME_CPP > > typedef union { > FrameTypeId type; // to distinguish between JavaFrame and NonJavaFrame > JavaFrame java_frame; > NonJavaFrame non_java_frame; > } CallFrame; > ``` > > This uses the same amount of space per frame (16 bytes) as the original but encodes far more information. > > Best regards > Johannes > > [1] https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fparttimenerd%2Fjdk%2Fblob%2Fparttimenerd_asgct2%2Fsrc%2Fhotspot%2Fshare%2Fjfr%2Frecorder%2Fstacktrace%2FstackWalker.hpp&data=04%7C01%7Cjohannes.bechberger%40sap.com%7Ceb5ca380974b40d8ad1908da0ac2c949%7C42f7676cf455423c82f6dc2d99791af7%7C0%7C0%7C637834128980129964%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=u8imCsxZLO5qHcB3Kdn%2FiC5FQ2NGwxJzBocy2QGKngM%3D&reserved=0 > > [2] https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fparttimenerd%2Fjdk%2Fblob%2Fparttimenerd_asgct2%2Fsrc%2Fhotspot%2Fshare%2Fprims%2Fasgct2.cpp****&data=04%7C01%7Cjohannes.bechberger%40sap.com%7Ceb5ca380974b40d8ad1908da0ac2c949%7C42f7676cf455423c82f6dc2d99791af7%7C0%7C0%7C637834128980129964%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=CVP%2BZFYiz%2Brmvn4RSFmYxttL6SttV9AxSLgWnGoBbXY%3D&reserved=0 > > [3] https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F8%2Fdocs%2Fplatform%2Fjvmti%2Fjvmti.html%23CompiledMethodLoad&data=04%7C01%7Cjohannes.bechberger%40sap.com%7Ceb5ca380974b40d8ad1908da0ac2c949%7C42f7676cf455423c82f6dc2d99791af7%7C0%7C0%7C637834128980129964%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=UmILa1T1BI4SKK3k%2BTYnCLE7dTwSL6jmUVvTMQIdA3E%3D&reserved=0 > > [4] https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fparttimenerd%2Fjdk%2Fblob%2Fparttimenerd_asgct2%2Fsrc%2Fhotspot%2Fshare%2Fprims%2Fasgct2.hpp&data=04%7C01%7Cjohannes.bechberger%40sap.com%7Ceb5ca380974b40d8ad1908da0ac2c949%7C42f7676cf455423c82f6dc2d99791af7%7C0%7C0%7C637834128980129964%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=ROyKJ2ADjrQvVIoLBxwBdKm3AWAdQ2Gk4m6f7He5mNI%3D&reserved=0 > From duke at openjdk.java.net Tue Mar 22 05:31:32 2022 From: duke at openjdk.java.net (ExE Boss) Date: Tue, 22 Mar 2022 05:31:32 GMT Subject: RFR: 8280035: Use Class.isInstance instead of Class.isAssignableFrom where applicable In-Reply-To: References: Message-ID: On Mon, 21 Feb 2022 12:16:53 GMT, Andrey Turbanov wrote: > Method `isAssignableFrom` is opposite: it brings unnecessary complexity in the code. And it's easy to confuse orders of parameters. Even JBS confirms that: Maybe we?should?add `Class::isSubclassOf(Class?that)` that?performs `that.isAssignableFrom(this)`: ------------- PR: https://git.openjdk.java.net/jdk/pull/7061