Skip to content

Commit

Permalink
cmd/internal/obj: make Prog.From3 a pointer
Browse files Browse the repository at this point in the history
It is almost never set and Addr is large, so having the full struct
in the Prog wastes memory most of the time.

Before (on a 64-bit system):

$ sizeof -p cmd/internal/obj Addr Prog
Addr 80
Prog 376
$

After:

$ sizeof -p cmd/internal/obj Addr Prog
Addr 80
Prog 304
$

Change-Id: I491f201241f87543964a7d0f48b85830759be9d0
Reviewed-on: https://go-review.googlesource.com/10457
Reviewed-by: Josh Bleecher Snyder <[email protected]>
  • Loading branch information
rsc committed May 29, 2015
1 parent 80864cf commit c413c45
Show file tree
Hide file tree
Showing 25 changed files with 863 additions and 548 deletions.
23 changes: 15 additions & 8 deletions src/cmd/asm/internal/asm/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
As: obj.ATEXT,
Lineno: p.histLineNum,
From: nameAddr,
From3: obj.Addr{
From3: &obj.Addr{
Type: obj.TYPE_CONST,
Offset: flag,
},
Expand Down Expand Up @@ -205,7 +205,7 @@ func (p *Parser) asmData(word string, operands [][]lex.Token) {
As: obj.ADATA,
Lineno: p.histLineNum,
From: nameAddr,
From3: obj.Addr{
From3: &obj.Addr{
Offset: int64(scale),
},
To: valueAddr,
Expand Down Expand Up @@ -244,7 +244,7 @@ func (p *Parser) asmGlobl(word string, operands [][]lex.Token) {
As: obj.AGLOBL,
Lineno: p.histLineNum,
From: nameAddr,
From3: obj.Addr{
From3: &obj.Addr{
Offset: flag,
},
To: addr,
Expand Down Expand Up @@ -504,7 +504,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
prog.To = a[2]
case '6', '8':
prog.From = a[0]
prog.From3 = a[1]
prog.From3 = newAddr(a[1])
prog.To = a[2]
case '9':
if arch.IsPPC64CMP(op) {
Expand All @@ -526,7 +526,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
prog.To = a[2]
case obj.TYPE_CONST:
prog.From = a[0]
prog.From3 = a[1]
prog.From3 = newAddr(a[1])
prog.To = a[2]
default:
p.errorf("invalid addressing modes for %s instruction", obj.Aconv(op))
Expand All @@ -551,7 +551,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
if p.arch.Thechar == '7' {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = a[2]
prog.From3 = newAddr(a[2])
prog.To = a[3]
break
}
Expand All @@ -561,7 +561,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
// That is, are there 4-operand instructions without this property?
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = a[2]
prog.From3 = newAddr(a[2])
prog.To = a[3]
break
}
Expand All @@ -579,7 +579,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
} else {
mask = (^uint32(0) >> uint(mask2+1)) & (^uint32(0) << uint(31-(mask1-1)))
}
prog.From3 = obj.Addr{
prog.From3 = &obj.Addr{
Type: obj.TYPE_CONST,
Offset: int64(mask),
}
Expand Down Expand Up @@ -615,6 +615,13 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
p.append(prog, cond, true)
}

// newAddr returns a new(Addr) initialized to x.
func newAddr(x obj.Addr) *obj.Addr {
p := new(obj.Addr)
*p = x
return p
}

var emptyProg obj.Prog

// getConstantPseudo checks that addr represents a plain constant and returns its value.
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/arm64/peep.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,9 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
// can be rewritten independently)
// 0 otherwise (not touched)
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
// 7g never generates a from3
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(&p.From3))
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(p.From3))
}
if p.RegTo2 != obj.REG_NONE {
// 7g never generates a to2
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/gc/gsubr.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func ggloblnod(nam *Node) {
p.To.Sym = nil
p.To.Type = obj.TYPE_CONST
p.To.Offset = nam.Type.Width
p.From3 = new(obj.Addr)
if nam.Name.Readonly {
p.From3.Offset = obj.RODATA
}
Expand All @@ -233,6 +234,7 @@ func ggloblsym(s *Sym, width int32, flags int16) {
}
p.To.Type = obj.TYPE_CONST
p.To.Offset = int64(width)
p.From3 = new(obj.Addr)
p.From3.Offset = int64(flags)
}

Expand Down
9 changes: 9 additions & 0 deletions src/cmd/compile/internal/gc/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ func dstringptr(s *Sym, off int, str string) int {
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
p.From.Offset = int64(off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthptr)

Expand Down Expand Up @@ -334,6 +335,7 @@ func dgostrlitptr(s *Sym, off int, lit *string) int {
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
p.From.Offset = int64(off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthptr)
datagostring(*lit, &p.To)
Expand All @@ -350,6 +352,7 @@ func dsname(s *Sym, off int, t string) int {
p.From.Name = obj.NAME_EXTERN
p.From.Offset = int64(off)
p.From.Sym = Linksym(s)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(len(t))

Expand All @@ -366,6 +369,7 @@ func dsymptr(s *Sym, off int, x *Sym, xoff int) int {
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
p.From.Offset = int64(off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthptr)
p.To.Type = obj.TYPE_ADDR
Expand All @@ -391,6 +395,7 @@ func gdata(nam *Node, nr *Node, wid int) {
}

p := Thearch.Gins(obj.ADATA, nam, nr)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(wid)
}
Expand All @@ -400,12 +405,14 @@ func gdatacomplex(nam *Node, cval *Mpcplx) {
w = int(Types[w].Width)

p := Thearch.Gins(obj.ADATA, nam, nil)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(w)
p.To.Type = obj.TYPE_FCONST
p.To.Val = mpgetflt(&cval.Real)

p = Thearch.Gins(obj.ADATA, nam, nil)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(w)
p.From.Offset += int64(w)
Expand All @@ -418,6 +425,7 @@ func gdatastring(nam *Node, sval string) {

p := Thearch.Gins(obj.ADATA, nam, nil)
Datastring(sval, &p.To)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = Types[Tptr].Width
p.To.Type = obj.TYPE_ADDR
Expand All @@ -427,6 +435,7 @@ func gdatastring(nam *Node, sval string) {
Nodconst(&nod1, Types[TINT], int64(len(sval)))

p = Thearch.Gins(obj.ADATA, nam, &nod1)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = int64(Widthint)
p.From.Offset += int64(Widthptr)
Expand Down
1 change: 1 addition & 0 deletions src/cmd/compile/internal/gc/pgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ func compile(fn *Node) {
nam = nil
}
ptxt = Thearch.Gins(obj.ATEXT, nam, &nod1)
ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok {
ptxt.From3.Offset |= obj.DUPOK
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/reg.go
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ func regopt(firstp *obj.Prog) {

// Currently we never generate three register forms.
// If we do, this will need to change.
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
Fatal("regopt not implemented for from3")
}

Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/ppc64/peep.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,9 +606,9 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
// can be rewritten independently)
// 0 otherwise (not touched)
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
// 9g never generates a from3
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(&p.From3))
fmt.Printf("copyu: from3 (%v) not implemented\n", gc.Ctxt.Dconv(p.From3))
}

switch p.As {
Expand Down
9 changes: 5 additions & 4 deletions src/cmd/internal/obj/arm64/asm7.go
Original file line number Diff line number Diff line change
Expand Up @@ -2040,7 +2040,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rt := int(p.To.Reg)
var r int
var ra int
if p.From3.Type == obj.TYPE_REG {
if p.From3Type() == obj.TYPE_REG {
r = int(p.From3.Reg)
ra = int(p.Reg)
if ra == 0 {
Expand Down Expand Up @@ -2091,7 +2091,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
r := int(p.Reg)
var rf int
if r != 0 {
if p.From3.Type == obj.TYPE_NONE {
if p.From3Type() == obj.TYPE_NONE {
/* CINC/CINV/CNEG */
rf = r

Expand Down Expand Up @@ -2348,7 +2348,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
ctxt.Diag("requires uimm16\n%v", p)
}
s := 0
if p.From3.Type != obj.TYPE_NONE {
if p.From3Type() != obj.TYPE_NONE {
if p.From3.Type != obj.TYPE_CONST {
ctxt.Diag("missing bit position\n%v", p)
}
Expand Down Expand Up @@ -2656,8 +2656,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
ctxt.Diag("implausible condition\n%v", p)
}
rf := int(p.Reg)
if p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
if p.From3 == nil || p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
ctxt.Diag("illegal FCCMP\n%v", p)
break
}
rt := int(p.From3.Reg)
o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/internal/obj/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func Nopout(p *Prog) {
p.As = ANOP
p.Scond = 0
p.From = Addr{}
p.From3 = Addr{}
p.From3 = nil
p.Reg = 0
p.To = Addr{}
}
Expand Down
10 changes: 9 additions & 1 deletion src/cmd/internal/obj/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ type Prog struct {
Ctxt *Link
Link *Prog
From Addr
From3 Addr
From3 *Addr // optional
To Addr
Opt interface{}
Forwd *Prog
Expand All @@ -231,6 +231,14 @@ type Prog struct {
Info ProgInfo
}

// From3Type returns From3.Type, or TYPE_NONE when From3 is nil.
func (p *Prog) From3Type() int16 {
if p.From3 == nil {
return TYPE_NONE
}
return p.From3.Type
}

// ProgInfo holds information about the instruction for use
// by clients such as the compiler. The exact meaning of this
// data is up to the client and is not interpreted by the cmd/internal/obj/... packages.
Expand Down
4 changes: 3 additions & 1 deletion src/cmd/internal/obj/pass.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ func linkpatch(ctxt *Link, sym *LSym) {

for p := sym.Text; p != nil; p = p.Link {
checkaddr(ctxt, p, &p.From)
checkaddr(ctxt, p, &p.From3)
if p.From3 != nil {
checkaddr(ctxt, p, p.From3)
}
checkaddr(ctxt, p, &p.To)

if ctxt.Arch.Progedit != nil {
Expand Down
Loading

0 comments on commit c413c45

Please sign in to comment.