[Turbofan] Serialize prototypes for PromisePrototypeThen

In the JSCallReducer, we need to serialize prototypes of receiver
maps in order to verify that they are the promise prototype.

Bug: v8:7790
Change-Id: Ie9817e531b7faaa3f11dae61a120b46ef5c49847
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1660487
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62191}
This commit is contained in:
Mike Stanton 2019-06-14 15:39:57 +02:00 committed by Commit Bot
parent 802f3e23eb
commit 9b5635ee41
3 changed files with 45 additions and 10 deletions

View File

@ -6022,6 +6022,8 @@ Reduction JSCallReducer::ReducePromisePrototypeThen(Node* node) {
Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
DisallowHeapAccessIf no_heap_acess(FLAG_concurrent_inlining);
MapInference inference(broker(), receiver, effect);
if (!inference.HaveMaps()) return NoChange();
MapHandles const& receiver_maps = inference.GetMaps();
@ -6031,7 +6033,13 @@ Reduction JSCallReducer::ReducePromisePrototypeThen(Node* node) {
for (Handle<Map> map : receiver_maps) {
MapRef receiver_map(broker(), map);
if (!receiver_map.IsJSPromiseMap()) return inference.NoChange();
receiver_map.SerializePrototype();
if (!FLAG_concurrent_inlining) {
receiver_map.SerializePrototype();
} else if (!receiver_map.serialized_prototype()) {
TRACE_BROKER_MISSING(broker(),
"Unserialized prototype for map " << receiver_map);
return inference.NoChange();
}
if (!receiver_map.prototype().equals(
native_context().promise_prototype())) {
return inference.NoChange();
@ -6084,6 +6092,8 @@ Reduction JSCallReducer::ReducePromisePrototypeThen(Node* node) {
// ES section #sec-promise.resolve
Reduction JSCallReducer::ReducePromiseResolveTrampoline(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
DisallowHeapAccessIf no_heap_acess(FLAG_concurrent_inlining);
Node* receiver = NodeProperties::GetValueInput(node, 1);
Node* value = node->op()->ValueInputCount() > 2
? NodeProperties::GetValueInput(node, 2)

View File

@ -758,7 +758,7 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
ProcessApiCall(shared, arguments);
DCHECK(!shared->IsInlineable());
} else if (shared->HasBuiltinId()) {
ProcessBuiltinCall(shared);
ProcessBuiltinCall(shared, arguments);
DCHECK(!shared->IsInlineable());
}
@ -775,7 +775,7 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
ProcessApiCall(shared, arguments);
DCHECK(!shared->IsInlineable());
} else if (shared->HasBuiltinId()) {
ProcessBuiltinCall(shared);
ProcessBuiltinCall(shared, arguments);
DCHECK(!shared->IsInlineable());
}
@ -860,18 +860,42 @@ void SerializerForBackgroundCompilation::ProcessReceiverMapForApiCall(
}
void SerializerForBackgroundCompilation::ProcessBuiltinCall(
Handle<SharedFunctionInfo> target) {
Handle<SharedFunctionInfo> target, const HintsVector& arguments) {
DCHECK(target->HasBuiltinId());
int builtin_id = target->builtin_id();
const int builtin_id = target->builtin_id();
switch (builtin_id) {
case Builtins::kPromiseConstructor:
TRACE_BROKER(broker(), "Found promise constructor");
case Builtins::kPromiseConstructor: {
TRACE_BROKER(broker(), "Serializing data for builtin PromiseConstructor");
broker()->native_context().SerializeScopeInfo();
break;
case Builtins::kPromisePrototypeFinally:
TRACE_BROKER(broker(), "Found promise prototype finally");
}
case Builtins::kPromisePrototypeFinally: {
TRACE_BROKER(broker(),
"Serializing data for builtin PromisePrototypeFinally");
broker()->native_context().SerializeScopeInfo();
break;
}
case Builtins::kPromisePrototypeThen: {
TRACE_BROKER(broker(),
"Serializing data for builtin PromisePrototypeThen");
CHECK_GE(arguments.size(), 1);
Hints const& receiver_hints = arguments[0];
// We need to serialize the prototypes on each receiver map.
for (auto hint : receiver_hints.constants()) {
if (!hint->IsJSPromise()) continue;
Handle<JSReceiver> receiver(Handle<JSReceiver>::cast(hint));
MapRef receiver_mapref(broker(),
handle(receiver->map(), broker()->isolate()));
receiver_mapref.SerializePrototype();
}
for (auto receiver_map : receiver_hints.maps()) {
if (!receiver_map->IsJSPromiseMap()) continue;
MapRef receiver_mapref(broker(), receiver_map);
receiver_mapref.SerializePrototype();
}
break;
}
default:
break;
}

View File

@ -324,7 +324,8 @@ class SerializerForBackgroundCompilation {
const HintsVector& arguments);
void ProcessReceiverMapForApiCall(FunctionTemplateInfoRef& target,
Handle<Map> receiver);
void ProcessBuiltinCall(Handle<SharedFunctionInfo> target);
void ProcessBuiltinCall(Handle<SharedFunctionInfo> target,
const HintsVector& arguments);
void ProcessJump(interpreter::BytecodeArrayIterator* iterator);