aboutsummaryrefslogtreecommitdiff
path: root/src/internal/pkgbits
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/pkgbits')
-rw-r--r--src/internal/pkgbits/decoder.go26
-rw-r--r--src/internal/pkgbits/encoder.go36
-rw-r--r--src/internal/pkgbits/flags.go9
-rw-r--r--src/internal/pkgbits/sync.go16
-rw-r--r--src/internal/pkgbits/syncmarker_string.go61
5 files changed, 99 insertions, 49 deletions
diff --git a/src/internal/pkgbits/decoder.go b/src/internal/pkgbits/decoder.go
index 0b5fd9705c..5e233b8770 100644
--- a/src/internal/pkgbits/decoder.go
+++ b/src/internal/pkgbits/decoder.go
@@ -18,6 +18,12 @@ import (
// A PkgDecoder provides methods for decoding a package's Unified IR
// export data.
type PkgDecoder struct {
+ // version is the file format version.
+ version uint32
+
+ // sync indicates whether the file uses sync markers.
+ sync bool
+
// pkgPath is the package path for the package to be decoded.
//
// TODO(mdempsky): Remove; unneeded since CL 391014.
@@ -52,6 +58,9 @@ type PkgDecoder struct {
// TODO(mdempsky): Remove; unneeded since CL 391014.
func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath }
+// SyncMarkers reports whether pr uses sync markers.
+func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync }
+
// NewPkgDecoder returns a PkgDecoder initialized to read the Unified
// IR export data from input. pkgPath is the package path for the
// compilation unit that produced the export data.
@@ -67,9 +76,18 @@ func NewPkgDecoder(pkgPath, input string) PkgDecoder {
r := strings.NewReader(input)
- var version uint32
- assert(binary.Read(r, binary.LittleEndian, &version) == nil)
- assert(version == 0)
+ assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil)
+
+ switch pr.version {
+ default:
+ panic(fmt.Errorf("unsupported version: %v", pr.version))
+ case 0:
+ // no flags
+ case 1:
+ var flags uint32
+ assert(binary.Read(r, binary.LittleEndian, &flags) == nil)
+ pr.sync = flags&flagSyncMarkers != 0
+ }
assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil)
@@ -215,7 +233,7 @@ func (r *Decoder) rawReloc(k RelocKind, idx int) Index {
//
// If EnableSync is false, then Sync is a no-op.
func (r *Decoder) Sync(mWant SyncMarker) {
- if !EnableSync {
+ if !r.common.sync {
return
}
diff --git a/src/internal/pkgbits/encoder.go b/src/internal/pkgbits/encoder.go
index 1326a135cf..ec47e352cb 100644
--- a/src/internal/pkgbits/encoder.go
+++ b/src/internal/pkgbits/encoder.go
@@ -14,6 +14,16 @@ import (
"runtime"
)
+// currentVersion is the current version number.
+//
+// - v0: initial prototype
+//
+// - v1: adds the flags uint32 word
+//
+// TODO(mdempsky): For the next version bump:
+// - remove the legacy "has init" bool from the public root
+const currentVersion uint32 = 1
+
// A PkgEncoder provides methods for encoding a package's Unified IR
// export data.
type PkgEncoder struct {
@@ -25,15 +35,21 @@ type PkgEncoder struct {
// elems[RelocString][stringsIdx[s]] == s (if present).
stringsIdx map[string]Index
+ // syncFrames is the number of frames to write at each sync
+ // marker. A negative value means sync markers are omitted.
syncFrames int
}
+// SyncMarkers reports whether pw uses sync markers.
+func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 }
+
// NewPkgEncoder returns an initialized PkgEncoder.
//
// syncFrames is the number of caller frames that should be serialized
// at Sync points. Serializing additional frames results in larger
// export data files, but can help diagnosing desync errors in
-// higher-level Unified IR reader/writer code.
+// higher-level Unified IR reader/writer code. If syncFrames is
+// negative, then sync markers are omitted entirely.
func NewPkgEncoder(syncFrames int) PkgEncoder {
return PkgEncoder{
stringsIdx: make(map[string]Index),
@@ -51,7 +67,13 @@ func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
assert(binary.Write(out, binary.LittleEndian, x) == nil)
}
- writeUint32(0) // version
+ writeUint32(currentVersion)
+
+ var flags uint32
+ if pw.SyncMarkers() {
+ flags |= flagSyncMarkers
+ }
+ writeUint32(flags)
// Write elemEndsEnds.
var sum uint32
@@ -204,7 +226,7 @@ func (w *Encoder) rawReloc(r RelocKind, idx Index) int {
}
func (w *Encoder) Sync(m SyncMarker) {
- if !EnableSync {
+ if !w.p.SyncMarkers() {
return
}
@@ -297,8 +319,14 @@ func (w *Encoder) Code(c Code) {
// section (if not already present), and then writing a relocation
// into the element bitstream.
func (w *Encoder) String(s string) {
+ w.StringRef(w.p.StringIdx(s))
+}
+
+// StringRef writes a reference to the given index, which must be a
+// previously encoded string value.
+func (w *Encoder) StringRef(idx Index) {
w.Sync(SyncString)
- w.Reloc(RelocString, w.p.StringIdx(s))
+ w.Reloc(RelocString, idx)
}
// Strings encodes and writes a variable-length slice of strings into
diff --git a/src/internal/pkgbits/flags.go b/src/internal/pkgbits/flags.go
new file mode 100644
index 0000000000..654222745f
--- /dev/null
+++ b/src/internal/pkgbits/flags.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+const (
+ flagSyncMarkers = 1 << iota // file format contains sync markers
+)
diff --git a/src/internal/pkgbits/sync.go b/src/internal/pkgbits/sync.go
index 72f776af05..1520b73afb 100644
--- a/src/internal/pkgbits/sync.go
+++ b/src/internal/pkgbits/sync.go
@@ -10,17 +10,6 @@ import (
"strings"
)
-// EnableSync controls whether sync markers are written into unified
-// IR's export data format and also whether they're expected when
-// reading them back in. They're inessential to the correct
-// functioning of unified IR, but are helpful during development to
-// detect mistakes.
-//
-// When sync is enabled, writer stack frames will also be included in
-// the export data. Currently, a fixed number of frames are included,
-// controlled by -d=syncframes (default 0).
-const EnableSync = true
-
// fmtFrames formats a backtrace for reporting reader/writer desyncs.
func fmtFrames(pcs ...uintptr) []string {
res := make([]string, 0, len(pcs))
@@ -109,6 +98,7 @@ const (
SyncExprs
SyncExpr
SyncExprType
+ SyncAssign
SyncOp
SyncFuncLit
SyncCompLit
@@ -139,4 +129,8 @@ const (
SyncStmtsEnd
SyncLabel
SyncOptLabel
+
+ SyncMultiExpr
+ SyncRType
+ SyncConvRTTI
)
diff --git a/src/internal/pkgbits/syncmarker_string.go b/src/internal/pkgbits/syncmarker_string.go
index 39db9eddad..4a5b0ca5f2 100644
--- a/src/internal/pkgbits/syncmarker_string.go
+++ b/src/internal/pkgbits/syncmarker_string.go
@@ -45,39 +45,40 @@ func _() {
_ = x[SyncExprs-35]
_ = x[SyncExpr-36]
_ = x[SyncExprType-37]
- _ = x[SyncOp-38]
- _ = x[SyncFuncLit-39]
- _ = x[SyncCompLit-40]
- _ = x[SyncDecl-41]
- _ = x[SyncFuncBody-42]
- _ = x[SyncOpenScope-43]
- _ = x[SyncCloseScope-44]
- _ = x[SyncCloseAnotherScope-45]
- _ = x[SyncDeclNames-46]
- _ = x[SyncDeclName-47]
- _ = x[SyncStmts-48]
- _ = x[SyncBlockStmt-49]
- _ = x[SyncIfStmt-50]
- _ = x[SyncForStmt-51]
- _ = x[SyncSwitchStmt-52]
- _ = x[SyncRangeStmt-53]
- _ = x[SyncCaseClause-54]
- _ = x[SyncCommClause-55]
- _ = x[SyncSelectStmt-56]
- _ = x[SyncDecls-57]
- _ = x[SyncLabeledStmt-58]
- _ = x[SyncUseObjLocal-59]
- _ = x[SyncAddLocal-60]
- _ = x[SyncLinkname-61]
- _ = x[SyncStmt1-62]
- _ = x[SyncStmtsEnd-63]
- _ = x[SyncLabel-64]
- _ = x[SyncOptLabel-65]
+ _ = x[SyncAssign-38]
+ _ = x[SyncOp-39]
+ _ = x[SyncFuncLit-40]
+ _ = x[SyncCompLit-41]
+ _ = x[SyncDecl-42]
+ _ = x[SyncFuncBody-43]
+ _ = x[SyncOpenScope-44]
+ _ = x[SyncCloseScope-45]
+ _ = x[SyncCloseAnotherScope-46]
+ _ = x[SyncDeclNames-47]
+ _ = x[SyncDeclName-48]
+ _ = x[SyncStmts-49]
+ _ = x[SyncBlockStmt-50]
+ _ = x[SyncIfStmt-51]
+ _ = x[SyncForStmt-52]
+ _ = x[SyncSwitchStmt-53]
+ _ = x[SyncRangeStmt-54]
+ _ = x[SyncCaseClause-55]
+ _ = x[SyncCommClause-56]
+ _ = x[SyncSelectStmt-57]
+ _ = x[SyncDecls-58]
+ _ = x[SyncLabeledStmt-59]
+ _ = x[SyncUseObjLocal-60]
+ _ = x[SyncAddLocal-61]
+ _ = x[SyncLinkname-62]
+ _ = x[SyncStmt1-63]
+ _ = x[SyncStmtsEnd-64]
+ _ = x[SyncLabel-65]
+ _ = x[SyncOptLabel-66]
}
-const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprAssertTypeOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
+const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
-var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 228, 230, 237, 244, 248, 256, 265, 275, 292, 301, 309, 314, 323, 329, 336, 346, 355, 365, 375, 385, 390, 401, 412, 420, 428, 433, 441, 446, 454}
+var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458}
func (i SyncMarker) String() string {
i -= 1