diff options
Diffstat (limited to 'chapter22')
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; |
