Commit 171d9411 authored by Arnaud Robin's avatar Arnaud Robin Committed by Commit Bot

[wasm] Add return value to the tracing of function calls

Added return value display when tracing function calls in wasm.
The new types handled are I32, I64, F32 and F64.
Only single return value is handled.

R=clemensb@chromium.org

Bug: v8:10559
Change-Id: I726d08fcfdc8bf2c3e43a25ec1932412ff74387b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2225024Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Arnaud Robin <arobin@google.com>
Cr-Commit-Position: refs/heads/master@{#68143}
parent a9b7830d
...@@ -22,6 +22,7 @@ extern runtime WasmStackGuard(Context): JSAny; ...@@ -22,6 +22,7 @@ extern runtime WasmStackGuard(Context): JSAny;
extern runtime ThrowWasmStackOverflow(Context): JSAny; extern runtime ThrowWasmStackOverflow(Context): JSAny;
extern runtime WasmTraceMemory(Context, Smi): JSAny; extern runtime WasmTraceMemory(Context, Smi): JSAny;
extern runtime WasmTraceEnter(Context): JSAny; extern runtime WasmTraceEnter(Context): JSAny;
extern runtime WasmTraceExit(Context, Smi): JSAny;
extern runtime WasmAtomicNotify( extern runtime WasmAtomicNotify(
Context, WasmInstanceObject, Number, Number): Smi; Context, WasmInstanceObject, Number, Number): Smi;
extern runtime WasmI32AtomicWait( extern runtime WasmI32AtomicWait(
...@@ -215,6 +216,10 @@ builtin WasmTraceEnter(): JSAny { ...@@ -215,6 +216,10 @@ builtin WasmTraceEnter(): JSAny {
tail runtime::WasmTraceEnter(LoadContextFromFrame()); tail runtime::WasmTraceEnter(LoadContextFromFrame());
} }
builtin WasmTraceExit(info: Smi): JSAny {
tail runtime::WasmTraceExit(LoadContextFromFrame(), info);
}
builtin WasmAllocateJSArray(implicit context: Context)(size: Smi): JSArray { builtin WasmAllocateJSArray(implicit context: Context)(size: Smi): JSArray {
const map: Map = GetFastPackedElementsJSArrayMap(); const map: Map = GetFastPackedElementsJSArrayMap();
return AllocateJSArray(ElementsKind::PACKED_ELEMENTS, map, size, size); return AllocateJSArray(ElementsKind::PACKED_ELEMENTS, map, size, size);
......
...@@ -950,11 +950,65 @@ RUNTIME_FUNCTION(Runtime_TraceExit) { ...@@ -950,11 +950,65 @@ RUNTIME_FUNCTION(Runtime_TraceExit) {
RUNTIME_FUNCTION(Runtime_WasmTraceEnter) { RUNTIME_FUNCTION(Runtime_WasmTraceEnter) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length()); DCHECK_EQ(0, args.length());
// TODO(10559): Print more useful info here. // TODO(10559): Print function name and indentation.
PrintF("Enter function\n"); PrintF("Enter function\n");
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
RUNTIME_FUNCTION(Runtime_WasmTraceExit) {
HandleScope shs(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_CHECKED(Smi, value_addr_smi, 0);
// TODO(10559): Print function name and indentation.
PrintF("Exit function");
// Find the caller wasm frame.
wasm::WasmCodeRefScope wasm_code_ref_scope;
StackTraceFrameIterator it(isolate);
DCHECK(!it.done());
DCHECK(it.is_wasm());
WasmFrame* frame = WasmFrame::cast(it.frame());
int func_index = frame->function_index();
const wasm::FunctionSig* sig =
frame->wasm_instance().module()->functions[func_index].sig;
size_t num_returns = sig->return_count();
if (num_returns == 1) {
wasm::ValueType return_type = sig->GetReturn(0);
switch (return_type.kind()) {
case wasm::ValueType::kI32: {
int32_t value = ReadUnalignedValue<int32_t>(value_addr_smi.ptr());
PrintF(" -> %d\n", value);
break;
}
case wasm::ValueType::kI64: {
int64_t value = ReadUnalignedValue<int64_t>(value_addr_smi.ptr());
PrintF(" -> %" PRId64 "\n", value);
break;
}
case wasm::ValueType::kF32: {
float_t value = ReadUnalignedValue<float_t>(value_addr_smi.ptr());
PrintF(" -> %f\n", value);
break;
}
case wasm::ValueType::kF64: {
double_t value = ReadUnalignedValue<double_t>(value_addr_smi.ptr());
PrintF(" -> %f\n", value);
break;
}
default:
PrintF(" -> Unsupported type\n");
break;
}
} else {
// TODO(wasm) Handle multiple return values.
PrintF("\n");
}
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_HaveSameMap) { RUNTIME_FUNCTION(Runtime_HaveSameMap) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK_EQ(2, args.length()); DCHECK_EQ(2, args.length());
......
...@@ -543,6 +543,7 @@ namespace internal { ...@@ -543,6 +543,7 @@ namespace internal {
F(WasmTierUpFunction, 2, 1) \ F(WasmTierUpFunction, 2, 1) \
F(WasmTierUpModule, 1, 1) \ F(WasmTierUpModule, 1, 1) \
F(WasmTraceEnter, 0, 1) \ F(WasmTraceEnter, 0, 1) \
F(WasmTraceExit, 1, 1) \
F(WasmTraceMemory, 1, 1) \ F(WasmTraceMemory, 1, 1) \
I(DeoptimizeNow, 0, 1) I(DeoptimizeNow, 0, 1)
......
...@@ -284,6 +284,8 @@ class LiftoffAssembler : public TurboAssembler { ...@@ -284,6 +284,8 @@ class LiftoffAssembler : public TurboAssembler {
explicit LiftoffAssembler(std::unique_ptr<AssemblerBuffer>); explicit LiftoffAssembler(std::unique_ptr<AssemblerBuffer>);
~LiftoffAssembler() override; ~LiftoffAssembler() override;
LiftoffRegister LoadToRegister(VarState slot, LiftoffRegList pinned);
LiftoffRegister PopToRegister(LiftoffRegList pinned = {}); LiftoffRegister PopToRegister(LiftoffRegList pinned = {});
// Returns the register which holds the value of stack slot {index}. If the // Returns the register which holds the value of stack slot {index}. If the
...@@ -1138,7 +1140,6 @@ class LiftoffAssembler : public TurboAssembler { ...@@ -1138,7 +1140,6 @@ class LiftoffAssembler : public TurboAssembler {
} }
private: private:
LiftoffRegister LoadToRegister(VarState slot, LiftoffRegList pinned);
LiftoffRegister LoadI64HalfIntoRegister(VarState slot, RegPairHalf half); LiftoffRegister LoadI64HalfIntoRegister(VarState slot, RegPairHalf half);
uint32_t num_locals_ = 0; uint32_t num_locals_ = 0;
......
...@@ -1545,7 +1545,45 @@ class LiftoffCompiler { ...@@ -1545,7 +1545,45 @@ class LiftoffCompiler {
__ cache_state()->stack_state.pop_back(); __ cache_state()->stack_state.pop_back();
} }
void TraceFunctionExit(FullDecoder* decoder) {
DEBUG_CODE_COMMENT("trace function exit");
// Before making the runtime call, spill all cache registers.
__ SpillAllRegisters();
LiftoffRegList pinned;
// Get a register to hold the stack slot for the return value.
LiftoffRegister info = pinned.set(__ GetUnusedRegister(kGpReg, pinned));
__ AllocateStackSlot(info.gp(), sizeof(int64_t));
// Store the return value if there is exactly one. Multiple return values
// are not handled yet.
size_t num_returns = decoder->sig_->return_count();
if (num_returns == 1) {
ValueType return_type = decoder->sig_->GetReturn(0);
LiftoffRegister return_reg =
__ LoadToRegister(__ cache_state()->stack_state.back(), pinned);
__ Store(info.gp(), no_reg, 0, return_reg,
StoreType::ForValueType(return_type), pinned);
}
// Put the parameter in its place.
WasmTraceExitDescriptor descriptor;
DCHECK_EQ(0, descriptor.GetStackParameterCount());
DCHECK_EQ(1, descriptor.GetRegisterParameterCount());
Register param_reg = descriptor.GetRegisterParameter(0);
if (info.gp() != param_reg) {
__ Move(param_reg, info.gp(), LiftoffAssembler::kWasmIntPtr);
}
source_position_table_builder_.AddPosition(
__ pc_offset(), SourcePosition(decoder->position()), false);
__ CallRuntimeStub(WasmCode::kWasmTraceExit);
safepoint_table_builder_.DefineSafepoint(&asm_, Safepoint::kNoLazyDeopt);
__ DeallocateStackSlot(sizeof(int64_t));
}
void ReturnImpl(FullDecoder* decoder) { void ReturnImpl(FullDecoder* decoder) {
if (FLAG_trace_wasm) TraceFunctionExit(decoder);
size_t num_returns = decoder->sig_->return_count(); size_t num_returns = decoder->sig_->return_count();
if (num_returns > 0) __ MoveToReturnLocations(decoder->sig_, descriptor_); if (num_returns > 0) __ MoveToReturnLocations(decoder->sig_, descriptor_);
DEBUG_CODE_COMMENT("leave frame"); DEBUG_CODE_COMMENT("leave frame");
......
...@@ -72,6 +72,7 @@ struct WasmModule; ...@@ -72,6 +72,7 @@ struct WasmModule;
V(WasmThrow) \ V(WasmThrow) \
V(WasmRethrow) \ V(WasmRethrow) \
V(WasmTraceEnter) \ V(WasmTraceEnter) \
V(WasmTraceExit) \
V(WasmTraceMemory) \ V(WasmTraceMemory) \
V(ArgumentsAdaptorTrampoline) \ V(ArgumentsAdaptorTrampoline) \
V(BigIntToI32Pair) \ V(BigIntToI32Pair) \
......
...@@ -11,8 +11,25 @@ let kRet23Function = builder.addFunction('ret_23', kSig_i_v) ...@@ -11,8 +11,25 @@ let kRet23Function = builder.addFunction('ret_23', kSig_i_v)
.addBody([kExprI32Const, 23]) .addBody([kExprI32Const, 23])
.exportFunc() .exportFunc()
.index; .index;
let kRet57Function = builder.addFunction('ret_57', kSig_l_v)
.addBody([kExprI64Const, 57])
.exportFunc()
.index;
let kRet0Function = builder.addFunction('ret_0', kSig_f_v)
.addBody(wasmF32Const(0))
.exportFunc()
.index;
let kRet1Function = builder.addFunction('ret_1', kSig_d_v)
.addBody(wasmF64Const(1))
.exportFunc()
.index;
builder.addFunction('main', kSig_v_v) builder.addFunction('main', kSig_v_v)
.addBody([kExprCallFunction, kRet23Function, kExprDrop]) .addBody([
kExprCallFunction, kRet23Function, kExprDrop, // -
kExprCallFunction, kRet57Function, kExprDrop, // -
kExprCallFunction, kRet0Function, kExprDrop, // -
kExprCallFunction, kRet1Function, kExprDrop // -
])
.exportAs('main'); .exportAs('main');
let instance = builder.instantiate(); let instance = builder.instantiate();
......
Enter function Enter function
Enter function Enter function
Exit function -> 23
Enter function
Exit function -> 57
Enter function
Exit function -> 0.000000
Enter function
Exit function -> 1.000000
Exit function
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment