diff options
| author | Drahflow <drahflow@gmx.de> | 2015-06-19 15:49:25 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2015-06-19 15:49:25 +0200 |
| commit | 350c441e9b6c1a5fc095263e7ddf8be9918c626c (patch) | |
| tree | 91e9e5f80cef7490c859cf011004ab5d945cb2c2 | |
| parent | 779fb09b603b83440685ae249557c677055031ba (diff) | |
Forward function objects to jump pad targets
... and fix really ugly memory bugs occuring because some
code referenced function objects not the code objects
it was calling
| -rw-r--r-- | TODO | 2 | ||||
| -rw-r--r-- | compiler/elymasAsmLib.ey | 25 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 18 | ||||
| -rw-r--r-- | elymas/lib/sys/opt.ey | 21 |
4 files changed, 54 insertions, 12 deletions
@@ -1,6 +1,6 @@ * apply the trace extractor to non-tail situations -* implement the GC-based function opcode forwarding * forward scope-cannot-escape information +* inline trivial functions when optimizer generates ... /rax :movqImmReg /rax :callqReg sequence * utf8 * regex substitution * asm-based regex engine diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey index 42d6ecb..4d51ce5 100644 --- a/compiler/elymasAsmLib.ey +++ b/compiler/elymasAsmLib.ey @@ -664,6 +664,7 @@ /r10 :pushqReg /r11 :pushqReg /r12 :pushqReg + /r13 :pushqReg /r8 :movqImmOOBReg HEAPBASE # constant through mark /r9 :movqImmOOBReg BLOCKBASE # constant through mark @@ -693,12 +694,13 @@ /resetMarkLoop :loopLbl8 @noResetNecessary - # start from current scope and mark all reachable blocks - /r14 /rdi :movqRegReg + # start from current coroutine and mark all reachable blocks + /r13 /rdi :movqRegReg # r13 must be checked first because we use it in markObject + /r13 /r13 :xorqRegReg /markObject :callqLbl32 - # start from current coroutine and mark all reachable blocks - /r13 /rdi :movqRegReg + # start from current scope and mark all reachable blocks + /r14 /rdi :movqRegReg /markObject :callqLbl32 # start from stack and mark all reachable blocks @@ -760,6 +762,7 @@ /freeLoop :loopLbl8 @noFreeNecessary + /r13 :popqReg /r12 :popqReg /r11 :popqReg /r10 :popqReg @@ -984,6 +987,7 @@ 16 /rsi /rdi :movqMemDisp8Reg /markObject :callqLbl32 24 /rsi /rdi :movqMemDisp8Reg + /rsi /r13 :movqRegReg # optimistically inform the mark on the code object of our location /rsi :popqReg /markObject :jmpLbl32 @@ -1028,7 +1032,18 @@ /markFunctionCodeFull :jnzLbl8 1 [ /rax :jmpqReg ] * 27 /rdi :cmpbImmMemDisp8 /markFunctionCodeFull :jnzLbl8 - # TODO: This would be good moment to forward the incoming reference (which is on the stack somewhere), actually + + /r13 /r13 :testqRegReg # check whether r13 contains something (a function object) + /noRewritePossible :jzLbl8 + 24 /r13 /rdi :cmpqMemDisp8Reg # ... which points to the forwarding function code object + /noRewritePossible :jnzLbl8 + + 18 /rdi /rdi :movqMemDisp8Reg + 16 /rdi :subqImm8Reg + /rdi 24 /r13 :movqRegMemDisp8 # if so, rewrite the originating function object while we are at it + /markObject :jmpLbl32 + + @noRewritePossible 18 /rdi /rdi :movqMemDisp8Reg 16 /rdi :subqImm8Reg /markObject :jmpLbl32 diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index 5d9f8f9..b35aa7a 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -1482,7 +1482,9 @@ :retn ] ::loadToRdi - /rdx 0 /rbp :movqRegMemDisp8 # save object reference + /rcx 0 /rbp :movqRegMemDisp8 # save scope reference + 16 /rbx :subqImm8Reg + /rbx 8 /rbp :movqRegMemDisp8 # ... and code reference (in case the function object is ever updated) 8 /r15 /rdi :movqMemDisp8Reg 16 /rdi :addqImm8Reg @@ -1515,7 +1517,8 @@ [ /rax :jmpqReg ] ::loadToRdi - /rdx 0 /rbp :movqRegMemDisp8 # save the address for the GC + 16 /rcx :subqImm8Reg + /rcx 0 /rbp :movqRegMemDisp8 # save code address for the GC 8 /r15 /rdi :movqMemDisp8Reg 16 /rdi :addqImm8Reg @@ -1527,20 +1530,24 @@ @patchConstantPassive 8 /r15 /rdi :movqMemDisp8Reg - # TODO: could reset string reference here + 8 /rdi /rbp :movqMemDisp8Reg + 16 1 /rbp /rdi /rbp :leaqMemIndexScaleDisp8Reg 16 /rdi :addqImm8Reg [ /rbx :popqReg /rax :movqImmOOBReg ] ::loadToRdi - /rdi :popqMem + /rdx :popqReg + /rdx /rdi :movqRegMem 8 /rdi :addqImm8Reg [ /rax :pushqReg /rbx :jmpqReg ] ::loadToRdi + /rdx 0 /rbp :movqRegMemDisp8 # save constant address for the GC + 8 /r15 /rdi :movqMemDisp8Reg 16 /rdi :addqImm8Reg @@ -1825,7 +1832,8 @@ /rsi /rdi :movqRegMem /rsi 0 /rbp :movqRegMemDisp8 8 /rdi :addqImm8Reg - 8 /rbp :addqImm8Reg + 16 /rbp :addqImm8Reg # we only save 1 reference here, but some cases need 2 after patching + 0 8 neg /rbp :andqImm8MemDisp8 [ /rax :pushqReg diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey index c15d0d5..009b6fa 100644 --- a/elymas/lib/sys/opt.ey +++ b/elymas/lib/sys/opt.ey @@ -360,6 +360,9 @@ ] { | ::rawCodeAddress } [ 0 ] [ 0 ] '' * ==:STATICDEFININGFUNCTIONS { ==o ==executingScope + [ ] ==fragileReferences # things the GC should leave alone while we are working on it + { [ -01 ] fragileReferences cat =fragileReferences } /protectReference deffst + 0 ==containsScopeModifications { _ ==logic logic { ==entry 0 entry * ==action @@ -1670,9 +1673,11 @@ executedObject sys .capturedScope { ==scope [ NOP ] i 1 sub logic =[] [ CALLSCOPED executedObject ::rawCodeAddress scope ::rawAddress ] i logic =[] + executedObject ::rawCodeAddress 16 sub ::rawObject protectReference } { [ NOP ] i 1 sub logic =[] [ CALL executedObject ::rawCodeAddress ] i logic =[] + executedObject ::rawCodeAddress 16 sub ::rawObject protectReference } ? * } ? * } @@ -1721,6 +1726,7 @@ } { [ NOP ] i 1 sub logic =[] [ RAWCONSTREP executedObject ::rawCodeAddress ] i logic =[] + executedObject ::rawCodeAddress 16 sub ::rawObject protectReference } ? * } ? * } @@ -1787,7 +1793,6 @@ [ NOP ] i 2 sub logic =[] [ NOP ] i 1 sub logic =[] [ RAWCONSTLOOPTHISSCOPE headerBody 16 add loopBody 16 add ] i logic =[] - /RAWCONSTLOOPTHISSCOPE dump } ] conds } each @@ -1884,6 +1889,8 @@ [ NOP ] i 2 sub logic =[] [ NOP ] i 1 sub logic =[] [ INLINEQUESTIONSTARUNSCOPEDCONST 1 thirdLast * ::rawObject ::rawCodeAddress 1 secondLast * ::rawObject ::rawCodeAddress ] i logic =[] + 1 thirdLast * ::rawObject ::rawCodeAddress 16 sub ::rawObject protectReference + 1 secondLast * ::rawObject ::rawCodeAddress 16 sub ::rawObject protectReference } ? * } ] conds @@ -2072,11 +2079,14 @@ [ s 2 add _ 8 add range peek each ] 256 math .unbase ==pushedConstant [ PUSH pushedConstant ] emitLogic + pushedConstant ::rawObject protectReference } { callConstantPattern match }' { [ s 2 add _ 8 add range peek each ] 256 math .unbase ==calledAddress calledAddress ==j + calledAddress 16 sub ::rawObject protectReference + { { j }' { =j }' peek generalMatch }' /callTargetMatch deffst [ { calledAddress 105553116266496 lt }' { # HEAPBASE # FIXME: should use global constant @@ -2088,6 +2098,7 @@ [ PUSH calledConstant ] emitLogic [ CALL "*" | ::rawCodeAddress ] emitLogic + calledConstant 16 sub ::rawObject protectReference } { constantNormalFunctionScopedUntypedPattern callTargetMatch }' { @@ -2095,18 +2106,22 @@ [ calledAddress 23 add _ 8 add range peek each ] 256 math .unbase ==finalAddress [ CALLSCOPED finalAddress functionScope ] emitLogic + finalAddress 16 sub ::rawObject protectReference + functionScope ::rawObject protectReference } { constantNormalFunctionUnscopedUntypedPattern callTargetMatch }' { [ calledAddress 2 add _ 8 add range peek each ] 256 math .unbase ==finalAddress [ CALL finalAddress ] emitLogic + finalAddress 16 sub ::rawObject protectReference } { constantPassivePattern callTargetMatch }' { [ calledAddress 3 add _ 8 add range peek each ] 256 math .unbase ==pushedConstant [ PUSH pushedConstant ] emitLogic + pushedConstant ::rawObject protectReference } { staticLoadPattern callTargetMatch }' { @@ -2132,6 +2147,7 @@ [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ::rawObject ==exampleObject [ STATICTYPED offsetInScope parentCount 0 exampleObject ] emitLogic + exampleObject protectReference } { staticLoadFromExtensionPattern callTargetMatch }' { @@ -2140,6 +2156,7 @@ [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ::rawObject ==exampleObject [ STATICTYPED offsetInScope parentCount 1 exampleObject ] emitLogic + exampleObject protectReference } { 1 }' { @@ -2172,12 +2189,14 @@ [ calledAddress 9 add _ 8 add range peek each ] 256 math .unbase ==pushedConstant [ PUSH pushedConstant ] emitLogic + pushedConstant ::rawObject protectReference } { customFunctionObjectCreationHeaderPattern callTargetMatch }' { [ calledAddress 9 add _ 8 add range peek each ] 256 math .unbase ==functionBody # function code object address [ FUNCTIONCREATE calledAddress functionBody ] emitLogic + functionBody ::rawObject protectReference } { customFunctionHeaderPattern callTargetMatch }' { |
