Skip to content

Commit 72541de

Browse files
iamstolisansalond
authored andcommitted
[GR-56523] Backport to 24.1: Fixes of performance regressions caused by resizable ArrayBuffers.
PullRequest: js/3215
2 parents 02e4c77 + b4040d3 commit 72541de

File tree

11 files changed

+305
-250
lines changed

11 files changed

+305
-250
lines changed

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public abstract static class GetBufferElementNode extends JavaScriptBaseNode {
271271
static Object doHeapArrayBuffer(JSArrayBufferObject.Heap buffer, int bufferIndex, boolean littleEndian, TypedArrayFactory factory) {
272272
assert !JSArrayBuffer.isJSInteropArrayBuffer(buffer) && !JSArrayBuffer.isJSDirectOrSharedArrayBuffer(buffer) : buffer;
273273
CompilerAsserts.partialEvaluationConstant(factory);
274-
TypedArray strategy = factory.createArrayType(false, true, false);
274+
TypedArray strategy = factory.createArrayType(TypedArray.BUFFER_TYPE_ARRAY, true, false);
275275
CompilerAsserts.partialEvaluationConstant(strategy);
276276
return strategy.getBufferElement(buffer, bufferIndex, littleEndian, null);
277277
}
@@ -280,7 +280,8 @@ static Object doHeapArrayBuffer(JSArrayBufferObject.Heap buffer, int bufferIndex
280280
static Object doDirectOrSharedArrayBuffer(JSArrayBufferObject.DirectBase buffer, int bufferIndex, boolean littleEndian, TypedArrayFactory factory) {
281281
assert !JSArrayBuffer.isJSInteropArrayBuffer(buffer) && JSArrayBuffer.isJSDirectOrSharedArrayBuffer(buffer) : buffer;
282282
CompilerAsserts.partialEvaluationConstant(factory);
283-
TypedArray strategy = factory.createArrayType(true, true, false);
283+
// It does not matter whether we use BUFFER_TYPE_DIRECT or BUFFER_TYPE_SHARED here
284+
TypedArray strategy = factory.createArrayType(TypedArray.BUFFER_TYPE_DIRECT, true, false);
284285
CompilerAsserts.partialEvaluationConstant(strategy);
285286
return strategy.getBufferElement(buffer, bufferIndex, littleEndian, null);
286287
}
@@ -290,7 +291,7 @@ static Object doInteropBuffer(JSArrayBufferObject.Interop buffer, int bufferInde
290291
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop) {
291292
assert JSArrayBuffer.isJSInteropArrayBuffer(buffer) && !JSArrayBuffer.isJSDirectOrSharedArrayBuffer(buffer) : buffer;
292293
CompilerAsserts.partialEvaluationConstant(factory);
293-
TypedArray strategy = factory.createArrayType(false, true, true);
294+
TypedArray strategy = factory.createArrayType(TypedArray.BUFFER_TYPE_INTEROP, true, false);
294295
CompilerAsserts.partialEvaluationConstant(strategy);
295296
return strategy.getBufferElement(buffer, bufferIndex, littleEndian, interop);
296297
}
@@ -352,7 +353,7 @@ public abstract static class SetBufferElementNode extends JavaScriptBaseNode {
352353
static void doHeapArrayBuffer(JSArrayBufferObject.Heap buffer, int bufferIndex, boolean littleEndian, Object value, TypedArrayFactory factory) {
353354
assert !JSArrayBuffer.isJSInteropArrayBuffer(buffer) && !JSArrayBuffer.isJSDirectOrSharedArrayBuffer(buffer) : buffer;
354355
CompilerAsserts.partialEvaluationConstant(factory);
355-
TypedArray strategy = factory.createArrayType(false, true, false);
356+
TypedArray strategy = factory.createArrayType(TypedArray.BUFFER_TYPE_ARRAY, true, false);
356357
CompilerAsserts.partialEvaluationConstant(strategy);
357358
strategy.setBufferElement(buffer, bufferIndex, littleEndian, value, null);
358359
}
@@ -361,7 +362,8 @@ static void doHeapArrayBuffer(JSArrayBufferObject.Heap buffer, int bufferIndex,
361362
static void doDirectOrSharedArrayBuffer(JSArrayBufferObject.DirectBase buffer, int bufferIndex, boolean littleEndian, Object value, TypedArrayFactory factory) {
362363
assert !JSArrayBuffer.isJSInteropArrayBuffer(buffer) && JSArrayBuffer.isJSDirectOrSharedArrayBuffer(buffer) : buffer;
363364
CompilerAsserts.partialEvaluationConstant(factory);
364-
TypedArray strategy = factory.createArrayType(true, true, false);
365+
// It does not matter whether we use BUFFER_TYPE_DIRECT or BUFFER_TYPE_SHARED here
366+
TypedArray strategy = factory.createArrayType(TypedArray.BUFFER_TYPE_DIRECT, true, false);
365367
CompilerAsserts.partialEvaluationConstant(strategy);
366368
strategy.setBufferElement(buffer, bufferIndex, littleEndian, value, null);
367369
}
@@ -371,7 +373,7 @@ static void doInteropBuffer(JSArrayBufferObject.Interop buffer, int bufferIndex,
371373
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop) {
372374
assert JSArrayBuffer.isJSInteropArrayBuffer(buffer) && !JSArrayBuffer.isJSDirectOrSharedArrayBuffer(buffer) : buffer;
373375
CompilerAsserts.partialEvaluationConstant(factory);
374-
TypedArray strategy = factory.createArrayType(false, true, true);
376+
TypedArray strategy = factory.createArrayType(TypedArray.BUFFER_TYPE_INTEROP, true, false);
375377
CompilerAsserts.partialEvaluationConstant(strategy);
376378
strategy.setBufferElement(buffer, bufferIndex, littleEndian, value, interop);
377379
}

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

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
*/
4141
package com.oracle.truffle.js.builtins;
4242

43+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_ARRAY;
44+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_DIRECT;
45+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_INTEROP;
46+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_SHARED;
47+
4348
import java.nio.ByteBuffer;
4449
import java.util.NoSuchElementException;
4550

@@ -181,19 +186,18 @@ private void checkDetachedBuffer(JSArrayBufferObject buffer) {
181186
protected JSDynamicObject doArrayBuffer(JSDynamicObject newTarget, JSArrayBufferObject arrayBuffer, Object byteOffset0, Object length0,
182187
@Cached @Shared InlinedConditionProfile lengthIsUndefined) {
183188
checkDetachedBuffer(arrayBuffer);
184-
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, false, false, this, lengthIsUndefined);
189+
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, BUFFER_TYPE_ARRAY, this, lengthIsUndefined);
185190
}
186191

187192
@Specialization(guards = {"!isUndefined(newTarget)", "isJSDirectArrayBuffer(arrayBuffer)"})
188193
protected JSDynamicObject doDirectArrayBuffer(JSDynamicObject newTarget, JSArrayBufferObject arrayBuffer, Object byteOffset0, Object length0,
189194
@Cached @Shared InlinedConditionProfile lengthIsUndefined) {
190195
checkDetachedBuffer(arrayBuffer);
191-
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, true, false, this, lengthIsUndefined);
196+
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, BUFFER_TYPE_DIRECT, this, lengthIsUndefined);
192197
}
193198

194199
private JSDynamicObject doArrayBufferImpl(JSArrayBufferObject arrayBuffer, Object byteOffset0, Object length0, JSDynamicObject newTarget,
195-
boolean direct, boolean isInteropBuffer,
196-
Node node, InlinedConditionProfile lengthIsUndefinedProfile) {
200+
byte bufferType, Node node, InlinedConditionProfile lengthIsUndefinedProfile) {
197201
final int elementSize = factory.getBytesPerElement();
198202

199203
final long byteOffset = toIndex(byteOffset0);
@@ -227,7 +231,7 @@ private JSDynamicObject doArrayBufferImpl(JSArrayBufferObject arrayBuffer, Objec
227231
}
228232

229233
assert byteOffset <= Integer.MAX_VALUE && length <= Integer.MAX_VALUE;
230-
TypedArray typedArray = factory.createArrayType(direct, byteOffset != 0, isInteropBuffer);
234+
TypedArray typedArray = factory.createArrayType(bufferType, byteOffset != 0, length != JSArrayBufferViewBase.AUTO_LENGTH);
231235
return createTypedArray(arrayBuffer, typedArray, (int) byteOffset, (int) length, newTarget);
232236
}
233237

@@ -242,7 +246,7 @@ private JSDynamicObject doArrayBufferImpl(JSArrayBufferObject arrayBuffer, Objec
242246
@Specialization(guards = {"!isUndefined(newTarget)", "isJSSharedArrayBuffer(arrayBuffer)"})
243247
protected JSDynamicObject doSharedArrayBuffer(JSDynamicObject newTarget, JSArrayBufferObject arrayBuffer, Object byteOffset0, Object length0,
244248
@Cached @Shared InlinedConditionProfile lengthIsUndefined) {
245-
return doDirectArrayBuffer(newTarget, arrayBuffer, byteOffset0, length0, lengthIsUndefined);
249+
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, BUFFER_TYPE_SHARED, this, lengthIsUndefined);
246250
}
247251

248252
/**
@@ -256,7 +260,7 @@ protected JSDynamicObject doSharedArrayBuffer(JSDynamicObject newTarget, JSArray
256260
@Specialization(guards = {"!isUndefined(newTarget)", "isJSInteropArrayBuffer(arrayBuffer)"})
257261
protected JSDynamicObject doInteropArrayBuffer(JSDynamicObject newTarget, JSArrayBufferObject arrayBuffer, Object byteOffset0, Object length0,
258262
@Cached @Shared InlinedConditionProfile lengthIsUndefined) {
259-
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, false, true, this, lengthIsUndefined);
263+
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, BUFFER_TYPE_INTEROP, this, lengthIsUndefined);
260264
}
261265

262266
/**
@@ -282,7 +286,7 @@ protected JSDynamicObject doTypedArray(JSDynamicObject newTarget, JSTypedArrayOb
282286
throw Errors.createTypeErrorCannotMixBigIntWithOtherTypes(this);
283287
}
284288

285-
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer(), false);
289+
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer() ? BUFFER_TYPE_DIRECT : BUFFER_TYPE_ARRAY, false, true);
286290
JSDynamicObject result = createTypedArray(arrayBuffer, typedArray, 0, (int) length, newTarget);
287291

288292
assert typedArray == JSArrayBufferView.typedArrayGetArrayType(result);
@@ -375,7 +379,7 @@ protected JSDynamicObject doObject(JSDynamicObject newTarget, JSObject object, @
375379
SimpleArrayList<Object> values = iterableToListNode.execute(getIteratorFromMethodNode.execute(node, object, usingIterator));
376380
int len = values.size();
377381
JSArrayBufferObject arrayBuffer = createTypedArrayBuffer(len);
378-
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer(), false);
382+
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer() ? BUFFER_TYPE_DIRECT : BUFFER_TYPE_ARRAY, false, true);
379383
JSDynamicObject obj = integerIndexedObjectCreate(arrayBuffer, typedArray, 0, len, proto);
380384
for (int k = 0; k < len; k++) {
381385
Object kValue = values.get(k);
@@ -388,7 +392,7 @@ protected JSDynamicObject doObject(JSDynamicObject newTarget, JSObject object, @
388392
long len = getLengthNode.executeLong(object);
389393
JSArrayBufferObject arrayBuffer = createTypedArrayBuffer(len);
390394
assert len <= Integer.MAX_VALUE;
391-
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer(), false);
395+
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer() ? BUFFER_TYPE_DIRECT : BUFFER_TYPE_ARRAY, false, true);
392396
JSDynamicObject obj = integerIndexedObjectCreate(arrayBuffer, typedArray, 0, (int) len, proto);
393397
for (int k = 0; k < len; k++) {
394398
Object kValue = readNode.executeWithTargetAndIndex(object, k);
@@ -409,7 +413,7 @@ protected JSDynamicObject doForeignObject(JSDynamicObject newTarget, Object obje
409413
if (interop.hasBufferElements(object)) {
410414
JSArrayBufferObject arrayBuffer = JSArrayBuffer.createInteropArrayBuffer(getContext(), getRealm(), object);
411415
checkLengthLimit(arrayBuffer.getByteLength(), 1);
412-
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, false, true, node, lengthIsUndefined);
416+
return doArrayBufferImpl(arrayBuffer, byteOffset0, length0, newTarget, BUFFER_TYPE_INTEROP, node, lengthIsUndefined);
413417
}
414418

415419
long length;
@@ -482,7 +486,7 @@ private JSArrayBufferObject createTypedArrayBuffer(long length) {
482486
*/
483487
private JSDynamicObject createTypedArrayWithLength(long length, JSDynamicObject newTarget) {
484488
JSArrayBufferObject arrayBuffer = createTypedArrayBuffer(length);
485-
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer(), false);
489+
TypedArray typedArray = factory.createArrayType(getContext().isOptionDirectByteBuffer() ? BUFFER_TYPE_DIRECT : BUFFER_TYPE_ARRAY, false, true);
486490
return createTypedArray(arrayBuffer, typedArray, 0, (int) length, newTarget);
487491
}
488492

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
*/
4141
package com.oracle.truffle.js.builtins;
4242

43+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_ARRAY;
44+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_DIRECT;
45+
import static com.oracle.truffle.js.runtime.array.TypedArray.BUFFER_TYPE_INTEROP;
4346
import static com.oracle.truffle.js.runtime.builtins.JSAbstractArray.arrayGetArrayType;
4447
import static com.oracle.truffle.js.runtime.builtins.JSArrayBufferView.typedArrayGetArrayType;
4548

@@ -536,7 +539,7 @@ private void setArrayBufferView(JSTypedArrayObject targetView, JSTypedArrayObjec
536539
sourceBuffer = cloneArrayBuffer(sourceBuffer, sourceArray, srcByteLength, srcByteOffset);
537540
if (sourceArray.isInterop()) {
538541
// cloned buffer is not an interop buffer anymore
539-
sourceArray = sourceArray.getFactory().createArrayType(getContext().isOptionDirectByteBuffer(), false);
542+
sourceArray = sourceArray.getFactory().createArrayType(getContext().isOptionDirectByteBuffer() ? BUFFER_TYPE_DIRECT : BUFFER_TYPE_ARRAY, false, true);
540543
}
541544
srcByteIndex = 0;
542545
}
@@ -693,8 +696,8 @@ private JSArrayBufferObject cloneArrayBuffer(JSArrayBufferObject sourceBuffer, T
693696
private JSArrayBufferObject cloneInteropArrayBuffer(JSArrayBufferObject sourceBuffer, int srcByteLength, int srcByteOffset, InteropLibrary interop) {
694697
assert JSArrayBuffer.isJSInteropArrayBuffer(sourceBuffer);
695698
boolean direct = getContext().isOptionDirectByteBuffer();
696-
TypedArray sourceType = TypedArrayFactory.Int8Array.createArrayType(false, false, true);
697-
TypedArray clonedType = TypedArrayFactory.Int8Array.createArrayType(direct, false);
699+
TypedArray sourceType = TypedArrayFactory.Int8Array.createArrayType(BUFFER_TYPE_INTEROP, false, true);
700+
TypedArray clonedType = TypedArrayFactory.Int8Array.createArrayType(direct ? BUFFER_TYPE_DIRECT : BUFFER_TYPE_ARRAY, false, true);
698701
JSArrayBufferObject clonedArrayBuffer = direct
699702
? JSArrayBuffer.createDirectArrayBuffer(getContext(), getRealm(), srcByteLength)
700703
: JSArrayBuffer.createArrayBuffer(getContext(), getRealm(), srcByteLength);

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/wasm/ExportByteSourceNode.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,17 @@ private Object exportBuffer(JSArrayBufferObject arrayBuffer, int offset, int len
115115
buffer = JSArrayBuffer.createArrayBuffer(context, realm, 0);
116116
}
117117
// Wrap ArrayBuffer into Uint8Array - to allow reading its bytes on WASM side
118-
boolean interop = JSArrayBuffer.isJSInteropArrayBuffer(arrayBuffer);
119-
boolean direct = JSArrayBuffer.isJSDirectArrayBuffer(arrayBuffer);
120-
TypedArray arrayType = TypedArrayFactory.Uint8Array.createArrayType(direct, (offset != 0), interop);
118+
byte bufferType;
119+
if (JSArrayBuffer.isJSInteropArrayBuffer(arrayBuffer)) {
120+
bufferType = TypedArray.BUFFER_TYPE_INTEROP;
121+
} else if (JSArrayBuffer.isJSHeapArrayBuffer(arrayBuffer)) {
122+
bufferType = TypedArray.BUFFER_TYPE_ARRAY;
123+
} else if (JSArrayBuffer.isJSDirectArrayBuffer(arrayBuffer)) {
124+
bufferType = TypedArray.BUFFER_TYPE_DIRECT;
125+
} else {
126+
bufferType = TypedArray.BUFFER_TYPE_SHARED;
127+
}
128+
TypedArray arrayType = TypedArrayFactory.Uint8Array.createArrayType(bufferType, (offset != 0), true);
121129
return JSArrayBufferView.createArrayBufferView(context, realm, buffer, arrayType, offset, length);
122130
}
123131

0 commit comments

Comments
 (0)