From 4204c72739a111c19b68b4fcd28e3591fd360249 Mon Sep 17 00:00:00 2001 From: jkummerow Date: Fri, 17 Apr 2015 05:16:12 -0700 Subject: [PATCH] Don't use normalized map cache for prototype maps 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 | 8 +++++--- src/objects.cc | 24 ++++++++++++++++++++++-- test/mjsunit/regress/regress-crbug-477924.js | 16 ++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-477924.js diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 00074f1..dd94871 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -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 diff --git a/src/objects.cc b/src/objects.cc index c6d5266..4e14108 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -1940,6 +1940,12 @@ void JSObject::MigrateToMap(Handle object, Handle 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(new_map->prototype_info()), + reinterpret_cast(*old_map), + reinterpret_cast(*new_map)); + } } } @@ -4721,6 +4727,12 @@ void JSObject::MigrateSlowToFast(Handle 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(new_map->prototype_info()), + reinterpret_cast(object->map()), + reinterpret_cast(*new_map)); + } } #if TRACE_MAPS @@ -6892,7 +6904,7 @@ Handle Map::Normalize(Handle fast_map, PropertyNormalizationMode mode, Isolate* isolate = fast_map->GetIsolate(); Handle 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 cache; if (use_cache) cache = Handle::cast(maybe_cache); @@ -10053,6 +10065,10 @@ void JSObject::RegisterPrototypeUser(Handle 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(*user), reinterpret_cast(*prototype)); + } } @@ -10072,6 +10088,10 @@ void JSObject::UnregisterPrototypeUser(Handle 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(*user), reinterpret_cast(*prototype)); + } } @@ -10126,7 +10146,7 @@ Handle Map::GetOrCreatePrototypeChainValidityCell(Handle map, prototype = Handle::cast(PrototypeIterator::GetCurrent(iter)); } Handle 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 index 0000000..feaf2d0 --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-477924.js @@ -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(); +} -- 2.7.4