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