Commit 59157272 authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

[wasm] Refactor runtime call builders as WasmGraphBuilder members

This is a step towards removing the dependency on CEntryStub. The next
step will reuse BuildCCall to that end. BuildCCall is a member of
WasmGraphBuilder.

Bug: 
Change-Id: I35d3af31b15c04af3d1b877049fd9eccaef306b5
Reviewed-on: https://chromium-review.googlesource.com/549106
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46266}
parent a00eb683
......@@ -64,97 +64,6 @@ void MergeControlToEnd(JSGraph* jsgraph, Node* node) {
}
}
Node* BuildModifyThreadInWasmFlag(bool new_value, JSGraph* jsgraph,
Node* centry_stub_node, Node** effect_ptr,
Node* control) {
// TODO(eholk): generate code to modify the thread-local storage directly,
// rather than calling the runtime.
if (!trap_handler::UseTrapHandler()) {
return control;
}
const Runtime::FunctionId f =
new_value ? Runtime::kSetThreadInWasm : Runtime::kClearThreadInWasm;
const Runtime::Function* fun = Runtime::FunctionForId(f);
DCHECK_EQ(0, fun->nargs);
const CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
jsgraph->zone(), f, fun->nargs, Operator::kNoProperties,
CallDescriptor::kNoFlags);
// CEntryStubConstant nodes have to be created and cached in the main
// thread. At the moment this is only done for CEntryStubConstant(1).
DCHECK_EQ(1, fun->result_size);
Node* inputs[] = {centry_stub_node,
jsgraph->ExternalConstant(
ExternalReference(f, jsgraph->isolate())), // ref
jsgraph->Int32Constant(fun->nargs), // arity
jsgraph->NoContextConstant(),
*effect_ptr,
control};
Node* node = jsgraph->graph()->NewNode(jsgraph->common()->Call(desc),
arraysize(inputs), inputs);
*effect_ptr = node;
return node;
}
// Only call this function for code which is not reused across instantiations,
// as we do not patch the embedded context.
Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, JSGraph* jsgraph,
Node* centry_stub_node, Node* context,
Node** parameters, int parameter_count,
Node** effect_ptr, Node** control) {
// Setting and clearing the thread-in-wasm flag should not be done as a normal
// runtime call.
DCHECK_NE(f, Runtime::kSetThreadInWasm);
DCHECK_NE(f, Runtime::kClearThreadInWasm);
// We're leaving Wasm code, so clear the flag.
*control = BuildModifyThreadInWasmFlag(false, jsgraph, centry_stub_node,
effect_ptr, *control);
const Runtime::Function* fun = Runtime::FunctionForId(f);
CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
jsgraph->zone(), f, fun->nargs, Operator::kNoProperties,
CallDescriptor::kNoFlags);
// CEntryStubConstant nodes have to be created and cached in the main
// thread. At the moment this is only done for CEntryStubConstant(1).
DCHECK_EQ(1, fun->result_size);
// At the moment we only allow 3 parameters. If more parameters are needed,
// increase this constant accordingly.
static const int kMaxParams = 3;
DCHECK_GE(kMaxParams, parameter_count);
Node* inputs[kMaxParams + 6];
int count = 0;
inputs[count++] = centry_stub_node;
for (int i = 0; i < parameter_count; i++) {
inputs[count++] = parameters[i];
}
inputs[count++] = jsgraph->ExternalConstant(
ExternalReference(f, jsgraph->isolate())); // ref
inputs[count++] = jsgraph->Int32Constant(fun->nargs); // arity
inputs[count++] = context; // context
inputs[count++] = *effect_ptr;
inputs[count++] = *control;
Node* node =
jsgraph->graph()->NewNode(jsgraph->common()->Call(desc), count, inputs);
*effect_ptr = node;
// Restore the thread-in-wasm flag, since we have returned to Wasm.
*control = BuildModifyThreadInWasmFlag(true, jsgraph, centry_stub_node,
effect_ptr, *control);
return node;
}
Node* BuildCallToRuntime(Runtime::FunctionId f, JSGraph* jsgraph,
Node* centry_stub_node, Node** parameters,
int parameter_count, Node** effect_ptr,
Node** control) {
return BuildCallToRuntimeWithContext(f, jsgraph, centry_stub_node,
jsgraph->NoContextConstant(), parameters,
parameter_count, effect_ptr, control);
}
} // namespace
WasmGraphBuilder::WasmGraphBuilder(
......@@ -1741,9 +1650,9 @@ Node* WasmGraphBuilder::GrowMemory(Node* input) {
Node* parameters[] = {BuildChangeUint32ToSmi(input)};
Node* old_effect = *effect_;
Node* call = BuildCallToRuntime(
Runtime::kWasmGrowMemory, jsgraph(), centry_stub_node_, parameters,
arraysize(parameters), effect_, &check_input_range.if_true);
*control_ = check_input_range.if_true;
Node* call = BuildCallToRuntime(Runtime::kWasmGrowMemory, parameters,
arraysize(parameters));
Node* result = BuildChangeSmiToInt32(call);
......@@ -1774,9 +1683,8 @@ Node* WasmGraphBuilder::Throw(Node* input) {
graph()->NewNode(machine->Word32And(), input, Int32Constant(0xFFFFu)));
Node* parameters[] = {lower, upper}; // thrown value
return BuildCallToRuntime(Runtime::kWasmThrow, jsgraph(), centry_stub_node_,
parameters, arraysize(parameters), effect_,
control_);
return BuildCallToRuntime(Runtime::kWasmThrow, parameters,
arraysize(parameters));
}
Node* WasmGraphBuilder::Catch(Node* input, wasm::WasmCodePosition position) {
......@@ -1785,8 +1693,7 @@ Node* WasmGraphBuilder::Catch(Node* input, wasm::WasmCodePosition position) {
Node* parameters[] = {input}; // caught value
Node* value = BuildCallToRuntime(Runtime::kWasmGetCaughtExceptionValue,
jsgraph(), centry_stub_node_, parameters,
arraysize(parameters), effect_, control_);
parameters, arraysize(parameters));
Node* is_smi;
Node* is_heap;
......@@ -2633,16 +2540,14 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
graph()->start());
// Set the ThreadInWasm flag before we do the actual call.
BuildModifyThreadInWasmFlag(true, jsgraph(), centry_stub_node_, effect_,
*control_);
BuildModifyThreadInWasmFlag(true);
if (!wasm::IsJSCompatibleSignature(sig_)) {
// Throw a TypeError. Use the context of the calling javascript function
// (passed as a parameter), such that the generated code is context
// independent.
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(),
centry_stub_node_, context, nullptr, 0,
effect_, control_);
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, context,
nullptr, 0);
// Add a dummy call to the wasm function so that the generated wrapper
// contains a reference to the wrapped wasm function. Without this reference
......@@ -2681,8 +2586,7 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
*effect_ = call;
// Clear the ThreadInWasmFlag
BuildModifyThreadInWasmFlag(false, jsgraph(), centry_stub_node_, effect_,
*control_);
BuildModifyThreadInWasmFlag(false);
Node* retval = call;
Node* jsval = ToJS(
......@@ -2719,9 +2623,8 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
// regenerated at instantiation time.
Node* context =
jsgraph()->HeapConstant(jsgraph()->isolate()->native_context());
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(),
centry_stub_node_, context, nullptr, 0,
effect_, control_);
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, context,
nullptr, 0);
// We don't need to return a value here, as the runtime call will not return
// anyway (the c entry stub will trigger stack unwinding).
ReturnVoid();
......@@ -2732,8 +2635,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
Node* call = nullptr;
BuildModifyThreadInWasmFlag(false, jsgraph(), centry_stub_node_, effect_,
*control_);
BuildModifyThreadInWasmFlag(false);
if (target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(target);
......@@ -2798,8 +2700,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
*effect_ = call;
SetSourcePosition(call, 0);
BuildModifyThreadInWasmFlag(true, jsgraph(), centry_stub_node_, effect_,
*control_);
BuildModifyThreadInWasmFlag(true);
// Convert the return value back.
Node* val = sig->return_count() == 0
......@@ -2882,8 +2783,8 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry(
jsgraph()->SmiConstant(function_index), // function index
arg_buffer, // argument buffer
};
BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), centry_stub_node_,
parameters, arraysize(parameters), effect_, control_);
BuildCallToRuntime(Runtime::kWasmRunInterpreter, parameters,
arraysize(parameters));
// Read back the return value.
if (sig->return_count() == 0) {
......@@ -2931,9 +2832,7 @@ Node* WasmGraphBuilder::CurrentMemoryPages() {
// CurrentMemoryPages can not be called from asm.js.
DCHECK_EQ(wasm::kWasmOrigin, module_->module->get_origin());
SetNeedsStackCheck();
Node* call =
BuildCallToRuntime(Runtime::kWasmMemorySize, jsgraph(), centry_stub_node_,
nullptr, 0, effect_, control_);
Node* call = BuildCallToRuntime(Runtime::kWasmMemorySize, nullptr, 0);
Node* result = BuildChangeSmiToInt32(call);
return result;
}
......@@ -2966,6 +2865,91 @@ void WasmGraphBuilder::EnsureFunctionTableNodes() {
}
}
Node* WasmGraphBuilder::BuildModifyThreadInWasmFlag(bool new_value) {
// TODO(eholk): generate code to modify the thread-local storage directly,
// rather than calling the runtime.
if (!trap_handler::UseTrapHandler()) {
return *control_;
}
const Runtime::FunctionId f =
new_value ? Runtime::kSetThreadInWasm : Runtime::kClearThreadInWasm;
const Runtime::Function* fun = Runtime::FunctionForId(f);
DCHECK_EQ(0, fun->nargs);
const CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties,
CallDescriptor::kNoFlags);
// CEntryStubConstant nodes have to be created and cached in the main
// thread. At the moment this is only done for CEntryStubConstant(1).
DCHECK_EQ(1, fun->result_size);
Node* inputs[] = {centry_stub_node_,
jsgraph()->ExternalConstant(
ExternalReference(f, jsgraph()->isolate())), // ref
jsgraph()->Int32Constant(fun->nargs), // arity
jsgraph()->NoContextConstant(),
*effect_,
*control_};
Node* node = jsgraph()->graph()->NewNode(jsgraph()->common()->Call(desc),
arraysize(inputs), inputs);
*effect_ = node;
return node;
}
// Only call this function for code which is not reused across instantiations,
// as we do not patch the embedded context.
Node* WasmGraphBuilder::BuildCallToRuntimeWithContext(Runtime::FunctionId f,
Node* context,
Node** parameters,
int parameter_count) {
// Setting and clearing the thread-in-wasm flag should not be done as a normal
// runtime call.
DCHECK_NE(f, Runtime::kSetThreadInWasm);
DCHECK_NE(f, Runtime::kClearThreadInWasm);
// We're leaving Wasm code, so clear the flag.
*control_ = BuildModifyThreadInWasmFlag(false);
const Runtime::Function* fun = Runtime::FunctionForId(f);
CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties,
CallDescriptor::kNoFlags);
// CEntryStubConstant nodes have to be created and cached in the main
// thread. At the moment this is only done for CEntryStubConstant(1).
DCHECK_EQ(1, fun->result_size);
// At the moment we only allow 3 parameters. If more parameters are needed,
// increase this constant accordingly.
static const int kMaxParams = 3;
DCHECK_GE(kMaxParams, parameter_count);
Node* inputs[kMaxParams + 6];
int count = 0;
inputs[count++] = centry_stub_node_;
for (int i = 0; i < parameter_count; i++) {
inputs[count++] = parameters[i];
}
inputs[count++] = jsgraph()->ExternalConstant(
ExternalReference(f, jsgraph()->isolate())); // ref
inputs[count++] = jsgraph()->Int32Constant(fun->nargs); // arity
inputs[count++] = context; // context
inputs[count++] = *effect_;
inputs[count++] = *control_;
Node* node = jsgraph()->graph()->NewNode(jsgraph()->common()->Call(desc),
count, inputs);
*effect_ = node;
// Restore the thread-in-wasm flag, since we have returned to Wasm.
*control_ = BuildModifyThreadInWasmFlag(true);
return node;
}
Node* WasmGraphBuilder::BuildCallToRuntime(Runtime::FunctionId f,
Node** parameters,
int parameter_count) {
return BuildCallToRuntimeWithContext(f, jsgraph()->NoContextConstant(),
parameters, parameter_count);
}
Node* WasmGraphBuilder::GetGlobal(uint32_t index) {
MachineType mem_type =
wasm::WasmOpcodes::MachineTypeFor(module_->GetGlobalType(index));
......
......@@ -409,6 +409,18 @@ class WasmGraphBuilder {
wasm::FunctionSig* sig);
void SetNeedsStackCheck() { needs_stack_check_ = true; }
//-----------------------------------------------------------------------
// Operations involving the CEntryStub, a dependency we want to remove
// to get off the GC heap.
//-----------------------------------------------------------------------
Node* BuildCallToRuntime(Runtime::FunctionId f, Node** parameters,
int parameter_count);
Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, Node* context,
Node** parameters, int parameter_count);
Node* BuildModifyThreadInWasmFlag(bool new_value);
};
V8_EXPORT_PRIVATE CallDescriptor* GetWasmCallDescriptor(Zone* zone,
......
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