Skip to content

Commit 465db35

Browse files
mkustermannCommit Queue
authored andcommitted
[dart2wasm] Avoid calling out to generic array copy for typed data arrays
The generic array copy in JS will call back into wasm to access each list element. Though the list elements will be accessed via dispatch table calls. This also means the wasm is too complex to get inlined into the generic list copy JS function. Since it doesn't pay off to do this, we instead use normal code to copy the JS typed arrays. Change-Id: Iff2bbf4a50cfcb89fd1b339660dc9f8a8e0099f6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/414761 Reviewed-by: Ömer Ağacan <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent aece514 commit 465db35

File tree

1 file changed

+68
-76
lines changed

1 file changed

+68
-76
lines changed

sdk/lib/_internal/wasm/lib/js_helper_patch.dart

Lines changed: 68 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -257,168 +257,168 @@ void copyToWasmF64Array(
257257
@pragma('wasm:prefer-inline')
258258
WasmExternRef jsInt8ArrayFromDartInt8List(Int8List l) {
259259
assert(l is! JSArrayBase);
260+
final length = l.length;
260261

262+
final jsArray = JSInt8Array.withLength(length);
263+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
261264
if (l is I8List) {
262-
final length = l.length;
263-
final jsArray = (JSInt8Array.withLength(length) as JSValue).toExternRef!;
264-
_copyFromWasmI8Array(jsArray, 0, l.data, l.offsetInElements, length);
265-
return jsArray;
265+
_copyFromWasmI8Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
266+
} else {
267+
jsArray.toDart.setRange(0, length, l);
266268
}
267-
268-
return JS<WasmExternRef>('l => arrayFromDartList(Int8Array, l)', l);
269+
return jsArrayRef;
269270
}
270271

271272
@patch
272273
@pragma('wasm:prefer-inline')
273274
WasmExternRef? jsUint8ArrayFromDartUint8List(Uint8List l) {
274275
assert(l is! JSArrayBase);
276+
final length = l.length;
275277

278+
final jsArray = JSUint8Array.withLength(length);
279+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
276280
if (l is U8List) {
277-
final length = l.length;
278-
final jsArray = (JSUint8Array.withLength(length) as JSValue).toExternRef!;
279-
_copyFromWasmI8Array(jsArray, 0, l.data, l.offsetInElements, length);
280-
return jsArray;
281+
_copyFromWasmI8Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
282+
} else {
283+
jsArray.toDart.setRange(0, length, l);
281284
}
282285

283-
return JS<WasmExternRef>('l => arrayFromDartList(Uint8Array, l)', l);
286+
return jsArrayRef;
284287
}
285288

286289
@patch
287290
@pragma('wasm:prefer-inline')
288291
WasmExternRef? jsUint8ClampedArrayFromDartUint8ClampedList(Uint8ClampedList l) {
289292
assert(l is! JSArrayBase);
293+
final length = l.length;
290294

295+
final jsArray = JSUint8ClampedArray.withLength(length);
296+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
291297
if (l is U8ClampedList) {
292-
final length = l.length;
293-
final jsArray =
294-
(JSUint8ClampedArray.withLength(length) as JSValue).toExternRef!;
295-
_copyFromWasmI8Array(jsArray, 0, l.data, l.offsetInElements, length);
296-
return jsArray;
298+
_copyFromWasmI8Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
299+
} else {
300+
jsArray.toDart.setRange(0, length, l);
297301
}
298-
299-
return JS<WasmExternRef>('l => arrayFromDartList(Uint8ClampedArray, l)', l);
302+
return jsArrayRef;
300303
}
301304

302305
@patch
303306
@pragma('wasm:prefer-inline')
304307
WasmExternRef jsInt16ArrayFromDartInt16List(Int16List l) {
305308
assert(l is! JSArrayBase);
309+
final length = l.length;
306310

311+
final jsArray = JSInt16Array.withLength(length);
312+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
307313
if (l is I16List) {
308-
final length = l.length;
309-
final jsArray = (JSInt16Array.withLength(length) as JSValue).toExternRef!;
310-
_copyFromWasmI16Array(jsArray, 0, l.data, l.offsetInElements, length);
311-
return jsArray;
314+
_copyFromWasmI16Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
315+
} else {
316+
jsArray.toDart.setRange(0, length, l);
312317
}
313-
314-
return JS<WasmExternRef>('l => arrayFromDartList(Int16Array, l)', l);
318+
return jsArrayRef;
315319
}
316320

317321
@patch
318322
@pragma('wasm:prefer-inline')
319323
WasmExternRef jsUint16ArrayFromDartUint16List(Uint16List l) {
320324
assert(l is! JSArrayBase);
325+
final length = l.length;
321326

327+
final jsArray = JSUint16Array.withLength(length);
328+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
322329
if (l is U16List) {
323-
final length = l.length;
324-
final jsArray = (JSUint16Array.withLength(length) as JSValue).toExternRef!;
325-
_copyFromWasmI16Array(jsArray, 0, l.data, l.offsetInElements, length);
326-
return jsArray;
330+
_copyFromWasmI16Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
331+
} else {
332+
jsArray.toDart.setRange(0, length, l);
327333
}
328-
329-
return JS<WasmExternRef>('l => arrayFromDartList(Uint16Array, l)', l);
334+
return jsArrayRef;
330335
}
331336

332337
@patch
333338
@pragma('wasm:prefer-inline')
334339
WasmExternRef jsInt32ArrayFromDartInt32List(Int32List l) {
335340
assert(l is! JSArrayBase);
341+
final length = l.length;
336342

343+
final jsArray = JSInt32Array.withLength(length);
344+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
337345
if (l is I32List) {
338-
final length = l.length;
339-
final jsArray = (JSInt32Array.withLength(length) as JSValue).toExternRef!;
340-
_copyFromWasmI32Array(jsArray, 0, l.data, l.offsetInElements, length);
341-
return jsArray;
346+
_copyFromWasmI32Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
347+
} else {
348+
jsArray.toDart.setRange(0, length, l);
342349
}
343350

344-
return JS<WasmExternRef>('l => arrayFromDartList(Int32Array, l)', l);
351+
return jsArrayRef;
345352
}
346353

347354
@patch
348355
@pragma('wasm:prefer-inline')
349356
WasmExternRef jsUint32ArrayFromDartUint32List(Uint32List l) {
350357
assert(l is! JSArrayBase);
358+
final length = l.length;
351359

360+
final jsArray = JSUint32Array.withLength(length);
361+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
352362
if (l is U32List) {
353-
final length = l.length;
354-
final jsArray = (JSUint32Array.withLength(length) as JSValue).toExternRef!;
355-
_copyFromWasmI32Array(jsArray, 0, l.data, l.offsetInElements, length);
356-
return jsArray;
363+
_copyFromWasmI32Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
364+
} else {
365+
jsArray.toDart.setRange(0, length, l);
357366
}
358-
359-
return JS<WasmExternRef>('l => arrayFromDartList(Uint32Array, l)', l);
367+
return jsArrayRef;
360368
}
361369

362370
@patch
363371
@pragma('wasm:prefer-inline')
364372
WasmExternRef jsFloat32ArrayFromDartFloat32List(Float32List l) {
365373
assert(l is! JSArrayBase);
374+
final length = l.length;
366375

376+
final jsArray = JSFloat32Array.withLength(length);
377+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
367378
if (l is F32List) {
368-
final length = l.length;
369-
final jsArray = (JSFloat32Array.withLength(length) as JSValue).toExternRef!;
370-
_copyFromWasmF32Array(jsArray, 0, l.data, l.offsetInElements, length);
371-
return jsArray;
379+
_copyFromWasmF32Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
380+
} else {
381+
jsArray.toDart.setRange(0, length, l);
372382
}
373-
374-
return JS<WasmExternRef>('l => arrayFromDartList(Float32Array, l)', l);
383+
return jsArrayRef;
375384
}
376385

377386
@patch
378387
@pragma('wasm:prefer-inline')
379388
WasmExternRef jsFloat64ArrayFromDartFloat64List(Float64List l) {
380389
assert(l is! JSArrayBase);
390+
final length = l.length;
381391

392+
final jsArray = JSFloat64Array.withLength(length);
393+
final jsArrayRef = (jsArray as JSValue).toExternRef!;
382394
if (l is F64List) {
383-
final length = l.length;
384-
final jsArray = (JSFloat64Array.withLength(length) as JSValue).toExternRef!;
385-
_copyFromWasmF64Array(jsArray, 0, l.data, l.offsetInElements, length);
386-
return jsArray;
395+
_copyFromWasmF64Array(jsArrayRef, 0, l.data, l.offsetInElements, length);
396+
} else {
397+
jsArray.toDart.setRange(0, length, l);
387398
}
388-
389-
return JS<WasmExternRef>('l => arrayFromDartList(Float64Array, l)', l);
399+
return jsArrayRef;
390400
}
391401

392402
@patch
393403
@pragma('wasm:prefer-inline')
394404
WasmExternRef jsDataViewFromDartByteData(ByteData l, int length) {
395405
assert(l is! JSDataViewImpl);
396406

407+
final jsArrayBuffer = JSArrayBuffer(length);
408+
final jsArray = JSUint8Array(jsArrayBuffer, 0, length);
397409
if (l is I8ByteData) {
398-
final jsArrayBuffer = JSArrayBuffer(length);
399-
final jsArray = JSUint8Array(jsArrayBuffer, 0, length);
400410
_copyFromWasmI8Array(
401411
(jsArray as JSValue).toExternRef!,
402412
0,
403413
l.data,
404414
l.offsetInBytes,
405415
length,
406416
);
407-
return (JSDataView(jsArrayBuffer, 0, length) as JSValue).toExternRef!;
417+
} else {
418+
jsArray.toDart.setRange(0, length, Uint8List.sublistView(l, length));
408419
}
409420

410-
return JS<WasmExternRef>(
411-
"""(data, length) => {
412-
const getValue = dartInstance.exports.\$byteDataGetUint8;
413-
const view = new DataView(new ArrayBuffer(length));
414-
for (let i = 0; i < length; i++) {
415-
view.setUint8(i, getValue(data, i));
416-
}
417-
return view;
418-
}""",
419-
l,
420-
length.toWasmI32(),
421-
);
421+
return (JSDataView(jsArrayBuffer, 0, length) as JSValue).toExternRef!;
422422
}
423423

424424
@pragma("wasm:export", "\$wasmI8ArrayGet")
@@ -500,11 +500,3 @@ void _wasmF64ArraySet(WasmExternRef? ref, WasmI32 index, WasmF64 value) {
500500
);
501501
array[index.toIntUnsigned()] = value;
502502
}
503-
504-
@pragma("wasm:export", "\$byteDataGetUint8")
505-
WasmI32 _byteDataGetUint8(WasmExternRef? ref, WasmI32 index) {
506-
final byteData = unsafeCastOpaque<ByteData>(
507-
unsafeCast<WasmExternRef>(ref).internalize(),
508-
);
509-
return byteData.getUint8(index.toIntSigned()).toWasmI32();
510-
}

0 commit comments

Comments
 (0)