diff options
| author | Drahflow <drahflow@gmx.de> | 2013-12-28 17:41:33 +0100 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-12-28 17:41:33 +0100 |
| commit | d245b90de88b762f65a5007c1776206dc7cd72dc (patch) | |
| tree | 342e65618ef54cf788a10fd8e64ebd52579a5f25 | |
| parent | e57558ebe4635cb0183f94c50f9f61e8603807ff (diff) | |
Reducing memory footprint
| -rw-r--r-- | compiler/elymasAsm.ey | 5 | ||||
| -rw-r--r-- | compiler/elymasAsmLib.ey | 79 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 37 | ||||
| -rw-r--r-- | compiler/elymasGlobalStr.ey | 7 | ||||
| -rw-r--r-- | compiler/standardClient.ey | 533 | ||||
| -rw-r--r-- | elymas/lib/sys/opt.ey | 12 | ||||
| -rw-r--r-- | elymas/lib/sys/so.ey | 15 | ||||
| -rw-r--r-- | elymas/lib/txt.ey | 6 | ||||
| -rw-r--r-- | elymas/memdump.ey | 193 |
9 files changed, 569 insertions, 318 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey index b3a61cd..3f166b1 100644 --- a/compiler/elymasAsm.ey +++ b/compiler/elymasAsm.ey @@ -1112,6 +1112,11 @@ %AE } /scasb deff + { + 1 /none /none /none rex + %AF + } /scasq deff + { ==reg reg regno %07 gt reg rexreqbyte or { 0 reg /none /none rex } rep %0F diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey index e7d38ab..879efe5 100644 --- a/compiler/elymasAsmLib.ey +++ b/compiler/elymasAsmLib.ey @@ -418,9 +418,11 @@ # rdi == cell index of first 16-byte cell of object # TODO optimize this by jumping right into markObject + /rdi /r10 :btsqRegMem # set mark bit 4 /rdi :shlqImm8Reg /r8 /rdi :addqRegReg - /markObject :jmpLbl8 + 1 /rbp :orqImm8Reg # rbp == 1: here from stack exploration, function code references valid in trivial forward + /markObjectUnclean :jmpLbl8 @markObjectDone :retn @@ -429,6 +431,7 @@ # guaranteed not to clobber rcx, rsi (because it is used in many loops) @markObject # rdi == address of a reachable object or some other random bits + /rbp /rbp :xorqRegReg # rbp == 0: not from stack exploration, function code references ignored if trivial forward /rdi /r8 :cmpqRegReg /markObjectDone :jaLbl32 # pointing below the heap 15 /dil :testbImmReg @@ -448,6 +451,7 @@ /rdx /r10 :btsqRegMem # test mark bit /markObjectDone :jcLbl8 # was already marked + @markObjectUnclean /rax /rax :xorqRegReg 7 /rdi /al :movbMemDisp8Reg %F0 /al :andbImmReg @@ -568,6 +572,10 @@ # "function code marked\n" outputError # /rdi :popqReg + /rbp /rbp :testqRegReg + /markFunctionCodeForward :jzLbl8 # FIXME reenable this one day + + @markFunctionCodeFull /rcx :pushqReg /rsi :pushqReg /rdi /ecx :movlMemReg @@ -589,6 +597,20 @@ /rcx :popqReg :retn + # function was reached from somewhere but the stack, check if trivial forward code + @markFunctionCodeForward + 0 [ 0 /rax :movqImmReg ] * 16 /rdi :cmpbImmMemDisp8 + /markFunctionCodeFull :jnzLbl8 + 1 [ 0 /rax :movqImmReg ] * 17 /rdi :cmpbImmMemDisp8 + /markFunctionCodeFull :jnzLbl8 + 0 [ /rax :jmpqReg ] * 26 /rdi :cmpbImmMemDisp8 + /markFunctionCodeFull :jnzLbl8 + 1 [ /rax :jmpqReg ] * 27 /rdi :cmpbImmMemDisp8 + /markFunctionCodeFull :jnzLbl8 + 18 /rdi /rdi :movqMemDisp8Reg + 16 /rdi :subqImm8Reg + /markObject :jmpLbl32 + @markArray # /rdi :pushqReg # "array marked\n" outputError @@ -694,6 +716,26 @@ > { defv }' allocateOffsetStruct < + # allocate a chunk of memory and zero it + # rdi -> size of chunk in bytes + # rax <- address of allocated chunk + # chunk will have GC length header initialized correctly + [[ + internalAllocate /rax :movqImmReg + /rax :callqReg + + /rax /ecx :movlMemReg + 3 /rcx :shrqImm8Reg + 1 /rcx :subqImm8Reg + 8 /rax /rdi :leaqMemDisp8Reg + /rsi /rax :xchgqRegReg + /rax /rax :xorqRegReg + :reprcx :stosq + /rsi /rax :xchgqRegReg + + :retn + ]] /internalAllocateAndZero defv + # resolve element from scope # rdi -> address of scope on the heap # rsi -> address of element name on the heap @@ -732,6 +774,9 @@ # ENDCHECK 8 /rdi /rbp :movqMemDisp8Reg # load name table + /rbp /rbp :testqRegReg + /end :jzLbl8 # no name table present - empty scope + 16 /rbp /rdx :leaqMemDisp8Reg # rdx will iterate over entries 8 /rbp /rbp :addqMemDisp8Reg # compute name table effective end /rsi /rax :movqRegReg @@ -892,44 +937,16 @@ # rax <- address of scope on the heap [ /rsi :pushqReg - /rdi :pushqReg - - # allocate name table - 4 /rdi :shlqImm8Reg - 16 /rdi :addqImm8Reg - internalAllocate /rax :movqImmReg - /rax :callqReg - - # set type - %30 7 /rax :orbImmMemDisp8 - - # set fill to header size - 16 8 /rax :movqImm32MemDisp8 - - /rdi :popqReg - /rax :pushqReg # save name table on the stack 3 /rdi :shlqImm8Reg 32 /rdi :addqImm8Reg - internalAllocate /rax :movqImmReg + internalAllocateAndZero /rax :movqImmReg /rax :callqReg # set type and existence of all pointers %26 7 /rax :orbImmMemDisp8 - 8 /rax :popqMemDisp8 # reference name table 16 /rax :popqMemDisp8 # set parent - # zero extension and remaining scope - - /rax /ecx :movlMemReg - 3 /rcx :shrqImm8Reg - 3 /rcx :subqImm8Reg - 24 /rax /rdi :leaqMemDisp8Reg - /rsi /rax :xchgqRegReg - /rax /rax :xorqRegReg - :reprcx :stosq - /rsi /rax :xchgqRegReg - :retn ] /internalAllocateScope defv @@ -1070,7 +1087,7 @@ 8 /r15 :subqImm8Reg /r14 /r15 :movqRegMem /r14 /rsi :movqRegReg - 8 /rdi :movqImmReg + 2 /rdi :movqImmReg # FIXME: this should use INITIALSCOPESIZE internalAllocateScope /rax :movqImmReg /rax :callqReg /rax /r14 :movqRegReg diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index 3e14219..ba1cbca 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -9,8 +9,9 @@ { [ } "[[" deff { ] :labelResolve ::stringResolve } "]]" deff - 256 ==INITIALEXTENSIONSIZE - 256 ==INITIALSCOPESIZE + 1 ==INITIALEXTENSIONSIZE + 2 ==INITIALSCOPESIZE + 1 ==INITIALNAMETABLESIZE # elymas functions, stack based ABI @@ -139,6 +140,8 @@ # search for name in nametable /r14 /rbx :movqRegReg # rbx == start of scope in heap 8 /rbx /rdx :movqMemDisp8Reg # rdx == start of nametable in heap + /rdx /rdx :testqRegReg + /createNameTable :jzLbl32 8 /rbx /rsi :movqMemDisp8Reg # rsi == start of nametable in heap 8 /rsi /rsi :addqMemDisp8Reg # rsi == end of nametable in heap (according to fill) @@ -172,7 +175,7 @@ /rsi :popqReg /rdx :popqReg /rax /rax :testqRegReg - /nameOffsetKnown :jnzLbl8 + /nameOffsetKnown :jnzLbl32 /nameSearch :jmpLbl8 # if not exists, insert @@ -193,7 +196,7 @@ 8 /rbx /rdx :movqMemDisp8Reg # rdx == start of nametable in heap 16 8 /rdx :addqImm8MemDisp8 # increment fill /rsi /rdx :movqRegReg - /nameOffsetKnown :jmpLbl8 + /nameOffsetKnown :jmpLbl32 @enlargeNameTable # if name table is already full, double size @@ -203,7 +206,7 @@ /rdx /edi :movlMemReg # load current length /rdi /rdi :addqRegReg - ::internalAllocate /rax :movqImmReg + ::internalAllocateAndZero /rax :movqImmReg /rax :callqReg %30 7 /rax :orbImmMemDisp8 # set type /rdx :popqReg @@ -215,15 +218,29 @@ 16 /rcx :subqImm8Reg 3 /rcx :shrqImm8Reg :reprcx :movsq # copy content + /insertIntoNewNameTable :jmpLbl8 + + @createNameTable + /rdi :pushqReg + + INITIALNAMETABLESIZE 16 mul 16 add /rdi :movqImmReg + ::internalAllocateAndZero /rax :movqImmReg + /rax :callqReg + %30 7 /rax :orbImmMemDisp8 # set type + 16 8 /rax :orbImmMemDisp8 # set initial fill + 16 /rax /rdi :leaqMemDisp8Reg # load first entry address + + @insertIntoNewNameTable - # rax == enlarged name table on heap + # rax == enlarged or new name table on heap + # rdi == target address for name table entry /rax 8 /rbx :movqRegMemDisp8 # switch scope to new name table # insert into name table /rsi :popqReg /rsi /rdi :xchgqRegReg - /insertIntoNameTable :jmpLbl8 + /insertIntoNameTable :jmpLbl32 @nameOffsetKnown 8 /rbx /rdx :subqMemDisp8Reg # substract name table address @@ -249,8 +266,8 @@ /extensionAreaExists :jnzLbl8 /rdx :pushqReg - INITIALEXTENSIONSIZE /rdi :movqImmReg - ::internalAllocate /rax :movqImmReg + INITIALEXTENSIONSIZE 8 mul 8 add /rdi :movqImmReg + ::internalAllocateAndZero /rax :movqImmReg /rax :callqReg /rdx :popqReg @@ -271,7 +288,7 @@ /rdx :pushqReg /rdi /edi :movlMemReg /rdi /rdi :addqRegReg - ::internalAllocate /rax :movqImmReg + ::internalAllocateAndZero /rax :movqImmReg /rax :callqReg /rdx :popqReg /rdi :popqReg diff --git a/compiler/elymasGlobalStr.ey b/compiler/elymasGlobalStr.ey index d6d395b..be0b65d 100644 --- a/compiler/elymasGlobalStr.ey +++ b/compiler/elymasGlobalStr.ey @@ -242,8 +242,12 @@ /rcx :popqReg # number of characters to copy /rsi :popqReg - 8 /rsi :addqImm8Reg # move rsi to first array entry /rax :pushqReg # store target string on stack + + /rcx /rcx :testqRegReg + /emptyArray :jzLbl8 + + 8 /rsi :addqImm8Reg # move rsi to first array entry 24 /rax :addqImm8Reg # move rax to first string byte @copyByte @@ -255,6 +259,7 @@ /rax :incqReg /copyByte :loopLbl8 + @emptyArray /rbx :pushqReg :retn ]] /eyfromArray defv diff --git a/compiler/standardClient.ey b/compiler/standardClient.ey index e3c3c23..8d47ad8 100644 --- a/compiler/standardClient.ey +++ b/compiler/standardClient.ey @@ -1,7 +1,7 @@ ## regex support # ideas taken from http://swtch.com/~rsc/regexp/regexp3.html # FIXME: correctly handly */+/? priority -{ +< 0 ==:MATCH 1 ==:TERM 2 ==:JUMP 3 ==:SPLIT 4 ==:SAVE 5 ==:FIRST 6 ==:LAST { ==b ==a [ @@ -9,7 +9,7 @@ a _ len dearray [ JUMP b len 1 add ] b _ len dearray - ] } /alternative deffst + ] } /alternative deffd |cat /sequence deffd @@ -17,17 +17,17 @@ [ JUMP a len 1 add ] a _ len dearray [ SPLIT a len neg 1 ] - ] } /star deffst + ] } /star deffd { ==?p [ [ TERM p ] - ] } /terminal deffst + ] } /terminal deffd { ==?i ==?a [ [ SAVE i 2 mul ] a _ len dearray [ SAVE i 2 mul 1 add ] - ] } /capture deffst + ] } /capture deffd { [ ] } /empty deffd @@ -42,180 +42,14 @@ { 1 -01 str .postfix } /tail deffd { 0 -01 * -101 head eq } "^" deffd - { deffd }' /install deffst + { deffd }' /install deffd [ "(" ")" "[" "]" "-" "|" "^" "*" "+" "." "$" "\\" "?" ] { ==?c { _ head 0 c * eq } "^" c cat install } each - { # "(parse) re: " -101 cat dump - - seq ==?a - ^| { - tail parse ==?b - a b alternative =a - } rep - a - } /parse deffst - - { # "(seq) re: " -101 cat dump - - empty _ ==?a - ==?l - - { # "(seq loop) re: " -101 cat dump - _ head 1 neg eq -01 - ^| -01 - ^) -01 - -0321 or or not - } { - [ { ^* } { - l star =l - tail - } { ^+ } { - l l star sequence =l - tail - } { ^? } { - l empty alternative =l - tail - } { 1 } { - a l sequence =a - atom =l - } ] conds - } loop - a l sequence - } /seq deffst - - 0 ==?currentCapture - - { # "(atom) re: " -101 cat dump - empty ==?a - - [ { ^( } { - tail parse currentCapture capture =a - currentCapture 1 add =currentCapture - ^) not { ") expected" die } rep - tail - } { ^[ } { - tail - ^^ { - tail chars =*nset - { nset not }' ==?set - ^] not { "] expected" die } rep - tail - }' { - chars ==?set - ^] not { "] expected" die } rep - tail - }' ? * - set terminal =a - } { ^. } { - { -- 1 }" terminal =a - tail - } { ^^ } { - [ [ FIRST ] ] =a - tail - } { ^$ } { - [ [ LAST ] ] =a - tail - } { ^\ } { - tail - [ { ^d } { - { _ 0 "0" * ge -01 0 "9" * le and }" terminal =a - tail - } { ^n } { - { 0 "\n" * eq }" terminal =a - tail - } - [ "." "[" "?" "*" "+" "$" "^" "\\" ] { ==c - { _ head 0 c * eq } { - { 0 c * eq } terminal =a - tail - } - } each - { 1 } { - "invalid character '" "' after \\ in regex" -120 cat cat die - } ] conds - } { 1 } { - _ head { eq }_ terminal =a - tail - } ] conds - - # "(atom end) re: " -101 cat dump - a - } /atom deffst - - { # "(chars) re: " -101 cat dump - ^] { - tail chars2 =*s - { _ s -01 0 "]" * eq or }' ==?set - }' { - chars2 ==?set - }' ? * - set - } /chars deffst - - { # "(chars2) re: " -101 cat dump - ^- { - tail chars2 =*s - { _ s -01 0 "-" * eq or }' ==?set - }' { - charsR ==?set - }' ? * - set - } /chars2 deffst - - { # "(charsR) re: " -101 cat dump - charsN ==?set - { ^] not } { - set =*s1 - charsN =*s2 - { _ s1 -01 s2 or }' =set - } loop - set - } /charsR deffst - - { # "(charsN) re: " -101 cat dump - _ head ==?start - ^\ { - tail - [ { ^\ } { - 0 "\\" * =start - } { ^n } { - 0 "\n" * =start - } { 1 } { - "invalid character '" "' after \\ in regex" -120 cat cat die - } ] conds - } rep - tail - ^- { - tail - _ head ==?end - ^\ { - tail - [ { ^\ } { - 0 "\\" * =end - } { ^n } { - 0 "\n" * =end - } { 1 } { - "invalid character '" "' after \\ in regex" -120 cat cat die - } ] conds - } rep - tail - { _ start ge -01 end le and }' ==?set - }' { - { start eq }' ==?set - }' ? * - set - } /charsN deffst - { 0 -01 * }" /threadGetPC deffd { 1 -01 * }" /threadGetCaptures deffd - { [ - 0 # pc - [ currentCapture { 0 0 } rep ] # captures - ] } /newThread deff - { #==thread ==newpc [ -021 threadGetCaptures ] }" /cloneThread deffd @@ -259,106 +93,274 @@ }' /clear deffst > } /threadList deffd - # TODO: reconsider clist/ilist and also reconsider optimisation potential - { ==prog ==string - 0 ==position - string len ==maxPosition - 0 ==matched - < > ==matchedThread + { + 0 ==?currentCapture + + { # "(parse) re: " -101 cat dump - prog len _ threadList ==clist - _ threadList ==nlist - threadList ==ilist + seq ==?a + ^| { + tail parse ==?b + a b alternative =a + } rep + a + } /parse deffst - newThread _ ==thread clist .add + { # "(seq) re: " -101 cat dump - 0 ==pc - { } =*code + empty _ ==?a + ==?l - ilist .|add =*iPush - ilist .|pop =*iPop + { # "(seq loop) re: " -101 cat dump + _ head 1 neg eq -01 + ^| -01 + ^) -01 + -0321 or or not + } { + [ { ^* } { + l star =l + tail + } { ^+ } { + l l star sequence =l + tail + } { ^? } { + l empty alternative =l + tail + } { 1 } { + a l sequence =a + atom =l + } ] conds + } loop + a l sequence + } /seq deffst - [ - { # MATCH - 1 =matched - thread =matchedThread - clist .clear - }" { # TERM - position maxPosition lt { - position string * 1 code * { pc 1 add thread updateThread nlist .add }" rep - }" rep - }" { # JUMP - pc 1 code add thread cloneThread iPush - }" { # SPLIT - pc 2 code add thread cloneThread iPush - pc 1 code add thread cloneThread iPush - }" { # SAVE - pc 1 add thread fullCloneThread - position 1 code -2102 threadGetCaptures =[] - iPush - }" { # FIRST - position 0 eq { pc 1 add thread cloneThread iPush }" rep - }" { # LAST - position maxPosition eq { pc 1 add thread cloneThread iPush }" rep - }" - ] =*codeSemantics - - 0 ==i - { position maxPosition le }" { - 0 =i - - { i clist .size lt }" { - i clist .get _ =thread - threadGetPC _ =pc - prog * =code - 0 code codeSemantics * - i 1 add =i - - { ilist .size }" { - iPop _ =thread - threadGetPC _ =pc - prog * =code + { # "(atom) re: " -101 cat dump + empty ==?a + + [ { ^( } { + tail parse currentCapture capture =a + currentCapture 1 add =currentCapture + ^) not { ") expected" die } rep + tail + } { ^[ } { + tail + ^^ { + tail chars =*nset + { nset not }' ==?set + ^] not { "] expected" die } rep + tail + }' { + chars ==?set + ^] not { "] expected" die } rep + tail + }' ? * + set terminal =a + } { ^. } { + { -- 1 }" terminal =a + tail + } { ^^ } { + [ [ FIRST ] ] =a + tail + } { ^$ } { + [ [ LAST ] ] =a + tail + } { ^\ } { + tail + [ { ^d } { + { _ 0 "0" * ge -01 0 "9" * le and }" terminal =a + tail + } { ^n } { + { 0 "\n" * eq }" terminal =a + tail + } + [ "." "[" "?" "*" "+" "$" "^" "\\" ] { ==c + { _ head 0 c * eq } { + { 0 c * eq } terminal =a + tail + } + } each + { 1 } { + "invalid character '" "' after \\ in regex" -120 cat cat die + } ] conds + } { 1 } { + _ head { eq }_ terminal =a + tail + } ] conds + + # "(atom end) re: " -101 cat dump + a + } /atom deffst + + { # "(chars) re: " -101 cat dump + ^] { + tail chars2 =*s + { _ s -01 0 "]" * eq or }' ==?set + }' { + chars2 ==?set + }' ? * + set + } /chars deffst + + { # "(chars2) re: " -101 cat dump + ^- { + tail chars2 =*s + { _ s -01 0 "-" * eq or }' ==?set + }' { + charsR ==?set + }' ? * + set + } /chars2 deffst + + { # "(charsR) re: " -101 cat dump + charsN ==?set + { ^] not } { + set =*s1 + charsN =*s2 + { _ s1 -01 s2 or }' =set + } loop + set + } /charsR deffst + + { # "(charsN) re: " -101 cat dump + _ head ==?start + ^\ { + tail + [ { ^\ } { + 0 "\\" * =start + } { ^n } { + 0 "\n" * =start + } { 1 } { + "invalid character '" "' after \\ in regex" -120 cat cat die + } ] conds + } rep + tail + ^- { + tail + _ head ==?end + ^\ { + tail + [ { ^\ } { + 0 "\\" * =end + } { ^n } { + 0 "\n" * =end + } { 1 } { + "invalid character '" "' after \\ in regex" -120 cat cat die + } ] conds + } rep + tail + { _ start ge -01 end le and }' ==?set + }' { + { start eq }' ==?set + }' ? * + set + } /charsN deffst + + { [ + 0 # pc + [ currentCapture { 0 0 } rep ] # captures + ] } /newThread deff + + # TODO: reconsider clist/ilist and also reconsider optimisation potential + { ==prog ==string + 0 ==position + string len ==maxPosition + 0 ==matched + < > ==matchedThread + + prog len _ threadList ==clist + _ threadList ==nlist + threadList ==ilist + + newThread _ ==thread clist .add + + 0 ==pc + { } =*code + + ilist .|add =*iPush + ilist .|pop =*iPop + + [ + { # MATCH + 1 =matched + thread =matchedThread + clist .clear + }" { # TERM + position maxPosition lt { + position string * 1 code * { pc 1 add thread updateThread nlist .add }" rep + }" rep + }" { # JUMP + pc 1 code add thread cloneThread iPush + }" { # SPLIT + pc 2 code add thread cloneThread iPush + pc 1 code add thread cloneThread iPush + }" { # SAVE + pc 1 add thread fullCloneThread + position 1 code -2102 threadGetCaptures =[] + iPush + }" { # FIRST + position 0 eq { pc 1 add thread cloneThread iPush }" rep + }" { # LAST + position maxPosition eq { pc 1 add thread cloneThread iPush }" rep + }" + ] =*codeSemantics + + 0 ==i + { position maxPosition le }" { + 0 =i + + { i clist .size lt }" { + i clist .get _ =thread + threadGetPC _ =pc + prog * =code 0 code codeSemantics * + i 1 add =i + + { ilist .size }" { + iPop _ =thread + threadGetPC _ =pc + prog * =code + 0 code codeSemantics * + }" loop }" loop + + # "Next input character ========" dump + clist nlist =clist =nlist + nlist .clear + ilist .clear + position 1 add =position }" loop - # "Next input character ========" dump - clist nlist =clist =nlist - nlist .clear - ilist .clear - position 1 add =position - }" loop - - matched { - currentCapture ==i - { i } { i 1 sub =i - string - i 2 mul matchedThread threadGetCaptures * _ ==start -01 str .postfix - i 2 mul 1 add matchedThread threadGetCaptures * start sub -01 str .inplacePrefix - } loop - } rep - matched - } /execute deffst + matched { + currentCapture ==i + { i } { i 1 sub =i + string + i 2 mul matchedThread threadGetCaptures * _ ==start -01 str .postfix + i 2 mul 1 add matchedThread threadGetCaptures * start sub -01 str .inplacePrefix + } loop + } rep + matched + } /execute deffst - parse ==prog -- - prog 0 -01 * 0 -01 * FIRST eq { - [ - 1 prog len range { prog * } each - ] =prog - } { + parse ==prog -- + prog 0 -01 * 0 -01 * FIRST eq { + [ + 1 prog len range { prog * } each + ] =prog + } { + [ + [ SPLIT 3 1 ] + [ TERM { -- 1 }" ] + [ JUMP 2 neg ] + prog _ len dearray + ] =prog + } ? * [ - [ SPLIT 3 1 ] - [ TERM { -- 1 }" ] - [ JUMP 2 neg ] prog _ len dearray + [ MATCH ] ] =prog - } ? * - [ - prog _ len dearray - [ MATCH ] - ] =prog - { prog execute } -} /enregex deffd + { prog execute } + } +> -- /enregex deffd { quoted { @@ -993,17 +995,16 @@ # Elf64_Xword p_align; /* Alignment of segment */ %01 %00 %00 %00 %00 %00 %00 %00 # alignment } each - ] metaSections { .data cat } each ==fileData + ] ==fileHeaders - fileData len str .alloc ==buffer - 0 fileData len range { ==i i fileData * i buffer =[] } each - - buffer out .writeall + 0 ==fileOffset + [ fileHeaders metaSections { .data } each ] { ==data + fileOffset data len add =fileOffset + data str .fromArray out .writeall + } each 1 ==:WRITE - buffer len ==fileOffset - allocSections { ==section section .dataOffset fileOffset sub str .alloc out .writeall section .dataOffset section .dataSize add =fileOffset diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey index 7e90457..8f54e1e 100644 --- a/elymas/lib/sys/opt.ey +++ b/elymas/lib/sys/opt.ey @@ -15,7 +15,7 @@ 8 /r15 :subqImm8Reg /r14 /r15 :movqRegMem /r14 /rsi :movqRegReg - 8 /rdi :movqImmReg + 0 /rdi :movqImmReg # this should match arbitrary INITIALSCOPESIZE, hence 0 0 /rax :movqImmReg /rax :callqReg /rax /r14 :movqRegReg @@ -694,7 +694,13 @@ [ ] ==newOpcodes { newOpcodes -01 cat =newOpcodes }' /emitOpcodes deffst [ ] ==newReferences - { newReferences [ -102 ] cat =newReferences }' /emitReference deffst + { ==ref + [ + { ref 105553116266496 lt } { } # HEAPBASE # FIXME: use a global constant + { ref 123145302310912 ge } { } # %700000000000 + { 1 } { newReferences [ ref ] cat =newReferences } + ] conds + }' /emitReference deffst # [ :ud2 ] emitOpcodes # enable for further development @@ -705,7 +711,7 @@ 8 /r15 :subqImm8Reg /r14 /r15 :movqRegMem /r14 /rsi :movqRegReg - 8 /rdi :movqImmReg + 2 /rdi :movqImmReg # FIXME: this should use INITIALSCOPESIZE ::internalAllocateScope /rax :movqImmReg /rax :callqReg /rax /r14 :movqRegReg diff --git a/elymas/lib/sys/so.ey b/elymas/lib/sys/so.ey index 1a0d367..0b68250 100644 --- a/elymas/lib/sys/so.ey +++ b/elymas/lib/sys/so.ey @@ -832,17 +832,16 @@ # Elf64_Xword sh_entsize; /* Size of entries, if section has table */ s .entsize uint64 } each } each - ] metaSections { .data cat } each ==fileData + ] ==fileHeaders - fileData len str .alloc ==buffer - 0 fileData len range { ==i i fileData * i buffer =[] } each - - buffer out .writeall + 0 ==fileOffset + [ fileHeaders metaSections { .data } each ] { ==data + fileOffset data len add =fileOffset + data str .fromArray out .writeall + } each 1 ==:WRITE - buffer len ==fileOffset - allocSections { ==section section .dataOffset fileOffset sub str .alloc out .writeall section .dataOffset section .dataSize add =fileOffset @@ -862,4 +861,6 @@ } /freeze deffd > /so sys .defv +{ "disabled to free the memory" die } /freeze sys .deff + # vim: syn=elymas diff --git a/elymas/lib/txt.ey b/elymas/lib/txt.ey index faae0ce..01bd495 100644 --- a/elymas/lib/txt.ey +++ b/elymas/lib/txt.ey @@ -27,6 +27,12 @@ { _ { [ -01 10 math .base reverse "0123456789" each ] str .fromArray } { -- "0" } ? * } [ 0 ] [ "" ] ' /u deffd + + # 0 -> positive integer (or zero) + # 0 <- hexadecimal representation as string + { + _ { [ -01 16 math .base reverse "0123456789ABCDEF" each ] str .fromArray } { -- "0" } ? * + } [ 0 ] [ "" ] ' /hu deffd > /produce defvd > /txt defvd diff --git a/elymas/memdump.ey b/elymas/memdump.ey new file mode 100644 index 0000000..e0f8a48 --- /dev/null +++ b/elymas/memdump.ey @@ -0,0 +1,193 @@ +txt .consume .|hu "%" deffd + +%400000000000 ==:MARKBASE +%500000000000 ==:BLOCKBASE +%600000000000 ==:HEAPBASE +%100000000000 ==:ELFBASE + +< + sys .asm .ops ":" via + sys .asm "::" via + + [ # ==addr + 8 /r15 :subqImm8Reg + /r15 :popqMem + + /rax :popqReg + 8 /rax /rax :movqMemDisp8Reg # this should be a boxed integer + /rax :pushqMem # load data to stack + ::internalAllocateInteger /rax :movqImmReg + /rax :callqReg + 8 /rax :popqMemDisp8 # store data to integer object + /rax :pushqReg + + /r15 :pushqMem + 8 /r15 :addqImm8Reg + :retn + ] [ ] sys .asm .createFunction +> -- /peek64 deffd + +sys .linux "+" via + +< + "shared" +ORDONLY 0 +open ==fd + fd +fstat -- # TODO: handle errors + .size ==s + ELFBASE s +PROTREAD +MAPPRIVATE fd 0 +mmap ELFBASE eq assert +> -- + +ELFBASE 32 add peek64 _ dump ==phdr +ELFBASE 56 add peek64 65536 mod _ dump ==phdrCount + +[ + phdrCount { + ELFBASE phdr add peek64 %100000000 mod 1 eq { # LOAD program header + < + ELFBASE phdr add 8 add peek64 ==fileStart + ELFBASE phdr add 16 add peek64 ==memoryStart + ELFBASE phdr add 32 add peek64 memoryStart add ==memoryEnd + > + } rep + phdr %38 add =phdr + } rep +] _ ==memoryLayout + +{ =*f _ =*a len ==maxI 0 ==i + { + i maxI lt { i a f } { 0 } ? * + } { i 1 add =i } loop +} /eachWhile deffd + +{ ==addr + memoryLayout { ==m + [ + { addr m .memoryStart lt } { 1 } + { addr m .memoryEnd ge } { 1 } + { 1 } { + addr m .memoryStart sub m .fileStart add ELFBASE add peek64 + 0 # loop done + } + ] conds + } eachWhile +} /peekElf64 deffst + +HEAPBASE peekElf64 %2E00000000000248 eq assert + +sys .asm .|programStart sys .asm .rawCodeAddress { add peekElf64 }_ =*peekProgramStart +2 peekProgramStart _ dump ==initialRsp +12 peekProgramStart _ dump ==initialR15 +32 peekProgramStart HEAPBASE add _ dump ==HEAPEND +78 peekProgramStart _ dump ==initialR14 + +< + HEAPEND HEAPBASE sub 16 div 8 div str .alloc _ str .zero ==objectSeen + { + HEAPBASE sub 16 div _ objectSeen str .bitTest -01 + objectSeen str .bitSet + } +> -- /seen deffst + + +1 neg ==indent +{ ==addr ==header + indent { " " sys .out .writeall } rep + header sys .out .writeall + " " sys .out .writeall + addr txt .produce .hu sys .out .writeall + "\n" sys .out .writeall +} /out deffst + +{ ==addr ==header ==type + indent { " " sys .out .writeall } rep + header sys .out .writeall + " " sys .out .writeall + addr txt .produce .hu sys .out .writeall + " " sys .out .writeall + type sys .out .writeall + "\n" sys .out .writeall +} /out2 deffst + +{ ==addr + indent 1 add =indent + [ + { addr HEAPBASE lt } { "--<low>---" addr out } + { addr HEAPEND ge } { "--<high>--" addr out } + { addr seen } { "--<seen>--" addr out } + { 1 } { + { "----------" addr out2 } ":" deffst + addr peekElf64 %1000000000000000 div + [ + { :integer } + { :string + addr 16 add peekElf64 "len:" -01 out + addr 24 add peekElf64 256 math .base str .fromArray 0 out + } + { :scope + addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range { + 8 mul addr add peekElf64 dumpElf + } each + } + { :name_table + addr 8 add peekElf64 _ "fill:" -01 out 16 div 1 -01 range { + 16 mul addr add peekElf64 dumpElf + } each + } + { :extension_area + addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range { + 8 mul addr add peekElf64 dumpElf + } each + } + { :function + addr 8 add peekElf64 dumpElf + addr 16 add peekElf64 dumpElf + addr 24 add peekElf64 dumpElf + } + { :function_code + addr 16 add peekElf64 %FFFF band %B848 eq + addr 26 add peekElf64 %FFFF band %E0FF eq and + { + addr 18 add peekElf64 16 sub dumpElf + } { + addr 8 add peekElf64 _ "oplen:" -01 out ==oplen + addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 2 oplen 8 div add -01 range { + 8 mul addr add peekElf64 dumpElf + } each + } ? * + } + { :array + addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range { + 8 mul addr add peekElf64 dumpElf + } each + } + { :function_type + addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range { + 8 mul addr add peekElf64 dumpElf + } each + } + { :errornous_9 } + { :errornous_A } + { :errornous_B } + { :errornous_C } + { :errornous_D } + { :errornous_E } + { :errornous_F } + ] * * + } + ] conds + indent 1 sub =indent +} /dumpElf deffst + +"=== From current scope ===\n" sys .out .writeall +initialR14 dumpElf +"=== From current data stack ===\n" sys .out .writeall +{ initialRsp %FFFF band } { + initialRsp peekElf64 dumpElf + initialRsp 8 add =initialRsp +} loop +"=== From current call stack ===\n" sys .out .writeall +{ initialR15 %FFFF band } { + initialR15 peekElf64 dumpElf + initialR15 8 add =initialRsp +} loop + +# vim: syn=elymas |
