Mark proxy map as unstable during proxy fixing (freezing, sealing or preventing exten...
authorishell <ishell@chromium.org>
Tue, 2 Jun 2015 11:29:22 +0000 (04:29 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 2 Jun 2015 11:29:27 +0000 (11:29 +0000)
BUG=chromium:493568
LOG=N

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

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

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

index 9176650..6fc18eb 100644 (file)
@@ -2019,17 +2019,13 @@ void Factory::ReinitializeJSProxy(Handle<JSProxy> 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> map = NewMap(type, size);
+  Handle<Map> proxy_map(proxy->map());
+  Handle<Map> 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<Object> prototype(proxy->map()->prototype(), isolate());
-  Map::SetPrototype(map, prototype);
-
   // Allocate the backing storage for the properties.
   int prop_size = map->InitialPropertiesLength();
   Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);
index 79ea1b1..661d769 100644 (file)
@@ -7200,6 +7200,25 @@ Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
 }
 
 
+Handle<Map> Map::FixProxy(Handle<Map> 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<Map> new_map = isolate->factory()->NewMap(type, size);
+
+  Handle<Object> 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()) {
index 0828952..1a1cb09 100644 (file)
@@ -6295,6 +6295,10 @@ class Map: public HeapObject {
                                               PropertyAttributes attrs_to_add,
                                               Handle<Symbol> transition_marker,
                                               const char* reason);
+
+  static Handle<Map> FixProxy(Handle<Map> 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 (file)
index 0000000..081f493
--- /dev/null
@@ -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);