diff options
Diffstat (limited to 'src/internal/pkgbits')
| -rw-r--r-- | src/internal/pkgbits/decoder.go | 26 | ||||
| -rw-r--r-- | src/internal/pkgbits/encoder.go | 36 | ||||
| -rw-r--r-- | src/internal/pkgbits/flags.go | 9 | ||||
| -rw-r--r-- | src/internal/pkgbits/sync.go | 16 | ||||
| -rw-r--r-- | src/internal/pkgbits/syncmarker_string.go | 61 |
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 |
