[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:
parent
32d4d8e93d
commit
dc662e5b74
@ -8646,8 +8646,8 @@ class Internals {
|
||||
static const int kNodeIsIndependentShift = 3;
|
||||
static const int kNodeIsActiveShift = 4;
|
||||
|
||||
static const int kJSApiObjectType = 0xba;
|
||||
static const int kJSObjectType = 0xbb;
|
||||
static const int kJSApiObjectType = 0xbb;
|
||||
static const int kJSObjectType = 0xbc;
|
||||
static const int kFirstNonstringType = 0x80;
|
||||
static const int kOddballType = 0x82;
|
||||
static const int kForeignType = 0x86;
|
||||
|
74
src/api.cc
74
src/api.cc
@ -2846,8 +2846,8 @@ Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
|
||||
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
|
||||
auto self = Utils::OpenHandle(this);
|
||||
auto obj = i::JSReceiver::GetElement(isolate, self, index).ToHandleChecked();
|
||||
auto jsobj = i::Handle<i::JSObject>::cast(obj);
|
||||
return scope.Escape(Utils::StackFrameToLocal(jsobj));
|
||||
auto info = i::Handle<i::StackFrameInfo>::cast(obj);
|
||||
return scope.Escape(Utils::StackFrameToLocal(info));
|
||||
}
|
||||
|
||||
|
||||
@ -2875,77 +2875,59 @@ Local<StackTrace> StackTrace::CurrentStackTrace(
|
||||
|
||||
// --- 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 {
|
||||
return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
|
||||
int v = Utils::OpenHandle(this)->line_number();
|
||||
return v ? v : Message::kNoLineNumberInfo;
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
|
||||
int v = Utils::OpenHandle(this)->script_id();
|
||||
return v ? v : Message::kNoScriptIdInfo;
|
||||
}
|
||||
|
||||
|
||||
static Local<String> getStringProperty(const StackFrame* f,
|
||||
const char* propertyName) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
|
||||
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
|
||||
Local<String> StackFrame::GetScriptName() const {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
|
||||
i::Handle<i::JSObject> self = Utils::OpenHandle(f);
|
||||
i::Handle<i::Object> obj =
|
||||
i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
|
||||
i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
|
||||
i::Handle<i::Object> obj(self->script_name(), isolate);
|
||||
return obj->IsString()
|
||||
? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
|
||||
: Local<String>();
|
||||
}
|
||||
|
||||
|
||||
Local<String> StackFrame::GetScriptName() const {
|
||||
return getStringProperty(this, "scriptName");
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
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>();
|
||||
}
|
||||
|
||||
|
||||
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::IsEval() const { return Utils::OpenHandle(this)->is_eval(); }
|
||||
|
||||
bool StackFrame::IsConstructor() const {
|
||||
return getBoolProperty(this, "isConstructor");
|
||||
return Utils::OpenHandle(this)->is_constructor();
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,7 +106,7 @@ class RegisteredExtension {
|
||||
V(Context, Context) \
|
||||
V(External, Object) \
|
||||
V(StackTrace, JSArray) \
|
||||
V(StackFrame, JSObject) \
|
||||
V(StackFrame, StackFrameInfo) \
|
||||
V(Proxy, JSProxy) \
|
||||
V(NativeWeakMap, JSWeakMap) \
|
||||
V(debug::GeneratorObject, JSGeneratorObject) \
|
||||
@ -188,7 +188,7 @@ class Utils {
|
||||
static inline Local<StackTrace> StackTraceToLocal(
|
||||
v8::internal::Handle<v8::internal::JSArray> obj);
|
||||
static inline Local<StackFrame> StackFrameToLocal(
|
||||
v8::internal::Handle<v8::internal::JSObject> obj);
|
||||
v8::internal::Handle<v8::internal::StackFrameInfo> obj);
|
||||
static inline Local<Number> NumberToLocal(
|
||||
v8::internal::Handle<v8::internal::Object> obj);
|
||||
static inline Local<Integer> IntegerToLocal(
|
||||
@ -318,7 +318,7 @@ MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
|
||||
MAKE_TO_LOCAL(MessageToLocal, Object, Message)
|
||||
MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise)
|
||||
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(IntegerToLocal, Object, Integer)
|
||||
MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
|
||||
|
@ -312,6 +312,7 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
|
||||
case ALIASED_ARGUMENTS_ENTRY_TYPE:
|
||||
case DEBUG_INFO_TYPE:
|
||||
case BREAK_POINT_INFO_TYPE:
|
||||
case STACK_FRAME_INFO_TYPE:
|
||||
case CELL_TYPE:
|
||||
case WEAK_CELL_TYPE:
|
||||
case PROTOTYPE_INFO_TYPE:
|
||||
|
@ -320,6 +320,7 @@ Type::bitset BitsetType::Lub(i::Map* map) {
|
||||
case PROMISE_REACTION_JOB_INFO_TYPE:
|
||||
case DEBUG_INFO_TYPE:
|
||||
case BREAK_POINT_INFO_TYPE:
|
||||
case STACK_FRAME_INFO_TYPE:
|
||||
case CELL_TYPE:
|
||||
case WEAK_CELL_TYPE:
|
||||
case PROTOTYPE_INFO_TYPE:
|
||||
|
@ -4203,6 +4203,7 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
|
||||
case PROMISE_REACTION_JOB_INFO_TYPE:
|
||||
case DEBUG_INFO_TYPE:
|
||||
case BREAK_POINT_INFO_TYPE:
|
||||
case STACK_FRAME_INFO_TYPE:
|
||||
case CELL_TYPE:
|
||||
case WEAK_CELL_TYPE:
|
||||
case PROTOTYPE_INFO_TYPE:
|
||||
|
@ -2592,6 +2592,19 @@ Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
|
||||
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,
|
||||
int length) {
|
||||
bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||
|
||||
|
@ -321,6 +321,7 @@ class V8_EXPORT_PRIVATE Factory final {
|
||||
Handle<Script> NewScript(Handle<String> source);
|
||||
|
||||
Handle<BreakPointInfo> NewBreakPointInfo(int source_position);
|
||||
Handle<StackFrameInfo> NewStackFrameInfo();
|
||||
|
||||
// Foreign objects are pretenured when allocated by the bootstrapper.
|
||||
Handle<Foreign> NewForeign(Address addr,
|
||||
|
161
src/isolate.cc
161
src/isolate.cc
@ -614,169 +614,85 @@ class CaptureStackTraceHelper {
|
||||
public:
|
||||
CaptureStackTraceHelper(Isolate* isolate,
|
||||
StackTrace::StackTraceOptions options)
|
||||
: isolate_(isolate) {
|
||||
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"));
|
||||
}
|
||||
}
|
||||
: isolate_(isolate), options_(options) {}
|
||||
|
||||
Handle<JSObject> NewStackFrameObject(FrameSummary& summ) {
|
||||
Handle<StackFrameInfo> NewStackFrameObject(FrameSummary& summ) {
|
||||
if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript());
|
||||
if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm());
|
||||
UNREACHABLE();
|
||||
return Handle<JSObject>::null();
|
||||
return factory()->NewStackFrameInfo();
|
||||
}
|
||||
|
||||
Handle<JSObject> NewStackFrameObject(
|
||||
Handle<StackFrameInfo> NewStackFrameObject(
|
||||
const FrameSummary::JavaScriptFrameSummary& summ) {
|
||||
Handle<JSObject> stack_frame =
|
||||
factory()->NewJSObject(isolate_->object_function());
|
||||
Handle<StackFrameInfo> frame = factory()->NewStackFrameInfo();
|
||||
Handle<Script> script = Handle<Script>::cast(summ.script());
|
||||
|
||||
if (!line_key_.is_null()) {
|
||||
if (options_ & StackTrace::kLineNumber) {
|
||||
Script::PositionInfo info;
|
||||
bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(),
|
||||
&info, Script::WITH_OFFSET);
|
||||
|
||||
if (!column_key_.is_null() && valid_pos) {
|
||||
JSObject::AddProperty(stack_frame, column_key_,
|
||||
handle(Smi::FromInt(info.column + 1), isolate_),
|
||||
NONE);
|
||||
if (valid_pos) {
|
||||
frame->set_line_number(info.line + 1);
|
||||
if (options_ & StackTrace::kColumnOffset) {
|
||||
frame->set_column_number(info.column + 1);
|
||||
}
|
||||
}
|
||||
JSObject::AddProperty(stack_frame, line_key_,
|
||||
handle(Smi::FromInt(info.line + 1), isolate_),
|
||||
NONE);
|
||||
}
|
||||
|
||||
if (!script_id_key_.is_null()) {
|
||||
JSObject::AddProperty(stack_frame, script_id_key_,
|
||||
handle(Smi::FromInt(script->id()), isolate_), NONE);
|
||||
if (options_ & StackTrace::kScriptId) frame->set_script_id(script->id());
|
||||
if (options_ & StackTrace::kScriptName) {
|
||||
frame->set_script_name(script->name());
|
||||
}
|
||||
|
||||
if (!script_name_key_.is_null()) {
|
||||
JSObject::AddProperty(stack_frame, script_name_key_,
|
||||
handle(script->name(), isolate_), NONE);
|
||||
if (options_ & StackTrace::kScriptNameOrSourceURL) {
|
||||
frame->set_script_name_or_source_url(script->GetNameOrSourceURL());
|
||||
}
|
||||
|
||||
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 (options_ & StackTrace::kIsEval) {
|
||||
frame->set_is_eval(script->compilation_type() ==
|
||||
Script::COMPILATION_TYPE_EVAL);
|
||||
}
|
||||
|
||||
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 (options_ & StackTrace::kFunctionName) {
|
||||
Handle<String> name = summ.FunctionName();
|
||||
frame->set_function_name(*name);
|
||||
}
|
||||
|
||||
if (!function_key_.is_null()) {
|
||||
Handle<String> fun_name = summ.FunctionName();
|
||||
JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
|
||||
if (options_ & StackTrace::kIsConstructor) {
|
||||
frame->set_is_constructor(summ.is_constructor());
|
||||
}
|
||||
|
||||
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;
|
||||
return 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(
|
||||
Handle<StackFrameInfo> NewStackFrameObject(
|
||||
const FrameSummary::WasmFrameSummary& summ) {
|
||||
Handle<JSObject> stack_frame =
|
||||
factory()->NewJSObject(isolate_->object_function());
|
||||
Handle<StackFrameInfo> info = factory()->NewStackFrameInfo();
|
||||
|
||||
if (!function_key_.is_null()) {
|
||||
if (options_ & StackTrace::kFunctionName) {
|
||||
Handle<WasmCompiledModule> compiled_module(
|
||||
summ.wasm_instance()->compiled_module(), isolate_);
|
||||
Handle<String> name = WasmCompiledModule::GetFunctionName(
|
||||
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).
|
||||
if (!line_key_.is_null()) {
|
||||
JSObject::AddProperty(
|
||||
stack_frame, line_key_,
|
||||
isolate_->factory()->NewNumberFromInt(summ.function_index() + 1),
|
||||
NONE);
|
||||
if (options_ & StackTrace::kLineNumber) {
|
||||
info->set_line_number(summ.function_index() + 1);
|
||||
}
|
||||
// Encode the byte offset as column (1-based).
|
||||
if (!column_key_.is_null()) {
|
||||
if (options_ & StackTrace::kColumnOffset) {
|
||||
int position = summ.byte_offset();
|
||||
// Make position 1-based.
|
||||
if (position >= 0) ++position;
|
||||
JSObject::AddProperty(stack_frame, column_key_,
|
||||
isolate_->factory()->NewNumberFromInt(position),
|
||||
NONE);
|
||||
info->set_column_number(position);
|
||||
}
|
||||
if (!script_id_key_.is_null()) {
|
||||
int script_id = summ.script()->id();
|
||||
JSObject::AddProperty(stack_frame, script_id_key_,
|
||||
handle(Smi::FromInt(script_id), isolate_), NONE);
|
||||
if (options_ & StackTrace::kScriptId) {
|
||||
info->set_script_id(summ.script()->id());
|
||||
}
|
||||
|
||||
return stack_frame;
|
||||
return info;
|
||||
}
|
||||
|
||||
private:
|
||||
inline Factory* factory() { return isolate_->factory(); }
|
||||
|
||||
Isolate* isolate_;
|
||||
Handle<String> column_key_;
|
||||
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_;
|
||||
StackTrace::StackTraceOptions options_;
|
||||
};
|
||||
|
||||
Handle<JSArray> Isolate::CaptureCurrentStackTrace(
|
||||
@ -803,7 +719,8 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
|
||||
if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
|
||||
!this->context()->HasSameSecurityTokenAs(*frames[i].native_context()))
|
||||
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);
|
||||
frames_seen++;
|
||||
}
|
||||
|
@ -1302,6 +1302,13 @@ void BreakPointInfo::BreakPointInfoVerify() {
|
||||
CHECK(IsBreakPointInfo());
|
||||
VerifyPointer(break_point_objects());
|
||||
}
|
||||
|
||||
void StackFrameInfo::StackFrameInfoVerify() {
|
||||
CHECK(IsStackFrameInfo());
|
||||
VerifyPointer(script_name());
|
||||
VerifyPointer(script_name_or_source_url());
|
||||
VerifyPointer(function_name());
|
||||
}
|
||||
#endif // VERIFY_HEAP
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -5797,6 +5797,17 @@ Code* DebugInfo::DebugCode() {
|
||||
SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
|
||||
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, optimized_code_map, FixedArray,
|
||||
kOptimizedCodeMapOffset)
|
||||
|
@ -1472,6 +1472,19 @@ void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT
|
||||
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
|
||||
for (int i = 0; i < 32; i++) {
|
||||
|
@ -144,6 +144,7 @@
|
||||
// - Script
|
||||
// - DebugInfo
|
||||
// - BreakPointInfo
|
||||
// - StackFrameInfo
|
||||
// - CodeCache
|
||||
// - PrototypeInfo
|
||||
// - Module
|
||||
@ -357,6 +358,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(PROMISE_REACTION_JOB_INFO_TYPE) \
|
||||
V(DEBUG_INFO_TYPE) \
|
||||
V(BREAK_POINT_INFO_TYPE) \
|
||||
V(STACK_FRAME_INFO_TYPE) \
|
||||
V(PROTOTYPE_INFO_TYPE) \
|
||||
V(TUPLE2_TYPE) \
|
||||
V(TUPLE3_TYPE) \
|
||||
@ -528,6 +530,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
promise_reaction_job_info) \
|
||||
V(DEBUG_INFO, DebugInfo, debug_info) \
|
||||
V(BREAK_POINT_INFO, BreakPointInfo, break_point_info) \
|
||||
V(STACK_FRAME_INFO, StackFrameInfo, stack_frame_info) \
|
||||
V(PROTOTYPE_INFO, PrototypeInfo, prototype_info) \
|
||||
V(TUPLE2, Tuple2, tuple2) \
|
||||
V(TUPLE3, Tuple3, tuple3) \
|
||||
@ -699,6 +702,7 @@ enum InstanceType {
|
||||
PROMISE_REACTION_JOB_INFO_TYPE,
|
||||
DEBUG_INFO_TYPE,
|
||||
BREAK_POINT_INFO_TYPE,
|
||||
STACK_FRAME_INFO_TYPE,
|
||||
PROTOTYPE_INFO_TYPE,
|
||||
TUPLE2_TYPE,
|
||||
TUPLE3_TYPE,
|
||||
@ -11283,6 +11287,42 @@ class BreakPointInfo: public Struct {
|
||||
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) \
|
||||
V(kStringTable, "string_table", "(Internalized strings)") \
|
||||
|
@ -103,19 +103,10 @@ Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset,
|
||||
Handle<FixedArray> stack_elements(
|
||||
FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements()));
|
||||
DCHECK_GE(stack_elements->length(), 1);
|
||||
Handle<JSObject> top_frame(JSObject::cast(stack_elements->get(0)));
|
||||
Handle<String> wasm_offset_key =
|
||||
isolate->factory()->InternalizeOneByteString(
|
||||
STATIC_CHAR_VECTOR("column"));
|
||||
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);
|
||||
Handle<StackFrameInfo> top_frame(
|
||||
StackFrameInfo::cast(stack_elements->get(0)));
|
||||
if (top_frame->column_number()) {
|
||||
top_frame->set_column_number(byte_offset + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user