symbol.hpp 9.7 KB
Newer Older
1
/*
2
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_OOPS_SYMBOL_HPP
#define SHARE_VM_OOPS_SYMBOL_HPP

#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
30
#include "runtime/atomic.hpp"
31 32 33 34 35 36 37 38

// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.

// Reference counting
//
// All Symbols are allocated and added to the SymbolTable.
// 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
// decremented.  When the reference count for a Symbol goes to 0, the garbage
// collector can free the Symbol and remove it from the SymbolTable.
//
// 0) Symbols need to be reference counted when a pointer to the Symbol is
// saved in persistent storage.  This does not include the pointer
// in the SymbolTable bucket (the _literal field in HashtableEntry)
// that points to the Symbol.  All other stores of a Symbol*
// to a field of a persistent variable (e.g., the _name filed in
// FieldAccessInfo or _ptr in a CPSlot) is reference counted.
//
// 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for
// "name" and returns a pointer to F or finds a pre-existing Symbol F for
// "name" and returns a pointer to it. In both cases the reference count for F
// is incremented under the assumption that a pointer to F will be created from
// the return value. Thus the increment of the reference count is on the lookup
// and not on the assignment to the new Symbol*.  That is
//    Symbol* G = lookup()
//                ^ increment on lookup()
// and not
//    Symbol* G = lookup()
//              ^ increment on assignmnet
// The reference count must be decremented manually when the copy of the
// pointer G is destroyed.
//
// 2) For a local Symbol* A that is a copy of an existing Symbol* B, the
// reference counting is elided when the scope of B is greater than the scope
// of A.  For example, in the code fragment
// below "klass" is passed as a parameter to the method.  Symbol* "kn"
// is a copy of the name in "klass".
//
//   Symbol*  kn = klass->name();
//   unsigned int d_hash = dictionary()->compute_hash(kn, class_loader);
//
// The scope of "klass" is greater than the scope of "kn" so the reference
// counting for "kn" is elided.
//
// Symbol* copied from ConstantPool entries are good candidates for reference
// counting elision.  The ConstantPool entries for a class C exist until C is
// unloaded.  If a Symbol* is copied out of the ConstantPool into Symbol* X,
// the Symbol* in the ConstantPool will in general out live X so the reference
// counting on X can be elided.
//
// For cases where the scope of A is not greater than the scope of B,
// the reference counting is explicitly done.  See ciSymbol,
// ResolutionErrorEntry and ClassVerifier for examples.
//
// 3) When a Symbol K is created for temporary use, generally for substrings of
// an existing symbol or to create a new symbol, assign it to a
// TempNewSymbol. The SymbolTable methods new_symbol(), lookup()
// and probe() all potentially return a pointer to a new Symbol.
// The allocation (or lookup) of K increments the reference count for K
// and the destructor decrements the reference count.
//
// Another example of TempNewSymbol usage is parsed_name used in
// ClassFileParser::parseClassFile() where parsed_name is used in the cleanup
// after a failed attempt to load a class.  Here parsed_name is a
// TempNewSymbol (passed in as a parameter) so the reference count on its symbol
// will be decremented when it goes out of scope.

99 100 101 102 103 104 105

// 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;

class Symbol : public MetaspaceObj {
106 107 108 109 110 111 112 113 114 115 116 117 118 119
  friend class VMStructs;
  friend class SymbolTable;
  friend class MoveSymbols;
 private:
  volatile int   _refcount;
  int            _identity_hash;
  unsigned short _length; // number of UTF8 characters in the symbol
  jbyte _body[1];

  enum {
    // max_symbol_length is constrained by type of _length
    max_symbol_length = (1 << 16) -1
  };

120 121 122
  static int size(int length) {
    size_t sz = heap_word_size(sizeof(Symbol) + (length > 0 ? length - 1 : 0));
    return align_object_size(sz);
123 124 125 126 127 128 129
  }

  void byte_at_put(int index, int value) {
    assert(index >=0 && index < _length, "symbol index overflow");
    _body[index] = value;
  }

130 131 132
  Symbol(const u1* name, int length, int refcount);
  void* operator new(size_t size, int len, TRAPS);
  void* operator new(size_t size, int len, Arena* arena, TRAPS);
133 134 135
  void* operator new(size_t size, int len, ClassLoaderData* loader_data, TRAPS);

  void  operator delete(void* p);
136 137 138 139 140

 public:
  // Low-level access (used with care, since not GC-safe)
  const jbyte* base() const { return &_body[0]; }

141
  int size()                { return size(utf8_length()); }
142 143

  // Returns the largest size symbol we can safely hold.
144
  static int max_length()   { return max_symbol_length; }
145

146
  int identity_hash()       { return _identity_hash; }
147

148 149 150
  // For symbol table alternate hashing
  unsigned int new_hash(jint seed);

151
  // Reference counting.  See comments above this class for when to use.
152 153 154
  int refcount() const      { return _refcount; }
  inline void increment_refcount();
  inline void decrement_refcount();
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

  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;
  bool equals(const char* str) const { return equals(str, (int) strlen(str)); }

  // Tests if the symbol starts with the given prefix.
  bool starts_with(const char* prefix, int len) const;
  bool starts_with(const char* prefix) const {
    return starts_with(prefix, (int) strlen(prefix));
  }

  // Tests if the symbol starts with the given prefix.
  int index_of_at(int i, const char* str, int len) const;
  int index_of_at(int i, const char* str) const {
    return index_of_at(i, str, (int) strlen(str));
  }

  // Three-way compare for sorting; returns -1/0/1 if receiver is </==/> than arg
  // note that the ordering is not alfabetical
  inline int fast_compare(Symbol* other) const;

  // Returns receiver converted to null-terminated UTF-8 string; string is
  // allocated in resource area, or in the char buffer provided by caller.
  char* as_C_string() const;
  char* as_C_string(char* buf, int size) const;
  // Use buf if needed buffer length is <= size.
  char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const;

192 193
  // Returns an escaped form of a Java string.
  char* as_quoted_ascii() const;
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

  // Returns a null terminated utf8 string in a resource array
  char* as_utf8() const { return as_C_string(); }
  char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const {
    return as_C_string_flexible_buffer(t, buf, size);
  }

  jchar* as_unicode(int& length) const;

  // Treating this symbol as a class name, returns the Java name for the class.
  // String is allocated in resource area if buffer is not provided.
  // See Klass::external_name()
  const char* as_klass_external_name() const;
  const char* as_klass_external_name(char* buf, int size) const;

  // Printing
  void print_symbol_on(outputStream* st = NULL) const;
  void print_on(outputStream* st) const;         // First level print
  void print_value_on(outputStream* st) const;   // Second level print.

  // printing on default output stream
  void print()         { print_on(tty);       }
  void print_value()   { print_value_on(tty); }

#ifndef PRODUCT
  // Empty constructor to create a dummy symbol object on stack
  // only for getting its vtable pointer.
  Symbol() { }

  static int _total_count;
#endif
};

// Note: this comparison is used for vtable sorting only; it doesn't matter
// what order it defines, as long as it is a total, time-invariant order
// Since Symbol*s are in C_HEAP, their relative order in memory never changes,
// so use address comparison for speed
int Symbol::fast_compare(Symbol* other) const {
 return (((uintptr_t)this < (uintptr_t)other) ? -1
   : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
}
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256

inline void Symbol::increment_refcount() {
  // Only increment the refcount if positive.  If negative either
  // overflow has occurred or it is a permanent symbol in a read only
  // shared archive.
  if (_refcount >= 0) {
    Atomic::inc(&_refcount);
    NOT_PRODUCT(Atomic::inc(&_total_count);)
  }
}

inline void Symbol::decrement_refcount() {
  if (_refcount >= 0) {
    Atomic::dec(&_refcount);
#ifdef ASSERT
    if (_refcount < 0) {
      print();
      assert(false, "reference count underflow for symbol");
    }
#endif
  }
}
257
#endif // SHARE_VM_OOPS_SYMBOL_HPP