Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 2 additions & 45 deletions src/hotspot/share/classfile/systemDictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,43 +1106,7 @@ bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle
return true;
}

// Pre-load class referred to in non-static null-free instance field. These fields trigger MANDATORY loading.
// Some pre-loading does not fail fatally
bool SystemDictionary::preload_from_null_free_field(InstanceKlass* ik, Handle class_loader, Symbol* sig, int field_index, TRAPS) {
TempNewSymbol name = Signature::strip_envelope(sig);
log_info(class, preload)("Preloading of class %s during loading of shared class %s. "
"Cause: a null-free non-static field is declared with this type",
name->as_C_string(), ik->name()->as_C_string());
InstanceKlass* real_k = SystemDictionary::resolve_with_circularity_detection(ik->name(), name,
class_loader, false, CHECK_false);
if (HAS_PENDING_EXCEPTION) {
log_info(class, preload)("Preloading of class %s during loading of class %s "
"(cause: null-free non-static field) failed: %s",
name->as_C_string(), ik->name()->as_C_string(),
PENDING_EXCEPTION->klass()->name()->as_C_string());
return false; // Exception is still pending
}

InstanceKlass* k = ik->get_inline_type_field_klass_or_null(field_index);
if (real_k != k) {
// oops, the app has substituted a different version of k! Does not fail fatally
log_info(class, preload)("Preloading of class %s during loading of shared class %s "
"(cause: null-free non-static field) failed : "
"app substituted a different version",
name->as_C_string(), ik->name()->as_C_string());
return false;
}
log_info(class, preload)("Preloading of class %s during loading of shared class %s "
"(cause: null-free non-static field) succeeded",
name->as_C_string(), ik->name()->as_C_string());

assert(real_k != nullptr, "Sanity check");
InstanceKlass::check_can_be_annotated_with_NullRestricted(real_k, ik->name(), CHECK_false);

return true;
}

// Tries to pre-load classes referred to in non-static nullable instance fields if they are found in the
// Tries to pre-load classes referred to in non-static instance fields if they are found in the
// loadable descriptors attribute. If loading fails, we can fail silently.
void SystemDictionary::try_preload_from_loadable_descriptors(InstanceKlass* ik, Handle class_loader, Symbol* sig, int field_index, TRAPS) {
TempNewSymbol name = Signature::strip_envelope(sig);
Expand Down Expand Up @@ -1203,14 +1167,7 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
Symbol* sig = fs.signature();
int field_index = fs.index();

if (fs.is_null_free_inline_type()) {
// A false return means that the class didn't load for other reasons than an exception.
bool check = preload_from_null_free_field(ik, class_loader, sig, field_index, CHECK_NULL);
if (!check) {
ik->set_shared_loading_failed();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we safely drop this failure marking?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used for regular shared class loading so I don't think we can drop this shared_loading_failed marker.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't realise that one was needed. I've re-added it, along with an edit to try_preload_from_loadable_descriptors so we can see if we failed or not. It now also has a new parameter that decides if failing means we call shared_loading_failed .

return nullptr;
}
} else if (Signature::has_envelope(sig)) {
if (Signature::has_envelope(sig)) {
// Pending exceptions are cleared so we can fail silently
try_preload_from_loadable_descriptors(ik, class_loader, sig, field_index, CHECK_NULL);
}
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/share/classfile/systemDictionary.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2026, 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
Expand Down Expand Up @@ -331,7 +331,6 @@ class SystemDictionary : AllStatic {

static bool add_loader_constraint(Symbol* name, Klass* klass_being_linked, Handle loader1,
Handle loader2);
static bool preload_from_null_free_field(InstanceKlass* ik, Handle class_loader, Symbol* sig, int field_index, TRAPS);
static void try_preload_from_loadable_descriptors(InstanceKlass* ik, Handle class_loader, Symbol* sig, int field_index, TRAPS);
static InstanceKlass* load_shared_class(InstanceKlass* ik,
Handle class_loader,
Expand Down