aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2015-06-19 15:49:25 +0200
committerDrahflow <drahflow@gmx.de>2015-06-19 15:49:25 +0200
commit350c441e9b6c1a5fc095263e7ddf8be9918c626c (patch)
tree91e9e5f80cef7490c859cf011004ab5d945cb2c2 /compiler
parent779fb09b603b83440685ae249557c677055031ba (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
Diffstat (limited to 'compiler')
-rw-r--r--compiler/elymasAsmLib.ey25
-rw-r--r--compiler/elymasGlobal.ey18
2 files changed, 33 insertions, 10 deletions
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