Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: src/ic/ic.cc

Issue 2419513002: [ic] Support data handlers that represent loads from prototypes. (Closed)
Patch Set: Rebasing Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/ic.cc
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index eea4629d048ca25da6f089495ef9c3643b4aa8d3..005e3e7403b5e0508d4b291821b10b7f0c078d31 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -831,6 +831,7 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) {
if (FLAG_tf_load_ic_stub) {
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
return handle(Smi::FromInt(index.GetLoadByFieldOffset()), isolate());
}
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
@@ -838,6 +839,46 @@ Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) {
return stub.GetCode();
}
+Handle<Object> LoadIC::SimpleFieldLoadFromPrototype(FieldIndex index,
+ Handle<Map> receiver_map,
+ Handle<JSObject> holder) {
+ if (!FLAG_tf_load_ic_stub) return Handle<Object>::null();
+
+ DCHECK(holder->HasFastProperties());
+
+ // The following kinds of receiver maps require custom handler compilation.
+ if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap() ||
+ receiver_map->IsJSGlobalObjectMap() ||
+ receiver_map->is_dictionary_map()) {
+ return Handle<Object>::null();
+ }
+
+ // Switch to custom compiled handler if the prototype chain contains global
+ // or dictionary objects.
+ for (PrototypeIterator iter(*receiver_map); !iter.IsAtEnd(); iter.Advance()) {
+ JSObject* current = iter.GetCurrent<JSObject>();
+ if (current == *holder) break;
+ Map* current_map = current->map();
+ if (current_map->IsJSGlobalObjectMap() ||
+ current_map->IsJSGlobalProxyMap() || current_map->is_dictionary_map()) {
+ return Handle<Object>::null();
+ }
+ // Only objects that do not require access checks are allowed in stubs.
+ DCHECK(!current_map->is_access_check_needed());
+ }
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH);
+ Handle<Cell> validity_cell =
+ Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
+ DCHECK(!validity_cell.is_null());
+
+ Handle<Object> handler(Smi::FromInt(index.GetLoadByFieldOffset()), isolate());
+ DCHECK(handler->IsSmi());
+
+ Factory* factory = isolate()->factory();
+
+ Handle<WeakCell> holder_cell = factory->NewWeakCell(holder);
+ return factory->NewTuple3(validity_cell, holder_cell, handler);
+}
bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
DCHECK(lookup->state() == LookupIterator::ACCESSOR);
@@ -1142,6 +1183,11 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
if (receiver_is_holder) {
return SimpleFieldLoad(field);
}
+ Handle<Object> handler =
+ SimpleFieldLoadFromPrototype(field, map, holder);
+ if (!handler.is_null()) {
+ return handler;
+ }
break; // Custom-compiled handler.
}
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698