Commit b7b42293 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Further reduce dependence on HeapCopyReducer

- Add serialization for CallNoFeedback, which was missing.
- Extend serialization for CallJSRuntime.
- Serialize for calls to higher-order Array builtins.
- Serialize for calls to Function#apply and Function#call.
- Serialize for calls to Reflect.apply and Reflect.construct.
- Serialize for calls to Promise constructor.
- Fix ConvertReceiverMode in serialization for CallProperty.

Bug: v8:7790
Change-Id: I4bba6f45f9b7948ed2ba9c70bd423a23ec29ecf7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1763530Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63497}
parent 6498f8bb
...@@ -2332,6 +2332,7 @@ void JSHeapBroker::InitializeRefsMap() { ...@@ -2332,6 +2332,7 @@ void JSHeapBroker::InitializeRefsMap() {
DCHECK_EQ(current_zone_, broker_zone_); DCHECK_EQ(current_zone_, broker_zone_);
current_zone_ = compiler_cache_->zone(); current_zone_ = compiler_cache_->zone();
// Serialize various builtins.
Builtins* const b = isolate()->builtins(); Builtins* const b = isolate()->builtins();
{ {
Builtins::Name builtins[] = { Builtins::Name builtins[] = {
...@@ -2345,6 +2346,7 @@ void JSHeapBroker::InitializeRefsMap() { ...@@ -2345,6 +2346,7 @@ void JSHeapBroker::InitializeRefsMap() {
Builtins::kCallFunction_ReceiverIsAny, Builtins::kCallFunction_ReceiverIsAny,
Builtins::kCallFunction_ReceiverIsNotNullOrUndefined, Builtins::kCallFunction_ReceiverIsNotNullOrUndefined,
Builtins::kCallFunction_ReceiverIsNullOrUndefined, Builtins::kCallFunction_ReceiverIsNullOrUndefined,
Builtins::kCompileLazy,
Builtins::kConstructFunctionForwardVarargs, Builtins::kConstructFunctionForwardVarargs,
Builtins::kForInFilter, Builtins::kForInFilter,
Builtins::kJSBuiltinsConstructStub, Builtins::kJSBuiltinsConstructStub,
...@@ -2445,9 +2447,10 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2445,9 +2447,10 @@ void JSHeapBroker::InitializeAndStartSerializing(
CollectArrayAndObjectPrototypes(); CollectArrayAndObjectPrototypes();
SerializeTypedArrayStringTags(); SerializeTypedArrayStringTags();
// Serialize standard objects.
//
// - Maps, strings, oddballs
Factory* const f = isolate()->factory(); Factory* const f = isolate()->factory();
// Maps, strings, oddballs
GetOrCreateData(f->arguments_marker_map()); GetOrCreateData(f->arguments_marker_map());
GetOrCreateData(f->bigint_string()); GetOrCreateData(f->bigint_string());
GetOrCreateData(f->block_context_map()); GetOrCreateData(f->block_context_map());
...@@ -2495,8 +2498,7 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2495,8 +2498,7 @@ void JSHeapBroker::InitializeAndStartSerializing(
GetOrCreateData(f->uninitialized_map()); GetOrCreateData(f->uninitialized_map());
GetOrCreateData(f->with_context_map()); GetOrCreateData(f->with_context_map());
GetOrCreateData(f->zero_string()); GetOrCreateData(f->zero_string());
// - Cells
// Protector cells
GetOrCreateData(f->array_buffer_detaching_protector()) GetOrCreateData(f->array_buffer_detaching_protector())
->AsPropertyCell() ->AsPropertyCell()
->Serialize(this); ->Serialize(this);
...@@ -2507,6 +2509,7 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2507,6 +2509,7 @@ void JSHeapBroker::InitializeAndStartSerializing(
GetOrCreateData(f->array_species_protector()) GetOrCreateData(f->array_species_protector())
->AsPropertyCell() ->AsPropertyCell()
->Serialize(this); ->Serialize(this);
GetOrCreateData(f->many_closures_cell())->AsFeedbackCell();
GetOrCreateData(f->no_elements_protector()) GetOrCreateData(f->no_elements_protector())
->AsPropertyCell() ->AsPropertyCell()
->Serialize(this); ->Serialize(this);
...@@ -2520,8 +2523,7 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2520,8 +2523,7 @@ void JSHeapBroker::InitializeAndStartSerializing(
->AsPropertyCell() ->AsPropertyCell()
->Serialize(this); ->Serialize(this);
GetOrCreateData(f->string_length_protector())->AsCell()->Serialize(this); GetOrCreateData(f->string_length_protector())->AsCell()->Serialize(this);
// - CEntry stub
// CEntry stub
GetOrCreateData( GetOrCreateData(
CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, true)); CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, true));
...@@ -4270,8 +4272,7 @@ bool JSHeapBroker::FeedbackIsInsufficient(FeedbackSource const& source) const { ...@@ -4270,8 +4272,7 @@ bool JSHeapBroker::FeedbackIsInsufficient(FeedbackSource const& source) const {
} }
namespace { namespace {
template <class MapContainer> MapHandles GetRelevantReceiverMaps(Isolate* isolate, MapHandles const& maps) {
MapHandles GetRelevantReceiverMaps(Isolate* isolate, MapContainer const& maps) {
MapHandles result; MapHandles result;
for (Handle<Map> map : maps) { for (Handle<Map> map : maps) {
if (Map::TryUpdate(isolate, map).ToHandle(&map) && if (Map::TryUpdate(isolate, map).ToHandle(&map) &&
...@@ -4281,7 +4282,7 @@ MapHandles GetRelevantReceiverMaps(Isolate* isolate, MapContainer const& maps) { ...@@ -4281,7 +4282,7 @@ MapHandles GetRelevantReceiverMaps(Isolate* isolate, MapContainer const& maps) {
} }
} }
return result; return result;
} } // namespace
} // namespace } // namespace
ProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess( ProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess(
......
...@@ -28,8 +28,8 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) { ...@@ -28,8 +28,8 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kHeapConstant: { case IrOpcode::kHeapConstant: {
ObjectRef object(broker(), HeapConstantOf(node->op())); ObjectRef object(broker(), HeapConstantOf(node->op()));
if (object.IsJSFunction()) object.AsJSFunction().Serialize();
if (!FLAG_concurrent_inlining) { if (!FLAG_concurrent_inlining) {
if (object.IsJSFunction()) object.AsJSFunction().Serialize();
if (object.IsJSObject()) { if (object.IsJSObject()) {
object.AsJSObject().SerializeObjectCreateMap(); object.AsJSObject().SerializeObjectCreateMap();
} }
...@@ -77,10 +77,13 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) { ...@@ -77,10 +77,13 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
break; break;
} }
case IrOpcode::kJSCreateClosure: { case IrOpcode::kJSCreateClosure: {
CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); if (!FLAG_concurrent_inlining) {
SharedFunctionInfoRef(broker(), p.shared_info()); CreateClosureParameters const& p =
FeedbackCellRef(broker(), p.feedback_cell()); CreateClosureParametersOf(node->op());
HeapObjectRef(broker(), p.code()); SharedFunctionInfoRef(broker(), p.shared_info());
FeedbackCellRef(broker(), p.feedback_cell());
HeapObjectRef(broker(), p.code());
}
break; break;
} }
case IrOpcode::kJSCreateEmptyLiteralArray: { case IrOpcode::kJSCreateEmptyLiteralArray: {
......
...@@ -1554,21 +1554,21 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) { ...@@ -1554,21 +1554,21 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
if (target_type.IsHeapConstant() && if (target_type.IsHeapConstant() &&
target_type.AsHeapConstant()->Ref().IsJSFunction()) { target_type.AsHeapConstant()->Ref().IsJSFunction()) {
JSFunctionRef function = target_type.AsHeapConstant()->Ref().AsJSFunction(); JSFunctionRef function = target_type.AsHeapConstant()->Ref().AsJSFunction();
SharedFunctionInfoRef shared = function.shared();
// Only optimize [[Construct]] here if {function} is a Constructor. // Only optimize [[Construct]] here if {function} is a Constructor.
if (!function.map().is_constructor()) return NoChange(); if (!function.map().is_constructor()) return NoChange();
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; if (!function.serialized()) {
TRACE_BROKER_MISSING(broker(), "data for function " << function);
return NoChange();
}
// Patch {node} to an indirect call via the {function}s construct stub. // Patch {node} to an indirect call via the {function}s construct stub.
bool use_builtin_construct_stub = shared.construct_as_builtin(); bool use_builtin_construct_stub = function.shared().construct_as_builtin();
CodeRef code(broker(), CodeRef code(broker(),
use_builtin_construct_stub use_builtin_construct_stub
? BUILTIN_CODE(isolate(), JSBuiltinsConstructStub) ? BUILTIN_CODE(isolate(), JSBuiltinsConstructStub)
: BUILTIN_CODE(isolate(), JSConstructStubGeneric)); : BUILTIN_CODE(isolate(), JSConstructStubGeneric));
node->RemoveInput(arity + 1); node->RemoveInput(arity + 1);
node->InsertInput(graph()->zone(), 0, jsgraph()->Constant(code)); node->InsertInput(graph()->zone(), 0, jsgraph()->Constant(code));
node->InsertInput(graph()->zone(), 2, new_target); node->InsertInput(graph()->zone(), 2, new_target);
...@@ -1576,10 +1576,9 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) { ...@@ -1576,10 +1576,9 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant()); node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, node, common()->Call(Linkage::GetStubCallDescriptor(
common()->Call(Linkage::GetStubCallDescriptor( graph()->zone(), ConstructStubDescriptor{}, 1 + arity,
graph()->zone(), ConstructStubDescriptor{}, 1 + arity, flags))); CallDescriptor::kNeedsFrameState)));
return Changed(node); return Changed(node);
} }
...@@ -1637,12 +1636,15 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { ...@@ -1637,12 +1636,15 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
if (target_type.IsHeapConstant() && if (target_type.IsHeapConstant() &&
target_type.AsHeapConstant()->Ref().IsJSFunction()) { target_type.AsHeapConstant()->Ref().IsJSFunction()) {
JSFunctionRef function = target_type.AsHeapConstant()->Ref().AsJSFunction(); JSFunctionRef function = target_type.AsHeapConstant()->Ref().AsJSFunction();
SharedFunctionInfoRef shared = function.shared();
if (shared.HasBreakInfo()) { if (!function.serialized()) {
// Do not inline the call if we need to check whether to break at entry. TRACE_BROKER_MISSING(broker(), "data for function " << function);
return NoChange(); return NoChange();
} }
SharedFunctionInfoRef shared = function.shared();
// Do not inline the call if we need to check whether to break at entry.
if (shared.HasBreakInfo()) return NoChange();
// Class constructors are callable, but [[Call]] will raise an exception. // Class constructors are callable, but [[Call]] will raise an exception.
// See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
......
...@@ -91,7 +91,6 @@ namespace compiler { ...@@ -91,7 +91,6 @@ namespace compiler {
V(JumpIfUndefinedOrNullConstant) V(JumpIfUndefinedOrNullConstant)
#define IGNORED_BYTECODE_LIST(V) \ #define IGNORED_BYTECODE_LIST(V) \
V(CallNoFeedback) \
V(IncBlockCounter) \ V(IncBlockCounter) \
V(StackCheck) \ V(StackCheck) \
V(ThrowSuperAlreadyCalledIfNotHole) \ V(ThrowSuperAlreadyCalledIfNotHole) \
...@@ -145,6 +144,7 @@ namespace compiler { ...@@ -145,6 +144,7 @@ namespace compiler {
#define SUPPORTED_BYTECODE_LIST(V) \ #define SUPPORTED_BYTECODE_LIST(V) \
V(CallAnyReceiver) \ V(CallAnyReceiver) \
V(CallJSRuntime) \ V(CallJSRuntime) \
V(CallNoFeedback) \
V(CallProperty) \ V(CallProperty) \
V(CallProperty0) \ V(CallProperty0) \
V(CallProperty1) \ V(CallProperty1) \
...@@ -377,8 +377,9 @@ class SerializerForBackgroundCompilation { ...@@ -377,8 +377,9 @@ class SerializerForBackgroundCompilation {
void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target, void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target,
const HintsVector& arguments, FeedbackSlot slot, const HintsVector& arguments, FeedbackSlot slot,
bool with_spread = false); bool with_spread = false);
void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator, void ProcessCallVarArgs(ConvertReceiverMode receiver_mode,
ConvertReceiverMode receiver_mode, Hints const& callee, interpreter::Register first_reg,
int reg_count, FeedbackSlot slot,
bool with_spread = false); bool with_spread = false);
void ProcessApiCall(Handle<SharedFunctionInfo> target, void ProcessApiCall(Handle<SharedFunctionInfo> target,
const HintsVector& arguments); const HintsVector& arguments);
...@@ -1447,7 +1448,13 @@ void SerializerForBackgroundCompilation::VisitCreateClosure( ...@@ -1447,7 +1448,13 @@ void SerializerForBackgroundCompilation::VisitCreateClosure(
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined); const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
FeedbackSlot slot = iterator->GetSlotOperand(3);
ProcessCallVarArgs(ConvertReceiverMode::kNullOrUndefined, callee, first_reg,
reg_count, slot);
} }
void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0( void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0(
...@@ -1494,12 +1501,34 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2( ...@@ -1494,12 +1501,34 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2(
void SerializerForBackgroundCompilation::VisitCallAnyReceiver( void SerializerForBackgroundCompilation::VisitCallAnyReceiver(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny); const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
FeedbackSlot slot = iterator->GetSlotOperand(3);
ProcessCallVarArgs(ConvertReceiverMode::kAny, callee, first_reg, reg_count,
slot);
}
void SerializerForBackgroundCompilation::VisitCallNoFeedback(
BytecodeArrayIterator* iterator) {
const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
ProcessCallVarArgs(ConvertReceiverMode::kAny, callee, first_reg, reg_count,
FeedbackSlot::Invalid());
} }
void SerializerForBackgroundCompilation::VisitCallProperty( void SerializerForBackgroundCompilation::VisitCallProperty(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
ProcessCallVarArgs(iterator, ConvertReceiverMode::kNullOrUndefined); const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
FeedbackSlot slot = iterator->GetSlotOperand(3);
ProcessCallVarArgs(ConvertReceiverMode::kNotNullOrUndefined, callee,
first_reg, reg_count, slot);
} }
void SerializerForBackgroundCompilation::VisitCallProperty0( void SerializerForBackgroundCompilation::VisitCallProperty0(
...@@ -1546,17 +1575,28 @@ void SerializerForBackgroundCompilation::VisitCallProperty2( ...@@ -1546,17 +1575,28 @@ void SerializerForBackgroundCompilation::VisitCallProperty2(
void SerializerForBackgroundCompilation::VisitCallWithSpread( void SerializerForBackgroundCompilation::VisitCallWithSpread(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
ProcessCallVarArgs(iterator, ConvertReceiverMode::kAny, true); const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
FeedbackSlot slot = iterator->GetSlotOperand(3);
ProcessCallVarArgs(ConvertReceiverMode::kAny, callee, first_reg, reg_count,
slot, true);
} }
void SerializerForBackgroundCompilation::VisitCallJSRuntime( void SerializerForBackgroundCompilation::VisitCallJSRuntime(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
// BytecodeGraphBuilder::VisitCallJSRuntime needs the {runtime_index}
// slot in the native context to be serialized.
const int runtime_index = iterator->GetNativeContextIndexOperand(0); const int runtime_index = iterator->GetNativeContextIndexOperand(0);
broker()->target_native_context().get( ObjectRef constant =
runtime_index, SerializationPolicy::kSerializeIfNeeded); broker()
environment()->accumulator_hints().Clear(); ->target_native_context()
.get(runtime_index, SerializationPolicy::kSerializeIfNeeded)
.value();
Hints callee = Hints::SingleConstant(constant.object(), zone());
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
ProcessCallVarArgs(ConvertReceiverMode::kNullOrUndefined, callee, first_reg,
reg_count, FeedbackSlot::Invalid());
} }
Hints SerializerForBackgroundCompilation::RunChildSerializer( Hints SerializerForBackgroundCompilation::RunChildSerializer(
...@@ -1650,25 +1690,28 @@ MaybeHandle<JSFunction> UnrollBoundFunction( ...@@ -1650,25 +1690,28 @@ MaybeHandle<JSFunction> UnrollBoundFunction(
void SerializerForBackgroundCompilation::ProcessCallOrConstruct( void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
Hints callee, base::Optional<Hints> new_target, Hints callee, base::Optional<Hints> new_target,
const HintsVector& arguments, FeedbackSlot slot, bool with_spread) { const HintsVector& arguments, FeedbackSlot slot, bool with_spread) {
FeedbackSource source(feedback_vector(), slot);
ProcessedFeedback const& feedback = broker()->ProcessFeedbackForCall(source);
if (BailoutOnUninitialized(feedback)) return;
// Incorporate feedback into hints copy to simplify processing.
SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation; SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation;
if (!feedback.IsInsufficient()) { if (!slot.IsInvalid()) {
speculation_mode = feedback.AsCall().speculation_mode(); FeedbackSource source(feedback_vector(), slot);
base::Optional<HeapObjectRef> target = feedback.AsCall().target(); ProcessedFeedback const& feedback =
if (target.has_value() && target->map().is_callable()) { broker()->ProcessFeedbackForCall(source);
// TODO(mvstanton): if the map isn't callable then we have an allocation if (BailoutOnUninitialized(feedback)) return;
// site, and it may make sense to add the Array JSFunction constant.
if (new_target.has_value()) { // Incorporate feedback into hints copy to simplify processing.
// Construct; feedback is new_target, which often is also the callee. if (!feedback.IsInsufficient()) {
new_target->AddConstant(target->object()); speculation_mode = feedback.AsCall().speculation_mode();
callee.AddConstant(target->object()); base::Optional<HeapObjectRef> target = feedback.AsCall().target();
} else { if (target.has_value() && target->map().is_callable()) {
// Call; target is callee. // TODO(mvstanton): if the map isn't callable then we have an allocation
callee.AddConstant(target->object()); // site, and it may make sense to add the Array JSFunction constant.
if (new_target.has_value()) {
// Construct; feedback is new_target, which often is also the callee.
new_target->AddConstant(target->object());
callee.AddConstant(target->object());
} else {
// Call; target is callee.
callee.AddConstant(target->object());
}
} }
} }
} }
...@@ -1717,14 +1760,9 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct( ...@@ -1717,14 +1760,9 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
} }
void SerializerForBackgroundCompilation::ProcessCallVarArgs( void SerializerForBackgroundCompilation::ProcessCallVarArgs(
BytecodeArrayIterator* iterator, ConvertReceiverMode receiver_mode, ConvertReceiverMode receiver_mode, Hints const& callee,
interpreter::Register first_reg, int reg_count, FeedbackSlot slot,
bool with_spread) { bool with_spread) {
const Hints& callee =
environment()->register_hints(iterator->GetRegisterOperand(0));
interpreter::Register first_reg = iterator->GetRegisterOperand(1);
int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2));
FeedbackSlot slot = iterator->GetSlotOperand(3);
HintsVector arguments(zone()); HintsVector arguments(zone());
// The receiver is either given in the first register or it is implicitly // The receiver is either given in the first register or it is implicitly
// the {undefined} value. // the {undefined} value.
...@@ -1860,11 +1898,41 @@ void SerializerForBackgroundCompilation::ProcessBuiltinCall( ...@@ -1860,11 +1898,41 @@ void SerializerForBackgroundCompilation::ProcessBuiltinCall(
ProcessHintsForRegExpTest(regexp_hints); ProcessHintsForRegExpTest(regexp_hints);
} }
break; break;
case Builtins::kFunctionPrototypeCall: case Builtins::kArrayEvery:
if (arguments.size() >= 1 && case Builtins::kArrayFilter:
case Builtins::kArrayForEach:
case Builtins::kArrayPrototypeFind:
case Builtins::kArrayPrototypeFindIndex:
case Builtins::kArrayMap:
case Builtins::kArrayReduce:
case Builtins::kArrayReduceRight:
case Builtins::kArraySome:
if (arguments.size() >= 2 &&
speculation_mode != SpeculationMode::kDisallowSpeculation) { speculation_mode != SpeculationMode::kDisallowSpeculation) {
Hints const& target_hints = arguments[0]; Hints const& callback_hints = arguments[1];
ProcessHintsForFunctionCall(target_hints); ProcessHintsForFunctionCall(callback_hints);
}
break;
case Builtins::kFunctionPrototypeApply:
case Builtins::kFunctionPrototypeCall:
case Builtins::kPromiseConstructor:
// TODO(mslekova): Since the reducer for all these introduce a
// JSCall/JSConstruct that will again get optimized by the JSCallReducer,
// we basically might have to do all the serialization that we do for that
// here as well. The only difference is that the new JSCall/JSConstruct
// has speculation disabled, causing the JSCallReducer to do much less
// work. To account for that, ProcessCallOrConstruct should have a way of
// taking the speculation mode as an argument rather than getting that
// from the feedback. (Also applies to Reflect.apply and
// Reflect.construct.)
if (arguments.size() >= 1) {
ProcessHintsForFunctionCall(arguments[0]);
}
break;
case Builtins::kReflectApply:
case Builtins::kReflectConstruct:
if (arguments.size() >= 2) {
ProcessHintsForFunctionCall(arguments[1]);
} }
break; break;
case Builtins::kObjectPrototypeIsPrototypeOf: case Builtins::kObjectPrototypeIsPrototypeOf:
...@@ -2018,9 +2086,7 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest( ...@@ -2018,9 +2086,7 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest(
void SerializerForBackgroundCompilation::ProcessHintsForFunctionCall( void SerializerForBackgroundCompilation::ProcessHintsForFunctionCall(
Hints const& target_hints) { Hints const& target_hints) {
for (auto constant : target_hints.constants()) { for (auto constant : target_hints.constants()) {
if (!constant->IsJSFunction()) continue; if (constant->IsJSFunction()) JSFunctionRef(broker(), constant).Serialize();
JSFunctionRef func(broker(), constant);
func.Serialize();
} }
} }
...@@ -2573,6 +2639,8 @@ void SerializerForBackgroundCompilation::VisitLdaNamedProperty( ...@@ -2573,6 +2639,8 @@ void SerializerForBackgroundCompilation::VisitLdaNamedProperty(
ProcessNamedPropertyAccess(receiver, name, slot, AccessMode::kLoad); ProcessNamedPropertyAccess(receiver, name, slot, AccessMode::kLoad);
} }
// TODO(neis): Do feedback-independent serialization also for *NoFeedback
// bytecodes.
void SerializerForBackgroundCompilation::VisitLdaNamedPropertyNoFeedback( void SerializerForBackgroundCompilation::VisitLdaNamedPropertyNoFeedback(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
NameRef(broker(), NameRef(broker(),
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "src/codegen/tick-counter.h" #include "src/codegen/tick-counter.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
#include "src/compiler/js-heap-broker.h"
#include "src/compiler/js-operator.h" #include "src/compiler/js-operator.h"
#include "src/compiler/linkage.h" #include "src/compiler/linkage.h"
#include "src/compiler/loop-variable-optimizer.h" #include "src/compiler/loop-variable-optimizer.h"
...@@ -1526,6 +1527,10 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { ...@@ -1526,6 +1527,10 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
return Type::NonInternal(); return Type::NonInternal();
} }
JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction(); JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
if (!function.serialized()) {
TRACE_BROKER_MISSING(t->broker(), "data for function " << function);
return Type::NonInternal();
}
if (!function.shared().HasBuiltinId()) { if (!function.shared().HasBuiltinId()) {
return Type::NonInternal(); return Type::NonInternal();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment