Skip to content

Commit 254200a

Browse files
committed
[GR-24628] Opencerts optimizations
PullRequest: js/1569
2 parents c212ac8 + 3839eae commit 254200a

File tree

3 files changed

+43
-26
lines changed

3 files changed

+43
-26
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import com.oracle.truffle.js.runtime.objects.JSObject;
7878
import com.oracle.truffle.js.runtime.objects.JSObjectUtil;
7979
import com.oracle.truffle.js.runtime.objects.Undefined;
80+
import com.oracle.truffle.js.runtime.util.StringBuilderProfile;
8081

8182
/**
8283
* Contains builtins for {@linkplain JSON} function (constructor).
@@ -271,7 +272,22 @@ private static void addToReplacer(List<String> replacerList, String item) {
271272
}
272273

273274
@SuppressWarnings("unused")
274-
@Specialization(guards = {"!isCallable(replacer)", "!isArray(replacer)"})
275+
@Specialization(guards = {"isString(value)", "!isCallable(replacer)", "!isArray(replacer)"})
276+
// GR-24628: JSON.stringify is frequently called with (just) a String argument
277+
protected Object stringifyAStringNoReplacer(Object value, Object replacer, Object spaceParam,
278+
@Cached("createStringBuilderProfile()") StringBuilderProfile stringBuilderProfile) {
279+
String str = JSRuntime.toStringIsString(value);
280+
StringBuilder builder = new StringBuilder(str.length() + 8);
281+
JSONStringifyStringNode.jsonQuote(stringBuilderProfile, builder, str);
282+
return stringBuilderProfile.toString(builder);
283+
}
284+
285+
protected StringBuilderProfile createStringBuilderProfile() {
286+
return StringBuilderProfile.create(getContext().getStringLengthLimit());
287+
}
288+
289+
@SuppressWarnings("unused")
290+
@Specialization(guards = {"!isString(value)", "!isCallable(replacer)", "!isArray(replacer)"})
275291
protected Object stringifyNoReplacer(Object value, Object replacer, Object spaceParam) {
276292
return stringifyIntl(value, spaceParam, null, null);
277293
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,8 @@ private void setFastArray(DynamicObject thisObj, DynamicObject array, int offset
384384
assert JSArray.isJSFastArray(array);
385385
boolean sourceCondition = JSArray.isJSArray(array);
386386
boolean targetCondition = JSArrayBufferView.isJSArrayBufferView(thisObj);
387-
ScriptArray sourceArray = arrayGetArrayType(array, sourceCondition);
388-
TypedArray targetArray = JSArrayBufferView.typedArrayGetArrayType(thisObj, targetCondition);
387+
ScriptArray sourceArray = sourceArrayProf.profile(arrayGetArrayType(array, sourceCondition));
388+
TypedArray targetArray = targetArrayProf.profile(JSArrayBufferView.typedArrayGetArrayType(thisObj, targetCondition));
389389
long sourceLen = sourceArray.length(array, sourceCondition);
390390
rangeCheck(0, sourceLen, offset, targetArray.length(thisObj, targetCondition));
391391

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/helper/JSONStringifyStringNode.java

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, 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
@@ -121,7 +121,7 @@ private void jsonStrExecute(StringBuilder builder, JSONData data, Object value)
121121
} else if (value instanceof Boolean) {
122122
stringBuilderProfile.append(builder, (boolean) value ? JSBoolean.TRUE_NAME : JSBoolean.FALSE_NAME);
123123
} else if (JSRuntime.isString(value)) {
124-
jsonQuote(builder, value.toString());
124+
jsonQuote(stringBuilderProfile, builder, value.toString());
125125
} else if (JSRuntime.isNumber(value)) {
126126
appendNumber(builder, (Number) value);
127127
} else if (JSRuntime.isBigInt(value)) {
@@ -138,7 +138,7 @@ private void jsonStrExecute(StringBuilder builder, JSONData data, Object value)
138138
jsonForeignObject(builder, data, value);
139139
} else if (JSRuntime.isJavaPrimitive(value)) {
140140
// call toString on Java objects, GR-3722
141-
jsonQuote(builder, value.toString());
141+
jsonQuote(stringBuilderProfile, builder, value.toString());
142142
} else {
143143
throw new RuntimeException("JSON.stringify: should never reach here, unknown type: " + value + " " + value.getClass());
144144
}
@@ -186,24 +186,24 @@ private Object jsonStrPrepare(JSONData data, String key, Object holder) {
186186
@TruffleBoundary
187187
private Object jsonStrPrepareArray(JSONData data, int key, DynamicObject holder) {
188188
Object value = JSObject.get(holder, key);
189-
return jsonStrPreparePart2(data, key, holder, value);
189+
return jsonStrPreparePart2(data, String.valueOf(key), holder, value);
190190
}
191191

192192
@TruffleBoundary
193193
private Object jsonStrPrepareForeign(JSONData data, int key, Object holder) {
194194
assert JSGuards.isForeignObject(holder);
195195
Object value = truffleRead(holder, key);
196-
return jsonStrPreparePart2(data, key, holder, value);
196+
return jsonStrPreparePart2(data, String.valueOf(key), holder, value);
197197
}
198198

199-
private Object jsonStrPreparePart2(JSONData data, Object key, Object holder, Object valueArg) {
199+
private Object jsonStrPreparePart2(JSONData data, String key, Object holder, Object valueArg) {
200200
Object value = valueArg;
201201
if (JSRuntime.isObject(value) || JSRuntime.isBigInt(value)) {
202-
value = jsonStrPrepareObject(JSRuntime.toPropertyKey(key), value);
202+
value = jsonStrPrepareObject(key, value);
203203
}
204204

205205
if (data.getReplacerFnObj() != null) {
206-
value = JSRuntime.call(data.getReplacerFnObj(), holder, new Object[]{JSRuntime.toPropertyKey(key), value});
206+
value = JSRuntime.call(data.getReplacerFnObj(), holder, new Object[]{key, value});
207207
}
208208
if (JSObject.isJSObject(value)) {
209209
return jsonStrPrepareJSObject((DynamicObject) value);
@@ -292,7 +292,7 @@ private boolean serializeJSONObjectProperties(StringBuilder builder, JSONData da
292292
} else {
293293
appendSeparator(builder, data, indent);
294294
}
295-
jsonQuote(builder, name);
295+
jsonQuote(stringBuilderProfile, builder, name);
296296
appendColon(builder, data);
297297
jsonStrExecute(builder, data, strPPrepared);
298298
hasContent = true;
@@ -335,7 +335,7 @@ private boolean serializeForeignObjectProperties(StringBuilder builder, JSONData
335335
} else {
336336
appendSeparator(builder, data, indent);
337337
}
338-
jsonQuote(builder, stringKey);
338+
jsonQuote(stringBuilderProfile, builder, stringKey);
339339
appendColon(builder, data);
340340
jsonStrExecute(builder, data, strPPrepared);
341341
hasContent = true;
@@ -453,7 +453,8 @@ private static void checkCycle(JSONData data, Object value) {
453453
}
454454
}
455455

456-
private void jsonQuote(StringBuilder builder, String value) {
456+
@TruffleBoundary
457+
public static void jsonQuote(StringBuilderProfile stringBuilderProfile, StringBuilder builder, String value) {
457458
stringBuilderProfile.append(builder, '"');
458459
for (int i = 0; i < value.length();) {
459460
char ch = value.charAt(i);
@@ -469,7 +470,7 @@ private void jsonQuote(StringBuilder builder, String value) {
469470
} else if (ch == '\t') {
470471
stringBuilderProfile.append(builder, "\\t");
471472
} else {
472-
jsonQuoteUnicode(builder, ch);
473+
jsonQuoteUnicode(stringBuilderProfile, builder, ch);
473474
}
474475
} else {
475476
if (ch == '\\') {
@@ -486,11 +487,11 @@ private void jsonQuote(StringBuilder builder, String value) {
486487
i++;
487488
} else {
488489
// unpaired high surrogate
489-
jsonQuoteSurrogate(builder, ch);
490+
jsonQuoteSurrogate(stringBuilderProfile, builder, ch);
490491
}
491492
} else {
492493
// unpaired low surrogate
493-
jsonQuoteSurrogate(builder, ch);
494+
jsonQuoteSurrogate(stringBuilderProfile, builder, ch);
494495
}
495496
} else {
496497
stringBuilderProfile.append(builder, ch);
@@ -501,17 +502,17 @@ private void jsonQuote(StringBuilder builder, String value) {
501502
stringBuilderProfile.append(builder, '"');
502503
}
503504

504-
private void jsonQuoteUnicode(StringBuilder builder, char c) {
505-
stringBuilderProfile.append(builder, "\\u00");
506-
stringBuilderProfile.append(builder, Character.forDigit((c >> 4) & 0xF, 16));
507-
stringBuilderProfile.append(builder, Character.forDigit(c & 0xF, 16));
505+
private static void jsonQuoteUnicode(StringBuilderProfile profile, StringBuilder builder, char c) {
506+
profile.append(builder, "\\u00");
507+
profile.append(builder, Character.forDigit((c >> 4) & 0xF, 16));
508+
profile.append(builder, Character.forDigit(c & 0xF, 16));
508509
}
509510

510-
private void jsonQuoteSurrogate(StringBuilder builder, char c) {
511-
stringBuilderProfile.append(builder, "\\ud");
512-
stringBuilderProfile.append(builder, Character.forDigit((c >> 8) & 0xF, 16));
513-
stringBuilderProfile.append(builder, Character.forDigit((c >> 4) & 0xF, 16));
514-
stringBuilderProfile.append(builder, Character.forDigit(c & 0xF, 16));
511+
private static void jsonQuoteSurrogate(StringBuilderProfile profile, StringBuilder builder, char c) {
512+
profile.append(builder, "\\ud");
513+
profile.append(builder, Character.forDigit((c >> 8) & 0xF, 16));
514+
profile.append(builder, Character.forDigit((c >> 4) & 0xF, 16));
515+
profile.append(builder, Character.forDigit(c & 0xF, 16));
515516
}
516517

517518
private Object truffleGetSize(Object obj) {

0 commit comments

Comments
 (0)