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 |