github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/cmd/compile/internal/gc/plive.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Garbage collector liveness bitmap generation. 6 7 // The command line flag -live causes this code to print debug information. 8 // The levels are: 9 // 10 // -live (aka -live=1): print liveness lists as code warnings at safe points 11 // -live=2: print an assembly listing with liveness annotations 12 // 13 // Each level includes the earlier output as well. 14 15 package gc 16 17 import ( 18 "cmd/compile/internal/ssa" 19 "cmd/compile/internal/types" 20 "cmd/internal/obj" 21 "cmd/internal/objabi" 22 "cmd/internal/src" 23 "crypto/md5" 24 "crypto/sha1" 25 "fmt" 26 "os" 27 "strings" 28 ) 29 30 // OpVarDef is an annotation for the liveness analysis, marking a place 31 // where a complete initialization (definition) of a variable begins. 32 // Since the liveness analysis can see initialization of single-word 33 // variables quite easy, OpVarDef is only needed for multi-word 34 // variables satisfying isfat(n.Type). For simplicity though, buildssa 35 // emits OpVarDef regardless of variable width. 36 // 37 // An 'OpVarDef x' annotation in the instruction stream tells the liveness 38 // analysis to behave as though the variable x is being initialized at that 39 // point in the instruction stream. The OpVarDef must appear before the 40 // actual (multi-instruction) initialization, and it must also appear after 41 // any uses of the previous value, if any. For example, if compiling: 42 // 43 // x = x[1:] 44 // 45 // it is important to generate code like: 46 // 47 // base, len, cap = pieces of x[1:] 48 // OpVarDef x 49 // x = {base, len, cap} 50 // 51 // If instead the generated code looked like: 52 // 53 // OpVarDef x 54 // base, len, cap = pieces of x[1:] 55 // x = {base, len, cap} 56 // 57 // then the liveness analysis would decide the previous value of x was 58 // unnecessary even though it is about to be used by the x[1:] computation. 59 // Similarly, if the generated code looked like: 60 // 61 // base, len, cap = pieces of x[1:] 62 // x = {base, len, cap} 63 // OpVarDef x 64 // 65 // then the liveness analysis will not preserve the new value of x, because 66 // the OpVarDef appears to have "overwritten" it. 67 // 68 // OpVarDef is a bit of a kludge to work around the fact that the instruction 69 // stream is working on single-word values but the liveness analysis 70 // wants to work on individual variables, which might be multi-word 71 // aggregates. It might make sense at some point to look into letting 72 // the liveness analysis work on single-word values as well, although 73 // there are complications around interface values, slices, and strings, 74 // all of which cannot be treated as individual words. 75 // 76 // OpVarKill is the opposite of OpVarDef: it marks a value as no longer needed, 77 // even if its address has been taken. That is, an OpVarKill annotation asserts 78 // that its argument is certainly dead, for use when the liveness analysis 79 // would not otherwise be able to deduce that fact. 80 81 // TODO: get rid of OpVarKill here. It's useful for stack frame allocation 82 // so the compiler can allocate two temps to the same location. Here it's now 83 // useless, since the implementation of stack objects. 84 85 // BlockEffects summarizes the liveness effects on an SSA block. 86 type BlockEffects struct { 87 // Computed during Liveness.prologue using only the content of 88 // individual blocks: 89 // 90 // uevar: upward exposed variables (used before set in block) 91 // varkill: killed variables (set in block) 92 uevar varRegVec 93 varkill varRegVec 94 95 // Computed during Liveness.solve using control flow information: 96 // 97 // livein: variables live at block entry 98 // liveout: variables live at block exit 99 livein varRegVec 100 liveout varRegVec 101 } 102 103 // A collection of global state used by liveness analysis. 104 type Liveness struct { 105 fn *Node 106 f *ssa.Func 107 vars []*Node 108 idx map[*Node]int32 109 stkptrsize int64 110 111 be []BlockEffects 112 113 // unsafePoints bit i is set if Value ID i is not a safe point. 114 unsafePoints bvec 115 116 // An array with a bit vector for each safe point in the 117 // current Block during Liveness.epilogue. Indexed in Value 118 // order for that block. Additionally, for the entry block 119 // livevars[0] is the entry bitmap. Liveness.compact moves 120 // these to stackMaps and regMaps. 121 livevars []varRegVec 122 123 // livenessMap maps from safe points (i.e., CALLs) to their 124 // liveness map indexes. 125 livenessMap LivenessMap 126 stackMapSet bvecSet 127 stackMaps []bvec 128 regMapSet map[liveRegMask]int 129 regMaps []liveRegMask 130 131 cache progeffectscache 132 } 133 134 // LivenessMap maps from *ssa.Value to LivenessIndex. 135 type LivenessMap struct { 136 m []LivenessIndex 137 } 138 139 func (m *LivenessMap) reset(ids int) { 140 m2 := m.m 141 if ids > cap(m2) { 142 m2 = make([]LivenessIndex, ids) 143 } else { 144 m2 = m2[:ids] 145 } 146 none := LivenessInvalid 147 for i := range m2 { 148 m2[i] = none 149 } 150 m.m = m2 151 } 152 153 func (m *LivenessMap) set(v *ssa.Value, i LivenessIndex) { 154 m.m[v.ID] = i 155 } 156 157 func (m LivenessMap) Get(v *ssa.Value) LivenessIndex { 158 if int(v.ID) < len(m.m) { 159 return m.m[int(v.ID)] 160 } 161 // Not a safe point. 162 return LivenessInvalid 163 } 164 165 // LivenessIndex stores the liveness map index for a safe-point. 166 type LivenessIndex struct { 167 stackMapIndex int 168 regMapIndex int 169 } 170 171 // LivenessInvalid indicates an unsafe point. 172 // 173 // We use index -2 because PCDATA tables conventionally start at -1, 174 // so -1 is used to mean the entry liveness map (which is actually at 175 // index 0; sigh). TODO(austin): Maybe we should use PCDATA+1 as the 176 // index into the liveness map so -1 uniquely refers to the entry 177 // liveness map. 178 var LivenessInvalid = LivenessIndex{-2, -2} 179 180 func (idx LivenessIndex) Valid() bool { 181 return idx.stackMapIndex >= 0 182 } 183 184 type progeffectscache struct { 185 retuevar []int32 186 tailuevar []int32 187 initialized bool 188 } 189 190 // varRegVec contains liveness bitmaps for variables and registers. 191 type varRegVec struct { 192 vars bvec 193 regs liveRegMask 194 } 195 196 func (v *varRegVec) Eq(v2 varRegVec) bool { 197 return v.vars.Eq(v2.vars) && v.regs == v2.regs 198 } 199 200 func (v *varRegVec) Copy(v2 varRegVec) { 201 v.vars.Copy(v2.vars) 202 v.regs = v2.regs 203 } 204 205 func (v *varRegVec) Clear() { 206 v.vars.Clear() 207 v.regs = 0 208 } 209 210 func (v *varRegVec) Or(v1, v2 varRegVec) { 211 v.vars.Or(v1.vars, v2.vars) 212 v.regs = v1.regs | v2.regs 213 } 214 215 func (v *varRegVec) AndNot(v1, v2 varRegVec) { 216 v.vars.AndNot(v1.vars, v2.vars) 217 v.regs = v1.regs &^ v2.regs 218 } 219 220 // livenessShouldTrack reports whether the liveness analysis 221 // should track the variable n. 222 // We don't care about variables that have no pointers, 223 // nor do we care about non-local variables, 224 // nor do we care about empty structs (handled by the pointer check), 225 // nor do we care about the fake PAUTOHEAP variables. 226 func livenessShouldTrack(n *Node) bool { 227 return n.Op == ONAME && (n.Class() == PAUTO || n.Class() == PPARAM || n.Class() == PPARAMOUT) && types.Haspointers(n.Type) 228 } 229 230 // getvariables returns the list of on-stack variables that we need to track 231 // and a map for looking up indices by *Node. 232 func getvariables(fn *Node) ([]*Node, map[*Node]int32) { 233 var vars []*Node 234 for _, n := range fn.Func.Dcl { 235 if livenessShouldTrack(n) { 236 vars = append(vars, n) 237 } 238 } 239 idx := make(map[*Node]int32, len(vars)) 240 for i, n := range vars { 241 idx[n] = int32(i) 242 } 243 return vars, idx 244 } 245 246 func (lv *Liveness) initcache() { 247 if lv.cache.initialized { 248 Fatalf("liveness cache initialized twice") 249 return 250 } 251 lv.cache.initialized = true 252 253 for i, node := range lv.vars { 254 switch node.Class() { 255 case PPARAM: 256 // A return instruction with a p.to is a tail return, which brings 257 // the stack pointer back up (if it ever went down) and then jumps 258 // to a new function entirely. That form of instruction must read 259 // all the parameters for correctness, and similarly it must not 260 // read the out arguments - they won't be set until the new 261 // function runs. 262 lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i)) 263 264 case PPARAMOUT: 265 // All results are live at every return point. 266 // Note that this point is after escaping return values 267 // are copied back to the stack using their PAUTOHEAP references. 268 lv.cache.retuevar = append(lv.cache.retuevar, int32(i)) 269 } 270 } 271 } 272 273 // A liveEffect is a set of flags that describe an instruction's 274 // liveness effects on a variable. 275 // 276 // The possible flags are: 277 // uevar - used by the instruction 278 // varkill - killed by the instruction (set) 279 // A kill happens after the use (for an instruction that updates a value, for example). 280 type liveEffect int 281 282 const ( 283 uevar liveEffect = 1 << iota 284 varkill 285 ) 286 287 // valueEffects returns the index of a variable in lv.vars and the 288 // liveness effects v has on that variable. 289 // If v does not affect any tracked variables, it returns -1, 0. 290 func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) { 291 n, e := affectedNode(v) 292 if e == 0 || n == nil || n.Op != ONAME { // cheapest checks first 293 return -1, 0 294 } 295 296 // AllocFrame has dropped unused variables from 297 // lv.fn.Func.Dcl, but they might still be referenced by 298 // OpVarFoo pseudo-ops. Ignore them to prevent "lost track of 299 // variable" ICEs (issue 19632). 300 switch v.Op { 301 case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive: 302 if !n.Name.Used() { 303 return -1, 0 304 } 305 } 306 307 var effect liveEffect 308 // Read is a read, obviously. 309 // 310 // Addr is a read also, as any subseqent holder of the pointer must be able 311 // to see all the values (including initialization) written so far. 312 if e&(ssa.SymRead|ssa.SymAddr) != 0 { 313 effect |= uevar 314 } 315 if e&ssa.SymWrite != 0 && (!isfat(n.Type) || v.Op == ssa.OpVarDef) { 316 effect |= varkill 317 } 318 319 if effect == 0 { 320 return -1, 0 321 } 322 323 if pos, ok := lv.idx[n]; ok { 324 return pos, effect 325 } 326 return -1, 0 327 } 328 329 // affectedNode returns the *Node affected by v 330 func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) { 331 // Special cases. 332 switch v.Op { 333 case ssa.OpLoadReg: 334 n, _ := AutoVar(v.Args[0]) 335 return n, ssa.SymRead 336 case ssa.OpStoreReg: 337 n, _ := AutoVar(v) 338 return n, ssa.SymWrite 339 340 case ssa.OpVarLive: 341 return v.Aux.(*Node), ssa.SymRead 342 case ssa.OpVarDef, ssa.OpVarKill: 343 return v.Aux.(*Node), ssa.SymWrite 344 case ssa.OpKeepAlive: 345 n, _ := AutoVar(v.Args[0]) 346 return n, ssa.SymRead 347 } 348 349 e := v.Op.SymEffect() 350 if e == 0 { 351 return nil, 0 352 } 353 354 switch a := v.Aux.(type) { 355 case nil, *obj.LSym: 356 // ok, but no node 357 return nil, e 358 case *Node: 359 return a, e 360 default: 361 Fatalf("weird aux: %s", v.LongString()) 362 return nil, e 363 } 364 } 365 366 // regEffects returns the registers affected by v. 367 func (lv *Liveness) regEffects(v *ssa.Value) (uevar, kill liveRegMask) { 368 if v.Op == ssa.OpPhi { 369 // All phi node arguments must come from the same 370 // register and the result must also go to that 371 // register, so there's no overall effect. 372 return 0, 0 373 } 374 addLocs := func(mask liveRegMask, v *ssa.Value, ptrOnly bool) liveRegMask { 375 if int(v.ID) >= len(lv.f.RegAlloc) { 376 // v has no allocated registers. 377 return mask 378 } 379 loc := lv.f.RegAlloc[v.ID] 380 if loc == nil { 381 // v has no allocated registers. 382 return mask 383 } 384 if v.Op == ssa.OpGetG { 385 // GetG represents the G register, which is a 386 // pointer, but not a valid GC register. The 387 // current G is always reachable, so it's okay 388 // to ignore this register. 389 return mask 390 } 391 392 // Collect registers and types from v's location. 393 var regs [2]*ssa.Register 394 nreg := 0 395 switch loc := loc.(type) { 396 case ssa.LocalSlot: 397 return mask 398 case *ssa.Register: 399 if ptrOnly && !v.Type.HasHeapPointer() { 400 return mask 401 } 402 regs[0] = loc 403 nreg = 1 404 case ssa.LocPair: 405 // The value will have TTUPLE type, and the 406 // children are nil or *ssa.Register. 407 if v.Type.Etype != types.TTUPLE { 408 v.Fatalf("location pair %s has non-tuple type %v", loc, v.Type) 409 } 410 for i, loc1 := range loc { 411 if loc1 == nil { 412 continue 413 } 414 if ptrOnly && !v.Type.FieldType(i).HasHeapPointer() { 415 continue 416 } 417 regs[nreg] = loc1.(*ssa.Register) 418 nreg++ 419 } 420 default: 421 v.Fatalf("weird RegAlloc location: %s (%T)", loc, loc) 422 } 423 424 // Add register locations to vars. 425 for _, reg := range regs[:nreg] { 426 if reg.GCNum() == -1 { 427 if ptrOnly { 428 v.Fatalf("pointer in non-pointer register %v", reg) 429 } else { 430 continue 431 } 432 } 433 mask |= 1 << uint(reg.GCNum()) 434 } 435 return mask 436 } 437 438 // v clobbers all registers it writes to (whether or not the 439 // write is pointer-typed). 440 kill = addLocs(0, v, false) 441 for _, arg := range v.Args { 442 // v uses all registers is reads from, but we only 443 // care about marking those containing pointers. 444 uevar = addLocs(uevar, arg, true) 445 } 446 return uevar, kill 447 } 448 449 type liveRegMask uint32 450 451 func (m liveRegMask) niceString(config *ssa.Config) string { 452 if m == 0 { 453 return "<none>" 454 } 455 str := "" 456 for i, reg := range config.GCRegMap { 457 if m&(1<<uint(i)) != 0 { 458 if str != "" { 459 str += "," 460 } 461 str += reg.String() 462 } 463 } 464 return str 465 } 466 467 type livenessFuncCache struct { 468 be []BlockEffects 469 livenessMap LivenessMap 470 } 471 472 // Constructs a new liveness structure used to hold the global state of the 473 // liveness computation. The cfg argument is a slice of *BasicBlocks and the 474 // vars argument is a slice of *Nodes. 475 func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkptrsize int64) *Liveness { 476 lv := &Liveness{ 477 fn: fn, 478 f: f, 479 vars: vars, 480 idx: idx, 481 stkptrsize: stkptrsize, 482 483 regMapSet: make(map[liveRegMask]int), 484 } 485 486 // Significant sources of allocation are kept in the ssa.Cache 487 // and reused. Surprisingly, the bit vectors themselves aren't 488 // a major source of allocation, but the slices are. 489 if lc, _ := f.Cache.Liveness.(*livenessFuncCache); lc == nil { 490 // Prep the cache so liveness can fill it later. 491 f.Cache.Liveness = new(livenessFuncCache) 492 } else { 493 if cap(lc.be) >= f.NumBlocks() { 494 lv.be = lc.be[:f.NumBlocks()] 495 } 496 lv.livenessMap = LivenessMap{lc.livenessMap.m[:0]} 497 } 498 if lv.be == nil { 499 lv.be = make([]BlockEffects, f.NumBlocks()) 500 } 501 502 nblocks := int32(len(f.Blocks)) 503 nvars := int32(len(vars)) 504 bulk := bvbulkalloc(nvars, nblocks*7) 505 for _, b := range f.Blocks { 506 be := lv.blockEffects(b) 507 508 be.uevar = varRegVec{vars: bulk.next()} 509 be.varkill = varRegVec{vars: bulk.next()} 510 be.livein = varRegVec{vars: bulk.next()} 511 be.liveout = varRegVec{vars: bulk.next()} 512 } 513 lv.livenessMap.reset(lv.f.NumValues()) 514 515 lv.markUnsafePoints() 516 return lv 517 } 518 519 func (lv *Liveness) blockEffects(b *ssa.Block) *BlockEffects { 520 return &lv.be[b.ID] 521 } 522 523 // NOTE: The bitmap for a specific type t could be cached in t after 524 // the first run and then simply copied into bv at the correct offset 525 // on future calls with the same type t. 526 func onebitwalktype1(t *types.Type, off int64, bv bvec) { 527 if t.Align > 0 && off&int64(t.Align-1) != 0 { 528 Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off) 529 } 530 531 switch t.Etype { 532 case TINT8, TUINT8, TINT16, TUINT16, 533 TINT32, TUINT32, TINT64, TUINT64, 534 TINT, TUINT, TUINTPTR, TBOOL, 535 TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128: 536 537 case TPTR, TUNSAFEPTR, TFUNC, TCHAN, TMAP: 538 if off&int64(Widthptr-1) != 0 { 539 Fatalf("onebitwalktype1: invalid alignment, %v", t) 540 } 541 bv.Set(int32(off / int64(Widthptr))) // pointer 542 543 case TSTRING: 544 // struct { byte *str; intgo len; } 545 if off&int64(Widthptr-1) != 0 { 546 Fatalf("onebitwalktype1: invalid alignment, %v", t) 547 } 548 bv.Set(int32(off / int64(Widthptr))) //pointer in first slot 549 550 case TINTER: 551 // struct { Itab *tab; void *data; } 552 // or, when isnilinter(t)==true: 553 // struct { Type *type; void *data; } 554 if off&int64(Widthptr-1) != 0 { 555 Fatalf("onebitwalktype1: invalid alignment, %v", t) 556 } 557 // The first word of an interface is a pointer, but we don't 558 // treat it as such. 559 // 1. If it is a non-empty interface, the pointer points to an itab 560 // which is always in persistentalloc space. 561 // 2. If it is an empty interface, the pointer points to a _type. 562 // a. If it is a compile-time-allocated type, it points into 563 // the read-only data section. 564 // b. If it is a reflect-allocated type, it points into the Go heap. 565 // Reflect is responsible for keeping a reference to 566 // the underlying type so it won't be GCd. 567 // If we ever have a moving GC, we need to change this for 2b (as 568 // well as scan itabs to update their itab._type fields). 569 bv.Set(int32(off/int64(Widthptr) + 1)) // pointer in second slot 570 571 case TSLICE: 572 // struct { byte *array; uintgo len; uintgo cap; } 573 if off&int64(Widthptr-1) != 0 { 574 Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t) 575 } 576 bv.Set(int32(off / int64(Widthptr))) // pointer in first slot (BitsPointer) 577 578 case TARRAY: 579 elt := t.Elem() 580 if elt.Width == 0 { 581 // Short-circuit for #20739. 582 break 583 } 584 for i := int64(0); i < t.NumElem(); i++ { 585 onebitwalktype1(elt, off, bv) 586 off += elt.Width 587 } 588 589 case TSTRUCT: 590 for _, f := range t.Fields().Slice() { 591 onebitwalktype1(f.Type, off+f.Offset, bv) 592 } 593 594 default: 595 Fatalf("onebitwalktype1: unexpected type, %v", t) 596 } 597 } 598 599 // usedRegs returns the maximum width of the live register map. 600 func (lv *Liveness) usedRegs() int32 { 601 var any liveRegMask 602 for _, live := range lv.regMaps { 603 any |= live 604 } 605 i := int32(0) 606 for any != 0 { 607 any >>= 1 608 i++ 609 } 610 return i 611 } 612 613 // Generates live pointer value maps for arguments and local variables. The 614 // this argument and the in arguments are always assumed live. The vars 615 // argument is a slice of *Nodes. 616 func (lv *Liveness) pointerMap(liveout bvec, vars []*Node, args, locals bvec) { 617 for i := int32(0); ; i++ { 618 i = liveout.Next(i) 619 if i < 0 { 620 break 621 } 622 node := vars[i] 623 switch node.Class() { 624 case PAUTO: 625 onebitwalktype1(node.Type, node.Xoffset+lv.stkptrsize, locals) 626 627 case PPARAM, PPARAMOUT: 628 onebitwalktype1(node.Type, node.Xoffset, args) 629 } 630 } 631 } 632 633 // markUnsafePoints finds unsafe points and computes lv.unsafePoints. 634 func (lv *Liveness) markUnsafePoints() { 635 if compiling_runtime || lv.f.NoSplit || objabi.Clobberdead_enabled != 0 { 636 // No complex analysis necessary. Do this on the fly 637 // in issafepoint. 638 return 639 } 640 641 lv.unsafePoints = bvalloc(int32(lv.f.NumValues())) 642 643 // Mark write barrier unsafe points. 644 for _, wbBlock := range lv.f.WBLoads { 645 if wbBlock.Kind == ssa.BlockPlain && len(wbBlock.Values) == 0 { 646 // The write barrier block was optimized away 647 // but we haven't done dead block elimination. 648 // (This can happen in -N mode.) 649 continue 650 } 651 // Check that we have the expected diamond shape. 652 if len(wbBlock.Succs) != 2 { 653 lv.f.Fatalf("expected branch at write barrier block %v", wbBlock) 654 } 655 s0, s1 := wbBlock.Succs[0].Block(), wbBlock.Succs[1].Block() 656 if s0 == s1 { 657 // There's no difference between write barrier on and off. 658 // Thus there's no unsafe locations. See issue 26024. 659 continue 660 } 661 if s0.Kind != ssa.BlockPlain || s1.Kind != ssa.BlockPlain { 662 lv.f.Fatalf("expected successors of write barrier block %v to be plain", wbBlock) 663 } 664 if s0.Succs[0].Block() != s1.Succs[0].Block() { 665 lv.f.Fatalf("expected successors of write barrier block %v to converge", wbBlock) 666 } 667 668 // Flow backwards from the control value to find the 669 // flag load. We don't know what lowered ops we're 670 // looking for, but all current arches produce a 671 // single op that does the memory load from the flag 672 // address, so we look for that. 673 var load *ssa.Value 674 v := wbBlock.Control 675 for { 676 if sym, ok := v.Aux.(*obj.LSym); ok && sym == writeBarrier { 677 load = v 678 break 679 } 680 switch v.Op { 681 case ssa.Op386TESTL: 682 // 386 lowers Neq32 to (TESTL cond cond), 683 if v.Args[0] == v.Args[1] { 684 v = v.Args[0] 685 continue 686 } 687 case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload, ssa.OpWasmI64Load32U: 688 // Args[0] is the address of the write 689 // barrier control. Ignore Args[1], 690 // which is the mem operand. 691 // TODO: Just ignore mem operands? 692 v = v.Args[0] 693 continue 694 } 695 // Common case: just flow backwards. 696 if len(v.Args) != 1 { 697 v.Fatalf("write barrier control value has more than one argument: %s", v.LongString()) 698 } 699 v = v.Args[0] 700 } 701 702 // Mark everything after the load unsafe. 703 found := false 704 for _, v := range wbBlock.Values { 705 found = found || v == load 706 if found { 707 lv.unsafePoints.Set(int32(v.ID)) 708 } 709 } 710 711 // Mark the two successor blocks unsafe. These come 712 // back together immediately after the direct write in 713 // one successor and the last write barrier call in 714 // the other, so there's no need to be more precise. 715 for _, succ := range wbBlock.Succs { 716 for _, v := range succ.Block().Values { 717 lv.unsafePoints.Set(int32(v.ID)) 718 } 719 } 720 } 721 722 // Find uintptr -> unsafe.Pointer conversions and flood 723 // unsafeness back to a call (which is always a safe point). 724 // 725 // Looking for the uintptr -> unsafe.Pointer conversion has a 726 // few advantages over looking for unsafe.Pointer -> uintptr 727 // conversions: 728 // 729 // 1. We avoid needlessly blocking safe-points for 730 // unsafe.Pointer -> uintptr conversions that never go back to 731 // a Pointer. 732 // 733 // 2. We don't have to detect calls to reflect.Value.Pointer, 734 // reflect.Value.UnsafeAddr, and reflect.Value.InterfaceData, 735 // which are implicit unsafe.Pointer -> uintptr conversions. 736 // We can't even reliably detect this if there's an indirect 737 // call to one of these methods. 738 // 739 // TODO: For trivial unsafe.Pointer arithmetic, it would be 740 // nice to only flood as far as the unsafe.Pointer -> uintptr 741 // conversion, but it's hard to know which argument of an Add 742 // or Sub to follow. 743 var flooded bvec 744 var flood func(b *ssa.Block, vi int) 745 flood = func(b *ssa.Block, vi int) { 746 if flooded.n == 0 { 747 flooded = bvalloc(int32(lv.f.NumBlocks())) 748 } 749 if flooded.Get(int32(b.ID)) { 750 return 751 } 752 for i := vi - 1; i >= 0; i-- { 753 v := b.Values[i] 754 if v.Op.IsCall() { 755 // Uintptrs must not contain live 756 // pointers across calls, so stop 757 // flooding. 758 return 759 } 760 lv.unsafePoints.Set(int32(v.ID)) 761 } 762 if vi == len(b.Values) { 763 // We marked all values in this block, so no 764 // need to flood this block again. 765 flooded.Set(int32(b.ID)) 766 } 767 for _, pred := range b.Preds { 768 flood(pred.Block(), len(pred.Block().Values)) 769 } 770 } 771 for _, b := range lv.f.Blocks { 772 for i, v := range b.Values { 773 if !(v.Op == ssa.OpConvert && v.Type.IsPtrShaped()) { 774 continue 775 } 776 // Flood the unsafe-ness of this backwards 777 // until we hit a call. 778 flood(b, i+1) 779 } 780 } 781 } 782 783 // Returns true for instructions that are safe points that must be annotated 784 // with liveness information. 785 func (lv *Liveness) issafepoint(v *ssa.Value) bool { 786 // The runtime was written with the assumption that 787 // safe-points only appear at call sites (because that's how 788 // it used to be). We could and should improve that, but for 789 // now keep the old safe-point rules in the runtime. 790 // 791 // go:nosplit functions are similar. Since safe points used to 792 // be coupled with stack checks, go:nosplit often actually 793 // means "no safe points in this function". 794 if compiling_runtime || lv.f.NoSplit || objabi.Clobberdead_enabled != 0 { 795 return v.Op.IsCall() 796 } 797 switch v.Op { 798 case ssa.OpInitMem, ssa.OpArg, ssa.OpSP, ssa.OpSB, 799 ssa.OpSelect0, ssa.OpSelect1, ssa.OpGetG, 800 ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive, 801 ssa.OpPhi: 802 // These don't produce code (see genssa). 803 return false 804 } 805 return !lv.unsafePoints.Get(int32(v.ID)) 806 } 807 808 // Initializes the sets for solving the live variables. Visits all the 809 // instructions in each basic block to summarizes the information at each basic 810 // block 811 func (lv *Liveness) prologue() { 812 lv.initcache() 813 814 for _, b := range lv.f.Blocks { 815 be := lv.blockEffects(b) 816 817 // Walk the block instructions backward and update the block 818 // effects with the each prog effects. 819 for j := len(b.Values) - 1; j >= 0; j-- { 820 pos, e := lv.valueEffects(b.Values[j]) 821 regUevar, regKill := lv.regEffects(b.Values[j]) 822 if e&varkill != 0 { 823 be.varkill.vars.Set(pos) 824 be.uevar.vars.Unset(pos) 825 } 826 be.varkill.regs |= regKill 827 be.uevar.regs &^= regKill 828 if e&uevar != 0 { 829 be.uevar.vars.Set(pos) 830 } 831 be.uevar.regs |= regUevar 832 } 833 } 834 } 835 836 // Solve the liveness dataflow equations. 837 func (lv *Liveness) solve() { 838 // These temporary bitvectors exist to avoid successive allocations and 839 // frees within the loop. 840 nvars := int32(len(lv.vars)) 841 newlivein := varRegVec{vars: bvalloc(nvars)} 842 newliveout := varRegVec{vars: bvalloc(nvars)} 843 844 // Walk blocks in postorder ordering. This improves convergence. 845 po := lv.f.Postorder() 846 847 // Iterate through the blocks in reverse round-robin fashion. A work 848 // queue might be slightly faster. As is, the number of iterations is 849 // so low that it hardly seems to be worth the complexity. 850 851 for change := true; change; { 852 change = false 853 for _, b := range po { 854 be := lv.blockEffects(b) 855 856 newliveout.Clear() 857 switch b.Kind { 858 case ssa.BlockRet: 859 for _, pos := range lv.cache.retuevar { 860 newliveout.vars.Set(pos) 861 } 862 case ssa.BlockRetJmp: 863 for _, pos := range lv.cache.tailuevar { 864 newliveout.vars.Set(pos) 865 } 866 case ssa.BlockExit: 867 // panic exit - nothing to do 868 default: 869 // A variable is live on output from this block 870 // if it is live on input to some successor. 871 // 872 // out[b] = \bigcup_{s \in succ[b]} in[s] 873 newliveout.Copy(lv.blockEffects(b.Succs[0].Block()).livein) 874 for _, succ := range b.Succs[1:] { 875 newliveout.Or(newliveout, lv.blockEffects(succ.Block()).livein) 876 } 877 } 878 879 if !be.liveout.Eq(newliveout) { 880 change = true 881 be.liveout.Copy(newliveout) 882 } 883 884 // A variable is live on input to this block 885 // if it is used by this block, or live on output from this block and 886 // not set by the code in this block. 887 // 888 // in[b] = uevar[b] \cup (out[b] \setminus varkill[b]) 889 newlivein.AndNot(be.liveout, be.varkill) 890 be.livein.Or(newlivein, be.uevar) 891 } 892 } 893 } 894 895 // Visits all instructions in a basic block and computes a bit vector of live 896 // variables at each safe point locations. 897 func (lv *Liveness) epilogue() { 898 nvars := int32(len(lv.vars)) 899 liveout := varRegVec{vars: bvalloc(nvars)} 900 livedefer := bvalloc(nvars) // always-live variables 901 902 // If there is a defer (that could recover), then all output 903 // parameters are live all the time. In addition, any locals 904 // that are pointers to heap-allocated output parameters are 905 // also always live (post-deferreturn code needs these 906 // pointers to copy values back to the stack). 907 // TODO: if the output parameter is heap-allocated, then we 908 // don't need to keep the stack copy live? 909 if lv.fn.Func.HasDefer() { 910 for i, n := range lv.vars { 911 if n.Class() == PPARAMOUT { 912 if n.IsOutputParamHeapAddr() { 913 // Just to be paranoid. Heap addresses are PAUTOs. 914 Fatalf("variable %v both output param and heap output param", n) 915 } 916 if n.Name.Param.Heapaddr != nil { 917 // If this variable moved to the heap, then 918 // its stack copy is not live. 919 continue 920 } 921 // Note: zeroing is handled by zeroResults in walk.go. 922 livedefer.Set(int32(i)) 923 } 924 if n.IsOutputParamHeapAddr() { 925 // This variable will be overwritten early in the function 926 // prologue (from the result of a mallocgc) but we need to 927 // zero it in case that malloc causes a stack scan. 928 n.Name.SetNeedzero(true) 929 livedefer.Set(int32(i)) 930 } 931 } 932 } 933 934 // We must analyze the entry block first. The runtime assumes 935 // the function entry map is index 0. Conveniently, layout 936 // already ensured that the entry block is first. 937 if lv.f.Entry != lv.f.Blocks[0] { 938 lv.f.Fatalf("entry block must be first") 939 } 940 941 { 942 // Reserve an entry for function entry. 943 live := bvalloc(nvars) 944 lv.livevars = append(lv.livevars, varRegVec{vars: live}) 945 } 946 947 for _, b := range lv.f.Blocks { 948 be := lv.blockEffects(b) 949 firstBitmapIndex := len(lv.livevars) 950 951 // Walk forward through the basic block instructions and 952 // allocate liveness maps for those instructions that need them. 953 for _, v := range b.Values { 954 if !lv.issafepoint(v) { 955 continue 956 } 957 958 live := bvalloc(nvars) 959 lv.livevars = append(lv.livevars, varRegVec{vars: live}) 960 } 961 962 // walk backward, construct maps at each safe point 963 index := int32(len(lv.livevars) - 1) 964 965 liveout.Copy(be.liveout) 966 for i := len(b.Values) - 1; i >= 0; i-- { 967 v := b.Values[i] 968 969 if lv.issafepoint(v) { 970 // Found an interesting instruction, record the 971 // corresponding liveness information. 972 973 live := &lv.livevars[index] 974 live.Or(*live, liveout) 975 live.vars.Or(live.vars, livedefer) // only for non-entry safe points 976 index-- 977 } 978 979 // Update liveness information. 980 pos, e := lv.valueEffects(v) 981 regUevar, regKill := lv.regEffects(v) 982 if e&varkill != 0 { 983 liveout.vars.Unset(pos) 984 } 985 liveout.regs &^= regKill 986 if e&uevar != 0 { 987 liveout.vars.Set(pos) 988 } 989 liveout.regs |= regUevar 990 } 991 992 if b == lv.f.Entry { 993 if index != 0 { 994 Fatalf("bad index for entry point: %v", index) 995 } 996 997 // Check to make sure only input variables are live. 998 for i, n := range lv.vars { 999 if !liveout.vars.Get(int32(i)) { 1000 continue 1001 } 1002 if n.Class() == PPARAM { 1003 continue // ok 1004 } 1005 Fatalf("bad live variable at entry of %v: %L", lv.fn.Func.Nname, n) 1006 } 1007 1008 // Record live variables. 1009 live := &lv.livevars[index] 1010 live.Or(*live, liveout) 1011 } 1012 1013 // Check that no registers are live across calls. 1014 // For closure calls, the CALLclosure is the last use 1015 // of the context register, so it's dead after the call. 1016 index = int32(firstBitmapIndex) 1017 for _, v := range b.Values { 1018 if lv.issafepoint(v) { 1019 live := lv.livevars[index] 1020 if v.Op.IsCall() && live.regs != 0 { 1021 lv.printDebug() 1022 v.Fatalf("internal error: %v register %s recorded as live at call", lv.fn.Func.Nname, live.regs.niceString(lv.f.Config)) 1023 } 1024 index++ 1025 } 1026 } 1027 1028 // The liveness maps for this block are now complete. Compact them. 1029 lv.compact(b) 1030 } 1031 1032 // Done compacting. Throw out the stack map set. 1033 lv.stackMaps = lv.stackMapSet.extractUniqe() 1034 lv.stackMapSet = bvecSet{} 1035 1036 // Useful sanity check: on entry to the function, 1037 // the only things that can possibly be live are the 1038 // input parameters. 1039 for j, n := range lv.vars { 1040 if n.Class() != PPARAM && lv.stackMaps[0].Get(int32(j)) { 1041 Fatalf("internal error: %v %L recorded as live on entry", lv.fn.Func.Nname, n) 1042 } 1043 } 1044 // Check that no registers are live at function entry. 1045 // The context register, if any, comes from a 1046 // LoweredGetClosurePtr operation first thing in the function, 1047 // so it doesn't appear live at entry. 1048 if regs := lv.regMaps[0]; regs != 0 { 1049 lv.printDebug() 1050 lv.f.Fatalf("internal error: %v register %s recorded as live on entry", lv.fn.Func.Nname, regs.niceString(lv.f.Config)) 1051 } 1052 } 1053 1054 func (lv *Liveness) clobber() { 1055 // The clobberdead experiment inserts code to clobber all the dead variables (locals and args) 1056 // before and after every safepoint. This experiment is useful for debugging the generation 1057 // of live pointer bitmaps. 1058 if objabi.Clobberdead_enabled == 0 { 1059 return 1060 } 1061 var varSize int64 1062 for _, n := range lv.vars { 1063 varSize += n.Type.Size() 1064 } 1065 if len(lv.stackMaps) > 1000 || varSize > 10000 { 1066 // Be careful to avoid doing too much work. 1067 // Bail if >1000 safepoints or >10000 bytes of variables. 1068 // Otherwise, giant functions make this experiment generate too much code. 1069 return 1070 } 1071 if h := os.Getenv("GOCLOBBERDEADHASH"); h != "" { 1072 // Clobber only functions where the hash of the function name matches a pattern. 1073 // Useful for binary searching for a miscompiled function. 1074 hstr := "" 1075 for _, b := range sha1.Sum([]byte(lv.fn.funcname())) { 1076 hstr += fmt.Sprintf("%08b", b) 1077 } 1078 if !strings.HasSuffix(hstr, h) { 1079 return 1080 } 1081 fmt.Printf("\t\t\tCLOBBERDEAD %s\n", lv.fn.funcname()) 1082 } 1083 if lv.f.Name == "forkAndExecInChild" || lv.f.Name == "wbBufFlush" { 1084 // forkAndExecInChild calls vfork (on linux/amd64, anyway). 1085 // The code we add here clobbers parts of the stack in the child. 1086 // When the parent resumes, it is using the same stack frame. But the 1087 // child has clobbered stack variables that the parent needs. Boom! 1088 // In particular, the sys argument gets clobbered. 1089 // Note to self: GOCLOBBERDEADHASH=011100101110 1090 // 1091 // runtime.wbBufFlush must not modify its arguments. See the comments 1092 // in runtime/mwbbuf.go:wbBufFlush. 1093 return 1094 } 1095 1096 var oldSched []*ssa.Value 1097 for _, b := range lv.f.Blocks { 1098 // Copy block's values to a temporary. 1099 oldSched = append(oldSched[:0], b.Values...) 1100 b.Values = b.Values[:0] 1101 1102 // Clobber all dead variables at entry. 1103 if b == lv.f.Entry { 1104 for len(oldSched) > 0 && len(oldSched[0].Args) == 0 { 1105 // Skip argless ops. We need to skip at least 1106 // the lowered ClosurePtr op, because it 1107 // really wants to be first. This will also 1108 // skip ops like InitMem and SP, which are ok. 1109 b.Values = append(b.Values, oldSched[0]) 1110 oldSched = oldSched[1:] 1111 } 1112 clobber(lv, b, lv.stackMaps[0]) 1113 } 1114 1115 // Copy values into schedule, adding clobbering around safepoints. 1116 for _, v := range oldSched { 1117 if !lv.issafepoint(v) { 1118 b.Values = append(b.Values, v) 1119 continue 1120 } 1121 before := true 1122 if v.Op.IsCall() && v.Aux != nil && v.Aux.(*obj.LSym) == typedmemmove { 1123 // Can't put clobber code before the call to typedmemmove. 1124 // The variable to-be-copied is marked as dead 1125 // at the callsite. That is ok, though, as typedmemmove 1126 // is marked as nosplit, and the first thing it does 1127 // is to call memmove (also nosplit), after which 1128 // the source value is dead. 1129 // See issue 16026. 1130 before = false 1131 } 1132 if before { 1133 clobber(lv, b, lv.stackMaps[lv.livenessMap.Get(v).stackMapIndex]) 1134 } 1135 b.Values = append(b.Values, v) 1136 clobber(lv, b, lv.stackMaps[lv.livenessMap.Get(v).stackMapIndex]) 1137 } 1138 } 1139 } 1140 1141 // clobber generates code to clobber all dead variables (those not marked in live). 1142 // Clobbering instructions are added to the end of b.Values. 1143 func clobber(lv *Liveness, b *ssa.Block, live bvec) { 1144 for i, n := range lv.vars { 1145 if !live.Get(int32(i)) { 1146 clobberVar(b, n) 1147 } 1148 } 1149 } 1150 1151 // clobberVar generates code to trash the pointers in v. 1152 // Clobbering instructions are added to the end of b.Values. 1153 func clobberVar(b *ssa.Block, v *Node) { 1154 clobberWalk(b, v, 0, v.Type) 1155 } 1156 1157 // b = block to which we append instructions 1158 // v = variable 1159 // offset = offset of (sub-portion of) variable to clobber (in bytes) 1160 // t = type of sub-portion of v. 1161 func clobberWalk(b *ssa.Block, v *Node, offset int64, t *types.Type) { 1162 if !types.Haspointers(t) { 1163 return 1164 } 1165 switch t.Etype { 1166 case TPTR, 1167 TUNSAFEPTR, 1168 TFUNC, 1169 TCHAN, 1170 TMAP: 1171 clobberPtr(b, v, offset) 1172 1173 case TSTRING: 1174 // struct { byte *str; int len; } 1175 clobberPtr(b, v, offset) 1176 1177 case TINTER: 1178 // struct { Itab *tab; void *data; } 1179 // or, when isnilinter(t)==true: 1180 // struct { Type *type; void *data; } 1181 // Note: the first word isn't a pointer. See comment in plive.go:onebitwalktype1. 1182 clobberPtr(b, v, offset+int64(Widthptr)) 1183 1184 case TSLICE: 1185 // struct { byte *array; int len; int cap; } 1186 clobberPtr(b, v, offset) 1187 1188 case TARRAY: 1189 for i := int64(0); i < t.NumElem(); i++ { 1190 clobberWalk(b, v, offset+i*t.Elem().Size(), t.Elem()) 1191 } 1192 1193 case TSTRUCT: 1194 for _, t1 := range t.Fields().Slice() { 1195 clobberWalk(b, v, offset+t1.Offset, t1.Type) 1196 } 1197 1198 default: 1199 Fatalf("clobberWalk: unexpected type, %v", t) 1200 } 1201 } 1202 1203 // clobberPtr generates a clobber of the pointer at offset offset in v. 1204 // The clobber instruction is added at the end of b. 1205 func clobberPtr(b *ssa.Block, v *Node, offset int64) { 1206 b.NewValue0IA(src.NoXPos, ssa.OpClobber, types.TypeVoid, offset, v) 1207 } 1208 1209 // Compact coalesces identical bitmaps from lv.livevars into the sets 1210 // lv.stackMapSet and lv.regMaps. 1211 // 1212 // Compact clears lv.livevars. 1213 // 1214 // There are actually two lists of bitmaps, one list for the local variables and one 1215 // list for the function arguments. Both lists are indexed by the same PCDATA 1216 // index, so the corresponding pairs must be considered together when 1217 // merging duplicates. The argument bitmaps change much less often during 1218 // function execution than the local variable bitmaps, so it is possible that 1219 // we could introduce a separate PCDATA index for arguments vs locals and 1220 // then compact the set of argument bitmaps separately from the set of 1221 // local variable bitmaps. As of 2014-04-02, doing this to the godoc binary 1222 // is actually a net loss: we save about 50k of argument bitmaps but the new 1223 // PCDATA tables cost about 100k. So for now we keep using a single index for 1224 // both bitmap lists. 1225 func (lv *Liveness) compact(b *ssa.Block) { 1226 add := func(live varRegVec) LivenessIndex { 1227 // Deduplicate the stack map. 1228 stackIndex := lv.stackMapSet.add(live.vars) 1229 // Deduplicate the register map. 1230 regIndex, ok := lv.regMapSet[live.regs] 1231 if !ok { 1232 regIndex = len(lv.regMapSet) 1233 lv.regMapSet[live.regs] = regIndex 1234 lv.regMaps = append(lv.regMaps, live.regs) 1235 } 1236 return LivenessIndex{stackIndex, regIndex} 1237 } 1238 pos := 0 1239 if b == lv.f.Entry { 1240 // Handle entry stack map. 1241 add(lv.livevars[0]) 1242 pos++ 1243 } 1244 for _, v := range b.Values { 1245 if lv.issafepoint(v) { 1246 lv.livenessMap.set(v, add(lv.livevars[pos])) 1247 pos++ 1248 } 1249 } 1250 1251 // Reset livevars. 1252 lv.livevars = lv.livevars[:0] 1253 } 1254 1255 func (lv *Liveness) showlive(v *ssa.Value, live bvec) { 1256 if debuglive == 0 || lv.fn.funcname() == "init" || strings.HasPrefix(lv.fn.funcname(), ".") { 1257 return 1258 } 1259 if !(v == nil || v.Op.IsCall()) { 1260 // Historically we only printed this information at 1261 // calls. Keep doing so. 1262 return 1263 } 1264 if live.IsEmpty() { 1265 return 1266 } 1267 1268 pos := lv.fn.Func.Nname.Pos 1269 if v != nil { 1270 pos = v.Pos 1271 } 1272 1273 s := "live at " 1274 if v == nil { 1275 s += fmt.Sprintf("entry to %s:", lv.fn.funcname()) 1276 } else if sym, ok := v.Aux.(*obj.LSym); ok { 1277 fn := sym.Name 1278 if pos := strings.Index(fn, "."); pos >= 0 { 1279 fn = fn[pos+1:] 1280 } 1281 s += fmt.Sprintf("call to %s:", fn) 1282 } else { 1283 s += "indirect call:" 1284 } 1285 1286 for j, n := range lv.vars { 1287 if live.Get(int32(j)) { 1288 s += fmt.Sprintf(" %v", n) 1289 } 1290 } 1291 1292 Warnl(pos, s) 1293 } 1294 1295 func (lv *Liveness) printbvec(printed bool, name string, live varRegVec) bool { 1296 if live.vars.IsEmpty() && live.regs == 0 { 1297 return printed 1298 } 1299 1300 if !printed { 1301 fmt.Printf("\t") 1302 } else { 1303 fmt.Printf(" ") 1304 } 1305 fmt.Printf("%s=", name) 1306 1307 comma := "" 1308 for i, n := range lv.vars { 1309 if !live.vars.Get(int32(i)) { 1310 continue 1311 } 1312 fmt.Printf("%s%s", comma, n.Sym.Name) 1313 comma = "," 1314 } 1315 fmt.Printf("%s%s", comma, live.regs.niceString(lv.f.Config)) 1316 return true 1317 } 1318 1319 // printeffect is like printbvec, but for valueEffects and regEffects. 1320 func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool, regMask liveRegMask) bool { 1321 if !x && regMask == 0 { 1322 return printed 1323 } 1324 if !printed { 1325 fmt.Printf("\t") 1326 } else { 1327 fmt.Printf(" ") 1328 } 1329 fmt.Printf("%s=", name) 1330 if x { 1331 fmt.Printf("%s", lv.vars[pos].Sym.Name) 1332 } 1333 for j, reg := range lv.f.Config.GCRegMap { 1334 if regMask&(1<<uint(j)) != 0 { 1335 if x { 1336 fmt.Printf(",") 1337 } 1338 x = true 1339 fmt.Printf("%v", reg) 1340 } 1341 } 1342 return true 1343 } 1344 1345 // Prints the computed liveness information and inputs, for debugging. 1346 // This format synthesizes the information used during the multiple passes 1347 // into a single presentation. 1348 func (lv *Liveness) printDebug() { 1349 fmt.Printf("liveness: %s\n", lv.fn.funcname()) 1350 1351 pcdata := 0 1352 for i, b := range lv.f.Blocks { 1353 if i > 0 { 1354 fmt.Printf("\n") 1355 } 1356 1357 // bb#0 pred=1,2 succ=3,4 1358 fmt.Printf("bb#%d pred=", b.ID) 1359 for j, pred := range b.Preds { 1360 if j > 0 { 1361 fmt.Printf(",") 1362 } 1363 fmt.Printf("%d", pred.Block().ID) 1364 } 1365 fmt.Printf(" succ=") 1366 for j, succ := range b.Succs { 1367 if j > 0 { 1368 fmt.Printf(",") 1369 } 1370 fmt.Printf("%d", succ.Block().ID) 1371 } 1372 fmt.Printf("\n") 1373 1374 be := lv.blockEffects(b) 1375 1376 // initial settings 1377 printed := false 1378 printed = lv.printbvec(printed, "uevar", be.uevar) 1379 printed = lv.printbvec(printed, "livein", be.livein) 1380 if printed { 1381 fmt.Printf("\n") 1382 } 1383 1384 // program listing, with individual effects listed 1385 1386 if b == lv.f.Entry { 1387 live := lv.stackMaps[pcdata] 1388 fmt.Printf("(%s) function entry\n", linestr(lv.fn.Func.Nname.Pos)) 1389 fmt.Printf("\tlive=") 1390 printed = false 1391 for j, n := range lv.vars { 1392 if !live.Get(int32(j)) { 1393 continue 1394 } 1395 if printed { 1396 fmt.Printf(",") 1397 } 1398 fmt.Printf("%v", n) 1399 printed = true 1400 } 1401 fmt.Printf("\n") 1402 } 1403 1404 for _, v := range b.Values { 1405 fmt.Printf("(%s) %v\n", linestr(v.Pos), v.LongString()) 1406 1407 if pos := lv.livenessMap.Get(v); pos.Valid() { 1408 pcdata = pos.stackMapIndex 1409 } 1410 1411 pos, effect := lv.valueEffects(v) 1412 regUevar, regKill := lv.regEffects(v) 1413 printed = false 1414 printed = lv.printeffect(printed, "uevar", pos, effect&uevar != 0, regUevar) 1415 printed = lv.printeffect(printed, "varkill", pos, effect&varkill != 0, regKill) 1416 if printed { 1417 fmt.Printf("\n") 1418 } 1419 1420 if !lv.issafepoint(v) { 1421 continue 1422 } 1423 1424 live := lv.stackMaps[pcdata] 1425 fmt.Printf("\tlive=") 1426 printed = false 1427 for j, n := range lv.vars { 1428 if !live.Get(int32(j)) { 1429 continue 1430 } 1431 if printed { 1432 fmt.Printf(",") 1433 } 1434 fmt.Printf("%v", n) 1435 printed = true 1436 } 1437 regLive := lv.regMaps[lv.livenessMap.Get(v).regMapIndex] 1438 if regLive != 0 { 1439 if printed { 1440 fmt.Printf(",") 1441 } 1442 fmt.Printf("%s", regLive.niceString(lv.f.Config)) 1443 } 1444 fmt.Printf("\n") 1445 } 1446 1447 // bb bitsets 1448 fmt.Printf("end\n") 1449 printed = false 1450 printed = lv.printbvec(printed, "varkill", be.varkill) 1451 printed = lv.printbvec(printed, "liveout", be.liveout) 1452 if printed { 1453 fmt.Printf("\n") 1454 } 1455 } 1456 1457 fmt.Printf("\n") 1458 } 1459 1460 // Dumps a slice of bitmaps to a symbol as a sequence of uint32 values. The 1461 // first word dumped is the total number of bitmaps. The second word is the 1462 // length of the bitmaps. All bitmaps are assumed to be of equal length. The 1463 // remaining bytes are the raw bitmaps. 1464 func (lv *Liveness) emit(argssym, livesym, regssym *obj.LSym) { 1465 // Size args bitmaps to be just large enough to hold the largest pointer. 1466 // First, find the largest Xoffset node we care about. 1467 // (Nodes without pointers aren't in lv.vars; see livenessShouldTrack.) 1468 var maxArgNode *Node 1469 for _, n := range lv.vars { 1470 switch n.Class() { 1471 case PPARAM, PPARAMOUT: 1472 if maxArgNode == nil || n.Xoffset > maxArgNode.Xoffset { 1473 maxArgNode = n 1474 } 1475 } 1476 } 1477 // Next, find the offset of the largest pointer in the largest node. 1478 var maxArgs int64 1479 if maxArgNode != nil { 1480 maxArgs = maxArgNode.Xoffset + typeptrdata(maxArgNode.Type) 1481 } 1482 1483 // Size locals bitmaps to be stkptrsize sized. 1484 // We cannot shrink them to only hold the largest pointer, 1485 // because their size is used to calculate the beginning 1486 // of the local variables frame. 1487 // Further discussion in https://golang.org/cl/104175. 1488 // TODO: consider trimming leading zeros. 1489 // This would require shifting all bitmaps. 1490 maxLocals := lv.stkptrsize 1491 1492 args := bvalloc(int32(maxArgs / int64(Widthptr))) 1493 aoff := duint32(argssym, 0, uint32(len(lv.stackMaps))) // number of bitmaps 1494 aoff = duint32(argssym, aoff, uint32(args.n)) // number of bits in each bitmap 1495 1496 locals := bvalloc(int32(maxLocals / int64(Widthptr))) 1497 loff := duint32(livesym, 0, uint32(len(lv.stackMaps))) // number of bitmaps 1498 loff = duint32(livesym, loff, uint32(locals.n)) // number of bits in each bitmap 1499 1500 for _, live := range lv.stackMaps { 1501 args.Clear() 1502 locals.Clear() 1503 1504 lv.pointerMap(live, lv.vars, args, locals) 1505 1506 aoff = dbvec(argssym, aoff, args) 1507 loff = dbvec(livesym, loff, locals) 1508 } 1509 1510 regs := bvalloc(lv.usedRegs()) 1511 roff := duint32(regssym, 0, uint32(len(lv.regMaps))) // number of bitmaps 1512 roff = duint32(regssym, roff, uint32(regs.n)) // number of bits in each bitmap 1513 if regs.n > 32 { 1514 // Our uint32 conversion below won't work. 1515 Fatalf("GP registers overflow uint32") 1516 } 1517 1518 if regs.n > 0 { 1519 for _, live := range lv.regMaps { 1520 regs.Clear() 1521 regs.b[0] = uint32(live) 1522 roff = dbvec(regssym, roff, regs) 1523 } 1524 } 1525 1526 // Give these LSyms content-addressable names, 1527 // so that they can be de-duplicated. 1528 // This provides significant binary size savings. 1529 // It is safe to rename these LSyms because 1530 // they are tracked separately from ctxt.hash. 1531 argssym.Name = fmt.Sprintf("gclocals·%x", md5.Sum(argssym.P)) 1532 livesym.Name = fmt.Sprintf("gclocals·%x", md5.Sum(livesym.P)) 1533 regssym.Name = fmt.Sprintf("gclocals·%x", md5.Sum(regssym.P)) 1534 } 1535 1536 // Entry pointer for liveness analysis. Solves for the liveness of 1537 // pointer variables in the function and emits a runtime data 1538 // structure read by the garbage collector. 1539 // Returns a map from GC safe points to their corresponding stack map index. 1540 func liveness(e *ssafn, f *ssa.Func) LivenessMap { 1541 // Construct the global liveness state. 1542 vars, idx := getvariables(e.curfn) 1543 lv := newliveness(e.curfn, f, vars, idx, e.stkptrsize) 1544 1545 // Run the dataflow framework. 1546 lv.prologue() 1547 lv.solve() 1548 lv.epilogue() 1549 lv.clobber() 1550 if debuglive > 0 { 1551 lv.showlive(nil, lv.stackMaps[0]) 1552 for _, b := range f.Blocks { 1553 for _, val := range b.Values { 1554 if idx := lv.livenessMap.Get(val); idx.Valid() { 1555 lv.showlive(val, lv.stackMaps[idx.stackMapIndex]) 1556 } 1557 } 1558 } 1559 } 1560 if debuglive >= 2 { 1561 lv.printDebug() 1562 } 1563 1564 // Update the function cache. 1565 { 1566 cache := f.Cache.Liveness.(*livenessFuncCache) 1567 if cap(lv.be) < 2000 { // Threshold from ssa.Cache slices. 1568 for i := range lv.be { 1569 lv.be[i] = BlockEffects{} 1570 } 1571 cache.be = lv.be 1572 } 1573 if cap(lv.livenessMap.m) < 2000 { 1574 cache.livenessMap = lv.livenessMap 1575 } 1576 } 1577 1578 // Emit the live pointer map data structures 1579 if ls := e.curfn.Func.lsym; ls != nil { 1580 lv.emit(&ls.Func.GCArgs, &ls.Func.GCLocals, &ls.Func.GCRegs) 1581 } 1582 return lv.livenessMap 1583 }