Closed Bug 436136 Opened 17 years ago Closed 17 years ago

TT: replace LIR_st with LIR_def in order to simplify stack tracking

Categories

(Tamarin Graveyard :: Tracing Virtual Machine, defect, P3)

x86
macOS
defect

Tracking

(Not tracked)

VERIFIED DUPLICATE of bug 460486

People

(Reporter: rreitmai, Unassigned)

References

Details

Instead of using a store to flush values to the stack, create a new instruction , called LIR_def that contains a ref to the value generating instruction, and a ref to LIR_2 which contains a base pointer ref (to rp or sp) and an imm that de-marks the offset on the stack (or an index into a 4Byte stack slot). This instruction is used in place of a LIR_st in the RegionTrackers and can be used as an operand for downstream computation.
During assembly, a LIR_def with a register set on it, will propagate the register setting to its value operand. If a register holding a LIR_def must be spilled then the LIR_def's LIR_2 operand is examined and the register is spilled to that location. (Q. What happens if the the req'd base is not current in a register; should we spill to the C stack ? Or do we take the hit and spill yet another value (making sure it too is not a a LIR_def) ; OK what if they are all LIR_def's then we won't be able to get a scratch register to perform the spill, maybe we could do a quick push / pop sequence to pull the base register, but this seems pretty heavy handed.
Comments also related to 434571... FYI, I'm seeing a similar pattern for trees, wherein we want to reconstitute the trackers at a given exit point. What about something like the following... I wonder if we had a DefWatcher that interrogated defs (or stores) as they streamed and simply kept a map of the most recent values. Assuming we use defs (for which operand 1 is the value and operand 2 is a LIR_2 instruction that consists of base, offset) then the logic for the watcher need only be: map.put(def->oprnd2(), value->oprnd2()) So we'd re-purpose the RegionTracker to be a cache of LIR_2 instructions that correspond to stack locations. The logic roughly being: Linsp pos = track.obtain( sp ); <- builds a LIR_2,base,offset instruction or if one already exists for this 'sp' return it. lirStream.ins(LIR_def, val, pos); <- pushes def into stream watcher.get( pos ); <- watcher was previously linked into the stream and this call now returns the LIR_def we just pushed. Now if we want to rebuild the stack image after the fact we'd build a stream consisting of a DefWatcher and a LirReader and push the instructions through it (although the time around we'd want the watcher to record the first (fifo) instruction encountered for each unique LIR_2 seen; maybe another class DefFirstWatcher?). Now mapping the LIR_2's back to stack positions could be done by the track class (as used above); The DefWatcher providing the LIR_2's that feed it. Another thing that might simplify (and decouple) these things, is to avoid storing the resolved stack offset in the LIR_2's offset operand. Instead we could normalize the value and use an integer index into 4Byte slots on the stack.
Priority: -- → P3
work appears to be continuing on this subject, see https://bugzilla.mozilla.org/show_bug.cgi?id=460486
Status: NEW → RESOLVED
Closed: 17 years ago
Resolution: --- → DUPLICATE
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.