summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/node/NewNode.java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-08-10 11:11:18 -0700
committerCliff Click <cliffc@acm.org>2026-10-08 16:52:27 -0700
commitd32f97238c903765dec4e9a9f3cbfa5fd12cded6 (patch)
treea5ac731801ef7066bab6359c4e85c2bdd20082a6 /src/main/java/com/seaofnodes/simple/node/NewNode.java
parentb5ebb2032aa04cf4506d533127d373d4cf5a25c6 (diff)
downloadSimple-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.java98
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()));
}
+
}