src/share/vm/oops/symbol.hpp

Mon, 12 Nov 2012 14:03:53 -0800

author
minqi
date
Mon, 12 Nov 2012 14:03:53 -0800
changeset 4267
bd7a7ce2e264
parent 4037
da91efe96a93
child 4675
63e54c37ac64
permissions
-rw-r--r--

6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com

duke@435 1 /*
coleenp@3682 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
coleenp@2497 25 #ifndef SHARE_VM_OOPS_SYMBOL_HPP
coleenp@2497 26 #define SHARE_VM_OOPS_SYMBOL_HPP
stefank@2314 27
stefank@2314 28 #include "utilities/utf8.hpp"
coleenp@2497 29 #include "memory/allocation.hpp"
coleenp@3682 30 #include "runtime/atomic.hpp"
stefank@2314 31
coleenp@2497 32 // A Symbol is a canonicalized string.
coleenp@2497 33 // All Symbols reside in global SymbolTable and are reference counted.
duke@435 34
coleenp@2497 35 // Reference counting
coleenp@2497 36 //
coleenp@2497 37 // All Symbols are allocated and added to the SymbolTable.
coleenp@2497 38 // When a class is unloaded, the reference counts of the Symbol pointers in
coleenp@4037 39 // the ConstantPool and in InstanceKlass (see release_C_heap_structures) are
coleenp@2497 40 // decremented. When the reference count for a Symbol goes to 0, the garbage
coleenp@2497 41 // collector can free the Symbol and remove it from the SymbolTable.
coleenp@2497 42 //
coleenp@2497 43 // 0) Symbols need to be reference counted when a pointer to the Symbol is
coleenp@2497 44 // saved in persistent storage. This does not include the pointer
coleenp@2497 45 // in the SymbolTable bucket (the _literal field in HashtableEntry)
coleenp@2497 46 // that points to the Symbol. All other stores of a Symbol*
coleenp@2497 47 // to a field of a persistent variable (e.g., the _name filed in
coleenp@2497 48 // FieldAccessInfo or _ptr in a CPSlot) is reference counted.
coleenp@2497 49 //
coleenp@2497 50 // 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for
coleenp@2497 51 // "name" and returns a pointer to F or finds a pre-existing Symbol F for
coleenp@2497 52 // "name" and returns a pointer to it. In both cases the reference count for F
coleenp@2497 53 // is incremented under the assumption that a pointer to F will be created from
coleenp@2497 54 // the return value. Thus the increment of the reference count is on the lookup
coleenp@2497 55 // and not on the assignment to the new Symbol*. That is
coleenp@2497 56 // Symbol* G = lookup()
coleenp@2497 57 // ^ increment on lookup()
coleenp@2497 58 // and not
coleenp@2497 59 // Symbol* G = lookup()
coleenp@2497 60 // ^ increment on assignmnet
coleenp@2497 61 // The reference count must be decremented manually when the copy of the
coleenp@2497 62 // pointer G is destroyed.
coleenp@2497 63 //
coleenp@2497 64 // 2) For a local Symbol* A that is a copy of an existing Symbol* B, the
coleenp@2497 65 // reference counting is elided when the scope of B is greater than the scope
coleenp@2497 66 // of A. For example, in the code fragment
coleenp@2497 67 // below "klass" is passed as a parameter to the method. Symbol* "kn"
coleenp@2497 68 // is a copy of the name in "klass".
coleenp@2497 69 //
coleenp@2497 70 // Symbol* kn = klass->name();
coleenp@2497 71 // unsigned int d_hash = dictionary()->compute_hash(kn, class_loader);
coleenp@2497 72 //
coleenp@2497 73 // The scope of "klass" is greater than the scope of "kn" so the reference
coleenp@2497 74 // counting for "kn" is elided.
coleenp@2497 75 //
coleenp@2497 76 // Symbol* copied from ConstantPool entries are good candidates for reference
coleenp@2497 77 // counting elision. The ConstantPool entries for a class C exist until C is
coleenp@2497 78 // unloaded. If a Symbol* is copied out of the ConstantPool into Symbol* X,
coleenp@2497 79 // the Symbol* in the ConstantPool will in general out live X so the reference
coleenp@2497 80 // counting on X can be elided.
coleenp@2497 81 //
coleenp@2497 82 // For cases where the scope of A is not greater than the scope of B,
coleenp@2497 83 // the reference counting is explicitly done. See ciSymbol,
coleenp@2497 84 // ResolutionErrorEntry and ClassVerifier for examples.
coleenp@2497 85 //
coleenp@2497 86 // 3) When a Symbol K is created for temporary use, generally for substrings of
coleenp@2497 87 // an existing symbol or to create a new symbol, assign it to a
coleenp@2497 88 // TempNewSymbol. The SymbolTable methods new_symbol(), lookup()
coleenp@2497 89 // and probe() all potentially return a pointer to a new Symbol.
coleenp@2497 90 // The allocation (or lookup) of K increments the reference count for K
coleenp@2497 91 // and the destructor decrements the reference count.
coleenp@2497 92 //
coleenp@2497 93 // Another example of TempNewSymbol usage is parsed_name used in
coleenp@2497 94 // ClassFileParser::parseClassFile() where parsed_name is used in the cleanup
coleenp@2497 95 // after a failed attempt to load a class. Here parsed_name is a
coleenp@2497 96 // TempNewSymbol (passed in as a parameter) so the reference count on its symbol
coleenp@2497 97 // will be decremented when it goes out of scope.
coleenp@2497 98
coleenp@4037 99
coleenp@4037 100 // This cannot be inherited from ResourceObj because it cannot have a vtable.
coleenp@4037 101 // Since sometimes this is allocated from Metadata, pick a base allocation
coleenp@4037 102 // type without virtual functions.
coleenp@4037 103 class ClassLoaderData;
coleenp@4037 104
coleenp@4037 105 class Symbol : public MetaspaceObj {
duke@435 106 friend class VMStructs;
coleenp@2497 107 friend class SymbolTable;
coleenp@2497 108 friend class MoveSymbols;
duke@435 109 private:
coleenp@2497 110 volatile int _refcount;
coleenp@2497 111 int _identity_hash;
duke@435 112 unsigned short _length; // number of UTF8 characters in the symbol
duke@435 113 jbyte _body[1];
duke@435 114
duke@435 115 enum {
duke@435 116 // max_symbol_length is constrained by type of _length
duke@435 117 max_symbol_length = (1 << 16) -1
duke@435 118 };
coleenp@2497 119
coleenp@4037 120 static int size(int length) {
coleenp@4037 121 size_t sz = heap_word_size(sizeof(Symbol) + (length > 0 ? length - 1 : 0));
coleenp@4037 122 return align_object_size(sz);
coleenp@2497 123 }
coleenp@2497 124
coleenp@2497 125 void byte_at_put(int index, int value) {
coleenp@2497 126 assert(index >=0 && index < _length, "symbol index overflow");
coleenp@2497 127 _body[index] = value;
coleenp@2497 128 }
coleenp@2497 129
coleenp@3682 130 Symbol(const u1* name, int length, int refcount);
coleenp@3682 131 void* operator new(size_t size, int len, TRAPS);
coleenp@3682 132 void* operator new(size_t size, int len, Arena* arena, TRAPS);
coleenp@4037 133 void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS);
coleenp@4037 134
coleenp@4037 135 void operator delete(void* p);
coleenp@2497 136
duke@435 137 public:
coleenp@2497 138 // Low-level access (used with care, since not GC-safe)
coleenp@2497 139 const jbyte* base() const { return &_body[0]; }
duke@435 140
coleenp@4037 141 int size() { return size(utf8_length()); }
duke@435 142
duke@435 143 // Returns the largest size symbol we can safely hold.
coleenp@3682 144 static int max_length() { return max_symbol_length; }
duke@435 145
coleenp@3682 146 int identity_hash() { return _identity_hash; }
duke@435 147
coleenp@4037 148 // For symbol table alternate hashing
coleenp@4037 149 unsigned int new_hash(jint seed);
coleenp@4037 150
coleenp@2497 151 // Reference counting. See comments above this class for when to use.
coleenp@3682 152 int refcount() const { return _refcount; }
coleenp@3682 153 inline void increment_refcount();
coleenp@3682 154 inline void decrement_refcount();
duke@435 155
duke@435 156 int byte_at(int index) const {
duke@435 157 assert(index >=0 && index < _length, "symbol index overflow");
coleenp@2497 158 return base()[index];
duke@435 159 }
duke@435 160
coleenp@2497 161 const jbyte* bytes() const { return base(); }
duke@435 162
duke@435 163 int utf8_length() const { return _length; }
duke@435 164
twisti@1573 165 // Compares the symbol with a string.
duke@435 166 bool equals(const char* str, int len) const;
twisti@1573 167 bool equals(const char* str) const { return equals(str, (int) strlen(str)); }
twisti@1573 168
twisti@1573 169 // Tests if the symbol starts with the given prefix.
twisti@1573 170 bool starts_with(const char* prefix, int len) const;
twisti@1573 171 bool starts_with(const char* prefix) const {
twisti@1573 172 return starts_with(prefix, (int) strlen(prefix));
twisti@1573 173 }
twisti@1573 174
twisti@1573 175 // Tests if the symbol starts with the given prefix.
twisti@1573 176 int index_of_at(int i, const char* str, int len) const;
twisti@1573 177 int index_of_at(int i, const char* str) const {
twisti@1573 178 return index_of_at(i, str, (int) strlen(str));
twisti@1573 179 }
duke@435 180
duke@435 181 // Three-way compare for sorting; returns -1/0/1 if receiver is </==/> than arg
duke@435 182 // note that the ordering is not alfabetical
coleenp@2497 183 inline int fast_compare(Symbol* other) const;
duke@435 184
duke@435 185 // Returns receiver converted to null-terminated UTF-8 string; string is
duke@435 186 // allocated in resource area, or in the char buffer provided by caller.
duke@435 187 char* as_C_string() const;
duke@435 188 char* as_C_string(char* buf, int size) const;
duke@435 189 // Use buf if needed buffer length is <= size.
duke@435 190 char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const;
duke@435 191
minqi@4267 192 // Returns an escaped form of a Java string.
minqi@4267 193 char* as_quoted_ascii() const;
duke@435 194
duke@435 195 // Returns a null terminated utf8 string in a resource array
duke@435 196 char* as_utf8() const { return as_C_string(); }
duke@435 197 char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const {
duke@435 198 return as_C_string_flexible_buffer(t, buf, size);
duke@435 199 }
duke@435 200
duke@435 201 jchar* as_unicode(int& length) const;
duke@435 202
duke@435 203 // Treating this symbol as a class name, returns the Java name for the class.
duke@435 204 // String is allocated in resource area if buffer is not provided.
duke@435 205 // See Klass::external_name()
duke@435 206 const char* as_klass_external_name() const;
duke@435 207 const char* as_klass_external_name(char* buf, int size) const;
duke@435 208
coleenp@2497 209 // Printing
coleenp@2497 210 void print_symbol_on(outputStream* st = NULL) const;
coleenp@2497 211 void print_on(outputStream* st) const; // First level print
coleenp@2497 212 void print_value_on(outputStream* st) const; // Second level print.
duke@435 213
coleenp@2497 214 // printing on default output stream
coleenp@2497 215 void print() { print_on(tty); }
coleenp@2497 216 void print_value() { print_value_on(tty); }
coleenp@2497 217
coleenp@2497 218 #ifndef PRODUCT
coleenp@2497 219 // Empty constructor to create a dummy symbol object on stack
coleenp@2497 220 // only for getting its vtable pointer.
coleenp@2497 221 Symbol() { }
coleenp@2497 222
coleenp@2497 223 static int _total_count;
coleenp@2497 224 #endif
duke@435 225 };
duke@435 226
duke@435 227 // Note: this comparison is used for vtable sorting only; it doesn't matter
duke@435 228 // what order it defines, as long as it is a total, time-invariant order
coleenp@2497 229 // Since Symbol*s are in C_HEAP, their relative order in memory never changes,
duke@435 230 // so use address comparison for speed
coleenp@2497 231 int Symbol::fast_compare(Symbol* other) const {
duke@435 232 return (((uintptr_t)this < (uintptr_t)other) ? -1
duke@435 233 : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
duke@435 234 }
coleenp@3682 235
coleenp@3682 236 inline void Symbol::increment_refcount() {
coleenp@3682 237 // Only increment the refcount if positive. If negative either
coleenp@3682 238 // overflow has occurred or it is a permanent symbol in a read only
coleenp@3682 239 // shared archive.
coleenp@3682 240 if (_refcount >= 0) {
coleenp@3682 241 Atomic::inc(&_refcount);
coleenp@3682 242 NOT_PRODUCT(Atomic::inc(&_total_count);)
coleenp@3682 243 }
coleenp@3682 244 }
coleenp@3682 245
coleenp@3682 246 inline void Symbol::decrement_refcount() {
coleenp@3682 247 if (_refcount >= 0) {
coleenp@3682 248 Atomic::dec(&_refcount);
coleenp@3682 249 #ifdef ASSERT
coleenp@3682 250 if (_refcount < 0) {
coleenp@3682 251 print();
coleenp@3682 252 assert(false, "reference count underflow for symbol");
coleenp@3682 253 }
coleenp@3682 254 #endif
coleenp@3682 255 }
coleenp@3682 256 }
coleenp@2497 257 #endif // SHARE_VM_OOPS_SYMBOL_HPP

mercurial