Skip to content

Commit ca5ee9d

Browse files
gahaasCommit Bot
authored andcommitted
[wasm] Introduce a WasmTableInit CSA builtin
This CL introduces a CSA builtin for the TableInit instruction. This builtin allows to generate smaller code for both TurboFan and Liftoff, and easier code generation from Liftoff. The smaller code size comes from: * Parameters are passed through registers, not the stack. * Lower number of parameters: the call target, number of parameters, and context are not passed as parameters. * No int to smi conversion in generated code. The CL also introduces a small CSA function which takes an uint32 value and a max value as parameters and returns a Smi of the minimum of these two. [email protected], [email protected] Bug: v8:10281 Change-Id: I40f248c20ec76e6ae9483a5e2907a68f42f2cb04 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2106201 Commit-Queue: Andreas Haas <[email protected]> Reviewed-by: Clemens Backes <[email protected]> Reviewed-by: Igor Sheludko <[email protected]> Cr-Commit-Position: refs/heads/master@{#66792}
1 parent 599a6e0 commit ca5ee9d

File tree

8 files changed

+85
-22
lines changed

8 files changed

+85
-22
lines changed

src/builtins/builtins-definitions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,7 @@ namespace internal {
857857
TFC(WasmI64AtomicWait32, WasmI64AtomicWait32) \
858858
TFC(WasmI64AtomicWait64, WasmI64AtomicWait64) \
859859
TFC(WasmMemoryGrow, WasmMemoryGrow) \
860+
TFC(WasmTableInit, WasmTableInit) \
860861
TFC(WasmTableGet, WasmTableGet) \
861862
TFC(WasmTableSet, WasmTableSet) \
862863
TFC(WasmStackGuard, NoContext) \

src/builtins/builtins-wasm-gen.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ class WasmBuiltinsAssembler : public CodeStubAssembler {
2828
IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
2929
kHeapObjectTag)));
3030
}
31+
32+
TNode<Smi> SmiFromUint32WithSaturation(TNode<Uint32T> value, uint32_t max) {
33+
DCHECK_LE(max, static_cast<uint32_t>(Smi::kMaxValue));
34+
TNode<Uint32T> capped_value = SelectConstant(
35+
Uint32LessThan(value, Uint32Constant(max)), value, Uint32Constant(max));
36+
return SmiFromUint32(capped_value);
37+
}
3138
};
3239

3340
TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
@@ -214,6 +221,33 @@ TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
214221
Return(Int32Constant(-1));
215222
}
216223

224+
TF_BUILTIN(WasmTableInit, WasmBuiltinsAssembler) {
225+
TNode<Uint32T> dst_raw =
226+
UncheckedCast<Uint32T>(Parameter(Descriptor::kDestination));
227+
// We cap {dst}, {src}, and {size} by {wasm::kV8MaxWasmTableSize + 1} to make
228+
// sure that the values fit into a Smi.
229+
STATIC_ASSERT(static_cast<size_t>(Smi::kMaxValue) >=
230+
wasm::kV8MaxWasmTableSize + 1);
231+
constexpr uint32_t kCap =
232+
static_cast<uint32_t>(wasm::kV8MaxWasmTableSize + 1);
233+
TNode<Smi> dst = SmiFromUint32WithSaturation(dst_raw, kCap);
234+
TNode<Uint32T> src_raw =
235+
UncheckedCast<Uint32T>(Parameter(Descriptor::kSource));
236+
TNode<Smi> src = SmiFromUint32WithSaturation(src_raw, kCap);
237+
TNode<Uint32T> size_raw =
238+
UncheckedCast<Uint32T>(Parameter(Descriptor::kSize));
239+
TNode<Smi> size = SmiFromUint32WithSaturation(size_raw, kCap);
240+
TNode<Smi> table_index =
241+
UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
242+
TNode<Smi> segment_index =
243+
UncheckedCast<Smi>(Parameter(Descriptor::kSegmentIndex));
244+
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
245+
TNode<Context> context = LoadContextFromInstance(instance);
246+
247+
TailCallRuntime(Runtime::kWasmTableInit, context, instance, table_index,
248+
segment_index, dst, src, size);
249+
}
250+
217251
TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) {
218252
TNode<Int32T> entry_index =
219253
UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));

src/codegen/interface-descriptors.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,12 @@ void WasmMemoryGrowDescriptor::InitializePlatformSpecific(
380380
DefaultInitializePlatformSpecific(data, kParameterCount);
381381
}
382382

383+
void WasmTableInitDescriptor::InitializePlatformSpecific(
384+
CallInterfaceDescriptorData* data) {
385+
DefaultInitializePlatformSpecific(data,
386+
kParameterCount - kStackArgumentsCount);
387+
}
388+
383389
void WasmTableGetDescriptor::InitializePlatformSpecific(
384390
CallInterfaceDescriptorData* data) {
385391
DefaultInitializePlatformSpecific(data, kParameterCount);

src/codegen/interface-descriptors.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace internal {
9696
V(WasmI64AtomicWait32) \
9797
V(WasmI64AtomicWait64) \
9898
V(WasmMemoryGrow) \
99+
V(WasmTableInit) \
99100
V(WasmTableGet) \
100101
V(WasmTableSet) \
101102
V(WasmThrow) \
@@ -1295,6 +1296,29 @@ class WasmMemoryGrowDescriptor final : public CallInterfaceDescriptor {
12951296
DECLARE_DESCRIPTOR(WasmMemoryGrowDescriptor, CallInterfaceDescriptor)
12961297
};
12971298

1299+
class WasmTableInitDescriptor final : public CallInterfaceDescriptor {
1300+
public:
1301+
DEFINE_PARAMETERS_NO_CONTEXT(kDestination, kSource, kSize, kTableIndex,
1302+
kSegmentIndex)
1303+
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kDestination
1304+
MachineType::Int32(), // kSource
1305+
MachineType::Int32(), // kSize
1306+
MachineType::AnyTagged(), // kTableIndex
1307+
MachineType::AnyTagged(), // kSegmentindex
1308+
)
1309+
1310+
#if V8_TARGET_ARCH_IA32
1311+
static constexpr bool kPassLastArgOnStack = true;
1312+
#else
1313+
static constexpr bool kPassLastArgOnStack = false;
1314+
#endif
1315+
1316+
// Pass the last parameter through the stack.
1317+
static constexpr int kStackArgumentsCount = kPassLastArgOnStack ? 1 : 0;
1318+
1319+
DECLARE_DESCRIPTOR(WasmTableInitDescriptor, CallInterfaceDescriptor)
1320+
};
1321+
12981322
class WasmTableGetDescriptor final : public CallInterfaceDescriptor {
12991323
public:
13001324
DEFINE_PARAMETERS_NO_CONTEXT(kTableIndex, kEntryIndex)

src/compiler/wasm-compiler.cc

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4956,19 +4956,18 @@ Node* WasmGraphBuilder::TableInit(uint32_t table_index,
49564956
uint32_t elem_segment_index, Node* dst,
49574957
Node* src, Node* size,
49584958
wasm::WasmCodePosition position) {
4959-
DCHECK_LT(table_index, env_->module->tables.size());
4960-
// The elem segment index must be in bounds since it is required by
4961-
// validation.
4962-
DCHECK_LT(elem_segment_index, env_->module->elem_segments.size());
4959+
auto call_descriptor = GetBuiltinCallDescriptor<WasmTableInitDescriptor>(
4960+
this, StubCallMode::kCallWasmRuntimeStub);
49634961

4964-
Node* args[] = {
4962+
intptr_t target = wasm::WasmCode::kWasmTableInit;
4963+
Node* call_target =
4964+
mcgraph()->RelocatableIntPtrConstant(target, RelocInfo::WASM_STUB_CALL);
4965+
4966+
return gasm_->Call(
4967+
call_descriptor, call_target, dst, src, size,
49654968
graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)),
4966-
graph()->NewNode(mcgraph()->common()->NumberConstant(elem_segment_index)),
4967-
BuildConvertUint32ToSmiWithSaturation(dst, FLAG_wasm_max_table_size),
4968-
BuildConvertUint32ToSmiWithSaturation(src, FLAG_wasm_max_table_size),
4969-
BuildConvertUint32ToSmiWithSaturation(size, FLAG_wasm_max_table_size)};
4970-
return SetEffect(
4971-
BuildCallToRuntime(Runtime::kWasmTableInit, args, arraysize(args)));
4969+
graph()->NewNode(
4970+
mcgraph()->common()->NumberConstant(elem_segment_index)));
49724971
}
49734972

49744973
Node* WasmGraphBuilder::ElemDrop(uint32_t elem_segment_index,

src/runtime/runtime-wasm.cc

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -498,17 +498,15 @@ RUNTIME_FUNCTION(Runtime_WasmFunctionTableSet) {
498498

499499
RUNTIME_FUNCTION(Runtime_WasmTableInit) {
500500
HandleScope scope(isolate);
501-
DCHECK_EQ(5, args.length());
502-
auto instance =
503-
Handle<WasmInstanceObject>(GetWasmInstanceOnStackTop(isolate), isolate);
504-
CONVERT_UINT32_ARG_CHECKED(table_index, 0);
505-
CONVERT_UINT32_ARG_CHECKED(elem_segment_index, 1);
506-
CONVERT_UINT32_ARG_CHECKED(dst, 2);
507-
CONVERT_UINT32_ARG_CHECKED(src, 3);
508-
CONVERT_UINT32_ARG_CHECKED(count, 4);
501+
DCHECK_EQ(6, args.length());
502+
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
503+
CONVERT_UINT32_ARG_CHECKED(table_index, 1);
504+
CONVERT_UINT32_ARG_CHECKED(elem_segment_index, 2);
505+
CONVERT_UINT32_ARG_CHECKED(dst, 3);
506+
CONVERT_UINT32_ARG_CHECKED(src, 4);
507+
CONVERT_UINT32_ARG_CHECKED(count, 5);
509508

510-
DCHECK(isolate->context().is_null());
511-
isolate->set_context(instance->native_context());
509+
DCHECK(!isolate->context().is_null());
512510

513511
bool oob = !WasmInstanceObject::InitTableEntries(
514512
isolate, instance, table_index, elem_segment_index, dst, src, count);

src/runtime/runtime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ namespace internal {
569569
F(WasmRefFunc, 1, 1) \
570570
F(WasmFunctionTableGet, 3, 1) \
571571
F(WasmFunctionTableSet, 4, 1) \
572-
F(WasmTableInit, 5, 1) \
572+
F(WasmTableInit, 6, 1) \
573573
F(WasmTableCopy, 5, 1) \
574574
F(WasmTableGrow, 3, 1) \
575575
F(WasmTableFill, 4, 1) \

src/wasm/wasm-code-manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct WasmModule;
5555
V(WasmI64AtomicWait32) \
5656
V(WasmI64AtomicWait64) \
5757
V(WasmMemoryGrow) \
58+
V(WasmTableInit) \
5859
V(WasmTableGet) \
5960
V(WasmTableSet) \
6061
V(WasmStackGuard) \

0 commit comments

Comments
 (0)