"cmd/compile/internal/ir"
"cmd/compile/internal/objw"
"cmd/compile/internal/ssa"
+ "cmd/compile/internal/typebits"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi"
return &lv.be[b.ID]
}
-// NOTE: The bitmap for a specific type t could be cached in t after
-// the first run and then simply copied into bv at the correct offset
-// on future calls with the same type t.
-func SetTypeBits(t *types.Type, off int64, bv bitvec.BitVec) {
- if t.Align > 0 && off&int64(t.Align-1) != 0 {
- base.Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
- }
- if !t.HasPointers() {
- // Note: this case ensures that pointers to go:notinheap types
- // are not considered pointers by garbage collection and stack copying.
- return
- }
-
- switch t.Kind() {
- case types.TPTR, types.TUNSAFEPTR, types.TFUNC, types.TCHAN, types.TMAP:
- if off&int64(types.PtrSize-1) != 0 {
- base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
- }
- bv.Set(int32(off / int64(types.PtrSize))) // pointer
-
- case types.TSTRING:
- // struct { byte *str; intgo len; }
- if off&int64(types.PtrSize-1) != 0 {
- base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
- }
- bv.Set(int32(off / int64(types.PtrSize))) //pointer in first slot
-
- case types.TINTER:
- // struct { Itab *tab; void *data; }
- // or, when isnilinter(t)==true:
- // struct { Type *type; void *data; }
- if off&int64(types.PtrSize-1) != 0 {
- base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
- }
- // The first word of an interface is a pointer, but we don't
- // treat it as such.
- // 1. If it is a non-empty interface, the pointer points to an itab
- // which is always in persistentalloc space.
- // 2. If it is an empty interface, the pointer points to a _type.
- // a. If it is a compile-time-allocated type, it points into
- // the read-only data section.
- // b. If it is a reflect-allocated type, it points into the Go heap.
- // Reflect is responsible for keeping a reference to
- // the underlying type so it won't be GCd.
- // If we ever have a moving GC, we need to change this for 2b (as
- // well as scan itabs to update their itab._type fields).
- bv.Set(int32(off/int64(types.PtrSize) + 1)) // pointer in second slot
-
- case types.TSLICE:
- // struct { byte *array; uintgo len; uintgo cap; }
- if off&int64(types.PtrSize-1) != 0 {
- base.Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
- }
- bv.Set(int32(off / int64(types.PtrSize))) // pointer in first slot (BitsPointer)
-
- case types.TARRAY:
- elt := t.Elem()
- if elt.Width == 0 {
- // Short-circuit for #20739.
- break
- }
- for i := int64(0); i < t.NumElem(); i++ {
- SetTypeBits(elt, off, bv)
- off += elt.Width
- }
-
- case types.TSTRUCT:
- for _, f := range t.Fields().Slice() {
- SetTypeBits(f.Type, off+f.Offset, bv)
- }
-
- default:
- base.Fatalf("onebitwalktype1: unexpected type, %v", t)
- }
-}
-
// Generates live pointer value maps for arguments and local variables. The
// this argument and the in arguments are always assumed live. The vars
// argument is a slice of *Nodes.
node := vars[i]
switch node.Class_ {
case ir.PAUTO:
- SetTypeBits(node.Type(), node.FrameOffset()+lv.stkptrsize, locals)
+ typebits.Set(node.Type(), node.FrameOffset()+lv.stkptrsize, locals)
case ir.PPARAM, ir.PPARAMOUT:
- SetTypeBits(node.Type(), node.FrameOffset(), args)
+ typebits.Set(node.Type(), node.FrameOffset(), args)
}
}
}
off = objw.Uint32(lsym, off, uint32(bv.N))
if ir.IsMethod(fn) {
- SetTypeBits(fn.Type().Recvs(), 0, bv)
+ typebits.Set(fn.Type().Recvs(), 0, bv)
}
if fn.Type().NumParams() > 0 {
- SetTypeBits(fn.Type().Params(), 0, bv)
+ typebits.Set(fn.Type().Params(), 0, bv)
}
off = objw.BitVec(lsym, off, bv)
if fn.Type().NumResults() > 0 {
- SetTypeBits(fn.Type().Results(), 0, bv)
+ typebits.Set(fn.Type().Results(), 0, bv)
off = objw.BitVec(lsym, off, bv)
}
import (
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
- "cmd/compile/internal/ssa"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
p.Pos = pp.Pos
if pp.Pos.IsStmt() == src.PosIsStmt {
// Clear IsStmt for later Progs at this pos provided that as can be marked as a stmt
- if ssa.LosesStmtMark(as) {
+ if LosesStmtMark(as) {
return p
}
pp.Pos = pp.Pos.WithNotStmt()
ptxt.From.Name = obj.NAME_EXTERN
ptxt.From.Sym = fn.LSym
}
+
+// LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF.
+// The attributes from some opcodes are lost in translation.
+// TODO: this is an artifact of how funcpctab combines information for instructions at a single PC.
+// Should try to fix it there.
+func LosesStmtMark(as obj.As) bool {
+ // is_stmt does not work for these; it DOES for ANOP even though that generates no code.
+ return as == obj.APCDATA || as == obj.AFUNCDATA
+}
"cmd/compile/internal/escape"
"cmd/compile/internal/inline"
"cmd/compile/internal/ir"
- "cmd/compile/internal/liveness"
"cmd/compile/internal/objw"
+ "cmd/compile/internal/typebits"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/gcprog"
}
vec := bitvec.New(8 * int32(len(ptrmask)))
- liveness.SetTypeBits(t, 0, vec)
+ typebits.Set(t, 0, vec)
nptr := types.PtrDataSize(t) / int64(types.PtrSize)
for i := int64(0); i < nptr; i++ {
package ssa
import (
- "cmd/internal/obj"
"cmd/internal/src"
"fmt"
"sort"
return false
}
-// LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF.
-// The attributes from some opcodes are lost in translation.
-// TODO: this is an artifact of how funcpctab combines information for instructions at a single PC.
-// Should try to fix it there.
-func LosesStmtMark(as obj.As) bool {
- // is_stmt does not work for these; it DOES for ANOP even though that generates no code.
- return as == obj.APCDATA || as == obj.AFUNCDATA
-}
-
// nextGoodStatementIndex returns an index at i or later that is believed
// to be a good place to start the statement for b. This decision is
// based on v's Op, the possibility of a better later operation, and
// Prog appends a new Prog.
func (s *State) Prog(as obj.As) *obj.Prog {
p := s.pp.Prog(as)
- if ssa.LosesStmtMark(as) {
+ if objw.LosesStmtMark(as) {
return p
}
// Float a statement start to the beginning of any same-line run.
--- /dev/null
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typebits
+
+import (
+ "cmd/compile/internal/base"
+ "cmd/compile/internal/bitvec"
+ "cmd/compile/internal/types"
+)
+
+// NOTE: The bitmap for a specific type t could be cached in t after
+// the first run and then simply copied into bv at the correct offset
+// on future calls with the same type t.
+func Set(t *types.Type, off int64, bv bitvec.BitVec) {
+ if t.Align > 0 && off&int64(t.Align-1) != 0 {
+ base.Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
+ }
+ if !t.HasPointers() {
+ // Note: this case ensures that pointers to go:notinheap types
+ // are not considered pointers by garbage collection and stack copying.
+ return
+ }
+
+ switch t.Kind() {
+ case types.TPTR, types.TUNSAFEPTR, types.TFUNC, types.TCHAN, types.TMAP:
+ if off&int64(types.PtrSize-1) != 0 {
+ base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
+ }
+ bv.Set(int32(off / int64(types.PtrSize))) // pointer
+
+ case types.TSTRING:
+ // struct { byte *str; intgo len; }
+ if off&int64(types.PtrSize-1) != 0 {
+ base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
+ }
+ bv.Set(int32(off / int64(types.PtrSize))) //pointer in first slot
+
+ case types.TINTER:
+ // struct { Itab *tab; void *data; }
+ // or, when isnilinter(t)==true:
+ // struct { Type *type; void *data; }
+ if off&int64(types.PtrSize-1) != 0 {
+ base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
+ }
+ // The first word of an interface is a pointer, but we don't
+ // treat it as such.
+ // 1. If it is a non-empty interface, the pointer points to an itab
+ // which is always in persistentalloc space.
+ // 2. If it is an empty interface, the pointer points to a _type.
+ // a. If it is a compile-time-allocated type, it points into
+ // the read-only data section.
+ // b. If it is a reflect-allocated type, it points into the Go heap.
+ // Reflect is responsible for keeping a reference to
+ // the underlying type so it won't be GCd.
+ // If we ever have a moving GC, we need to change this for 2b (as
+ // well as scan itabs to update their itab._type fields).
+ bv.Set(int32(off/int64(types.PtrSize) + 1)) // pointer in second slot
+
+ case types.TSLICE:
+ // struct { byte *array; uintgo len; uintgo cap; }
+ if off&int64(types.PtrSize-1) != 0 {
+ base.Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
+ }
+ bv.Set(int32(off / int64(types.PtrSize))) // pointer in first slot (BitsPointer)
+
+ case types.TARRAY:
+ elt := t.Elem()
+ if elt.Width == 0 {
+ // Short-circuit for #20739.
+ break
+ }
+ for i := int64(0); i < t.NumElem(); i++ {
+ Set(elt, off, bv)
+ off += elt.Width
+ }
+
+ case types.TSTRUCT:
+ for _, f := range t.Fields().Slice() {
+ Set(f.Type, off+f.Offset, bv)
+ }
+
+ default:
+ base.Fatalf("onebitwalktype1: unexpected type, %v", t)
+ }
+}