summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/Parser.java3
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java30
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java35
3 files changed, 52 insertions, 16 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
index ab43e1a9..25e3054c 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java
@@ -1293,13 +1293,12 @@ public class Parser {
TypeMemPtr tmp = typeAry(TypeInteger.U8);
int lenAlias = tmp._obj.field("#" )._alias;
int elemAlias = tmp._obj.field("[]")._alias;
- TypeInteger len = TypeInteger.constant(s.length());
TypeConAryB con = TypeConAryB.make(s);
Type elem = con.elem();
// Make a TMP, not-null (byte)2, singleton (true) (requires text
// strings are hash-interned), with a TypeStruct having a constant
// array body.
- TypeMemPtr str = TypeMemPtr.make((byte)2,TypeStruct.makeAry("[u8]", len, lenAlias, elem, elemAlias, true, con),true);
+ TypeMemPtr str = TypeMemPtr.make((byte)2,TypeStruct.makeAry("[u8]", TypeInteger.U32, lenAlias, elem, elemAlias, true, con),true);
return con(str);
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 6aaa3396..693c4077 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -424,32 +424,44 @@ public class Encoding {
void writeConstantPool( BAOS bits, boolean patch ) {
padN(16,bits);
+ // radix sort the big constants by alignment
+ Ary<Relo>[] raligns = new Ary[5];
+ for( Node op : _bigCons.keySet() ) {
+ Relo relo = _bigCons.get(op);
+ int align = relo._t.alignment();
+ Ary<Relo> relos = raligns[align]==null ? (raligns[align]=new Ary<>(Relo.class)) : raligns[align];
+ relos.add(relo);
+ }
+
+
+ // Types can be used more than once; collapse the dups
HashMap<Type,Integer> targets = new HashMap<>();
// By alignment
for( int align = 4; align >= 0; align-- ) {
- // Write the 8-byte constants
- for( Node op : _bigCons.keySet() ) {
- Relo relo = _bigCons.get(op);
- if( relo._t.alignment()==align ) {
+ Ary<Relo> relos = raligns[align];
+ if( relos != null )
+ for( Relo relo : relos ) {
// Map from relo to constant start and patch
Integer target = targets.get(relo._t);
if( target==null ) {
targets.put(relo._t,target = bits.size());
// Put constant into code space.
- if( relo._t instanceof TypeTuple tt ) // Constant tuples put all entries
+ if( relo._t instanceof TypeTuple tt ) // Constant tuples put all entries at same alignment
for( Type tx : tt._types )
addN(align,tx,bits);
- else
+ else if( relo._t instanceof TypeStruct ts ) {
+ int alignX = ts.alignment();
+ throw Utils.TODO();
+ } else // Simple primitive (e.g. larger int, float)
addN(align,relo._t,bits);
}
relo._target = target;
- relo._opStart= _opStart[op._nid];
+ relo._opStart= _opStart[relo._op._nid];
// Go ahead and locally patch in-memory
if( patch )
- ((RIPRelSize)op).patch(this, relo._opStart, _opLen[op._nid], relo._target - relo._opStart);
+ ((RIPRelSize)relo._op).patch(this, relo._opStart, _opLen[relo._op._nid], relo._target - relo._opStart);
}
- }
}
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
index 0855bee8..e0426e0c 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
@@ -168,17 +168,42 @@ public class TypeStruct extends Type {
}
@Override public boolean isConstant() {
+ int len = _fields.length;
+ // If we have a constant array, then ignore the last 2 array fields-
+ // they are effectively constant.
+
+ // Fields are given sizes according to their types at *offset time*.
+ // And thus layout, packing & padding are determined by the Types
+ // at *offset-time*, which means *offset-time* has to be picked
+ // when types are Stable - post/during TypeCheck.
+
+ // The array-length field is shared with other like-sized arrays, so
+ // you are allowed to mix "abc" and "very_hugh_>256_char_string" and
+ // the resulting TMP can query the length field (getting 3 or >256
+ // respectively), and reading from a prolly 16bit length field.
+
+ // Basically asking: forward-flow declared-types, are these compatible?
+ // Only array-lengths have an issue here? So internally name fields
+ // `#0` or `#1` or `#2` or `#3`.
+ //
+ // Also means I cannot track exact array length without losing the
+ // "declared type requires a 4-byte field".
+ //
+ // Same-same for all fields in a struct, space in memory is based on
+ // declared-type at least, possible (future work) optimized where all
+ // memory versions of the same field get a smaller footprint (or even a
+ // constant past or moved into prototype) past construction
+
+ if( _con!=TypeConAry.BOT ) len -= 2;
// Check all fields for being constant
- for( int i=0; i<_fields.length; i++ )
+ for( int i=0; i<len; i++ )
if( !_fields[i].isConstant() )
- // Last field checks for a constant array
- if( i<_fields.length-1 || !isAry() || _con==TypeConAry.BOT )
- return false;
+ return false;
return true;
}
// log_size for a struct is not defined, unless its exactly some power of
- // 2. *Total* size is well defined, and is available in the offsets.
+ // 2. *Total size* is well-defined, and is available in the offsets.
@Override public int log_size() { throw Utils.TODO(); }
@Override public int alignment() {
int align = 0;