diff options
Diffstat (limited to 'src/cmd/compile/internal/noder/export.go')
-rw-r--r-- | src/cmd/compile/internal/noder/export.go | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/noder/export.go b/src/cmd/compile/internal/noder/export.go index 9fb3b4da10..1a296e22c8 100644 --- a/src/cmd/compile/internal/noder/export.go +++ b/src/cmd/compile/internal/noder/export.go @@ -5,22 +5,61 @@ package noder import ( + "bytes" "fmt" + "io" "cmd/compile/internal/base" "cmd/compile/internal/typecheck" "cmd/internal/bio" ) +// writeNewExportFunc is a hook that can be added to append extra +// export data after the normal export data section. It allows +// experimenting with new export data format designs without requiring +// immediate support in the go/internal or x/tools importers. +var writeNewExportFunc func(out io.Writer) + func WriteExports(out *bio.Writer) { + // When unified IR exports are enable, we simply append it to the + // end of the normal export data (with compiler extensions + // disabled), and write an extra header giving its size. + // + // If the compiler sees this header, it knows to read the new data + // instead; meanwhile the go/types importers will silently ignore it + // and continue processing the old export instead. + // + // This allows us to experiment with changes to the new export data + // format without needing to update the go/internal/gcimporter or + // (worse) x/tools/go/gcexportdata. + + useNewExport := writeNewExportFunc != nil + + var old, new bytes.Buffer + + typecheck.WriteExports(&old, !useNewExport) + + if useNewExport { + writeNewExportFunc(&new) + } + + oldLen := old.Len() + newLen := new.Len() + + if useNewExport { + fmt.Fprintf(out, "\nnewexportsize %v\n", newLen) + } + // The linker also looks for the $$ marker - use char after $$ to distinguish format. out.WriteString("\n$$B\n") // indicate binary export format - off := out.Offset() - typecheck.WriteExports(out, true) - size := out.Offset() - off + io.Copy(out, &old) out.WriteString("\n$$\n") + io.Copy(out, &new) if base.Debug.Export != 0 { - fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, size) + fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, oldLen) + if useNewExport { + fmt.Printf("BenchmarkNewExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, newLen) + } } } |