Skip to content

Commit

Permalink
internal/runtime: check abi.TFlagRegularMemory
Browse files Browse the repository at this point in the history
  • Loading branch information
visualfc committed Jul 4, 2024
1 parent bcb217c commit be32f40
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 19 deletions.
21 changes: 4 additions & 17 deletions internal/runtime/alg.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,8 @@ func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
// Note: this function must match the compiler generated
// functions exactly. See issue 37716.
func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
// if t.TFlag&abi.TFlagRegularMemory != 0 {
// // Handle ptr sizes specially, see issue 37086.
// switch t.Size_ {
// case 4:
// return memhash32(p, h)
// case 8:
// return memhash64(p, h)
// default:
// return memhash(p, h, t.Size_)
// }
// }
switch t.Kind() {
case abi.Bool, abi.Int, abi.Int8, abi.Int16, abi.Int32, abi.Int64,
abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64,
abi.Uintptr, abi.UnsafePointer, abi.Pointer:
if t.TFlag&abi.TFlagRegularMemory != 0 {
// Handle ptr sizes specially, see issue 37086.
switch t.Size_ {
case 4:
return memhash32(p, h)
Expand All @@ -157,6 +144,8 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
default:
return memhash(p, h, t.Size_)
}
}
switch t.Kind() {
case abi.Float32:
return f32hash(p, h)
case abi.Float64:
Expand All @@ -179,8 +168,6 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
h = typehash(a.Elem, add(p, i*a.Elem.Size_), h)
}
return h
case abi.Chan:
return typehash(t.Elem(), p, h)
case abi.Struct:
s := (*structtype)(unsafe.Pointer(t))
for _, f := range s.Fields {
Expand Down
71 changes: 69 additions & 2 deletions internal/runtime/z_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ func basicEqual(kind Kind, size uintptr) func(a, b unsafe.Pointer) bool {
panic("unreachable")
}

func basicFlags(kind Kind) abi.TFlag {
switch kind {
case abi.Float32, abi.Float64, abi.Complex64, abi.Complex128, abi.String:
return 0
}
return abi.TFlagRegularMemory
}

func Basic(kind Kind) *Type {
if tyBasic[kind] == nil {
name, size, align := basicTypeInfo(kind)
Expand All @@ -70,6 +78,7 @@ func Basic(kind Kind) *Type {
FieldAlign_: uint8(align),
Kind_: uint8(kind),
Equal: basicEqual(kind, size),
TFlag: basicFlags(kind),
Str_: name,
}
}
Expand Down Expand Up @@ -170,6 +179,9 @@ func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
}
}
}
if isRegularMemory(&ret.Type) {
ret.TFlag = abi.TFlagRegularMemory
}
return &ret.Type
}

Expand All @@ -196,13 +208,14 @@ func newPointer(elem *Type) *Type {
FieldAlign_: pointerAlign,
Kind_: uint8(abi.Pointer),
Equal: memequalptr,
TFlag: abi.TFlagRegularMemory,
},
Elem: elem,
}
if (elem.TFlag & abi.TFlagExtraStar) != 0 {
ptr.Str_ = "**" + elem.Str_
} else {
ptr.TFlag = abi.TFlagExtraStar
ptr.TFlag |= abi.TFlagExtraStar
ptr.Str_ = elem.Str_
}
return &ptr.Type
Expand Down Expand Up @@ -255,6 +268,9 @@ func ArrayOf(length uintptr, elem *Type) *Type {
}
}
}
if ret.Len == 0 || ret.Elem.TFlag&abi.TFlagRegularMemory != 0 {
ret.TFlag = abi.TFlagRegularMemory
}
return &ret.Type
}

Expand All @@ -264,6 +280,7 @@ func ChanOf(dir int, strChan string, elem *Type) *Type {
Size_: 8,
Hash: uint32(abi.Chan),
Align_: pointerAlign,
TFlag: abi.TFlagRegularMemory,
FieldAlign_: pointerAlign,
Kind_: uint8(abi.Chan),
Equal: memequalptr,
Expand All @@ -272,7 +289,6 @@ func ChanOf(dir int, strChan string, elem *Type) *Type {
Elem: elem,
Dir: abi.ChanDir(dir),
}

return &ret.Type
}

Expand Down Expand Up @@ -300,4 +316,55 @@ func MapOf(key, elem *Type, bucket *Type, flags int) *Type {
return &ret.Type
}

func isRegularMemory(t *_type) bool {
switch t.Kind() {
case abi.Func, abi.Map, abi.Slice, abi.String, abi.Interface:
return false
case abi.Float32, abi.Float64, abi.Complex64, abi.Complex128:
return false
case abi.Array:
at := t.ArrayType()
b := isRegularMemory(at.Elem)
if b {
return true
}
if at.Len == 0 {
return true
}
return b
case abi.Struct:
st := t.StructType()
n := len(st.Fields)
switch n {
case 0:
return true
case 1:
f := st.Fields[0]
if f.Name_ == "_" {
return false
}
return isRegularMemory(f.Typ)
default:
for i := 0; i < n; i++ {
f := st.Fields[i]
if f.Name_ == "_" || !isRegularMemory(f.Typ) || ispaddedfield(st, i) {
return false
}
}
}
}
return true
}

// ispaddedfield reports whether the i'th field of struct type t is followed
// by padding.
func ispaddedfield(st *structtype, i int) bool {
end := st.Size()
if i+1 < len(st.Fields) {
end = st.Fields[i+1].Offset
}
fd := st.Fields[i]
return fd.Offset+fd.Typ.Size_ != end
}

// -----------------------------------------------------------------------------

0 comments on commit be32f40

Please sign in to comment.