Skip to content

Commit 340466d

Browse files
Emit closed over values in deterministic order
1 parent 7bdda74 commit 340466d

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

src/jvm/clojure/lang/Compiler.java

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4571,7 +4571,7 @@ else if(methodArray[f.reqParms.count()] == null)
45714571
"Can't have fixed arity function with more params than variadic function");
45724572
}
45734573

4574-
fn.canBeDirect = !fn.hasEnclosingMethod && fn.closes.count() == 0 && !usesThis;
4574+
fn.canBeDirect = !fn.hasEnclosingMethod && fn.closes.isEmpty() && !usesThis;
45754575

45764576
IPersistentCollection methods = null;
45774577
for(int i = 0; i < methodArray.length; i++)
@@ -4680,7 +4680,7 @@ static public class ObjExpr implements Expr{
46804680
Type objtype;
46814681
public final Object tag;
46824682
//localbinding->itself
4683-
IPersistentMap closes = PersistentHashMap.EMPTY;
4683+
List<LocalBinding> closes = new ArrayList<>();
46844684
//localbndingexprs
46854685
IPersistentVector closesExprs = PersistentVector.EMPTY;
46864686
//symbols
@@ -4737,7 +4737,7 @@ public final Type objtype(){
47374737
return objtype;
47384738
}
47394739

4740-
public final IPersistentMap closes(){
4740+
public final List<LocalBinding> closes(){
47414741
return closes;
47424742
}
47434743

@@ -4800,9 +4800,8 @@ static String trimGenID(String name){
48004800

48014801
Type[] ctorTypes(){
48024802
IPersistentVector tv = !supportsMeta()?PersistentVector.EMPTY:RT.vector(IPERSISTENTMAP_TYPE);
4803-
for(ISeq s = RT.keys(closes); s != null; s = s.next())
4803+
for(LocalBinding lb : closes())
48044804
{
4805-
LocalBinding lb = (LocalBinding) s.first();
48064805
if(lb.getPrimitiveType() != null)
48074806
tv = tv.cons(Type.getType(lb.getPrimitiveType()));
48084807
else
@@ -4867,9 +4866,8 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
48674866
cv.visitField(ACC_FINAL, "__meta", IPERSISTENTMAP_TYPE.getDescriptor(), null, null);
48684867
}
48694868
//instance fields for closed-overs
4870-
for(ISeq s = RT.keys(closes); s != null; s = s.next())
4869+
for(LocalBinding lb : closes())
48714870
{
4872-
LocalBinding lb = (LocalBinding) s.first();
48734871
if(isDeftype())
48744872
{
48754873
int access = isVolatile(lb) ? ACC_VOLATILE :
@@ -4945,9 +4943,8 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
49454943
}
49464944

49474945
int a = supportsMeta()?2:1;
4948-
for(ISeq s = RT.keys(closes); s != null; s = s.next(), ++a)
4946+
for(LocalBinding lb : closes())
49494947
{
4950-
LocalBinding lb = (LocalBinding) s.first();
49514948
ctorgen.loadThis();
49524949
Class primc = lb.getPrimitiveType();
49534950
if(primc != null)
@@ -4963,6 +4960,7 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
49634960
ctorgen.putField(objtype, lb.name, OBJECT_TYPE);
49644961
}
49654962
closesExprs = closesExprs.cons(new LocalBindingExpr(lb, null));
4963+
++a;
49664964
}
49674965

49684966

@@ -5073,9 +5071,8 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
50735071
gen.dup();
50745072
gen.loadArg(0);
50755073

5076-
for(ISeq s = RT.keys(closes); s != null; s = s.next(), ++a)
5074+
for(LocalBinding lb : closes())
50775075
{
5078-
LocalBinding lb = (LocalBinding) s.first();
50795076
gen.loadThis();
50805077
Class primc = lb.getPrimitiveType();
50815078
if(primc != null)
@@ -5086,6 +5083,7 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
50865083
{
50875084
gen.getField(objtype, lb.name, OBJECT_TYPE);
50885085
}
5086+
++a;
50895087
}
50905088

50915089
gen.invokeConstructor(objtype, new Method("<init>", Type.VOID_TYPE, ctorTypes));
@@ -5522,9 +5520,8 @@ public void emitLetFnInits(GeneratorAdapter gen, ObjExpr objx, IPersistentSet le
55225520
//objx arg is enclosing objx, not this
55235521
gen.checkCast(objtype);
55245522

5525-
for(ISeq s = RT.keys(closes); s != null; s = s.next())
5523+
for(LocalBinding lb : closes())
55265524
{
5527-
LocalBinding lb = (LocalBinding) s.first();
55285525
if(letFnLocals.contains(lb))
55295526
{
55305527
Class primc = lb.getPrimitiveType();
@@ -5608,7 +5605,7 @@ public void emitAssignLocal(GeneratorAdapter gen, LocalBinding lb,Expr val){
56085605
}
56095606

56105607
private void emitLocal(GeneratorAdapter gen, LocalBinding lb, boolean clear){
5611-
if(closes.containsKey(lb))
5608+
if(closes.contains(lb))
56125609
{
56135610
Class primc = lb.getPrimitiveType();
56145611
gen.loadThis();
@@ -5680,7 +5677,7 @@ private void emitLocal(GeneratorAdapter gen, LocalBinding lb, boolean clear){
56805677
private void emitUnboxedLocal(GeneratorAdapter gen, LocalBinding lb){
56815678
int argoff = canBeDirect ?0:1;
56825679
Class primc = lb.getPrimitiveType();
5683-
if(closes.containsKey(lb))
5680+
if(closes.contains(lb))
56845681
{
56855682
gen.loadThis();
56865683
gen.getField(objtype, lb.name, Type.getType(primc));
@@ -6561,7 +6558,7 @@ public LocalBindingExpr(LocalBinding b, Symbol tag)
65616558
}
65626559

65636560
ObjMethod method = ((ObjMethod) METHOD.deref());
6564-
boolean closedOver = method.objx.closes.containsKey(b);
6561+
boolean closedOver = method.objx.closes.contains(b);
65656562
if(clearRoot == b.clearPathRoot || (closedOver && clearRoot == method.clearRoot))
65666563
{
65676564
this.shouldClear = true;
@@ -8055,7 +8052,7 @@ static void closeOver(LocalBinding b, ObjMethod method){
80558052
LocalBinding lb = (LocalBinding) RT.get(method.locals, b);
80568053
if(lb == null)
80578054
{
8058-
method.objx.closes = (IPersistentMap) RT.assoc(method.objx.closes, b, b);
8055+
if (!method.objx.closes.contains(b)) method.objx.closes.add(b);
80598056
closeOver(b, method.parent);
80608057
}
80618058
else {
@@ -8513,20 +8510,19 @@ static ObjExpr build(IPersistentVector interfaceSyms, IPersistentVector fieldSym
85138510
if(fieldSyms != null)
85148511
{
85158512
IPersistentMap fmap = PersistentHashMap.EMPTY;
8516-
Object[] closesvec = new Object[2 * fieldSyms.count()];
8513+
List<LocalBinding> closes = new ArrayList<>(fieldSyms.count());
85178514
for(int i=0;i<fieldSyms.count();i++)
85188515
{
85198516
Symbol sym = (Symbol) fieldSyms.nth(i);
85208517
LocalBinding lb = new LocalBinding(-1, sym, null,
85218518
new MethodParamExpr(tagClass(tagOf(sym))),false,null);
85228519
fmap = fmap.assoc(sym, lb);
8523-
closesvec[i*2] = lb;
8524-
closesvec[i*2 + 1] = lb;
8520+
closes.add(lb);
85258521
}
85268522

85278523
//todo - inject __meta et al into closes - when?
85288524
//use array map to preserve ctor order
8529-
ret.closes = new PersistentArrayMap(closesvec);
8525+
ret.closes = closes;
85308526
ret.fields = fmap;
85318527
for(int i=fieldSyms.count()-1;i >= 0 && (((Symbol)fieldSyms.nth(i)).name.equals("__meta")
85328528
|| ((Symbol)fieldSyms.nth(i)).name.equals("__extmap")
@@ -8632,9 +8628,8 @@ static Class compileStub(String superName, NewInstanceExpr ret, String[] interfa
86328628
null,superName,interfaceNames);
86338629

86348630
//instance fields for closed-overs
8635-
for(ISeq s = RT.keys(ret.closes); s != null; s = s.next())
8631+
for(LocalBinding lb : ret.closes())
86368632
{
8637-
LocalBinding lb = (LocalBinding) s.first();
86388633
int access = ACC_PUBLIC + (ret.isVolatile(lb) ? ACC_VOLATILE :
86398634
ret.isMutable(lb) ? 0 :
86408635
ACC_FINAL);

0 commit comments

Comments
 (0)