Skip to content

Commit 327ab99

Browse files
committed
Ensure that inverted maps of symbols are not stored in aux engine cache.
1 parent ccada47 commit 327ab99

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/lang/JavaScriptLanguage.java

Lines changed: 13 additions & 1 deletion
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, 2024, 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
@@ -186,6 +186,8 @@ public final class JavaScriptLanguage extends TruffleLanguage<JSRealm> {
186186
ensureErrorClassesInitialized();
187187
}
188188

189+
private int realmCount;
190+
189191
public JavaScriptLanguage() {
190192
this.promiseJobsQueueEmptyAssumption = Truffle.getRuntime().createAssumption("PromiseJobsQueueEmpty");
191193
}
@@ -359,6 +361,9 @@ private JSContext newJSContext(Env env) {
359361

360362
@Override
361363
protected void initializeContext(JSRealm realm) {
364+
synchronized (this) {
365+
realmCount++;
366+
}
362367
realm.initialize();
363368
}
364369

@@ -457,6 +462,13 @@ protected void disposeContext(JSRealm realm) {
457462
realm.getContext().getTimeProfiler().printCumulative();
458463
}
459464
realm.dispose();
465+
synchronized (this) {
466+
if (--realmCount == 0) {
467+
// Clear inverted maps that are no longer needed to ensure
468+
// that they are not stored in aux engine cache
469+
realm.getContext().clearSymbolInvertedMaps();
470+
}
471+
}
460472
}
461473

462474
@Override

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/JSContext.java

Lines changed: 16 additions & 1 deletion
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, 2024, 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
@@ -269,6 +269,21 @@ public class JSContext {
269269
// Used to track singleton symbols allocations across aux engine cache runs.
270270
private Object symbolUsageMarker = new Object();
271271

272+
private final Map<Symbol, Void> unregisteredSymbols = new WeakHashMap<>();
273+
274+
@TruffleBoundary
275+
public void unregisteredSymbolCreated(Symbol symbol) {
276+
synchronized (this) {
277+
unregisteredSymbols.put(symbol, null);
278+
}
279+
}
280+
281+
public void clearSymbolInvertedMaps() {
282+
for (Symbol symbol : unregisteredSymbols.keySet()) {
283+
symbol.clearInvertedMap();
284+
}
285+
}
286+
272287
public void resetSymbolUsageMarker() {
273288
CompilerAsserts.neverPartOfCompilation();
274289
// Symbols that were used exactly once in previous executions, will most-likely

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/Symbol.java

Lines changed: 25 additions & 14 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, 2024, 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
@@ -69,67 +69,67 @@ public final class Symbol implements TruffleObject {
6969
* A method that determines if a constructor object recognizes an object as one of the
7070
* constructor's instances. Called by the semantics of the instanceof operator.
7171
*/
72-
public static final Symbol SYMBOL_HAS_INSTANCE = Symbol.create(Strings.constant("Symbol.hasInstance"));
72+
public static final Symbol SYMBOL_HAS_INSTANCE = createWellKnown(Strings.constant("Symbol.hasInstance"));
7373
/**
7474
* A Boolean valued property that if true indicates that an object should be flatten to its
7575
* array elements by Array.prototype.concat.
7676
*/
77-
public static final Symbol SYMBOL_IS_CONCAT_SPREADABLE = Symbol.create(Strings.constant("Symbol.isConcatSpreadable"));
77+
public static final Symbol SYMBOL_IS_CONCAT_SPREADABLE = createWellKnown(Strings.constant("Symbol.isConcatSpreadable"));
7878
/**
7979
* A method that returns the default iterator for an object. Called by the semantics of the
8080
* for-of statement.
8181
*/
82-
public static final Symbol SYMBOL_ITERATOR = Symbol.create(Strings.constant("Symbol.iterator"));
82+
public static final Symbol SYMBOL_ITERATOR = createWellKnown(Strings.constant("Symbol.iterator"));
8383
/**
8484
* A method that returns the default asynchronous iterator for an object. Called by the
8585
* semantics of the for-await-of statement.
8686
*/
87-
public static final Symbol SYMBOL_ASYNC_ITERATOR = Symbol.create(Strings.constant("Symbol.asyncIterator"));
87+
public static final Symbol SYMBOL_ASYNC_ITERATOR = createWellKnown(Strings.constant("Symbol.asyncIterator"));
8888
/**
8989
* A regular expression method that matches the regular expression against a string. Called by
9090
* the String.prototype.match method.
9191
*/
92-
public static final Symbol SYMBOL_MATCH = Symbol.create(Strings.constant("Symbol.match"));
92+
public static final Symbol SYMBOL_MATCH = createWellKnown(Strings.constant("Symbol.match"));
9393
/**
9494
* A regular expression method that returns an iterator, that yields matches of the regular
9595
* expression against a string. Called by the String.prototype.matchAll method.
9696
*/
97-
public static final Symbol SYMBOL_MATCH_ALL = Symbol.create(Strings.constant("Symbol.matchAll"));
97+
public static final Symbol SYMBOL_MATCH_ALL = createWellKnown(Strings.constant("Symbol.matchAll"));
9898
/**
9999
* A regular expression method that replaces matched substrings of a string. Called by the
100100
* String.prototype.replace method.
101101
*/
102-
public static final Symbol SYMBOL_REPLACE = Symbol.create(Strings.constant("Symbol.replace"));
102+
public static final Symbol SYMBOL_REPLACE = createWellKnown(Strings.constant("Symbol.replace"));
103103
/**
104104
* A regular expression method that returns the index within a string that matches the regular
105105
* expression. Called by the String.prototype.search method.
106106
*/
107-
public static final Symbol SYMBOL_SEARCH = Symbol.create(Strings.constant("Symbol.search"));
107+
public static final Symbol SYMBOL_SEARCH = createWellKnown(Strings.constant("Symbol.search"));
108108
/**
109109
* A function valued property that is the constructor function that is used to create derived
110110
* objects.
111111
*/
112-
public static final Symbol SYMBOL_SPECIES = Symbol.create(Strings.constant("Symbol.species"));
112+
public static final Symbol SYMBOL_SPECIES = createWellKnown(Strings.constant("Symbol.species"));
113113
/**
114114
* A regular expression method that splits a string at the indices that match the regular
115115
* expression. Called by the String.prototype.split method.
116116
*/
117-
public static final Symbol SYMBOL_SPLIT = Symbol.create(Strings.constant("Symbol.split"));
117+
public static final Symbol SYMBOL_SPLIT = createWellKnown(Strings.constant("Symbol.split"));
118118
/**
119119
* A method that converts an object to a corresponding primitive value. Called by the
120120
* ToPrimitive abstract operation.
121121
*/
122-
public static final Symbol SYMBOL_TO_PRIMITIVE = Symbol.create(Strings.constant("Symbol.toPrimitive"));
122+
public static final Symbol SYMBOL_TO_PRIMITIVE = createWellKnown(Strings.constant("Symbol.toPrimitive"));
123123
/**
124124
* A property whose String value that is used in the creation of the default string description
125125
* of an object. Called by the built-in method Object.prototype.toString.
126126
*/
127-
public static final Symbol SYMBOL_TO_STRING_TAG = Symbol.create(Strings.constant("Symbol.toStringTag"));
127+
public static final Symbol SYMBOL_TO_STRING_TAG = createWellKnown(Strings.constant("Symbol.toStringTag"));
128128
/**
129129
* A property whose value is an Object whose own property names are property names that are
130130
* excluded from the with environment bindings of the associated object.
131131
*/
132-
public static final Symbol SYMBOL_UNSCOPABLES = Symbol.create(Strings.constant("Symbol.unscopables"));
132+
public static final Symbol SYMBOL_UNSCOPABLES = createWellKnown(Strings.constant("Symbol.unscopables"));
133133

134134
/**
135135
* [[Description]] of Symbol if it is a String value, {@code null} otherwise ([[Description]] is
@@ -154,6 +154,12 @@ private Symbol(TruffleString description, boolean registered, boolean isPrivate)
154154
}
155155

156156
public static Symbol create(TruffleString description) {
157+
Symbol symbol = new Symbol(description, false, false);
158+
JavaScriptLanguage.getCurrentLanguage().getJSContext().unregisteredSymbolCreated(symbol);
159+
return symbol;
160+
}
161+
162+
private static Symbol createWellKnown(TruffleString description) {
157163
return new Symbol(description, false, false);
158164
}
159165

@@ -269,4 +275,9 @@ public void setInvertedMap(Map<WeakMap, Object> invMap) {
269275
assert this.invertedMap == null;
270276
this.invertedMap = invMap;
271277
}
278+
279+
void clearInvertedMap() {
280+
this.invertedMap = null;
281+
}
282+
272283
}

0 commit comments

Comments
 (0)