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  

View as plain text