2015-10-08 23:45 GMT+02:00 Eliot Miranda <[email protected]>: > Hi Nicolai, > > On Thu, Oct 8, 2015 at 2:27 PM, Nicolai Hess <[email protected]> wrote: > >> Hello Eliot, and thanks for your time. >> >> >> In our (pharo) implementation for sourceNodeForPC, we start at the >> AST-Node of >> the compiled method, get the IR (IntermediateRepresentation) and scan >> this sequence of IRNodes >> until we finally find that one, that maps to the bytecode of the closure >> creation code (this should be a IRPushClosureCopy). >> The problem is now, we don't find (always) the right IRNode, and it >> depens on the number of local temps, if this is > 3 we don't hit the right >> one. >> > > That's very strange. Can you construct a synthetic example of two simple > blocks, one with three temps and and one with four temps and show me the > difference in the byte code? >
[ :x | | a b c | a:=b:=c:=x ] "calling #sourceNode gives a RBBlockNode - ok" Bytecode 13 <8F 01 00 0B> closureNumCopied: 0 numArgs: 1 bytes 17 to 27 17 <73> pushConstant: nil 18 <73> pushConstant: nil 19 <73> pushConstant: nil 20 <10> pushTemp: 0 21 <81 43> storeIntoTemp: 3 23 <81 42> storeIntoTemp: 2 25 <81 41> storeIntoTemp: 1 27 <7D> blockReturn 28 <7C> returnTop [ :x | | a b c d | a:=b:=c:=d:=x ] "calling #sourceNode gives a RBMethodNode - not ok" Bytecode 13 <8F 01 00 0E> closureNumCopied: 0 numArgs: 1 bytes 17 to 30 17 <73> pushConstant: nil 18 <73> pushConstant: nil 19 <73> pushConstant: nil 20 <73> pushConstant: nil 21 <10> pushTemp: 0 22 <81 44> storeIntoTemp: 4 24 <81 43> storeIntoTemp: 3 26 <81 42> storeIntoTemp: 2 28 <81 41> storeIntoTemp: 1 30 <7D> blockReturn 31 <7C> returnTop As I wrote above, in Pharo, to get the sourceNode we try to find the push closure bytecode from "startpc - 1" by traversing the IR and try to get the IRNode with matching "bytecodeOffset". The bytecodeOffsets for the above blocks: [ :x | | a b c | a:=b:=c:=x ] "bytecodeOffset -> IR" 19->pushClosureCopyCopiedValues: #() args: #(#x) 28->returnTop 20->pushTemp: #x 22->storeTemp: #c 24->storeTemp: #b 26->storeTemp: #a 27->blockReturnTop [ :x | | a b c d | a:=b:=c:=d:=x ] "bytecodeOffset -> IR" 20->pushClosureCopyCopiedValues: #() args: #(#x) 31->returnTop 21->pushTemp: #x 23->storeTemp: #d 25->storeTemp: #c 27->storeTemp: #b 29->storeTemp: #a 30->blockReturnTop Both blocks don't have a bytecodeOffset matching the bytecode of the pushclosure (13), but we start the search from "startpc - 1" (= 16) and do a loop from 0 to -3 (because bytecodes can have a length of 1,2 or 4) For the first block, this works bytecodeOffset 19 = 16 - (-3) For the second block this does not work, somehow the bytecodeoffset value depends on the number of local temps. And for the second block this is one greater. > And my interpretation was, the IRPushClosureCopy node has the wrong >> "bytecode offset" (whatever this is). The bytecodeOffset value (somehow) >> depends on the number of local temps, but maybe this is right (for >> whatever this is used) and we are just using it wrong for in this situation. >> > > So you need to ask Marcus how to interpret bytecodeOffset. The thing is, > it should be simple. One has: > > BlockCreationBytecode > any number of pushConstant: nil's (0 to N) > first byte code in block > last bytecode in block (always a blockReturnTop) > > and a block's startup is always that of the byte immediately following the > BlockCreationBytecode. So if the byte code offset is somehow the span of > the "any number of pushConstant: nil's (0 to N)" then there's a bug in the > IR somewhere when the number of temps is > 3. But if that's not what it > means then, well, I don't know what the problem is. > >
