< prev index next >

hotspot/src/share/vm/asm/codeBuffer.cpp

Print this page

        

@@ -1091,13 +1091,20 @@
   }
 }
 
 void CodeStrings::assign(CodeStrings& other) {
   other.check_valid();
-  // Cannot do following because CodeStrings constructor is not alway run!
-  assert(is_null(), "Cannot assign onto non-empty CodeStrings");
-  _strings = other._strings;
+
+  if (!is_null()) {
+    // The assignment replaces the old content.
+    // Delete old CodeStrings, invalidating it if there are non-comment
+    // strings.
+    free();
+    check_valid(); // else the container may reference freed strings
+  }
+
+  *this = other; // copy all fields (including _defunct when it exists)
   other.set_null_and_invalidate();
 }
 
 // Deep copy of CodeStrings for consistent memory management.
 // Only used for actual disassembly so this is cheaper than reference counting

@@ -1113,34 +1120,50 @@
     ps = &((*ps)->_next);
     n = n->next();
   }
 }
 
+const char* CodeStrings::_prefix = " ;; ";  // default: can be changed via set_prefix
+
 void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
     check_valid();
     if (_strings != NULL) {
     CodeString* c = find(offset);
     while (c && c->offset() == offset) {
       stream->bol();
-      stream->print("  ;; ");
+      stream->print("%s", _prefix);
       stream->print_cr("%s", c->string());
       c = c->next_comment();
     }
   }
 }
 
 // Also sets isNull()
 void CodeStrings::free() {
+  check_valid();
+  bool still_valid = true;
   CodeString* n = _strings;
   while (n) {
     // unlink the node from the list saving a pointer to the next
     CodeString* p = n->next();
     n->set_next(NULL);
+    if (!n->is_comment()) {
+      // The string was not an optional comment. Deleting it may cause
+      // the container to no longer be valid. Mark the CodeStrings as
+      // invalid to detect it on future accesses.
+      still_valid = false;
+    }
     delete n;
     n = p;
   }
+  if (still_valid) {
+    // Only comments were removed, a null CodeStrings is valid for
+    // the container associated to this CodeStrings instance.
+    set_null();
+  } else {
   set_null_and_invalidate();
+  }
 }
 
 const char* CodeStrings::add_string(const char * string) {
   check_valid();
   CodeString* s = new CodeString(string);
< prev index next >