Skip to content

Commit ddb8646

Browse files
committed
8306123: Move InstanceKlass writeable flags
Reviewed-by: iklam, fparain
1 parent 1a41e12 commit ddb8646

File tree

6 files changed

+80
-50
lines changed

6 files changed

+80
-50
lines changed

src/hotspot/share/oops/instanceKlass.hpp

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,11 @@ class InstanceKlass: public Klass {
223223

224224
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
225225

226-
// _is_marked_dependent can be set concurrently, thus cannot be part of the
227-
// _misc_flags right now.
228-
bool _is_marked_dependent; // used for marking during flushing and deoptimization
229-
230226
volatile ClassState _init_state; // state of class
231227

232228
u1 _reference_type; // reference type
233229

234-
// State is set while executing, eventually atomically to not disturb other state
230+
// State is set either at parse time or while executing, atomically to not disturb other state
235231
InstanceKlassFlags _misc_flags;
236232

237233
Monitor* _init_monitor; // mutual exclusion to _init_state and _init_thread.
@@ -531,8 +527,8 @@ class InstanceKlass: public Klass {
531527
void set_should_verify_class(bool value) { _misc_flags.set_should_verify_class(value); }
532528

533529
// marking
534-
bool is_marked_dependent() const { return _is_marked_dependent; }
535-
void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
530+
bool is_marked_dependent() const { return _misc_flags.is_marked_dependent(); }
531+
void set_is_marked_dependent(bool value) { _misc_flags.set_is_marked_dependent(value); }
536532

537533
// initialization (virtuals from Klass)
538534
bool should_be_initialized() const; // means that initialize should be called
@@ -681,16 +677,8 @@ class InstanceKlass: public Klass {
681677
// Redefinition locking. Class can only be redefined by one thread at a time.
682678
// The flag is in access_flags so that it can be set and reset using atomic
683679
// operations, and not be reset by other misc_flag settings.
684-
bool is_being_redefined() const {
685-
return _access_flags.is_being_redefined();
686-
}
687-
void set_is_being_redefined(bool value) {
688-
if (value) {
689-
_access_flags.set_is_being_redefined();
690-
} else {
691-
_access_flags.clear_is_being_redefined();
692-
}
693-
}
680+
bool is_being_redefined() const { return _misc_flags.is_being_redefined(); }
681+
void set_is_being_redefined(bool value) { _misc_flags.set_is_being_redefined(value); }
694682

695683
// RedefineClasses() support for previous versions:
696684
void add_previous_version(InstanceKlass* ik, int emcp_method_count);
@@ -716,13 +704,8 @@ class InstanceKlass: public Klass {
716704
bool is_scratch_class() const { return _misc_flags.is_scratch_class(); }
717705
void set_is_scratch_class() { _misc_flags.set_is_scratch_class(true); }
718706

719-
bool has_resolved_methods() const {
720-
return _access_flags.has_resolved_methods();
721-
}
722-
723-
void set_has_resolved_methods() {
724-
_access_flags.set_has_resolved_methods();
725-
}
707+
bool has_resolved_methods() const { return _misc_flags.has_resolved_methods(); }
708+
void set_has_resolved_methods() { _misc_flags.set_has_resolved_methods(true); }
726709

727710
public:
728711
#if INCLUDE_JVMTI

src/hotspot/share/oops/instanceKlassFlags.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,31 @@
2626
#include "classfile/classLoader.hpp"
2727
#include "classfile/classLoaderData.inline.hpp"
2828
#include "oops/instanceKlassFlags.hpp"
29+
#include "runtime/atomic.hpp"
2930
#include "runtime/safepoint.hpp"
3031
#include "utilities/macros.hpp"
3132

33+
// This can be removed for the atomic bitset functions, when available.
34+
void InstanceKlassFlags::atomic_set_bits(u1 bits) {
35+
// Atomically update the status with the bits given
36+
u1 old_status, new_status, f;
37+
do {
38+
old_status = _status;
39+
new_status = old_status | bits;
40+
f = Atomic::cmpxchg(&_status, old_status, new_status);
41+
} while(f != old_status);
42+
}
43+
44+
void InstanceKlassFlags::atomic_clear_bits(u1 bits) {
45+
// Atomically update the status with the bits given
46+
u1 old_status, new_status, f;
47+
do {
48+
old_status = _status;
49+
new_status = old_status & ~bits;
50+
f = Atomic::cmpxchg(&_status, old_status, new_status);
51+
} while(f != old_status);
52+
}
53+
3254
#if INCLUDE_CDS
3355
void InstanceKlassFlags::set_shared_class_loader_type(s2 loader_type) {
3456
switch (loader_type) {

src/hotspot/share/oops/instanceKlassFlags.hpp

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727

2828
class ClassLoaderData;
2929

30+
// The InstanceKlassFlags class contains the parse-time and writeable flags associated with
31+
// an InstanceKlass, and their associated accessors.
32+
// _flags are parse-time and constant in the InstanceKlass after that. _status are set at runtime and
33+
// require atomic access.
34+
// These flags are JVM internal and not part of the AccessFlags classfile specification.
35+
3036
class InstanceKlassFlags {
3137
friend class VMStructs;
3238
friend class JVMCIVMStructs;
@@ -35,32 +41,45 @@ class InstanceKlassFlags {
3541
flag(rewritten , 1 << 0) /* methods rewritten. */ \
3642
flag(has_nonstatic_fields , 1 << 1) /* for sizing with UseCompressedOops */ \
3743
flag(should_verify_class , 1 << 2) /* allow caching of preverification */ \
38-
flag(unused , 1 << 3) /* not currently used */ \
39-
flag(is_contended , 1 << 4) /* marked with contended annotation */ \
40-
flag(has_nonstatic_concrete_methods , 1 << 5) /* class/superclass/implemented interfaces has non-static, concrete methods */ \
41-
flag(declares_nonstatic_concrete_methods, 1 << 6) /* directly declares non-static, concrete methods */ \
42-
flag(has_been_redefined , 1 << 7) /* class has been redefined */ \
43-
flag(shared_loading_failed , 1 << 8) /* class has been loaded from shared archive */ \
44-
flag(is_scratch_class , 1 << 9) /* class is the redefined scratch class */ \
45-
flag(is_shared_boot_class , 1 << 10) /* defining class loader is boot class loader */ \
46-
flag(is_shared_platform_class , 1 << 11) /* defining class loader is platform class loader */ \
47-
flag(is_shared_app_class , 1 << 12) /* defining class loader is app class loader */ \
48-
flag(has_contended_annotations , 1 << 13) /* has @Contended annotation */ \
49-
flag(has_localvariable_table , 1 << 14) /* has localvariable information */
44+
flag(is_contended , 1 << 3) /* marked with contended annotation */ \
45+
flag(has_nonstatic_concrete_methods , 1 << 4) /* class/superclass/implemented interfaces has non-static, concrete methods */ \
46+
flag(declares_nonstatic_concrete_methods, 1 << 5) /* directly declares non-static, concrete methods */ \
47+
flag(shared_loading_failed , 1 << 6) /* class has been loaded from shared archive */ \
48+
flag(is_shared_boot_class , 1 << 7) /* defining class loader is boot class loader */ \
49+
flag(is_shared_platform_class , 1 << 8) /* defining class loader is platform class loader */ \
50+
flag(is_shared_app_class , 1 << 9) /* defining class loader is app class loader */ \
51+
flag(has_contended_annotations , 1 << 10) /* has @Contended annotation */ \
52+
flag(has_localvariable_table , 1 << 11) /* has localvariable information */
5053

5154
#define IK_FLAGS_ENUM_NAME(name, value) _misc_##name = value,
5255
enum {
5356
IK_FLAGS_DO(IK_FLAGS_ENUM_NAME)
5457
};
5558
#undef IK_FLAGS_ENUM_NAME
5659

60+
#define IK_STATUS_DO(status) \
61+
status(is_being_redefined , 1 << 0) /* True if the klass is being redefined */ \
62+
status(has_resolved_methods , 1 << 1) /* True if the klass has resolved MethodHandle methods */ \
63+
status(has_been_redefined , 1 << 2) /* class has been redefined */ \
64+
status(is_scratch_class , 1 << 3) /* class is the redefined scratch class */ \
65+
status(is_marked_dependent , 1 << 4) /* class is the redefined scratch class */
66+
67+
#define IK_STATUS_ENUM_NAME(name, value) _misc_##name = value,
68+
enum {
69+
IK_STATUS_DO(IK_STATUS_ENUM_NAME)
70+
};
71+
#undef IK_STATUS_ENUM_NAME
72+
5773
u2 shared_loader_type_bits() const {
5874
return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
5975
}
6076

6177
// These flags are write-once before the class is published and then read-only so don't require atomic updates.
6278
u2 _flags;
6379

80+
// These flags are written during execution so require atomic stores
81+
u1 _status;
82+
6483
public:
6584

6685
InstanceKlassFlags() : _flags(0) {}
@@ -87,6 +106,26 @@ class InstanceKlassFlags {
87106

88107
void assign_class_loader_type(const ClassLoaderData* cld);
89108
void assert_is_safe(bool set) NOT_DEBUG_RETURN;
109+
110+
// Create getters and setters for the status values.
111+
#define IK_STATUS_GET(name, ignore) \
112+
bool name() const { return (_status & _misc_##name) != 0; }
113+
IK_STATUS_DO(IK_STATUS_GET)
114+
#undef IK_STATUS_GET
115+
116+
#define IK_STATUS_SET(name, ignore) \
117+
void set_##name(bool b) { \
118+
if (b) { \
119+
atomic_set_bits(_misc_##name); \
120+
} else { \
121+
atomic_clear_bits(_misc_##name); \
122+
} \
123+
}
124+
IK_STATUS_DO(IK_STATUS_SET)
125+
#undef IK_STATUS_SET
126+
127+
void atomic_set_bits(u1 bits);
128+
void atomic_clear_bits(u1 bits);
90129
};
91130

92131
#endif // SHARE_OOPS_INSTANCEKLASSFLAGS_HPP

src/hotspot/share/runtime/vmStructs.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@
236236
nonstatic_field(InstanceKlass, _static_field_size, int) \
237237
nonstatic_field(InstanceKlass, _static_oop_field_count, u2) \
238238
nonstatic_field(InstanceKlass, _nonstatic_oop_map_size, int) \
239-
nonstatic_field(InstanceKlass, _is_marked_dependent, bool) \
240239
volatile_nonstatic_field(InstanceKlass, _init_state, InstanceKlass::ClassState) \
241240
volatile_nonstatic_field(InstanceKlass, _init_thread, JavaThread*) \
242241
nonstatic_field(InstanceKlass, _itable_len, int) \

src/hotspot/share/utilities/accessFlags.hpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ enum {
6868
JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method
6969
JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden
7070
JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class
71-
JVM_ACC_IS_BEING_REDEFINED = 0x00100000, // True if the klass is being redefined.
72-
JVM_ACC_HAS_RESOLVED_METHODS = 0x00200000, // True if the klass has resolved methods
7371

7472
// Method* flags
7573
JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00400000,
@@ -133,13 +131,6 @@ class AccessFlags {
133131
void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); }
134132
void clear_has_localvariable_table() { atomic_clear_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); }
135133

136-
bool is_being_redefined() const { return (_flags & JVM_ACC_IS_BEING_REDEFINED) != 0; }
137-
void set_is_being_redefined() { atomic_set_bits(JVM_ACC_IS_BEING_REDEFINED); }
138-
void clear_is_being_redefined() { atomic_clear_bits(JVM_ACC_IS_BEING_REDEFINED); }
139-
140-
bool has_resolved_methods() const { return (_flags & JVM_ACC_HAS_RESOLVED_METHODS) != 0; }
141-
void set_has_resolved_methods() { atomic_set_bits(JVM_ACC_HAS_RESOLVED_METHODS); }
142-
143134
bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; }
144135

145136
// get .class file flags

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ private static synchronized void initialize(TypeDataBase db) throws WrongTypeExc
8080
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
8181
staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
8282
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
83-
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
8483
initState = new CIntField(type.getCIntegerField("_init_state"), 0);
8584
itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
8685
if (VM.getVM().isJvmtiSupported()) {
@@ -145,7 +144,6 @@ public InstanceKlass(Address addr) {
145144
private static CIntField staticFieldSize;
146145
private static CIntField staticOopFieldCount;
147146
private static CIntField nonstaticOopMapSize;
148-
private static CIntField isMarkedDependent;
149147
private static CIntField initState;
150148
private static CIntField itableLen;
151149
private static AddressField breakpoints;
@@ -373,7 +371,6 @@ public int getAllFieldsCount() {
373371
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
374372
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
375373
public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
376-
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
377374
public long getItableLen() { return itableLen.getValue(this); }
378375
public long majorVersion() { return getConstants().majorVersion(); }
379376
public long minorVersion() { return getConstants().minorVersion(); }
@@ -571,7 +568,6 @@ public void iterateFields(MetadataVisitor visitor) {
571568
visitor.doCInt(staticFieldSize, true);
572569
visitor.doCInt(staticOopFieldCount, true);
573570
visitor.doCInt(nonstaticOopMapSize, true);
574-
visitor.doCInt(isMarkedDependent, true);
575571
visitor.doCInt(initState, true);
576572
visitor.doCInt(itableLen, true);
577573
}

0 commit comments

Comments
 (0)