Skip to content

Commit 42a318b

Browse files
author
Vladimir Kozlov
committed
8380025: C2: Missed Value() optimization opportunity in CCP with LoadUB
Reviewed-by: vlivanov, dlong, jrose
1 parent c553e75 commit 42a318b

5 files changed

Lines changed: 60 additions & 31 deletions

File tree

src/hotspot/share/ci/ciEnv.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -236,6 +236,9 @@ class ciEnv : StackObj {
236236
ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
237237
return _factory->get_unloaded_method(declared_holder, name, signature, accessor);
238238
}
239+
InstanceKlass::ClassState get_cached_init_state(uint id) {
240+
return (InstanceKlass::ClassState)_factory->cached_init_state(id);
241+
}
239242

240243
// Get a ciKlass representing an unloaded klass.
241244
// Ensures uniqueness of the result.

src/hotspot/share/ci/ciInstanceKlass.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -136,12 +136,14 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
136136

137137

138138
// ------------------------------------------------------------------
139-
// ciInstanceKlass::compute_shared_is_initialized
140-
void ciInstanceKlass::compute_shared_init_state() {
141-
GUARDED_VM_ENTRY(
142-
InstanceKlass* ik = get_instanceKlass();
143-
_init_state = ik->init_state();
144-
)
139+
InstanceKlass::ClassState ciInstanceKlass::compute_init_state() {
140+
if (_is_shared && is_loaded()) {
141+
// Return cached init state of shared klass
142+
ciEnv* env = CURRENT_ENV;
143+
assert(env->task() != nullptr, "only calls from compilation are expected here");
144+
return env->get_cached_init_state(ident());
145+
}
146+
return _init_state;
145147
}
146148

147149
// ------------------------------------------------------------------
@@ -319,11 +321,11 @@ void ciInstanceKlass::print_impl(outputStream* st) {
319321
bool_to_str(has_subklass()),
320322
layout_helper());
321323

322-
_flags.print_klass_flags();
324+
_flags.print_klass_flags(st);
323325

324326
if (_super) {
325327
st->print(" super=");
326-
_super->print_name();
328+
_super->print_name_on(st);
327329
}
328330
if (_java_mirror) {
329331
st->print(" mirror=PRESENT");

src/hotspot/share/ci/ciInstanceKlass.hpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -106,43 +106,36 @@ class ciInstanceKlass : public ciKlass {
106106

107107
bool is_shared() { return _is_shared; }
108108

109-
void compute_shared_init_state();
109+
InstanceKlass::ClassState compute_init_state();
110110
bool compute_shared_has_subklass();
111111
int compute_nonstatic_fields();
112112
GrowableArray<ciField*>* compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields);
113113
bool compute_has_trusted_loader();
114114

115-
// Update the init_state for shared klasses
116-
void update_if_shared(InstanceKlass::ClassState expected) {
117-
if (_is_shared && _init_state != expected) {
118-
if (is_loaded()) compute_shared_init_state();
119-
}
120-
}
121-
122115
public:
123116
// Has this klass been initialized?
124117
bool is_initialized() {
125-
update_if_shared(InstanceKlass::fully_initialized);
126-
return _init_state == InstanceKlass::fully_initialized;
118+
InstanceKlass::ClassState state = compute_init_state();
119+
return state == InstanceKlass::fully_initialized;
127120
}
128121
bool is_not_initialized() {
129-
update_if_shared(InstanceKlass::fully_initialized);
130-
return _init_state < InstanceKlass::being_initialized;
122+
InstanceKlass::ClassState state = compute_init_state();
123+
return state < InstanceKlass::being_initialized;
131124
}
132125
// Is this klass being initialized?
133126
bool is_being_initialized() {
134-
update_if_shared(InstanceKlass::being_initialized);
135-
return _init_state == InstanceKlass::being_initialized;
127+
InstanceKlass::ClassState state = compute_init_state();
128+
return state == InstanceKlass::being_initialized;
136129
}
137130
// Has this klass been linked?
138131
bool is_linked() {
139-
update_if_shared(InstanceKlass::linked);
140-
return _init_state >= InstanceKlass::linked;
132+
InstanceKlass::ClassState state = compute_init_state();
133+
return state >= InstanceKlass::linked;
141134
}
142135
// Is this klass in error state?
143136
bool is_in_error_state() {
144-
update_if_shared(InstanceKlass::initialization_error);
145-
return _init_state == InstanceKlass::initialization_error;
137+
InstanceKlass::ClassState state = compute_init_state();
138+
return state == InstanceKlass::initialization_error;
146139
}
147140

148141
// General klass information.

src/hotspot/share/ci/ciObjectFactory.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,7 @@
4848
#include "gc/shared/collectedHeap.inline.hpp"
4949
#include "memory/allocation.inline.hpp"
5050
#include "memory/universe.hpp"
51+
#include "oops/instanceKlass.hpp"
5152
#include "oops/oop.inline.hpp"
5253
#include "oops/trainingData.hpp"
5354
#include "runtime/handles.inline.hpp"
@@ -83,6 +84,7 @@ ciObjectFactory::ciObjectFactory(Arena* arena,
8384
int expected_size)
8485
: _arena(arena),
8586
_ci_metadata(arena, expected_size, 0, nullptr),
87+
_cached_init_state(arena, _shared_ident_limit, 0, (u1)0),
8688
_unloaded_methods(arena, 4, 0, nullptr),
8789
_unloaded_klasses(arena, 8, 0, nullptr),
8890
_unloaded_instances(arena, 4, 0, nullptr),
@@ -97,6 +99,28 @@ ciObjectFactory::ciObjectFactory(Arena* arena,
9799
// If the shared ci objects exist append them to this factory's objects
98100
if (_shared_ci_metadata != nullptr) {
99101
_ci_metadata.appendAll(_shared_ci_metadata);
102+
// ciInstanceKlass for well-known class is shared by all
103+
// compiler threads and can be updated concurrently by
104+
// other compiler threads during compilation.
105+
// Make local copy of class state to avoid state change
106+
// during compilation.
107+
int len = _ci_metadata.length();
108+
for (int i = 0; i < len; i++) {
109+
ciMetadata* obj = _ci_metadata.at(i);
110+
if (obj->is_loaded() && obj->is_instance_klass()) {
111+
ciInstanceKlass* cik = obj->as_instance_klass();
112+
precond(cik->is_shared());
113+
InstanceKlass::ClassState current_state = cik->_init_state;
114+
InstanceKlass::ClassState state = InstanceKlass::fully_initialized;
115+
if (current_state != state) {
116+
GUARDED_VM_ENTRY( state = cik->get_instanceKlass()->init_state(); )
117+
// Update state of shared ciInstanceKlass
118+
cik->_init_state = state;
119+
}
120+
// Cache state for current compilation
121+
_cached_init_state.at_put_grow(cik->ident(), (u1)state, 0);
122+
}
123+
}
100124
}
101125
}
102126

src/hotspot/share/ci/ciObjectFactory.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,8 @@ class ciObjectFactory : public ArenaObj {
4747

4848
Arena* _arena;
4949
GrowableArray<ciMetadata*> _ci_metadata;
50+
// Local copy of shared ciInstanceKlass init state for current compilation
51+
GrowableArray<u1> _cached_init_state;
5052
GrowableArray<ciMethod*> _unloaded_methods;
5153
GrowableArray<ciKlass*> _unloaded_klasses;
5254
GrowableArray<ciInstance*> _unloaded_instances;
@@ -103,6 +105,11 @@ class ciObjectFactory : public ArenaObj {
103105
ciMetadata* cached_metadata(Metadata* key);
104106
ciSymbol* get_symbol(Symbol* key);
105107

108+
// Get cached init state of shared ciInstanceKlass
109+
u1 cached_init_state(uint id) {
110+
return _cached_init_state.at(id);
111+
}
112+
106113
// Get the ciSymbol corresponding to one of the vmSymbols.
107114
static ciSymbol* vm_symbol_at(vmSymbolID index);
108115

0 commit comments

Comments
 (0)