Commit 95cd71c2 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Avoid stack-walks in some runtime functions.

This avoids unnecessary stack-walks to determine the current context in
WebAssembly runtime functions, in cases where the calling stub already
determined the calling instance and can just set the context register
itself before calling into the runtime.

R=clemensh@chromium.org

Change-Id: Iba02d479a7dad8907195bf94efb9d559be20a6d1
Reviewed-on: https://chromium-review.googlesource.com/1228035Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55962}
parent 279cbe86
......@@ -38,16 +38,19 @@ class WasmBuiltinsAssembler : public CodeStubAssembler {
LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
}
TNode<Object> LoadContextFromInstance(TNode<Object> instance) {
return UncheckedCast<Object>(
Load(MachineType::AnyTagged(), instance,
IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
kHeapObjectTag)));
}
TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) {
return UncheckedCast<Code>(
Load(MachineType::AnyTagged(), instance,
IntPtrConstant(WasmInstanceObject::kCEntryStubOffset -
kHeapObjectTag)));
}
TNode<Code> LoadCEntryFromFrame() {
return LoadCEntryFromInstance(LoadInstanceFromFrame());
}
};
TF_BUILTIN(WasmAllocateHeapNumber, WasmBuiltinsAssembler) {
......@@ -71,9 +74,10 @@ TF_BUILTIN(WasmToNumber, WasmBuiltinsAssembler) {
}
TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
TNode<Code> centry = LoadCEntryFromFrame();
TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry,
NoContextConstant());
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Object> context = LoadContextFromInstance(instance);
TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, context);
}
TF_BUILTIN(WasmGrowMemory, WasmBuiltinsAssembler) {
......@@ -88,9 +92,9 @@ TF_BUILTIN(WasmGrowMemory, WasmBuiltinsAssembler) {
TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
TNode<Object> instance = LoadInstanceFromFrame();
TNode<Code> centry = LoadCEntryFromInstance(instance);
TNode<Smi> ret_smi = UncheckedCast<Smi>(
CallRuntimeWithCEntry(Runtime::kWasmGrowMemory, centry,
NoContextConstant(), instance, num_pages_smi));
TNode<Object> context = LoadContextFromInstance(instance);
TNode<Smi> ret_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
Runtime::kWasmGrowMemory, centry, context, instance, num_pages_smi));
TNode<Int32T> ret = SmiToInt32(ret_smi);
ReturnRaw(ret);
......@@ -100,10 +104,12 @@ TF_BUILTIN(WasmGrowMemory, WasmBuiltinsAssembler) {
#define DECLARE_ENUM(name) \
TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) { \
TNode<Code> centry = LoadCEntryFromFrame(); \
TNode<Object> instance = LoadInstanceFromFrame(); \
TNode<Code> centry = LoadCEntryFromInstance(instance); \
TNode<Object> context = LoadContextFromInstance(instance); \
int message_id = wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, \
NoContextConstant(), SmiConstant(message_id)); \
TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context, \
SmiConstant(message_id)); \
}
FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
#undef DECLARE_ENUM
......
......@@ -42,19 +42,15 @@ Context* GetNativeContextFromWasmInstanceOnStackTop(Isolate* isolate) {
class ClearThreadInWasmScope {
public:
explicit ClearThreadInWasmScope(bool coming_from_wasm)
: coming_from_wasm_(coming_from_wasm) {
DCHECK_EQ(trap_handler::IsTrapHandlerEnabled() && coming_from_wasm,
ClearThreadInWasmScope() {
DCHECK_EQ(trap_handler::IsTrapHandlerEnabled(),
trap_handler::IsThreadInWasm());
if (coming_from_wasm) trap_handler::ClearThreadInWasm();
trap_handler::ClearThreadInWasm();
}
~ClearThreadInWasmScope() {
DCHECK(!trap_handler::IsThreadInWasm());
if (coming_from_wasm_) trap_handler::SetThreadInWasm();
trap_handler::SetThreadInWasm();
}
private:
const bool coming_from_wasm_;
};
} // namespace
......@@ -68,11 +64,7 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
CONVERT_UINT32_ARG_CHECKED(delta_pages, 1);
// This runtime function is always being called from wasm code.
ClearThreadInWasmScope flag_scope(true);
// Set the current isolate's context.
DCHECK_NULL(isolate->context());
isolate->set_context(instance->native_context());
ClearThreadInWasmScope flag_scope;
int ret = WasmMemoryObject::Grow(
isolate, handle(instance->memory_object(), isolate), delta_pages);
......@@ -84,11 +76,9 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
RUNTIME_FUNCTION(Runtime_ThrowWasmError) {
DCHECK_EQ(1, args.length());
CONVERT_SMI_ARG_CHECKED(message_id, 0);
ClearThreadInWasmScope clear_wasm_flag(isolate->context() == nullptr);
ClearThreadInWasmScope clear_wasm_flag;
HandleScope scope(isolate);
DCHECK_NULL(isolate->context());
isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate));
Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError(
static_cast<MessageTemplate::Template>(message_id));
return isolate->Throw(*error_obj);
......@@ -242,7 +232,7 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
CHECK(arg_buffer_obj->IsSmi());
Address arg_buffer = reinterpret_cast<Address>(*arg_buffer_obj);
ClearThreadInWasmScope wasm_flag(true);
ClearThreadInWasmScope wasm_flag;
// Find the frame pointer and instance of the interpreter frame on the stack.
Handle<WasmInstanceObject> instance;
......@@ -284,11 +274,7 @@ RUNTIME_FUNCTION(Runtime_WasmStackGuard) {
DCHECK(!trap_handler::IsTrapHandlerEnabled() ||
trap_handler::IsThreadInWasm());
ClearThreadInWasmScope wasm_flag(true);
// Set the current isolate's context.
DCHECK_NULL(isolate->context());
isolate->set_context(GetNativeContextFromWasmInstanceOnStackTop(isolate));
ClearThreadInWasmScope wasm_flag;
// Check if this is a real stack overflow.
StackLimitCheck check(isolate);
......@@ -303,7 +289,7 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) {
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
CONVERT_SMI_ARG_CHECKED(func_index, 1);
ClearThreadInWasmScope wasm_flag(true);
ClearThreadInWasmScope wasm_flag;
#ifdef DEBUG
StackFrameIterator it(isolate, isolate->thread_local_top());
......
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