Skip to content

Commit 2ae6cda

Browse files
manoskoukV8 LUCI CQ
authored andcommitted
[wasm-gc] Skip array.copy if length == 0
Bug: v8:7748 Change-Id: Id6adc39af6818f5a37307f26cfe40de11a0ce3c2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3195872 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#77169}
1 parent 07d82db commit 2ae6cda

6 files changed

Lines changed: 26 additions & 1 deletion

File tree

src/builtins/wasm.tq

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ builtin WasmArrayCopyWithChecks(
364364
srcIndex + length > srcArray.length || srcIndex + length < srcIndex) {
365365
tail ThrowWasmTrapArrayOutOfBounds();
366366
}
367+
if (length == 0) return Undefined;
367368
tail runtime::WasmArrayCopy(
368369
LoadContextFromFrame(), dstArray, SmiFromUint32(dstIndex), srcArray,
369370
SmiFromUint32(srcIndex), SmiFromUint32(length));

src/compiler/wasm-compiler.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6009,6 +6009,11 @@ void WasmGraphBuilder::ArrayCopy(Node* dst_array, Node* dst_index,
60096009
BoundsCheckArrayCopy(dst_array, dst_index, length, position);
60106010
BoundsCheckArrayCopy(src_array, src_index, length, position);
60116011

6012+
auto skip = gasm_->MakeLabel();
6013+
6014+
gasm_->GotoIf(gasm_->WordEqual(length, Int32Constant(0)), &skip,
6015+
BranchHint::kFalse);
6016+
60126017
Node* function =
60136018
gasm_->ExternalConstant(ExternalReference::wasm_array_copy());
60146019
MachineType arg_types[]{
@@ -6018,6 +6023,8 @@ void WasmGraphBuilder::ArrayCopy(Node* dst_array, Node* dst_index,
60186023
MachineSignature sig(0, 6, arg_types);
60196024
BuildCCall(&sig, function, GetInstance(), dst_array, dst_index, src_array,
60206025
src_index, length);
6026+
gasm_->Goto(&skip);
6027+
gasm_->Bind(&skip);
60216028
}
60226029

60236030
// 1 bit V8 Smi tag, 31 bits V8 Smi shift, 1 bit i31ref high-bit truncation.

src/runtime/runtime-wasm.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ inline void* ArrayElementAddress(Handle<WasmArray> array, uint32_t index,
640640
}
641641
} // namespace
642642

643-
// Assumes copy ranges are in-bounds.
643+
// Assumes copy ranges are in-bounds and copy length > 0.
644644
RUNTIME_FUNCTION(Runtime_WasmArrayCopy) {
645645
ClearThreadInWasmScope flag_scope(isolate);
646646
HandleScope scope(isolate);
@@ -650,6 +650,7 @@ RUNTIME_FUNCTION(Runtime_WasmArrayCopy) {
650650
CONVERT_ARG_HANDLE_CHECKED(WasmArray, src_array, 2);
651651
CONVERT_UINT32_ARG_CHECKED(src_index, 3);
652652
CONVERT_UINT32_ARG_CHECKED(length, 4);
653+
DCHECK_GT(length, 0);
653654
bool overlapping_ranges =
654655
dst_array->ptr() == src_array->ptr() &&
655656
(dst_index < src_index ? dst_index + length > src_index

src/wasm/wasm-external-refs.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ inline void* ArrayElementAddress(WasmArray array, uint32_t index,
548548
void array_copy_wrapper(Address raw_instance, Address raw_dst_array,
549549
uint32_t dst_index, Address raw_src_array,
550550
uint32_t src_index, uint32_t length) {
551+
DCHECK_GT(length, 0);
551552
ThreadNotInWasmScope thread_not_in_wasm_scope;
552553
DisallowGarbageCollection no_gc;
553554
WasmArray dst_array = WasmArray::cast(Object(raw_dst_array));

src/wasm/wasm-external-refs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int32_t memory_copy_wrapper(Address data);
111111
// zero-extend the result in the return register.
112112
int32_t memory_fill_wrapper(Address data);
113113

114+
// Assumes copy ranges are in-bounds and length > 0.
114115
void array_copy_wrapper(Address raw_instance, Address raw_dst_array,
115116
uint32_t dst_index, Address raw_src_array,
116117
uint32_t src_index, uint32_t length);

test/cctest/wasm/test-gc.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,19 @@ WASM_COMPILED_EXEC_TEST(WasmArrayCopy) {
11111111
WASM_I32V(5)),
11121112
kExprEnd});
11131113

1114+
const byte kZeroLength = tester.DefineFunction(
1115+
tester.sigs.i_v(), {optref(arrayref_index), optref(arrayref_index)},
1116+
{WASM_LOCAL_SET(
1117+
0, WASM_ARRAY_NEW_DEFAULT_WITH_RTT(arrayref_index, WASM_I32V(10),
1118+
WASM_RTT_CANON(arrayref_index))),
1119+
WASM_LOCAL_SET(
1120+
1, WASM_ARRAY_NEW_DEFAULT_WITH_RTT(arrayref_index, WASM_I32V(10),
1121+
WASM_RTT_CANON(arrayref_index))),
1122+
WASM_ARRAY_COPY(arrayref_index, arrayref_index, WASM_LOCAL_GET(1),
1123+
WASM_I32V(6), WASM_LOCAL_GET(0), WASM_I32V(3),
1124+
WASM_I32V(0)),
1125+
WASM_I32V(0), kExprEnd});
1126+
11141127
tester.CompileModule();
11151128

11161129
tester.CheckResult(kCopyI32, 0, 5);
@@ -1153,6 +1166,7 @@ WASM_COMPILED_EXEC_TEST(WasmArrayCopy) {
11531166

11541167
tester.CheckHasThrown(kOobSource);
11551168
tester.CheckHasThrown(kOobDestination);
1169+
tester.CheckResult(kZeroLength, 0); // Does not throw.
11561170
}
11571171

11581172
WASM_COMPILED_EXEC_TEST(NewDefault) {

0 commit comments

Comments
 (0)