diff options
| author | Drahflow <drahflow@gmx.de> | 2013-09-05 14:19:00 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-09-05 14:19:00 +0200 |
| commit | 05de0ef924f9e4b3b14bd26a6db96f33185cf1f1 (patch) | |
| tree | 35f774be54232eed471a2ecb2a0acad3759b0d59 | |
| parent | 4900a0d4845a67afeed28c7b8a1e3662425c838b (diff) | |
Improvements to the GC
| -rw-r--r-- | compiler/elymasAsm.ey | 13 | ||||
| -rw-r--r-- | compiler/elymasAsmLib.ey | 108 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 1 |
3 files changed, 57 insertions, 65 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey index c3fc242..0fdf307 100644 --- a/compiler/elymasAsm.ey +++ b/compiler/elymasAsm.ey @@ -372,6 +372,17 @@ } mnemonic /bImm variant cat defOp { parse ==mem ==i + i 65536 lt assert + + width16 + mem .base regno %07 gt mem .idx regno %07 gt or + { 0 /none mem .idx mem .base rex } rep + %81 + modrmOpcode mem .encode + i imm16 + } mnemonic /wImm variant cat defOp + + { parse ==mem ==i i 256 lt assert 1 /none mem .idx mem .base rex @@ -766,8 +777,8 @@ mem bit64assert i 65536 lt assert - mem regno %07 gt { 0 /none /none mem rex } rep width16 + mem regno %07 gt { 0 /none /none mem rex } rep %C7 /zero mem modrm00 i imm16 diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey index a2eba57..b8cf32c 100644 --- a/compiler/elymasAsmLib.ey +++ b/compiler/elymasAsmLib.ey @@ -223,17 +223,11 @@ /rbx /rbp :cmpqRegReg /noFreeBlockAvailable :jbeLbl32 - /rbx /rax :movqRegReg - /rbx /rcx :movqRegReg - %3F /rcx :andqImm8Reg # extract bit position in quadword - 6 /rax :shrqImm8Reg # extract quadword - 6 /rbp :shrqImm8Reg # extract one-after-last quadword - /rsi /rsi :xorqRegReg # rsi > 0 => currently counting block extent of free block @testBlockBitLoop - /rcx 8 /rax /r8 :btqRegMemIndexScale # test block bitmap + /rbx /r8 :btqRegMem # test block bitmap /nonFreeBlock :jcLbl8 # block not free /rsi /rsi :andqRegReg /notCurrentlyCounting :jzLbl8 @@ -243,25 +237,19 @@ /rsi /rdi :cmpqRegReg /freeBlockFound :jbeLbl8 - /rcx :incqReg - 6 /rcx :btqImm8Reg - 0 /rax :adcqImm8Reg - %3F /rcx :andqImm8Reg - /rax /rbp :cmpqRegReg + /rbx :incqReg + /rbx /rbp :cmpqRegReg /testBlockBitLoop :jaLbl8 /noFreeBlockAvailable :jmpLbl32 @notCurrentlyCounting - /rcx 8 /rax /r9 :btqRegMemIndexScale # test mark bitmap + /rbx /r9 :btqRegMem # test mark bitmap /currentlyCounting :jcLbl8 # block marked, i.e. truly free block start @nonFreeBlock /rsi /rsi :xorqRegReg - /rcx :incqReg - 6 /rcx :btqImm8Reg - 0 /rax :adcqImm8Reg - %3F /rcx :andqImm8Reg - /rax /rbp :cmpqRegReg + /rbx :incqReg + /rbx /rbp :cmpqRegReg /testBlockBitLoop :jaLbl8 /noFreeBlockAvailable :jmpLbl32 @@ -269,10 +257,6 @@ /r9 :popqReg /r8 :popqReg - 6 /rbp :shlqImm8Reg - 6 /rax :shlqImm8Reg - /rcx /rax /rbx :leaqMemIndexReg - # rdi == size of block to allocate # rbx == last cell of free block of sufficient size @@ -421,37 +405,35 @@ /markObject :callqLbl32 # start from stack and mark all reachable blocks - :mainStack .base :STACKSIZE add /rdi :movqImmReg + :mainStack .base :STACKSIZE add /rsi :movqImmReg @loopThroughMainStack - 8 /rdi :subqImm8Reg - /rdi :pushqReg - /rdi /rdi :movqMemReg + 8 /rsi :subqImm8Reg + /rsi /rdi :movqMemReg /markObject :callqLbl32 - /rdi :popqReg - /rdi /rsp :cmpqRegReg + /rsi /rsp :cmpqRegReg /loopThroughMainStack :jbLbl8 - :mainCallStack .base :STACKSIZE add /rdi :movqImmReg + :mainCallStack .base :STACKSIZE add /rsi :movqImmReg @loopThroughCallStack - 8 /rdi :subqImm8Reg - /rdi :pushqReg - /rdi /rdi :movqMemReg + 8 /rsi :subqImm8Reg + /rsi /rdi :movqMemReg /markObject :callqLbl32 - /rdi :popqReg - /rdi /r15 :cmpqRegReg + /rsi /r15 :cmpqRegReg /loopThroughCallStack :jbLbl8 # start from encoding buffer and mark all reachable blocks # TODO clear encoding buffer in the allocating functions (or mark via :ud2 at beginning) - :quoteEncodingBuffer /rdi :movqImmReg + :quoteEncodingBuffer /rsi :movqImmReg + [ 0 1 ] { [ :ud2 ] * } each 256 mul add /rsi :cmpwImmMem + /quoteEncodingBufferUnused :jzLbl8 + :STACKSIZE 8 sub /rcx :movqImmReg @loopThroughEncodingBuffer - /rdi :pushqReg - /rdi /rdi :movqMemReg + /rsi /rdi :movqMemReg /markObject :callqLbl32 - /rdi :popqReg - /rdi :incqReg + /rsi :incqReg /loopThroughEncodingBuffer :loopLbl8 + @quoteEncodingBufferUnused # free unmarked blocks /r11 /rcx :movqRegReg @@ -485,34 +467,27 @@ :retn # recursively mark this object reachable + # 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 - /rdi /r11 :cmpqRegReg - /markObjectDone :jbeLbl32 # pointing above the heap /rdi /r8 :cmpqRegReg /markObjectDone :jaLbl32 # pointing below the heap 15 /dil :testbImmReg /markObjectDone :jnzLbl32 # pointing to unaligned address + /rdi /r11 :cmpqRegReg + /markObjectDone :jbeLbl32 # pointing above the heap + # rdi == address of a reachable object /rdi /rdx :movqRegReg /r8 /rdx :subqRegReg # rdx == byte offset relative to heap begin 4 /rdx :shrqImm8Reg # rdx == cell index of first 16-byte cell of object - 1 /rsi :movqImmReg - /rdx /rcx :movqRegReg - 7 /cl :andbImmReg - /rsi :shlqClReg # rsi now contains mask bit for block/mark in byte (set bit at relevant position) - /rdx /rcx :movqRegReg - 3 /rcx :shrqImm8Reg # rcx holds byte address for block/mark byte in bitmaps - /rax :movqImmOOBReg BLOCKBASE - /sil 1 /rcx /rax :testbRegMemIndexScale # test block bit - /markObjectDone :jzLbl8 # not pointing to an object - /rax :movqImmOOBReg MARKBASE - /sil 1 /rcx /rax :testbRegMemIndexScale # test mark bit - /markObjectDone :jnzLbl8 # already marked - /sil 1 /rcx /rax :orbRegMemIndexScale # set mark bit + /rdx /r9 :btqRegMem # test block bit + /markObjectDone :jncLbl8 # not pointing to an object + /rdx /r10 :btsqRegMem # test mark bit + /markObjectDone :jcLbl8 # was already marked /rax /rax :xorqRegReg 7 /rdi /al :movbMemDisp8Reg @@ -536,6 +511,7 @@ /rax :decqReg /markFunctionType :jzLbl32 + @markInvalidType /rax /rbx :movqRegReg # for easier inspection "unknown object type during mark phase" outputError :ud2 @@ -555,17 +531,17 @@ # "scope marked\n" outputError # /rdi :popqReg + /rcx :pushqReg /rdi /ecx :movlMemReg 8 /rcx :subqImm8Reg @markScopeLoop /rdi :pushqReg - /rcx :pushqReg /rdi /rcx /rdi :movqMemIndexReg /markObject :callqLbl32 - /rcx :popqReg /rdi :popqReg 8 /rcx :subqImm8Reg /markScopeLoop :jnzLbl8 + /rcx :popqReg :retn @markNameTable @@ -573,19 +549,19 @@ # "name table marked\n" outputError # /rdi :popqReg + /rcx :pushqReg 8 /rdi /ecx :movlMemDisp8Reg 16 /rcx :subqImm8Reg /markNameTableEmpty :jzLbl8 @markNameTableLoop /rdi :pushqReg - /rcx :pushqReg /rdi /rcx /rdi :movqMemIndexReg /markObject :callqLbl32 - /rcx :popqReg /rdi :popqReg 16 /rcx :subqImm8Reg /markNameTableLoop :jnzLbl8 @markNameTableEmpty + /rcx :popqReg :retn @markExtensionArea @@ -593,17 +569,17 @@ # "extension area marked\n" outputError # /rdi :popqReg + /rcx :pushqReg /rdi /ecx :movlMemReg 8 /rcx :subqImm8Reg @markExtensionAreaLoop /rdi :pushqReg - /rcx :pushqReg /rdi /rcx /rdi :movqMemIndexReg /markObject :callqLbl32 - /rcx :popqReg /rdi :popqReg 8 /rcx :subqImm8Reg /markExtensionAreaLoop :jnzLbl8 + /rcx :popqReg :retn @markFunction @@ -630,6 +606,7 @@ # "function code marked\n" outputError # /rdi :popqReg + /rcx :pushqReg /rdi /ecx :movlMemReg 8 /rdi :addqImm8Reg 16 /rcx :subqImm8Reg @@ -638,15 +615,14 @@ /rdi /r11 :cmpqMemReg /codePartNotObject :jbeLbl32 # pointing above the heap /rdi :pushqReg - /rcx :pushqReg /rdi /rdi :movqMemReg /markObject :callqLbl32 - /rcx :popqReg /rdi :popqReg @codePartNotObject /rdi :incqReg /markFunctionCodeLoop :loopLbl8 + /rcx :popqReg :retn @markArray @@ -654,19 +630,19 @@ # "array marked\n" outputError # /rdi :popqReg + /rcx :pushqReg /rdi /ecx :movlMemReg 8 /rcx :subqImm8Reg /markArrayEmpty :jzLbl8 @markArrayLoop /rdi :pushqReg - /rcx :pushqReg /rdi /rcx /rdi :movqMemIndexReg /markObject :callqLbl32 - /rcx :popqReg /rdi :popqReg 8 /rcx :subqImm8Reg /markArrayLoop :jnzLbl8 @markArrayEmpty + /rcx :popqReg :retn @markFunctionType @@ -1099,6 +1075,10 @@ 8 /rax /rdi :leaqMemDisp8Reg /rcx :popqReg :reprcx :movsb + + # mark buffer unused + :quoteEncodingBuffer /rdi :movqImmReg + [ 0 1 ] { [ :ud2 ] * } each 256 mul add /rdi :movwImmMem } /allocateCodeFromEncodingBuffer deff { strToUTF8Bytes _ =*v len _ ==exactLength diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index d9308de..4c42a0b 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -1531,6 +1531,7 @@ /rax /rdi :movqRegMem # TODO kill remaining opcodes to remove GC-followable memory addresses + # possible solution: updatable exact-length field for code blocks # but think of the return stack /rbx :jmpqReg ]] /internalOptimizeGeneratedScopedFunction defv |
