Reviewers: Igor Sheludko,

Message:
ptal

Should probably first create the map and afterwards the instance in
api-natives.cc, but this will do for now.

Description:
Increment descriptor array slack for prototypes by a constant rather than 50% Additionally speed up instantiation of ObjectTemplates by preallocating enough
space in the descriptor arrays

BUG=

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

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+58, -39 lines):
  M src/api.cc
  M src/api-natives.cc
  M src/objects.h
  M src/objects.cc
  M src/objects-inl.h
  M src/transitions.cc


Index: src/api-natives.cc
diff --git a/src/api-natives.cc b/src/api-natives.cc
index 72c9208992c72662f38c7a4381153b8326eb2e12..e6fc28e9ef07912a16c1462568f6ba920c789547 100644
--- a/src/api-natives.cc
+++ b/src/api-natives.cc
@@ -37,11 +37,12 @@ MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
 }


-MaybeHandle<Object> DefineAccessorProperty(
-    Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
-    Handle<Object> getter, Handle<Object> setter, Smi* attributes) {
-  DCHECK(PropertyDetails::AttributesField::is_valid(
-      static_cast<PropertyAttributes>(attributes->value())));
+MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
+                                           Handle<JSObject> object,
+                                           Handle<Name> name,
+                                           Handle<Object> getter,
+                                           Handle<Object> setter,
+                                           PropertyAttributes attributes) {
   if (!getter->IsUndefined()) {
     ASSIGN_RETURN_ON_EXCEPTION(
         isolate, getter,
@@ -56,10 +57,8 @@ MaybeHandle<Object> DefineAccessorProperty(
                             Handle<FunctionTemplateInfo>::cast(setter)),
         Object);
   }
-  RETURN_ON_EXCEPTION(isolate,
-                      JSObject::DefineAccessor(
-                          object, name, getter, setter,
- static_cast<PropertyAttributes>(attributes->value())), + RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter, + setter, attributes),
                       Object);
   return object;
 }
@@ -69,13 +68,7 @@ MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
                                        Handle<JSObject> object,
                                        Handle<Name> name,
                                        Handle<Object> prop_data,
-                                       Smi* unchecked_attributes) {
-  DCHECK((unchecked_attributes->value() &
-          ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes->value());
-
+                                       PropertyAttributes attributes) {
   Handle<Object> value;
   ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
Instantiate(isolate, prop_data, name), Object); @@ -150,21 +143,36 @@ MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
   HandleScope scope(isolate);
   // Disable access checks while instantiating the object.
   AccessCheckDisableScope access_check_scope(isolate, obj);
-  for (int i = 0; i < properties.length();) {
+
+  int i = 0;
+  for (int c = 0; c < data->number_of_properties(); c++) {
     int length = Smi::cast(properties.get(i))->value();
-    if (length == 3) {
-      auto name = handle(Name::cast(properties.get(i + 1)), isolate);
-      auto prop_data = handle(properties.get(i + 2), isolate);
-      auto attributes = Smi::cast(properties.get(i + 3));
+    PropertyKind kind = length == 3 ? kData : kAccessor;
+    auto name = handle(Name::cast(properties.get(i + 1)), isolate);
+    auto unchecked_attributes = Smi::cast(properties.get(i + 2));
+    PropertyAttributes attributes =
+        static_cast<PropertyAttributes>(unchecked_attributes->value());
+    DCHECK(PropertyDetails::AttributesField::is_valid(attributes));
+
+    if (TransitionArray::SearchTransition(obj->map(), kind, *name,
+                                          attributes) == NULL &&
+        obj->map()->owns_descriptors() &&
+        obj->map()->instance_descriptors()->length() != 0 &&
+ obj->map()->instance_descriptors()->NumberOfSlackDescriptors() == 0) {
+      Map::EnsureDescriptorSlack(handle(obj->map()),
+                                 data->number_of_properties() - c);
+    }
+
+    if (kind == kData) {
+      auto prop_data = handle(properties.get(i + 3), isolate);
+
       RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
prop_data, attributes),
                           JSObject);
     } else {
-      DCHECK(length == 4);
-      auto name = handle(Name::cast(properties.get(i + 1)), isolate);
-      auto getter = handle(properties.get(i + 2), isolate);
-      auto setter = handle(properties.get(i + 3), isolate);
-      auto attributes = Smi::cast(properties.get(i + 4));
+      DCHECK_EQ(4, length);
+      auto getter = handle(properties.get(i + 3), isolate);
+      auto setter = handle(properties.get(i + 4), isolate);
       RETURN_ON_EXCEPTION(isolate,
DefineAccessorProperty(isolate, obj, name, getter,
                                                  setter, attributes),
@@ -311,6 +319,7 @@ void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ,
     list = NeanderArray(isolate).value();
     templ->set_property_list(*list);
   }
+  templ->set_number_of_properties(templ->number_of_properties() + 1);
   NeanderArray array(list);
   array.add(isolate, isolate->factory()->NewNumberFromInt(length));
   for (int i = 0; i < length; i++) {
@@ -364,7 +373,7 @@ void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
   DCHECK(Smi::IsValid(static_cast<int>(attributes)));
   auto attribute_handle =
       handle(Smi::FromInt(static_cast<int>(attributes)), isolate);
-  Handle<Object> data[kSize] = {name, value, attribute_handle};
+  Handle<Object> data[kSize] = {name, attribute_handle, value};
   AddPropertyToPropertyList(isolate, info, kSize, data);
 }

@@ -379,7 +388,7 @@ void ApiNatives::AddAccessorProperty(Isolate* isolate,
   DCHECK(Smi::IsValid(static_cast<int>(attributes)));
   auto attribute_handle =
       handle(Smi::FromInt(static_cast<int>(attributes)), isolate);
-  Handle<Object> data[kSize] = {name, getter, setter, attribute_handle};
+  Handle<Object> data[kSize] = {name, attribute_handle, getter, setter};
   AddPropertyToPropertyList(isolate, info, kSize, data);
 }

Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index c503b033affb34be8f1cc1fe61e0843f18a2b9bf..fa78df41f38c759955e8e309a6d19594e9038479 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -904,6 +904,7 @@ void NeanderArray::set(int index, i::Object* value) {


 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
+  that->set_number_of_properties(0);
   that->set_tag(i::Smi::FromInt(type));
 }

@@ -946,7 +947,7 @@ void Template::SetAccessorProperty(
 // --- F u n c t i o n   T e m p l a t e ---
 static void InitializeFunctionTemplate(
     i::Handle<i::FunctionTemplateInfo> info) {
-  info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
+  InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
   info->set_flag(0);
 }

Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 0007b37ca99a85ebc7643c9309e7a78834847e5d..0e43e1d3a0fbd434bf311fa3dffc579b3b73a3ee 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -5092,6 +5092,7 @@ ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
 ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)

 ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
+SMI_ACCESSORS(TemplateInfo, number_of_properties, kNumberOfProperties)
 ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
ACCESSORS(TemplateInfo, property_accessors, Object, kPropertyAccessorsOffset)

@@ -6945,11 +6946,13 @@ void Map::ClearCodeCache(Heap* heap) {
 }


-int Map::SlackForArraySize(int old_size, int size_limit) {
+int Map::SlackForArraySize(bool is_prototype_map, int old_size,
+                           int size_limit) {
   const int max_slack = size_limit - old_size;
-  CHECK(max_slack >= 0);
+  CHECK_LE(0, max_slack);
   if (old_size < 4) return Min(max_slack, 1);
-  return Min(max_slack, old_size / 2);
+  if (is_prototype_map) return Min(max_slack, 4);
+  return Min(max_slack, old_size / 4);
 }


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index a517615d4b8f0c669172b834caa65f003b6c4b29..bed2d0af335247cb94111a633083333b3430d201 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6784,8 +6784,9 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
     if (old_size == 0) {
       descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
     } else {
-      EnsureDescriptorSlack(
-          map, SlackForArraySize(old_size, kMaxNumberOfDescriptors));
+      int slack = SlackForArraySize(map->is_prototype_map(), old_size,
+                                    kMaxNumberOfDescriptors);
+      EnsureDescriptorSlack(map, slack);
       descriptors = handle(map->instance_descriptors());
     }
   }
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 15924b22c129178b60135026b1aa836a00d07525..e02230d49140a341faf257e23da2fce4b50fcc8f 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -6021,7 +6021,8 @@ class Map: public HeapObject {
   static void AppendCallbackDescriptors(Handle<Map> map,
                                         Handle<Object> descriptors);

-  static inline int SlackForArraySize(int old_size, int size_limit);
+  static inline int SlackForArraySize(bool is_prototype_map, int old_size,
+                                      int size_limit);

   static void EnsureDescriptorSlack(Handle<Map> map, int slack);

@@ -10452,13 +10453,16 @@ class CallHandlerInfo: public Struct {
 class TemplateInfo: public Struct {
  public:
   DECL_ACCESSORS(tag, Object)
+  inline int number_of_properties() const;
+  inline void set_number_of_properties(int value);
   DECL_ACCESSORS(property_list, Object)
   DECL_ACCESSORS(property_accessors, Object)

   DECLARE_VERIFIER(TemplateInfo)

   static const int kTagOffset = HeapObject::kHeaderSize;
-  static const int kPropertyListOffset = kTagOffset + kPointerSize;
+  static const int kNumberOfProperties = kTagOffset + kPointerSize;
+ static const int kPropertyListOffset = kNumberOfProperties + kPointerSize;
   static const int kPropertyAccessorsOffset =
       kPropertyListOffset + kPointerSize;
   static const int kHeaderSize = kPropertyAccessorsOffset + kPointerSize;
Index: src/transitions.cc
diff --git a/src/transitions.cc b/src/transitions.cc
index f00f33146792df503ffe9cd333bb0206e87c97b2..09884d506658408d6f0c7de58fcedd381b7f0502 100644
--- a/src/transitions.cc
+++ b/src/transitions.cc
@@ -106,9 +106,10 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
   }

   // We're gonna need a bigger TransitionArray.
-  Handle<TransitionArray> result = Allocate(
-      map->GetIsolate(), new_nof,
- Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions));
+  Handle<TransitionArray> result =
+      Allocate(map->GetIsolate(), new_nof,
+               Map::SlackForArraySize(false, number_of_transitions,
+                                      kMaxNumberOfTransitions));

// The map's transition array may have shrunk during the allocation above as // it was weakly traversed, though it is guaranteed not to disappear. Trim the


--
--
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