]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: track pragmas in lexer rather than global variables
authorRobert Griesemer <gri@golang.org>
Fri, 26 Feb 2016 21:32:28 +0000 (13:32 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 26 Feb 2016 22:01:16 +0000 (22:01 +0000)
By using a Pragma bit set (8 bits) rather than 8 booleans, also
reduce Func type size by 8 bytes (208B -> 200B on 64bit platforms,
116B -> 108B on 32bit platforms).

Change-Id: Ibb7e1f8c418a0b5bc6ff813cbdde7bc6f0013b5a
Reviewed-on: https://go-review.googlesource.com/19966
Reviewed-by: Dave Cheney <dave@cheney.net>
src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/cgen.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/lex.go
src/cmd/compile/internal/gc/parser.go
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/racewalk.go
src/cmd/compile/internal/gc/syntax.go

index 731f31ba52d3e5062056f172b25487c4b84576aa..f330f1b9e67222aa91a5c68de5a07acfb87bbda8 100644 (file)
@@ -240,10 +240,9 @@ func (p *importer) typ() *Type {
                        {
                                saved := structpkg
                                structpkg = tsym.Pkg
-                               addmethod(sym, n.Type, false, nointerface)
+                               addmethod(sym, n.Type, false, false)
                                structpkg = saved
                        }
-                       nointerface = false
                        funchdr(n)
 
                        // (comment from go.y)
index fdeb6e65f7912c83d2799f32958af91aade0748d..7be050dd56651cd6308b7d7ee95f9636178e3e31 100644 (file)
@@ -781,7 +781,7 @@ var sys_wbptr *Node
 
 func cgen_wbptr(n, res *Node) {
        if Curfn != nil {
-               if Curfn.Func.Nowritebarrier {
+               if Curfn.Func.Pragma&Nowritebarrier != 0 {
                        Yyerror("write barrier prohibited")
                }
                if Curfn.Func.WBLineno == 0 {
@@ -831,7 +831,7 @@ func cgen_wbptr(n, res *Node) {
 
 func cgen_wbfat(n, res *Node) {
        if Curfn != nil {
-               if Curfn.Func.Nowritebarrier {
+               if Curfn.Func.Pragma&Nowritebarrier != 0 {
                        Yyerror("write barrier prohibited")
                }
                if Curfn.Func.WBLineno == 0 {
index ccbb2d9d70bf84be8b1fda91fc6e27a48e50226d..e485f9d79faa577c04222772a4f90e73ea31ad9c 100644 (file)
@@ -1530,7 +1530,7 @@ func checknowritebarrierrec() {
 
                // Check nowritebarrierrec functions.
                for _, n := range list {
-                       if !n.Func.Nowritebarrierrec {
+                       if n.Func.Pragma&Nowritebarrierrec == 0 {
                                continue
                        }
                        call, hasWB := c.best[n]
index a6fe8947c3b2ef0e13f8dfdb399d2f2a2c2cdc58..dbf3a97e7cb230f9fe50bfc1a2854fa05605f397 100644 (file)
@@ -616,23 +616,10 @@ var flag_largemodel int
 // when the race detector is enabled.
 var instrumenting bool
 
-// Pending annotations for next func declaration.
-var (
-       noescape          bool
-       noinline          bool
-       norace            bool
-       nosplit           bool
-       nowritebarrier    bool
-       nowritebarrierrec bool
-       systemstack       bool
-)
-
 var debuglive int
 
 var Ctxt *obj.Link
 
-var nointerface bool
-
 var writearchive int
 
 var bstdout obj.Biobuf
index cae15f91dee460f3d1782a1fcd2a8a36c4d6ff5a..17cc61a823f8be27554d6d0f959adc1d42c984e3 100644 (file)
@@ -107,7 +107,7 @@ func caninl(fn *Node) {
        }
 
        // If marked "go:noinline", don't inline
-       if fn.Func.Noinline {
+       if fn.Func.Pragma&Noinline != 0 {
                return
        }
 
index d6a18c7286d313124f71f72450af906a1d7a33f7..c15fefb71ddef83ae59bd8157fa7a0d3e6ef0115 100644 (file)
@@ -844,6 +844,19 @@ func plan9quote(s string) string {
        return s
 }
 
+type Pragma uint8
+
+const (
+       Nointerface       Pragma = 1 << iota
+       Noescape                 // func parameters don't escape
+       Norace                   // func must not have race detector annotations
+       Nosplit                  // func should not execute on separate stack
+       Noinline                 // func should not be inlined
+       Systemstack              // func must run on system stack
+       Nowritebarrier           // emit compiler error instead of write barrier
+       Nowritebarrierrec        // error on write barrier in this or recursive callees
+)
+
 type lexer struct {
        // source
        bin    *obj.Biobuf
@@ -852,6 +865,10 @@ type lexer struct {
 
        nlsemi bool // if set, '\n' and EOF translate to ';'
 
+       // pragma flags
+       // accumulated by lexer; reset by parser
+       pragma Pragma
+
        // current token
        tok  int32
        sym_ *Sym // valid if tok == LNAME
@@ -1650,32 +1667,31 @@ func (l *lexer) getlinepragma() rune {
                        Lookup(f[1]).Linkname = f[2]
                case "go:nointerface":
                        if obj.Fieldtrack_enabled != 0 {
-                               nointerface = true
+                               l.pragma |= Nointerface
                        }
                case "go:noescape":
-                       noescape = true
+                       l.pragma |= Noescape
                case "go:norace":
-                       norace = true
+                       l.pragma |= Norace
                case "go:nosplit":
-                       nosplit = true
+                       l.pragma |= Nosplit
                case "go:noinline":
-                       noinline = true
+                       l.pragma |= Noinline
                case "go:systemstack":
                        if compiling_runtime == 0 {
                                Yyerror("//go:systemstack only allowed in runtime")
                        }
-                       systemstack = true
+                       l.pragma |= Systemstack
                case "go:nowritebarrier":
                        if compiling_runtime == 0 {
                                Yyerror("//go:nowritebarrier only allowed in runtime")
                        }
-                       nowritebarrier = true
+                       l.pragma |= Nowritebarrier
                case "go:nowritebarrierrec":
                        if compiling_runtime == 0 {
                                Yyerror("//go:nowritebarrierrec only allowed in runtime")
                        }
-                       nowritebarrierrec = true
-                       nowritebarrier = true // Implies nowritebarrier
+                       l.pragma |= Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
                }
                return c
        }
index 5a67a3fa3a3c8ba65bb1f83ce7985bac692bb062..d42572391d55aba8e329d8834e28f7734012d5fc 100644 (file)
@@ -1893,25 +1893,21 @@ func (p *parser) xfndcl() *Node {
        }
 
        p.want(LFUNC)
-       f := p.fndcl()
+       f := p.fndcl(p.pragma&Nointerface != 0)
        body := p.fnbody()
 
        if f == nil {
                return nil
        }
-       if noescape && body != nil {
-               Yyerror("can only use //go:noescape with external func implementations")
-       }
 
        f.Nbody = body
+       f.Noescape = p.pragma&Noescape != 0
+       if f.Noescape && body != nil {
+               Yyerror("can only use //go:noescape with external func implementations")
+       }
+       f.Func.Pragma = p.pragma
        f.Func.Endlineno = lineno
-       f.Noescape = noescape
-       f.Func.Norace = norace
-       f.Func.Nosplit = nosplit
-       f.Func.Noinline = noinline
-       f.Func.Nowritebarrier = nowritebarrier
-       f.Func.Nowritebarrierrec = nowritebarrierrec
-       f.Func.Systemstack = systemstack
+
        funcbody(f)
 
        return f
@@ -1922,7 +1918,7 @@ func (p *parser) xfndcl() *Node {
 // Function     = Signature FunctionBody .
 // MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
 // Receiver     = Parameters .
-func (p *parser) fndcl() *Node {
+func (p *parser) fndcl(nointerface bool) *Node {
        if trace && Debug['x'] != 0 {
                defer p.trace("fndcl")()
        }
@@ -2058,8 +2054,7 @@ func (p *parser) hidden_fndcl() *Node {
                ss.Type = functype(s2.N, s6, s8)
 
                checkwidth(ss.Type)
-               addmethod(s4, ss.Type, false, nointerface)
-               nointerface = false
+               addmethod(s4, ss.Type, false, false)
                funchdr(ss)
 
                // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
@@ -2140,18 +2135,10 @@ loop:
                        testdclstack()
                }
 
-               noescape = false
-               noinline = false
-               nointerface = false
-               norace = false
-               nosplit = false
-               nowritebarrier = false
-               nowritebarrierrec = false
-               systemstack = false
+               // Reset p.pragma BEFORE advancing to the next token (consuming ';')
+               // since comments before may set pragmas for the next function decl.
+               p.pragma = 0
 
-               // Consume ';' AFTER resetting the above flags since
-               // it may read the subsequent comment line which may
-               // set the flags for the next function declaration.
                if p.tok != EOF && !p.got(';') {
                        p.syntax_error("after top level declaration")
                        p.advance(LVAR, LCONST, LTYPE, LFUNC)
index a44cc734f658bc965188d744764a3b0eaa70a476..475d8e7b83c883c3a5f2dc2c024054016b9dca76 100644 (file)
@@ -434,10 +434,10 @@ func compile(fn *Node) {
        if fn.Func.Needctxt {
                ptxt.From3.Offset |= obj.NEEDCTXT
        }
-       if fn.Func.Nosplit {
+       if fn.Func.Pragma&Nosplit != 0 {
                ptxt.From3.Offset |= obj.NOSPLIT
        }
-       if fn.Func.Systemstack {
+       if fn.Func.Pragma&Systemstack != 0 {
                ptxt.From.Sym.Cfunc = 1
        }
 
index 8a6eba3964752c75d0a5e0c47458c7beffaf6060..d1ae6be0ad058c7e2bc11fb37e340ccc68d586d7 100644 (file)
@@ -50,7 +50,7 @@ func ispkgin(pkgs []string) bool {
 }
 
 func instrument(fn *Node) {
-       if ispkgin(omit_pkgs) || fn.Func.Norace {
+       if ispkgin(omit_pkgs) || fn.Func.Pragma&Norace != 0 {
                return
        }
 
index adf447de01cd351fbe64b07ed75050355091e342..83ee4aedebc2df75b8368f2a83d4796e8d00c1a0 100644 (file)
@@ -169,18 +169,12 @@ type Func struct {
        Depth   int32
 
        Endlineno int32
+       WBLineno  int32 // line number of first write barrier
 
-       Norace            bool // func must not have race detector annotations
-       Nosplit           bool // func should not execute on separate stack
-       Noinline          bool // func should not be inlined
-       Nowritebarrier    bool // emit compiler error instead of write barrier
-       Nowritebarrierrec bool // error on write barrier in this or recursive callees
-       Dupok             bool // duplicate definitions ok
-       Wrapper           bool // is method wrapper
-       Needctxt          bool // function uses context register (has closure variables)
-       Systemstack       bool // must run on system stack
-
-       WBLineno int32 // line number of first write barrier
+       Pragma   Pragma // go:xxx function annotations
+       Dupok    bool   // duplicate definitions ok
+       Wrapper  bool   // is method wrapper
+       Needctxt bool   // function uses context register (has closure variables)
 }
 
 type Op uint8