[wasm][debug] Fix location computation from interpreted frames

The {IsWasmFrame} check in {ComputeLocationFromStackTrace} only returned
true for compiled frames, but not for interpreted ones. Thus, for
interpreted frames we would run into the code for JS frames, which
assumes that a {JSFunction} is available.

This CL fixes this issue by renaming {IsWasmFrame} to
{IsWasmCompiledFrame}, and introducing a new {IsWasmFrame} method which
returns true for both compiled and interpreted frames.

R=mstarzinger@chromium.org

Bug: chromium:1018227
Change-Id: If83b4129edaad775a212ccb741f3c62eabc2addb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1883892
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64607}
This commit is contained in:
Clemens Backes 2019-10-28 16:40:21 +01:00 committed by Commit Bot
parent 61971c0b7a
commit 700f9b0ea6
5 changed files with 26 additions and 15 deletions

View File

@ -677,7 +677,7 @@ class FrameArrayBuilder {
flags |= FrameArray::kAsmJsAtNumberConversion; flags |= FrameArray::kAsmJsAtNumberConversion;
} }
} else { } else {
flags |= FrameArray::kIsWasmFrame; flags |= FrameArray::kIsWasmCompiledFrame;
} }
elements_ = FrameArray::AppendWasmFrame( elements_ = FrameArray::AppendWasmFrame(
@ -2136,20 +2136,21 @@ bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
Handle<WasmInstanceObject> instance(elements->WasmInstance(i), this); Handle<WasmInstanceObject> instance(elements->WasmInstance(i), this);
uint32_t func_index = uint32_t func_index =
static_cast<uint32_t>(elements->WasmFunctionIndex(i).value()); static_cast<uint32_t>(elements->WasmFunctionIndex(i).value());
int code_offset = elements->Offset(i).value(); int offset = elements->Offset(i).value();
bool is_at_number_conversion = bool is_at_number_conversion =
elements->IsAsmJsWasmFrame(i) && elements->IsAsmJsWasmFrame(i) &&
elements->Flags(i).value() & FrameArray::kAsmJsAtNumberConversion; elements->Flags(i).value() & FrameArray::kAsmJsAtNumberConversion;
// WasmCode* held alive by the {GlobalWasmCodeRef}. if (elements->IsWasmCompiledFrame(i)) {
wasm::WasmCode* code = // WasmCode* held alive by the {GlobalWasmCodeRef}.
Managed<wasm::GlobalWasmCodeRef>::cast(elements->WasmCodeObject(i)) wasm::WasmCode* code =
.get() Managed<wasm::GlobalWasmCodeRef>::cast(elements->WasmCodeObject(i))
->code(); .get()
int byte_offset = ->code();
FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition( offset = FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
code, code_offset); code, offset);
}
int pos = WasmModuleObject::GetSourcePosition( int pos = WasmModuleObject::GetSourcePosition(
handle(instance->module_object(), this), func_index, byte_offset, handle(instance->module_object(), this), func_index, offset,
is_at_number_conversion); is_at_number_conversion);
Handle<Script> script(instance->module_object().script(), this); Handle<Script> script(instance->module_object().script(), this);

View File

@ -687,7 +687,7 @@ void FrameArrayIterator::Advance() { frame_ix_++; }
StackFrameBase* FrameArrayIterator::Frame() { StackFrameBase* FrameArrayIterator::Frame() {
DCHECK(HasFrame()); DCHECK(HasFrame());
const int flags = array_->Flags(frame_ix_).value(); const int flags = array_->Flags(frame_ix_).value();
int flag_mask = FrameArray::kIsWasmFrame | int flag_mask = FrameArray::kIsWasmCompiledFrame |
FrameArray::kIsWasmInterpretedFrame | FrameArray::kIsWasmInterpretedFrame |
FrameArray::kIsAsmJsWasmFrame; FrameArray::kIsAsmJsWasmFrame;
switch (flags & flag_mask) { switch (flags & flag_mask) {
@ -695,7 +695,7 @@ StackFrameBase* FrameArrayIterator::Frame() {
// JavaScript Frame. // JavaScript Frame.
js_frame_.FromFrameArray(isolate_, array_, frame_ix_); js_frame_.FromFrameArray(isolate_, array_, frame_ix_);
return &js_frame_; return &js_frame_;
case FrameArray::kIsWasmFrame: case FrameArray::kIsWasmCompiledFrame:
case FrameArray::kIsWasmInterpretedFrame: case FrameArray::kIsWasmInterpretedFrame:
// Wasm Frame: // Wasm Frame:
wasm_frame_.FromFrameArray(isolate_, array_, frame_ix_); wasm_frame_.FromFrameArray(isolate_, array_, frame_ix_);

View File

@ -33,8 +33,12 @@ FRAME_ARRAY_FIELD_LIST(DEFINE_FRAME_ARRAY_ACCESSORS)
#undef DEFINE_FRAME_ARRAY_ACCESSORS #undef DEFINE_FRAME_ARRAY_ACCESSORS
bool FrameArray::IsWasmFrame(int frame_ix) const { bool FrameArray::IsWasmFrame(int frame_ix) const {
return IsWasmCompiledFrame(frame_ix) || IsWasmInterpretedFrame(frame_ix);
}
bool FrameArray::IsWasmCompiledFrame(int frame_ix) const {
const int flags = Flags(frame_ix).value(); const int flags = Flags(frame_ix).value();
return (flags & kIsWasmFrame) != 0; return (flags & kIsWasmCompiledFrame) != 0;
} }
bool FrameArray::IsWasmInterpretedFrame(int frame_ix) const { bool FrameArray::IsWasmInterpretedFrame(int frame_ix) const {

View File

@ -38,6 +38,7 @@ class FrameArray : public FixedArray {
#undef DECL_FRAME_ARRAY_ACCESSORS #undef DECL_FRAME_ARRAY_ACCESSORS
inline bool IsWasmFrame(int frame_ix) const; inline bool IsWasmFrame(int frame_ix) const;
inline bool IsWasmCompiledFrame(int frame_ix) const;
inline bool IsWasmInterpretedFrame(int frame_ix) const; inline bool IsWasmInterpretedFrame(int frame_ix) const;
inline bool IsAsmJsWasmFrame(int frame_ix) const; inline bool IsAsmJsWasmFrame(int frame_ix) const;
inline bool IsAnyWasmFrame(int frame_ix) const; inline bool IsAnyWasmFrame(int frame_ix) const;
@ -47,7 +48,7 @@ class FrameArray : public FixedArray {
// Flags. // Flags.
enum Flag { enum Flag {
kIsWasmFrame = 1 << 0, kIsWasmCompiledFrame = 1 << 0,
kIsWasmInterpretedFrame = 1 << 1, kIsWasmInterpretedFrame = 1 << 1,
kIsAsmJsWasmFrame = 1 << 2, kIsAsmJsWasmFrame = 1 << 2,
kIsStrict = 1 << 3, kIsStrict = 1 << 3,

View File

@ -4145,6 +4145,11 @@ Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
Handle<FrameArray> FrameArray::AppendWasmFrame( Handle<FrameArray> FrameArray::AppendWasmFrame(
Handle<FrameArray> in, Handle<WasmInstanceObject> wasm_instance, Handle<FrameArray> in, Handle<WasmInstanceObject> wasm_instance,
int wasm_function_index, wasm::WasmCode* code, int offset, int flags) { int wasm_function_index, wasm::WasmCode* code, int offset, int flags) {
// This must be either a compiled or interpreted wasm frame, or an asm.js
// frame (which is always compiled).
DCHECK_EQ(1, ((flags & kIsWasmInterpretedFrame) != 0) +
((flags & kIsWasmCompiledFrame) != 0) +
((flags & kIsAsmJsWasmFrame) != 0));
Isolate* isolate = wasm_instance->GetIsolate(); Isolate* isolate = wasm_instance->GetIsolate();
const int frame_count = in->FrameCount(); const int frame_count = in->FrameCount();
const int new_length = LengthFor(frame_count + 1); const int new_length = LengthFor(frame_count + 1);