[inspector] store stack frame in struct instead of JSObject

JSObject is slow: creating strings for keys and storing values by these keys after takes significant amount of time.
With this CL console methods (most of them collect top stack frame to calculate source location) are ~33% faster.
V8Debugger::captureStackTrace is ~50% faster.

BUG=v8:6189
R=yangguo@chromium.org
TBR=bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/2789073002
Cr-Commit-Position: refs/heads/master@{#44344}
This commit is contained in:
kozyatinskiy 2017-04-03 07:58:49 -07:00 committed by Commit bot
parent 32d4d8e93d
commit dc662e5b74
14 changed files with 164 additions and 186 deletions

View File

@ -8646,8 +8646,8 @@ class Internals {
static const int kNodeIsIndependentShift = 3; static const int kNodeIsIndependentShift = 3;
static const int kNodeIsActiveShift = 4; static const int kNodeIsActiveShift = 4;
static const int kJSApiObjectType = 0xba; static const int kJSApiObjectType = 0xbb;
static const int kJSObjectType = 0xbb; static const int kJSObjectType = 0xbc;
static const int kFirstNonstringType = 0x80; static const int kFirstNonstringType = 0x80;
static const int kOddballType = 0x82; static const int kOddballType = 0x82;
static const int kForeignType = 0x86; static const int kForeignType = 0x86;

View File

@ -2846,8 +2846,8 @@ Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
auto self = Utils::OpenHandle(this); auto self = Utils::OpenHandle(this);
auto obj = i::JSReceiver::GetElement(isolate, self, index).ToHandleChecked(); auto obj = i::JSReceiver::GetElement(isolate, self, index).ToHandleChecked();
auto jsobj = i::Handle<i::JSObject>::cast(obj); auto info = i::Handle<i::StackFrameInfo>::cast(obj);
return scope.Escape(Utils::StackFrameToLocal(jsobj)); return scope.Escape(Utils::StackFrameToLocal(info));
} }
@ -2875,77 +2875,59 @@ Local<StackTrace> StackTrace::CurrentStackTrace(
// --- S t a c k F r a m e --- // --- S t a c k F r a m e ---
static int getIntProperty(const StackFrame* f, const char* propertyName,
int defaultValue) {
i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(f);
i::Handle<i::Object> obj =
i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
}
int StackFrame::GetLineNumber() const { int StackFrame::GetLineNumber() const {
return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo); int v = Utils::OpenHandle(this)->line_number();
return v ? v : Message::kNoLineNumberInfo;
} }
int StackFrame::GetColumn() const { int StackFrame::GetColumn() const {
return getIntProperty(this, "column", Message::kNoColumnInfo); int v = Utils::OpenHandle(this)->column_number();
return v ? v : Message::kNoLineNumberInfo;
} }
int StackFrame::GetScriptId() const { int StackFrame::GetScriptId() const {
return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo); int v = Utils::OpenHandle(this)->script_id();
return v ? v : Message::kNoScriptIdInfo;
} }
Local<String> StackFrame::GetScriptName() const {
static Local<String> getStringProperty(const StackFrame* f, i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
const char* propertyName) {
i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::JSObject> self = Utils::OpenHandle(f); i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
i::Handle<i::Object> obj = i::Handle<i::Object> obj(self->script_name(), isolate);
i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
return obj->IsString() return obj->IsString()
? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj))) ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
: Local<String>(); : Local<String>();
} }
Local<String> StackFrame::GetScriptName() const {
return getStringProperty(this, "scriptName");
}
Local<String> StackFrame::GetScriptNameOrSourceURL() const { Local<String> StackFrame::GetScriptNameOrSourceURL() const {
return getStringProperty(this, "scriptNameOrSourceURL"); i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
i::Handle<i::Object> obj(self->script_name_or_source_url(), isolate);
return obj->IsString()
? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
: Local<String>();
} }
Local<String> StackFrame::GetFunctionName() const { Local<String> StackFrame::GetFunctionName() const {
return getStringProperty(this, "functionName"); i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
i::Handle<i::Object> obj(self->function_name(), isolate);
return obj->IsString()
? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
: Local<String>();
} }
bool StackFrame::IsEval() const { return Utils::OpenHandle(this)->is_eval(); }
static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(f);
i::Handle<i::Object> obj =
i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
return obj->IsTrue(isolate);
}
bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
bool StackFrame::IsConstructor() const { bool StackFrame::IsConstructor() const {
return getBoolProperty(this, "isConstructor"); return Utils::OpenHandle(this)->is_constructor();
} }

View File

@ -106,7 +106,7 @@ class RegisteredExtension {
V(Context, Context) \ V(Context, Context) \
V(External, Object) \ V(External, Object) \
V(StackTrace, JSArray) \ V(StackTrace, JSArray) \
V(StackFrame, JSObject) \ V(StackFrame, StackFrameInfo) \
V(Proxy, JSProxy) \ V(Proxy, JSProxy) \
V(NativeWeakMap, JSWeakMap) \ V(NativeWeakMap, JSWeakMap) \
V(debug::GeneratorObject, JSGeneratorObject) \ V(debug::GeneratorObject, JSGeneratorObject) \
@ -188,7 +188,7 @@ class Utils {
static inline Local<StackTrace> StackTraceToLocal( static inline Local<StackTrace> StackTraceToLocal(
v8::internal::Handle<v8::internal::JSArray> obj); v8::internal::Handle<v8::internal::JSArray> obj);
static inline Local<StackFrame> StackFrameToLocal( static inline Local<StackFrame> StackFrameToLocal(
v8::internal::Handle<v8::internal::JSObject> obj); v8::internal::Handle<v8::internal::StackFrameInfo> obj);
static inline Local<Number> NumberToLocal( static inline Local<Number> NumberToLocal(
v8::internal::Handle<v8::internal::Object> obj); v8::internal::Handle<v8::internal::Object> obj);
static inline Local<Integer> IntegerToLocal( static inline Local<Integer> IntegerToLocal(
@ -318,7 +318,7 @@ MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
MAKE_TO_LOCAL(MessageToLocal, Object, Message) MAKE_TO_LOCAL(MessageToLocal, Object, Message)
MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise) MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise)
MAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace) MAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace)
MAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame) MAKE_TO_LOCAL(StackFrameToLocal, StackFrameInfo, StackFrame)
MAKE_TO_LOCAL(NumberToLocal, Object, Number) MAKE_TO_LOCAL(NumberToLocal, Object, Number)
MAKE_TO_LOCAL(IntegerToLocal, Object, Integer) MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32) MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)

View File

@ -312,6 +312,7 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
case ALIASED_ARGUMENTS_ENTRY_TYPE: case ALIASED_ARGUMENTS_ENTRY_TYPE:
case DEBUG_INFO_TYPE: case DEBUG_INFO_TYPE:
case BREAK_POINT_INFO_TYPE: case BREAK_POINT_INFO_TYPE:
case STACK_FRAME_INFO_TYPE:
case CELL_TYPE: case CELL_TYPE:
case WEAK_CELL_TYPE: case WEAK_CELL_TYPE:
case PROTOTYPE_INFO_TYPE: case PROTOTYPE_INFO_TYPE:

View File

@ -320,6 +320,7 @@ Type::bitset BitsetType::Lub(i::Map* map) {
case PROMISE_REACTION_JOB_INFO_TYPE: case PROMISE_REACTION_JOB_INFO_TYPE:
case DEBUG_INFO_TYPE: case DEBUG_INFO_TYPE:
case BREAK_POINT_INFO_TYPE: case BREAK_POINT_INFO_TYPE:
case STACK_FRAME_INFO_TYPE:
case CELL_TYPE: case CELL_TYPE:
case WEAK_CELL_TYPE: case WEAK_CELL_TYPE:
case PROTOTYPE_INFO_TYPE: case PROTOTYPE_INFO_TYPE:

View File

@ -4203,6 +4203,7 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
case PROMISE_REACTION_JOB_INFO_TYPE: case PROMISE_REACTION_JOB_INFO_TYPE:
case DEBUG_INFO_TYPE: case DEBUG_INFO_TYPE:
case BREAK_POINT_INFO_TYPE: case BREAK_POINT_INFO_TYPE:
case STACK_FRAME_INFO_TYPE:
case CELL_TYPE: case CELL_TYPE:
case WEAK_CELL_TYPE: case WEAK_CELL_TYPE:
case PROTOTYPE_INFO_TYPE: case PROTOTYPE_INFO_TYPE:

View File

@ -2592,6 +2592,19 @@ Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
return new_break_point_info; return new_break_point_info;
} }
Handle<StackFrameInfo> Factory::NewStackFrameInfo() {
Handle<StackFrameInfo> stack_frame_info =
Handle<StackFrameInfo>::cast(NewStruct(STACK_FRAME_INFO_TYPE));
stack_frame_info->set_line_number(0);
stack_frame_info->set_column_number(0);
stack_frame_info->set_script_id(0);
stack_frame_info->set_script_name(Smi::kZero);
stack_frame_info->set_script_name_or_source_url(Smi::kZero);
stack_frame_info->set_function_name(Smi::kZero);
stack_frame_info->set_flag(0);
return stack_frame_info;
}
Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee, Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
int length) { int length) {
bool strict_mode_callee = is_strict(callee->shared()->language_mode()) || bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||

View File

@ -321,6 +321,7 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<Script> NewScript(Handle<String> source); Handle<Script> NewScript(Handle<String> source);
Handle<BreakPointInfo> NewBreakPointInfo(int source_position); Handle<BreakPointInfo> NewBreakPointInfo(int source_position);
Handle<StackFrameInfo> NewStackFrameInfo();
// Foreign objects are pretenured when allocated by the bootstrapper. // Foreign objects are pretenured when allocated by the bootstrapper.
Handle<Foreign> NewForeign(Address addr, Handle<Foreign> NewForeign(Address addr,

View File

@ -614,169 +614,85 @@ class CaptureStackTraceHelper {
public: public:
CaptureStackTraceHelper(Isolate* isolate, CaptureStackTraceHelper(Isolate* isolate,
StackTrace::StackTraceOptions options) StackTrace::StackTraceOptions options)
: isolate_(isolate) { : isolate_(isolate), options_(options) {}
if (options & StackTrace::kColumnOffset) {
column_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("column"));
}
if (options & StackTrace::kLineNumber) {
line_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("lineNumber"));
}
if (options & StackTrace::kScriptId) {
script_id_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptId"));
}
if (options & StackTrace::kScriptName) {
script_name_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptName"));
}
if (options & StackTrace::kScriptNameOrSourceURL) {
script_name_or_source_url_key_ = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("scriptNameOrSourceURL"));
}
if (options & StackTrace::kFunctionName) {
function_key_ = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("functionName"));
}
if (options & StackTrace::kIsEval) {
eval_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval"));
}
if (options & StackTrace::kIsConstructor) {
constructor_key_ = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("isConstructor"));
}
}
Handle<JSObject> NewStackFrameObject(FrameSummary& summ) { Handle<StackFrameInfo> NewStackFrameObject(FrameSummary& summ) {
if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript());
if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm());
UNREACHABLE(); UNREACHABLE();
return Handle<JSObject>::null(); return factory()->NewStackFrameInfo();
} }
Handle<JSObject> NewStackFrameObject( Handle<StackFrameInfo> NewStackFrameObject(
const FrameSummary::JavaScriptFrameSummary& summ) { const FrameSummary::JavaScriptFrameSummary& summ) {
Handle<JSObject> stack_frame = Handle<StackFrameInfo> frame = factory()->NewStackFrameInfo();
factory()->NewJSObject(isolate_->object_function());
Handle<Script> script = Handle<Script>::cast(summ.script()); Handle<Script> script = Handle<Script>::cast(summ.script());
if (options_ & StackTrace::kLineNumber) {
if (!line_key_.is_null()) {
Script::PositionInfo info; Script::PositionInfo info;
bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(), bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(),
&info, Script::WITH_OFFSET); &info, Script::WITH_OFFSET);
if (valid_pos) {
if (!column_key_.is_null() && valid_pos) { frame->set_line_number(info.line + 1);
JSObject::AddProperty(stack_frame, column_key_, if (options_ & StackTrace::kColumnOffset) {
handle(Smi::FromInt(info.column + 1), isolate_), frame->set_column_number(info.column + 1);
NONE); }
} }
JSObject::AddProperty(stack_frame, line_key_,
handle(Smi::FromInt(info.line + 1), isolate_),
NONE);
} }
if (!script_id_key_.is_null()) { if (options_ & StackTrace::kScriptId) frame->set_script_id(script->id());
JSObject::AddProperty(stack_frame, script_id_key_, if (options_ & StackTrace::kScriptName) {
handle(Smi::FromInt(script->id()), isolate_), NONE); frame->set_script_name(script->name());
}
if (options_ & StackTrace::kScriptNameOrSourceURL) {
frame->set_script_name_or_source_url(script->GetNameOrSourceURL());
}
if (options_ & StackTrace::kIsEval) {
frame->set_is_eval(script->compilation_type() ==
Script::COMPILATION_TYPE_EVAL);
}
if (options_ & StackTrace::kFunctionName) {
Handle<String> name = summ.FunctionName();
frame->set_function_name(*name);
}
if (options_ & StackTrace::kIsConstructor) {
frame->set_is_constructor(summ.is_constructor());
}
return frame;
} }
if (!script_name_key_.is_null()) { Handle<StackFrameInfo> NewStackFrameObject(
JSObject::AddProperty(stack_frame, script_name_key_,
handle(script->name(), isolate_), NONE);
}
if (!script_name_or_source_url_key_.is_null()) {
Handle<Object> result(script->GetNameOrSourceURL(), isolate_);
JSObject::AddProperty(stack_frame, script_name_or_source_url_key_, result,
NONE);
}
if (!eval_key_.is_null()) {
Handle<Object> is_eval = factory()->ToBoolean(
script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE);
}
if (!function_key_.is_null()) {
Handle<String> fun_name = summ.FunctionName();
JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
}
if (!constructor_key_.is_null()) {
Handle<Object> is_constructor_obj =
factory()->ToBoolean(summ.is_constructor());
JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj,
NONE);
}
return stack_frame;
}
Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) {
Handle<JSObject> stack_frame =
factory()->NewJSObject(isolate_->object_function());
Handle<JSFunction> fun = handle(frame->function(), isolate_);
if (!function_key_.is_null()) {
Handle<Object> fun_name = JSFunction::GetDebugName(fun);
JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
}
// We don't have a script and hence cannot set line and col positions.
DCHECK(!fun->shared()->script()->IsScript());
return stack_frame;
}
Handle<JSObject> NewStackFrameObject(
const FrameSummary::WasmFrameSummary& summ) { const FrameSummary::WasmFrameSummary& summ) {
Handle<JSObject> stack_frame = Handle<StackFrameInfo> info = factory()->NewStackFrameInfo();
factory()->NewJSObject(isolate_->object_function());
if (!function_key_.is_null()) { if (options_ & StackTrace::kFunctionName) {
Handle<WasmCompiledModule> compiled_module( Handle<WasmCompiledModule> compiled_module(
summ.wasm_instance()->compiled_module(), isolate_); summ.wasm_instance()->compiled_module(), isolate_);
Handle<String> name = WasmCompiledModule::GetFunctionName( Handle<String> name = WasmCompiledModule::GetFunctionName(
isolate_, compiled_module, summ.function_index()); isolate_, compiled_module, summ.function_index());
JSObject::AddProperty(stack_frame, function_key_, name, NONE); info->set_function_name(*name);
} }
// Encode the function index as line number (1-based). // Encode the function index as line number (1-based).
if (!line_key_.is_null()) { if (options_ & StackTrace::kLineNumber) {
JSObject::AddProperty( info->set_line_number(summ.function_index() + 1);
stack_frame, line_key_,
isolate_->factory()->NewNumberFromInt(summ.function_index() + 1),
NONE);
} }
// Encode the byte offset as column (1-based). // Encode the byte offset as column (1-based).
if (!column_key_.is_null()) { if (options_ & StackTrace::kColumnOffset) {
int position = summ.byte_offset(); int position = summ.byte_offset();
// Make position 1-based. // Make position 1-based.
if (position >= 0) ++position; if (position >= 0) ++position;
JSObject::AddProperty(stack_frame, column_key_, info->set_column_number(position);
isolate_->factory()->NewNumberFromInt(position),
NONE);
} }
if (!script_id_key_.is_null()) { if (options_ & StackTrace::kScriptId) {
int script_id = summ.script()->id(); info->set_script_id(summ.script()->id());
JSObject::AddProperty(stack_frame, script_id_key_,
handle(Smi::FromInt(script_id), isolate_), NONE);
} }
return info;
return stack_frame;
} }
private: private:
inline Factory* factory() { return isolate_->factory(); } inline Factory* factory() { return isolate_->factory(); }
Isolate* isolate_; Isolate* isolate_;
Handle<String> column_key_; StackTrace::StackTraceOptions options_;
Handle<String> line_key_;
Handle<String> script_id_key_;
Handle<String> script_name_key_;
Handle<String> script_name_or_source_url_key_;
Handle<String> function_key_;
Handle<String> eval_key_;
Handle<String> constructor_key_;
}; };
Handle<JSArray> Isolate::CaptureCurrentStackTrace( Handle<JSArray> Isolate::CaptureCurrentStackTrace(
@ -803,7 +719,8 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
!this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) !this->context()->HasSameSecurityTokenAs(*frames[i].native_context()))
continue; continue;
Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]); Handle<StackFrameInfo> new_frame_obj =
helper.NewStackFrameObject(frames[i]);
stack_trace_elems->set(frames_seen, *new_frame_obj); stack_trace_elems->set(frames_seen, *new_frame_obj);
frames_seen++; frames_seen++;
} }

View File

@ -1302,6 +1302,13 @@ void BreakPointInfo::BreakPointInfoVerify() {
CHECK(IsBreakPointInfo()); CHECK(IsBreakPointInfo());
VerifyPointer(break_point_objects()); VerifyPointer(break_point_objects());
} }
void StackFrameInfo::StackFrameInfoVerify() {
CHECK(IsStackFrameInfo());
VerifyPointer(script_name());
VerifyPointer(script_name_or_source_url());
VerifyPointer(function_name());
}
#endif // VERIFY_HEAP #endif // VERIFY_HEAP
#ifdef DEBUG #ifdef DEBUG

View File

@ -5797,6 +5797,17 @@ Code* DebugInfo::DebugCode() {
SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex) SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex) ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
SMI_ACCESSORS(StackFrameInfo, line_number, kLineNumberIndex)
SMI_ACCESSORS(StackFrameInfo, column_number, kColumnNumberIndex)
SMI_ACCESSORS(StackFrameInfo, script_id, kScriptIdIndex)
ACCESSORS(StackFrameInfo, script_name, Object, kScriptNameIndex)
ACCESSORS(StackFrameInfo, script_name_or_source_url, Object,
kScriptNameOrSourceUrlIndex)
ACCESSORS(StackFrameInfo, function_name, Object, kFunctionNameIndex)
SMI_ACCESSORS(StackFrameInfo, flag, kFlagIndex)
BOOL_ACCESSORS(StackFrameInfo, flag, is_eval, kIsEvalBit)
BOOL_ACCESSORS(StackFrameInfo, flag, is_constructor, kIsConstructorBit)
ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset) ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
ACCESSORS(SharedFunctionInfo, optimized_code_map, FixedArray, ACCESSORS(SharedFunctionInfo, optimized_code_map, FixedArray,
kOptimizedCodeMapOffset) kOptimizedCodeMapOffset)

View File

@ -1472,6 +1472,19 @@ void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT
os << "\n"; os << "\n";
} }
void StackFrameInfo::StackFrameInfoPrint(std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "StackFrame");
os << "\n - line_number: " << line_number();
os << "\n - column_number: " << column_number();
os << "\n - script_id: " << script_id();
os << "\n - script_name: " << Brief(script_name());
os << "\n - script_name_or_source_url: "
<< Brief(script_name_or_source_url());
os << "\n - function_name: " << Brief(function_name());
os << "\n - is_eval: " << (is_eval() ? "true" : "false");
os << "\n - is_constructor: " << (is_constructor() ? "true" : "false");
os << "\n";
}
static void PrintBitMask(std::ostream& os, uint32_t value) { // NOLINT static void PrintBitMask(std::ostream& os, uint32_t value) { // NOLINT
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {

View File

@ -144,6 +144,7 @@
// - Script // - Script
// - DebugInfo // - DebugInfo
// - BreakPointInfo // - BreakPointInfo
// - StackFrameInfo
// - CodeCache // - CodeCache
// - PrototypeInfo // - PrototypeInfo
// - Module // - Module
@ -357,6 +358,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
V(PROMISE_REACTION_JOB_INFO_TYPE) \ V(PROMISE_REACTION_JOB_INFO_TYPE) \
V(DEBUG_INFO_TYPE) \ V(DEBUG_INFO_TYPE) \
V(BREAK_POINT_INFO_TYPE) \ V(BREAK_POINT_INFO_TYPE) \
V(STACK_FRAME_INFO_TYPE) \
V(PROTOTYPE_INFO_TYPE) \ V(PROTOTYPE_INFO_TYPE) \
V(TUPLE2_TYPE) \ V(TUPLE2_TYPE) \
V(TUPLE3_TYPE) \ V(TUPLE3_TYPE) \
@ -528,6 +530,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
promise_reaction_job_info) \ promise_reaction_job_info) \
V(DEBUG_INFO, DebugInfo, debug_info) \ V(DEBUG_INFO, DebugInfo, debug_info) \
V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \ V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \
V(STACK_FRAME_INFO, StackFrameInfo, stack_frame_info) \
V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \ V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
V(TUPLE2, Tuple2, tuple2) \ V(TUPLE2, Tuple2, tuple2) \
V(TUPLE3, Tuple3, tuple3) \ V(TUPLE3, Tuple3, tuple3) \
@ -699,6 +702,7 @@ enum InstanceType {
PROMISE_REACTION_JOB_INFO_TYPE, PROMISE_REACTION_JOB_INFO_TYPE,
DEBUG_INFO_TYPE, DEBUG_INFO_TYPE,
BREAK_POINT_INFO_TYPE, BREAK_POINT_INFO_TYPE,
STACK_FRAME_INFO_TYPE,
PROTOTYPE_INFO_TYPE, PROTOTYPE_INFO_TYPE,
TUPLE2_TYPE, TUPLE2_TYPE,
TUPLE3_TYPE, TUPLE3_TYPE,
@ -11283,6 +11287,42 @@ class BreakPointInfo: public Struct {
DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo); DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
}; };
class StackFrameInfo : public Struct {
public:
DECL_INT_ACCESSORS(line_number)
DECL_INT_ACCESSORS(column_number)
DECL_INT_ACCESSORS(script_id)
DECL_ACCESSORS(script_name, Object)
DECL_ACCESSORS(script_name_or_source_url, Object)
DECL_ACCESSORS(function_name, Object)
DECL_BOOLEAN_ACCESSORS(is_eval)
DECL_BOOLEAN_ACCESSORS(is_constructor)
DECL_INT_ACCESSORS(flag)
DECLARE_CAST(StackFrameInfo)
// Dispatched behavior.
DECLARE_PRINTER(StackFrameInfo)
DECLARE_VERIFIER(StackFrameInfo)
static const int kLineNumberIndex = Struct::kHeaderSize;
static const int kColumnNumberIndex = kLineNumberIndex + kPointerSize;
static const int kScriptIdIndex = kColumnNumberIndex + kPointerSize;
static const int kScriptNameIndex = kScriptIdIndex + kPointerSize;
static const int kScriptNameOrSourceUrlIndex =
kScriptNameIndex + kPointerSize;
static const int kFunctionNameIndex =
kScriptNameOrSourceUrlIndex + kPointerSize;
static const int kFlagIndex = kFunctionNameIndex + kPointerSize;
static const int kSize = kFlagIndex + kPointerSize;
private:
// Bit position in the flag, from least significant bit position.
static const int kIsEvalBit = 0;
static const int kIsConstructorBit = 1;
DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrameInfo);
};
#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \ #define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
V(kStringTable, "string_table", "(Internalized strings)") \ V(kStringTable, "string_table", "(Internalized strings)") \

View File

@ -103,19 +103,10 @@ Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset,
Handle<FixedArray> stack_elements( Handle<FixedArray> stack_elements(
FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements())); FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements()));
DCHECK_GE(stack_elements->length(), 1); DCHECK_GE(stack_elements->length(), 1);
Handle<JSObject> top_frame(JSObject::cast(stack_elements->get(0))); Handle<StackFrameInfo> top_frame(
Handle<String> wasm_offset_key = StackFrameInfo::cast(stack_elements->get(0)));
isolate->factory()->InternalizeOneByteString( if (top_frame->column_number()) {
STATIC_CHAR_VECTOR("column")); top_frame->set_column_number(byte_offset + 1);
LookupIterator it(top_frame, wasm_offset_key, top_frame,
LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
if (it.IsFound()) {
DCHECK(JSReceiver::GetDataProperty(&it)->IsSmi());
// Make column number 1-based here.
Maybe<bool> data_set = JSReceiver::SetDataProperty(
&it, handle(Smi::FromInt(byte_offset + 1), isolate));
DCHECK(data_set.IsJust() && data_set.FromJust() == true);
USE(data_set);
} }
} }