internal/runtime: cache rtypeList
This commit is contained in:
@@ -130,11 +130,11 @@ func makeMethodValue(op string, v Value) Value {
|
|||||||
// v.Type returns the actual type of the method value.
|
// v.Type returns the actual type of the method value.
|
||||||
ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
|
ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
|
||||||
ptyp := rtypeOf(unsafe.Pointer(uintptr(0)))
|
ptyp := rtypeOf(unsafe.Pointer(uintptr(0)))
|
||||||
typ := runtime.Struct("", 2*unsafe.Sizeof(0), abi.StructField{
|
typ := runtime.Struct(v.typ().Uncommon().PkgPath_, 2*unsafe.Sizeof(0), abi.StructField{
|
||||||
Name_: "llgo_ctx",
|
Name_: "f",
|
||||||
Typ: &ftyp.Type,
|
Typ: &ftyp.Type,
|
||||||
}, abi.StructField{
|
}, abi.StructField{
|
||||||
Name_: "f",
|
Name_: "data",
|
||||||
Typ: ptyp,
|
Typ: ptyp,
|
||||||
Offset: unsafe.Sizeof(0),
|
Offset: unsafe.Sizeof(0),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -203,6 +203,9 @@ func setUncommon(ret *Type, methods []Method) {
|
|||||||
|
|
||||||
// Func returns a function type.
|
// Func returns a function type.
|
||||||
func Func(in, out []*Type, variadic bool) *FuncType {
|
func Func(in, out []*Type, variadic bool) *FuncType {
|
||||||
|
if t := rtypeList.findFunc(in, out, variadic); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &FuncType{
|
ret := &FuncType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: 2 * unsafe.Sizeof(uintptr(0)),
|
Size_: 2 * unsafe.Sizeof(uintptr(0)),
|
||||||
@@ -219,6 +222,7 @@ func Func(in, out []*Type, variadic bool) *FuncType {
|
|||||||
ret.TFlag |= abi.TFlagVariadic
|
ret.TFlag |= abi.TFlagVariadic
|
||||||
}
|
}
|
||||||
ret.Str_ = funcStr(ret)
|
ret.Str_ = funcStr(ret)
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +270,9 @@ func InitNamedInterface(ret *InterfaceType, methods []Imethod) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Interface(pkgPath string, methods []Imethod) *InterfaceType {
|
func Interface(pkgPath string, methods []Imethod) *InterfaceType {
|
||||||
|
if t := rtypeList.findInterface(pkgPath, methods); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &abi.InterfaceType{
|
ret := &abi.InterfaceType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: unsafe.Sizeof(eface{}),
|
Size_: unsafe.Sizeof(eface{}),
|
||||||
@@ -284,6 +291,7 @@ func Interface(pkgPath string, methods []Imethod) *InterfaceType {
|
|||||||
ret.Equal = interequal
|
ret.Equal = interequal
|
||||||
}
|
}
|
||||||
ret.Str_ = interfaceStr(ret)
|
ret.Str_ = interfaceStr(ret)
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,9 @@ func StructField(name string, typ *Type, off uintptr, tag string, embedded bool)
|
|||||||
|
|
||||||
// Struct returns a struct type.
|
// Struct returns a struct type.
|
||||||
func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
|
func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
|
||||||
|
if t := rtypeList.findStruct(pkgPath, size, fields); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &abi.StructType{
|
ret := &abi.StructType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: size,
|
Size_: size,
|
||||||
@@ -194,6 +197,7 @@ func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
|
|||||||
if len(fields) == 1 && isDirectIface(fields[0].Typ) {
|
if len(fields) == 1 && isDirectIface(fields[0].Typ) {
|
||||||
ret.Kind_ |= abi.KindDirectIface
|
ret.Kind_ |= abi.KindDirectIface
|
||||||
}
|
}
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return &ret.Type
|
return &ret.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +252,9 @@ func setPointer(ptr *abi.PtrType, elem *Type) {
|
|||||||
|
|
||||||
// SliceOf returns the slice type with element elem.
|
// SliceOf returns the slice type with element elem.
|
||||||
func SliceOf(elem *Type) *Type {
|
func SliceOf(elem *Type) *Type {
|
||||||
|
if t := rtypeList.findElem(abi.Slice, elem, 0); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &abi.SliceType{
|
ret := &abi.SliceType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: unsafe.Sizeof([]int{}),
|
Size_: unsafe.Sizeof([]int{}),
|
||||||
@@ -260,11 +267,15 @@ func SliceOf(elem *Type) *Type {
|
|||||||
},
|
},
|
||||||
Elem: elem,
|
Elem: elem,
|
||||||
}
|
}
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return &ret.Type
|
return &ret.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayOf returns the array type with element elem and length.
|
// ArrayOf returns the array type with element elem and length.
|
||||||
func ArrayOf(length uintptr, elem *Type) *Type {
|
func ArrayOf(length uintptr, elem *Type) *Type {
|
||||||
|
if t := rtypeList.findElem(abi.Array, elem, length); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &abi.ArrayType{
|
ret := &abi.ArrayType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: length * elem.Size_,
|
Size_: length * elem.Size_,
|
||||||
@@ -303,10 +314,14 @@ func ArrayOf(length uintptr, elem *Type) *Type {
|
|||||||
if ret.Len == 1 && isDirectIface(ret.Elem) {
|
if ret.Len == 1 && isDirectIface(ret.Elem) {
|
||||||
ret.Kind_ |= abi.KindDirectIface
|
ret.Kind_ |= abi.KindDirectIface
|
||||||
}
|
}
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return &ret.Type
|
return &ret.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChanOf(dir int, strChan string, elem *Type) *Type {
|
func ChanOf(dir int, strChan string, elem *Type) *Type {
|
||||||
|
if t := rtypeList.findElem(abi.Chan, elem, uintptr(dir)); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &abi.ChanType{
|
ret := &abi.ChanType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: pointerSize,
|
Size_: pointerSize,
|
||||||
@@ -322,10 +337,14 @@ func ChanOf(dir int, strChan string, elem *Type) *Type {
|
|||||||
Elem: elem,
|
Elem: elem,
|
||||||
Dir: abi.ChanDir(dir),
|
Dir: abi.ChanDir(dir),
|
||||||
}
|
}
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return &ret.Type
|
return &ret.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func MapOf(key, elem *Type, bucket *Type, flags int) *Type {
|
func MapOf(key, elem *Type, bucket *Type, flags int) *Type {
|
||||||
|
if t := rtypeList.findMap(key, elem); t != nil {
|
||||||
|
return t
|
||||||
|
}
|
||||||
ret := &abi.MapType{
|
ret := &abi.MapType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: unsafe.Sizeof(uintptr(0)),
|
Size_: unsafe.Sizeof(uintptr(0)),
|
||||||
@@ -347,6 +366,7 @@ func MapOf(key, elem *Type, bucket *Type, flags int) *Type {
|
|||||||
ret.Hasher = func(p unsafe.Pointer, seed uintptr) uintptr {
|
ret.Hasher = func(p unsafe.Pointer, seed uintptr) uintptr {
|
||||||
return typehash(key, p, seed)
|
return typehash(key, p, seed)
|
||||||
}
|
}
|
||||||
|
rtypeList.addType(&ret.Type)
|
||||||
return &ret.Type
|
return &ret.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,6 +456,111 @@ func (r *rtypes) findNamed(pkgPath string, name string) *Type {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *rtypes) findElem(kind abi.Kind, elem *Type, extra uintptr) *Type {
|
||||||
|
for _, typ := range r.types {
|
||||||
|
if typ.Kind() == kind && typ.Elem() == elem {
|
||||||
|
switch kind {
|
||||||
|
case abi.Chan:
|
||||||
|
if uintptr(typ.ChanDir()) == extra {
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
case abi.Array:
|
||||||
|
if uintptr(typ.Len()) == extra {
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rtypes) findMap(key, elem *Type) *Type {
|
||||||
|
for _, typ := range r.types {
|
||||||
|
if typ.Kind() == abi.Map {
|
||||||
|
if mt := typ.MapType(); mt.Key == key && mt.Elem == elem {
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func eqFields(s1, s2 []abi.StructField) bool {
|
||||||
|
n := len(s1)
|
||||||
|
if n != len(s2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
f1, f2 := s1[i], s2[i]
|
||||||
|
if f1.Name_ != f2.Name_ || f1.Embedded_ != f2.Embedded_ || f1.Typ != f2.Typ {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rtypes) findStruct(pkgPath string, size uintptr, fields []abi.StructField) *Type {
|
||||||
|
for _, typ := range r.types {
|
||||||
|
if typ.Kind() == abi.Struct && typ.Size() == size {
|
||||||
|
if st := typ.StructType(); st.PkgPath_ == pkgPath && eqFields(st.Fields, fields) {
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func eqImethods(s1, s2 []Imethod) bool {
|
||||||
|
n := len(s1)
|
||||||
|
if n != len(s2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
f1, f2 := s1[i], s2[i]
|
||||||
|
if f1.Name_ != f2.Name_ || f1.Typ_ != f2.Typ_ {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rtypes) findInterface(pkgPath string, methods []Imethod) *abi.InterfaceType {
|
||||||
|
for _, typ := range r.types {
|
||||||
|
if typ.Kind() == abi.Interface {
|
||||||
|
if it := typ.InterfaceType(); it.PkgPath_ == pkgPath && eqImethods(it.Methods, methods) {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func eqTypes(s1, s2 []*Type) bool {
|
||||||
|
n := len(s1)
|
||||||
|
if n != len(s2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if s1[i] != s2[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rtypes) findFunc(in, out []*Type, variadic bool) *abi.FuncType {
|
||||||
|
for _, typ := range r.types {
|
||||||
|
if typ.Kind() == abi.Func {
|
||||||
|
if ft := typ.FuncType(); ft.Variadic() == variadic && eqTypes(ft.In, in) && eqTypes(ft.Out, out) {
|
||||||
|
return ft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *rtypes) addType(typ *Type) {
|
func (r *rtypes) addType(typ *Type) {
|
||||||
r.types = append(r.types, typ)
|
r.types = append(r.types, typ)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user