Skip to content

Commit 3220c4c

Browse files
committed
8372696: Allow boot classes to explicitly opt-in for final field trusting
Reviewed-by: jvernee, jrose, alanb
1 parent b42861a commit 3220c4c

File tree

13 files changed

+155
-14
lines changed

13 files changed

+155
-14
lines changed

src/hotspot/share/ci/ciField.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ ciField::ciField(fieldDescriptor *fd) :
216216
static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
217217
if (holder == nullptr)
218218
return false;
219+
if (holder->trust_final_fields()) {
220+
// Explicit opt-in from system classes
221+
return true;
222+
}
219223
// Even if general trusting is disabled, trust system-built closures in these packages.
220224
if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke") ||
221225
holder->is_in_package("java/lang/reflect") || holder->is_in_package("jdk/internal/reflect") ||
@@ -230,14 +234,6 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
230234
// Trust final fields in records
231235
if (holder->is_record())
232236
return true;
233-
// Trust Atomic*FieldUpdaters: they are very important for performance, and make up one
234-
// more reason not to use Unsafe, if their final fields are trusted. See more in JDK-8140483.
235-
if (holder->name() == ciSymbols::java_util_concurrent_atomic_AtomicIntegerFieldUpdater_Impl() ||
236-
holder->name() == ciSymbols::java_util_concurrent_atomic_AtomicLongFieldUpdater_CASUpdater() ||
237-
holder->name() == ciSymbols::java_util_concurrent_atomic_AtomicLongFieldUpdater_LockedUpdater() ||
238-
holder->name() == ciSymbols::java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl()) {
239-
return true;
240-
}
241237
return TrustFinalNonStaticFields;
242238
}
243239

src/hotspot/share/ci/ciInstanceKlass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) :
6565
_has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods();
6666
_is_hidden = ik->is_hidden();
6767
_is_record = ik->is_record();
68+
_trust_final_fields = ik->trust_final_fields();
6869
_nonstatic_fields = nullptr; // initialized lazily by compute_nonstatic_fields:
6970
_has_injected_fields = -1;
7071
_implementor = nullptr; // we will fill these lazily

src/hotspot/share/ci/ciInstanceKlass.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class ciInstanceKlass : public ciKlass {
5959
bool _has_nonstatic_concrete_methods;
6060
bool _is_hidden;
6161
bool _is_record;
62+
bool _trust_final_fields;
6263
bool _has_trusted_loader;
6364

6465
ciFlags _flags;
@@ -207,6 +208,10 @@ class ciInstanceKlass : public ciKlass {
207208
return _is_record;
208209
}
209210

211+
bool trust_final_fields() const {
212+
return _trust_final_fields;
213+
}
214+
210215
ciInstanceKlass* get_canonical_holder(int offset);
211216
ciField* get_field_by_offset(int field_offset, bool is_static);
212217
ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static);

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ class AnnotationCollector : public ResourceObj{
943943
_java_lang_Deprecated_for_removal,
944944
_jdk_internal_vm_annotation_AOTSafeClassInitializer,
945945
_method_AOTRuntimeSetup,
946+
_jdk_internal_vm_annotation_TrustFinalFields,
946947
_annotation_LIMIT
947948
};
948949
const Location _location;
@@ -1878,6 +1879,11 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
18781879
if (!privileged) break; // only allow in privileged code
18791880
return _field_Stable;
18801881
}
1882+
case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_TrustFinalFields_signature): {
1883+
if (_location != _in_class) break; // only allow for classes
1884+
if (!privileged) break; // only allow in privileged code
1885+
return _jdk_internal_vm_annotation_TrustFinalFields;
1886+
}
18811887
case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Contended_signature): {
18821888
if (_location != _in_field && _location != _in_class) {
18831889
break; // only allow for fields and classes
@@ -1992,6 +1998,9 @@ void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
19921998
if (has_annotation(_jdk_internal_vm_annotation_AOTSafeClassInitializer)) {
19931999
ik->set_has_aot_safe_initializer();
19942000
}
2001+
if (has_annotation(_jdk_internal_vm_annotation_TrustFinalFields)) {
2002+
ik->set_trust_final_fields(true);
2003+
}
19952004
}
19962005

19972006
#define MAX_ARGS_SIZE 255

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,6 @@ class SerializeClosure;
245245
\
246246
/* Concurrency support */ \
247247
template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
248-
template(java_util_concurrent_atomic_AtomicIntegerFieldUpdater_Impl, "java/util/concurrent/atomic/AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl") \
249-
template(java_util_concurrent_atomic_AtomicLongFieldUpdater_CASUpdater, "java/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater") \
250-
template(java_util_concurrent_atomic_AtomicLongFieldUpdater_LockedUpdater, "java/util/concurrent/atomic/AtomicLongFieldUpdater$LockedUpdater") \
251-
template(java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl, "java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl") \
252248
template(jdk_internal_vm_annotation_Contended_signature, "Ljdk/internal/vm/annotation/Contended;") \
253249
template(jdk_internal_vm_annotation_ReservedStackAccess_signature, "Ljdk/internal/vm/annotation/ReservedStackAccess;") \
254250
template(jdk_internal_ValueBased_signature, "Ljdk/internal/ValueBased;") \
@@ -302,6 +298,7 @@ class SerializeClosure;
302298
template(jdk_internal_misc_Scoped_signature, "Ljdk/internal/misc/ScopedMemoryAccess$Scoped;") \
303299
template(jdk_internal_vm_annotation_IntrinsicCandidate_signature, "Ljdk/internal/vm/annotation/IntrinsicCandidate;") \
304300
template(jdk_internal_vm_annotation_Stable_signature, "Ljdk/internal/vm/annotation/Stable;") \
301+
template(jdk_internal_vm_annotation_TrustFinalFields_signature, "Ljdk/internal/vm/annotation/TrustFinalFields;") \
305302
\
306303
template(jdk_internal_vm_annotation_ChangesCurrentThread_signature, "Ljdk/internal/vm/annotation/ChangesCurrentThread;") \
307304
template(jdk_internal_vm_annotation_JvmtiHideEvents_signature, "Ljdk/internal/vm/annotation/JvmtiHideEvents;") \

src/hotspot/share/oops/instanceKlass.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ class InstanceKlass: public Klass {
353353
int static_oop_field_count() const { return (int)_static_oop_field_count; }
354354
void set_static_oop_field_count(u2 size) { _static_oop_field_count = size; }
355355

356+
bool trust_final_fields() { return _misc_flags.trust_final_fields(); }
357+
void set_trust_final_fields(bool value) { _misc_flags.set_trust_final_fields(value); }
358+
356359
// Java itable
357360
int itable_length() const { return _itable_len; }
358361
void set_itable_length(int len) { _itable_len = len; }

src/hotspot/share/oops/instanceKlassFlags.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class InstanceKlassFlags {
5454
flag(has_localvariable_table , 1 << 11) /* has localvariable information */ \
5555
flag(has_miranda_methods , 1 << 12) /* True if this class has miranda methods in it's vtable */ \
5656
flag(has_final_method , 1 << 13) /* True if klass has final method */ \
57+
flag(trust_final_fields , 1 << 14) /* All instance final fields in this class should be trusted */ \
5758
/* end of list */
5859

5960
#define IK_FLAGS_ENUM_NAME(name, value) _misc_##name = value,

src/java.base/share/classes/java/util/Optional.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
package java.util;
2727

28-
import jdk.internal.vm.annotation.Stable;
28+
import jdk.internal.vm.annotation.TrustFinalFields;
2929

3030
import java.util.function.Consumer;
3131
import java.util.function.Function;
@@ -62,6 +62,7 @@
6262
* @since 1.8
6363
*/
6464
@jdk.internal.ValueBased
65+
@TrustFinalFields
6566
public final class Optional<T> {
6667
/**
6768
* Common instance for {@code empty()}.
@@ -71,7 +72,6 @@ public final class Optional<T> {
7172
/**
7273
* If non-null, the value; if null, indicates no value is present
7374
*/
74-
@Stable
7575
private final T value;
7676

7777
/**

src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import jdk.internal.misc.Unsafe;
4343
import jdk.internal.reflect.CallerSensitive;
4444
import jdk.internal.reflect.Reflection;
45+
import jdk.internal.vm.annotation.TrustFinalFields;
46+
4547
import java.lang.invoke.VarHandle;
4648

4749
/**
@@ -371,6 +373,7 @@ public final int accumulateAndGet(T obj, int x,
371373
/**
372374
* Standard hotspot implementation using intrinsics.
373375
*/
376+
@TrustFinalFields
374377
private static final class AtomicIntegerFieldUpdaterImpl<T>
375378
extends AtomicIntegerFieldUpdater<T> {
376379
private static final Unsafe U = Unsafe.getUnsafe();

src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import jdk.internal.misc.Unsafe;
4343
import jdk.internal.reflect.CallerSensitive;
4444
import jdk.internal.reflect.Reflection;
45+
import jdk.internal.vm.annotation.TrustFinalFields;
46+
4547
import java.lang.invoke.VarHandle;
4648

4749
/**
@@ -368,6 +370,7 @@ public final long accumulateAndGet(T obj, long x,
368370
return next;
369371
}
370372

373+
@TrustFinalFields
371374
private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
372375
private static final Unsafe U = Unsafe.getUnsafe();
373376
private final long offset;

0 commit comments

Comments
 (0)