Skip to content

Commit 64724e7

Browse files
committed
Implement Atomics.pause proposal.
1 parent df18e59 commit 64724e7

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.oracle.truffle.api.dsl.Bind;
4646
import com.oracle.truffle.api.dsl.Cached;
4747
import com.oracle.truffle.api.dsl.Cached.Shared;
48+
import com.oracle.truffle.api.dsl.Fallback;
4849
import com.oracle.truffle.api.dsl.ImportStatic;
4950
import com.oracle.truffle.api.dsl.Specialization;
5051
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -57,6 +58,7 @@
5758
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsIsLockFreeNodeGen;
5859
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsLoadNodeGen;
5960
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsNotifyNodeGen;
61+
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsPauseNodeGen;
6062
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsStoreNodeGen;
6163
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsWaitAsyncNodeGen;
6264
import com.oracle.truffle.js.builtins.AtomicsBuiltinsFactory.AtomicsWaitNodeGen;
@@ -147,7 +149,9 @@ public enum Atomics implements BuiltinEnum<Atomics> {
147149
notify(3),
148150

149151
// ES 2024
150-
waitAsync(4);
152+
waitAsync(4),
153+
154+
pause(0);
151155

152156
private final int length;
153157

@@ -165,6 +169,7 @@ public int getECMAScriptVersion() {
165169
return switch (this) {
166170
case notify -> JSConfig.ECMAScript2019;
167171
case waitAsync -> JSConfig.ECMAScript2024;
172+
case pause -> JSConfig.StagingECMAScriptVersion;
168173
default -> JSConfig.ECMAScript2017;
169174
};
170175
}
@@ -206,6 +211,8 @@ protected Object createNode(JSContext context, JSBuiltin builtin, boolean constr
206211
return AtomicsIsLockFreeNodeGen.create(context, builtin, args().fixedArgs(1).createArgumentNodes(context));
207212
case waitAsync:
208213
return AtomicsWaitAsyncNodeGen.create(context, builtin, args().fixedArgs(4).createArgumentNodes(context));
214+
case pause:
215+
return AtomicsPauseNodeGen.create(context, builtin, args().fixedArgs(1).createArgumentNodes(context));
209216
}
210217
return null;
211218
}
@@ -1264,6 +1271,45 @@ protected Object doGeneric(VirtualFrame frame, Object maybeTarget, Object index,
12641271
}
12651272
}
12661273

1274+
@ImportStatic({JSRuntime.class})
1275+
public abstract static class AtomicsPauseNode extends JSBuiltinNode {
1276+
1277+
protected AtomicsPauseNode(JSContext context, JSBuiltin builtin) {
1278+
super(context, builtin);
1279+
}
1280+
1281+
@SuppressWarnings("unused")
1282+
@Specialization(guards = "isUndefined(n)")
1283+
protected static Object pauseOnce(Object n) {
1284+
Thread.onSpinWait();
1285+
return Undefined.instance;
1286+
}
1287+
1288+
@Specialization
1289+
protected static Object pauseInt(int n) {
1290+
for (int i = 0; i < n; i++) {
1291+
Thread.onSpinWait();
1292+
}
1293+
return Undefined.instance;
1294+
}
1295+
1296+
@Specialization(guards = "isIntegralNumber(n)")
1297+
protected static Object pauseDouble(double n) {
1298+
return pauseInt((int) n);
1299+
}
1300+
1301+
@Specialization
1302+
protected static Object pauseLong(long n) {
1303+
return pauseInt((int) Math.min(Math.max(n, 0), Integer.MAX_VALUE));
1304+
}
1305+
1306+
@SuppressWarnings("unused")
1307+
@Fallback
1308+
protected static Object illegalArgument(Object n) {
1309+
throw Errors.createTypeError("Atomics.pause argument must be undefined or an integer");
1310+
}
1311+
}
1312+
12671313
/**
12681314
* Lock-free regions checking.
12691315
*/

0 commit comments

Comments
 (0)