summaryrefslogtreecommitdiff
path: root/chapter25/src/main/java/com/seaofnodes/simple/node
diff options
context:
space:
mode:
Diffstat (limited to 'chapter25/src/main/java/com/seaofnodes/simple/node')
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/CLInitNode.java58
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java12
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java4
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java6
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/FunNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/MemOpNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java9
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/Node.java23
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java3
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java1
10 files changed, 89 insertions, 30 deletions
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CLInitNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CLInitNode.java
index f00d8076..5131049e 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/CLInitNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CLInitNode.java
@@ -2,29 +2,65 @@ package com.seaofnodes.simple.node;
import com.seaofnodes.print.ExprPrinter;
import com.seaofnodes.simple.Parser;
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.codegen.CompUnit;
import com.seaofnodes.simple.type.*;
+import com.seaofnodes.simple.util.BAOS;
+import com.seaofnodes.simple.util.Utils;
+import java.util.*;
-/** An active class touch, retained in control until initialization validation.
- * This checkpoint records the obligation only; flag/call lowering comes later.
- */
+// Track class initializers - the code just after this point expects the named
+// class to be initialized. If this code path dies, then the dependency dies
+// also - dead code does not force class init.
+//
public class CLInitNode extends CFGNode {
- public final Parser.Lexer _loc;
- public final String _field;
+ public Parser.Lexer _loc; // For error reporting
- public CLInitNode(Parser.Lexer loc, String field, Node ctrl, Node ptr) {
+ // For field references, the ptr might be the dst clz ptr or not.
+ public CLInitNode(Parser.Lexer loc, Node ctrl, Node ptr) {
super(ctrl,ptr);
- _loc=loc;
- _field=field;
+ _loc = loc;
}
- public Node ptr() { return in(1); }
+ CLInitNode(BAOS bais) { super(null,null); }
+ @Override public Tag serialTag() { return Tag.CLInit; }
+ @Override public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) {
+ }
+
+ public CLInitNode(CLInitNode init) {
+ super(init);
+ _loc = init._loc;
+ }
+
+ Node ptr() { return in(1); }
@Override public String label() { return "CLInit"; }
- @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { return p.p("CLInit ").p(ptr()); }
+
+ // Best effort dst compunit, based on ptr - or null
+ public CompUnit cu() {
+ if( !(ptr()._type instanceof TypeMemPtr ptr && Parser.startsClzPrefix(ptr._obj._name)) )
+ return null;
+ // Convert "class:sys.ary" into "sys/ary" and lookup CompUnit
+ String fname = ptr._obj._name.substring(6).replace(".","/");
+ return CodeGen.CODE._compunits.get(fname);
+ }
+
+ @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) {
+ FunNode fun = fun();
+ CompUnit cu = cu();
+ return p.p("CLInit ").p(fun._name).p(" -> ").p(cu==null ? "---" : cu._cname);
+ }
+
+ // Block head is Start, Region, CProj, but not e.g. If, Return, Stop
+ public boolean blockHead() { return true; }
+
@Override public Type compute() { return in(0)._type; }
@Override public Node idealize() {
// A receiver discovered to be an ordinary instance needs no class init.
if( ptr()._type instanceof TypeMemPtr ptr && ptr._obj!=TypeStruct.BOT &&
- !ptr._obj.isHigh() && !Parser.startsClzPrefix(ptr._obj._name) ) return in(0);
+ !ptr._obj.isHigh() && !Parser.startsClzPrefix(ptr._obj._name) )
+ return in(0); // Normal instance, no class init
+ if( ptr()._type == Type.NIL || ptr()._type.isHigh() )
+ return in(0);
return null;
}
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java
index 4372e2d5..38117f23 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java
@@ -22,11 +22,17 @@ public class CallNode extends CFGNode {
// Source location for late reported errors
public final Parser.Lexer _loc;
- public CallNode(Parser.Lexer loc, Node... nodes) { super(nodes); _loc = loc; }
+ public CallNode(Parser.Lexer loc, Node... nodes) { this(loc,loc==null ? 0 : loc.lineColumn(),nodes); }
+ private CallNode(Parser.Lexer loc, long position, Node... nodes) { super(nodes); _loc=loc; }
public CallNode(CallNode call) { super(call); _loc = call._loc; }
@Override public Tag serialTag() { return Tag.Call; }
- public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) { baos.packed1(nIns()); }
- static Node make( BAOS bais ) { return new CallNode(null,new Node[bais.packed1()]); }
+ public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) {
+ baos.packed1(nIns());
+ }
+ static Node make( BAOS bais ) {
+ int nIns = bais.packed1();
+ return new CallNode(null,new Node[nIns]);
+ }
@Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) {
String fname = name();
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java
index f94fa484..284220ea 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java
@@ -71,4 +71,8 @@ public class ConFldOffNode extends ConstantNode {
return _ts._name==off._ts._name && _fname.equals(off._fname) && super.eq(n);
}
@Override int hash() { return super.hash() * _ts._name.hashCode() * _fname.hashCode(); }
+
+ @Override public Parser.ParseException err() {
+ return _ts._fref ? Parser.error("Unknown struct type '"+_ts._name+"'",null) : null;
+ }
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java
index ef894929..a9f8d692 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java
@@ -45,4 +45,10 @@ public class FldOffNode extends TypeNode {
return _fname.equals(off._fname) && super.eq(n);
}
@Override int hash() { return super.hash() * _fname.hashCode(); }
+
+ @Override public Parser.ParseException err() {
+ if( in(0)._type instanceof TypeMemPtr tmp && tmp._obj._fref )
+ return Parser.error("Unknown struct type '"+tmp._obj._name+"'",null);
+ return null;
+ }
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/FunNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/FunNode.java
index 1e2ee10a..7f9a2819 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/FunNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FunNode.java
@@ -49,6 +49,7 @@ public class FunNode extends RegionNode {
baos.packed2(types.get(_sig)); // NPE if fails lookup
baos.packed2(_name==null ? 0 : strs.get(_name));
baos.packed2(_approxUIDs);
+ // _compunit set from context on loading, do not write
}
static Node make( BAOS bais, String[] strs, Type[] types) {
Node[] ins = new Node[bais.packed1()];
@@ -56,6 +57,7 @@ public class FunNode extends RegionNode {
String name = strs[bais.packed2()];
FunNode fun = new FunNode(null,sig,name,null,ins);
fun._approxUIDs = bais.packed2();
+ // _compunit set from context on loading, do not read
return fun;
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/MemOpNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/MemOpNode.java
index 365157d2..373b8825 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/MemOpNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MemOpNode.java
@@ -136,7 +136,6 @@ public abstract class MemOpNode extends TypeNode {
if( off() instanceof ConFldOffNode && CodeGen.CODE._phase.ordinal() > CodeGen.Phase.Opto.ordinal() )
return Parser.error("Accessing unknown field '"+_name+"' from '*"+tmp._obj._name+"'",_loc);
return null;
-
}
// Memory writers which must follow this read. A packaging node is not a
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java
index 5eedd0cd..fe80f690 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java
@@ -1,12 +1,11 @@
package com.seaofnodes.simple.node;
import com.seaofnodes.print.ExprPrinter;
-
+import com.seaofnodes.simple.Parser;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.type.*;
import com.seaofnodes.simple.util.BAOS;
import com.seaofnodes.simple.util.SB;
-
import java.util.HashMap;
import java.util.IdentityHashMap;
@@ -64,6 +63,12 @@ public class NewNode extends Node implements MultiNode {
@Override int hash() { return _ts.hashCode(); }
+
+ @Override public Parser.ParseException err() {
+ return _ts._fref ? Parser.error("Unknown struct type '"+_ts._name+"'",null) : null;
+ }
+
+
// ------------
// MachNode specifics, shared across all CPUs
public int _arg2Reg, _xslot;
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java
index 23a7e2c4..796965b5 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java
@@ -70,20 +70,21 @@ public abstract class Node extends BaseNode<Node> implements Cloneable {
// Disk/serialized opcode tags
public enum Tag {
- Add,And,EQ,NE,LT,LE,ULT,
- CallEnd,Call,ConFldOff,Con,CProj,
- Div,Escape,Extern,Fun,FunPtr,If,Load,Loop,
- MemMerge,Minus,Mul,
- New,Never,Not,Or,Parm,Phi,Proj,
+ Add,And,BulkMemPhi,EQ,NE,LT,LE,ULT,
+ CallEnd,Call,ConFldOff,Con,CLInit,CProj,
+ Div,Escape,Extern,ExternOffset,Fun,FunPtr,Guard,
+ If,Load,Loop,MemMerge,MemPhi,Minus,Mul,
+ New,Never,Not,Or,Parm,Phi,Proj,PtrToInt,
ReadOnly,Return,Region,RoundF32,
- Sar,Shl,Shr,Start,Stop,Store,Sub,ToFloat,
- XCtrl,Xor,StartCU,StopCU,Guard,MemPhi,BulkMemPhi,PtrToInt,ExternOffset,ToInteger;
+ Sar,Shl,Shr,Start,StartCU,StopCU,Stop,Store,Sub,
+ ToInteger,ToFloat,XCtrl,Xor;
public static final Tag[] VALS = values();
public Node make( BAOS bais, String[] strs, Type[] types, GlobalBits fileAliases, GlobalBits aliases ) {
return switch(this) {
case Add -> new AddNode(null,null,(byte)bais.packed1());
case And -> { int mode=bais.packed1(); assert mode==1; yield new AndNode(null,null,null); }
case Div -> new DivNode(null,null,(byte)bais.packed1());
+ case Guard -> GuardNode.make(bais);
case If -> new IfNode(null,null);
case Loop -> new LoopNode(null,null,null);
case Minus -> new MinusNode(null,(byte)bais.packed1());
@@ -104,7 +105,6 @@ public abstract class Node extends BaseNode<Node> implements Cloneable {
case ToInteger-> new ToIntegerNode(null);
case XCtrl -> new XCtrlNode();
case Xor -> { int mode=bais.packed1(); assert mode==1; yield new XorNode(null,null,null); }
- case Guard -> GuardNode.make(bais);
case EQ -> new BoolNode.EQ (null,null,(byte)bais.packed1());
case NE -> new BoolNode.NE (null,null,(byte)bais.packed1());
@@ -114,23 +114,24 @@ public abstract class Node extends BaseNode<Node> implements Cloneable {
case Call -> CallNode.make(bais);
case CallEnd-> CallEndNode.make(bais ,types);
+ case CLInit -> new CLInitNode(bais);
case CProj -> CProjNode.make(bais,strs);
case Con -> ConstantNode.make(bais ,types);
case Escape-> EscapeNode.make(bais ,types);
case Extern-> ExternNode.make(bais,strs,types);
case ExternOffset-> new ExternOffsetNode(strs[bais.packed2()]);
- case FunPtr-> FunPtrNode.make(bais, types);
+ case FunPtr-> FunPtrNode.make(bais, types);
case Fun -> FunNode.make(bais,strs,types);
case Load -> new LoadNode(bais,strs,types,fileAliases,aliases);
case MemMerge->MemMergeNode.make(bais);
- case MemPhi-> MemPhiNode.make(bais,strs,types,fileAliases,aliases);
+ case MemPhi-> MemPhiNode.make(bais,strs,types,fileAliases,aliases);
case BulkMemPhi-> BulkMemPhiNode.make(bais,strs,types,fileAliases,aliases);
case New -> NewNode.make(bais ,types);
case Parm -> ParmNode.make(bais,strs,types);
case Phi -> PhiNode.make(bais,strs,types);
case Proj -> ProjNode.make(bais,strs);
case Store -> new StoreNode(bais,strs,types,fileAliases,aliases);
- case Stop -> StopNode.make(bais);
+ case Stop -> StopNode.make(bais);
case StartCU-> StartCUNode.make(bais,strs,types);
case StopCU -> StopCUNode.make(bais);
case Region-> RegionNode.make(bais);
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
index 92cad745..21d60d53 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
@@ -1,12 +1,11 @@
package com.seaofnodes.simple.node;
import com.seaofnodes.print.ExprPrinter;
-
import com.seaofnodes.simple.Parser;
import com.seaofnodes.simple.Var;
import com.seaofnodes.simple.codegen.CodeGen;
-import com.seaofnodes.simple.codegen.ParseAll;
import com.seaofnodes.simple.codegen.CompUnit;
+import com.seaofnodes.simple.codegen.ParseAll;
import com.seaofnodes.simple.type.*;
import com.seaofnodes.simple.util.Ary;
import com.seaofnodes.simple.util.Utils;
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index ff15fdad..23c4d530 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -282,6 +282,7 @@ public class x86_64_v2 extends Machine {
case AddNode add -> add(add);
case AndNode and -> and(and);
case BoolNode bool -> cmp(bool);
+ case CLInitNode init -> new CLInitNode(init);
case CProjNode c -> new CProjNode(c);
case CallEndNode cend -> new CallEndMach(cend);
case CallNode call -> call(call);