提交 d6270254 编写于 作者: C coleenp

7102776: Pack instanceKlass boolean fields into single u1 field

Summary: Reduce class runtime memory usage by packing 4 instanceKlass boolean fields into single u1 field. Save 4-byte for each loaded class.
Reviewed-by: dholmes, bobv, phh, twisti, never, coleenp
Contributed-by: NJiangli Zhou <jiangli.zhou@oracle.com>
上级 437d3fc6
...@@ -63,6 +63,8 @@ public class InstanceKlass extends Klass { ...@@ -63,6 +63,8 @@ public class InstanceKlass extends Klass {
private static int CLASS_STATE_FULLY_INITIALIZED; private static int CLASS_STATE_FULLY_INITIALIZED;
private static int CLASS_STATE_INITIALIZATION_ERROR; private static int CLASS_STATE_INITIALIZATION_ERROR;
private static int IS_MARKED_DEPENDENT_MASK;
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("instanceKlass"); Type type = db.lookupType("instanceKlass");
arrayKlasses = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize()); arrayKlasses = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize());
...@@ -90,7 +92,7 @@ public class InstanceKlass extends Klass { ...@@ -90,7 +92,7 @@ public class InstanceKlass extends Klass {
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize()); staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize()); nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize()); miscFlags = new CIntField(type.getCIntegerField("_misc_flags"), Oop.getHeaderSize());
initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize()); initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize()); vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize());
itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize()); itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize());
...@@ -118,6 +120,8 @@ public class InstanceKlass extends Klass { ...@@ -118,6 +120,8 @@ public class InstanceKlass extends Klass {
CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue(); CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue();
CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue(); CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue();
IS_MARKED_DEPENDENT_MASK = db.lookupIntConstant("instanceKlass::IS_MARKED_DEPENDENT").intValue();
} }
InstanceKlass(OopHandle handle, ObjectHeap heap) { InstanceKlass(OopHandle handle, ObjectHeap heap) {
...@@ -151,7 +155,7 @@ public class InstanceKlass extends Klass { ...@@ -151,7 +155,7 @@ public class InstanceKlass extends Klass {
private static CIntField staticFieldSize; private static CIntField staticFieldSize;
private static CIntField staticOopFieldCount; private static CIntField staticOopFieldCount;
private static CIntField nonstaticOopMapSize; private static CIntField nonstaticOopMapSize;
private static CIntField isMarkedDependent; private static CIntField miscFlags;
private static CIntField initState; private static CIntField initState;
private static CIntField vtableLen; private static CIntField vtableLen;
private static CIntField itableLen; private static CIntField itableLen;
...@@ -333,7 +337,7 @@ public class InstanceKlass extends Klass { ...@@ -333,7 +337,7 @@ public class InstanceKlass extends Klass {
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); } public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); } public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } public boolean getIsMarkedDependent() { return (miscFlags.getValue(this) & IS_MARKED_DEPENDENT_MASK) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); } public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.getValue(this); } public long getItableLen() { return itableLen.getValue(this); }
public Symbol getGenericSignature() { return getSymbol(genericSignature); } public Symbol getGenericSignature() { return getSymbol(genericSignature); }
...@@ -524,7 +528,7 @@ public class InstanceKlass extends Klass { ...@@ -524,7 +528,7 @@ public class InstanceKlass extends Klass {
visitor.doCInt(staticFieldSize, true); visitor.doCInt(staticFieldSize, true);
visitor.doCInt(staticOopFieldCount, true); visitor.doCInt(staticOopFieldCount, true);
visitor.doCInt(nonstaticOopMapSize, true); visitor.doCInt(nonstaticOopMapSize, true);
visitor.doCInt(isMarkedDependent, true); visitor.doCInt(miscFlags, true);
visitor.doCInt(initState, true); visitor.doCInt(initState, true);
visitor.doCInt(vtableLen, true); visitor.doCInt(vtableLen, true);
visitor.doCInt(itableLen, true); visitor.doCInt(itableLen, true);
......
...@@ -1624,7 +1624,7 @@ void KlassDepChange::initialize() { ...@@ -1624,7 +1624,7 @@ void KlassDepChange::initialize() {
for (ContextStream str(*this); str.next(); ) { for (ContextStream str(*this); str.next(); ) {
klassOop d = str.klass(); klassOop d = str.klass();
assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking"); assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking");
instanceKlass::cast(d)->set_is_marked_dependent(true); instanceKlass::cast(d)->set_is_marked_dependent();
} }
} }
...@@ -1633,7 +1633,7 @@ KlassDepChange::~KlassDepChange() { ...@@ -1633,7 +1633,7 @@ KlassDepChange::~KlassDepChange() {
// Unmark transitive interfaces // Unmark transitive interfaces
for (ContextStream str(*this); str.next(); ) { for (ContextStream str(*this); str.next(); ) {
klassOop d = str.klass(); klassOop d = str.klass();
instanceKlass::cast(d)->set_is_marked_dependent(false); instanceKlass::cast(d)->clear_is_marked_dependent();
} }
} }
......
...@@ -230,10 +230,7 @@ class instanceKlass: public Klass { ...@@ -230,10 +230,7 @@ class instanceKlass: public Klass {
int _static_oop_field_count;// number of static oop fields in this klass int _static_oop_field_count;// number of static oop fields in this klass
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
int _java_fields_count; // The number of declared Java fields int _java_fields_count; // The number of declared Java fields
bool _is_marked_dependent; // used for marking during flushing and deoptimization
bool _rewritten; // methods rewritten.
bool _has_nonstatic_fields; // for sizing with UseCompressedOops
bool _should_verify_class; // allow caching of preverification
u2 _minor_version; // minor version number of class file u2 _minor_version; // minor version number of class file
u2 _major_version; // major version number of class file u2 _major_version; // major version number of class file
ClassState _init_state; // state of class ClassState _init_state; // state of class
...@@ -260,6 +257,19 @@ class instanceKlass: public Klass { ...@@ -260,6 +257,19 @@ class instanceKlass: public Klass {
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
// Compact the following four boolean flags into 1-bit each. These four flags
// were defined as separate boolean fields and each was 1-byte before. Since
// there are 2 bytes unused after the _idnum_allocated_count field, place the
// _misc_flags field after _idnum_allocated_count to utilize the unused bits
// and save total 4-bytes.
enum {
IS_MARKED_DEPENDENT = 0x1, // used for marking during flushing and deoptimization
REWRITTEN = 0x2, // methods rewritten.
HAS_NONSTATIC_FIELDS = 0x4, // for sizing with UseCompressedOops
SHOULD_VERIFY_CLASS = 0x8 // allow caching of preverification
};
u1 _misc_flags;
// embedded Java vtable follows here // embedded Java vtable follows here
// embedded Java itables follows here // embedded Java itables follows here
// embedded static fields follows here // embedded static fields follows here
...@@ -269,8 +279,14 @@ class instanceKlass: public Klass { ...@@ -269,8 +279,14 @@ class instanceKlass: public Klass {
friend class SystemDictionary; friend class SystemDictionary;
public: public:
bool has_nonstatic_fields() const { return _has_nonstatic_fields; } bool has_nonstatic_fields() const { return (_misc_flags & HAS_NONSTATIC_FIELDS) != 0; }
void set_has_nonstatic_fields(bool b) { _has_nonstatic_fields = b; } void set_has_nonstatic_fields(bool b) {
if (b) {
_misc_flags |= HAS_NONSTATIC_FIELDS;
} else {
_misc_flags &= ~HAS_NONSTATIC_FIELDS;
}
}
// field sizes // field sizes
int nonstatic_field_size() const { return _nonstatic_field_size; } int nonstatic_field_size() const { return _nonstatic_field_size; }
...@@ -378,15 +394,23 @@ class instanceKlass: public Klass { ...@@ -378,15 +394,23 @@ class instanceKlass: public Klass {
bool is_in_error_state() const { return _init_state == initialization_error; } bool is_in_error_state() const { return _init_state == initialization_error; }
bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; } bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; }
int get_init_state() { return _init_state; } // Useful for debugging int get_init_state() { return _init_state; } // Useful for debugging
bool is_rewritten() const { return _rewritten; } bool is_rewritten() const { return (_misc_flags & REWRITTEN) != 0; }
// defineClass specified verification // defineClass specified verification
bool should_verify_class() const { return _should_verify_class; } bool should_verify_class() const { return (_misc_flags & SHOULD_VERIFY_CLASS) != 0; }
void set_should_verify_class(bool value) { _should_verify_class = value; } void set_should_verify_class(bool value) {
if (value) {
_misc_flags |= SHOULD_VERIFY_CLASS;
} else {
_misc_flags &= ~SHOULD_VERIFY_CLASS;
}
}
// marking // marking
bool is_marked_dependent() const { return _is_marked_dependent; } bool is_marked_dependent() const { return (_misc_flags & IS_MARKED_DEPENDENT) != 0; }
void set_is_marked_dependent(bool value) { _is_marked_dependent = value; } void set_is_marked_dependent() { _misc_flags |= IS_MARKED_DEPENDENT; }
void clear_is_marked_dependent() { _misc_flags &= ~IS_MARKED_DEPENDENT; }
// initialization (virtuals from Klass) // initialization (virtuals from Klass)
bool should_be_initialized() const; // means that initialize should be called bool should_be_initialized() const; // means that initialize should be called
...@@ -756,7 +780,7 @@ private: ...@@ -756,7 +780,7 @@ private:
#else #else
void set_init_state(ClassState state) { _init_state = state; } void set_init_state(ClassState state) { _init_state = state; }
#endif #endif
void set_rewritten() { _rewritten = true; } void set_rewritten() { _misc_flags |= REWRITTEN; }
void set_init_thread(Thread *thread) { _init_thread = thread; } void set_init_thread(Thread *thread) { _init_thread = thread; }
u2 idnum_allocated_count() const { return _idnum_allocated_count; } u2 idnum_allocated_count() const { return _idnum_allocated_count; }
......
...@@ -399,7 +399,7 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it ...@@ -399,7 +399,7 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it
ik->set_inner_classes(NULL); ik->set_inner_classes(NULL);
ik->set_static_oop_field_count(0); ik->set_static_oop_field_count(0);
ik->set_nonstatic_field_size(0); ik->set_nonstatic_field_size(0);
ik->set_is_marked_dependent(false); ik->clear_is_marked_dependent();
ik->set_init_state(instanceKlass::allocated); ik->set_init_state(instanceKlass::allocated);
ik->set_init_thread(NULL); ik->set_init_thread(NULL);
ik->set_reference_type(rt); ik->set_reference_type(rt);
......
...@@ -307,7 +307,7 @@ static inline uint64_t cast_uint64_t(size_t x) ...@@ -307,7 +307,7 @@ static inline uint64_t cast_uint64_t(size_t x)
nonstatic_field(instanceKlass, _static_field_size, int) \ nonstatic_field(instanceKlass, _static_field_size, int) \
nonstatic_field(instanceKlass, _static_oop_field_count, int) \ nonstatic_field(instanceKlass, _static_oop_field_count, int) \
nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \ nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \
nonstatic_field(instanceKlass, _is_marked_dependent, bool) \ nonstatic_field(instanceKlass, _misc_flags, u1) \
nonstatic_field(instanceKlass, _minor_version, u2) \ nonstatic_field(instanceKlass, _minor_version, u2) \
nonstatic_field(instanceKlass, _major_version, u2) \ nonstatic_field(instanceKlass, _major_version, u2) \
nonstatic_field(instanceKlass, _init_state, instanceKlass::ClassState) \ nonstatic_field(instanceKlass, _init_state, instanceKlass::ClassState) \
...@@ -1362,6 +1362,7 @@ static inline uint64_t cast_uint64_t(size_t x) ...@@ -1362,6 +1362,7 @@ static inline uint64_t cast_uint64_t(size_t x)
/* The compiler thinks this is a different type than */ \ /* The compiler thinks this is a different type than */ \
/* unsigned short on Win32 */ \ /* unsigned short on Win32 */ \
declare_unsigned_integer_type(u2) \ declare_unsigned_integer_type(u2) \
declare_unsigned_integer_type(u1) \
declare_unsigned_integer_type(unsigned) \ declare_unsigned_integer_type(unsigned) \
\ \
/*****************************/ \ /*****************************/ \
...@@ -2385,6 +2386,7 @@ static inline uint64_t cast_uint64_t(size_t x) ...@@ -2385,6 +2386,7 @@ static inline uint64_t cast_uint64_t(size_t x)
declare_constant(instanceKlass::being_initialized) \ declare_constant(instanceKlass::being_initialized) \
declare_constant(instanceKlass::fully_initialized) \ declare_constant(instanceKlass::fully_initialized) \
declare_constant(instanceKlass::initialization_error) \ declare_constant(instanceKlass::initialization_error) \
declare_constant(instanceKlass::IS_MARKED_DEPENDENT) \
\ \
/*********************************/ \ /*********************************/ \
/* Symbol* - symbol max length */ \ /* Symbol* - symbol max length */ \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册