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

View File

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

View File

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

View File

@ -4145,6 +4145,11 @@ Handle<FrameArray> FrameArray::AppendJSFrame(Handle<FrameArray> in,
Handle<FrameArray> FrameArray::AppendWasmFrame(
Handle<FrameArray> in, Handle<WasmInstanceObject> wasm_instance,
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();
const int frame_count = in->FrameCount();
const int new_length = LengthFor(frame_count + 1);