duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 3b7ccfa7feacf8ec38c73b41acc00df5502c15fd
parent f3f139a7e21d3659afae9765aacb56fbb10bcadd
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed, 24 May 2023 15:34:50 -0400

Change dictionary entry structure

As I'm about to implement it on ARM, which makes me alignment-aware a little bit
more, I'm thinking that it's a good time to improve this structure.

The idea is to make the link and meta fields 4b-aligned. With the old structure,
those fields could never be aligned because the length field would displace them
by one.

Diffstat:
Mfs/doc/arch.txt | 8+++++++-
Mfs/lib/meta.fs | 2+-
Mfs/xcomp/bootlo.fs | 9+++++----
Mfs/xcomp/i386/kernel.fs | 12++++++------
Mfs/xcomp/tools.fs | 2+-
Mposix/vm.c | 29++++++++++++++---------------
6 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/fs/doc/arch.txt b/fs/doc/arch.txt @@ -21,10 +21,12 @@ Dictionaries are a form of linked list. The structure of each entry is: +Xb of padding to align the structure to 4b Xb name +1b name length + immediate 4b pointer to metadata 4b pointer to previous entry --> this is where we link -1b name length + immediate +... payload ... The "previous entry" field in an entry refers to this same place. @@ -33,6 +35,10 @@ The link to "metadata" is a linked list, initialized to 0. The "name length" field is a 7 bit length with the 8th bit reserved for the "immediate" flag (1=immediate). +The whole structure is aligned to 4 bytes, with zero padding in front of the +name to enforce that alignment. This means that the payload is also always +aligned to 4b. + When we refer to a "word" in Dusk OS, we always refer to its first executable byte, right after the name length field. When what you have is a word, you can call it. diff --git a/fs/lib/meta.fs b/fs/lib/meta.fs @@ -2,7 +2,7 @@ \ Dictionary 9 const ENTRYSZ -: wordlen ( w -- len ) 1- c@ $3f and ; +: wordlen ( w -- len ) w>e e>wlen c@ $3f and ; : wordname[] ( w -- sa sl ) bi wordlen | 9 - over - ( sl sa ) swap ; : .word ( w -- ) wordname[] rtype ; diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -57,12 +57,13 @@ code8b W>A, drop, A) 8b) [!], 1 A) [+n], drop, exit, code + PSP) +, nip, exit, code - -W, PSP) +, nip, exit, : -^ swap - ; -: e>w 5 + ; -: w>e 5 - ; +: e>w 4 + ; +: e>wlen 5 - ; +: w>e 4 - ; : current sysdict @ e>w ; code 1+ 1 W+n, exit, code 1- -1 W+n, exit, -: immediate current 1- dup c@ $80 or swap c! ; +: immediate sysdict @ e>wlen dup c@ $80 or swap c! ; : EMETA_16B $11 ; : EMETA_8B $10 ; : 16b EMETA_16B MOD ! ; immediate : 8b EMETA_8B MOD ! ; immediate @@ -329,7 +330,7 @@ code move ( src dst u -- ) word" SZ" code _cur e>w structsz' litn W) @, exit, does> ( 'struct ) _structfind - dup 1- c@ $80 and not compiling and \ compile only if not immediate + dup w>e e>wlen c@ $80 and not compiling and \ compile only if not immediate if execute, else execute then ; : ]struct \ break the chain at the root of the struct diff --git a/fs/xcomp/i386/kernel.fs b/fs/xcomp/i386/kernel.fs @@ -492,20 +492,20 @@ pc to lblfind \ ax=str dx='dict ax inc, di push, si push, pc ( loop ) - bl dx 4 d) mov, \ entry len + bl dx -5 d) mov, \ entry len bl $3f i) and, \ 3f instead of 7f? we reserve space for another flag. bl cl cmp, forward jnz, to L1 ( skip1 ) \ same length di dx mov, - di 4 i) sub, + di 5 i) sub, di cx sub, \ beginning of name range si ax mov, repz, cmpsb, forward jnz, to L2 ( skip2 ) \ same contents si pop, di pop, - dx 5 i) add, \ word + dx 4 i) add, \ word ax dx mov, ret, L2 forward! ( skip2 ) @@ -643,7 +643,7 @@ xcode findmod ( w -- w ) lblmod m) -1 i) test, lblret abs>rel jz, dx ax mov, - ax ax -9 d) mov, + ax ax -8 d) mov, bx lblmod m) mov, L1 abscall, \ findmeta ax ax test, @@ -675,7 +675,7 @@ xcode compword ( str -- ) xwordlbl litn abs>rel jnz, \ literal: jump to litn \ not a literal, find and compile L2 abscall, \ ax=w - ax -1 d) 8b) $80 i) test, + ax -9 d) 8b) $80 i) test, L1 abs>rel jnz, \ immediate? execute \ compile word wcall, findmod @@ -711,13 +711,13 @@ xcode entry ( 'dict s -- ) ax inc, wcall, align4 \ ( 'dict -- ) cx push, lblwriterange abscall, cx pop, + cl cwrite, bx lblnextmeta m) mov, bx dwrite, lblnextmeta m) 0 i) mov, bx ax 0 d) mov, \ ax='dict bx=dict dx lblhere m) mov, ax 0 d) dx mov, xdrop, ( -- ) bx dwrite, - cl cwrite, lbl[rcnt] m) 0 i) mov, ret, diff --git a/fs/xcomp/tools.fs b/fs/xcomp/tools.fs @@ -10,7 +10,7 @@ create xbindict 0 , : xoffset binstart org - ; : xcode xbindict word entry ; -: ximm xbindict @ e>w 1- dup c@ $80 or swap c! ; +: ximm xbindict @ e>wlen dup c@ $80 or swap c! ; \ Usage: xwordlbl foo call, "foo" being a word name in xbindict : xwordlbl ( "name" -- pc ) diff --git a/posix/vm.c b/posix/vm.c @@ -168,9 +168,9 @@ static dword _find(dword dict, byte *name, byte slen) { dword a = dict; byte len; while (memchk(a)) { - len = gb(a+4) & 0x3f; - if ((len == slen) && (memcmp(name, &vm.mem[a-4-len], len)==0)) { - return a+5; + len = gb(a-5) & 0x3f; + if ((len == slen) && (memcmp(name, &vm.mem[a-5-len], len)==0)) { + return a+4; } a = gd(a); } @@ -227,13 +227,18 @@ static void compbinopwr(byte binopidx) { litwr(binopidx); cwrite(0x45); } static void storewr() { cwrite(0x0e); dropwr(); wstorewr(OPA); dropwr(); } static void callword(dword addr); // forward declaration +static void align4(dword n) { + n = (here() + n) % 4; + if (n) { allot(4-n); } +} static void _entry(dword dict, byte *name, byte slen) { + align4(slen+1); memcpy(&vm.mem[here()], name, slen); allot(slen); + cwrite(slen); dwrite(gd(NEXTMETA)); dwrite(gd(dict)); - cwrite(slen); - sd(dict, here()-5); + sd(dict, here()-4); sd(NEXTMETA, 0); } static void entry(char *name) { @@ -470,7 +475,7 @@ static void WNF() { static void FINDMOD() { dword a; if (gd(MOD)) { - if ((a = findmeta(gd(MOD), gd(vm.W-9)))) { + if ((a = findmeta(gd(MOD), gd(vm.W-8)))) { vm.W = a + 8; sd(MOD, 0); } @@ -493,7 +498,7 @@ static void COMPWORD() { ppush(sysdict()); FIND(); if (!vm.W) { WNF(); return; } - if ((gb(vm.W-1) & 0x80) /* immediate */) { + if ((gb(vm.W-9) & 0x80) /* immediate */) { FINDMOD(); callword(ppop()); STACKCHK(); @@ -532,18 +537,12 @@ static void RSADDWR() { static void COMPOP() { dword opcode = ppop(); dword operand = ppop(); wopwr(opcode, operand); } -static void ALIGN4() { // 0x40 - dword n = ppop(); - n = (here() + n) % 4; - if (n) { allot(4-n); } -} +static void ALIGN4() { align4(ppop()); } // 0x40 // ( 'dict s -- ) static void ENTRY() { dword s = ppop(); dword dict = ppop(); byte len = gb(s++); - ppush(len+1); - ALIGN4(); _entry(dict, &vm.mem[s], len); sd(_RCNT_, 0); } @@ -935,7 +934,7 @@ static void callword(dword addr) { static void wentry(char *name, byte op) { entry(name); cwrite(op); retwr(); } static void sysconst(char *name, dword val) { entry(name); litwr(val); retwr(); } static void sysalias(char *name, char *target) { entry(name); brwr(find(target)); } -static void makeimm() { dword a = sysdict()+4; sb(a, gb(a)|0x80); } +static void makeimm() { dword a = sysdict()-5; sb(a, gb(a)|0x80); } static void compileop(byte op) { litwr(op); cwritewr(); } // Names for simple word-to-code mappings