package wazevoapi
import (
"context"
"encoding/hex"
"fmt"
"math/rand"
"os"
"time"
)
const (
FrontEndLoggingEnabled = false
SSALoggingEnabled = false
RegAllocLoggingEnabled = false
)
const (
PrintSSA = false
PrintOptimizedSSA = false
PrintSSAToBackendIRLowering = false
PrintRegisterAllocated = false
PrintFinalizedMachineCode = false
PrintMachineCodeHexPerFunction = printMachineCodeHexPerFunctionUnmodified || PrintMachineCodeHexPerFunctionDisassemblable
printMachineCodeHexPerFunctionUnmodified = false
PrintMachineCodeHexPerFunctionDisassemblable = false
)
const printTarget = -1
func PrintEnabledIndex (ctx context .Context ) bool {
if printTarget == -1 {
return true
}
return GetCurrentFunctionIndex (ctx ) == printTarget
}
const (
SSAValidationEnabled = false
)
const (
StackGuardCheckEnabled = false
StackGuardCheckGuardPageSize = 8096
)
func CheckStackGuardPage (s []byte ) {
for i := 0 ; i < StackGuardCheckGuardPageSize ; i ++ {
if s [i ] != 0 {
panic (
fmt .Sprintf ("BUG: stack guard page is corrupted:\n\tguard_page=%s\n\tstack=%s" ,
hex .EncodeToString (s [:StackGuardCheckGuardPageSize ]),
hex .EncodeToString (s [StackGuardCheckGuardPageSize :]),
))
}
}
}
const (
DeterministicCompilationVerifierEnabled = false
DeterministicCompilationVerifyingIter = 5
)
type (
verifierState struct {
initialCompilationDone bool
maybeRandomizedIndexes []int
r *rand .Rand
values map [string ]string
}
verifierStateContextKey struct {}
currentFunctionNameKey struct {}
currentFunctionIndexKey struct {}
)
func NewDeterministicCompilationVerifierContext (ctx context .Context , localFunctions int ) context .Context {
maybeRandomizedIndexes := make ([]int , localFunctions )
for i := range maybeRandomizedIndexes {
maybeRandomizedIndexes [i ] = i
}
r := rand .New (rand .NewSource (time .Now ().UnixNano ()))
return context .WithValue (ctx , verifierStateContextKey {}, &verifierState {
r : r , maybeRandomizedIndexes : maybeRandomizedIndexes , values : map [string ]string {},
})
}
func DeterministicCompilationVerifierRandomizeIndexes (ctx context .Context ) {
state := ctx .Value (verifierStateContextKey {}).(*verifierState )
if !state .initialCompilationDone {
state .initialCompilationDone = true
return
}
r := state .r
r .Shuffle (len (state .maybeRandomizedIndexes ), func (i , j int ) {
state .maybeRandomizedIndexes [i ], state .maybeRandomizedIndexes [j ] = state .maybeRandomizedIndexes [j ], state .maybeRandomizedIndexes [i ]
})
}
func DeterministicCompilationVerifierGetRandomizedLocalFunctionIndex (ctx context .Context , index int ) int {
state := ctx .Value (verifierStateContextKey {}).(*verifierState )
ret := state .maybeRandomizedIndexes [index ]
return ret
}
func VerifyOrSetDeterministicCompilationContextValue (ctx context .Context , scope string , newValue string ) {
fn := ctx .Value (currentFunctionNameKey {}).(string )
key := fn + ": " + scope
verifierCtx := ctx .Value (verifierStateContextKey {}).(*verifierState )
oldValue , ok := verifierCtx .values [key ]
if !ok {
verifierCtx .values [key ] = newValue
return
}
if oldValue != newValue {
fmt .Printf (
`BUG: Deterministic compilation failed for function%s at scope="%s".
This is mostly due to (but might not be limited to):
* Resetting ssa.Builder, backend.Compiler or frontend.Compiler, etc doens't work as expected, and the compilation has been affected by the previous iterations.
* Using a map with non-deterministic iteration order.
---------- [old] ----------
%s
---------- [new] ----------
%s
` ,
fn , scope , oldValue , newValue ,
)
os .Exit (1 )
}
}
const NeedFunctionNameInContext = PrintSSA ||
PrintOptimizedSSA ||
PrintSSAToBackendIRLowering ||
PrintRegisterAllocated ||
PrintFinalizedMachineCode ||
PrintMachineCodeHexPerFunction ||
DeterministicCompilationVerifierEnabled ||
PerfMapEnabled
func SetCurrentFunctionName (ctx context .Context , index int , functionName string ) context .Context {
ctx = context .WithValue (ctx , currentFunctionNameKey {}, functionName )
ctx = context .WithValue (ctx , currentFunctionIndexKey {}, index )
return ctx
}
func GetCurrentFunctionName (ctx context .Context ) string {
ret , _ := ctx .Value (currentFunctionNameKey {}).(string )
return ret
}
func GetCurrentFunctionIndex (ctx context .Context ) int {
ret , _ := ctx .Value (currentFunctionIndexKey {}).(int )
return ret
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .