[wasm] Move {WasmModuleObject::GetContainingFunction}.

This introduces {GetContainingWasmFunction} to replace the above method,
since calculating offsets into the wire bytes is independent of the
concrete module object and hence only needs the shared decoded module.

R=clemensh@chromium.org
BUG=v8:6847

Change-Id: I145d527506289686653979dbb135480cc42ea4c8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1809369
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63870}
This commit is contained in:
Michael Starzinger 2019-09-18 15:29:02 +02:00 committed by Commit Bot
parent 33b5ca20d8
commit e6f8d122f3
5 changed files with 57 additions and 64 deletions

View File

@ -4656,8 +4656,26 @@ bool Script::GetPositionInfo(int position, PositionInfo* info,
// directly.
if (type() == Script::TYPE_WASM) {
DCHECK_LE(0, position);
return WasmModuleObject::cast(wasm_module_object())
.GetPositionInfo(static_cast<uint32_t>(position), info);
wasm::NativeModule* native_module = wasm_native_module();
const wasm::WasmModule* module = native_module->module();
if (source_mapping_url().IsString()) {
if (module->functions.size() == 0) return false;
info->line = 0;
info->column = position;
info->line_start = module->functions[0].code.offset();
info->line_end = module->functions.back().code.end_offset();
return true;
}
int func_index = GetContainingWasmFunction(module, position);
if (func_index < 0) return false;
const wasm::WasmFunction& function = module->functions[func_index];
info->line = func_index;
info->column = position - function.code.offset();
info->line_start = function.code.offset();
info->line_end = function.code.end_offset();
return true;
}
if (line_ends().IsUndefined()) {

View File

@ -67,6 +67,32 @@ int GetWasmFunctionOffset(const WasmModule* module, uint32_t func_index) {
return static_cast<int>(functions[func_index].code.offset());
}
// static
int GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset) {
const std::vector<WasmFunction>& functions = module->functions;
// Binary search for a function containing the given position.
int left = 0; // inclusive
int right = static_cast<int>(functions.size()); // exclusive
if (right == 0) return false;
while (right - left > 1) {
int mid = left + (right - left) / 2;
if (functions[mid].code.offset() <= byte_offset) {
left = mid;
} else {
right = mid;
}
}
// If the found function does not contains the given position, return -1.
const WasmFunction& func = functions[left];
if (byte_offset < func.code.offset() ||
byte_offset >= func.code.end_offset()) {
return -1;
}
return left;
}
// static
v8::debug::WasmDisassembly DisassembleWasmFunction(
const WasmModule* module, const ModuleWireBytes& wire_bytes,

View File

@ -250,6 +250,11 @@ int GetExportWrapperIndex(const WasmModule* module, const FunctionSig* sig,
// Returns -1 if the function index is invalid.
int GetWasmFunctionOffset(const WasmModule* module, uint32_t func_index);
// Returns the function containing the given byte offset.
// Returns -1 if the byte offset is not contained in any function of this
// module.
int GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset);
// Compute the disassembly of a wasm function.
// Returns the disassembly string and a list of <byte_offset, line, column>
// entries, mapping wasm byte offsets to line and column in the disassembly.

View File

@ -258,9 +258,10 @@ bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object,
Isolate* isolate = module_object->GetIsolate();
// Find the function for this breakpoint.
int func_index = module_object->GetContainingFunction(*position);
const WasmModule* module = module_object->module();
int func_index = GetContainingWasmFunction(module, *position);
if (func_index < 0) return false;
const WasmFunction& func = module_object->module()->functions[func_index];
const WasmFunction& func = module->functions[func_index];
int offset_in_func = *position - func.code.offset();
// According to the current design, we should only be called with valid
@ -403,9 +404,10 @@ void WasmModuleObject::SetBreakpointsOnNewInstance(
int position = breakpoint_info->source_position();
// Find the function for this breakpoint, and set the breakpoint.
int func_index = module_object->GetContainingFunction(position);
const WasmModule* module = module_object->module();
int func_index = GetContainingWasmFunction(module, position);
DCHECK_LE(0, func_index);
const WasmFunction& func = module_object->module()->functions[func_index];
const WasmFunction& func = module->functions[func_index];
int offset_in_func = position - func.code.offset();
WasmDebugInfo::SetBreakpoint(debug_info, func_index, offset_in_func);
}
@ -689,53 +691,6 @@ Vector<const uint8_t> WasmModuleObject::GetRawFunctionName(
return Vector<const uint8_t>::cast(name);
}
int WasmModuleObject::GetContainingFunction(uint32_t byte_offset) {
const std::vector<WasmFunction>& functions = module()->functions;
// Binary search for a function containing the given position.
int left = 0; // inclusive
int right = static_cast<int>(functions.size()); // exclusive
if (right == 0) return false;
while (right - left > 1) {
int mid = left + (right - left) / 2;
if (functions[mid].code.offset() <= byte_offset) {
left = mid;
} else {
right = mid;
}
}
// If the found function does not contains the given position, return -1.
const WasmFunction& func = functions[left];
if (byte_offset < func.code.offset() ||
byte_offset >= func.code.end_offset()) {
return -1;
}
return left;
}
bool WasmModuleObject::GetPositionInfo(uint32_t position,
Script::PositionInfo* info) {
if (script().source_mapping_url().IsString()) {
if (module()->functions.size() == 0) return false;
info->line = 0;
info->column = position;
info->line_start = module()->functions[0].code.offset();
info->line_end = module()->functions.back().code.end_offset();
return true;
}
int func_index = GetContainingFunction(position);
if (func_index < 0) return false;
const WasmFunction& function = module()->functions[func_index];
info->line = func_index;
info->column = position - function.code.offset();
info->line_start = function.code.offset();
info->line_end = function.code.end_offset();
return true;
}
Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate,
wasm::ValueType type,
uint32_t initial, bool has_maximum,

View File

@ -12,7 +12,6 @@
#include "src/debug/debug.h"
#include "src/heap/heap.h"
#include "src/objects/objects.h"
#include "src/objects/script.h"
#include "src/wasm/value-type.h"
// Has to be the last include (doesn't have include guards)
@ -198,16 +197,6 @@ class WasmModuleObject : public JSObject {
// Does not allocate, hence gc-safe.
Vector<const uint8_t> GetRawFunctionName(uint32_t func_index);
// Returns the function containing the given byte offset.
// Returns -1 if the byte offset is not contained in any function of this
// module.
int GetContainingFunction(uint32_t byte_offset);
// Translate from byte offset in the module to function number and byte offset
// within that function, encoded as line and column in the position info.
// Returns true if the position is valid inside this module, false otherwise.
bool GetPositionInfo(uint32_t position, Script::PositionInfo* info);
// Get the source position from a given function index and byte offset,
// for either asm.js or pure Wasm modules.
static int GetSourcePosition(Handle<WasmModuleObject>, uint32_t func_index,