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.