New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8261127: Cleanup THREAD/TRAPS/CHECK usage in CDS code #2397
Conversation
|
@dholmes-ora The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
/label remove hotspot |
@dholmes-ora |
@dholmes-ora |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes look good to me.
You probably have found out that that some of the functions you changed (e.g., HeapShared::archive_reachable_objects_from) are executed inside the VMThread, which is not a JavaThread. So their current use of TRAPS/CHECK will not be compatible with your upcoming changes in JDK-8252685. The PR will fix these cases (but I am not sure if there are others).
For the functions that you converted to use TRAPS, these are OK as they are called only inside a Java thread, before the CDS code switches to VM_PopulateDumpSharedSpace::doit().
Just a side note ... the CDS code has more misuse of THREAD. But those can be done in a separate RFE, and they probably won't affect JDK-8252685.
E.g., MetaspaceShared::preload_and_dump should probably be changed to:
void MetaspaceShared::preload_and_dump(TRAPS) {
MetaspaceShared::preload_and_dump_impl(THREAD);
if (HAS_PENDING_EXCEPTION) {
log_error(cds)("CDS dumping has failed");
vm_exit(1);
}
}
void MetaspaceShared::preload_and_dump_impl(TRAPS) {
.... the old MetaspaceShared::preload_and_dump()
.... change all THREAD to CHECK;
}
@dholmes-ora This change now passes all automated pre-integration checks. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been no new commits pushed to the
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using CATCH is preferable to passing THREAD with a comment, which is unenforceable in the code. Thanks for cleaning up excess TRAPS.
static oop process_archived_mirror(Klass* k, oop mirror, oop archived_mirror, Thread *THREAD) | ||
static void archive_basic_type_mirrors() NOT_CDS_JAVA_HEAP_RETURN; | ||
static oop archive_mirror(Klass* k) NOT_CDS_JAVA_HEAP_RETURN_(NULL); | ||
static oop process_archived_mirror(Klass* k, oop mirror, oop archived_mirro) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing an 'r'.
resolve_classes_for_subgraphs(fmg_open_archive_subgraph_entry_fields, | ||
num_fmg_open_archive_subgraph_entry_fields, | ||
CHECK); | ||
THREAD /* exceptions are ignored */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are exceptions ignored or unexpected? This pattern doesn't exist anywhere else as far as I know, otherwise maybe we should have a CLEAR macro in addition to CHECK/CATCH that clears pending exceptions? I don't really like that there may be exceptions lurking through multiple calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so I'm reading this in context. This still looks unusual and possibly problematic without deeper inspection. It seems like removing TRAPS here also and the callees, and adding this before the functions that clear pending exceptions would be better.
JavaThread* THREAD = JavaThread::current();
@@ -701,7 +697,7 @@ void HeapShared::resolve_classes_for_subgraphs(ArchivableStaticFieldInfo fields[ | |||
TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name); | |||
InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name); | |||
assert(k != NULL && k->is_shared_boot_class(), "sanity"); | |||
resolve_classes_for_subgraph_of(k, CHECK); | |||
resolve_classes_for_subgraph_of(k, THREAD /* exceptions are ignored */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're not ignored though, they're passed to the caller of this function. Since this function passes TRAPS, the caller should have a CHECK/CATCH or handle the pending exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are passed to the callers of this function as THREAD->_pending_exception will have an something in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exceptions aren't ignored, they are cleared by the callees, so you don't expect any exceptions, which is CATCH.
assert(is_heap_object_archiving_allowed(), "Sanity check"); | ||
_dump_time_subgraph_info_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeKlassSubGraphInfoTable(); | ||
init_subgraph_entry_fields(closed_archive_subgraph_entry_fields, | ||
num_closed_archive_subgraph_entry_fields, | ||
THREAD); | ||
THREAD /* aborts on exception */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So these should really be debug version of CATCH then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code makes me wonder if Thread* THREAD doesn't make the intent of this code clearer.
Mailing list message from David Holmes on hotspot-runtime-dev: Hi Coleen, Thanks for taking a look at this. On 4/02/2021 11:41 pm, Coleen Phillimore wrote:
To be honest I never even considered CATCH because I thought it "caught"
Well spotted -thanks!
Ignored. resolve_classes_for_subgraphs calls if (HAS_PENDING_EXCEPTION) { so no exceptions can percolate up.
They are ignored as I just explained.
All I was trying to capture by the comment was why this is not a CHECK CATCH really is the wrong word for the actual semantics here. :( And I really don't want to add useless checks in product mode. :( Thanks, |
Mailing list message from David Holmes on hotspot-runtime-dev: Hi Ioi, Thanks for taking a look. On 4/02/2021 4:09 pm, Ioi Lam wrote:
Having TRAPS on such functions is plain wrong - if there were actually
Given their use of exceptions it is imperative they are only executed by
Right - I didn't try to do a full audit, I simply found a particular Thanks, |
resolve_classes_for_subgraphs(fmg_open_archive_subgraph_entry_fields, | ||
num_fmg_open_archive_subgraph_entry_fields, | ||
CHECK); | ||
THREAD /* exceptions are ignored */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so I'm reading this in context. This still looks unusual and possibly problematic without deeper inspection. It seems like removing TRAPS here also and the callees, and adding this before the functions that clear pending exceptions would be better.
JavaThread* THREAD = JavaThread::current();
@@ -701,7 +697,7 @@ void HeapShared::resolve_classes_for_subgraphs(ArchivableStaticFieldInfo fields[ | |||
TempNewSymbol klass_name = SymbolTable::new_symbol(info->klass_name); | |||
InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name); | |||
assert(k != NULL && k->is_shared_boot_class(), "sanity"); | |||
resolve_classes_for_subgraph_of(k, CHECK); | |||
resolve_classes_for_subgraph_of(k, THREAD /* exceptions are ignored */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exceptions aren't ignored, they are cleared by the callees, so you don't expect any exceptions, which is CATCH.
assert(is_heap_object_archiving_allowed(), "Sanity check"); | ||
_dump_time_subgraph_info_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeKlassSubGraphInfoTable(); | ||
init_subgraph_entry_fields(closed_archive_subgraph_entry_fields, | ||
num_closed_archive_subgraph_entry_fields, | ||
THREAD); | ||
THREAD /* aborts on exception */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code makes me wonder if Thread* THREAD doesn't make the intent of this code clearer.
Mailing list message from David Holmes on hotspot-runtime-dev: On 5/02/2021 9:19 am, Coleen Phillimore wrote:
The code does: void HeapShared::resolve_classes_for_subgraph_of(Klass* k, TRAPS) { so we clear any pending exception that might arise. David |
Mailing list message from David Holmes on hotspot-runtime-dev: On 5/02/2021 9:42 am, Coleen Phillimore wrote:
I guess it depends on what we each think TRAPS should indicate. I like Passing through "Thread* thread" is still reasonable from a performance
"Thread* thread" - perhaps. To me "Thread* THREAD" is a sign that the I'll rework the changes in this area to avoid using TRAPS and THREAD. Thanks, |
Mailing list message from Coleen Phillimore on hotspot-runtime-dev: On 2/4/21 7:00 PM, David Holmes wrote:
To me TRAPS means that you're going to return with an exception pending, I think separately we should make CATCH not fail in production. I'm glad you're trying to change TRAPS to be JavaThread*, that's a
I'm sensitive to that.
The trouble with Thread* thread as a parameter is that one expects
Yes thanks.? See what you can do, I'm not going to insist on these Coleen
|
I agree we should change the check to an assert. It's not clear what In the Monty VM, we had a similar construct. Instead of CATCH, it's call MUST_SUCCEED (if I remember correctly). Like:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still good.
Mailing list message from David Holmes on hotspot-runtime-dev: On 5/02/2021 3:57 pm, Ioi Lam wrote:
Thanks Ioi! David |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I don't know why replying in email appended a ? in many of my sentences. Thank you for these changes.
@dholmes-ora this pull request can not be integrated into git checkout 8261127
git fetch https://git.openjdk.java.net/jdk master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
/integrate |
Thanks Coleen and Ioi! |
@dholmes-ora Pushed as commit f03e839. |
While examining changes related to the TRAPS macro I noticed that a number of CDS related methods were passed a thread parameter that ended up never being used. Fixing this percolates up the call chain resulting in the ability to remove the parameter from other calls. In some places the thread is needed and has to be manifested via Thread::current(), but these are few and non-critical, and the cleanup of the API (including the benefit to the TRAPS work - see JDK-8252685) makes this worthwhile.
I also changed
Thread* THREAD
to TRAPS where it relates to exception processing (even if CDS diverts to an abort path).Some uses of CHECK were removed that were only passing THREAD and the called code never triggers any exceptions.
Added commentary where it is not clear why we don't use CHECK.
Testing: local build and CI tiers 1-3
Thanks,
David
Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/2397/head:pull/2397
$ git checkout pull/2397