src/share/vm/oops/symbol.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2497
3582bf76420e
child 2708
1d1603768966
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 1997, 2009, 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"
    31 // A Symbol is a canonicalized string.
    32 // All Symbols reside in global SymbolTable and are reference counted.
    34 // Reference counting
    35 //
    36 // All Symbols are allocated and added to the SymbolTable.
    37 // When a class is unloaded, the reference counts of the Symbol pointers in
    38 // the ConstantPool and in instanceKlass (see release_C_heap_structures) are
    39 // decremented.  When the reference count for a Symbol goes to 0, the garbage
    40 // collector can free the Symbol and remove it from the SymbolTable.
    41 //
    42 // 0) Symbols need to be reference counted when a pointer to the Symbol is
    43 // saved in persistent storage.  This does not include the pointer
    44 // in the SymbolTable bucket (the _literal field in HashtableEntry)
    45 // that points to the Symbol.  All other stores of a Symbol*
    46 // to a field of a persistent variable (e.g., the _name filed in
    47 // FieldAccessInfo or _ptr in a CPSlot) is reference counted.
    48 //
    49 // 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for
    50 // "name" and returns a pointer to F or finds a pre-existing Symbol F for
    51 // "name" and returns a pointer to it. In both cases the reference count for F
    52 // is incremented under the assumption that a pointer to F will be created from
    53 // the return value. Thus the increment of the reference count is on the lookup
    54 // and not on the assignment to the new Symbol*.  That is
    55 //    Symbol* G = lookup()
    56 //                ^ increment on lookup()
    57 // and not
    58 //    Symbol* G = lookup()
    59 //              ^ increment on assignmnet
    60 // The reference count must be decremented manually when the copy of the
    61 // pointer G is destroyed.
    62 //
    63 // 2) For a local Symbol* A that is a copy of an existing Symbol* B, the
    64 // reference counting is elided when the scope of B is greater than the scope
    65 // of A.  For example, in the code fragment
    66 // below "klass" is passed as a parameter to the method.  Symbol* "kn"
    67 // is a copy of the name in "klass".
    68 //
    69 //   Symbol*  kn = klass->name();
    70 //   unsigned int d_hash = dictionary()->compute_hash(kn, class_loader);
    71 //
    72 // The scope of "klass" is greater than the scope of "kn" so the reference
    73 // counting for "kn" is elided.
    74 //
    75 // Symbol* copied from ConstantPool entries are good candidates for reference
    76 // counting elision.  The ConstantPool entries for a class C exist until C is
    77 // unloaded.  If a Symbol* is copied out of the ConstantPool into Symbol* X,
    78 // the Symbol* in the ConstantPool will in general out live X so the reference
    79 // counting on X can be elided.
    80 //
    81 // For cases where the scope of A is not greater than the scope of B,
    82 // the reference counting is explicitly done.  See ciSymbol,
    83 // ResolutionErrorEntry and ClassVerifier for examples.
    84 //
    85 // 3) When a Symbol K is created for temporary use, generally for substrings of
    86 // an existing symbol or to create a new symbol, assign it to a
    87 // TempNewSymbol. The SymbolTable methods new_symbol(), lookup()
    88 // and probe() all potentially return a pointer to a new Symbol.
    89 // The allocation (or lookup) of K increments the reference count for K
    90 // and the destructor decrements the reference count.
    91 //
    92 // Another example of TempNewSymbol usage is parsed_name used in
    93 // 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 // TempNewSymbol (passed in as a parameter) so the reference count on its symbol
    96 // will be decremented when it goes out of scope.
    98 class Symbol : public CHeapObj {
    99   friend class VMStructs;
   100   friend class SymbolTable;
   101   friend class MoveSymbols;
   102  private:
   103   volatile int   _refcount;
   104   int            _identity_hash;
   105   unsigned short _length; // number of UTF8 characters in the symbol
   106   jbyte _body[1];
   108   enum {
   109     // max_symbol_length is constrained by type of _length
   110     max_symbol_length = (1 << 16) -1
   111   };
   113   static int object_size(int length) {
   114     size_t size = heap_word_size(sizeof(Symbol) + length);
   115     return align_object_size(size);
   116   }
   118   void byte_at_put(int index, int value) {
   119     assert(index >=0 && index < _length, "symbol index overflow");
   120     _body[index] = value;
   121   }
   123   Symbol(const u1* name, int length);
   124   void* operator new(size_t size, int len);
   126  public:
   127   // Low-level access (used with care, since not GC-safe)
   128   const jbyte* base() const { return &_body[0]; }
   130   int object_size() { return object_size(utf8_length()); }
   132   // Returns the largest size symbol we can safely hold.
   133   static int max_length() {
   134     return max_symbol_length;
   135   }
   137   int identity_hash() {
   138     return _identity_hash;
   139   }
   141   // Reference counting.  See comments above this class for when to use.
   142   int refcount() const { return _refcount; }
   143   void increment_refcount();
   144   void decrement_refcount();
   146   int byte_at(int index) const {
   147     assert(index >=0 && index < _length, "symbol index overflow");
   148     return base()[index];
   149   }
   151   const jbyte* bytes() const { return base(); }
   153   int utf8_length() const { return _length; }
   155   // Compares the symbol with a string.
   156   bool equals(const char* str, int len) const;
   157   bool equals(const char* str) const { return equals(str, (int) strlen(str)); }
   159   // Tests if the symbol starts with the given prefix.
   160   bool starts_with(const char* prefix, int len) const;
   161   bool starts_with(const char* prefix) const {
   162     return starts_with(prefix, (int) strlen(prefix));
   163   }
   165   // Tests if the symbol starts with the given prefix.
   166   int index_of_at(int i, const char* str, int len) const;
   167   int index_of_at(int i, const char* str) const {
   168     return index_of_at(i, str, (int) strlen(str));
   169   }
   171   // Three-way compare for sorting; returns -1/0/1 if receiver is </==/> than arg
   172   // note that the ordering is not alfabetical
   173   inline int fast_compare(Symbol* other) const;
   175   // Returns receiver converted to null-terminated UTF-8 string; string is
   176   // allocated in resource area, or in the char buffer provided by caller.
   177   char* as_C_string() const;
   178   char* as_C_string(char* buf, int size) const;
   179   // Use buf if needed buffer length is <= size.
   180   char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const;
   183   // Returns a null terminated utf8 string in a resource array
   184   char* as_utf8() const { return as_C_string(); }
   185   char* as_utf8_flexible_buffer(Thread* t, char* buf, int size) const {
   186     return as_C_string_flexible_buffer(t, buf, size);
   187   }
   189   jchar* as_unicode(int& length) const;
   191   // Treating this symbol as a class name, returns the Java name for the class.
   192   // String is allocated in resource area if buffer is not provided.
   193   // See Klass::external_name()
   194   const char* as_klass_external_name() const;
   195   const char* as_klass_external_name(char* buf, int size) const;
   197   // Printing
   198   void print_symbol_on(outputStream* st = NULL) const;
   199   void print_on(outputStream* st) const;         // First level print
   200   void print_value_on(outputStream* st) const;   // Second level print.
   202   // printing on default output stream
   203   void print()         { print_on(tty);       }
   204   void print_value()   { print_value_on(tty); }
   206 #ifndef PRODUCT
   207   // Empty constructor to create a dummy symbol object on stack
   208   // only for getting its vtable pointer.
   209   Symbol() { }
   211   static int _total_count;
   212 #endif
   213 };
   215 // Note: this comparison is used for vtable sorting only; it doesn't matter
   216 // what order it defines, as long as it is a total, time-invariant order
   217 // Since Symbol*s are in C_HEAP, their relative order in memory never changes,
   218 // so use address comparison for speed
   219 int Symbol::fast_compare(Symbol* other) const {
   220  return (((uintptr_t)this < (uintptr_t)other) ? -1
   221    : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
   222 }
   223 #endif // SHARE_VM_OOPS_SYMBOL_HPP

mercurial