Skip to content

Commit c7c11ab

Browse files
committed
[GR-71972] Support fast copies from interop-backed TypedArrays.
PullRequest: js/3644
2 parents 1f14228 + 7629a3d commit c7c11ab

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/TypedArrayPrototypeBuiltins.java

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@
6060
import com.oracle.truffle.api.dsl.ImportStatic;
6161
import com.oracle.truffle.api.dsl.Specialization;
6262
import com.oracle.truffle.api.interop.InteropLibrary;
63+
import com.oracle.truffle.api.interop.InvalidBufferOffsetException;
64+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
65+
import com.oracle.truffle.api.library.CachedLibrary;
6366
import com.oracle.truffle.api.nodes.Node;
6467
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
6568
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
@@ -687,7 +690,8 @@ static void copyBytewise(Node node, JSArrayBufferObject targetBuffer, JSArrayBuf
687690
@Cached @Shared GetBufferElementTypeDispatchNode getBufferElementNode,
688691
@Cached @Shared SetBufferElementTypeDispatchNode setBufferElementNode,
689692
@Cached @Shared InlinedConditionProfile bothArraysBranch,
690-
@Cached @Shared InlinedBranchProfile sameArrayBranch) {
693+
@Cached @Shared InlinedBranchProfile sameArrayBranch,
694+
@Cached @Shared CopyTypedArrayElementsFromInteropBufferNode copyTypedArrayElementsFromInteropBufferNode) {
691695
int sourceByteLength = sourceLength * sourceElementSize;
692696
if (bothArraysBranch.profile(node, targetType.isArray() && sourceType.isArray())) {
693697
byte[] sourceByteArray = JSArrayBuffer.getByteArray(sourceBuffer);
@@ -719,12 +723,18 @@ static void copyBytewise(Node node, JSArrayBufferObject targetBuffer, JSArrayBuf
719723
targetByteBuffer = Boundaries.byteBufferWrap(JSArrayBuffer.getByteArray(targetBuffer));
720724
}
721725
// if buffers are distinct, try to perform a bulk copy
722-
if (distinctBuffers && (sourceByteBuffer != null && targetByteBuffer != null)) {
723-
Boundaries.byteBufferPutSlice(
724-
targetByteBuffer, targetByteIndex,
725-
sourceByteBuffer, sourceByteIndex,
726-
sourceByteIndex + sourceByteLength);
727-
return;
726+
if (distinctBuffers) {
727+
if (sourceByteBuffer != null && targetByteBuffer != null) {
728+
Boundaries.byteBufferPutSlice(
729+
targetByteBuffer, targetByteIndex,
730+
sourceByteBuffer, sourceByteIndex,
731+
sourceByteIndex + sourceByteLength);
732+
return;
733+
}
734+
if (sourceType.isInterop() && targetByteBuffer != null && targetByteBuffer.hasArray()) {
735+
copyTypedArrayElementsFromInteropBufferNode.execute(node, sourceBuffer, sourceByteIndex, targetByteBuffer, targetByteIndex, sourceByteLength);
736+
return;
737+
}
728738
}
729739

730740
// if we could not do a bulk copy, perform a bytewise copy
@@ -768,6 +778,27 @@ static void copyElementwise(Node node, JSArrayBufferObject targetBuffer, JSArray
768778
}
769779
}
770780

781+
@GenerateCached(false)
782+
@GenerateInline
783+
@ImportStatic(JSConfig.class)
784+
abstract static class CopyTypedArrayElementsFromInteropBufferNode extends JavaScriptBaseNode {
785+
786+
abstract void execute(Node node, JSArrayBufferObject sourceBuffer, int sourceByteIndex, ByteBuffer targetByteBuffer, int targetByteIndex, int byteLength);
787+
788+
@Specialization
789+
static void doReadBuffer(JSArrayBufferObject sourceBuffer, int sourceByteIndex,
790+
ByteBuffer targetByteBuffer, int targetByteIndex,
791+
int byteLength,
792+
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interopLibrary) {
793+
assert targetByteBuffer.hasArray();
794+
try {
795+
interopLibrary.readBuffer(sourceBuffer, sourceByteIndex, targetByteBuffer.array(), targetByteBuffer.arrayOffset() + targetByteIndex, byteLength);
796+
} catch (InvalidBufferOffsetException | UnsupportedMessageException e) {
797+
throw CompilerDirectives.shouldNotReachHere(e);
798+
}
799+
}
800+
}
801+
771802
/**
772803
* Wrapper around {@link GetBufferElementNode}, dispatching on the typed array element type.
773804
*/

0 commit comments

Comments
 (0)