Commit c79af355 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Use {SmallVector} for call arguments and returns.

This switches the {WasmGraphBuilder} to use {SmallVector} for passing
argument and return values. It deprecates {WasmGraphBuilder::Buffer},
which is a dangerous construct as it makes it easy to accidentally use
the single buffer for two vectors at the same time. This also removes
the by now unused {WasmGraphBuilder::Realloc} method.

R=clemensb@chromium.org

Change-Id: I6bd9be437a99c23bb403a046a75c148ac4a14451
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1859619Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64277}
parent b67f096e
......@@ -2646,7 +2646,8 @@ Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node* function,
return SetEffect(graph()->NewNode(op, arraysize(call_args), call_args));
}
Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig, Node** args,
Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig,
Vector<Node*> args,
wasm::WasmCodePosition position,
Node* instance_node, const Operator* op) {
if (instance_node == nullptr) {
......@@ -2659,25 +2660,28 @@ Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig, Node** args,
const size_t count = 1 + params + extra;
// Reallocate the buffer to make space for extra inputs.
args = Realloc(args, 1 + params, count).begin();
base::SmallVector<Node*, 16 + extra> inputs(count);
DCHECK_EQ(1 + params, args.size());
// Make room for the instance_node parameter at index 1, just after code.
memmove(&args[2], &args[1], params * sizeof(Node*));
args[1] = instance_node;
inputs[0] = args[0]; // code
inputs[1] = instance_node;
if (params > 0) memcpy(&inputs[2], &args[1], params * sizeof(Node*));
// Add effect and control inputs.
args[params + 2] = Effect();
args[params + 3] = Control();
inputs[params + 2] = Effect();
inputs[params + 3] = Control();
Node* call = SetEffect(graph()->NewNode(op, static_cast<int>(count), args));
Node* call =
SetEffect(graph()->NewNode(op, static_cast<int>(count), inputs.begin()));
DCHECK(position == wasm::kNoCodePosition || position > 0);
if (position > 0) SetSourcePosition(call, position);
return call;
}
Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args,
Node*** rets,
Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig,
Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position,
Node* instance_node,
UseRetpoline use_retpoline) {
......@@ -2689,21 +2693,22 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args,
size_t ret_count = sig->return_count();
if (ret_count == 0) return call; // No return value.
*rets = Buffer(ret_count).begin();
DCHECK_EQ(ret_count, rets.size());
if (ret_count == 1) {
// Only a single return value.
(*rets)[0] = call;
rets[0] = call;
} else {
// Create projections for all return values.
for (size_t i = 0; i < ret_count; i++) {
(*rets)[i] = graph()->NewNode(mcgraph()->common()->Projection(i), call,
rets[i] = graph()->NewNode(mcgraph()->common()->Projection(i), call,
graph()->start());
}
}
return call;
}
Node* WasmGraphBuilder::BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args,
Node* WasmGraphBuilder::BuildWasmReturnCall(wasm::FunctionSig* sig,
Vector<Node*> args,
wasm::WasmCodePosition position,
Node* instance_node,
UseRetpoline use_retpoline) {
......@@ -2717,8 +2722,8 @@ Node* WasmGraphBuilder::BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args,
return call;
}
Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args,
Node*** rets,
Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig,
Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position,
int func_index,
IsReturnCall continuation) {
......@@ -2743,13 +2748,13 @@ Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args,
case kCallContinues:
return BuildWasmCall(sig, args, rets, position, ref_node, use_retpoline);
case kReturnCall:
DCHECK_NULL(rets);
DCHECK(rets.empty());
return BuildWasmReturnCall(sig, args, position, ref_node, use_retpoline);
}
}
Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args,
Node*** rets,
Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig,
Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position,
Node* func_index,
IsReturnCall continuation) {
......@@ -2793,12 +2798,13 @@ Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args,
case kCallContinues:
return BuildWasmCall(sig, args, rets, position, ref_node, use_retpoline);
case kReturnCall:
DCHECK_NULL(rets);
DCHECK(rets.empty());
return BuildWasmReturnCall(sig, args, position, ref_node, use_retpoline);
}
}
Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets,
Node* WasmGraphBuilder::CallDirect(uint32_t index, Vector<Node*> args,
Vector<Node*> rets,
wasm::WasmCodePosition position) {
DCHECK_NULL(args[0]);
wasm::FunctionSig* sig = env_->module->functions[index].sig;
......@@ -2817,7 +2823,7 @@ Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets,
}
Node* WasmGraphBuilder::CallIndirect(uint32_t table_index, uint32_t sig_index,
Node** args, Node*** rets,
Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position) {
return BuildIndirectCall(table_index, sig_index, args, rets, position,
kCallContinues);
......@@ -2866,8 +2872,9 @@ void WasmGraphBuilder::LoadIndirectFunctionTable(uint32_t table_index,
}
Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index,
uint32_t sig_index, Node** args,
Node*** rets,
uint32_t sig_index,
Vector<Node*> args,
Vector<Node*> rets,
wasm::WasmCodePosition position,
IsReturnCall continuation) {
DCHECK_NOT_NULL(args[0]);
......@@ -2957,14 +2964,14 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index,
}
}
Node* WasmGraphBuilder::ReturnCall(uint32_t index, Node** args,
Node* WasmGraphBuilder::ReturnCall(uint32_t index, Vector<Node*> args,
wasm::WasmCodePosition position) {
DCHECK_NULL(args[0]);
wasm::FunctionSig* sig = env_->module->functions[index].sig;
if (env_ && index < env_->module->num_imported_functions) {
// Return Call to an imported function.
return BuildImportCall(sig, args, nullptr, position, index, kReturnCall);
return BuildImportCall(sig, args, {}, position, index, kReturnCall);
}
// A direct tail call to a wasm function defined in this module.
......@@ -2977,9 +2984,10 @@ Node* WasmGraphBuilder::ReturnCall(uint32_t index, Node** args,
}
Node* WasmGraphBuilder::ReturnCallIndirect(uint32_t table_index,
uint32_t sig_index, Node** args,
uint32_t sig_index,
Vector<Node*> args,
wasm::WasmCodePosition position) {
return BuildIndirectCall(table_index, sig_index, args, nullptr, position,
return BuildIndirectCall(table_index, sig_index, args, {}, position,
kReturnCall);
}
......@@ -5674,6 +5682,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
void BuildJSToWasmWrapper(bool is_import) {
const int wasm_count = static_cast<int>(sig_->parameter_count());
const int rets_count = static_cast<int>(sig_->return_count());
// Build the start and the JS parameter nodes.
SetEffect(SetControl(Start(wasm_count + 5)));
......@@ -5707,8 +5716,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
}
const int args_count = wasm_count + 1; // +1 for wasm_code.
Vector<Node*> args = Buffer(args_count);
Node** rets;
base::SmallVector<Node*, 16> args(args_count);
base::SmallVector<Node*, 1> rets(rets_count);
// Convert JS parameters to wasm numbers.
for (int i = 0; i < wasm_count; ++i) {
......@@ -5725,8 +5734,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// Load function index from {WasmExportedFunctionData}.
Node* function_index =
BuildLoadFunctionIndexFromExportedFunctionData(function_data);
BuildImportCall(sig_, args.begin(), &rets, wasm::kNoCodePosition,
function_index, kCallContinues);
BuildImportCall(sig_, VectorOf(args), VectorOf(rets),
wasm::kNoCodePosition, function_index, kCallContinues);
} else {
// Call to a wasm function defined in this module.
// The call target is the jump table slot for that function.
......@@ -5738,8 +5747,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
mcgraph()->machine()->IntAdd(), jump_table_start, jump_table_offset);
args[0] = jump_table_slot;
BuildWasmCall(sig_, args.begin(), &rets, wasm::kNoCodePosition, nullptr,
kNoRetpoline);
BuildWasmCall(sig_, VectorOf(args), VectorOf(rets), wasm::kNoCodePosition,
nullptr, kNoRetpoline);
}
// Clear the ThreadInWasm flag.
......@@ -5810,7 +5819,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
sloppy_receiver = false;
V8_FALLTHROUGH; // fallthru
case WasmImportCallKind::kJSFunctionArityMatchSloppy: {
Vector<Node*> args = Buffer(wasm_count + 7);
base::SmallVector<Node*, 16> args(wasm_count + 7);
int pos = 0;
Node* function_context =
LOAD_RAW(callable_node,
......@@ -5830,7 +5839,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);
pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_);
args[pos++] = undefined_node; // new target
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
......@@ -5850,7 +5859,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
sloppy_receiver = false;
V8_FALLTHROUGH; // fallthru
case WasmImportCallKind::kJSFunctionArityMismatchSloppy: {
Vector<Node*> args = Buffer(wasm_count + 9);
base::SmallVector<Node*, 16> args(wasm_count + 9);
int pos = 0;
Node* function_context =
LOAD_RAW(callable_node,
......@@ -5897,7 +5906,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
flags, Operator::kNoProperties);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);
pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_);
args[pos++] = function_context;
args[pos++] = Effect();
args[pos++] = Control();
......@@ -5911,7 +5920,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// === General case of unknown callable ==================================
// =======================================================================
case WasmImportCallKind::kUseCallBuiltin: {
Vector<Node*> args = Buffer(wasm_count + 7);
base::SmallVector<Node*, 16> args(wasm_count + 7);
int pos = 0;
args[pos++] =
BuildLoadBuiltinFromIsolateRoot(Builtins::kCall_ReceiverIsAny);
......@@ -5924,7 +5933,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
CallDescriptor::kNoFlags, Operator::kNoProperties);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);
pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_);
// The native_context is sufficient here, because all kind of callables
// which depend on the context provide their own context. The context
......@@ -6184,7 +6193,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
wasm::ObjectAccess::ToTagged(WasmJSFunctionData::kCallableOffset));
// Call the underlying closure.
Vector<Node*> args = Buffer(wasm_count + 7);
base::SmallVector<Node*, 16> args(wasm_count + 7);
int pos = 0;
args[pos++] =
BuildLoadBuiltinFromIsolateRoot(Builtins::kCall_ReceiverIsAny);
......@@ -6254,7 +6263,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
kNoWriteBarrier);
int wasm_arg_count = static_cast<int>(sig_->parameter_count());
Vector<Node*> args = Buffer(wasm_arg_count + 4);
base::SmallVector<Node*, 16> args(wasm_arg_count + 4);
int pos = 0;
args[pos++] = code_entry;
......
......@@ -19,6 +19,12 @@
#include "src/zone/zone.h"
namespace v8 {
namespace base {
template <typename T, size_t kSize>
class SmallVector;
} // namespace base
namespace internal {
struct AssemblerOptions;
class OptimizedCompilationJob;
......@@ -179,6 +185,7 @@ class WasmGraphBuilder {
wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph,
wasm::FunctionSig* sig, compiler::SourcePositionTable* spt = nullptr);
// TODO(mstarzinger): Remove this deprecated buffer.
Vector<Node*> Buffer(size_t count) {
if (count > cur_bufsize_) {
size_t new_size = count + cur_bufsize_ + 5;
......@@ -276,15 +283,16 @@ class WasmGraphBuilder {
}
Node* Unreachable(wasm::WasmCodePosition position);
Node* CallDirect(uint32_t index, Node** args, Node*** rets,
Node* CallDirect(uint32_t index, Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position);
Node* CallIndirect(uint32_t table_index, uint32_t sig_index,
Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position);
Node* CallIndirect(uint32_t table_index, uint32_t sig_index, Node** args,
Node*** rets, wasm::WasmCodePosition position);
Node* ReturnCall(uint32_t index, Node** args,
Node* ReturnCall(uint32_t index, Vector<Node*> args,
wasm::WasmCodePosition position);
Node* ReturnCallIndirect(uint32_t table_index, uint32_t sig_index,
Node** args, wasm::WasmCodePosition position);
Vector<Node*> args, wasm::WasmCodePosition position);
Node* Invert(Node* node);
......@@ -497,28 +505,29 @@ class WasmGraphBuilder {
template <typename... Args>
Node* BuildCCall(MachineSignature* sig, Node* function, Args... args);
Node* BuildCallNode(wasm::FunctionSig* sig, Node** args,
Node* BuildCallNode(wasm::FunctionSig* sig, Vector<Node*> args,
wasm::WasmCodePosition position, Node* instance_node,
const Operator* op);
// Helper function for {BuildIndirectCall}.
void LoadIndirectFunctionTable(uint32_t table_index, Node** ift_size,
Node** ift_sig_ids, Node** ift_targets,
Node** ift_instances);
Node* BuildIndirectCall(uint32_t table_index, uint32_t sig_index, Node** args,
Node*** rets, wasm::WasmCodePosition position,
Node* BuildIndirectCall(uint32_t table_index, uint32_t sig_index,
Vector<Node*> args, Vector<Node*> rets,
wasm::WasmCodePosition position,
IsReturnCall continuation);
Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, Node* instance_node,
UseRetpoline use_retpoline);
Node* BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args,
Node* BuildWasmCall(wasm::FunctionSig* sig, Vector<Node*> args,
Vector<Node*> rets, wasm::WasmCodePosition position,
Node* instance_node, UseRetpoline use_retpoline);
Node* BuildWasmReturnCall(wasm::FunctionSig* sig, Vector<Node*> args,
wasm::WasmCodePosition position,
Node* instance_node, UseRetpoline use_retpoline);
Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, int func_index,
IsReturnCall continuation);
Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, Node* func_index,
IsReturnCall continuation);
Node* BuildImportCall(wasm::FunctionSig* sig, Vector<Node*> args,
Vector<Node*> rets, wasm::WasmCodePosition position,
int func_index, IsReturnCall continuation);
Node* BuildImportCall(wasm::FunctionSig* sig, Vector<Node*> args,
Vector<Node*> rets, wasm::WasmCodePosition position,
Node* func_index, IsReturnCall continuation);
Node* BuildF32CopySign(Node* left, Node* right);
Node* BuildF64CopySign(Node* left, Node* right);
......@@ -606,16 +615,6 @@ class WasmGraphBuilder {
Node* BuildMultiReturnFixedArrayFromIterable(const wasm::FunctionSig* sig,
Node* iterable, Node* context);
Vector<Node*> Realloc(Node* const* buffer, size_t old_count,
size_t new_count) {
DCHECK_GE(new_count, old_count); // Only support growing.
Vector<Node*> buf = Buffer(new_count);
if (buf.begin() != buffer) {
memcpy(buf.begin(), buffer, old_count * sizeof(Node*));
}
return buf;
}
//-----------------------------------------------------------------------
// Operations involving the CEntry, a dependency we want to remove
// to get off the GC heap.
......
......@@ -887,22 +887,22 @@ class WasmGraphBuildingInterface {
void DoCall(FullDecoder* decoder, uint32_t table_index, TFNode* index_node,
FunctionSig* sig, uint32_t sig_index, const Value args[],
Value returns[]) {
int param_count = static_cast<int>(sig->parameter_count());
Vector<TFNode*> arg_nodes = builder_->Buffer(param_count + 1);
TFNode** return_nodes = nullptr;
size_t param_count = sig->parameter_count();
size_t return_count = sig->return_count();
base::SmallVector<TFNode*, 16> arg_nodes(param_count + 1);
base::SmallVector<TFNode*, 1> return_nodes(return_count);
arg_nodes[0] = index_node;
for (int i = 0; i < param_count; ++i) {
for (size_t i = 0; i < param_count; ++i) {
arg_nodes[i + 1] = args[i].node;
}
if (index_node) {
BUILD(CallIndirect, table_index, sig_index, arg_nodes.begin(),
&return_nodes, decoder->position());
BUILD(CallIndirect, table_index, sig_index, VectorOf(arg_nodes),
VectorOf(return_nodes), decoder->position());
} else {
BUILD(CallDirect, sig_index, arg_nodes.begin(), &return_nodes,
BUILD(CallDirect, sig_index, VectorOf(arg_nodes), VectorOf(return_nodes),
decoder->position());
}
int return_count = static_cast<int>(sig->return_count());
for (int i = 0; i < return_count; ++i) {
for (size_t i = 0; i < return_count; ++i) {
returns[i].node = return_nodes[i];
}
// The invoked function could have used grow_memory, so we need to
......@@ -913,17 +913,17 @@ class WasmGraphBuildingInterface {
void DoReturnCall(FullDecoder* decoder, uint32_t table_index,
TFNode* index_node, FunctionSig* sig, uint32_t sig_index,
const Value args[]) {
int arg_count = static_cast<int>(sig->parameter_count());
Vector<TFNode*> arg_nodes = builder_->Buffer(arg_count + 1);
size_t arg_count = sig->parameter_count();
base::SmallVector<TFNode*, 16> arg_nodes(arg_count + 1);
arg_nodes[0] = index_node;
for (int i = 0; i < arg_count; ++i) {
for (size_t i = 0; i < arg_count; ++i) {
arg_nodes[i + 1] = args[i].node;
}
if (index_node) {
BUILD(ReturnCallIndirect, table_index, sig_index, arg_nodes.begin(),
BUILD(ReturnCallIndirect, table_index, sig_index, VectorOf(arg_nodes),
decoder->position());
} else {
BUILD(ReturnCall, sig_index, arg_nodes.begin(), decoder->position());
BUILD(ReturnCall, sig_index, VectorOf(arg_nodes), decoder->position());
}
}
};
......
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