From 65ada9fa0b0d938c2e05cbee08a8a7f47665db87 Mon Sep 17 00:00:00 2001 From: ishell Date: Tue, 2 Jun 2015 04:29:22 -0700 Subject: [PATCH] Mark proxy map as unstable during proxy fixing (freezing, sealing or preventing extensions). BUG=chromium:493568 LOG=N Review URL: https://codereview.chromium.org/1158023003 Cr-Commit-Position: refs/heads/master@{#28759} --- src/factory.cc | 10 +++------- src/objects.cc | 19 +++++++++++++++++++ src/objects.h | 4 ++++ test/mjsunit/regress/regress-crbug-493568.js | 12 ++++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-493568.js diff --git a/src/factory.cc b/src/factory.cc index 9176650..6fc18eb 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -2019,17 +2019,13 @@ void Factory::ReinitializeJSProxy(Handle proxy, InstanceType type, int size) { DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE); - // Allocate fresh map. - // TODO(rossberg): Once we optimize proxies, cache these maps. - Handle map = NewMap(type, size); + Handle proxy_map(proxy->map()); + Handle map = Map::FixProxy(proxy_map, type, size); // Check that the receiver has at least the size of the fresh object. - int size_difference = proxy->map()->instance_size() - map->instance_size(); + int size_difference = proxy_map->instance_size() - map->instance_size(); DCHECK(size_difference >= 0); - Handle prototype(proxy->map()->prototype(), isolate()); - Map::SetPrototype(map, prototype); - // Allocate the backing storage for the properties. int prop_size = map->InitialPropertiesLength(); Handle properties = NewFixedArray(prop_size, TENURED); diff --git a/src/objects.cc b/src/objects.cc index 79ea1b1..661d769 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -7200,6 +7200,25 @@ Handle Map::CopyForPreventExtensions(Handle map, } +Handle Map::FixProxy(Handle map, InstanceType type, int size) { + DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE); + DCHECK(map->IsJSProxyMap()); + + Isolate* isolate = map->GetIsolate(); + + // Allocate fresh map. + // TODO(rossberg): Once we optimize proxies, cache these maps. + Handle new_map = isolate->factory()->NewMap(type, size); + + Handle prototype(map->prototype(), isolate); + Map::SetPrototype(new_map, prototype); + + map->NotifyLeafMapLayoutChange(); + + return new_map; +} + + bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { PropertyDetails details = GetDetails(descriptor); switch (details.type()) { diff --git a/src/objects.h b/src/objects.h index 0828952..1a1cb09 100644 --- a/src/objects.h +++ b/src/objects.h @@ -6295,6 +6295,10 @@ class Map: public HeapObject { PropertyAttributes attrs_to_add, Handle transition_marker, const char* reason); + + static Handle FixProxy(Handle map, InstanceType type, int size); + + // Maximal number of fast properties. Used to restrict the number of map // transitions to avoid an explosion in the number of maps for objects used as // dictionaries. diff --git a/test/mjsunit/regress/regress-crbug-493568.js b/test/mjsunit/regress/regress-crbug-493568.js new file mode 100644 index 0000000..081f493 --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-493568.js @@ -0,0 +1,12 @@ +// 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. + +// Flags: --allow-natives-syntax --harmony-proxies + +var p = Proxy.create({ fix: function() { return {}; } }); + +var obj = {}; +obj.x = p; + +Object.preventExtensions(p); -- 2.7.4