Skip to content

Commit 36a412c

Browse files
committed
[GR-19220] Reduce empty array memory
PullRequest: truffleruby/4230
2 parents 5819d67 + 235c7ef commit 36a412c

File tree

5 files changed

+30
-8
lines changed

5 files changed

+30
-8
lines changed

src/main/java/org/truffleruby/core/array/MultipleAssignmentNode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ public RubyNode cloneUninitialized() {
144144
}
145145

146146
protected AssignableNode[] cloneUninitializedAssignable(AssignableNode[] nodes) {
147+
if (nodes.length == 0) {
148+
return AssignableNode.EMPTY_ARRAY;
149+
}
150+
147151
AssignableNode[] copies = new AssignableNode[nodes.length];
148152
for (int i = 0; i < nodes.length; i++) {
149153
copies[i] = nodes[i].cloneUninitializedAssignable();

src/main/java/org/truffleruby/core/kernel/KernelNodes.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ RubyClass getClass(Object self) {
416416
@GenerateInline(inlineByDefault = true)
417417
public abstract static class CopyInstanceVariablesNode extends RubyBaseNode {
418418

419+
public static final DynamicObjectLibrary[] EMPTY_DYNAMIC_OBJECT_LIBRARY_ARRAY = new DynamicObjectLibrary[0];
419420
public static final PropertyGetter[] EMPTY_PROPERTY_GETTER_ARRAY = new PropertyGetter[0];
420421

421422
public abstract RubyDynamicObject execute(Node node, RubyDynamicObject newObject, RubyDynamicObject from);
@@ -466,6 +467,10 @@ protected static PropertyGetter[] getCopiedProperties(Shape shape) {
466467
}
467468

468469
protected DynamicObjectLibrary[] createWriteFieldNodes(PropertyGetter[] propertyGetters) {
470+
if (propertyGetters.length == 0) {
471+
return EMPTY_DYNAMIC_OBJECT_LIBRARY_ARRAY;
472+
}
473+
469474
final DynamicObjectLibrary[] nodes = new DynamicObjectLibrary[propertyGetters.length];
470475
for (int i = 0; i < propertyGetters.length; i++) {
471476
nodes[i] = DynamicObjectLibrary.getFactory().createDispatched(1);

src/main/java/org/truffleruby/core/symbol/RubySymbol.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public final class RubySymbol extends ImmutableRubyObjectNotCopyable implements
4040

4141
private static final int CLASS_SALT = 92021474; // random number, stops hashes for similar values but different classes being the same, static because we want deterministic hashes
4242

43+
public static final RubySymbol[] EMPTY_ARRAY = new RubySymbol[0];
44+
4345
public final RubyEncoding encoding;
4446
private final String string;
4547
public final TruffleString tstring;

src/main/java/org/truffleruby/language/arguments/CheckKeywordArityNode.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ private Object[] findExtraKeywordArguments(RubyHash keywordArguments) {
117117

118118
static RubySymbol[] keywordsAsSymbols(RubyLanguage language, Arity arity) {
119119
final String[] names = arity.getKeywordArguments();
120+
121+
if (names.length == 0) {
122+
return RubySymbol.EMPTY_ARRAY;
123+
}
124+
120125
final RubySymbol[] symbols = new RubySymbol[names.length];
121126
for (int i = 0; i < names.length; i++) {
122127
symbols[i] = language.getSymbol(names[i]);

src/main/java/org/truffleruby/parser/YARPMultiTargetNodeTranslator.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,7 @@ public MultipleAssignmentNode translate() {
7878
true,
7979
null);
8080

81-
final AssignableNode[] preNodes = new AssignableNode[node.lefts.length];
82-
for (int i = 0; i < node.lefts.length; i++) {
83-
preNodes[i] = node.lefts[i].accept(this);
84-
}
81+
final AssignableNode[] preNodes = processAssignables(node.lefts);
8582

8683
final AssignableNode restNode;
8784
if (node.rest != null) {
@@ -97,10 +94,7 @@ public MultipleAssignmentNode translate() {
9794
restNode = null;
9895
}
9996

100-
final AssignableNode[] postNodes = new AssignableNode[node.rights.length];
101-
for (int i = 0; i < node.rights.length; i++) {
102-
postNodes[i] = node.rights[i].accept(this);
103-
}
97+
final AssignableNode[] postNodes = processAssignables(node.rights);
10498

10599
// prolog is supposed to be executed in the outer MultipleAssignmentNode (in multi-assignment only)
106100
final var multipleAssignmentNode = new MultipleAssignmentNode(
@@ -113,6 +107,18 @@ public MultipleAssignmentNode translate() {
113107
return multipleAssignmentNode;
114108
}
115109

110+
private AssignableNode[] processAssignables(Nodes.Node[] nodes) {
111+
if (nodes.length == 0) {
112+
return AssignableNode.EMPTY_ARRAY;
113+
}
114+
115+
final AssignableNode[] assignables = new AssignableNode[nodes.length];
116+
for (int i = 0; i < nodes.length; i++) {
117+
assignables[i] = nodes[i].accept(this);
118+
}
119+
return assignables;
120+
}
121+
116122
@Override
117123
public AssignableNode visitClassVariableTargetNode(Nodes.ClassVariableTargetNode node) {
118124
final RubyNode rubyNode = node.accept(yarpTranslator);

0 commit comments

Comments
 (0)