Skip to content

Commit 7a12edd

Browse files
committed
Vendor org.graalvm.collections
Motivation: Package org.graalvm.collections is used throughout the Pkl codebase. It is most heavily used in the Truffle interpreter, which requires putting most collection methods behind @TruffleBoundary. At the moment, this is done by wrapping collection methods with static methods declared in classes EconomicMaps and EconomicSets. However, static wrapper methods are inconvenient to use, decrease code readability, add some overhead, and are easy to forget about. Changes: - vendor package org.graalvm.collections into org.pkl.core.collection - org.graalvm.collections is licensed under: The Universal Permissive License (UPL), Version 1.0 - vendored version: https://github.com/oracle/graal/tree/graal-23.0.3/sdk/src/org.graalvm.collections/src/org/graalvm/collections - add package-info.java with original license - annotate most public methods with @TruffleBoundary - add @nullable annotations - switching to JSpecify will enable more accurate nullability checks - remove prefix tree classes (not used in Pkl) - make no other code changes to simplify review/updates - inline and remove EconomicMaps/Sets wrapper methods - replace usages of EconomicMaps.equals/hashCode with EconomicMapUtil.equals/hashCode - fix ProjectDeps.hashCode() Result: Cleaner, safer, and more efficient code.
1 parent 9a27616 commit 7a12edd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2608
-492
lines changed

pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java

+12-13
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import org.antlr.v4.runtime.Token;
3333
import org.antlr.v4.runtime.tree.ParseTree;
3434
import org.antlr.v4.runtime.tree.TerminalNode;
35-
import org.graalvm.collections.EconomicMap;
3635
import org.pkl.core.PClassInfo;
3736
import org.pkl.core.SecurityManagerException;
3837
import org.pkl.core.TypeParameter;
@@ -55,6 +54,7 @@
5554
import org.pkl.core.ast.lambda.ApplyVmFunction1NodeGen;
5655
import org.pkl.core.ast.member.*;
5756
import org.pkl.core.ast.type.*;
57+
import org.pkl.core.collection.EconomicMap;
5858
import org.pkl.core.externalreader.ExternalReaderProcessException;
5959
import org.pkl.core.module.ModuleKey;
6060
import org.pkl.core.module.ModuleKeys;
@@ -68,7 +68,6 @@
6868
import org.pkl.core.stdlib.registry.ExternalMemberRegistry;
6969
import org.pkl.core.stdlib.registry.MemberRegistryFactory;
7070
import org.pkl.core.util.CollectionUtils;
71-
import org.pkl.core.util.EconomicMaps;
7271
import org.pkl.core.util.IoUtils;
7372
import org.pkl.core.util.Nullable;
7473
import org.pkl.core.util.Pair;
@@ -217,7 +216,7 @@ public PklRootNode visitModule(ModuleContext ctx) {
217216

218217
for (var methodCtx : ctx.ms) {
219218
var localMethod = doVisitObjectMethod(methodCtx.methodHeader(), methodCtx.expr(), true);
220-
EconomicMaps.put(moduleProperties, localMethod.getName(), localMethod);
219+
moduleProperties.put(localMethod.getName(), localMethod);
221220
}
222221

223222
var moduleNode =
@@ -302,7 +301,7 @@ public ObjectMember visitClazz(ClazzContext ctx) {
302301
typeParameters,
303302
null,
304303
supertypeNode,
305-
EconomicMaps.create(),
304+
EconomicMap.create(),
306305
doVisitClassProperties(propertyCtxs, propertyNames),
307306
doVisitMethodDefs(methodCtxs));
308307

@@ -1065,7 +1064,7 @@ private ExpressionNode doVisitObjectBody(ObjectBodyContext ctx, ExpressionNode p
10651064
var parametersDescriptorBuilder = createFrameDescriptorBuilder(ctx);
10661065
var parameterTypes = doVisitParameterTypes(ctx);
10671066

1068-
var members = EconomicMaps.<Object, ObjectMember>create();
1067+
var members = EconomicMap.<Object, ObjectMember>create();
10691068
var elements = new ArrayList<ObjectMember>();
10701069
var keyNodes = new ArrayList<ExpressionNode>();
10711070
var values = new ArrayList<ObjectMember>();
@@ -1188,7 +1187,7 @@ private void addConstantEntries(
11881187
for (var i = 0; i < keyNodes.size(); i++) {
11891188
var key = ((ConstantNode) keyNodes.get(i)).getValue();
11901189
var value = values.get(i);
1191-
var previousValue = EconomicMaps.put(members, key, value);
1190+
var previousValue = members.put(key, value);
11921191
if (previousValue != null) {
11931192
CompilerDirectives.transferToInterpreter();
11941193
throw exceptionBuilder()
@@ -1310,7 +1309,7 @@ public ExpressionNode visitAnnotation(AnnotationContext ctx) {
13101309
currentScope.isCustomThisScope(),
13111310
null,
13121311
new UnresolvedTypeNode[0],
1313-
EconomicMaps.create(),
1312+
EconomicMap.create(),
13141313
verifyNode);
13151314
}
13161315

@@ -2606,12 +2605,12 @@ private EconomicMap<Object, ObjectMember> doVisitModuleProperties(
26062605
ModuleInfo moduleInfo) {
26072606

26082607
var totalSize = importCtxs.size() + classCtxs.size() + typeAliasCtxs.size();
2609-
var result = EconomicMaps.<Object, ObjectMember>create(totalSize);
2608+
var result = EconomicMap.<Object, ObjectMember>create(totalSize);
26102609

26112610
for (var ctx : importCtxs) {
26122611
var member = visitImportClause(ctx);
26132612
checkDuplicateMember(member.getName(), member.getHeaderSection(), propertyNames);
2614-
EconomicMaps.put(result, member.getName(), member);
2613+
result.put(member.getName(), member);
26152614
}
26162615

26172616
for (var ctx : classCtxs) {
@@ -2625,7 +2624,7 @@ private EconomicMap<Object, ObjectMember> doVisitModuleProperties(
26252624
}
26262625

26272626
checkDuplicateMember(member.getName(), member.getHeaderSection(), propertyNames);
2628-
EconomicMaps.put(result, member.getName(), member);
2627+
result.put(member.getName(), member);
26292628
}
26302629

26312630
for (TypeAliasContext ctx : typeAliasCtxs) {
@@ -2639,7 +2638,7 @@ private EconomicMap<Object, ObjectMember> doVisitModuleProperties(
26392638
}
26402639

26412640
checkDuplicateMember(member.getName(), member.getHeaderSection(), propertyNames);
2642-
EconomicMaps.put(result, member.getName(), member);
2641+
result.put(member.getName(), member);
26432642
}
26442643

26452644
for (var ctx : propertyCtxs) {
@@ -2660,7 +2659,7 @@ private EconomicMap<Object, ObjectMember> doVisitModuleProperties(
26602659
}
26612660

26622661
checkDuplicateMember(member.getName(), member.getHeaderSection(), propertyNames);
2663-
EconomicMaps.put(result, member.getName(), member);
2662+
result.put(member.getName(), member);
26642663
}
26652664

26662665
return result;
@@ -2684,7 +2683,7 @@ private void checkDuplicateMember(
26842683
// TODO: use Set<String> and checkDuplicateMember() to find duplicates between local and non-local
26852684
// properties
26862685
private void addProperty(EconomicMap<Object, ObjectMember> objectMembers, ObjectMember property) {
2687-
if (EconomicMaps.put(objectMembers, property.getName(), property) != null) {
2686+
if (objectMembers.put(property.getName(), property) != null) {
26882687
throw exceptionBuilder()
26892688
.evalError("duplicateDefinition", property.getName())
26902689
.withSourceSection(property.getHeaderSection())

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorElementNode.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.pkl.core.runtime.VmClass;
2525
import org.pkl.core.runtime.VmDynamic;
2626
import org.pkl.core.runtime.VmListing;
27-
import org.pkl.core.util.EconomicMaps;
2827

2928
@ImportStatic(BaseModule.class)
3029
public abstract class GeneratorElementNode extends GeneratorMemberNode {
@@ -68,7 +67,7 @@ void fallback(Object parent, ObjectData data) {
6867

6968
private void addElement(ObjectData data) {
7069
long index = data.length;
71-
EconomicMaps.put(data.members, index, element);
70+
data.members.put(index, element);
7271
data.length += 1;
7372
data.persistForBindings(index);
7473
}

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorEntryNode.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.pkl.core.ast.member.ObjectMember;
2626
import org.pkl.core.runtime.*;
2727
import org.pkl.core.runtime.VmException.ProgramValue;
28-
import org.pkl.core.util.EconomicMaps;
2928

3029
@ImportStatic(BaseModule.class)
3130
public abstract class GeneratorEntryNode extends GeneratorMemberNode {
@@ -112,7 +111,7 @@ private void addListingEntry(VirtualFrame frame, ObjectData data, int parentLeng
112111
}
113112

114113
private void doAdd(Object key, ObjectData data) {
115-
if (EconomicMaps.put(data.members, key, member) != null) {
114+
if (data.members.put(key, member) != null) {
116115
CompilerDirectives.transferToInterpreter();
117116
throw duplicateDefinition(key, member);
118117
}

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorMemberNode.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
import com.oracle.truffle.api.frame.VirtualFrame;
2323
import com.oracle.truffle.api.source.SourceSection;
2424
import java.util.Arrays;
25-
import org.graalvm.collections.EconomicMap;
2625
import org.pkl.core.ast.PklNode;
2726
import org.pkl.core.ast.member.ObjectMember;
27+
import org.pkl.core.collection.EconomicMap;
2828
import org.pkl.core.runtime.Identifier;
2929
import org.pkl.core.runtime.VmClass;
3030
import org.pkl.core.runtime.VmException;
3131
import org.pkl.core.runtime.VmException.ProgramValue;
32-
import org.pkl.core.util.EconomicMaps;
3332
import org.pkl.core.util.Nullable;
3433

3534
public abstract class GeneratorMemberNode extends PklNode {
@@ -81,7 +80,7 @@ protected boolean checkIsValidTypedProperty(VmClass clazz, ObjectMember member)
8180
public static final class ObjectData {
8281
// member count is exact iff every for/when body has exactly one member
8382
ObjectData(int minMemberCount, int length) {
84-
this.members = EconomicMaps.create(minMemberCount);
83+
this.members = EconomicMap.create(minMemberCount);
8584
this.length = length;
8685
}
8786

@@ -122,7 +121,7 @@ public static final class ObjectData {
122121
}
123122

124123
void persistForBindings(Object key) {
125-
EconomicMaps.put(forBindings, key, currentForBindings);
124+
forBindings.put(key, currentForBindings);
126125
}
127126

128127
void resetForBindings(Object @Nullable [] bindings) {

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorPredicateMemberNode.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
import org.pkl.core.ast.ExpressionNode;
2525
import org.pkl.core.ast.builder.SymbolTable.CustomThisScope;
2626
import org.pkl.core.ast.member.ObjectMember;
27+
import org.pkl.core.collection.EconomicSet;
2728
import org.pkl.core.runtime.*;
28-
import org.pkl.core.util.EconomicMaps;
29-
import org.pkl.core.util.EconomicSets;
3029

3130
public abstract class GeneratorPredicateMemberNode extends GeneratorMemberNode {
3231
@Child private ExpressionNode predicateNode;
@@ -81,15 +80,15 @@ private void addMembers(VirtualFrame frame, VmObject parent, ObjectData data) {
8180
initThisSlot(frame);
8281

8382
var previousValue = frame.getAuxiliarySlot(customThisSlot);
84-
var visitedKeys = EconomicSets.create();
83+
var visitedKeys = EconomicSet.create();
8584

8685
// do our own traversal instead of relying on `VmAbstractObject.force/iterateMemberValues`
8786
// (more efficient and we don't want to execute `predicateNode` behind Truffle boundary)
8887
for (var owner = parent; owner != null; owner = owner.getParent()) {
89-
var entries = EconomicMaps.getEntries(owner.getMembers());
88+
var entries = owner.getMembers().getEntries();
9089
while (entries.advance()) {
9190
var key = entries.getKey();
92-
if (!EconomicSets.add(visitedKeys, key)) continue;
91+
if (!visitedKeys.add(key)) continue;
9392

9493
var member = entries.getValue();
9594
if (member.isProp() || member.isLocal()) continue;
@@ -136,7 +135,7 @@ private void initThisSlot(VirtualFrame frame) {
136135
}
137136

138137
private void doAdd(Object key, ObjectData data) {
139-
if (EconomicMaps.put(data.members, key, member) != null) {
138+
if (data.members.put(key, member) != null) {
140139
CompilerDirectives.transferToInterpreter();
141140
throw duplicateDefinition(key, member);
142141
}

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorPropertyNode.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.oracle.truffle.api.dsl.Specialization;
2323
import org.pkl.core.ast.member.ObjectMember;
2424
import org.pkl.core.runtime.*;
25-
import org.pkl.core.util.EconomicMaps;
2625

2726
@ImportStatic({BaseModule.class, GeneratorObjectLiteralNode.class})
2827
public abstract class GeneratorPropertyNode extends GeneratorMemberNode {
@@ -118,7 +117,7 @@ protected boolean checkIsValidMappingProperty() {
118117
}
119118

120119
private void addProperty(ObjectData data) {
121-
if (EconomicMaps.put(data.members, member.getName(), member) == null) return;
120+
if (data.members.put(member.getName(), member) == null) return;
122121

123122
CompilerDirectives.transferToInterpreter();
124123
throw duplicateDefinition(member.getName(), member);

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorSpreadNode.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.pkl.core.runtime.VmObject;
4242
import org.pkl.core.runtime.VmTyped;
4343
import org.pkl.core.runtime.VmUtils;
44-
import org.pkl.core.util.EconomicMaps;
4544
import org.pkl.core.util.MutableLong;
4645

4746
@ImportStatic(BaseModule.class)
@@ -179,9 +178,9 @@ protected void doEvalDynamic(ObjectData data, VmObject iterable) {
179178
iterable.forceAndIterateMemberValues(
180179
(key, member, value) -> {
181180
if (member.isElement()) {
182-
EconomicMaps.put(data.members, length.getAndIncrement(), createMember(member, value));
181+
data.members.put(length.getAndIncrement(), createMember(member, value));
183182
} else {
184-
if (EconomicMaps.put(data.members, key, createMember(member, value)) != null) {
183+
if (data.members.put(key, createMember(member, value)) != null) {
185184
duplicateMember(key, member);
186185
}
187186
}
@@ -196,7 +195,7 @@ private void doEvalMapping(ObjectData data, VmObject iterable) {
196195
if (member.isElement() || member.isProp()) {
197196
cannotHaveMember(BaseModule.getMappingClass(), member);
198197
}
199-
if (EconomicMaps.put(data.members, key, createMember(member, value)) != null) {
198+
if (data.members.put(key, createMember(member, value)) != null) {
200199
duplicateMember(key, member);
201200
}
202201
return true;
@@ -210,7 +209,7 @@ private void doEvalListing(ObjectData data, VmObject iterable) {
210209
if (member.isEntry() || member.isProp()) {
211210
cannotHaveMember(getListingClass(), member);
212211
}
213-
EconomicMaps.put(data.members, length.getAndIncrement(), createMember(member, value));
212+
data.members.put(length.getAndIncrement(), createMember(member, value));
214213
return true;
215214
});
216215
data.length = (int) length.get();
@@ -223,7 +222,7 @@ private void doEvalTyped(VmClass clazz, ObjectData data, VmObject iterable) {
223222
cannotHaveMember(clazz, member);
224223
}
225224
checkTypedProperty(clazz, member);
226-
if (EconomicMaps.put(data.members, key, createMember(member, value)) != null) {
225+
if (data.members.put(key, createMember(member, value)) != null) {
227226
duplicateMember(key, member);
228227
}
229228
return true;
@@ -255,7 +254,7 @@ private void doEvalMap(VmClass parent, ObjectData data, VmMap iterable) {
255254
}
256255
for (var entry : iterable) {
257256
var member = VmUtils.createSyntheticObjectEntry("", VmUtils.getValue(entry));
258-
if (EconomicMaps.put(data.members, VmUtils.getKey(entry), member) != null) {
257+
if (data.members.put(VmUtils.getKey(entry), member) != null) {
259258
duplicateMember(VmUtils.getKey(entry), member);
260259
}
261260
}
@@ -337,7 +336,7 @@ private void spreadIterable(ObjectData data, Iterable<?> iterable) {
337336
for (var elem : iterable) {
338337
var index = length++;
339338
var member = VmUtils.createSyntheticObjectElement(String.valueOf(index), elem);
340-
EconomicMaps.put(data.members, (long) index, member);
339+
data.members.put((long) index, member);
341340
}
342341
data.length = length;
343342
}

pkl-core/src/main/java/org/pkl/core/ast/expression/generator/WriteForVariablesNode.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@
1717

1818
import com.oracle.truffle.api.frame.VirtualFrame;
1919
import com.oracle.truffle.api.nodes.ExplodeLoop;
20-
import org.graalvm.collections.UnmodifiableEconomicMap;
2120
import org.pkl.core.ast.ExpressionNode;
21+
import org.pkl.core.collection.UnmodifiableEconomicMap;
2222
import org.pkl.core.runtime.VmUtils;
23-
import org.pkl.core.util.EconomicMaps;
2423

2524
public final class WriteForVariablesNode extends ExpressionNode {
2625
private final int[] auxiliarySlots;
@@ -39,7 +38,7 @@ public Object executeGeneric(VirtualFrame frame) {
3938

4039
@SuppressWarnings("unchecked")
4140
var forBindings = (UnmodifiableEconomicMap<Object, Object[]>) extraStorage;
42-
var bindings = EconomicMaps.get(forBindings, VmUtils.getMemberKey(frame));
41+
var bindings = forBindings.get(VmUtils.getMemberKey(frame));
4342
assert bindings != null;
4443
assert bindings.length == auxiliarySlots.length;
4544

pkl-core/src/main/java/org/pkl/core/ast/expression/literal/AmendModuleNode.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
import com.oracle.truffle.api.dsl.Specialization;
2121
import com.oracle.truffle.api.frame.VirtualFrame;
2222
import com.oracle.truffle.api.source.SourceSection;
23-
import org.graalvm.collections.EconomicMap;
2423
import org.pkl.core.ast.ExpressionNode;
2524
import org.pkl.core.ast.member.ObjectMember;
2625
import org.pkl.core.ast.type.UnresolvedTypeNode;
26+
import org.pkl.core.collection.EconomicMap;
2727
import org.pkl.core.runtime.ModuleInfo;
2828
import org.pkl.core.runtime.VmLanguage;
2929
import org.pkl.core.runtime.VmTyped;

pkl-core/src/main/java/org/pkl/core/ast/expression/literal/ConstantEntriesLiteralNode.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
import com.oracle.truffle.api.frame.FrameDescriptor;
2222
import com.oracle.truffle.api.frame.VirtualFrame;
2323
import com.oracle.truffle.api.source.SourceSection;
24-
import org.graalvm.collections.UnmodifiableEconomicMap;
2524
import org.pkl.core.ast.ExpressionNode;
2625
import org.pkl.core.ast.member.ObjectMember;
2726
import org.pkl.core.ast.type.UnresolvedTypeNode;
27+
import org.pkl.core.collection.UnmodifiableEconomicMap;
2828
import org.pkl.core.runtime.*;
2929
import org.pkl.core.util.Nullable;
3030

pkl-core/src/main/java/org/pkl/core/ast/expression/literal/ElementsEntriesLiteralNode.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
import com.oracle.truffle.api.frame.VirtualFrame;
2525
import com.oracle.truffle.api.nodes.ExplodeLoop;
2626
import com.oracle.truffle.api.source.SourceSection;
27-
import org.graalvm.collections.UnmodifiableEconomicMap;
2827
import org.pkl.core.ast.ExpressionNode;
2928
import org.pkl.core.ast.member.ObjectMember;
3029
import org.pkl.core.ast.type.UnresolvedTypeNode;
30+
import org.pkl.core.collection.EconomicMap;
31+
import org.pkl.core.collection.UnmodifiableEconomicMap;
3132
import org.pkl.core.runtime.*;
32-
import org.pkl.core.util.EconomicMaps;
3333
import org.pkl.core.util.Nullable;
3434

3535
/**
@@ -152,15 +152,15 @@ protected void fallback(Object parent) {
152152
protected UnmodifiableEconomicMap<Object, ObjectMember> createMembers(
153153
VirtualFrame frame, int parentLength) {
154154
var result =
155-
EconomicMaps.<Object, ObjectMember>create(
156-
EconomicMaps.size(members) + keyNodes.length + elements.length);
155+
EconomicMap.<Object, ObjectMember>create(
156+
members.size() + keyNodes.length + elements.length);
157157

158-
EconomicMaps.putAll(result, members);
158+
result.putAll(members);
159159

160160
addListEntries(frame, parentLength, result, keyNodes, values);
161161

162162
for (var i = 0; i < elements.length; i++) {
163-
EconomicMaps.put(result, (long) (parentLength + i), elements[i]);
163+
result.put((long) (parentLength + i), elements[i]);
164164
}
165165

166166
return result;

0 commit comments

Comments
 (0)