< prev index next >

src/share/vm/classfile/symbolTable.hpp

Print this page

        

@@ -40,38 +40,66 @@
 //  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
 
 class BoolObjectClosure;
 class outputStream;
 
-// Class to hold a newly created or referenced Symbol* temporarily in scope.
-// new_symbol() and lookup() will create a Symbol* if not already in the
+// TempNewSymbol acts as a handle class in a handle/body idiom and is
+// responsible for proper resource management of the body (which is a Symbol*).
+// The body is resource managed by a reference counting scheme.
+// TempNewSymbol can therefore be used to properly hold a newly created or referenced
+// Symbol* temporarily in scope.
+//
+// Routines in SymbolTable will initialize the reference count of a Symbol* before
+// it becomes "managed" by TempNewSymbol instances. As a handle class, TempNewSymbol
+// needs to maintain proper reference counting in context of copy semantics.
+//
+// In SymbolTable, new_symbol() and lookup() will create a Symbol* if not already in the
 // symbol table and add to the symbol's reference count.
 // probe() and lookup_only() will increment the refcount if symbol is found.
 class TempNewSymbol : public StackObj {
   Symbol* _temp;
 
  public:
   TempNewSymbol() : _temp(NULL) {}
-  // Creating or looking up a symbol increments the symbol's reference count
+
+  // Conversion from a Symbol* to a TempNewSymbol.
+  // Does not increment the current reference count.
   TempNewSymbol(Symbol *s) : _temp(s) {}
 
-  // Operator= increments reference count.
-  void operator=(const TempNewSymbol &s) {
-    //clear();  //FIXME
-    _temp = s._temp;
-    if (_temp !=NULL) _temp->increment_refcount();
+  // Copy constructor increments reference count.
+  TempNewSymbol(const TempNewSymbol& rhs) : _temp(rhs._temp) {
+    if (_temp != NULL) {
+      _temp->increment_refcount();
+    }
+  }
+
+  // Assignment operator decrements the reference count for any
+  // existing resource. It increments the reference count
+  // for the newly assigned resource.
+  const TempNewSymbol& operator=(const TempNewSymbol &rhs) {
+    if (this != &rhs && _temp != rhs._temp) {
+      clear();
+      _temp = rhs._temp;
+      if (_temp != NULL) {
+        _temp->increment_refcount();
+      }
+    }
+    return *this;
   }
 
   // Decrement reference counter so it can go away if it's unique
-  void clear() { if (_temp != NULL)  _temp->decrement_refcount();  _temp = NULL; }
+  void clear() {
+    if (_temp != NULL) {
+      _temp->decrement_refcount();
+    }
+  }
 
   ~TempNewSymbol() { clear(); }
 
-  // Operators so they can be used like Symbols
+  // Symbol* conversion operators
   Symbol* operator -> () const                   { return _temp; }
   bool    operator == (Symbol* o) const          { return _temp == o; }
-  // Sneaky conversion function
   operator Symbol*()                             { return _temp; }
 };
 
 template <class T, class N> class CompactHashtable;
 
< prev index next >