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

Unified Diff: src/ic/ic.cc

Issue 2513893003: [ic] Don't check full prototype chain if name is a private symbol. (Closed)
Patch Set: and JSProxy case Created 4 years, 1 month 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 | « no previous file | src/prototype.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 28070b84dae9b7fb39392de7d0b0b77050162b38..d46388faf9983f4bc8923566eae51e5d22a167f3 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -855,8 +855,8 @@ namespace {
template <bool fill_array = true>
int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
- Handle<JSObject> holder, Handle<FixedArray> array,
- Handle<Name> name, int first_index) {
+ Handle<JSObject> holder, Handle<Name> name,
+ Handle<FixedArray> array, int first_index) {
DCHECK(holder.is_null() || holder->HasFastProperties());
// We don't encode the requirement to check access rights because we already
@@ -894,7 +894,11 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
// Create/count entries for each global or dictionary prototype appeared in
// the prototype chain contains from receiver till holder.
- for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) {
+ PrototypeIterator::WhereToEnd end = name->IsPrivate()
+ ? PrototypeIterator::END_AT_NON_HIDDEN
+ : PrototypeIterator::END_AT_NULL;
+ for (PrototypeIterator iter(receiver_map, end); !iter.IsAtEnd();
+ iter.Advance()) {
Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
if (holder.is_identical_to(current)) break;
Handle<Map> current_map(current->map(), isolate);
@@ -932,9 +936,9 @@ int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
// Returns -1 if the handler has to be compiled or the number of prototype
// checks otherwise.
int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map,
- Handle<JSObject> holder) {
- return InitPrototypeChecks<false>(isolate, receiver_map, holder,
- Handle<FixedArray>(), Handle<Name>(), 0);
+ Handle<JSObject> holder, Handle<Name> name) {
+ return InitPrototypeChecks<false>(isolate, receiver_map, holder, name,
+ Handle<FixedArray>(), 0);
}
} // namespace
@@ -943,7 +947,8 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Handle<JSObject> holder,
Handle<Name> name,
Handle<Object> smi_handler) {
- int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder);
+ int checks_count =
+ GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
DCHECK_LE(0, checks_count);
if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) {
@@ -973,7 +978,7 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler);
handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell);
handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell);
- InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name,
+ InitPrototypeChecks(isolate(), receiver_map, holder, name, handler_array,
LoadHandler::kFirstPrototypeIndex);
return handler_array;
}
@@ -981,7 +986,8 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map,
Handle<Name> name) {
Handle<JSObject> holder; // null handle
- int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder);
+ int checks_count =
+ GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
DCHECK_LE(0, checks_count);
bool do_negative_lookup_on_receiver =
@@ -999,9 +1005,6 @@ Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map,
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
if (validity_cell.is_null()) {
- // This must be a case when receiver's prototype is null.
- DCHECK_EQ(*isolate()->factory()->null_value(),
- receiver_map->GetPrototypeChainRootMap(isolate())->prototype());
DCHECK_EQ(0, checks_count);
validity_cell = handle(Smi::FromInt(0), isolate());
}
@@ -1016,7 +1019,7 @@ Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map,
handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler);
handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell);
handler_array->set(LoadHandler::kHolderCellIndex, *factory->null_value());
- InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name,
+ InitPrototypeChecks(isolate(), receiver_map, holder, name, handler_array,
LoadHandler::kFirstPrototypeIndex);
return handler_array;
}
@@ -1893,17 +1896,20 @@ Handle<Object> StoreIC::StoreTransition(Handle<Map> receiver_map,
smi_handler = StoreHandler::TransitionToField(
isolate(), descriptor, index, representation, extend_storage);
}
+ // |holder| is either a receiver if the property is non-existent or
+ // one of the prototypes.
+ DCHECK(!holder.is_null());
+ bool is_nonexistent = holder->map() == transition->GetBackPointer();
+ if (is_nonexistent) holder = Handle<JSObject>::null();
- int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder);
+ int checks_count =
+ GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
DCHECK_LE(0, checks_count);
DCHECK(!receiver_map->IsJSGlobalObjectMap());
Handle<Object> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
if (validity_cell.is_null()) {
- // This must be a case when receiver's prototype is null.
- DCHECK_EQ(*isolate()->factory()->null_value(),
- receiver_map->GetPrototypeChainRootMap(isolate())->prototype());
DCHECK_EQ(0, checks_count);
validity_cell = handle(Smi::FromInt(0), isolate());
}
@@ -1919,7 +1925,7 @@ Handle<Object> StoreIC::StoreTransition(Handle<Map> receiver_map,
handler_array->set(StoreHandler::kSmiHandlerIndex, *smi_handler);
handler_array->set(StoreHandler::kValidityCellIndex, *validity_cell);
handler_array->set(StoreHandler::kTransitionCellIndex, *transition_cell);
- InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name,
+ InitPrototypeChecks(isolate(), receiver_map, holder, name, handler_array,
StoreHandler::kFirstPrototypeIndex);
return handler_array;
}
« no previous file with comments | « no previous file | src/prototype.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698