Commit a75b129a authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[TurboFan] Only serialize JSFunction feedback and code if needed.

The feedback_vector/cell and code fields of a JSFunctionRef are only
used when generating code for the function (e.g., for the function
being optimized or inlined functions). This CL explicitly serializes
these fields only when the function will be used for codegen, otherwise
avoiding their serialization.

BUG=v8:7790,v8:9684

Change-Id: If76bc0b77e51aa10517699e0a9198358fe77f009
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2617083Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72129}
parent d7f767e1
......@@ -355,10 +355,15 @@ class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef {
ContextRef context() const;
NativeContextRef native_context() const;
SharedFunctionInfoRef shared() const;
int InitialMapInstanceSizeWithMinSlack() const;
void SerializeCodeAndFeedback();
bool serialized_code_and_feedback() const;
// The following are available only after calling SerializeCodeAndFeedback().
FeedbackVectorRef feedback_vector() const;
FeedbackCellRef raw_feedback_cell() const;
CodeRef code() const;
int InitialMapInstanceSizeWithMinSlack() const;
};
class JSRegExpRef : public JSObjectRef {
......
......@@ -607,14 +607,28 @@ class JSFunctionData : public JSObjectData {
void Serialize(JSHeapBroker* broker);
bool serialized() const { return serialized_; }
void SerializeCodeAndFeedback(JSHeapBroker* broker);
bool serialized_code_and_feedback() const {
return serialized_code_and_feedback_;
}
ObjectData* context() const { return context_; }
ObjectData* native_context() const { return native_context_; }
ObjectData* initial_map() const { return initial_map_; }
ObjectData* prototype() const { return prototype_; }
ObjectData* shared() const { return shared_; }
ObjectData* raw_feedback_cell() const { return feedback_cell_; }
ObjectData* feedback_vector() const { return feedback_vector_; }
ObjectData* code() const { return code_; }
ObjectData* raw_feedback_cell() const {
DCHECK(serialized_code_and_feedback());
return feedback_cell_;
}
ObjectData* feedback_vector() const {
DCHECK(serialized_code_and_feedback());
return feedback_vector_;
}
ObjectData* code() const {
DCHECK(serialized_code_and_feedback());
return code_;
}
int initial_map_instance_size_with_min_slack() const {
CHECK(serialized_);
return initial_map_instance_size_with_min_slack_;
......@@ -628,6 +642,7 @@ class JSFunctionData : public JSObjectData {
bool PrototypeRequiresRuntimeLookup_;
bool serialized_ = false;
bool serialized_code_and_feedback_ = false;
ObjectData* context_ = nullptr;
ObjectData* native_context_ = nullptr;
......@@ -1250,18 +1265,11 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) {
DCHECK_NULL(initial_map_);
DCHECK_NULL(prototype_);
DCHECK_NULL(shared_);
DCHECK_NULL(feedback_cell_);
DCHECK_NULL(feedback_vector_);
DCHECK_NULL(code_);
context_ = broker->GetOrCreateData(function->context());
native_context_ = broker->GetOrCreateData(function->native_context());
shared_ = broker->GetOrCreateData(function->shared());
feedback_cell_ = broker->GetOrCreateData(function->raw_feedback_cell());
feedback_vector_ = has_feedback_vector()
? broker->GetOrCreateData(function->feedback_vector())
: nullptr;
code_ = broker->GetOrCreateData(function->code());
initial_map_ = has_initial_map()
? broker->GetOrCreateData(function->initial_map())
: nullptr;
......@@ -1284,6 +1292,24 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) {
}
}
void JSFunctionData::SerializeCodeAndFeedback(JSHeapBroker* broker) {
DCHECK(serialized_);
if (serialized_code_and_feedback_) return;
serialized_code_and_feedback_ = true;
TraceScope tracer(broker, this, "JSFunctionData::SerializeCodeAndFeedback");
Handle<JSFunction> function = Handle<JSFunction>::cast(object());
DCHECK_NULL(feedback_cell_);
DCHECK_NULL(feedback_vector_);
DCHECK_NULL(code_);
code_ = broker->GetOrCreateData(function->code());
feedback_cell_ = broker->GetOrCreateData(function->raw_feedback_cell());
feedback_vector_ = has_feedback_vector()
? broker->GetOrCreateData(function->feedback_vector())
: nullptr;
}
void MapData::SerializeElementsKindGeneralizations(JSHeapBroker* broker) {
if (serialized_elements_kind_generalizations_) return;
serialized_elements_kind_generalizations_ = true;
......@@ -4061,6 +4087,12 @@ void JSFunctionRef::Serialize() {
data()->AsJSFunction()->Serialize(broker());
}
void JSFunctionRef::SerializeCodeAndFeedback() {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSFunction()->SerializeCodeAndFeedback(broker());
}
bool JSBoundFunctionRef::serialized() const {
if (data_->should_access_heap()) return true;
return data()->AsJSBoundFunction()->serialized();
......@@ -4071,6 +4103,11 @@ bool JSFunctionRef::serialized() const {
return data()->AsJSFunction()->serialized();
}
bool JSFunctionRef::serialized_code_and_feedback() const {
if (data_->should_access_heap()) return true;
return data()->AsJSFunction()->serialized_code_and_feedback();
}
void SharedFunctionInfoRef::SerializeFunctionTemplateInfo() {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
......
......@@ -44,7 +44,6 @@ bool CanConsiderForInlining(JSHeapBroker* broker,
<< feedback_vector << " (missing data)");
return false;
}
TRACE("Considering " << shared << " for inlining with " << feedback_vector);
return true;
}
......@@ -57,12 +56,13 @@ bool CanConsiderForInlining(JSHeapBroker* broker,
return false;
}
if (!function.serialized()) {
if (!function.serialized() || !function.serialized_code_and_feedback()) {
TRACE_BROKER_MISSING(
broker, "data for " << function << " (cannot consider for inlining)");
TRACE("Cannot consider " << function << " for inlining (missing data)");
return false;
}
return CanConsiderForInlining(broker, function.shared(),
function.feedback_vector());
}
......
......@@ -1070,6 +1070,7 @@ SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
arguments_(zone()) {
closure_hints_.AddConstant(closure, zone(), broker_);
JSFunctionRef(broker, closure).Serialize();
JSFunctionRef(broker, closure).SerializeCodeAndFeedback();
TRACE_BROKER(broker_, "Hints for <closure>: " << closure_hints_);
TRACE_BROKER(broker_, "Initial environment:\n" << *environment_);
......@@ -1097,6 +1098,7 @@ SerializerForBackgroundCompilation::SerializerForBackgroundCompilation(
if (function.closure().ToHandle(&closure)) {
closure_hints_.AddConstant(closure, zone(), broker);
JSFunctionRef(broker, closure).Serialize();
JSFunctionRef(broker, closure).SerializeCodeAndFeedback();
} else {
closure_hints_.AddVirtualClosure(function.virtual_closure(), zone(),
broker);
......
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