Skip to content

Commit 91ed132

Browse files
authored
Merge pull request #21 from golang/master
[pull] master from golang:master
2 parents 9c347fc + 834214f commit 91ed132

57 files changed

Lines changed: 975 additions & 281 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/next/77363.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pkg crypto/tls, type QUICConfig struct, ClientHelloInfoConn net.Conn #77363
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The new [QUICConfig.ClientHelloInfoConn] field specifies the [net.Conn] to use
2+
for the [ClientHelloInfo.Conn] field during QUIC server handshakes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[Transport] and [Server] support TLS ALPN protocol negotiation on
2+
user-provided [net.Conn] connections which implement a
3+
`ConnectionState() tls.ConnectionState` method.

src/cmd/compile/internal/amd64/ssa.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,33 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
700700
case ssa.OpAMD64SUBQconst, ssa.OpAMD64SUBLconst,
701701
ssa.OpAMD64ANDLconst,
702702
ssa.OpAMD64ORQconst, ssa.OpAMD64ORLconst,
703-
ssa.OpAMD64XORQconst, ssa.OpAMD64XORLconst,
704-
ssa.OpAMD64SHLQconst, ssa.OpAMD64SHLLconst,
703+
ssa.OpAMD64XORQconst, ssa.OpAMD64XORLconst:
704+
p := s.Prog(v.Op.Asm())
705+
p.From.Type = obj.TYPE_CONST
706+
p.From.Offset = v.AuxInt
707+
p.To.Type = obj.TYPE_REG
708+
p.To.Reg = v.Reg()
709+
710+
case ssa.OpAMD64SHLQconst, ssa.OpAMD64SHLLconst,
705711
ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst,
706712
ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst,
707713
ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst:
714+
var maxShift int64
715+
switch v.Op {
716+
case ssa.OpAMD64SHLQconst, ssa.OpAMD64SHRQconst, ssa.OpAMD64SARQconst, ssa.OpAMD64ROLQconst:
717+
maxShift = 63
718+
case ssa.OpAMD64SHLLconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SARLconst, ssa.OpAMD64ROLLconst:
719+
maxShift = 31
720+
case ssa.OpAMD64SHRWconst, ssa.OpAMD64SARWconst, ssa.OpAMD64ROLWconst:
721+
maxShift = 15
722+
case ssa.OpAMD64SHRBconst, ssa.OpAMD64SARBconst, ssa.OpAMD64ROLBconst:
723+
maxShift = 7
724+
default:
725+
panic("unreachable")
726+
}
727+
if v.AuxInt < 0 || v.AuxInt > maxShift {
728+
v.Fatalf("shift amount out of range [0,%d]: %d", maxShift, v.AuxInt)
729+
}
708730
p := s.Prog(v.Op.Asm())
709731
p.From.Type = obj.TYPE_CONST
710732
p.From.Offset = v.AuxInt

src/cmd/compile/internal/inline/inl.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,9 @@ func CanInline(fn *ir.Func, profile *pgoir.Profile) {
324324
// function is inlinable.
325325
func noteInlinableFunc(n *ir.Name, fn *ir.Func, cost int32) {
326326
if base.Flag.LowerM > 1 {
327-
fmt.Printf("%v: can inline %v with cost %d as: %v { %v }\n", ir.Line(fn), n, cost, fn.Type(), fn.Body)
327+
fmt.Printf("%v: can inline %v with cost %d as: %v { %v }\n", ir.Line(fn), n.DiagName(), cost, fn.Type(), fn.Body)
328328
} else if base.Flag.LowerM != 0 {
329-
fmt.Printf("%v: can inline %v\n", ir.Line(fn), n)
329+
fmt.Printf("%v: can inline %v\n", ir.Line(fn), n.DiagName())
330330
}
331331
// JSON optimization log output.
332332
if logopt.Enabled() {
@@ -1252,9 +1252,9 @@ func mkinlcall(callerfn *ir.Func, n *ir.CallExpr, fn *ir.Func, bigCaller, closur
12521252
if base.Flag.LowerM != 0 {
12531253
if buildcfg.Experiment.NewInliner {
12541254
fmt.Printf("%v: inlining call to %v with score %d\n",
1255-
ir.Line(n), fn, score)
1255+
ir.Line(n), fn.Nname.DiagName(), score)
12561256
} else {
1257-
fmt.Printf("%v: inlining call to %v\n", ir.Line(n), fn)
1257+
fmt.Printf("%v: inlining call to %v\n", ir.Line(n), fn.Nname.DiagName())
12581258
}
12591259
}
12601260
if base.Flag.LowerM > 2 {
@@ -1264,7 +1264,7 @@ func mkinlcall(callerfn *ir.Func, n *ir.CallExpr, fn *ir.Func, bigCaller, closur
12641264
res := InlineCall(callerfn, n, fn, inlIndex)
12651265

12661266
if res == nil {
1267-
base.FatalfAt(n.Pos(), "inlining call to %v failed", fn)
1267+
base.FatalfAt(n.Pos(), "inlining call to %v failed", fn.Nname.DiagName())
12681268
}
12691269

12701270
if base.Flag.LowerM > 2 {

src/cmd/compile/internal/ir/func.go

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ package ir
77
import (
88
"cmd/compile/internal/base"
99
"cmd/compile/internal/types"
10+
"cmd/internal/hash"
1011
"cmd/internal/obj"
1112
"cmd/internal/objabi"
1213
"cmd/internal/src"
14+
"encoding/base64"
1315
"fmt"
14-
"strings"
16+
"io"
1517
"unicode/utf8"
1618
)
1719

@@ -430,10 +432,9 @@ func ClosureDebugRuntimeCheck(clo *ClosureExpr) {
430432
var globClosgen int32
431433

432434
// closureName generates a new unique name for a closure within outerfn at pos.
433-
func closureName(outerfn *Func, pos src.XPos, why Op) *types.Sym {
434-
if outerfn.OClosure != nil && outerfn.OClosure.Func.RangeParent != nil {
435-
outerfn = outerfn.OClosure.Func.RangeParent
436-
}
435+
// gen is an optional counter for the closure name. If it is 0, the counter
436+
// will be computed based on outerfn.
437+
func closureName(outerfn *Func, pos src.XPos, why Op, gen int) *types.Sym {
437438
pkg := types.LocalPkg
438439
outer := "glob."
439440
var suffix string = "."
@@ -451,38 +452,64 @@ func closureName(outerfn *Func, pos src.XPos, why Op) *types.Sym {
451452
case ODEFER:
452453
suffix = ".deferwrap"
453454
}
454-
gen := &globClosgen
455455

456456
// There may be multiple functions named "_". In those
457457
// cases, we can't use their individual Closgens as it
458458
// would lead to name clashes.
459459
if !IsBlank(outerfn.Nname) {
460460
pkg = outerfn.Sym().Pkg
461461
outer = FuncName(outerfn)
462-
463-
switch why {
464-
case OCLOSURE:
465-
gen = &outerfn.funcLitGen
466-
case ORANGE:
467-
gen = &outerfn.rangeLitGen
468-
default:
469-
gen = &outerfn.goDeferGen
470-
}
471462
}
472463

473-
// If this closure was created due to inlining, then incorporate any
474-
// inlined functions' names into the closure's linker symbol name
475-
// too (#60324).
464+
// If this closure was created due to inlining, find the original
465+
// outer function's name for the closure (#60324).
466+
var inlHash string
476467
if inlIndex := base.Ctxt.InnermostPos(pos).Base().InliningIndex(); inlIndex >= 0 {
477-
names := []string{outer}
468+
// The compiler doesn't like multiple symbols with the same
469+
// name. We make a unique suffix temporarily for the
470+
// compiler, and strip it during object file writing, so
471+
// it will not be the linker symbol name. For linking,
472+
// we use a content hash to disambiguate instead.
473+
// We choose the suffix as a hash of the inline call stack.
474+
h := hash.New32()
475+
io.WriteString(h, outer)
478476
base.Ctxt.InlTree.AllParents(inlIndex, func(call obj.InlinedCall) {
479-
names = append(names, call.Name)
477+
io.WriteString(h, call.Name+":"+call.Pos.LineNumber()+":"+call.Pos.ColumnNumber())
480478
})
481-
outer = strings.Join(names, ".")
479+
inlHash = base64.StdEncoding.EncodeToString(h.Sum(nil)[:8])
480+
481+
outer = base.Ctxt.InlTree.InlinedFuncName(inlIndex)
482+
if pkgPath := base.Ctxt.InlTree.InlinedFuncPkg(inlIndex); pkgPath != "" {
483+
pkg = types.NewPkg(pkgPath, "")
484+
}
482485
}
483486

484-
*gen++
485-
return pkg.Lookup(fmt.Sprintf("%s%s%d", outer, suffix, *gen))
487+
if gen == 0 {
488+
p := &globClosgen
489+
if !IsBlank(outerfn.Nname) {
490+
switch why {
491+
case OCLOSURE:
492+
p = &outerfn.funcLitGen
493+
case ORANGE:
494+
p = &outerfn.rangeLitGen
495+
default:
496+
p = &outerfn.goDeferGen
497+
}
498+
}
499+
*p++
500+
gen = int(*p)
501+
}
502+
503+
name := fmt.Sprintf("%s%s%d", outer, suffix, gen)
504+
if inlHash != "" {
505+
// Attach the inline hash (see the comment above).
506+
// If it already has a hash, trim it, so we don't include
507+
// two hashes for nested closures. The new hash should be
508+
// enough to disambiguate.
509+
name = obj.TrimInlineHash(name) + "#" + inlHash + "#"
510+
}
511+
512+
return pkg.Lookup(name)
486513
}
487514

488515
// NewClosureFunc creates a new Func to represent a function literal
@@ -500,14 +527,19 @@ func closureName(outerfn *Func, pos src.XPos, why Op) *types.Sym {
500527
// why is the reason we're generating this Func. It can be OCLOSURE
501528
// (for a normal function literal) or OGO or ODEFER (for wrapping a
502529
// call expression that has parameters or results).
503-
func NewClosureFunc(fpos, cpos src.XPos, why Op, typ *types.Type, outerfn *Func, pkg *Package) *Func {
530+
//
531+
// gen is an optional counter for the closure name. If it is 0,
532+
// the counter will be computed based on outerfn.
533+
func NewClosureFunc(fpos, cpos src.XPos, why Op, typ *types.Type, outerfn *Func, pkg *Package, gen int) *Func {
504534
if outerfn == nil {
505535
base.FatalfAt(fpos, "outerfn is nil")
506536
}
507537

508-
fn := NewFunc(fpos, fpos, closureName(outerfn, cpos, why), typ)
538+
fn := NewFunc(fpos, fpos, closureName(outerfn, cpos, why, gen), typ)
509539
fn.SetDupok(outerfn.Dupok()) // if the outer function is dupok, so is the closure
510540

541+
fn.Linksym().Set(obj.AttrContentAddressable, true)
542+
511543
clo := &ClosureExpr{Func: fn}
512544
clo.op = OCLOSURE
513545
clo.pos = cpos

src/cmd/compile/internal/ir/name.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ func (*Name) CanBeNtype() {}
167167
func (*Name) CanBeAnSSASym() {}
168168
func (*Name) CanBeAnSSAAux() {}
169169

170+
// DiagName returns the symbol name for diagnostics.
171+
// XXX should it be part of the formatter?
172+
func (n *Name) DiagName() string { return obj.TrimInlineHash(fmt.Sprint(n.Sym())) }
173+
170174
// Pragma returns the PragmaFlag for p, which must be for an OTYPE.
171175
func (n *Name) Pragma() PragmaFlag { return n.pragma }
172176

src/cmd/compile/internal/noder/reader.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ type reader struct {
100100

101101
dict *readerDict
102102

103+
// funcLitGen is a counter for closure names.
104+
funcLitGen int
105+
// rangeLitGen is a counter for range func closure names.
106+
rangeLitGen int
107+
103108
// TODO(mdempsky): The state below is all specific to reading
104109
// function bodies. It probably makes sense to split it out
105110
// separately so that it doesn't take up space in every reader
@@ -3307,8 +3312,17 @@ func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type, why ir.Op) *i
33073312
curfn = r.curfn
33083313
}
33093314

3315+
var gen int
3316+
if why == ir.ORANGE {
3317+
r.rangeLitGen++
3318+
gen = r.rangeLitGen
3319+
} else {
3320+
r.funcLitGen++
3321+
gen = r.funcLitGen
3322+
}
3323+
33103324
// TODO(mdempsky): Remove hard-coding of typecheck.Target.
3311-
return ir.NewClosureFunc(origPos, r.inlPos(origPos), why, sig, curfn, typecheck.Target)
3325+
return ir.NewClosureFunc(origPos, r.inlPos(origPos), why, sig, curfn, typecheck.Target, gen)
33123326
}
33133327

33143328
func (r *reader) exprList() []ir.Node {

src/cmd/compile/internal/ssa/_gen/AMD64.rules

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,8 @@
912912
(LEA(Q|L)2 [0] {s} (ADD(Q|L) x x) x) && s == nil => (SHL(Q|L)const [2] x)
913913

914914
// (x + x) << 2 -> x << 3 and similar
915-
(SHL(Q|L)const [c] (ADD(Q|L) x x)) => (SHL(Q|L)const [c+1] x)
915+
(SHLQconst [c] (ADDQ x x)) && c < 63 => (SHLQconst [c+1] x)
916+
(SHLLconst [c] (ADDL x x)) && c < 31 => (SHLLconst [c+1] x)
916917

917918
// reverse ordering of compare instruction
918919
(SETL (InvertFlags x)) => (SETG x)

src/cmd/compile/internal/ssa/rewriteAMD64.go

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)