[ic] Clarify lookup start object vs holder more

This CL also allows reusing slow case for API callbacks.

Bug: chromium:1201781
Change-Id: Ib5f81c510404060c888ba30c82357d6ed1a95cf5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2882809
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74470}
This commit is contained in:
Igor Sheludko 2021-05-10 14:07:41 +02:00 committed by V8 LUCI CQ
parent d0c5b343da
commit 0e9a480fa5
4 changed files with 45 additions and 45 deletions

View File

@ -696,8 +696,9 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
p->name(), p->slot(), p->vector());
} else {
exit_point->ReturnCallRuntime(Runtime::kGetProperty, p->context(), holder,
p->name(), p->receiver());
exit_point->ReturnCallRuntime(Runtime::kGetProperty, p->context(),
p->lookup_start_object(), p->name(),
p->receiver());
}
}

View File

@ -774,23 +774,20 @@ void IC::SetCache(Handle<Name> name, const MaybeObjectHandle& handler) {
}
void LoadIC::UpdateCaches(LookupIterator* lookup) {
Handle<Object> code;
Handle<Object> handler;
if (lookup->state() == LookupIterator::ACCESS_CHECK) {
code = LoadHandler::LoadSlow(isolate());
handler = LoadHandler::LoadSlow(isolate());
} else if (!lookup->IsFound()) {
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
Handle<Smi> smi_handler = LoadHandler::LoadNonExistent(isolate());
code = LoadHandler::LoadFullChain(
handler = LoadHandler::LoadFullChain(
isolate(), lookup_start_object_map(),
MaybeObjectHandle(isolate()->factory()->null_value()), smi_handler);
} else if (IsLoadGlobalIC() && lookup->state() == LookupIterator::JSPROXY) {
// If there is proxy just install the slow stub since we need to call the
// HasProperty trap for global loads. The ProxyGetProperty builtin doesn't
// handle this case.
Handle<Smi> slow_handler = LoadHandler::LoadSlow(isolate());
Handle<JSProxy> holder = lookup->GetHolder<JSProxy>();
code = LoadHandler::LoadFromPrototype(isolate(), lookup_start_object_map(),
holder, slow_handler);
handler = LoadHandler::LoadSlow(isolate());
} else {
if (IsLoadGlobalIC()) {
if (lookup->TryLookupCachedProperty()) {
@ -805,12 +802,12 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
return;
}
}
code = ComputeHandler(lookup);
handler = ComputeHandler(lookup);
}
// Can't use {lookup->name()} because the LookupIterator might be in
// "elements" mode for keys that are strings representing integers above
// JSArray::kMaxIndex.
SetCache(lookup->GetName(), code);
SetCache(lookup->GetName(), handler);
TraceIC("LoadIC", lookup->GetName());
}

View File

@ -27,23 +27,22 @@
namespace v8 {
namespace internal {
MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
Handle<Object> holder,
Handle<Object> key,
Handle<Object> receiver,
bool* is_found) {
MaybeHandle<Object> Runtime::GetObjectProperty(
Isolate* isolate, Handle<Object> lookup_start_object, Handle<Object> key,
Handle<Object> receiver, bool* is_found) {
if (receiver.is_null()) {
receiver = holder;
receiver = lookup_start_object;
}
if (holder->IsNullOrUndefined(isolate)) {
ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, holder, key);
if (lookup_start_object->IsNullOrUndefined(isolate)) {
ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, lookup_start_object, key);
return MaybeHandle<Object>();
}
bool success = false;
LookupIterator::Key lookup_key(isolate, key, &success);
if (!success) return MaybeHandle<Object>();
LookupIterator it = LookupIterator(isolate, receiver, lookup_key, holder);
LookupIterator it =
LookupIterator(isolate, receiver, lookup_key, lookup_start_object);
MaybeHandle<Object> result = Object::GetProperty(&it);
if (is_found) *is_found = it.IsFound();
@ -60,12 +59,12 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
: name_string;
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kInvalidPrivateBrand,
class_name, holder),
class_name, lookup_start_object),
Object);
}
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kInvalidPrivateMemberRead,
name_string, holder),
name_string, lookup_start_object),
Object);
}
return result;
@ -707,15 +706,15 @@ RUNTIME_FUNCTION(Runtime_JSReceiverSetPrototypeOfDontThrow) {
RUNTIME_FUNCTION(Runtime_GetProperty) {
HandleScope scope(isolate);
DCHECK(args.length() == 3 || args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, holder_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, lookup_start_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
Handle<Object> receiver_obj = holder_obj;
Handle<Object> receiver_obj = lookup_start_obj;
if (args.length() == 3) {
CHECK(args[2].IsObject());
receiver_obj = args.at<Object>(2);
}
// Fast cases for getting named properties of the holder JSObject
// Fast cases for getting named properties of the lookup_start_obj JSObject
// itself.
//
// The global proxy objects has to be excluded since LookupOwn on
@ -733,18 +732,19 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
if (key_obj->IsString() && String::cast(*key_obj).AsArrayIndex(&index)) {
key_obj = isolate->factory()->NewNumberFromUint(index);
}
if (holder_obj->IsJSObject()) {
if (!holder_obj->IsJSGlobalProxy() && !holder_obj->IsAccessCheckNeeded() &&
key_obj->IsName()) {
Handle<JSObject> holder = Handle<JSObject>::cast(holder_obj);
if (lookup_start_obj->IsJSObject()) {
Handle<JSObject> lookup_start_object =
Handle<JSObject>::cast(lookup_start_obj);
if (!lookup_start_object->IsJSGlobalProxy() &&
!lookup_start_object->IsAccessCheckNeeded() && key_obj->IsName()) {
Handle<Name> key = Handle<Name>::cast(key_obj);
key_obj = key = isolate->factory()->InternalizeName(key);
DisallowGarbageCollection no_gc;
if (holder->IsJSGlobalObject()) {
if (lookup_start_object->IsJSGlobalObject()) {
// Attempt dictionary lookup.
GlobalDictionary dictionary =
JSGlobalObject::cast(*holder).global_dictionary(kAcquireLoad);
GlobalDictionary dictionary = JSGlobalObject::cast(*lookup_start_object)
.global_dictionary(kAcquireLoad);
InternalIndex entry = dictionary.FindEntry(isolate, key);
if (entry.is_found()) {
PropertyCell cell = dictionary.CellAt(entry);
@ -754,17 +754,19 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
// If value is the hole (meaning, absent) do the general lookup.
}
}
} else if (!holder->HasFastProperties()) {
} else if (!lookup_start_object->HasFastProperties()) {
// Attempt dictionary lookup.
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
SwissNameDictionary dictionary = holder->property_dictionary_swiss();
SwissNameDictionary dictionary =
lookup_start_object->property_dictionary_swiss();
InternalIndex entry = dictionary.FindEntry(isolate, *key);
if (entry.is_found() &&
(dictionary.DetailsAt(entry).kind() == kData)) {
return dictionary.ValueAt(entry);
}
} else {
NameDictionary dictionary = holder->property_dictionary();
NameDictionary dictionary =
lookup_start_object->property_dictionary();
InternalIndex entry = dictionary.FindEntry(isolate, key);
if ((entry.is_found()) &&
(dictionary.DetailsAt(entry).kind() == kData)) {
@ -779,22 +781,21 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
// transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
// doubles for those future calls in the case that the elements would
// become PACKED_DOUBLE_ELEMENTS.
Handle<JSObject> js_object = Handle<JSObject>::cast(holder_obj);
ElementsKind elements_kind = js_object->GetElementsKind();
ElementsKind elements_kind = lookup_start_object->GetElementsKind();
if (IsDoubleElementsKind(elements_kind)) {
if (Smi::ToInt(*key_obj) >= js_object->elements().length()) {
if (Smi::ToInt(*key_obj) >= lookup_start_object->elements().length()) {
elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
: PACKED_ELEMENTS;
JSObject::TransitionElementsKind(js_object, elements_kind);
JSObject::TransitionElementsKind(lookup_start_object, elements_kind);
}
} else {
DCHECK(IsSmiOrObjectElementsKind(elements_kind) ||
!IsFastElementsKind(elements_kind));
}
}
} else if (holder_obj->IsString() && key_obj->IsSmi()) {
} else if (lookup_start_obj->IsString() && key_obj->IsSmi()) {
// Fast case for string indexing using [] with a smi index.
Handle<String> str = Handle<String>::cast(holder_obj);
Handle<String> str = Handle<String>::cast(lookup_start_obj);
int index = Handle<Smi>::cast(key_obj)->value();
if (index >= 0 && index < str->length()) {
Factory* factory = isolate->factory();
@ -805,8 +806,8 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
// Fall back to GetObjectProperty.
RETURN_RESULT_OR_FAILURE(
isolate,
Runtime::GetObjectProperty(isolate, holder_obj, key_obj, receiver_obj));
isolate, Runtime::GetObjectProperty(isolate, lookup_start_obj, key_obj,
receiver_obj));
}
RUNTIME_FUNCTION(Runtime_SetKeyedProperty) {

View File

@ -788,9 +788,10 @@ class Runtime : public AllStatic {
Handle<Object> value, StoreOrigin store_origin,
Maybe<ShouldThrow> should_throw = Nothing<ShouldThrow>());
// When "receiver" is not passed, it defaults to "holder".
// When "receiver" is not passed, it defaults to "lookup_start_object".
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Object>
GetObjectProperty(Isolate* isolate, Handle<Object> holder, Handle<Object> key,
GetObjectProperty(Isolate* isolate, Handle<Object> lookup_start_object,
Handle<Object> key,
Handle<Object> receiver = Handle<Object>(),
bool* is_found = nullptr);