Clear Map::constructor to object_function from the same context for prototype maps...
authorverwaest <verwaest@chromium.org>
Thu, 19 Feb 2015 13:01:52 +0000 (05:01 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 19 Feb 2015 13:01:59 +0000 (13:01 +0000)
function inherit(parent, child) {
  function p() {}
  p.prototype = parent.prototype;
  child.prototype = new p();
}

Otherwise child.prototype[constructor] keeps alive p, p's context, the
initial map attached to p, and the (now empty) transition array of the
initial map.

BUG=

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

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

src/objects.cc

index 598c638..5d210bd 100644 (file)
@@ -9976,6 +9976,19 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
       Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype");
       JSObject::MigrateToMap(object, new_map);
     }
+    if (object->map()->constructor()->IsJSFunction()) {
+      JSFunction* constructor = JSFunction::cast(object->map()->constructor());
+      // Replace the pointer to the exact constructor with the Object function
+      // from the same context if undetectable from JS. This is to avoid keeping
+      // memory alive unnecessarily.
+      if (!constructor->shared()->IsApiFunction() &&
+          object->class_name() ==
+              object->GetIsolate()->heap()->Object_string()) {
+        Context* context = constructor->context()->native_context();
+        JSFunction* object_function = context->object_function();
+        object->map()->set_constructor(object_function);
+      }
+    }
     object->map()->set_is_prototype_map(true);
   }
 }