Commit 63db7615 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Prepare broker and serializer for CreateClosure support

When inlining based on CreateClosure, we don't have a JSFunction but
only the SharedFunctionInfo and FeedbackVector.

Bug: v8:7790
Change-Id: I7a3cf50710273c7175e43e969d2364cff11c3d93
Reviewed-on: https://chromium-review.googlesource.com/c/1421357Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58977}
parent effb7ad7
......@@ -318,14 +318,6 @@ class JSFunctionData : public JSObjectData {
void Serialize(JSHeapBroker* broker);
void SetSerializedForCompilation(JSHeapBroker* broker) {
CHECK(!serialized_for_compilation_);
serialized_for_compilation_ = true;
}
bool serialized_for_compilation() const {
return serialized_for_compilation_;
}
ContextData* context() const { return context_; }
NativeContextData* native_context() const { return native_context_; }
MapData* initial_map() const { return initial_map_; }
......@@ -342,7 +334,6 @@ class JSFunctionData : public JSObjectData {
bool PrototypeRequiresRuntimeLookup_;
bool serialized_ = false;
bool serialized_for_compilation_ = false;
ContextData* context_ = nullptr;
NativeContextData* native_context_ = nullptr;
......@@ -1142,39 +1133,60 @@ ScopeInfoData::ScopeInfoData(JSHeapBroker* broker, ObjectData** storage,
class SharedFunctionInfoData : public HeapObjectData {
public:
SharedFunctionInfoData(JSHeapBroker* broker, ObjectData** storage,
Handle<SharedFunctionInfo> object);
int builtin_id() const { return builtin_id_; }
BytecodeArrayData* GetBytecodeArray() const { return GetBytecodeArray_; }
void SetSerializedForCompilation(FeedbackVectorRef feedback);
bool IsSerializedForCompilation(FeedbackVectorRef feedback) const;
#define DECL_ACCESSOR(type, name) \
type name() const { return name##_; }
BROKER_SFI_FIELDS(DECL_ACCESSOR)
#undef DECL_ACCESSOR
SharedFunctionInfoData(JSHeapBroker* broker, ObjectData** storage,
Handle<SharedFunctionInfo> object)
: HeapObjectData(broker, storage, object),
builtin_id_(object->HasBuiltinId() ? object->builtin_id()
: Builtins::kNoBuiltinId),
GetBytecodeArray_(
object->HasBytecodeArray()
? broker->GetOrCreateData(object->GetBytecodeArray())
->AsBytecodeArray()
: nullptr)
#define INIT_MEMBER(type, name) , name##_(object->name())
BROKER_SFI_FIELDS(INIT_MEMBER)
#undef INIT_MEMBER
{
DCHECK_EQ(HasBuiltinId_, builtin_id_ != Builtins::kNoBuiltinId);
DCHECK_EQ(HasBytecodeArray_, GetBytecodeArray_ != nullptr);
}
private:
int const builtin_id_;
BytecodeArrayData* const GetBytecodeArray_;
ZoneUnorderedSet<Handle<FeedbackVector>, Handle<FeedbackVector>::hash,
Handle<FeedbackVector>::equal_to>
serialized_for_compilation_;
#define DECL_MEMBER(type, name) type const name##_;
BROKER_SFI_FIELDS(DECL_MEMBER)
#undef DECL_MEMBER
};
SharedFunctionInfoData::SharedFunctionInfoData(
JSHeapBroker* broker, ObjectData** storage,
Handle<SharedFunctionInfo> object)
: HeapObjectData(broker, storage, object),
builtin_id_(object->HasBuiltinId() ? object->builtin_id()
: Builtins::kNoBuiltinId),
GetBytecodeArray_(
object->HasBytecodeArray()
? broker->GetOrCreateData(object->GetBytecodeArray())
->AsBytecodeArray()
: nullptr),
serialized_for_compilation_(broker->zone())
#define INIT_MEMBER(type, name) , name##_(object->name())
BROKER_SFI_FIELDS(INIT_MEMBER)
#undef INIT_MEMBER
{
DCHECK_EQ(HasBuiltinId_, builtin_id_ != Builtins::kNoBuiltinId);
DCHECK_EQ(HasBytecodeArray_, GetBytecodeArray_ != nullptr);
}
void SharedFunctionInfoData::SetSerializedForCompilation(
FeedbackVectorRef feedback) {
CHECK(serialized_for_compilation_.insert(feedback.object()).second);
}
bool SharedFunctionInfoData::IsSerializedForCompilation(
FeedbackVectorRef feedback) const {
return serialized_for_compilation_.find(feedback.object()) !=
serialized_for_compilation_.end();
}
class ModuleData : public HeapObjectData {
public:
ModuleData(JSHeapBroker* broker, ObjectData** storage, Handle<Module> object);
......@@ -2663,14 +2675,16 @@ void JSFunctionRef::Serialize() {
data()->AsJSFunction()->Serialize(broker());
}
void JSFunctionRef::SetSerializedForCompilation() {
void SharedFunctionInfoRef::SetSerializedForCompilation(
FeedbackVectorRef feedback) {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSFunction()->SetSerializedForCompilation(broker());
data()->AsSharedFunctionInfo()->SetSerializedForCompilation(feedback);
}
bool JSFunctionRef::serialized_for_compilation() const {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
return data()->AsJSFunction()->serialized_for_compilation();
bool SharedFunctionInfoRef::IsSerializedForCompilation(
FeedbackVectorRef feedback) const {
CHECK_NE(broker()->mode(), JSHeapBroker::kDisabled);
return data()->AsSharedFunctionInfo()->IsSerializedForCompilation(feedback);
}
void JSObjectRef::SerializeObjectCreateMap() {
......
......@@ -235,9 +235,6 @@ class JSFunctionRef : public JSObjectRef {
bool PrototypeRequiresRuntimeLookup() const;
void Serialize();
void SetSerializedForCompilation();
bool serialized_for_compilation() const;
// The following are available only after calling Serialize().
ObjectRef prototype() const;
......@@ -536,6 +533,9 @@ class SharedFunctionInfoRef : public HeapObjectRef {
#define DECL_ACCESSOR(type, name) type name() const;
BROKER_SFI_FIELDS(DECL_ACCESSOR)
#undef DECL_ACCESSOR
bool IsSerializedForCompilation(FeedbackVectorRef feedback) const;
void SetSerializedForCompilation(FeedbackVectorRef feedback);
};
class StringRef : public NameRef {
......
......@@ -304,12 +304,6 @@ bool JSInliner::DetermineCallTarget(
return false;
}
JSFunctionRef ref(broker(), function);
if (FLAG_concurrent_inlining && !ref.serialized_for_compilation()) {
TRACE_BROKER(broker(), "Missed opportunity to inline a function ("
<< Brief(*match.Value()) << ")");
}
shared_info_out = handle(function->shared(), isolate());
return true;
}
......@@ -480,6 +474,17 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
Handle<FeedbackVector> feedback_vector;
DetermineCallContext(node, context, feedback_vector);
if (FLAG_concurrent_inlining) {
SharedFunctionInfoRef sfi(broker(), shared_info);
FeedbackVectorRef feedback(broker(), feedback_vector);
if (!sfi.IsSerializedForCompilation(feedback)) {
TRACE_BROKER(broker(),
"Would have missed opportunity to inline a function ("
<< Brief(*sfi.object()) << " with "
<< Brief(*feedback.object()) << ")");
}
}
// Remember that we inlined this function.
int inlining_id = info_->AddInlinedFunction(
shared_info, bytecode_array, source_positions_->GetSourcePosition(node));
......
......@@ -182,52 +182,45 @@ void SerializerForBackgroundCompilation::Environment::SetRegisterHints(
}
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
JSHeapBroker* broker, Zone* zone, Handle<JSFunction> closure)
JSHeapBroker* broker, Zone* zone, Handle<JSFunction> function)
: broker_(broker),
zone_(zone),
sfi_(function->shared(), broker->isolate()),
feedback_(function->feedback_vector(), broker->isolate()),
environment_(new (zone) Environment(
zone, broker_->isolate(),
closure->shared()->GetBytecodeArray()->register_count(),
closure->shared()->GetBytecodeArray()->parameter_count())),
closure_(closure) {}
zone, broker_->isolate(), sfi_->GetBytecodeArray()->register_count(),
sfi_->GetBytecodeArray()->parameter_count())) {
JSFunctionRef(broker, function).Serialize();
}
SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
JSHeapBroker* broker, Zone* zone, Handle<JSFunction> closure,
const Hints& receiver, const HintsVector& arguments)
JSHeapBroker* broker, Zone* zone, Handle<SharedFunctionInfo> sfi,
Handle<FeedbackVector> feedback, const Hints& receiver,
const HintsVector& arguments)
: broker_(broker),
zone_(zone),
sfi_(sfi),
feedback_(feedback),
environment_(new (zone) Environment(
this, broker->isolate(),
closure->shared()->GetBytecodeArray()->register_count(),
closure->shared()->GetBytecodeArray()->parameter_count(), receiver,
arguments)),
closure_(closure) {}
this, broker->isolate(), sfi->GetBytecodeArray()->register_count(),
sfi->GetBytecodeArray()->parameter_count(), receiver, arguments)) {}
Hints SerializerForBackgroundCompilation::Run() {
JSFunctionRef closure_ref(broker(), closure_);
if (closure_ref.serialized_for_compilation()) {
SharedFunctionInfoRef sfi(broker(), sfi_);
FeedbackVectorRef feedback(broker(), feedback_);
if (sfi.IsSerializedForCompilation(feedback)) {
return Hints(zone());
}
closure_ref.SetSerializedForCompilation();
FeedbackVectorRef fv(
broker(), handle(closure_->feedback_vector(), broker()->isolate()));
fv.SerializeSlots();
BytecodeArrayRef bytecode_array(
broker(),
handle(closure_->shared()->GetBytecodeArray(), broker()->isolate()));
closure_ref.Serialize();
sfi.SetSerializedForCompilation(feedback);
feedback.SerializeSlots();
TraverseBytecode();
return environment()->LookupReturnValue();
}
void SerializerForBackgroundCompilation::TraverseBytecode() {
interpreter::BytecodeArrayIterator iterator(
handle(closure_->shared()->GetBytecodeArray(), broker()->isolate()));
BytecodeArrayRef bytecode_array(
broker(), handle(sfi_->GetBytecodeArray(), broker()->isolate()));
interpreter::BytecodeArrayIterator iterator(bytecode_array.object());
for (; !iterator.done(); iterator.Advance()) {
switch (iterator.current_bytecode()) {
......@@ -431,17 +424,19 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
const Hints& callee, const Hints& receiver, const HintsVector& arguments) {
environment()->ClearAccumulatorHints();
for (auto value : callee) {
if (!value->IsJSFunction()) continue;
for (auto hint : callee) {
if (!hint->IsJSFunction()) continue;
Handle<JSFunction> callee(Handle<JSFunction>::cast(value));
if (!callee->shared()->HasBytecodeArray() ||
!callee->shared()->IsInlineable())
continue;
Handle<JSFunction> function = Handle<JSFunction>::cast(hint);
if (!function->shared()->IsInlineable()) continue;
SerializerForBackgroundCompilation child_serializer(
broker(), zone(), callee, receiver, arguments);
JSFunctionRef(broker(), function).Serialize();
Handle<SharedFunctionInfo> sfi(function->shared(), broker()->isolate());
Handle<FeedbackVector> feedback(function->feedback_vector(),
broker()->isolate());
SerializerForBackgroundCompilation child_serializer(
broker(), zone(), sfi, feedback, receiver, arguments);
environment()->AddAccumulatorHints(child_serializer.Run());
}
}
......
......@@ -116,20 +116,17 @@ typedef ZoneVector<Hints> HintsVector;
// optimizations in the compiler, is copied to the heap broker.
class SerializerForBackgroundCompilation {
public:
class Environment;
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
Handle<JSFunction> closure);
Handle<JSFunction> function);
Hints Run();
private:
SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
Handle<JSFunction> closure,
Handle<SharedFunctionInfo> sfi,
Handle<FeedbackVector> feedback,
const Hints& receiver,
const HintsVector& arguments);
Hints Run();
Zone* zone() const { return zone_; }
private:
void TraverseBytecode();
#define DECLARE_VISIT_BYTECODE(name, ...) \
......@@ -137,6 +134,9 @@ class SerializerForBackgroundCompilation {
SUPPORTED_BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
#undef DECLARE_VISIT_BYTECODE
class Environment;
Zone* zone() const { return zone_; }
JSHeapBroker* broker() const { return broker_; }
Environment* environment() const { return environment_; }
......@@ -147,9 +147,9 @@ class SerializerForBackgroundCompilation {
JSHeapBroker* broker_;
Zone* zone_;
Handle<SharedFunctionInfo> sfi_;
Handle<FeedbackVector> feedback_;
Environment* environment_;
Handle<JSFunction> closure_;
};
} // namespace compiler
......
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