aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--compiler/elymasAsmLib.ey25
-rw-r--r--compiler/elymasGlobal.ey18
-rw-r--r--elymas/lib/sys/opt.ey21
4 files changed, 54 insertions, 12 deletions
diff --git a/TODO b/TODO
index 20ae1a5..b8dee38 100644
--- a/TODO
+++ b/TODO
@@ -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 }' {