Commit 43cd5d10 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[tracing] Speed up SharedFunctionInfo::TraceID

Avoid the linear lookup of function literal id when getting the shared
function info TraceID, by optionally passing through a FunctionLiteral.
Additionally, use the FunctionLiteralId helper when a FunctionLiteral is
not available, since it can also fast-path in some cases.

As a drive-by, allow using a ScriptIterator without an Isolate pointer
(e.g. manually creating a handle) to allow calling FunctionLiteralId
without an Isolate pointer.

Bug: v8:9325
Change-Id: Ibfa053f300d6d5005485c67174a848264a5d1372
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1643429
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61983}
parent cbf72529
...@@ -1124,8 +1124,7 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script, ...@@ -1124,8 +1124,7 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
} }
new_script->shared_function_infos().Set( new_script->shared_function_infos().Set(
mapping.second->function_literal_id(), HeapObjectReference::Weak(*sfi)); mapping.second->function_literal_id(), HeapObjectReference::Weak(*sfi));
DCHECK_EQ(sfi->FunctionLiteralId(isolate), DCHECK_EQ(sfi->FunctionLiteralId(), mapping.second->function_literal_id());
mapping.second->function_literal_id());
// Save the new start_position -> id mapping, so that we can recover it when // Save the new start_position -> id mapping, so that we can recover it when
// iterating over changed functions' constant pools. // iterating over changed functions' constant pools.
...@@ -1222,7 +1221,7 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script, ...@@ -1222,7 +1221,7 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
std::set<int> start_positions; std::set<int> start_positions;
for (SharedFunctionInfo sfi = it.Next(); !sfi.is_null(); sfi = it.Next()) { for (SharedFunctionInfo sfi = it.Next(); !sfi.is_null(); sfi = it.Next()) {
DCHECK_EQ(sfi.script(), *new_script); DCHECK_EQ(sfi.script(), *new_script);
DCHECK_EQ(sfi.FunctionLiteralId(isolate), it.CurrentIndex()); DCHECK_EQ(sfi.FunctionLiteralId(), it.CurrentIndex());
// Don't check the start position of the top-level function, as it can // Don't check the start position of the top-level function, as it can
// overlap with a function in the script. // overlap with a function in the script.
if (sfi.is_toplevel()) { if (sfi.is_toplevel()) {
...@@ -1242,7 +1241,7 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script, ...@@ -1242,7 +1241,7 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
SharedFunctionInfo::cast(constants.get(i)); SharedFunctionInfo::cast(constants.get(i));
DCHECK_EQ(inner_sfi.script(), *new_script); DCHECK_EQ(inner_sfi.script(), *new_script);
DCHECK_EQ(inner_sfi, new_script->shared_function_infos() DCHECK_EQ(inner_sfi, new_script->shared_function_infos()
.Get(inner_sfi.FunctionLiteralId(isolate)) .Get(inner_sfi.FunctionLiteralId())
->GetHeapObject()); ->GetHeapObject());
} }
} }
......
...@@ -3335,10 +3335,12 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral( ...@@ -3335,10 +3335,12 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral(
false); false);
TRACE_EVENT_OBJECT_CREATED_WITH_ID( TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("v8.compile"), "SharedFunctionInfo", TRACE_DISABLED_BY_DEFAULT("v8.compile"), "SharedFunctionInfo",
TRACE_ID_WITH_SCOPE(SharedFunctionInfo::kTraceScope, shared->TraceID())); TRACE_ID_WITH_SCOPE(SharedFunctionInfo::kTraceScope,
shared->TraceID(literal)));
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("v8.compile"), "SharedFunctionInfo", TRACE_DISABLED_BY_DEFAULT("v8.compile"), "SharedFunctionInfo",
TRACE_ID_WITH_SCOPE(SharedFunctionInfo::kTraceScope, shared->TraceID()), TRACE_ID_WITH_SCOPE(SharedFunctionInfo::kTraceScope,
shared->TraceID(literal)),
shared->ToTracedValue(literal)); shared->ToTracedValue(literal));
return shared; return shared;
} }
......
...@@ -4855,22 +4855,12 @@ std::unique_ptr<v8::tracing::TracedValue> SharedFunctionInfo::ToTracedValue( ...@@ -4855,22 +4855,12 @@ std::unique_ptr<v8::tracing::TracedValue> SharedFunctionInfo::ToTracedValue(
const char* SharedFunctionInfo::kTraceScope = const char* SharedFunctionInfo::kTraceScope =
"v8::internal::SharedFunctionInfo"; "v8::internal::SharedFunctionInfo";
uint64_t SharedFunctionInfo::TraceID() const { uint64_t SharedFunctionInfo::TraceID(FunctionLiteral* literal) const {
// TODO(bmeurer): We use a combination of Script ID and function literal int literal_id =
// ID (within the Script) to uniquely identify SharedFunctionInfos. This literal ? literal->function_literal_id() : FunctionLiteralId();
// can add significant overhead, and we should probably find a better way
// to uniquely identify SharedFunctionInfos over time.
Script script = Script::cast(this->script()); Script script = Script::cast(this->script());
WeakFixedArray script_functions = script.shared_function_infos(); return (static_cast<uint64_t>(script.id() + 1) << 32) |
for (int i = 0; i < script_functions.length(); ++i) { (static_cast<uint64_t>(literal_id));
HeapObject script_function;
if (script_functions.Get(i).GetHeapObjectIfWeak(&script_function) &&
script_function.address() == address()) {
return (static_cast<uint64_t>(script.id() + 1) << 32) |
(static_cast<uint64_t>(i));
}
}
UNREACHABLE();
} }
std::unique_ptr<v8::tracing::TracedValue> SharedFunctionInfo::TraceIDRef() std::unique_ptr<v8::tracing::TracedValue> SharedFunctionInfo::TraceIDRef()
...@@ -4946,21 +4936,17 @@ WasmCapiFunctionData SharedFunctionInfo::wasm_capi_function_data() const { ...@@ -4946,21 +4936,17 @@ WasmCapiFunctionData SharedFunctionInfo::wasm_capi_function_data() const {
SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate, SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate,
Script script) Script script)
: ScriptIterator(isolate, handle(script.shared_function_infos(), isolate)) { : ScriptIterator(handle(script.shared_function_infos(), isolate)) {}
}
SharedFunctionInfo::ScriptIterator::ScriptIterator( SharedFunctionInfo::ScriptIterator::ScriptIterator(
Isolate* isolate, Handle<WeakFixedArray> shared_function_infos) Handle<WeakFixedArray> shared_function_infos)
: isolate_(isolate), : shared_function_infos_(shared_function_infos), index_(0) {}
shared_function_infos_(shared_function_infos),
index_(0) {}
SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() { SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() {
while (index_ < shared_function_infos_->length()) { while (index_ < shared_function_infos_->length()) {
MaybeObject raw = shared_function_infos_->Get(index_++); MaybeObject raw = shared_function_infos_->Get(index_++);
HeapObject heap_object; HeapObject heap_object;
if (!raw->GetHeapObject(&heap_object) || if (!raw->GetHeapObject(&heap_object) || heap_object.IsUndefined()) {
heap_object.IsUndefined(isolate_)) {
continue; continue;
} }
return SharedFunctionInfo::cast(heap_object); return SharedFunctionInfo::cast(heap_object);
...@@ -4968,13 +4954,15 @@ SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() { ...@@ -4968,13 +4954,15 @@ SharedFunctionInfo SharedFunctionInfo::ScriptIterator::Next() {
return SharedFunctionInfo(); return SharedFunctionInfo();
} }
void SharedFunctionInfo::ScriptIterator::Reset(Script script) { void SharedFunctionInfo::ScriptIterator::Reset(Isolate* isolate,
shared_function_infos_ = handle(script.shared_function_infos(), isolate_); Script script) {
shared_function_infos_ = handle(script.shared_function_infos(), isolate);
index_ = 0; index_ = 0;
} }
SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate) SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate)
: script_iterator_(isolate), : isolate_(isolate),
script_iterator_(isolate),
noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()), noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()),
sfi_iterator_(isolate, script_iterator_.Next()) {} sfi_iterator_(isolate, script_iterator_.Next()) {}
...@@ -4986,7 +4974,7 @@ SharedFunctionInfo SharedFunctionInfo::GlobalIterator::Next() { ...@@ -4986,7 +4974,7 @@ SharedFunctionInfo SharedFunctionInfo::GlobalIterator::Next() {
if (!next.is_null()) return SharedFunctionInfo::cast(next); if (!next.is_null()) return SharedFunctionInfo::cast(next);
Script next_script = script_iterator_.Next(); Script next_script = script_iterator_.Next();
if (next_script.is_null()) return SharedFunctionInfo(); if (next_script.is_null()) return SharedFunctionInfo();
sfi_iterator_.Reset(next_script); sfi_iterator_.Reset(isolate_, next_script);
} }
} }
...@@ -5148,7 +5136,7 @@ void SharedFunctionInfo::DiscardCompiled( ...@@ -5148,7 +5136,7 @@ void SharedFunctionInfo::DiscardCompiled(
handle(shared_info->inferred_name(), isolate); handle(shared_info->inferred_name(), isolate);
int start_position = shared_info->StartPosition(); int start_position = shared_info->StartPosition();
int end_position = shared_info->EndPosition(); int end_position = shared_info->EndPosition();
int function_literal_id = shared_info->FunctionLiteralId(isolate); int function_literal_id = shared_info->FunctionLiteralId();
shared_info->DiscardCompiledMetadata(isolate); shared_info->DiscardCompiledMetadata(isolate);
...@@ -5273,7 +5261,7 @@ bool SharedFunctionInfo::IsInlineable() { ...@@ -5273,7 +5261,7 @@ bool SharedFunctionInfo::IsInlineable() {
int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); } int SharedFunctionInfo::SourceSize() { return EndPosition() - StartPosition(); }
int SharedFunctionInfo::FindIndexInScript(Isolate* isolate) const { int SharedFunctionInfo::FindIndexInScript() const {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Object script_obj = script(); Object script_obj = script();
...@@ -5282,7 +5270,6 @@ int SharedFunctionInfo::FindIndexInScript(Isolate* isolate) const { ...@@ -5282,7 +5270,6 @@ int SharedFunctionInfo::FindIndexInScript(Isolate* isolate) const {
WeakFixedArray shared_info_list = WeakFixedArray shared_info_list =
Script::cast(script_obj).shared_function_infos(); Script::cast(script_obj).shared_function_infos();
SharedFunctionInfo::ScriptIterator iterator( SharedFunctionInfo::ScriptIterator iterator(
isolate,
Handle<WeakFixedArray>(reinterpret_cast<Address*>(&shared_info_list))); Handle<WeakFixedArray>(reinterpret_cast<Address*>(&shared_info_list)));
for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null(); for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null();
...@@ -5510,19 +5497,19 @@ int SharedFunctionInfo::EndPosition() const { ...@@ -5510,19 +5497,19 @@ int SharedFunctionInfo::EndPosition() const {
return kNoSourcePosition; return kNoSourcePosition;
} }
int SharedFunctionInfo::FunctionLiteralId(Isolate* isolate) const { int SharedFunctionInfo::FunctionLiteralId() const {
// Fast path for the common case when the SFI is uncompiled and so the // Fast path for the common case when the SFI is uncompiled and so the
// function literal id is already in the uncompiled data. // function literal id is already in the uncompiled data.
if (HasUncompiledData() && uncompiled_data().has_function_literal_id()) { if (HasUncompiledData() && uncompiled_data().has_function_literal_id()) {
int id = uncompiled_data().function_literal_id(); int id = uncompiled_data().function_literal_id();
// Make sure the id is what we should have found with the slow path. // Make sure the id is what we should have found with the slow path.
DCHECK_EQ(id, FindIndexInScript(isolate)); DCHECK_EQ(id, FindIndexInScript());
return id; return id;
} }
// Otherwise, search for the function in the SFI's script's function list, // Otherwise, search for the function in the SFI's script's function list,
// and return its index in that list. // and return its index in that list.
return FindIndexInScript(isolate); return FindIndexInScript();
} }
void SharedFunctionInfo::SetPosition(int start_position, int end_position) { void SharedFunctionInfo::SetPosition(int start_position, int end_position) {
......
...@@ -386,7 +386,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -386,7 +386,7 @@ class SharedFunctionInfo : public HeapObject {
inline String inferred_name(); inline String inferred_name();
// Get the function literal id associated with this function, for parsing. // Get the function literal id associated with this function, for parsing.
V8_EXPORT_PRIVATE int FunctionLiteralId(Isolate* isolate) const; V8_EXPORT_PRIVATE int FunctionLiteralId() const;
// Break infos are contained in DebugInfo, this is a convenience method // Break infos are contained in DebugInfo, this is a convenience method
// to simplify access. // to simplify access.
...@@ -624,7 +624,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -624,7 +624,7 @@ class SharedFunctionInfo : public HeapObject {
// Returns the unique TraceID for this SharedFunctionInfo (within the // Returns the unique TraceID for this SharedFunctionInfo (within the
// kTraceScope, works only for functions that have a Script and start/end // kTraceScope, works only for functions that have a Script and start/end
// position). // position).
uint64_t TraceID() const; uint64_t TraceID(FunctionLiteral* literal = nullptr) const;
// Returns the unique trace ID reference for this SharedFunctionInfo // Returns the unique trace ID reference for this SharedFunctionInfo
// (based on the |TraceID()| above). // (based on the |TraceID()| above).
...@@ -634,16 +634,14 @@ class SharedFunctionInfo : public HeapObject { ...@@ -634,16 +634,14 @@ class SharedFunctionInfo : public HeapObject {
class ScriptIterator { class ScriptIterator {
public: public:
V8_EXPORT_PRIVATE ScriptIterator(Isolate* isolate, Script script); V8_EXPORT_PRIVATE ScriptIterator(Isolate* isolate, Script script);
ScriptIterator(Isolate* isolate, explicit ScriptIterator(Handle<WeakFixedArray> shared_function_infos);
Handle<WeakFixedArray> shared_function_infos);
V8_EXPORT_PRIVATE SharedFunctionInfo Next(); V8_EXPORT_PRIVATE SharedFunctionInfo Next();
int CurrentIndex() const { return index_ - 1; } int CurrentIndex() const { return index_ - 1; }
// Reset the iterator to run on |script|. // Reset the iterator to run on |script|.
void Reset(Script script); void Reset(Isolate* isolate, Script script);
private: private:
Isolate* isolate_;
Handle<WeakFixedArray> shared_function_infos_; Handle<WeakFixedArray> shared_function_infos_;
int index_; int index_;
DISALLOW_COPY_AND_ASSIGN(ScriptIterator); DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
...@@ -656,6 +654,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -656,6 +654,7 @@ class SharedFunctionInfo : public HeapObject {
V8_EXPORT_PRIVATE SharedFunctionInfo Next(); V8_EXPORT_PRIVATE SharedFunctionInfo Next();
private: private:
Isolate* isolate_;
Script::Iterator script_iterator_; Script::Iterator script_iterator_;
WeakArrayList::Iterator noscript_sfi_iterator_; WeakArrayList::Iterator noscript_sfi_iterator_;
SharedFunctionInfo::ScriptIterator sfi_iterator_; SharedFunctionInfo::ScriptIterator sfi_iterator_;
...@@ -746,7 +745,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -746,7 +745,7 @@ class SharedFunctionInfo : public HeapObject {
// Find the index of this function in the parent script. Slow path of // Find the index of this function in the parent script. Slow path of
// FunctionLiteralId. // FunctionLiteralId.
int FindIndexInScript(Isolate* isolate) const; int FindIndexInScript() const;
OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject); OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
}; };
......
...@@ -97,7 +97,7 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared) ...@@ -97,7 +97,7 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
set_start_position(shared->StartPosition()); set_start_position(shared->StartPosition());
set_end_position(shared->EndPosition()); set_end_position(shared->EndPosition());
function_literal_id_ = shared->FunctionLiteralId(isolate); function_literal_id_ = shared->FunctionLiteralId();
SetFunctionInfo(shared); SetFunctionInfo(shared);
Handle<Script> script(Script::cast(shared->script()), isolate); Handle<Script> script(Script::cast(shared->script()), isolate);
......
...@@ -94,7 +94,7 @@ class CompilerDispatcherTest : public TestWithNativeContext { ...@@ -94,7 +94,7 @@ class CompilerDispatcherTest : public TestWithNativeContext {
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true, FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true,
shared->FunctionLiteralId(isolate), nullptr); shared->FunctionLiteralId(), nullptr);
return dispatcher->Enqueue(outer_parse_info.get(), function_name, return dispatcher->Enqueue(outer_parse_info.get(), function_name,
function_literal); function_literal);
......
...@@ -73,7 +73,7 @@ class BackgroundCompileTaskTest : public TestWithNativeContext { ...@@ -73,7 +73,7 @@ class BackgroundCompileTaskTest : public TestWithNativeContext {
FunctionLiteral::kNoDuplicateParameters, FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true, FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true,
shared->FunctionLiteralId(isolate), nullptr); shared->FunctionLiteralId(), nullptr);
return new BackgroundCompileTask( return new BackgroundCompileTask(
allocator(), outer_parse_info.get(), function_name, function_literal, allocator(), outer_parse_info.get(), function_name, function_literal,
......
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