reflect.go (go1.19.src) | : | reflect.go (go1.19.1.src) | ||
---|---|---|---|---|
skipping to change at line 1893 | skipping to change at line 1893 | |||
} | } | |||
dot := typecheck.AddImplicitDots(ir.NewSelectorExpr(base.Pos, ir.OXDOT, n this, method.Sym)) | dot := typecheck.AddImplicitDots(ir.NewSelectorExpr(base.Pos, ir.OXDOT, n this, method.Sym)) | |||
// generate call | // generate call | |||
// It's not possible to use a tail call when dynamic linking on ppc64le. The | // It's not possible to use a tail call when dynamic linking on ppc64le. The | |||
// bad scenario is when a local call is made to the wrapper: the wrapper will | // bad scenario is when a local call is made to the wrapper: the wrapper will | |||
// call the implementation, which might be in a different module and so s et | // call the implementation, which might be in a different module and so s et | |||
// the TOC to the appropriate value for that module. But if it returns | // the TOC to the appropriate value for that module. But if it returns | |||
// directly to the wrapper's caller, nothing will reset it to the correct | // directly to the wrapper's caller, nothing will reset it to the correct | |||
// value for that function. | // value for that function. | |||
var call *ir.CallExpr | ||||
if !base.Flag.Cfg.Instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !types.IsInterfaceMethod(method.Type) && !(base.Ctxt.Arc h.Name == "ppc64le" && base.Ctxt.Flag_dynlink) && !generic { | if !base.Flag.Cfg.Instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !types.IsInterfaceMethod(method.Type) && !(base.Ctxt.Arc h.Name == "ppc64le" && base.Ctxt.Flag_dynlink) && !generic { | |||
call := ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil) | call = ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil) | |||
call.Args = ir.ParamNames(fn.Type()) | call.Args = ir.ParamNames(fn.Type()) | |||
call.IsDDD = fn.Type().IsVariadic() | call.IsDDD = fn.Type().IsVariadic() | |||
fn.Body.Append(ir.NewTailCallStmt(base.Pos, call)) | fn.Body.Append(ir.NewTailCallStmt(base.Pos, call)) | |||
} else { | } else { | |||
fn.SetWrapper(true) // ignore frame for panic+recover matching | fn.SetWrapper(true) // ignore frame for panic+recover matching | |||
var call *ir.CallExpr | ||||
if generic && dot.X != nthis { | if generic && dot.X != nthis { | |||
// If there is embedding involved, then we should do the | // If there is embedding involved, then we should do the | |||
// normal non-generic embedding wrapper below, which call s | // normal non-generic embedding wrapper below, which call s | |||
// the wrapper for the real receiver type using dot as an | // the wrapper for the real receiver type using dot as an | |||
// argument. There is no need for generic processing (add ing | // argument. There is no need for generic processing (add ing | |||
// a dictionary) for this wrapper. | // a dictionary) for this wrapper. | |||
generic = false | generic = false | |||
} | } | |||
skipping to change at line 1985 | skipping to change at line 1985 | |||
typecheck.FinishFuncBody() | typecheck.FinishFuncBody() | |||
if base.Debug.DclStack != 0 { | if base.Debug.DclStack != 0 { | |||
types.CheckDclstack() | types.CheckDclstack() | |||
} | } | |||
typecheck.Func(fn) | typecheck.Func(fn) | |||
ir.CurFunc = fn | ir.CurFunc = fn | |||
typecheck.Stmts(fn.Body) | typecheck.Stmts(fn.Body) | |||
if AfterGlobalEscapeAnalysis { | if AfterGlobalEscapeAnalysis { | |||
inline.InlineCalls(fn) | // Inlining the method may reveal closures, which require walking | |||
all function bodies | ||||
// to decide whether to capture free variables by value or by ref | ||||
. So we only do inline | ||||
// if the method do not contain any closures, otherwise, the esca | ||||
pe analysis may make | ||||
// dead variables resurrected, and causing liveness analysis conf | ||||
used, see issue #53702. | ||||
var canInline bool | ||||
switch x := call.X.(type) { | ||||
case *ir.Name: | ||||
canInline = len(x.Func.Closures) == 0 | ||||
case *ir.SelectorExpr: | ||||
if x.Op() == ir.OMETHEXPR { | ||||
canInline = x.FuncName().Func != nil && len(x.Fun | ||||
cName().Func.Closures) == 0 | ||||
} | ||||
} | ||||
if canInline { | ||||
inline.InlineCalls(fn) | ||||
} | ||||
escape.Batch([]*ir.Func{fn}, false) | escape.Batch([]*ir.Func{fn}, false) | |||
} | } | |||
ir.CurFunc = nil | ir.CurFunc = nil | |||
typecheck.Target.Decls = append(typecheck.Target.Decls, fn) | typecheck.Target.Decls = append(typecheck.Target.Decls, fn) | |||
return lsym | return lsym | |||
} | } | |||
// AfterGlobalEscapeAnalysis tracks whether package gc has already | // AfterGlobalEscapeAnalysis tracks whether package gc has already | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 23 lines changed or added |