curfn *Node // fn these Progs are for
progcache []obj.Prog // local progcache
cacheidx int // first free element of progcache
+
+ nextLive LivenessIndex // liveness index for the next Prog
+ prevLive LivenessIndex // last emitted liveness index
}
// newProgs returns a new Progs for fn.
pp.pos = fn.Pos
pp.settext(fn)
+ pp.nextLive = LivenessInvalid
+ pp.prevLive = LivenessInvalid
return pp
}
// Prog adds a Prog with instruction As to pp.
func (pp *Progs) Prog(as obj.As) *obj.Prog {
+ if pp.nextLive.stackMapIndex != pp.prevLive.stackMapIndex {
+ // Emit stack map index change.
+ idx := pp.nextLive.stackMapIndex
+ pp.prevLive.stackMapIndex = idx
+ p := pp.Prog(obj.APCDATA)
+ Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
+ Addrconst(&p.To, int64(idx))
+ }
+
p := pp.next
pp.next = pp.NewProg()
pp.clearp(pp.next)
}
// LivenessInvalid indicates an unsafe point.
-var LivenessInvalid = LivenessIndex{-1}
+//
+// We use index -2 because PCDATA tables conventionally start at -1,
+// so -1 is used to mean the entry liveness map (which is actually at
+// index 0; sigh). TODO(austin): Maybe we should use PCDATA+1 as the
+// index into the liveness map so -1 uniquely refers to the entry
+// liveness map.
+var LivenessInvalid = LivenessIndex{-2}
func (idx LivenessIndex) Valid() bool {
return idx.stackMapIndex >= 0
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
"cmd/internal/obj"
- "cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
)
// Emit basic blocks
for i, b := range f.Blocks {
s.bstart[b.ID] = s.pp.next
+ s.pp.nextLive = LivenessInvalid
s.lineRunStart = nil
+
// Emit values in block
thearch.SSAMarkMoves(&s, b)
for _, v := range b.Values {
x := s.pp.next
s.DebugFriendlySetPosFrom(v)
+ // Attach this safe point to the next
+ // instruction.
+ s.pp.nextLive = s.livenessMap.Get(v)
switch v.Op {
case ssa.OpInitMem:
// memory arg needs no code
Fatalf("missing stack map index for %v", v.LongString())
}
}
- p := s.Prog(obj.APCDATA)
- Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
- Addrconst(&p.To, int64(idx.stackMapIndex))
if sym, _ := v.Aux.(*obj.LSym); sym == Deferreturn {
// Deferred calls will appear to be returning to