Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.

Commit 58a5910

Browse files
committed
8239347: Refactor Symbol to make _length a standalone field again
Reviewed-by: iklam, coleenp
1 parent 90ee2c3 commit 58a5910

File tree

7 files changed

+38
-46
lines changed

7 files changed

+38
-46
lines changed

make/hotspot/src/native/dtrace/generateJvmOffsets.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ int generateJvmOffsets(GEN_variant gen_variant) {
213213
GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE);
214214
GEN_VALUE(ConstMethod_has_linenumber_table, ConstMethod::_has_linenumber_table);
215215
GEN_OFFS(AccessFlags, _flags);
216-
GEN_OFFS(Symbol, _length_and_refcount);
216+
GEN_OFFS(Symbol, _length);
217217
GEN_OFFS(Symbol, _body);
218218
printf("\n");
219219

src/hotspot/os/solaris/dtrace/jhelper.d

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ dtrace:helper:ustack:
111111
copyin_offset(OFFSET_HeapBlockHeader_used);
112112
copyin_offset(OFFSET_oopDesc_metadata);
113113

114-
copyin_offset(OFFSET_Symbol_length_and_refcount);
114+
copyin_offset(OFFSET_Symbol_length);
115115
copyin_offset(OFFSET_Symbol_body);
116116

117117
copyin_offset(OFFSET_Method_constMethod);
@@ -463,27 +463,24 @@ dtrace:helper:ustack:
463463
/* The symbol is a CPSlot and has lower bit set to indicate metadata */
464464
this->nameSymbol &= (~1); /* remove metadata lsb */
465465

466-
/* Because sparc is big endian, the top half length is at the correct offset. */
467466
this->nameSymbolLength = copyin_uint16(this->nameSymbol +
468-
OFFSET_Symbol_length_and_refcount);
467+
OFFSET_Symbol_length);
469468

470469
this->signatureSymbol = copyin_ptr(this->constantPool +
471470
this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool);
472471
this->signatureSymbol &= (~1); /* remove metadata lsb */
473472

474-
/* Because sparc is big endian, the top half length is at the correct offset. */
475473
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
476-
OFFSET_Symbol_length_and_refcount);
474+
OFFSET_Symbol_length);
477475

478476
this->klassPtr = copyin_ptr(this->constantPool +
479477
OFFSET_ConstantPool_pool_holder);
480478

481479
this->klassSymbol = copyin_ptr(this->klassPtr +
482480
OFFSET_Klass_name);
483481

484-
/* Because sparc is big endian, the top half length is at the correct offset. */
485482
this->klassSymbolLength = copyin_uint16(this->klassSymbol +
486-
OFFSET_Symbol_length_and_refcount);
483+
OFFSET_Symbol_length);
487484

488485
/*
489486
* Enough for three strings, plus the '.', plus the trailing '\0'.

src/hotspot/share/oops/symbol.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,18 @@
3737
#include "runtime/os.hpp"
3838
#include "utilities/utf8.hpp"
3939

40-
uint32_t Symbol::pack_length_and_refcount(int length, int refcount) {
41-
STATIC_ASSERT(max_symbol_length == ((1 << 16) - 1));
40+
uint32_t Symbol::pack_hash_and_refcount(short hash, int refcount) {
4241
STATIC_ASSERT(PERM_REFCOUNT == ((1 << 16) - 1));
43-
assert(length >= 0, "negative length");
44-
assert(length <= max_symbol_length, "too long symbol");
4542
assert(refcount >= 0, "negative refcount");
4643
assert(refcount <= PERM_REFCOUNT, "invalid refcount");
47-
uint32_t hi = length;
44+
uint32_t hi = hash;
4845
uint32_t lo = refcount;
4946
return (hi << 16) | lo;
5047
}
5148

5249
Symbol::Symbol(const u1* name, int length, int refcount) {
53-
_length_and_refcount = pack_length_and_refcount(length, refcount);
54-
_identity_hash = (short)os::random();
50+
_hash_and_refcount = pack_hash_and_refcount((short)os::random(), refcount);
51+
_length = length;
5552
_body[0] = 0; // in case length == 0
5653
for (int i = 0; i < length; i++) {
5754
byte_at_put(i, name[i]);
@@ -78,7 +75,7 @@ void Symbol::operator delete(void *p) {
7875
void Symbol::set_permanent() {
7976
// This is called at a safepoint during dumping of a dynamic CDS archive.
8077
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
81-
_length_and_refcount = pack_length_and_refcount(length(), PERM_REFCOUNT);
78+
_hash_and_refcount = pack_hash_and_refcount(extract_hash(_hash_and_refcount), PERM_REFCOUNT);
8279
}
8380

8481

@@ -282,7 +279,7 @@ void Symbol::print_as_signature_external_parameters(outputStream *os) {
282279
// a thread could be concurrently removing the Symbol. This is used during SymbolTable
283280
// lookup to avoid reviving a dead Symbol.
284281
bool Symbol::try_increment_refcount() {
285-
uint32_t found = _length_and_refcount;
282+
uint32_t found = _hash_and_refcount;
286283
while (true) {
287284
uint32_t old_value = found;
288285
int refc = extract_refcount(old_value);
@@ -291,7 +288,7 @@ bool Symbol::try_increment_refcount() {
291288
} else if (refc == 0) {
292289
return false; // dead, can't revive.
293290
} else {
294-
found = Atomic::cmpxchg(&_length_and_refcount, old_value, old_value + 1);
291+
found = Atomic::cmpxchg(&_hash_and_refcount, old_value, old_value + 1);
295292
if (found == old_value) {
296293
return true; // successfully updated.
297294
}
@@ -321,7 +318,7 @@ void Symbol::increment_refcount() {
321318
// to check the value after attempting to decrement so that if another
322319
// thread increments to PERM_REFCOUNT the value is not decremented.
323320
void Symbol::decrement_refcount() {
324-
uint32_t found = _length_and_refcount;
321+
uint32_t found = _hash_and_refcount;
325322
while (true) {
326323
uint32_t old_value = found;
327324
int refc = extract_refcount(old_value);
@@ -334,7 +331,7 @@ void Symbol::decrement_refcount() {
334331
#endif
335332
return;
336333
} else {
337-
found = Atomic::cmpxchg(&_length_and_refcount, old_value, old_value - 1);
334+
found = Atomic::cmpxchg(&_hash_and_refcount, old_value, old_value - 1);
338335
if (found == old_value) {
339336
return; // successfully updated.
340337
}
@@ -344,7 +341,7 @@ void Symbol::decrement_refcount() {
344341
}
345342

346343
void Symbol::make_permanent() {
347-
uint32_t found = _length_and_refcount;
344+
uint32_t found = _hash_and_refcount;
348345
while (true) {
349346
uint32_t old_value = found;
350347
int refc = extract_refcount(old_value);
@@ -357,8 +354,8 @@ void Symbol::make_permanent() {
357354
#endif
358355
return;
359356
} else {
360-
int len = extract_length(old_value);
361-
found = Atomic::cmpxchg(&_length_and_refcount, old_value, pack_length_and_refcount(len, PERM_REFCOUNT));
357+
int hash = extract_hash(old_value);
358+
found = Atomic::cmpxchg(&_hash_and_refcount, old_value, pack_hash_and_refcount(hash, PERM_REFCOUNT));
362359
if (found == old_value) {
363360
return; // successfully updated.
364361
}

src/hotspot/share/oops/symbol.hpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,13 @@ class Symbol : public MetaspaceObj {
106106

107107
private:
108108

109-
// This is an int because it needs atomic operation on the refcount. Mask length
109+
// This is an int because it needs atomic operation on the refcount. Mask hash
110110
// in high half word. length is the number of UTF8 characters in the symbol
111-
volatile uint32_t _length_and_refcount;
112-
short _identity_hash;
111+
volatile uint32_t _hash_and_refcount;
112+
u2 _length;
113113
u1 _body[2];
114114

115115
enum {
116-
// max_symbol_length must fit into the top 16 bits of _length_and_refcount
117116
max_symbol_length = (1 << 16) -1
118117
};
119118

@@ -137,11 +136,11 @@ class Symbol : public MetaspaceObj {
137136

138137
void operator delete(void* p);
139138

140-
static int extract_length(uint32_t value) { return value >> 16; }
139+
static short extract_hash(uint32_t value) { return (short)(value >> 16); }
141140
static int extract_refcount(uint32_t value) { return value & 0xffff; }
142-
static uint32_t pack_length_and_refcount(int length, int refcount);
141+
static uint32_t pack_hash_and_refcount(short hash, int refcount);
143142

144-
int length() const { return extract_length(_length_and_refcount); }
143+
int length() const { return _length; }
145144

146145
public:
147146
// Low-level access (used with care, since not GC-safe)
@@ -157,12 +156,12 @@ class Symbol : public MetaspaceObj {
157156
static int max_length() { return max_symbol_length; }
158157
unsigned identity_hash() const {
159158
unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3));
160-
return ((unsigned)_identity_hash & 0xffff) |
159+
return ((unsigned)extract_hash(_hash_and_refcount) & 0xffff) |
161160
((addr_bits ^ (length() << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
162161
}
163162

164163
// Reference counting. See comments above this class for when to use.
165-
int refcount() const { return extract_refcount(_length_and_refcount); }
164+
int refcount() const { return extract_refcount(_hash_and_refcount); }
166165
bool try_increment_refcount();
167166
void increment_refcount();
168167
void decrement_refcount();

src/hotspot/share/runtime/vmStructs.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
327327
nonstatic_field(ConstMethod, _size_of_parameters, u2) \
328328
nonstatic_field(ObjArrayKlass, _element_klass, Klass*) \
329329
nonstatic_field(ObjArrayKlass, _bottom_klass, Klass*) \
330-
volatile_nonstatic_field(Symbol, _length_and_refcount, unsigned int) \
331-
nonstatic_field(Symbol, _identity_hash, short) \
330+
volatile_nonstatic_field(Symbol, _hash_and_refcount, unsigned int) \
331+
nonstatic_field(Symbol, _length, u2) \
332332
unchecked_nonstatic_field(Symbol, _body, sizeof(u1)) /* NOTE: no type */ \
333333
nonstatic_field(Symbol, _body[0], u1) \
334334
nonstatic_field(TypeArrayKlass, _max_length, jint) \

src/java.base/solaris/native/libjvm_db/libjvm_db.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,7 @@ name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t siz
552552
CHECK_FAIL(err);
553553
// The symbol is a CPSlot and has lower bit set to indicate metadata
554554
nameSymbol &= (~1); // remove metadata lsb
555-
// The length is in the top half of the word.
556-
err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length_and_refcount, &nameSymbolLength, 2);
555+
err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
557556
CHECK_FAIL(err);
558557
nameString = (char*)calloc(nameSymbolLength + 1, 1);
559558
err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
@@ -565,7 +564,7 @@ name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t siz
565564
err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol);
566565
CHECK_FAIL(err);
567566
signatureSymbol &= (~1); // remove metadata lsb
568-
err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length_and_refcount, &signatureSymbolLength, 2);
567+
err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
569568
CHECK_FAIL(err);
570569
signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
571570
err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
@@ -576,7 +575,7 @@ name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t siz
576575
CHECK_FAIL(err);
577576
err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol);
578577
CHECK_FAIL(err);
579-
err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length_and_refcount, &klassSymbolLength, 2);
578+
err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
580579
CHECK_FAIL(err);
581580
klassString = (char*)calloc(klassSymbolLength + 1, 1);
582581
err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ public void update(Observable o, Object data) {
4545

4646
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
4747
Type type = db.lookupType("Symbol");
48-
lengthAndRefcount = type.getCIntegerField("_length_and_refcount");
48+
lengthField = type.getCIntegerField("_length");
4949
baseOffset = type.getField("_body").getOffset();
50-
idHash = type.getCIntegerField("_identity_hash");
50+
idHashAndRefcount = type.getCIntegerField("_hash_and_refcount");
5151
}
5252

5353
public static Symbol create(Address addr) {
@@ -66,19 +66,18 @@ public static Symbol create(Address addr) {
6666
private static long baseOffset; // tells where the array part starts
6767

6868
// Fields
69-
private static CIntegerField lengthAndRefcount;
69+
private static CIntegerField lengthField;
70+
// idHash is a short packed into the high bits of a 32-bit integer with refcount
71+
private static CIntegerField idHashAndRefcount;
7072

7173
// Accessors for declared fields
7274
public long getLength() {
73-
long i = lengthAndRefcount.getValue(this.addr);
74-
return (i >> 16) & 0xffff;
75+
return lengthField.getValue(this.addr);
7576
}
7677

7778
public byte getByteAt(long index) {
7879
return addr.getJByteAt(baseOffset + index);
7980
}
80-
// _identity_hash is a short
81-
private static CIntegerField idHash;
8281

8382
public long identityHash() {
8483
long addr_value = getAddress().asLongValue();
@@ -87,7 +86,8 @@ public long identityHash() {
8786
int length = (int)getLength();
8887
int byte0 = getByteAt(0);
8988
int byte1 = getByteAt(1);
90-
long id_hash = 0xffffL & (long)idHash.getValue(this.addr);
89+
long id_hash = (long)idHashAndRefcount.getValue(this.addr);
90+
id_hash = (id_hash >> 16) & 0xffff;
9191
return (id_hash |
9292
((addr_bits ^ (length << 8) ^ ((byte0 << 8) | byte1)) << 16)) & 0xffffffffL;
9393
}

0 commit comments

Comments
 (0)