[inspector] Introduce v8::StackFrame::GetLocation() API.

This introduces a new `GetLocation()` method for `v8::StackFrame`s,
which returns both line and column number at the same time (using the
existing `v8::Location` class). Since `v8::StackFrame` instances store
only the source position (per https://bit.ly/v8-stack-frame), we
currently need to look up the source position in the Script's line table
twice, once when we request the line number, and another time when we
request the column number.

With `GetLocation()` we perform only a single lookup in the Script's
line table and return both line and column number at the same time. This
cuts roughly 8% of the average execution time from the `standalone.js`
benchmark mentioned in crbug.com/1280519.

Bug: chromium:1280519, chromium:1278650, chromium:1069425
Bug: chromium:1077657, chromium:1283162
Doc: https://bit.ly/v8-cheaper-inspector-stack-traces
Change-Id: Ia3a0502990b6230363112a358b59875283399404
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3359628
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78452}
This commit is contained in:
Benedikt Meurer 2021-12-29 11:50:01 +01:00 committed by V8 LUCI CQ
parent 6a90e91624
commit ed7b66400e
3 changed files with 22 additions and 24 deletions

View File

@ -7,8 +7,8 @@
#include <stdint.h>
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
#include "v8-script.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
namespace v8 {
@ -20,13 +20,18 @@ class String;
*/
class V8_EXPORT StackFrame {
public:
/**
* Returns the source location, 0-based, for the associated function call.
*/
Location GetLocation() const;
/**
* Returns the number, 1-based, of the line for the associate function call.
* This method will return Message::kNoLineNumberInfo if it is unable to
* retrieve the line number, or if kLineNumber was not passed as an option
* when capturing the StackTrace.
*/
int GetLineNumber() const;
int GetLineNumber() const { return GetLocation().GetLineNumber() + 1; }
/**
* Returns the 1-based column offset on the line for the associated function
@ -35,7 +40,7 @@ class V8_EXPORT StackFrame {
* the column number, or if kColumnOffset was not passed as an option when
* capturing the StackTrace.
*/
int GetColumn() const;
int GetColumn() const { return GetLocation().GetColumnNumber() + 1; }
/**
* Returns the id of the script for the function for this StackFrame.

View File

@ -3250,28 +3250,20 @@ Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
// --- S t a c k F r a m e ---
int StackFrame::GetLineNumber() const {
Location StackFrame::GetLocation() const {
i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
i::Handle<i::Script> script(self->script(), self->GetIsolate());
int position = self->source_position();
int line_number = i::Script::GetLineNumber(script, position) + 1;
i::Isolate* isolate = self->GetIsolate();
i::Handle<i::Script> script(self->script(), isolate);
i::Script::PositionInfo info;
CHECK(i::Script::GetPositionInfo(script, self->source_position(), &info,
i::Script::WITH_OFFSET));
if (script->HasSourceURLComment()) {
line_number -= script->line_offset();
}
return line_number;
}
int StackFrame::GetColumn() const {
i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
i::Handle<i::Script> script(self->script(), self->GetIsolate());
int position = self->source_position();
int column_number = i::Script::GetColumnNumber(script, position) + 1;
if (script->HasSourceURLComment()) {
if (i::Script::GetLineNumber(script, position) == script->line_offset()) {
column_number -= script->column_offset();
info.line -= script->line_offset();
if (info.line == 0) {
info.column -= script->column_offset();
}
}
return column_number;
return {info.line, info.column};
}
int StackFrame::GetScriptId() const {

View File

@ -1091,8 +1091,9 @@ void V8Debugger::collectOldAsyncStacksIfNeeded() {
std::shared_ptr<StackFrame> V8Debugger::symbolize(
v8::Local<v8::StackFrame> v8Frame) {
int scriptId = v8Frame->GetScriptId();
int lineNumber = v8Frame->GetLineNumber() - 1;
int columnNumber = v8Frame->GetColumn() - 1;
auto location = v8Frame->GetLocation();
int lineNumber = location.GetLineNumber();
int columnNumber = location.GetColumnNumber();
CachedStackFrameKey key{scriptId, lineNumber, columnNumber};
auto functionName = toProtocolString(isolate(), v8Frame->GetFunctionName());
auto it = m_cachedStackFrames.find(key);