Commit 98966f56 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Refactor runtime functions for throw

We made two runtime calls: The first one allocated the exception object
containing a FixedArray of exception values, the second call did the
actual throw. Inbetween the code was filling the values array.
This CL refactors this to only allocate the FixedArray initially, fill
it, and then allocate the actual exception and throw it both from the
second runtime function.
This avoids a WasmGetOwnProperty call to find the values array.

R=thibaudm@chromium.org

Bug: v8:11453
Change-Id: I091aaa5c7bfb2b5579fc92c953adf582e6cc175a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2697359
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72811}
parent 5d618f1f
......@@ -16,7 +16,7 @@ extern runtime WasmFunctionTableGet(
extern runtime WasmFunctionTableSet(
Context, WasmInstanceObject, Smi, Smi, Object): JSAny;
extern runtime ThrowWasmError(Context, Smi): JSAny;
extern runtime WasmThrow(Context, Object): JSAny;
extern runtime WasmThrow(Context, Object, FixedArray): JSAny;
extern runtime WasmReThrow(Context, Object): JSAny;
extern runtime WasmTriggerTierUp(Context, WasmInstanceObject): JSAny;
extern runtime WasmStackGuard(Context): JSAny;
......@@ -192,8 +192,8 @@ builtin WasmRefFunc(index: uint32): Object {
}
}
builtin WasmThrow(exception: Object): JSAny {
tail runtime::WasmThrow(LoadContextFromFrame(), exception);
builtin WasmThrow(tag: Object, values: FixedArray): JSAny {
tail runtime::WasmThrow(LoadContextFromFrame(), tag, values);
}
builtin WasmRethrow(exception: Object): JSAny {
......
......@@ -2277,19 +2277,12 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index,
wasm::WasmCodePosition position) {
needs_stack_check_ = true;
uint32_t encoded_size = WasmExceptionPackage::GetEncodedSize(exception);
Node* create_parameters[] = {
LoadExceptionTagFromTable(exception_index),
BuildChangeUint31ToSmi(mcgraph()->Uint32Constant(encoded_size))};
Node* except_obj =
BuildCallToRuntime(Runtime::kWasmThrowCreate, create_parameters,
arraysize(create_parameters));
SetSourcePosition(except_obj, position);
Node* values_array = CALL_BUILTIN(
WasmGetOwnProperty, except_obj,
LOAD_FULL_POINTER(BuildLoadIsolateRoot(),
IsolateData::root_slot_offset(
RootIndex::kwasm_exception_values_symbol)),
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
Node* encoded_size_smi =
BuildChangeUint31ToSmi(mcgraph()->Uint32Constant(encoded_size));
Node* values_array = BuildCallToRuntime(
Runtime::kWasmCreateFixedArrayForThrow, &encoded_size_smi, 1);
SetSourcePosition(values_array, position);
uint32_t index = 0;
const wasm::WasmExceptionSig* sig = exception->sig;
MachineOperatorBuilder* m = mcgraph()->machine();
......@@ -2343,6 +2336,9 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index,
}
}
DCHECK_EQ(encoded_size, index);
Node* exception_tag = LoadExceptionTagFromTable(exception_index);
WasmThrowDescriptor interface_descriptor;
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), interface_descriptor,
......@@ -2350,9 +2346,8 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index,
Operator::kNoProperties, StubCallMode::kCallWasmRuntimeStub);
Node* call_target = mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmThrow, RelocInfo::WASM_STUB_CALL);
Node* call = SetEffectControl(
graph()->NewNode(mcgraph()->common()->Call(call_descriptor), call_target,
except_obj, effect(), control()));
Node* call =
gasm_->Call(call_descriptor, call_target, exception_tag, values_array);
SetSourcePosition(call, position);
return call;
}
......
......@@ -148,31 +148,16 @@ RUNTIME_FUNCTION(Runtime_WasmThrowJSTypeError) {
isolate, NewTypeError(MessageTemplate::kWasmTrapJSTypeError));
}
RUNTIME_FUNCTION(Runtime_WasmThrowCreate) {
RUNTIME_FUNCTION(Runtime_WasmCreateFixedArrayForThrow) {
ClearThreadInWasmScope clear_wasm_flag;
// TODO(kschimpf): Can this be replaced with equivalent TurboFan code/calls.
// TODO(wasm): Replace this by equivalent TurboFan code.
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
DCHECK_EQ(1, args.length());
DCHECK(isolate->context().is_null());
isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate));
CONVERT_ARG_CHECKED(WasmExceptionTag, tag_raw, 0);
CONVERT_SMI_ARG_CHECKED(size, 1);
// TODO(wasm): Manually box because parameters are not visited yet.
Handle<Object> tag(tag_raw, isolate);
Handle<Object> exception = isolate->factory()->NewWasmRuntimeError(
MessageTemplate::kWasmExceptionError);
CHECK(!Object::SetProperty(isolate, exception,
isolate->factory()->wasm_exception_tag_symbol(),
tag, StoreOrigin::kMaybeKeyed,
Just(ShouldThrow::kThrowOnError))
.is_null());
CONVERT_SMI_ARG_CHECKED(size, 0);
Handle<FixedArray> values = isolate->factory()->NewFixedArray(size);
CHECK(!Object::SetProperty(isolate, exception,
isolate->factory()->wasm_exception_values_symbol(),
values, StoreOrigin::kMaybeKeyed,
Just(ShouldThrow::kThrowOnError))
.is_null());
return *exception;
return *values;
}
RUNTIME_FUNCTION(Runtime_WasmThrow) {
......@@ -180,9 +165,29 @@ RUNTIME_FUNCTION(Runtime_WasmThrow) {
// is caught by a wasm frame, otherwise we keep it cleared.
trap_handler::ClearThreadInWasm();
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
DCHECK_EQ(2, args.length());
// The context is still set from WasmCreateFixedArrayForThrow.
DCHECK_EQ(isolate->context(),
GetNativeContextFromWasmInstanceOnStackTop(isolate));
CONVERT_ARG_CHECKED(WasmExceptionTag, tag_raw, 0);
CONVERT_ARG_CHECKED(FixedArray, values_raw, 1);
// TODO(wasm): Manually box because parameters are not visited yet.
Handle<WasmExceptionTag> tag(tag_raw, isolate);
Handle<FixedArray> values(values_raw, isolate);
Handle<Object> exception = isolate->factory()->NewWasmRuntimeError(
MessageTemplate::kWasmExceptionError);
Object::SetProperty(
isolate, exception, isolate->factory()->wasm_exception_tag_symbol(), tag,
StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError))
.Check();
Object::SetProperty(
isolate, exception, isolate->factory()->wasm_exception_values_symbol(),
values, StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError))
.Check();
isolate->wasm_engine()->SampleThrowEvent(isolate);
return isolate->Throw(args[0]);
return isolate->Throw(*exception);
}
RUNTIME_FUNCTION(Runtime_WasmReThrow) {
......
......@@ -571,30 +571,30 @@ namespace internal {
F(TypedArraySet, 2, 1) \
F(TypedArraySortFast, 1, 1)
#define FOR_EACH_INTRINSIC_WASM(F, I) \
F(ThrowWasmError, 1, 1) \
F(ThrowWasmStackOverflow, 0, 1) \
F(WasmI32AtomicWait, 4, 1) \
F(WasmI64AtomicWait, 5, 1) \
F(WasmAtomicNotify, 3, 1) \
F(WasmMemoryGrow, 2, 1) \
F(WasmStackGuard, 0, 1) \
F(WasmThrowCreate, 2, 1) \
F(WasmThrow, 1, 1) \
F(WasmReThrow, 1, 1) \
F(WasmThrowJSTypeError, 0, 1) \
F(WasmRefFunc, 1, 1) \
F(WasmFunctionTableGet, 3, 1) \
F(WasmFunctionTableSet, 4, 1) \
F(WasmTableInit, 6, 1) \
F(WasmTableCopy, 6, 1) \
F(WasmTableGrow, 3, 1) \
F(WasmTableFill, 4, 1) \
F(WasmIsValidRefValue, 3, 1) \
F(WasmCompileLazy, 2, 1) \
F(WasmCompileWrapper, 2, 1) \
F(WasmTriggerTierUp, 1, 1) \
F(WasmDebugBreak, 0, 1) \
#define FOR_EACH_INTRINSIC_WASM(F, I) \
F(ThrowWasmError, 1, 1) \
F(ThrowWasmStackOverflow, 0, 1) \
F(WasmI32AtomicWait, 4, 1) \
F(WasmI64AtomicWait, 5, 1) \
F(WasmAtomicNotify, 3, 1) \
F(WasmMemoryGrow, 2, 1) \
F(WasmStackGuard, 0, 1) \
F(WasmCreateFixedArrayForThrow, 1, 1) \
F(WasmThrow, 2, 1) \
F(WasmReThrow, 1, 1) \
F(WasmThrowJSTypeError, 0, 1) \
F(WasmRefFunc, 1, 1) \
F(WasmFunctionTableGet, 3, 1) \
F(WasmFunctionTableSet, 4, 1) \
F(WasmTableInit, 6, 1) \
F(WasmTableCopy, 6, 1) \
F(WasmTableGrow, 3, 1) \
F(WasmTableFill, 4, 1) \
F(WasmIsValidRefValue, 3, 1) \
F(WasmCompileLazy, 2, 1) \
F(WasmCompileWrapper, 2, 1) \
F(WasmTriggerTierUp, 1, 1) \
F(WasmDebugBreak, 0, 1) \
F(WasmAllocateRtt, 2, 1)
#define FOR_EACH_INTRINSIC_WEAKREF(F, I) \
......
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