Revision: 22826
Author:   [email protected]
Date:     Mon Aug  4 15:02:07 2014 UTC
Log:      Keep function.prototype fast.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/437083004
http://code.google.com/p/v8/source/detail?r=22826

Modified:
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/test/mjsunit/fast-prototype.js

=======================================
--- /branches/bleeding_edge/src/factory.cc      Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc      Mon Aug  4 15:02:07 2014 UTC
@@ -1318,7 +1318,7 @@
     // maps between prototypes of different constructors.
     Handle<JSFunction> object_function(native_context->object_function());
     DCHECK(object_function->has_initial_map());
-    new_map = Map::Copy(handle(object_function->initial_map()));
+ new_map = Map::CopyAsPrototypeMap(handle(object_function->initial_map()));
   }

   Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Mon Aug  4 15:02:07 2014 UTC
@@ -2115,6 +2115,7 @@

 bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
   if (unused_property_fields() != 0) return false;
+  if (is_prototype_map()) return false;
   int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
   int limit = Max(minimum, inobject_properties());
   int external = NumberOfFields() - inobject_properties();
@@ -4443,6 +4444,15 @@
 bool Map::is_extensible() {
   return ((1 << kIsExtensible) & bit_field2()) != 0;
 }
+
+
+void Map::mark_prototype_map() {
+  set_bit_field2(IsPrototypeMapBits::update(bit_field2(), true));
+}
+
+bool Map::is_prototype_map() {
+  return IsPrototypeMapBits::decode(bit_field2());
+}


 void Map::set_is_shared(bool value) {
=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Mon Aug  4 15:02:07 2014 UTC
@@ -7264,6 +7264,13 @@
   new_map->SetBackPointer(*map);
   return new_map;
 }
+
+
+Handle<Map> Map::CopyAsPrototypeMap(Handle<Map> map) {
+  Handle<Map> result = Copy(map);
+  result->mark_prototype_map();
+  return result;
+}


 Handle<Map> Map::Copy(Handle<Map> map) {
@@ -10003,7 +10010,12 @@
// First some logic for the map of the prototype to make sure it is in fast
   // mode.
   if (value->IsJSObject()) {
-    JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
+    Handle<JSObject> js_proto = Handle<JSObject>::cast(value);
+    JSObject::OptimizeAsPrototype(js_proto);
+    if (js_proto->HasFastProperties()) {
+ Handle<Map> new_map = Map::CopyAsPrototypeMap(handle(js_proto->map()));
+      JSObject::MigrateToMap(js_proto, new_map);
+    }
   }

// Now some logic for the maps of the objects that are created by using this
@@ -10120,15 +10132,9 @@
   Handle<Object> prototype;
   if (function->has_instance_prototype()) {
     prototype = handle(function->instance_prototype(), isolate);
-    for (PrototypeIterator iter(isolate, prototype,
-                                PrototypeIterator::START_AT_RECEIVER);
-         !iter.IsAtEnd(); iter.Advance()) {
-      if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
-        break;
-      }
-      JSObject::OptimizeAsPrototype(
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
-    }
+ // TODO(verwaest): Remove once "delete" keeps objects marked as prototypes
+    // fast as well.
+    JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(prototype));
   } else {
     prototype = isolate->factory()->NewFunctionPrototype(function);
   }
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Mon Aug  4 15:02:07 2014 UTC
@@ -6204,6 +6204,8 @@

   inline void set_is_extensible(bool value);
   inline bool is_extensible();
+  inline void mark_prototype_map();
+  inline bool is_prototype_map();

   inline void set_elements_kind(ElementsKind elements_kind) {
     DCHECK(elements_kind < kElementsKindCount);
@@ -6537,6 +6539,7 @@
   // Returns a copy of the map, with all transitions dropped from the
   // instance descriptors.
   static Handle<Map> Copy(Handle<Map> map);
+  static Handle<Map> CopyAsPrototypeMap(Handle<Map> map);
   static Handle<Map> Create(Handle<JSFunction> constructor,
                             int extra_inobject_properties);

@@ -6736,7 +6739,7 @@
   // Bit positions for bit field 2
   static const int kIsExtensible = 0;
   static const int kStringWrapperSafeForDefaultValueOf = 1;
-  // Currently bit 2 is not used.
+  class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
   class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};

   // Derived values from bit field 2
=======================================
--- /branches/bleeding_edge/test/mjsunit/fast-prototype.js Tue Jan 21 12:41:25 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/fast-prototype.js Mon Aug 4 15:02:07 2014 UTC
@@ -72,10 +72,15 @@
     // Still fast
     assertTrue(%HasFastProperties(proto));
     AddProps(proto);
-    // After we add all those properties it went slow mode again :-(
-    assertFalse(%HasFastProperties(proto));
+    if (set__proto__) {
+      // After we add all those properties it went slow mode again :-(
+      assertFalse(%HasFastProperties(proto));
+    } else {
+      // .prototype keeps it fast.
+      assertTrue(%HasFastProperties(proto));
+    }
   }
-  if (same_map_as && !add_first) {
+  if (same_map_as && !add_first && set__proto__) {
     assertTrue(%HaveSameMap(same_map_as, proto));
   }
   return proto;

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to