[protectors] Move PromiseThenLookupChain protector to Protectors

Bug: v8:9463
Change-Id: Ife5ea730166e76bdbe8b18eac1eb5688b7aaf150
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1800513
Commit-Queue: Joshua Litt <joshualitt@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63795}
This commit is contained in:
Joshua Litt 2019-09-16 06:09:05 -07:00 committed by Commit Bot
parent bec49d81df
commit 7c9c1039b4
5 changed files with 16 additions and 44 deletions

View File

@ -3929,23 +3929,6 @@ bool Isolate::IsPromiseResolveLookupChainIntact() {
return is_promise_resolve_protector_intact;
}
bool Isolate::IsPromiseThenLookupChainIntact() {
PropertyCell promise_then_cell = heap()->promise_then_protector();
bool is_promise_then_protector_intact =
Smi::ToInt(promise_then_cell.value()) == kProtectorValid;
return is_promise_then_protector_intact;
}
bool Isolate::IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver) {
DisallowHeapAllocation no_gc;
if (!receiver->IsJSPromise()) return false;
if (!IsInAnyContext(receiver->map().prototype(),
Context::PROMISE_PROTOTYPE_INDEX)) {
return false;
}
return IsPromiseThenLookupChainIntact();
}
void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
DisallowHeapAllocation no_gc;
if (!object->map().is_prototype_map()) return;
@ -4059,15 +4042,6 @@ void Isolate::InvalidatePromiseResolveProtector() {
DCHECK(!IsPromiseResolveLookupChainIntact());
}
void Isolate::InvalidatePromiseThenProtector() {
DCHECK(factory()->promise_then_protector()->value().IsSmi());
DCHECK(IsPromiseThenLookupChainIntact());
PropertyCell::SetValueWithInvalidation(
this, "promise_then_protector", factory()->promise_then_protector(),
handle(Smi::FromInt(kProtectorInvalid), this));
DCHECK(!IsPromiseThenLookupChainIntact());
}
bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
DisallowHeapAllocation no_gc;
return IsInAnyContext(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);

View File

@ -1226,14 +1226,6 @@ class Isolate final : private HiddenFactory {
// yeidls the initial Promise.resolve method.
bool IsPromiseResolveLookupChainIntact();
// Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the
// initial %PromisePrototype% yields the initial method. In addition this
// protector also guards the negative lookup of "then" on the intrinsic
// %ObjectPrototype%, meaning that such lookups are guaranteed to yield
// undefined without triggering any side-effects.
bool IsPromiseThenLookupChainIntact();
bool IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver);
// On intent to set an element in object, make sure that appropriate
// notifications occur if the set is on the elements of the array or
// object prototype. Also ensure that changes to prototype chain between
@ -1252,8 +1244,6 @@ class Isolate final : private HiddenFactory {
// The `protector_name` C string must be statically allocated.
void TraceProtectorInvalidation(const char* protector_name);
void InvalidateArrayConstructorProtector();
void InvalidateRegExpSpeciesProtector(Handle<NativeContext> native_context);
void InvalidateIsConcatSpreadableProtector();
void InvalidateStringLengthOverflowProtector();
void InvalidateArrayIteratorProtector();
@ -1263,7 +1253,6 @@ class Isolate final : private HiddenFactory {
void InvalidateArrayBufferDetachingProtector();
V8_EXPORT_PRIVATE void InvalidatePromiseHookProtector();
void InvalidatePromiseResolveProtector();
void InvalidatePromiseThenProtector();
// Returns true if array is the initial array prototype in any native context.
bool IsAnyInitialArrayPrototype(Handle<JSArray> array);

View File

@ -21,6 +21,7 @@ class Protectors : public AllStatic {
#define DECLARED_PROTECTORS_ON_ISOLATE(V) \
V(ArraySpeciesLookupChain, ArraySpeciesProtector, array_species_protector) \
V(ArrayConstructor, ArrayConstructorProtector, array_constructor_protector) \
V(PromiseThenLookupChain, PromiseThenProtector, promise_then_protector) \
V(PromiseSpeciesLookupChain, PromiseSpeciesProtector, \
promise_species_protector) \
V(TypedArraySpeciesLookupChain, TypedArraySpeciesProtector, \

View File

@ -419,7 +419,7 @@ void LookupIterator::InternalUpdateProtector() {
isolate_->InvalidatePromiseResolveProtector();
}
} else if (*name_ == roots.then_string()) {
if (!isolate_->IsPromiseThenLookupChainIntact()) return;
if (!Protectors::IsPromiseThenLookupChainIntact(isolate_)) return;
// Setting the "then" property on any JSPromise instance or on the
// initial %PromisePrototype% invalidates the Promise#then protector.
// Also setting the "then" property on the initial %ObjectPrototype%
@ -431,7 +431,7 @@ void LookupIterator::InternalUpdateProtector() {
isolate_->IsInAnyContext(*receiver,
Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ||
isolate_->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) {
isolate_->InvalidatePromiseThenProtector();
Protectors::InvalidatePromiseThenLookupChain(isolate_);
}
}
}

View File

@ -5886,17 +5886,25 @@ MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
// 8. Let then be Get(resolution, "then").
MaybeHandle<Object> then;
if (isolate->IsPromiseThenLookupChainIntact(
Handle<JSReceiver>::cast(resolution))) {
Handle<JSReceiver> receiver(Handle<JSReceiver>::cast(resolution));
// Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the
// initial %PromisePrototype% yields the initial method. In addition this
// protector also guards the negative lookup of "then" on the intrinsic
// %ObjectPrototype%, meaning that such lookups are guaranteed to yield
// undefined without triggering any side-effects.
if (receiver->IsJSPromise() &&
isolate->IsInAnyContext(receiver->map().prototype(),
Context::PROMISE_PROTOTYPE_INDEX) &&
Protectors::IsPromiseThenLookupChainIntact(isolate)) {
// We can skip the "then" lookup on {resolution} if its [[Prototype]]
// is the (initial) Promise.prototype and the Promise#then protector
// is intact, as that guards the lookup path for the "then" property
// on JSPromise instances which have the (initial) %PromisePrototype%.
then = isolate->promise_then();
} else {
then =
JSReceiver::GetProperty(isolate, Handle<JSReceiver>::cast(resolution),
isolate->factory()->then_string());
then = JSReceiver::GetProperty(isolate, receiver,
isolate->factory()->then_string());
}
// 9. If then is an abrupt completion, then