src/share/vm/oops/symbol.hpp

changeset 3682
fc9d8850ab8b
parent 2708
1d1603768966
child 4037
da91efe96a93
equal deleted inserted replaced
3681:51612f0c0a79 3682:fc9d8850ab8b
1 /* 1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
25 #ifndef SHARE_VM_OOPS_SYMBOL_HPP 25 #ifndef SHARE_VM_OOPS_SYMBOL_HPP
26 #define SHARE_VM_OOPS_SYMBOL_HPP 26 #define SHARE_VM_OOPS_SYMBOL_HPP
27 27
28 #include "utilities/utf8.hpp" 28 #include "utilities/utf8.hpp"
29 #include "memory/allocation.hpp" 29 #include "memory/allocation.hpp"
30 #include "runtime/atomic.hpp"
30 31
31 // A Symbol is a canonicalized string. 32 // A Symbol is a canonicalized string.
32 // All Symbols reside in global SymbolTable and are reference counted. 33 // All Symbols reside in global SymbolTable and are reference counted.
33 34
34 // Reference counting 35 // Reference counting
93 // ClassFileParser::parseClassFile() where parsed_name is used in the cleanup 94 // ClassFileParser::parseClassFile() where parsed_name is used in the cleanup
94 // after a failed attempt to load a class. Here parsed_name is a 95 // after a failed attempt to load a class. Here parsed_name is a
95 // TempNewSymbol (passed in as a parameter) so the reference count on its symbol 96 // TempNewSymbol (passed in as a parameter) so the reference count on its symbol
96 // will be decremented when it goes out of scope. 97 // will be decremented when it goes out of scope.
97 98
98 class Symbol : public CHeapObj { 99 class Symbol : public ResourceObj {
99 friend class VMStructs; 100 friend class VMStructs;
100 friend class SymbolTable; 101 friend class SymbolTable;
101 friend class MoveSymbols; 102 friend class MoveSymbols;
102 private: 103 private:
103 volatile int _refcount; 104 volatile int _refcount;
109 // max_symbol_length is constrained by type of _length 110 // max_symbol_length is constrained by type of _length
110 max_symbol_length = (1 << 16) -1 111 max_symbol_length = (1 << 16) -1
111 }; 112 };
112 113
113 static int object_size(int length) { 114 static int object_size(int length) {
114 size_t size = heap_word_size(sizeof(Symbol) + length); 115 size_t size = heap_word_size(sizeof(Symbol) + (length > 0 ? length - 1 : 0));
115 return align_object_size(size); 116 return align_object_size(size);
116 } 117 }
117 118
118 void byte_at_put(int index, int value) { 119 void byte_at_put(int index, int value) {
119 assert(index >=0 && index < _length, "symbol index overflow"); 120 assert(index >=0 && index < _length, "symbol index overflow");
120 _body[index] = value; 121 _body[index] = value;
121 } 122 }
122 123
123 Symbol(const u1* name, int length); 124 Symbol(const u1* name, int length, int refcount);
124 void* operator new(size_t size, int len); 125 void* operator new(size_t size, int len, TRAPS);
126 void* operator new(size_t size, int len, Arena* arena, TRAPS);
125 127
126 public: 128 public:
127 // Low-level access (used with care, since not GC-safe) 129 // Low-level access (used with care, since not GC-safe)
128 const jbyte* base() const { return &_body[0]; } 130 const jbyte* base() const { return &_body[0]; }
129 131
130 int object_size() { return object_size(utf8_length()); } 132 int object_size() { return object_size(utf8_length()); }
131 133
132 // Returns the largest size symbol we can safely hold. 134 // Returns the largest size symbol we can safely hold.
133 static int max_length() { 135 static int max_length() { return max_symbol_length; }
134 return max_symbol_length; 136
135 } 137 int identity_hash() { return _identity_hash; }
136
137 int identity_hash() {
138 return _identity_hash;
139 }
140 138
141 // Reference counting. See comments above this class for when to use. 139 // Reference counting. See comments above this class for when to use.
142 int refcount() const { return _refcount; } 140 int refcount() const { return _refcount; }
143 void increment_refcount(); 141 inline void increment_refcount();
144 void decrement_refcount(); 142 inline void decrement_refcount();
145 143
146 int byte_at(int index) const { 144 int byte_at(int index) const {
147 assert(index >=0 && index < _length, "symbol index overflow"); 145 assert(index >=0 && index < _length, "symbol index overflow");
148 return base()[index]; 146 return base()[index];
149 } 147 }
218 // so use address comparison for speed 216 // so use address comparison for speed
219 int Symbol::fast_compare(Symbol* other) const { 217 int Symbol::fast_compare(Symbol* other) const {
220 return (((uintptr_t)this < (uintptr_t)other) ? -1 218 return (((uintptr_t)this < (uintptr_t)other) ? -1
221 : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1); 219 : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
222 } 220 }
221
222 inline void Symbol::increment_refcount() {
223 // Only increment the refcount if positive. If negative either
224 // overflow has occurred or it is a permanent symbol in a read only
225 // shared archive.
226 if (_refcount >= 0) {
227 Atomic::inc(&_refcount);
228 NOT_PRODUCT(Atomic::inc(&_total_count);)
229 }
230 }
231
232 inline void Symbol::decrement_refcount() {
233 if (_refcount >= 0) {
234 Atomic::dec(&_refcount);
235 #ifdef ASSERT
236 if (_refcount < 0) {
237 print();
238 assert(false, "reference count underflow for symbol");
239 }
240 #endif
241 }
242 }
223 #endif // SHARE_VM_OOPS_SYMBOL_HPP 243 #endif // SHARE_VM_OOPS_SYMBOL_HPP

mercurial