Skip to content

Commit e8ae251

Browse files
trying json encoding
1 parent e2299db commit e8ae251

File tree

6 files changed

+81
-119
lines changed

6 files changed

+81
-119
lines changed

build/build.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -807,13 +807,12 @@ func NewSession(options *Options) (*Session, error) {
807807
// Disable caching by leaving buildCache set to nil.
808808
if !s.options.NoCache {
809809
s.buildCache = &cache.BuildCache{
810-
GOOS: env.GOOS,
811-
GOARCH: env.GOARCH,
812-
GOROOT: env.GOROOT,
813-
GOPATH: env.GOPATH,
814-
BuildTags: append([]string{}, env.BuildTags...),
815-
TestedPackage: options.TestedPackage,
816-
Version: compiler.Version,
810+
GOOS: env.GOOS,
811+
GOARCH: env.GOARCH,
812+
GOROOT: env.GOROOT,
813+
GOPATH: env.GOPATH,
814+
BuildTags: append([]string{}, env.BuildTags...),
815+
Version: compiler.Version,
817816
}
818817
}
819818

@@ -1224,8 +1223,7 @@ func (s *Session) CompilePackage(srcs *sources.Sources, tContext *types.Context)
12241223
if dc != nil && dc.Changed() {
12251224
s.buildCache.Store(dc, srcs.ImportPath, time.Now())
12261225
}
1227-
// Uncomment to get statics for individual packages cache usage.
1228-
// log.Infof(`DeclCache stats: %s`, dc.String())
1226+
log.Debugf(`DeclCache stats: %s`, dc.String())
12291227
}
12301228

12311229
s.UpToDateArchives[srcs.ImportPath] = archive

build/cache/cache.go

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"compress/gzip"
77
"crypto/sha256"
88
"encoding/gob"
9+
"encoding/json"
910
"fmt"
1011
"go/build"
1112
"io"
@@ -20,9 +21,10 @@ import (
2021
// Cacheable defines methods to serialize and deserialize cachable objects.
2122
// This object should represent a package's build artifact.
2223
//
23-
// The encode and decode functions are typically wrappers around gob.Encoder.Encode
24-
// and gob.Decoder.Decode, but other formats are possible as well, the same way
25-
// as FileSet.Write and FileSet.Read work with any encode/decode functions.
24+
// The encode and decode functions are typically wrappers around gob or json
25+
// Encoder.Encode and Decoder.Decode, but other formats are possible as well,
26+
// the same way as FileSet.Write and FileSet.Read work with any encode/decode
27+
// functions.
2628
type Cacheable interface {
2729
Write(encode func(any) error) error
2830
Read(decode func(any) error) error
@@ -113,31 +115,18 @@ type BuildCache struct {
113115

114116
// Version should be set to compiler.Version
115117
Version string
116-
117-
// TestedPackage is the import path of the package being tested, or
118-
// empty when not building for tests. The package under test is built
119-
// with *_test.go sources included so we should always skip reading
120-
// and writing cache in that case.
121-
TestedPackage string
122118
}
123119

120+
const encoding = `json`
121+
124122
func (bc BuildCache) String() string {
125123
return fmt.Sprintf("%#v", bc)
126124
}
127125

128-
func (bc *BuildCache) isTestPackage(importPath string) bool {
129-
return bc != nil && len(importPath) > 0 &&
130-
(importPath == bc.TestedPackage || importPath == bc.TestedPackage+"_test")
131-
}
132-
133126
func (bc *BuildCache) Store(c Cacheable, importPath string, buildTime time.Time) bool {
134127
if bc == nil {
135128
return false // Caching is disabled.
136129
}
137-
if bc.isTestPackage(importPath) {
138-
log.Infof("Skipped storing cache of test package for %q.", importPath)
139-
return false // Don't use cache when building the package under test.
140-
}
141130

142131
start := time.Now()
143132
path := cachedPath(bc.packageKey(importPath))
@@ -169,14 +158,32 @@ func (bc *BuildCache) Store(c Cacheable, importPath string, buildTime time.Time)
169158
return true
170159
}
171160

161+
func (bc *BuildCache) getEncode(w io.Writer) func(any) error {
162+
switch encoding {
163+
case `gob`:
164+
return gob.NewEncoder(w).Encode
165+
case `json`:
166+
return json.NewEncoder(w).Encode
167+
default:
168+
panic(fmt.Errorf(`unexpected encoding for encoder: %q`, encoding))
169+
}
170+
}
171+
172+
func (bc *BuildCache) getDecode(r io.Reader) func(any) error {
173+
switch encoding {
174+
case `gob`:
175+
return gob.NewDecoder(r).Decode
176+
case `json`:
177+
return json.NewDecoder(r).Decode
178+
default:
179+
panic(fmt.Errorf(`unexpected encoding for decoder: %q`, encoding))
180+
}
181+
}
182+
172183
func (bc *BuildCache) Load(c Cacheable, importPath string, srcModTime time.Time) bool {
173184
if bc == nil {
174185
return false // Caching is disabled.
175186
}
176-
if bc.isTestPackage(importPath) {
177-
log.Infof("Skipped loading cache of test package for %q.", importPath)
178-
return false // Don't use cache when building the package under test.
179-
}
180187

181188
start := time.Now()
182189
path := cachedPath(bc.packageKey(importPath))
@@ -213,11 +220,11 @@ func (bc *BuildCache) serialize(c Cacheable, buildTime time.Time, w io.Writer) (
213220
}
214221
}()
215222

216-
ge := gob.NewEncoder(zw)
217-
if err := ge.Encode(buildTime); err != nil {
223+
encode := bc.getEncode(w)
224+
if err := encode(buildTime); err != nil {
218225
return err
219226
}
220-
return c.Write(ge.Encode)
227+
return c.Write(encode)
221228
}
222229

223230
func (bc *BuildCache) deserialize(c Cacheable, srcModTime time.Time, r io.Reader) (buildTime time.Time, old bool, err error) {
@@ -232,14 +239,14 @@ func (bc *BuildCache) deserialize(c Cacheable, srcModTime time.Time, r io.Reader
232239
}
233240
}()
234241

235-
gd := gob.NewDecoder(zr)
236-
if err := gd.Decode(&buildTime); err != nil {
242+
decode := bc.getDecode(r)
243+
if err := decode(&buildTime); err != nil {
237244
return buildTime, false, err
238245
}
239246
if srcModTime.After(buildTime) {
240247
return buildTime, true, nil // Package is out-of-date, cache miss.
241248
}
242-
return buildTime, false, c.Read(gd.Decode)
249+
return buildTime, false, c.Read(decode)
243250
}
244251

245252
// commonKey returns a part of the cache key common for all artifacts generated

build/cache/cache_test.go

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -114,47 +114,6 @@ func TestOldCache(t *testing.T) {
114114
}
115115
}
116116

117-
func TestSkipOfTestPackage(t *testing.T) {
118-
cacheForTest(t)
119-
120-
const data = `fake/data`
121-
const importPath = "fake/package"
122-
want := &CacheableMock{Data: data}
123-
srcModTime := newTime(0.0)
124-
buildTime := newTime(5.0)
125-
126-
bc := BuildCache{}
127-
if !bc.Store(want, importPath, buildTime) {
128-
t.Errorf("Failed to store %s with %q.", importPath, want.Data)
129-
}
130-
131-
// Simulate writing a cache for a pacakge under test.
132-
bc.TestedPackage = importPath
133-
if bc.Store(want, importPath, buildTime) {
134-
t.Errorf("Got: cache stored for %q. Want: test packages to not write to cache.", importPath)
135-
}
136-
if bc.Store(want, importPath+"_test", buildTime) {
137-
t.Errorf("Got: cache stored for %q. Want: test packages to not write to cache.", importPath+"_test")
138-
}
139-
140-
// Simulate reading the cache for a pacakge under test.
141-
got := &CacheableMock{}
142-
if bc.Load(got, importPath, srcModTime) {
143-
t.Errorf("Got: cache with %q. Want: test package cache to not be loaded for %q.", got.Data, importPath)
144-
}
145-
got = &CacheableMock{}
146-
if bc.Load(got, importPath+"_test", srcModTime) {
147-
t.Errorf("Got: cache with %q. Want: test package cache to not be loaded for %q.", got.Data, importPath+"_test")
148-
}
149-
150-
// No package under test, cache should work normally and load previously stored non-test package.
151-
bc.TestedPackage = ""
152-
got = &CacheableMock{}
153-
if !bc.Load(got, importPath, srcModTime) || got.Data != want.Data {
154-
t.Errorf("Got: cache with %q. Want: up-to-date package cache to be loaded with %q.", got.Data, want.Data)
155-
}
156-
}
157-
158117
func cacheForTest(t *testing.T) {
159118
t.Helper()
160119
originalRoot := cacheRoot

compiler/declCache.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ func (dc *DeclCache) SetDecls(importedPaths []string, importDecls, typeDecls, va
9191
}
9292

9393
type serializableDeclCache struct {
94-
ImportPath string
95-
ImportedPaths []string
96-
ImportDecls []*Decl
97-
TypeDecls []*Decl
98-
VarDecls []*Decl
99-
FuncDecls []*Decl
94+
ImportPath string `json:"path"`
95+
ImportedPaths []string `json:"p,omitempty"`
96+
ImportDecls []*Decl `json:"i,omitempty"`
97+
TypeDecls []*Decl `json:"t,omitempty"`
98+
VarDecls []*Decl `json:"v,omitempty"`
99+
FuncDecls []*Decl `json:"f,omitempty"`
100100
}
101101

102102
func (dc *DeclCache) Read(decode func(any) error) error {

compiler/decls.go

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,50 +37,48 @@ type Decl struct {
3737
// implementation.
3838
LinkingName symbol.Name
3939
// A list of package-level JavaScript variable names this symbol needs to declare.
40-
Vars []string
40+
Vars []string `json:",omitempty"`
4141
// A JS expression by which the object represented by this decl may be
4242
// referenced within the package context. Empty if the decl represents no such
4343
// object.
44-
RefExpr string
44+
RefExpr string `json:",omitempty"`
4545
// NamedRecvType is method named recv declare.
46-
NamedRecvType string
46+
NamedRecvType string `json:",omitempty"`
4747
// JavaScript code that declares a local variable for an imported package.
48-
ImportCode []byte
48+
ImportCode []byte `json:",omitempty"`
4949
// JavaScript code that declares basic information about a named type symbol.
5050
// It configures basic information about the type and its identity.
51-
TypeDeclCode []byte
51+
TypeDeclCode []byte `json:",omitempty"`
5252
// JavaScript code that assigns exposed named types to the package.
53-
ExportTypeCode []byte
53+
ExportTypeCode []byte `json:",omitempty"`
5454
// JavaScript code that declares basic information about an anonymous type.
5555
// It configures basic information about the type.
5656
// This is added to the finish setup phase to have access to all packages.
57-
AnonTypeDeclCode []byte
57+
AnonTypeDeclCode []byte `json:",omitempty"`
5858
// JavaScript code that declares basic information about a function or
5959
// method symbol. This contains the function's or method's compiled body.
6060
// This is added to the finish setup phase to have access to all packages.
61-
FuncDeclCode []byte
61+
FuncDeclCode []byte `json:",omitempty"`
6262
// JavaScript code that assigns exposed functions to the package.
6363
// This is added to the finish setup phase to have access to all packages.
64-
ExportFuncCode []byte
64+
ExportFuncCode []byte `json:",omitempty"`
6565
// JavaScript code that initializes reflection metadata about a type's method list.
6666
// This is added to the finish setup phase to have access to all packages.
67-
MethodListCode []byte
67+
MethodListCode []byte `json:",omitempty"`
6868
// JavaScript code that initializes the rest of reflection metadata about a type
6969
// (e.g. struct fields, array type sizes, element types, etc.).
7070
// This is added to the finish setup phase to have access to all packages.
71-
TypeInitCode []byte
71+
TypeInitCode []byte `json:",omitempty"`
7272
// JavaScript code that needs to be executed during the package init phase to
7373
// set the symbol up (e.g. initialize package-level variable value).
74-
InitCode []byte
74+
InitCode []byte `json:",omitempty"`
7575
// DCEInfo stores the information for dead-code elimination.
7676
DCEInfo dce.Info
7777
// Set to true if a function performs a blocking operation (I/O or
7878
// synchronization). The compiler will have to generate function code such
7979
// that it can be resumed after a blocking operation completes without
8080
// blocking the main thread in the meantime.
8181
Blocking bool
82-
// ForGeneric inidicates this decl is for a generic function or type.
83-
ForGeneric bool
8482
}
8583

8684
// minify returns a copy of Decl with unnecessary whitespace removed from the
@@ -185,10 +183,9 @@ func (fc *funcContext) importDecls() (importedPaths []string, importDecls []*Dec
185183

186184
// newImportDecl registers the imported package and returns a Decl instance for it.
187185
func (fc *funcContext) newImportDecl(importedPkg *types.Package) *Decl {
188-
fullName := importDeclFullName(importedPkg)
189186
pkgVar := fc.importedPkgVar(importedPkg)
190187
d := &Decl{
191-
FullName: fullName,
188+
FullName: importDeclFullName(importedPkg),
192189
Vars: []string{pkgVar},
193190
ImportCode: []byte(fmt.Sprintf("\t%s = $packages[\"%s\"];\n", pkgVar, importedPkg.Path())),
194191
InitCode: fc.CatchOutput(1, func() { fc.translateStmt(fc.importInitializer(importedPkg.Path()), nil) }),
@@ -253,9 +250,8 @@ func (fc *funcContext) varDecls(vars []*types.Var) []*Decl {
253250
// newVarDecl creates a new Decl describing a variable, given an explicit
254251
// initializer.
255252
func (fc *funcContext) newVarDecl(init *types.Initializer) *Decl {
256-
fullName := varDeclFullName(init)
257253
d := &Decl{
258-
FullName: fullName,
254+
FullName: varDeclFullName(init),
259255
}
260256
assignLHS := []ast.Expr{}
261257
for _, o := range init.Lhs {
@@ -371,9 +367,8 @@ func (fc *funcContext) newFuncVarDecl(fun *ast.FuncDecl, o *types.Func, instance
371367
}
372368

373369
varDecl := &Decl{
374-
FullName: fullName,
375-
Vars: []string{varName},
376-
ForGeneric: generic,
370+
FullName: fullName,
371+
Vars: []string{varName},
377372
}
378373
varDecl.Dce().SetName(o, nil, nil)
379374

@@ -386,23 +381,20 @@ func (fc *funcContext) newFuncVarDecl(fun *ast.FuncDecl, o *types.Func, instance
386381
}
387382

388383
func (fc *funcContext) newCallMainFuncDecl(mainFunc *types.Func) *Decl {
389-
fullName := mainFuncDeclFullName()
390384
d := &Decl{
391-
FullName: fullName,
385+
FullName: mainFuncDeclFullName(),
392386
InitCode: fc.CatchOutput(1, func() { fc.translateStmt(fc.callMainFunc(mainFunc), nil) }),
393387
}
394388
return d
395389
}
396390

397391
// newFuncDecl returns a Decl that defines a package-level function or a method.
398392
func (fc *funcContext) newFuncDecl(fun *ast.FuncDecl, inst typeparams.Instance) *Decl {
399-
fullName := funcDeclFullName(inst)
400393
o := fc.pkgCtx.Defs[fun.Name].(*types.Func)
401394
d := &Decl{
402-
FullName: fullName,
395+
FullName: funcDeclFullName(inst),
403396
Blocking: fc.pkgCtx.IsBlocking(inst),
404397
LinkingName: symbol.New(o),
405-
ForGeneric: !inst.IsTrivial(),
406398
}
407399
d.Dce().SetName(o, inst.TNest, inst.TArgs)
408400

@@ -531,17 +523,15 @@ func (fc *funcContext) namedTypeDecls(typeNames typesutil.TypeNames) ([]*Decl, e
531523
// of the type, keyed by the type argument combination. Otherwise it contains
532524
// the type definition directly.
533525
func (fc *funcContext) newNamedTypeVarDecl(obj *types.TypeName) *Decl {
534-
fullName := typeVarDeclFullName(obj)
535526
name := fc.objectName(obj)
536527
generic := fc.pkgCtx.instanceSet.Pkg(obj.Pkg()).ObjHasInstances(obj)
537528
varName := name
538529
if generic {
539530
varName += ` = []`
540531
}
541532
varDecl := &Decl{
542-
FullName: fullName,
543-
Vars: []string{varName},
544-
ForGeneric: generic,
533+
FullName: typeVarDeclFullName(obj),
534+
Vars: []string{varName},
545535
}
546536
varDecl.Dce().SetName(obj, nil, nil)
547537
if isPkgLevel(obj) {
@@ -555,7 +545,6 @@ func (fc *funcContext) newNamedTypeVarDecl(obj *types.TypeName) *Decl {
555545
// newNamedTypeInstDecl returns a Decl that represents an instantiation of a
556546
// named Go type.
557547
func (fc *funcContext) newNamedTypeInstDecl(inst typeparams.Instance) (*Decl, error) {
558-
fullName := typeDeclFullName(inst)
559548
originType := inst.Object.Type().(*types.Named)
560549

561550
fc.typeResolver = typeparams.NewResolver(fc.pkgCtx.typesCtx, inst)
@@ -575,8 +564,7 @@ func (fc *funcContext) newNamedTypeInstDecl(inst typeparams.Instance) (*Decl, er
575564

576565
underlying := instanceType.Underlying()
577566
d := &Decl{
578-
FullName: fullName,
579-
ForGeneric: !inst.IsTrivial(),
567+
FullName: typeDeclFullName(inst),
580568
}
581569
d.Dce().SetName(inst.Object, inst.TNest, inst.TArgs)
582570
fc.pkgCtx.CollectDCEDeps(d, func() {
@@ -700,9 +688,8 @@ func (fc *funcContext) anonTypeDecls(anonTypes []*types.TypeName) []*Decl {
700688
}
701689
decls := []*Decl{}
702690
for _, t := range anonTypes {
703-
fullName := anonTypeDeclFullName(t)
704691
d := &Decl{
705-
FullName: fullName,
692+
FullName: anonTypeDeclFullName(t),
706693
Vars: []string{t.Name()},
707694
}
708695
d.Dce().SetName(t, nil, nil)

0 commit comments

Comments
 (0)