Fix crash involving zombie maps escaping from the JSON parser's underground lab
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 25 Mar 2013 15:18:52 +0000 (15:18 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 25 Mar 2013 15:18:52 +0000 (15:18 +0000)
Zapping is required since transition arrays contain weak references to maps: At the end of a GC cycle, ClearNonLiveTransitions removes references to dead maps from transition arrays. If a marked transition array with weak (dead) references is replaced by another transition array before the end of the GC cycle, dead references are not removed from the replaced transition array. If the replaced transition array is kept alive by a handle, marking will crash when trying to mark the first reference to a dead map.

Review URL: https://codereview.chromium.org/12987013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14063 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects-inl.h

index b2bad48..2bed396 100644 (file)
@@ -1490,7 +1490,7 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
 bool JSObject::TryTransitionToField(Handle<JSObject> object,
                                     Handle<Name> key) {
   if (!object->map()->HasTransitionArray()) return false;
-  Handle<TransitionArray> transitions(object->map()->transitions());
+  TransitionArray* transitions = object->map()->transitions();
   int transition = transitions->Search(*key);
   if (transition == TransitionArray::kNotFound) return false;
   PropertyDetails target_details = transitions->GetTargetDetails(transition);
@@ -4128,9 +4128,12 @@ TransitionArray* Map::transitions() {
 
 void Map::set_transitions(TransitionArray* transition_array,
                           WriteBarrierMode mode) {
-  // In release mode, only run this code if verify_heap is on.
-  if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
-    CHECK(transitions() != transition_array);
+  // Transition arrays are not shared. When one is replaced, it should not
+  // keep referenced objects alive, so we zap it.
+  // When there is another reference to the array somewhere (e.g. a handle),
+  // not zapping turns from a waste of memory into a source of crashes.
+  if (HasTransitionArray()) {
+    ASSERT(transitions() != transition_array);
     ZapTransitions();
   }