Don't use normalized map cache for prototype maps
authorjkummerow <jkummerow@chromium.org>
Fri, 17 Apr 2015 12:16:12 +0000 (05:16 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 17 Apr 2015 12:16:07 +0000 (12:16 +0000)
BUG=chromium:477924
LOG=n
R=verwaest@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27916}

src/flag-definitions.h
src/objects.cc
test/mjsunit/regress/regress-crbug-477924.js [new file with mode: 0644]

index 00074f1..dd94871 100644 (file)
@@ -678,11 +678,13 @@ DEFINE_INT(random_seed, 0,
            "(0, the default, means to use system random).")
 
 // objects.cc
-DEFINE_BOOL(trace_weak_arrays, false, "trace WeakFixedArray usage")
+DEFINE_BOOL(trace_weak_arrays, false, "Trace WeakFixedArray usage")
 DEFINE_BOOL(track_prototype_users, false,
-            "keep track of which maps refer to a given prototype object")
+            "Keep track of which maps refer to a given prototype object")
+DEFINE_BOOL(trace_prototype_users, false,
+            "Trace updates to prototype user tracking")
 DEFINE_BOOL(eliminate_prototype_chain_checks, true,
-            "collapse prototype chain checks into single-cell checks")
+            "Collapse prototype chain checks into single-cell checks")
 DEFINE_IMPLICATION(eliminate_prototype_chain_checks, track_prototype_users)
 DEFINE_BOOL(use_verbose_printer, true, "allows verbose printing")
 #if TRACE_MAPS
index c6d5266..4e14108 100644 (file)
@@ -1940,6 +1940,12 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
     DCHECK(object->map() == *new_map);
     new_map->set_prototype_info(old_map->prototype_info());
     old_map->set_prototype_info(Smi::FromInt(0));
+    if (FLAG_trace_prototype_users) {
+      PrintF("Moving prototype_info %p from map %p to map %p.\n",
+             reinterpret_cast<void*>(new_map->prototype_info()),
+             reinterpret_cast<void*>(*old_map),
+             reinterpret_cast<void*>(*new_map));
+    }
   }
 }
 
@@ -4721,6 +4727,12 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
     DCHECK(new_map->is_prototype_map());
     new_map->set_prototype_info(object->map()->prototype_info());
     object->map()->set_prototype_info(Smi::FromInt(0));
+    if (FLAG_trace_prototype_users) {
+      PrintF("Moving prototype_info %p from map %p to map %p.\n",
+             reinterpret_cast<void*>(new_map->prototype_info()),
+             reinterpret_cast<void*>(object->map()),
+             reinterpret_cast<void*>(*new_map));
+    }
   }
 
 #if TRACE_MAPS
@@ -6892,7 +6904,7 @@ Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode,
   Isolate* isolate = fast_map->GetIsolate();
   Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
                              isolate);
-  bool use_cache = !maybe_cache->IsUndefined();
+  bool use_cache = !fast_map->is_prototype_map() && !maybe_cache->IsUndefined();
   Handle<NormalizedMapCache> cache;
   if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
 
@@ -10053,6 +10065,10 @@ void JSObject::RegisterPrototypeUser(Handle<JSObject> prototype,
   if (!maybe_registry.is_identical_to(new_array)) {
     proto_info->set_prototype_users(*new_array);
   }
+  if (FLAG_trace_prototype_users) {
+    PrintF("Registering %p as a user of prototype %p.\n",
+           reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
+  }
 }
 
 
@@ -10072,6 +10088,10 @@ void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype,
   Object* maybe_registry = proto_info->prototype_users();
   if (!maybe_registry->IsWeakFixedArray()) return;
   WeakFixedArray::cast(maybe_registry)->Remove(user);
+  if (FLAG_trace_prototype_users) {
+    PrintF("Unregistering %p as a user of prototype %p.\n",
+           reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
+  }
 }
 
 
@@ -10126,7 +10146,7 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
     prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   }
   Handle<PrototypeInfo> proto_info(
-      PrototypeInfo::cast(prototype->map()->prototype_info()));
+      PrototypeInfo::cast(prototype->map()->prototype_info()), isolate);
   Object* maybe_cell = proto_info->validity_cell();
   // Return existing cell if it's still valid.
   if (maybe_cell->IsCell()) {
diff --git a/test/mjsunit/regress/regress-crbug-477924.js b/test/mjsunit/regress/regress-crbug-477924.js
new file mode 100644 (file)
index 0000000..feaf2d0
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var dummy = new ReferenceError("dummy");
+
+constructors = [ ReferenceError, TypeError];
+
+for (var i in constructors) {
+  constructors[i].prototype.__defineGetter__("stack", function() {});
+}
+
+for (var i in constructors) {
+  var obj = new constructors[i];
+  obj.toString();
+}