[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:
parent
279cbe86da
commit
95cd71c25a
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user