Skip to content

Commit ea1d517

Browse files
committed
make symbol cache result-wide vs on each scope
1 parent 5e590f4 commit ea1d517

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

src/main/java/org/jruby/prism/builder/IRBuilderPrism.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ public class IRBuilderPrism extends IRBuilder<Node, DefNode, WhenNode, RescueNod
9292
byte[] source;
9393
Nodes.Source nodeSource;
9494
StaticScope staticScope;
95-
IdentityHashMap<byte[], RubySymbol> symbols = new IdentityHashMap<>();
95+
// This is originally sourced from ParseResult so that we only resolve symbols once per result instead of
96+
// one per scope. There is a little dance to set this ... we keep getting it from the parent scope
97+
// unless it is a method definition then we get reference from the lazymethoddefinition.
98+
IdentityHashMap<byte[], RubySymbol> symbols = null;
9699
ThreadContext context;
97100

98101
public IRBuilderPrism(IRManager manager, IRScope scope, IRBuilder parent, IRBuilder variableBuilder, Encoding encoding) {
@@ -101,12 +104,19 @@ public IRBuilderPrism(IRManager manager, IRScope scope, IRBuilder parent, IRBuil
101104
if (parent != null) {
102105
source = ((IRBuilderPrism) parent).source;
103106
nodeSource = ((IRBuilderPrism) parent).nodeSource;
107+
symbols = ((IRBuilderPrism) parent).symbols;
108+
} else { // For END which is made without a parent and not setup by lazy method def.
109+
symbols = new IdentityHashMap<>();
104110
}
105111
staticScope = scope.getStaticScope();
106112
staticScope.setFile(scope.getFile()); // staticScope and IRScope contain the same field.
107113
context = manager.getRuntime().getCurrentContext();
108114
}
109115

116+
public void setSymbols(IdentityHashMap<byte[], RubySymbol> symbols) {
117+
this.symbols = symbols;
118+
}
119+
110120
// FIXME: Delete once we are no longer depedent on source code
111121
public void setSourceFrom(IRBuilderPrism other) {
112122
if (other.nodeSource == null) throw new RuntimeException("WETF");
@@ -130,6 +140,7 @@ public Operand build(ParseResult result) {
130140
this.executesOnce = false;
131141
this.source = ((ParseResultPrism) result).getSource();
132142
this.nodeSource = ((ParseResultPrism) result).getSourceNode();
143+
this.symbols = ((ParseResultPrism) result).getSymbols();
133144

134145
// System.out.println("NAME: " + fileName);
135146
// System.out.println(((ParseResultPrism) result).getRoot());
@@ -899,7 +910,7 @@ private Operand buildDef(DefNode node) {
899910
// FIXME: due to how lazy methods work we need this set on method before we actually parse the method.
900911
StaticScope staticScope = createStaticScopeFrom(node.locals, StaticScope.Type.LOCAL);
901912
staticScope.setSignature(calculateSignature(node.parameters));
902-
LazyMethodDefinition def = new LazyMethodDefinitionPrism(getManager().getRuntime(), source, nodeSource, encoding, node);
913+
LazyMethodDefinition def = new LazyMethodDefinitionPrism(getManager().getRuntime(), source, nodeSource, encoding, node, symbols);
903914

904915
if (node.receiver == null) {
905916
return buildDefn(defineNewMethod(def, symbol(node.name).getBytes(), getLine(node), staticScope, true));
@@ -2860,6 +2871,21 @@ private Operand buildModuleParent(Node parent) {
28602871
}
28612872

28622873
private RubySymbol symbol(byte[] bytes) {
2874+
/*
2875+
var hit = symbols.get(bytes);
2876+
2877+
if (hit == null) {
2878+
hit = asSymbol(context, new ByteList(bytes, encoding));
2879+
if (hit.idString().charAt(0) == 'R') {
2880+
System.out.println("SAVING: " + hit + ", ENC: " + encoding);
2881+
}
2882+
symbols.put(bytes, hit);
2883+
} else {
2884+
//System.out.println("ALREADY FOUND: " + hit);
2885+
}
2886+
2887+
return hit;
2888+
*/
28632889
return symbols.computeIfAbsent(bytes, (_b) -> asSymbol(context, new ByteList(bytes, encoding)));
28642890
}
28652891

src/main/java/org/jruby/prism/builder/LazyMethodDefinitionPrism.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.jcodings.Encoding;
44
import org.jruby.Ruby;
5+
import org.jruby.RubySymbol;
56
import org.jruby.ir.IRManager;
67
import org.jruby.ir.IRMethod;
78
import org.jruby.ir.builder.IRBuilder;
@@ -19,6 +20,7 @@
1920
import org.ruby_lang.prism.Nodes.WhenNode;
2021

2122
import java.util.ArrayList;
23+
import java.util.IdentityHashMap;
2224
import java.util.List;
2325

2426
import static org.jruby.api.Convert.asSymbol;
@@ -28,15 +30,18 @@ public class LazyMethodDefinitionPrism implements LazyMethodDefinition<Node, Def
2830
private final Nodes.Source nodeSource;
2931
private DefNode node;
3032
private byte[] source;
33+
private IdentityHashMap<byte[], RubySymbol> symbols;
3134

3235
final private Encoding encoding;
3336

34-
public LazyMethodDefinitionPrism(Ruby runtime, byte[] source, Nodes.Source nodeSource, Encoding encoding, DefNode node) {
37+
public LazyMethodDefinitionPrism(Ruby runtime, byte[] source, Nodes.Source nodeSource, Encoding encoding,
38+
DefNode node, IdentityHashMap<byte[], RubySymbol> symbols) {
3539
this.runtime = runtime;
3640
this.source = source;
3741
this.node = node;
3842
this.nodeSource = nodeSource;
3943
this.encoding = encoding;
44+
this.symbols = symbols;
4045
}
4146
@Override
4247
public int getEndLine() {
@@ -89,6 +94,7 @@ public Node getMethodBody() {
8994
public IRBuilder<Node, DefNode, WhenNode, RescueNode, ConstantPathNode, Nodes.HashPatternNode> getBuilder(IRManager manager, IRMethod methodScope) {
9095
IRBuilder<Node, DefNode, WhenNode, RescueNode, ConstantPathNode, Nodes.HashPatternNode> builder = manager.getBuilderFactory().newIRBuilder(manager, methodScope, null, encoding);
9196

97+
((IRBuilderPrism) builder).setSymbols(symbols);
9298
((IRBuilderPrism) builder).setSourceFrom(nodeSource, source);
9399

94100
return builder;

src/main/java/org/jruby/prism/parser/ParseResultPrism.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
import org.jruby.util.ByteList;
1111
import org.ruby_lang.prism.Nodes;
1212

13+
import java.util.IdentityHashMap;
14+
1315
import static org.jruby.api.Convert.asSymbol;
1416

1517
public class ParseResultPrism implements ParseResult {
1618
final Encoding encoding;
1719
StaticScope rootScope;
1820
Nodes.ProgramNode root;
21+
IdentityHashMap<byte[], RubySymbol> symbols = new IdentityHashMap<>();
1922

2023
final Nodes.Source nodeSource;
2124
final String fileName;
@@ -73,6 +76,10 @@ public int getCoverageMode() {
7376
return coverageMode;
7477
}
7578

79+
public IdentityHashMap<byte[], RubySymbol> getSymbols() {
80+
return symbols;
81+
}
82+
7683
public Nodes.ProgramNode getRoot() {
7784
return root;
7885
}

0 commit comments

Comments
 (0)