about summary refs log tree commit diff stats
path: root/069allocate.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-05-13 00:08:18 -0700
committerKartik Agaram <vc@akkartik.com>2020-05-18 00:44:49 -0700
commite5118fa9fb6b1925f785f810767ca642097622d3 (patch)
treea6ee4e2dd5b491b9897bca991145d3e9b5455656 /069allocate.subx
parent8becbf3c542ecaf2df29ea80cf178921fbc67e82 (diff)
downloadmu-e5118fa9fb6b1925f785f810767ca642097622d3.tar.gz
handle nulls in lookup
Cleaner abstraction, but adds 3 instructions to our overhead for handles,
including one potentially-hard-to-predict jump :/

I wish I could have put the alloc id in eax for the comparison as well,
to save a few bytes of instruction space. But that messes up the non-null
case.
Diffstat (limited to '069allocate.subx')
-rw-r--r--069allocate.subx40
1 files changed, 36 insertions, 4 deletions
diff --git a/069allocate.subx b/069allocate.subx
index 2a40866e..31afc4ff 100644
--- a/069allocate.subx
+++ b/069allocate.subx
@@ -123,6 +123,7 @@ allocate-raw:  # ad: (addr allocation-descriptor), n: int, out: (addr handle)
     89/copy                         0/mod/indirect  2/rm32/edx    .           .             .           0/r32/eax   .               .                 # copy eax to *edx
     # out->payload = ad->curr
     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
+$allocate-raw:save-payload-in-eax:
     89/copy                         1/mod/*+disp8   2/rm32/edx    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(edx+4)
     # *out->payload = Next-alloc-id
     8b/copy                         1/mod/*+disp8   2/rm32/edx    .           .             .           7/r32/edi   4/disp8         .                 # copy *(edx+4) to edi
@@ -260,8 +261,13 @@ lookup:  # h: (handle T) -> eax: (addr T)
     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
     # . save registers
     51/push-ecx
+    # eax = 0
+    31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
     # ecx = handle->alloc_id
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
+    # if (ecx == 0) return 0
+    81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0/imm32           # compare ecx
+    74/jump-if-=  $lookup:end/disp8
     # eax = handle->address (payload)
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
     # if (ecx != *eax) abort
@@ -295,7 +301,6 @@ test-lookup-success:
     # . prologue
     55/push-ebp
     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # . save registers
     # var ad/ebx: allocation-descriptor
     68/push  0/imm32/limit
     68/push  0/imm32/curr
@@ -344,9 +349,36 @@ test-lookup-success:
     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
     # clean up
     c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .           Next-alloc-id/disp32  0x100/imm32 # copy to *Next-alloc-id
-    # . restore registers
-    5a/pop-to-edx
-    59/pop-to-ecx
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
+test-lookup-null-returns-null:
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # var handle/ecx: handle
+    68/push  0/imm32/address
+    68/push  0/imm32/alloc-id
+    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+    # eax = lookup(handle)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   1/rm32/ecx    .           .             .           .           4/disp8         .                 # push *(ecx+4)
+    ff          6/subop/push        0/mod/indirect  1/rm32/ecx    .           .             .           .           .               .                 # push *ecx
+    # . . call
+    e8/call  lookup/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+    # check-ints-equal(eax, 0, msg)
+    # . . push args
+    68/push  "F - test-lookup-null-returns-null"/imm32
+    68/push  0/imm32
+    50/push-eax
+    # . . call
+    e8/call  check-ints-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
     # . epilogue
     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
     5d/pop-to-ebp