Reviewers: Igor Sheludko,

Message:
PTAL

Description:
Keep function.prototype fast.

BUG=

Please review this at https://codereview.chromium.org/437083004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+36, -6 lines):
  M src/factory.cc
  M src/objects.h
  M src/objects.cc
  M src/objects-inl.h
  M test/mjsunit/fast-prototype.js


Index: src/factory.cc
diff --git a/src/factory.cc b/src/factory.cc
index 60dc0b7a8d7a67fe2b507e10e23e89f15e24e881..864672143a800e0e6b5a4672f6697786f35a5341 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1318,7 +1318,7 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
     // maps between prototypes of different constructors.
     Handle<JSFunction> object_function(native_context->object_function());
     ASSERT(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);
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 42b3913e3a2528c6b536e0b27743b747e4db7aa2..32746b0c7a0d9e2100e2a70e47beb80b5d98a992 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2115,6 +2115,7 @@ bool JSObject::HasFastProperties() {

 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();
@@ -4445,6 +4446,15 @@ bool Map::is_extensible() {
 }


+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) {
   set_bit_field3(IsShared::update(bit_field3(), value));
 }
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 4217666afa02b859f0055d4811bb17d41cdb04f2..19a22b433e24e4eca8f43b62c11691fb1051a785 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -7266,6 +7266,13 @@ Handle<Map> Map::CopyForObserved(Handle<Map> 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) {
   Handle<DescriptorArray> descriptors(map->instance_descriptors());
   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
@@ -10003,7 +10010,12 @@ void JSFunction::SetInstancePrototype(Handle<JSFunction> function, // 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
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 701a17a969af6b6d9dd35c59201965c1b7ffcfcb..a0369416bb41ad4ab0c149aed89ce653fe11c48d 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -6204,6 +6204,8 @@ class Map: public HeapObject {

   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) {
     ASSERT(elements_kind < kElementsKindCount);
@@ -6537,6 +6539,7 @@ class Map: public HeapObject {
   // 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 @@ class Map: public HeapObject {
   // 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
Index: test/mjsunit/fast-prototype.js
diff --git a/test/mjsunit/fast-prototype.js b/test/mjsunit/fast-prototype.js
index cdcc1a9ed68e8995b4642b5702166e781b46e211..55a0faae805341b16804deeef6e53e7a49dfc1cd 100644
--- a/test/mjsunit/fast-prototype.js
+++ b/test/mjsunit/fast-prototype.js
@@ -72,10 +72,15 @@ function test(use_new, add_first, set__proto__, same_map_as) {
     // 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