]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] all: merge master (912f075) into dev.typeparams
authorMatthew Dempsky <mdempsky@google.com>
Fri, 2 Jul 2021 22:46:51 +0000 (15:46 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 2 Jul 2021 23:03:51 +0000 (16:03 -0700)
Conflicts:

- src/cmd/compile/internal/escape/escape.go

  On master, CL 332230 changed the ">=" in HeapAllocReason to ">"; but
  on dev.typeparams, CL 329989 moved HeapAllocReason into utils.go.

Merge List:

+ 2021-07-02 912f075047 net/http: mention socks5 support in proxy
+ 2021-07-02 287c5e8066 cmd/compile: fix stack growing algorithm
+ 2021-07-02 743f03eeb0 spec, unsafe: clarify unsafe.Slice docs
+ 2021-07-02 6125d0c426 cmd/dist: correct comment: SysProcAttri -> SysProcAttr
+ 2021-07-01 03761ede02 net: don't reject null mx records
+ 2021-07-01 877688c838 testing: add TB.Setenv
+ 2021-07-01 ef8ae82b37 cmd/compile: fix bug in dwarf-gen var location generation
+ 2021-07-01 770899f7e1 cmd/go: add a regression test for 'go mod vendor' path traversal
+ 2021-07-01 835d86a17e cmd/go: use path.Dir instead of filepath.Dir for package paths in 'go mod vendor'
+ 2021-07-01 eb437ba92c cmd/compile: make stack value size threshold comparisons consistent
+ 2021-07-01 9d65578b83 cmd/compile: fix typos in document

Change-Id: I08aa852441af0f070aa32dd2f99b6fa4e9d79cfa

1  2 
src/cmd/compile/abi-internal.md
src/cmd/compile/internal/escape/utils.go
src/cmd/compile/internal/walk/builtin.go
src/runtime/stack.go

Simple merge
index 1ac4cc602905c98e2875a02f37c856f0632e77f5,0000000000000000000000000000000000000000..6e2f9c424a8cf70cc4f9700ed54edd72eef9ad54
mode 100644,000000..100644
--- /dev/null
@@@ -1,215 -1,0 +1,215 @@@
-       if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width >= ir.MaxImplicitStackVarSize {
 +// Copyright 2018 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
 +
 +package escape
 +
 +import (
 +      "cmd/compile/internal/ir"
 +      "cmd/compile/internal/typecheck"
 +)
 +
 +func isSliceSelfAssign(dst, src ir.Node) bool {
 +      // Detect the following special case.
 +      //
 +      //      func (b *Buffer) Foo() {
 +      //              n, m := ...
 +      //              b.buf = b.buf[n:m]
 +      //      }
 +      //
 +      // This assignment is a no-op for escape analysis,
 +      // it does not store any new pointers into b that were not already there.
 +      // However, without this special case b will escape, because we assign to OIND/ODOTPTR.
 +      // Here we assume that the statement will not contain calls,
 +      // that is, that order will move any calls to init.
 +      // Otherwise base ONAME value could change between the moments
 +      // when we evaluate it for dst and for src.
 +
 +      // dst is ONAME dereference.
 +      var dstX ir.Node
 +      switch dst.Op() {
 +      default:
 +              return false
 +      case ir.ODEREF:
 +              dst := dst.(*ir.StarExpr)
 +              dstX = dst.X
 +      case ir.ODOTPTR:
 +              dst := dst.(*ir.SelectorExpr)
 +              dstX = dst.X
 +      }
 +      if dstX.Op() != ir.ONAME {
 +              return false
 +      }
 +      // src is a slice operation.
 +      switch src.Op() {
 +      case ir.OSLICE, ir.OSLICE3, ir.OSLICESTR:
 +              // OK.
 +      case ir.OSLICEARR, ir.OSLICE3ARR:
 +              // Since arrays are embedded into containing object,
 +              // slice of non-pointer array will introduce a new pointer into b that was not already there
 +              // (pointer to b itself). After such assignment, if b contents escape,
 +              // b escapes as well. If we ignore such OSLICEARR, we will conclude
 +              // that b does not escape when b contents do.
 +              //
 +              // Pointer to an array is OK since it's not stored inside b directly.
 +              // For slicing an array (not pointer to array), there is an implicit OADDR.
 +              // We check that to determine non-pointer array slicing.
 +              src := src.(*ir.SliceExpr)
 +              if src.X.Op() == ir.OADDR {
 +                      return false
 +              }
 +      default:
 +              return false
 +      }
 +      // slice is applied to ONAME dereference.
 +      var baseX ir.Node
 +      switch base := src.(*ir.SliceExpr).X; base.Op() {
 +      default:
 +              return false
 +      case ir.ODEREF:
 +              base := base.(*ir.StarExpr)
 +              baseX = base.X
 +      case ir.ODOTPTR:
 +              base := base.(*ir.SelectorExpr)
 +              baseX = base.X
 +      }
 +      if baseX.Op() != ir.ONAME {
 +              return false
 +      }
 +      // dst and src reference the same base ONAME.
 +      return dstX.(*ir.Name) == baseX.(*ir.Name)
 +}
 +
 +// isSelfAssign reports whether assignment from src to dst can
 +// be ignored by the escape analysis as it's effectively a self-assignment.
 +func isSelfAssign(dst, src ir.Node) bool {
 +      if isSliceSelfAssign(dst, src) {
 +              return true
 +      }
 +
 +      // Detect trivial assignments that assign back to the same object.
 +      //
 +      // It covers these cases:
 +      //      val.x = val.y
 +      //      val.x[i] = val.y[j]
 +      //      val.x1.x2 = val.x1.y2
 +      //      ... etc
 +      //
 +      // These assignments do not change assigned object lifetime.
 +
 +      if dst == nil || src == nil || dst.Op() != src.Op() {
 +              return false
 +      }
 +
 +      // The expression prefix must be both "safe" and identical.
 +      switch dst.Op() {
 +      case ir.ODOT, ir.ODOTPTR:
 +              // Safe trailing accessors that are permitted to differ.
 +              dst := dst.(*ir.SelectorExpr)
 +              src := src.(*ir.SelectorExpr)
 +              return ir.SameSafeExpr(dst.X, src.X)
 +      case ir.OINDEX:
 +              dst := dst.(*ir.IndexExpr)
 +              src := src.(*ir.IndexExpr)
 +              if mayAffectMemory(dst.Index) || mayAffectMemory(src.Index) {
 +                      return false
 +              }
 +              return ir.SameSafeExpr(dst.X, src.X)
 +      default:
 +              return false
 +      }
 +}
 +
 +// mayAffectMemory reports whether evaluation of n may affect the program's
 +// memory state. If the expression can't affect memory state, then it can be
 +// safely ignored by the escape analysis.
 +func mayAffectMemory(n ir.Node) bool {
 +      // We may want to use a list of "memory safe" ops instead of generally
 +      // "side-effect free", which would include all calls and other ops that can
 +      // allocate or change global state. For now, it's safer to start with the latter.
 +      //
 +      // We're ignoring things like division by zero, index out of range,
 +      // and nil pointer dereference here.
 +
 +      // TODO(rsc): It seems like it should be possible to replace this with
 +      // an ir.Any looking for any op that's not the ones in the case statement.
 +      // But that produces changes in the compiled output detected by buildall.
 +      switch n.Op() {
 +      case ir.ONAME, ir.OLITERAL, ir.ONIL:
 +              return false
 +
 +      case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD:
 +              n := n.(*ir.BinaryExpr)
 +              return mayAffectMemory(n.X) || mayAffectMemory(n.Y)
 +
 +      case ir.OINDEX:
 +              n := n.(*ir.IndexExpr)
 +              return mayAffectMemory(n.X) || mayAffectMemory(n.Index)
 +
 +      case ir.OCONVNOP, ir.OCONV:
 +              n := n.(*ir.ConvExpr)
 +              return mayAffectMemory(n.X)
 +
 +      case ir.OLEN, ir.OCAP, ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
 +              n := n.(*ir.UnaryExpr)
 +              return mayAffectMemory(n.X)
 +
 +      case ir.ODOT, ir.ODOTPTR:
 +              n := n.(*ir.SelectorExpr)
 +              return mayAffectMemory(n.X)
 +
 +      case ir.ODEREF:
 +              n := n.(*ir.StarExpr)
 +              return mayAffectMemory(n.X)
 +
 +      default:
 +              return true
 +      }
 +}
 +
 +// HeapAllocReason returns the reason the given Node must be heap
 +// allocated, or the empty string if it doesn't.
 +func HeapAllocReason(n ir.Node) string {
 +      if n == nil || n.Type() == nil {
 +              return ""
 +      }
 +
 +      // Parameters are always passed via the stack.
 +      if n.Op() == ir.ONAME {
 +              n := n.(*ir.Name)
 +              if n.Class == ir.PPARAM || n.Class == ir.PPARAMOUT {
 +                      return ""
 +              }
 +      }
 +
 +      if n.Type().Width > ir.MaxStackVarSize {
 +              return "too large for stack"
 +      }
 +
-       if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() >= ir.MaxImplicitStackVarSize {
++      if (n.Op() == ir.ONEW || n.Op() == ir.OPTRLIT) && n.Type().Elem().Width > ir.MaxImplicitStackVarSize {
 +              return "too large for stack"
 +      }
 +
-       if n.Op() == ir.OMETHVALUE && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() >= ir.MaxImplicitStackVarSize {
++      if n.Op() == ir.OCLOSURE && typecheck.ClosureType(n.(*ir.ClosureExpr)).Size() > ir.MaxImplicitStackVarSize {
 +              return "too large for stack"
 +      }
-               if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) >= ir.MaxImplicitStackVarSize/t.Elem().Width {
++      if n.Op() == ir.OMETHVALUE && typecheck.PartialCallType(n.(*ir.SelectorExpr)).Size() > ir.MaxImplicitStackVarSize {
 +              return "too large for stack"
 +      }
 +
 +      if n.Op() == ir.OMAKESLICE {
 +              n := n.(*ir.MakeExpr)
 +              r := n.Cap
 +              if r == nil {
 +                      r = n.Len
 +              }
 +              if !ir.IsSmallIntConst(r) {
 +                      return "non-constant size"
 +              }
++              if t := n.Type(); t.Elem().Width != 0 && ir.Int64Val(r) > ir.MaxImplicitStackVarSize/t.Elem().Width {
 +                      return "too large for stack"
 +              }
 +      }
 +
 +      return ""
 +}
Simple merge