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

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

mercurial