Commit f718cd13 authored by ishell's avatar ishell Committed by Commit bot

[ic] Invalidate prototype validity cell when a slow prototype becomes fast.

BUG=chromium:665886

Review-Url: https://codereview.chromium.org/2502393002
Cr-Commit-Position: refs/heads/master@{#41045}
parent 764371bc
......@@ -2219,12 +2219,11 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
// The proxy's hash should be retained across reinitialization.
Handle<Object> hash(object->hash(), isolate());
JSObject::InvalidatePrototypeChains(*old_map);
if (old_map->is_prototype_map()) {
map = Map::Copy(map, "CopyAsPrototypeForJSGlobalProxy");
map->set_is_prototype_map(true);
}
JSObject::UpdatePrototypeUserRegistration(old_map, map, isolate());
JSObject::NotifyMapChange(old_map, map, isolate());
// Check that the already allocated object has the same size and type as
// objects allocated using the constructor.
......
......@@ -3207,7 +3207,7 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
Handle<Map> new_map,
Isolate* isolate) {
if (!old_map->is_prototype_map()) return;
DCHECK(old_map->is_prototype_map());
DCHECK(new_map->is_prototype_map());
bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
new_map->set_prototype_info(old_map->prototype_info());
......@@ -3567,22 +3567,26 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
} // namespace
// static
void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
Isolate* isolate) {
if (!old_map->is_prototype_map()) return;
InvalidatePrototypeChains(*old_map);
// If the map was registered with its prototype before, ensure that it
// registers with its new prototype now. This preserves the invariant that
// when a map on a prototype chain is registered with its prototype, then
// all prototypes further up the chain are also registered with their
// respective prototypes.
UpdatePrototypeUserRegistration(old_map, new_map, isolate);
}
void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
int expected_additional_properties) {
if (object->map() == *new_map) return;
Handle<Map> old_map(object->map());
if (old_map->is_prototype_map()) {
// If this object is a prototype (the callee will check), invalidate any
// prototype chains involving it.
InvalidatePrototypeChains(object->map());
// If the map was registered with its prototype before, ensure that it
// registers with its new prototype now. This preserves the invariant that
// when a map on a prototype chain is registered with its prototype, then
// all prototypes further up the chain are also registered with their
// respective prototypes.
UpdatePrototypeUserRegistration(old_map, new_map, new_map->GetIsolate());
}
NotifyMapChange(old_map, new_map, new_map->GetIsolate());
if (old_map->is_dictionary_map()) {
// For slow-to-fast migrations JSObject::MigrateSlowToFast()
......@@ -6012,7 +6016,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
new_map->set_dictionary_map(false);
UpdatePrototypeUserRegistration(old_map, new_map, isolate);
NotifyMapChange(old_map, new_map, isolate);
#if TRACE_MAPS
if (FLAG_trace_maps) {
......@@ -12704,7 +12708,7 @@ bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
static void InvalidatePrototypeChainsInternal(Map* map) {
if (!map->is_prototype_map()) return;
DCHECK(map->is_prototype_map());
if (FLAG_trace_prototype_users) {
PrintF("Invalidating prototype map %p 's cell\n",
reinterpret_cast<void*>(map));
......
......@@ -2353,6 +2353,11 @@ class JSObject: public JSReceiver {
static bool UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate);
static void InvalidatePrototypeChains(Map* map);
// Updates prototype chain tracking information when an object changes its
// map from |old_map| to |new_map|.
static void NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
Isolate* isolate);
// Utility used by many Array builtins and runtime functions
static inline bool PrototypeHasNoElements(Isolate* isolate, JSObject* object);
......
// Copyright 2016 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.
[1].toLocaleString();
delete Number.prototype.toLocaleString;
[1].toLocaleString();
var o = {};
o.__proto__ = { toString: Array.prototype.toString };
o.toString();
Number.prototype.arrayToString = Array.prototype.toString;
(42).arrayToString();
var a = [7];
a.toLocaleString();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment