Commit ed7b6640 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by V8 LUCI CQ

[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/+/3359628Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78452}
parent 6a90e916
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#include <stdint.h> #include <stdint.h>
#include "v8-local-handle.h" // NOLINT(build/include_directory) #include "v8-script.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory) #include "v8config.h" // NOLINT(build/include_directory)
namespace v8 { namespace v8 {
...@@ -20,13 +20,18 @@ class String; ...@@ -20,13 +20,18 @@ class String;
*/ */
class V8_EXPORT StackFrame { class V8_EXPORT StackFrame {
public: 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. * Returns the number, 1-based, of the line for the associate function call.
* This method will return Message::kNoLineNumberInfo if it is unable to * This method will return Message::kNoLineNumberInfo if it is unable to
* retrieve the line number, or if kLineNumber was not passed as an option * retrieve the line number, or if kLineNumber was not passed as an option
* when capturing the StackTrace. * 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 * Returns the 1-based column offset on the line for the associated function
...@@ -35,7 +40,7 @@ class V8_EXPORT StackFrame { ...@@ -35,7 +40,7 @@ class V8_EXPORT StackFrame {
* the column number, or if kColumnOffset was not passed as an option when * the column number, or if kColumnOffset was not passed as an option when
* capturing the StackTrace. * 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. * Returns the id of the script for the function for this StackFrame.
......
...@@ -3250,28 +3250,20 @@ Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate, ...@@ -3250,28 +3250,20 @@ Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
// --- S t a c k F r a m e --- // --- 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::StackFrameInfo> self = Utils::OpenHandle(this);
i::Handle<i::Script> script(self->script(), self->GetIsolate()); i::Isolate* isolate = self->GetIsolate();
int position = self->source_position(); i::Handle<i::Script> script(self->script(), isolate);
int line_number = i::Script::GetLineNumber(script, position) + 1; i::Script::PositionInfo info;
if (script->HasSourceURLComment()) { CHECK(i::Script::GetPositionInfo(script, self->source_position(), &info,
line_number -= script->line_offset(); i::Script::WITH_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 (script->HasSourceURLComment()) {
if (i::Script::GetLineNumber(script, position) == script->line_offset()) { info.line -= script->line_offset();
column_number -= script->column_offset(); if (info.line == 0) {
info.column -= script->column_offset();
} }
} }
return column_number; return {info.line, info.column};
} }
int StackFrame::GetScriptId() const { int StackFrame::GetScriptId() const {
......
...@@ -1091,8 +1091,9 @@ void V8Debugger::collectOldAsyncStacksIfNeeded() { ...@@ -1091,8 +1091,9 @@ void V8Debugger::collectOldAsyncStacksIfNeeded() {
std::shared_ptr<StackFrame> V8Debugger::symbolize( std::shared_ptr<StackFrame> V8Debugger::symbolize(
v8::Local<v8::StackFrame> v8Frame) { v8::Local<v8::StackFrame> v8Frame) {
int scriptId = v8Frame->GetScriptId(); int scriptId = v8Frame->GetScriptId();
int lineNumber = v8Frame->GetLineNumber() - 1; auto location = v8Frame->GetLocation();
int columnNumber = v8Frame->GetColumn() - 1; int lineNumber = location.GetLineNumber();
int columnNumber = location.GetColumnNumber();
CachedStackFrameKey key{scriptId, lineNumber, columnNumber}; CachedStackFrameKey key{scriptId, lineNumber, columnNumber};
auto functionName = toProtocolString(isolate(), v8Frame->GetFunctionName()); auto functionName = toProtocolString(isolate(), v8Frame->GetFunctionName());
auto it = m_cachedStackFrames.find(key); auto it = m_cachedStackFrames.find(key);
......
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