diff options
| author | Cliff Click <cliffc@acm.org> | 2026-08-10 11:11:18 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-08 16:52:27 -0700 |
| commit | d32f97238c903765dec4e9a9f3cbfa5fd12cded6 (patch) | |
| tree | a5ac731801ef7066bab6359c4e85c2bdd20082a6 /src/main/java/com/seaofnodes/simple/node/NewNode.java | |
| parent | b5ebb2032aa04cf4506d533127d373d4cf5a25c6 (diff) | |
| download | Simple-linear.tar.gz Simple-linear.zip | |
Chapter 25: Modules, Separate Compilation, and SSA Constructionlinear
Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com>
Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com>
Co-authored-by: Symious <14933944+symious@users.noreply.github.com>
Co-authored-by: Jun Kawasaki <jun784@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/main/java/com/seaofnodes/simple/node/NewNode.java')
| -rw-r--r-- | src/main/java/com/seaofnodes/simple/node/NewNode.java | 98 |
1 files changed, 48 insertions, 50 deletions
diff --git a/src/main/java/com/seaofnodes/simple/node/NewNode.java b/src/main/java/com/seaofnodes/simple/node/NewNode.java index 840d2759..5eedd0cd 100644 --- a/src/main/java/com/seaofnodes/simple/node/NewNode.java +++ b/src/main/java/com/seaofnodes/simple/node/NewNode.java @@ -4,68 +4,65 @@ import com.seaofnodes.print.ExprPrinter; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.type.*; +import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.SB; -import com.seaofnodes.simple.util.Utils; +import java.util.HashMap; +import java.util.IdentityHashMap; -/** Allocate a zeroed object. Inputs {ctrl, $mem, size}; - * results {ptr, $mem}. - * The memory input and result cover only the aliases in the allocated struct. - */ +/** + * Allocation! Allocate a chunk of memory, no init. + * Takes in ctrl and size, and TypeStruct. + * Produces a ptr and private memory. +*/ public class NewNode extends Node implements MultiNode { + public TypeStruct _ts; + public NewNode( TypeStruct ts, Node ctrl, Node size ) { super(ctrl,size); _ts = ts; } - public final TypeMemPtr _ptr; + public Node ctrl() { return in(0); } + public Node size() { return in(1); } - public NewNode(TypeMemPtr ptr, Node... nodes) { - super(nodes); - assert !ptr.nullable(); - _ptr = ptr; - assert nodes.length==3; - assert nodes[0]._type==Type.CONTROL || nodes[0]._type==Type.XCONTROL; - assert nodes[1]._type instanceof TypeMem; - assert nodes[2]._type instanceof TypeInteger || nodes[2]._type==Type.NIL; + // --- Serialization + public NewNode(NewNode nnn) { super(nnn); _ts = nnn._ts; } + @Override public Tag serialTag() { return Tag.New; } + @Override public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) { + baos.packed2(types.get(_ts)); } - - public Node mem() { return in(1); } - public Node size() { return in(2); } - - public Field field(int alias) { - for( Field f : _ptr._obj._fields ) - if( !f._one && f._alias==alias ) return f; - return null; + static Node make( BAOS bais, Type[] types) { + TypeStruct ts = (TypeStruct)types[bais.packed2()]; + return new NewNode(ts,null,null); } - public NewNode(NewNode nnn) { super(nnn); _ptr = nnn._ptr; } - + @Override public String label() { return "new_"+(_ts.isAry() ? "ary_"+_ts._fields[1]._t.str() : _ts.str()); } - @Override public String label() { return "new_"+(_ptr._obj.isAry() ? "ary_"+_ptr._obj._fields[1]._t.str() : _ptr._obj.str()); } @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { - return p.p("new ").p(_ptr._obj.str()); + return p.p("new ").p(_ts.str()); } - - @Override - public TypeTuple compute() { - return in(0)._type.isHigh() - ? TypeTuple.make(_ptr.makeHigh(),TypeMem.TOP) - : TypeTuple.make(_ptr,TypeMem.BOT); + @Override public TypeTuple compute() { + if( ctrl()._type.isHigh() ) + return TypeTuple.DEAD_NEW; + TypeStruct ts = _ts.isAry() ? _ts : _ts.makeInit(); + return TypeTuple.make(TypeMemPtr.make(_ts), + // Arrays get pre-zeroed by constructor. + // Objects start with default-zero memory for + // fields that can be zero-initialized. This is + // still private memory, so no aliases escape yet. + TypeMem.make(1,ts,true,false,false,null,null)); } - @Override - public Node idealize() { - Node progress=null; - for( int i=1; i<nIns(); i++ ) { - if( in(i) instanceof CastNode cast ) - progress = setDef(i,cast.in(1)); - } - return progress == null ? null : this; + @Override public Node idealize() { return null; } + + @Override boolean _upgradeType( HashMap<String,Type> TYPES) { + Type old = _ts; _ts = (TypeStruct)_ts.upgradeType(TYPES); return old != _ts; } - @Override - public boolean eq(Node n) { return this == n; } + // Two NewNodes are never equal; NewNodes always make independent pointers + // so they are not functional - they internally bump-ptr allocate always a + // new pointer. + @Override public boolean eq(Node n) { return this==n; } - @Override - int hash() { return _ptr.hashCode(); } + @Override int hash() { return _ts.hashCode(); } // ------------ // MachNode specifics, shared across all CPUs @@ -74,30 +71,31 @@ public class NewNode extends Node implements MultiNode { private RegMask _retMask; private RegMask _kills; public void cacheRegs(CodeGen code) { - _arg2Reg = code._mach.callArgMask(TypeFunPtr.CALLOC,2,0).firstReg(); - _arg3Mask = code._mach.callArgMask(TypeFunPtr.CALLOC,3,0); + _arg2Reg = code._mach.callArgMask(TypeFunPtr.CALLOC,2,0,code._cCallingConv).firstReg(); + _arg3Mask = code._mach.callArgMask(TypeFunPtr.CALLOC,3,0,code._cCallingConv); // Return mask depends on TFP (either GPR or FPR) _retMask = code._mach.retMask(TypeFunPtr.CALLOC); // Kill mask is all caller-saves, and any mirror stack slots for args // in registers. - RegMaskRW kills = code._callerSave.copy(); + RegMaskRW kills = code._cCallerSave.copy(); // Start of stack slots int maxReg = code._mach.regs().length; // Incoming function arg slots, all low numbered in the RA int fslot = cfg0().fun()._maxArgSlot; // Killed slots for this calls outgoing args - int xslot = code._mach.maxArgSlot(TypeFunPtr.CALLOC); + int xslot = code._mach.maxArgSlot(TypeFunPtr.CALLOC,code._cCallingConv); _xslot = (maxReg+fslot)+xslot; for( int i=0; i<xslot; i++ ) kills.set((maxReg+fslot)+i); _kills = kills; } public String op() { return "alloc"; } - public RegMask regmap(int i) { return i==2 ? _arg3Mask : null; } + public RegMask regmap(int i) { return i==1 ? _arg3Mask : null; } public RegMask outregmap() { return null; } public RegMask outregmap(int idx) { return idx==0 ? _retMask : null; } public RegMask killmap() { return _kills; } public void asm(CodeGen code, SB sb) { - sb.p("#calloc, ").p(code.reg(size())); + sb.p("#malloc, ").p(code.reg(size())); } + } |
