< prev index next >
src/hotspot/share/oops/symbol.hpp
Print this page
*** 94,118 ****
// This cannot be inherited from ResourceObj because it cannot have a vtable.
// Since sometimes this is allocated from Metadata, pick a base allocation
// type without virtual functions.
class ClassLoaderData;
! // Set _refcount to PERM_REFCOUNT to prevent the Symbol from being GC'ed.
#ifndef PERM_REFCOUNT
! #define PERM_REFCOUNT -1
#endif
class Symbol : public MetaspaceObj {
friend class VMStructs;
friend class SymbolTable;
friend class MoveSymbols;
private:
! ATOMIC_SHORT_PAIR(
! volatile short _refcount, // needs atomic operation
! unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op)
! );
short _identity_hash;
jbyte _body[2];
enum {
// max_symbol_length is constrained by type of _length
--- 94,118 ----
// This cannot be inherited from ResourceObj because it cannot have a vtable.
// Since sometimes this is allocated from Metadata, pick a base allocation
// type without virtual functions.
class ClassLoaderData;
! // Set _refcount to PERM_REFCOUNT to prevent the Symbol from being freed.
#ifndef PERM_REFCOUNT
! #define PERM_REFCOUNT 0xffff
#endif
class Symbol : public MetaspaceObj {
friend class VMStructs;
friend class SymbolTable;
friend class MoveSymbols;
private:
!
! // This is an int because it needs atomic operation on the refcount. Mask length
! // in high half word. length is the number of UTF8 characters in the symbol
! volatile uint32_t _length_and_refcount;
short _identity_hash;
jbyte _body[2];
enum {
// max_symbol_length is constrained by type of _length
*** 127,147 ****
// minimum number of natural words needed to hold these bits (no non-heap version)
return (int)heap_word_size(byte_size(length));
}
void byte_at_put(int index, int value) {
! assert(index >=0 && index < _length, "symbol index overflow");
_body[index] = value;
}
Symbol(const u1* name, int length, int refcount);
void* operator new(size_t size, int len, TRAPS) throw();
void* operator new(size_t size, int len, Arena* arena, TRAPS) throw();
void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS) throw();
void operator delete(void* p);
public:
// Low-level access (used with care, since not GC-safe)
const jbyte* base() const { return &_body[0]; }
int size() { return size(utf8_length()); }
--- 127,153 ----
// minimum number of natural words needed to hold these bits (no non-heap version)
return (int)heap_word_size(byte_size(length));
}
void byte_at_put(int index, int value) {
! assert(index >=0 && index < length(), "symbol index overflow");
_body[index] = value;
}
Symbol(const u1* name, int length, int refcount);
void* operator new(size_t size, int len, TRAPS) throw();
void* operator new(size_t size, int len, Arena* arena, TRAPS) throw();
void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS) throw();
void operator delete(void* p);
+ static int extract_length(uint32_t value) { return value >> 16; }
+ static int extract_refcount(uint32_t value) { return value & 0xffff; }
+ static uint32_t pack_length_and_refcount(int length, int refcount);
+
+ int length() const { return extract_length(_length_and_refcount); }
+
public:
// Low-level access (used with care, since not GC-safe)
const jbyte* base() const { return &_body[0]; }
int size() { return size(utf8_length()); }
*** 153,184 ****
// Returns the largest size symbol we can safely hold.
static int max_length() { return max_symbol_length; }
unsigned identity_hash() const {
unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3));
return ((unsigned)_identity_hash & 0xffff) |
! ((addr_bits ^ (_length << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
}
// For symbol table alternate hashing
unsigned int new_hash(juint seed);
// Reference counting. See comments above this class for when to use.
! int refcount() const { return _refcount; }
void increment_refcount();
void decrement_refcount();
bool is_permanent() {
! return (_refcount == PERM_REFCOUNT);
}
int byte_at(int index) const {
! assert(index >=0 && index < _length, "symbol index overflow");
return base()[index];
}
const jbyte* bytes() const { return base(); }
! int utf8_length() const { return _length; }
// Compares the symbol with a string.
bool equals(const char* str, int len) const {
int l = utf8_length();
if (l != len) return false;
--- 159,191 ----
// Returns the largest size symbol we can safely hold.
static int max_length() { return max_symbol_length; }
unsigned identity_hash() const {
unsigned addr_bits = (unsigned)((uintptr_t)this >> (LogMinObjAlignmentInBytes + 3));
return ((unsigned)_identity_hash & 0xffff) |
! ((addr_bits ^ (length() << 8) ^ (( _body[0] << 8) | _body[1])) << 16);
}
// For symbol table alternate hashing
unsigned int new_hash(juint seed);
// Reference counting. See comments above this class for when to use.
! int refcount() const { return extract_refcount(_length_and_refcount); }
! bool try_increment_refcount();
void increment_refcount();
void decrement_refcount();
bool is_permanent() {
! return (refcount() == PERM_REFCOUNT);
}
int byte_at(int index) const {
! assert(index >=0 && index < length(), "symbol index overflow");
return base()[index];
}
const jbyte* bytes() const { return base(); }
! int utf8_length() const { return length(); }
// Compares the symbol with a string.
bool equals(const char* str, int len) const {
int l = utf8_length();
if (l != len) return false;
< prev index next >