Skip to content

Commit 3b5a6a1

Browse files
committed
Allow block-wise splice to be used even when the new array length exceeds Integer.MAX_VALUE.
(cherry picked from commit 68dfdfb)
1 parent ed2687b commit 3b5a6a1

File tree

4 files changed

+19
-12
lines changed

4 files changed

+19
-12
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,7 +2037,7 @@ static void doCached(JSArrayObject array, long len, long actualStart, long actua
20372037
@Bind Node node,
20382038
@Cached @Shared GetPrototypeNode getPrototypeNode,
20392039
@Cached @Shared InlinedConditionProfile arrayElementwise) {
2040-
if (arrayElementwise.profile(node, parent.mustUseElementwise(array, len, actualDeleteCount, itemCount, cachedArrayType.cast(arrayType), getPrototypeNode))) {
2040+
if (arrayElementwise.profile(node, parent.mustUseElementwise(array, len, cachedArrayType.cast(arrayType), getPrototypeNode))) {
20412041
parent.spliceJSArrayElementwise(array, len, actualStart, actualDeleteCount, itemCount);
20422042
} else {
20432043
parent.spliceJSArrayBlockwise(array, actualStart, actualDeleteCount, itemCount, cachedArrayType.cast(arrayType));
@@ -2049,21 +2049,20 @@ static void doUncached(JSArrayObject array, long len, long actualStart, long act
20492049
@Bind Node node,
20502050
@Cached @Shared GetPrototypeNode getPrototypeNode,
20512051
@Cached @Shared InlinedConditionProfile arrayElementwise) {
2052-
if (arrayElementwise.profile(node, parent.mustUseElementwise(array, len, actualDeleteCount, itemCount, arrayType, getPrototypeNode))) {
2052+
if (arrayElementwise.profile(node, parent.mustUseElementwise(array, len, arrayType, getPrototypeNode))) {
20532053
parent.spliceJSArrayElementwise(array, len, actualStart, actualDeleteCount, itemCount);
20542054
} else {
20552055
parent.spliceJSArrayBlockwise(array, actualStart, actualDeleteCount, itemCount, arrayType);
20562056
}
20572057
}
20582058
}
20592059

2060-
final boolean mustUseElementwise(JSDynamicObject obj, long expectedLength, long deleteCount, long itemCount, ScriptArray array, GetPrototypeNode getPrototypeNode) {
2060+
final boolean mustUseElementwise(JSDynamicObject obj, long expectedLength, ScriptArray array, GetPrototypeNode getPrototypeNode) {
20612061
return array.isLengthNotWritable() ||
20622062
getPrototypeNode.execute(obj) != getRealm().getArrayPrototype() ||
20632063
!getContext().getArrayPrototypeNoElementsAssumption().isValid() ||
20642064
(!getContext().getFastArrayAssumption().isValid() && JSSlowArray.isJSSlowArray(obj)) ||
2065-
array.length(obj) != expectedLength ||
2066-
expectedLength + itemCount - deleteCount >= Integer.MAX_VALUE;
2065+
array.length(obj) != expectedLength;
20672066
}
20682067

20692068
private void spliceRead(Object thisObj, long actualStart, long actualDeleteCount, Object aObj, long length) {

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/access/WriteElementNode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,8 @@ protected boolean doConstantArray(JSDynamicObject target, AbstractConstantArray
823823
@Cached InlinedBranchProfile objectValueBranch,
824824
@Cached InlinedConditionProfile inBoundsIf,
825825
@Cached CreateWritableProfileAccess createWritableProfile) {
826-
if (inBoundsIf.profile(this, index >= 0 && index < 0x7fff_ffff)) {
826+
if (inBoundsIf.profile(this, index >= 0 && index < 0x7fff_ffff && constantArray.length(target) <= Integer.MAX_VALUE)) {
827+
// Note: createWritable* must only be used if the array length fits in int.
827828
ScriptArray newArray;
828829
if (value instanceof Integer) {
829830
intValueBranch.enter(this);

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/array/dyn/AbstractConstantArray.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -55,7 +55,7 @@ protected AbstractConstantArray(int integrityLevel, DynamicArrayCache cache) {
5555

5656
@Override
5757
public final ScriptArray setElementImpl(JSDynamicObject object, long index, Object value, boolean strict) {
58-
if (index <= Integer.MAX_VALUE) {
58+
if (index < Integer.MAX_VALUE && length(object) <= Integer.MAX_VALUE) {
5959
if (value instanceof Integer) {
6060
return createWriteableInt(object, index, (int) value, null, CreateWritableProfileAccess.getUncached()).setElementImpl(object, index, value, strict);
6161
} else if (value instanceof Double) {
@@ -86,7 +86,7 @@ public final Object getElementInBounds(JSDynamicObject object, long index) {
8686
public abstract Object getElementInBounds(JSDynamicObject object, int index);
8787

8888
@Override
89-
public final long length(JSDynamicObject object) {
89+
public long length(JSDynamicObject object) {
9090
return lengthInt(object);
9191
}
9292

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/array/dyn/AbstractConstantEmptyArray.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -73,8 +73,15 @@ public Object getElementInBounds(JSDynamicObject object, int index) {
7373
}
7474

7575
@Override
76-
public int lengthInt(JSDynamicObject object) {
77-
return (int) getCapacity(object);
76+
public final long length(JSDynamicObject object) {
77+
return getCapacity(object);
78+
}
79+
80+
@Override
81+
public final int lengthInt(JSDynamicObject object) {
82+
long capacity = getCapacity(object);
83+
assert JSRuntime.longIsRepresentableAsInt(capacity) : capacity;
84+
return (int) capacity;
7885
}
7986

8087
@Override

0 commit comments

Comments
 (0)