[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/1228035
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55962}
This commit is contained in:
Michael Starzinger 2018-09-17 15:14:31 +02:00 committed by Commit Bot
parent 279cbe86da
commit 95cd71c25a
2 changed files with 28 additions and 36 deletions

View File

@ -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

View File

@ -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());