Skip to content

Commit 1df1dc8

Browse files
authored
Improve sizegen to handle more types (#17583)
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
1 parent 43e6089 commit 1df1dc8

File tree

7 files changed

+506
-7
lines changed

7 files changed

+506
-7
lines changed

go/mysql/decimal/cached_size.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/tools/sizegen/sizegen.go

Lines changed: 117 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ func isPod(tt types.Type) bool {
107107
return false
108108
}
109109
return true
110+
case *types.Alias:
111+
return isPod(types.Unalias(tt))
110112
default:
111113
return false
112114
}
@@ -152,8 +154,37 @@ func (sizegen *sizegen) generateType(pkg *types.Package, file *codeFile, named *
152154
sizegen.generateTyp(tt)
153155
}
154156
})
157+
158+
case *types.Slice:
159+
impl, flag := sizegen.sizeImplForSlice(named.Obj(), tt)
160+
file.impls = append(file.impls, codeImpl{
161+
code: impl,
162+
name: named.String(),
163+
flags: flag,
164+
})
165+
case *types.Map:
166+
impl, flag := sizegen.sizeImplForMap(named.Obj(), tt)
167+
file.impls = append(file.impls, codeImpl{
168+
code: impl,
169+
name: named.String(),
170+
flags: flag,
171+
})
172+
case *types.Basic:
173+
impl, flag := sizegen.sizeImplForBasic(named.Obj(), tt)
174+
file.impls = append(file.impls, codeImpl{
175+
code: impl,
176+
name: named.String(),
177+
flags: flag,
178+
})
179+
case *types.Signature:
180+
impl, flag := sizegen.sizeImplForSignature(named.Obj(), tt)
181+
file.impls = append(file.impls, codeImpl{
182+
code: impl,
183+
name: named.String(),
184+
flags: flag,
185+
})
155186
default:
156-
// no-op
187+
panic(fmt.Sprintf("unhandled type: %v (%T)", named, tt))
157188
}
158189
}
159190

@@ -286,6 +317,77 @@ func (sizegen *sizegen) sizeImplForStruct(name *types.TypeName, st *types.Struct
286317
return f, funcFlags
287318
}
288319

320+
func (sizegen *sizegen) sizeImplForSlice(name *types.TypeName, st *types.Slice) (jen.Code, codeFlag) {
321+
var stmt []jen.Code
322+
var funcFlags codeFlag
323+
stmt, funcFlags = sizegen.sizeStmtForArray(stmt, jen.Op("*").Add(jen.Id("cached")), st.Elem())
324+
325+
f := jen.Func()
326+
f.Params(jen.Id("cached").Op("*").Id(name.Name()))
327+
f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64()
328+
f.BlockFunc(func(b *jen.Group) {
329+
b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0)))))
330+
b.Add(jen.Id("size").Op(":=").Lit(int64(0)))
331+
b.Add(jen.If(jen.Id("alloc")).Block(
332+
jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizegen.sizes.Sizeof(st))),
333+
))
334+
for _, s := range stmt {
335+
b.Add(s)
336+
}
337+
b.Add(jen.Return(jen.Id("size")))
338+
})
339+
return f, funcFlags
340+
}
341+
342+
func (sizegen *sizegen) sizeImplForMap(name *types.TypeName, st *types.Map) (jen.Code, codeFlag) {
343+
stmt := sizegen.sizeStmtForMap(jen.Op("*").Add(jen.Id("cached")), st)
344+
345+
f := jen.Func()
346+
f.Params(jen.Id("cached").Op("*").Id(name.Name()))
347+
f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64()
348+
f.BlockFunc(func(b *jen.Group) {
349+
b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0)))))
350+
b.Add(jen.Id("size").Op(":=").Lit(int64(0)))
351+
b.Add(jen.If(jen.Id("alloc")).Block(
352+
jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizegen.sizes.Sizeof(st))),
353+
))
354+
for _, s := range stmt {
355+
b.Add(s)
356+
}
357+
b.Add(jen.Return(jen.Id("size")))
358+
})
359+
return f, 0
360+
}
361+
362+
func (sizegen *sizegen) sizeImplForBasic(name *types.TypeName, st *types.Basic) (jen.Code, codeFlag) {
363+
f := jen.Func()
364+
f.Params(jen.Id("cached").Op("*").Id(name.Name()))
365+
f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64()
366+
f.BlockFunc(func(b *jen.Group) {
367+
b.Add(jen.If(jen.Id("cached").Op("==").Nil()).Block(jen.Return(jen.Lit(int64(0)))))
368+
b.Add(jen.Id("size").Op(":=").Lit(int64(0)))
369+
b.Add(jen.If(jen.Id("alloc")).Block(
370+
jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(st)))),
371+
))
372+
if st.Info()&types.IsString != 0 {
373+
b.Add(jen.Id("size").Op("+=").Do(mallocsize(jen.Int64().Call(jen.Len(jen.Op("*").Add(jen.Id("cached")))))))
374+
}
375+
b.Add(jen.Return(jen.Id("size")))
376+
})
377+
return f, 0
378+
}
379+
380+
func (sizegen *sizegen) sizeImplForSignature(name *types.TypeName, _ *types.Signature) (jen.Code, codeFlag) {
381+
f := jen.Func()
382+
f.Params(jen.Id("cached").Op("*").Id(name.Name()))
383+
f.Id("CachedSize").Params(jen.Id("alloc").Id("bool")).Int64()
384+
f.BlockFunc(func(b *jen.Group) {
385+
// assume that function pointers do not allocate (although they might, if they're closures)
386+
b.Add(jen.Return(jen.Lit(int64(0))))
387+
})
388+
return f, 0
389+
}
390+
289391
func (sizegen *sizegen) sizeStmtForMap(fieldName *jen.Statement, m *types.Map) []jen.Code {
290392
const bucketCnt = 8
291393
const sizeofHmap = int64(6 * 8)
@@ -447,12 +549,21 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty
447549
ts := sizegen.getKnownType(node)
448550
if ts.pod || !ts.local {
449551
if alloc {
450-
if !ts.local {
451-
log.Printf("WARNING: size of external type %s cannot be fully calculated", node)
552+
var stmts []jen.Code
553+
if node.String() == "math/big.Int" {
554+
// This type is not accessible, but with the given
555+
// accessors we can compute a proper size.
556+
stmts = append(stmts, jen.Id("size").
557+
Op("+=").
558+
Do(mallocsize(jen.Int64().Call(jen.Cap(fieldName.Clone().Dot("Bits").Call())).
559+
Op("*").
560+
Lit(4),
561+
)))
562+
} else if !ts.local {
563+
stmts = append(stmts, jen.Commentf("WARNING: size of external type %s cannot be fully calculated", node))
452564
}
453-
return jen.If(fieldName.Clone().Op("!=").Nil()).Block(
454-
jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(node.Underlying())))),
455-
), 0
565+
stmts = append(stmts, jen.Id("size").Op("+=").Do(mallocsize(jen.Lit(sizegen.sizes.Sizeof(node.Underlying())))))
566+
return jen.If(fieldName.Clone().Op("!=").Nil()).Block(stmts...), 0
456567
}
457568
return nil, 0
458569
}
@@ -502,7 +613,6 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty
502613

503614
var defaultGenTypes = []string{
504615
"vitess.io/vitess/go/pools/smartconnpool.Setting",
505-
"vitess.io/vitess/go/vt/schema.DDLStrategySetting",
506616
"vitess.io/vitess/go/vt/vtgate/engine.Plan",
507617
"vitess.io/vitess/go/vt/vttablet/tabletserver.TabletPlan",
508618
"vitess.io/vitess/go/sqltypes.Result",

go/vt/schema/cached_size.go

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

0 commit comments

Comments
 (0)