Reviewers: Igor Sheludko,

Message:
Hi Igor,
Here is the change we were discussing. I front-load the work that might change
after the property set.

This will make vector-based stores way easier.
Thanks,
--Michael

Description:
Reorder KeyedStoreIC MISS code to avoid unnecessary compilation.

We can set the property in the MISS handler before organizing our handlers
for element-based keyed stores. Since the property set may fail with an
exception, this saves work.

BUG=

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

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

Affected files (+32, -23 lines):
  M src/ic/ic.h
  M src/ic/ic.cc


Index: src/ic/ic.cc
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index e6ee50108bb33699349a0bd32c49454b3c7de5a6..0dc60c061c6695a200543c8041cf8873af2cd7a2 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -1851,7 +1851,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
 }


-Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
+Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode) {
   // Don't handle megamorphic property accesses for INTERCEPTORS or
   // ACCESSOR_CONSTANT
@@ -1862,7 +1862,6 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
     return megamorphic_stub();
   }

-  Handle<Map> receiver_map(receiver->map(), isolate());
   MapHandleList target_receiver_maps;
   TargetMaps(&target_receiver_maps);
   if (target_receiver_maps.length() == 0) {
@@ -1896,7 +1895,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
       store_mode = GetNonTransitioningStoreMode(store_mode);
       return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
           transitioned_receiver_map, language_mode(), store_mode);
-    } else if (*previous_receiver_map == receiver->map() &&
+    } else if (receiver_map.is_identical_to(previous_receiver_map) &&
                old_store_mode == STANDARD_STORE &&
                (store_mode == STORE_AND_GROW_NO_TRANSITION ||
                 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
@@ -2160,23 +2159,41 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
     }
   }

+  Handle<Map> old_receiver_map;
+  bool sloppy_arguments_elements = false;
+  bool key_is_valid_index = false;
+  KeyedAccessStoreMode store_mode = STANDARD_STORE;
+  if (object->IsJSObject()) {
+    Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+    old_receiver_map = handle(receiver->map(), isolate());
+    sloppy_arguments_elements =
+        receiver->elements()->map() ==
+        isolate()->heap()->sloppy_arguments_elements_map();
+    if (!sloppy_arguments_elements) {
+      key_is_valid_index = key->IsSmi() && Smi::cast(*key)->value() >= 0;
+      if (key_is_valid_index) {
+        uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value());
+        store_mode = GetStoreMode(receiver, index, value);
+      }
+    }
+  }
+
+  ASSIGN_RETURN_ON_EXCEPTION(isolate(), store_handle,
+ Runtime::SetObjectProperty(isolate(), object, key, + value, language_mode()),
+                             Object);
+
   if (use_ic) {
-    if (object->IsJSObject()) {
-      Handle<JSObject> receiver = Handle<JSObject>::cast(object);
-      if (receiver->elements()->map() ==
-              isolate()->heap()->sloppy_arguments_elements_map() &&
-          !is_sloppy(language_mode())) {
+    if (!old_receiver_map.is_null()) {
+      if (sloppy_arguments_elements && !is_sloppy(language_mode())) {
         TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
-      } else if (key->IsSmi() && Smi::cast(*key)->value() >= 0) {
-        uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value());
+      } else if (key_is_valid_index) {
         // We should go generic if receiver isn't a dictionary, but our
         // prototype chain does have dictionary elements. This ensures that
         // other non-dictionary receivers in the polymorphic case benefit
         // from fast path keyed stores.
-        if (!receiver->map()->DictionaryElementsInPrototypeChainOnly()) {
-          KeyedAccessStoreMode store_mode =
-              GetStoreMode(receiver, index, value);
-          stub = StoreElementStub(receiver, store_mode);
+        if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly()) {
+          stub = StoreElementStub(old_receiver_map, store_mode);

           // Validate that the store_mode in the stub can also be derived
           // from peeking in the code bits of the handlers.
@@ -2192,14 +2209,6 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
     }
   }

-  if (store_handle.is_null()) {
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate(), store_handle,
-        Runtime::SetObjectProperty(isolate(), object, key, value,
-                                   language_mode()),
-        Object);
-  }
-
   if (FLAG_vector_stores) {
     if (!is_vector_set() || stub.is_null()) {
       Code* megamorphic = *megamorphic_stub();
Index: src/ic/ic.h
diff --git a/src/ic/ic.h b/src/ic/ic.h
index 9f4ccd15ad5c694103341031c1a9aa70a9b7eb46..9223e7dce8e6e16d396c6bf006813fe8bf7f6e41 100644
--- a/src/ic/ic.h
+++ b/src/ic/ic.h
@@ -587,7 +587,7 @@ class KeyedStoreIC : public StoreIC {
     }
   }

-  Handle<Code> StoreElementStub(Handle<JSObject> receiver,
+  Handle<Code> StoreElementStub(Handle<Map> receiver_map,
                                 KeyedAccessStoreMode store_mode);

  private:


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