Source file src/cmd/compile/internal/noder/export.go
1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package noder 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 12 "cmd/compile/internal/base" 13 "cmd/compile/internal/typecheck" 14 "cmd/internal/bio" 15 ) 16 17 // writeNewExportFunc is a hook that can be added to append extra 18 // export data after the normal export data section. It allows 19 // experimenting with new export data format designs without requiring 20 // immediate support in the go/internal or x/tools importers. 21 var writeNewExportFunc func(out io.Writer) 22 23 func WriteExports(out *bio.Writer) { 24 // When unified IR exports are enable, we simply append it to the 25 // end of the normal export data (with compiler extensions 26 // disabled), and write an extra header giving its size. 27 // 28 // If the compiler sees this header, it knows to read the new data 29 // instead; meanwhile the go/types importers will silently ignore it 30 // and continue processing the old export instead. 31 // 32 // This allows us to experiment with changes to the new export data 33 // format without needing to update the go/internal/gcimporter or 34 // (worse) x/tools/go/gcexportdata. 35 36 useNewExport := writeNewExportFunc != nil 37 38 var old, new bytes.Buffer 39 40 typecheck.WriteExports(&old, !useNewExport) 41 42 if useNewExport { 43 writeNewExportFunc(&new) 44 } 45 46 oldLen := old.Len() 47 newLen := new.Len() 48 49 if useNewExport { 50 fmt.Fprintf(out, "\nnewexportsize %v\n", newLen) 51 } 52 53 // The linker also looks for the $$ marker - use char after $$ to distinguish format. 54 out.WriteString("\n$$B\n") // indicate binary export format 55 io.Copy(out, &old) 56 out.WriteString("\n$$\n") 57 io.Copy(out, &new) 58 59 if base.Debug.Export != 0 { 60 fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, oldLen) 61 if useNewExport { 62 fmt.Printf("BenchmarkNewExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, newLen) 63 } 64 } 65 } 66