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

Unified Diff: src/ic/ic.cc

Issue 2419513002: [ic] Support data handlers that represent loads from prototypes. (Closed)
Patch Set: 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
Index: src/ic/ic.cc
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index eea4629d048ca25da6f089495ef9c3643b4aa8d3..458d90d73e676c7165943cbd67d32ab03f425cbb 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -838,6 +838,52 @@ 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();
Jakob Kummerow 2016/10/13 11:59:26 nit: you probably want to make the flag non-readon
Igor Sheludko 2016/10/13 13:20:38 We should just remove this flag once you remove th
+
+ DCHECK(holder->HasFastProperties());
+
+ // Primitive maps require custom handler compilation.
+ if (receiver_map->IsPrimitiveMap()) {
+ return Handle<Object>::null();
+ }
+
+ // Switch to custom compiled handler if the prototype chain contains global
+ // or dictionary objects.
+ {
+ Map* current_map = *receiver_map;
+ Map* holder_map = holder->map();
+ while (current_map != holder_map) {
+ // Only global objects and objects that do not require access
+ // checks are allowed in stubs.
+ DCHECK(current_map->IsJSGlobalProxyMap() ||
+ !current_map->is_access_check_needed());
+
+ if (current_map->IsJSGlobalObjectMap() ||
+ current_map->IsJSGlobalProxyMap() ||
+ current_map->is_dictionary_map()) {
+ return Handle<Object>::null();
+ }
+ // Go to the next object in the prototype chain.
+ JSObject* prototype = JSObject::cast(current_map->prototype());
Jakob Kummerow 2016/10/13 11:59:26 nit: use a PrototypeIterator please
Igor Sheludko 2016/10/13 13:20:38 Done.
+ current_map = prototype->map();
+ }
+ }
+
+ Handle<Cell> validity_cell =
+ Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
+ DCHECK(!validity_cell.is_null());
+
+ Handle<Object> handler = SimpleFieldLoad(index);
+ DCHECK(handler->IsSmi());
+
+ Factory* factory = isolate()->factory();
+
+ Handle<WeakCell> holder_cell = factory->NewWeakCell(holder);
+ return isolate()->factory()->NewTuple3(validity_cell, holder_cell, handler);
Jakob Kummerow 2016/10/13 11:59:26 nit: s/isolate()->factory()/factory/
Igor Sheludko 2016/10/13 13:20:38 Done.
+}
bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
DCHECK(lookup->state() == LookupIterator::ACCESSOR);
@@ -1142,6 +1188,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.
}

Powered by Google App Engine
This is Rietveld 408576698