mirror of
https://github.com/golang/go
synced 2024-11-23 23:40:13 -07:00
cmd/compile: add Func.SetNilCheckDisabled
Generated hash and eq routines don't need nil checks. Prior to this CL, this was accomplished by temporarily incrementing the global variable disable_checknil. However, that increment lasted only the lifetime of the call to funccompile. After CL 41503, funccompile may do nothing but enqueue the function for compilation, resulting in nil checks being generated. Fix this by adding an explicit flag to a function indicating whether nil checks should be disabled for that function. While we're here, allow concurrent compilation with the -w and -W flags, since that was needed to investigate this issue. Fixes #20242 Change-Id: Ib9140c22c49e9a09e62fa3cf350f5d3eff18e2bd Reviewed-on: https://go-review.googlesource.com/42591 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
09b71d563a
commit
53e62aba2f
@ -311,9 +311,8 @@ func genhash(sym *types.Sym, t *types.Type) {
|
|||||||
old_safemode := safemode
|
old_safemode := safemode
|
||||||
safemode = false
|
safemode = false
|
||||||
|
|
||||||
disable_checknil++
|
fn.Func.SetNilCheckDisabled(true)
|
||||||
funccompile(fn)
|
funccompile(fn)
|
||||||
disable_checknil--
|
|
||||||
|
|
||||||
safemode = old_safemode
|
safemode = old_safemode
|
||||||
}
|
}
|
||||||
@ -500,12 +499,10 @@ func geneq(sym *types.Sym, t *types.Type) {
|
|||||||
// We are comparing a struct or an array,
|
// We are comparing a struct or an array,
|
||||||
// neither of which can be nil, and our comparisons
|
// neither of which can be nil, and our comparisons
|
||||||
// are shallow.
|
// are shallow.
|
||||||
disable_checknil++
|
fn.Func.SetNilCheckDisabled(true)
|
||||||
|
|
||||||
funccompile(fn)
|
funccompile(fn)
|
||||||
|
|
||||||
safemode = old_safemode
|
safemode = old_safemode
|
||||||
disable_checknil--
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eqfield returns the node
|
// eqfield returns the node
|
||||||
|
@ -1087,6 +1087,8 @@ var concurrentFlagOK = [256]bool{
|
|||||||
'I': true, // add `directory` to import search path
|
'I': true, // add `directory` to import search path
|
||||||
'N': true, // disable optimizations
|
'N': true, // disable optimizations
|
||||||
'l': true, // disable inlining
|
'l': true, // disable inlining
|
||||||
|
'w': true, // all printing happens before compilation
|
||||||
|
'W': true, // all printing happens before compilation
|
||||||
}
|
}
|
||||||
|
|
||||||
func concurrentBackendAllowed() bool {
|
func concurrentBackendAllowed() bool {
|
||||||
|
@ -3399,7 +3399,7 @@ func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value {
|
|||||||
// Used only for automatically inserted nil checks,
|
// Used only for automatically inserted nil checks,
|
||||||
// not for user code like 'x != nil'.
|
// not for user code like 'x != nil'.
|
||||||
func (s *state) nilCheck(ptr *ssa.Value) {
|
func (s *state) nilCheck(ptr *ssa.Value) {
|
||||||
if disable_checknil != 0 {
|
if disable_checknil != 0 || s.curfn.Func.NilCheckDisabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.newValue2(ssa.OpNilCheck, ssa.TypeVoid, ptr, s.mem())
|
s.newValue2(ssa.OpNilCheck, ssa.TypeVoid, ptr, s.mem())
|
||||||
|
@ -386,25 +386,28 @@ const (
|
|||||||
funcNeedctxt // function uses context register (has closure variables)
|
funcNeedctxt // function uses context register (has closure variables)
|
||||||
funcReflectMethod // function calls reflect.Type.Method or MethodByName
|
funcReflectMethod // function calls reflect.Type.Method or MethodByName
|
||||||
funcIsHiddenClosure
|
funcIsHiddenClosure
|
||||||
funcNoFramePointer // Must not use a frame pointer for this function
|
funcNoFramePointer // Must not use a frame pointer for this function
|
||||||
funcHasDefer // contains a defer statement
|
funcHasDefer // contains a defer statement
|
||||||
|
funcNilCheckDisabled // disable nil checks when compiling this function
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *Func) Dupok() bool { return f.flags&funcDupok != 0 }
|
func (f *Func) Dupok() bool { return f.flags&funcDupok != 0 }
|
||||||
func (f *Func) Wrapper() bool { return f.flags&funcWrapper != 0 }
|
func (f *Func) Wrapper() bool { return f.flags&funcWrapper != 0 }
|
||||||
func (f *Func) Needctxt() bool { return f.flags&funcNeedctxt != 0 }
|
func (f *Func) Needctxt() bool { return f.flags&funcNeedctxt != 0 }
|
||||||
func (f *Func) ReflectMethod() bool { return f.flags&funcReflectMethod != 0 }
|
func (f *Func) ReflectMethod() bool { return f.flags&funcReflectMethod != 0 }
|
||||||
func (f *Func) IsHiddenClosure() bool { return f.flags&funcIsHiddenClosure != 0 }
|
func (f *Func) IsHiddenClosure() bool { return f.flags&funcIsHiddenClosure != 0 }
|
||||||
func (f *Func) NoFramePointer() bool { return f.flags&funcNoFramePointer != 0 }
|
func (f *Func) NoFramePointer() bool { return f.flags&funcNoFramePointer != 0 }
|
||||||
func (f *Func) HasDefer() bool { return f.flags&funcHasDefer != 0 }
|
func (f *Func) HasDefer() bool { return f.flags&funcHasDefer != 0 }
|
||||||
|
func (f *Func) NilCheckDisabled() bool { return f.flags&funcNilCheckDisabled != 0 }
|
||||||
|
|
||||||
func (f *Func) SetDupok(b bool) { f.flags.set(funcDupok, b) }
|
func (f *Func) SetDupok(b bool) { f.flags.set(funcDupok, b) }
|
||||||
func (f *Func) SetWrapper(b bool) { f.flags.set(funcWrapper, b) }
|
func (f *Func) SetWrapper(b bool) { f.flags.set(funcWrapper, b) }
|
||||||
func (f *Func) SetNeedctxt(b bool) { f.flags.set(funcNeedctxt, b) }
|
func (f *Func) SetNeedctxt(b bool) { f.flags.set(funcNeedctxt, b) }
|
||||||
func (f *Func) SetReflectMethod(b bool) { f.flags.set(funcReflectMethod, b) }
|
func (f *Func) SetReflectMethod(b bool) { f.flags.set(funcReflectMethod, b) }
|
||||||
func (f *Func) SetIsHiddenClosure(b bool) { f.flags.set(funcIsHiddenClosure, b) }
|
func (f *Func) SetIsHiddenClosure(b bool) { f.flags.set(funcIsHiddenClosure, b) }
|
||||||
func (f *Func) SetNoFramePointer(b bool) { f.flags.set(funcNoFramePointer, b) }
|
func (f *Func) SetNoFramePointer(b bool) { f.flags.set(funcNoFramePointer, b) }
|
||||||
func (f *Func) SetHasDefer(b bool) { f.flags.set(funcHasDefer, b) }
|
func (f *Func) SetHasDefer(b bool) { f.flags.set(funcHasDefer, b) }
|
||||||
|
func (f *Func) SetNilCheckDisabled(b bool) { f.flags.set(funcNilCheckDisabled, b) }
|
||||||
|
|
||||||
type Op uint8
|
type Op uint8
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user