1 package gc 2 3 import ( 4 "os" 5 "runtime" 6 "runtime/pprof" 7 "strconv" 8 "strings" 9 ) 10 11 func (n *Node) Line() string { 12 return Ctxt.LineHist.LineString(int(n.Lineno)) 13 } 14 15 func atoi(s string) int { 16 // NOTE: Not strconv.Atoi, accepts hex and octal prefixes. 17 n, _ := strconv.ParseInt(s, 0, 0) 18 return int(n) 19 } 20 21 func isalnum(c int) bool { 22 return isalpha(c) || isdigit(c) 23 } 24 25 func isalpha(c int) bool { 26 return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' 27 } 28 29 func isdigit(c int) bool { 30 return '0' <= c && c <= '9' 31 } 32 33 func plan9quote(s string) string { 34 if s == "" { 35 return "'" + strings.Replace(s, "'", "''", -1) + "'" 36 } 37 for i := 0; i < len(s); i++ { 38 if s[i] <= ' ' || s[i] == '\'' { 39 return "'" + strings.Replace(s, "'", "''", -1) + "'" 40 } 41 } 42 return s 43 } 44 45 // strings.Compare, introduced in Go 1.5. 46 func stringsCompare(a, b string) int { 47 if a == b { 48 return 0 49 } 50 if a < b { 51 return -1 52 } 53 return +1 54 } 55 56 var atExitFuncs []func() 57 58 func AtExit(f func()) { 59 atExitFuncs = append(atExitFuncs, f) 60 } 61 62 func Exit(code int) { 63 for i := len(atExitFuncs) - 1; i >= 0; i-- { 64 f := atExitFuncs[i] 65 atExitFuncs = atExitFuncs[:i] 66 f() 67 } 68 os.Exit(code) 69 } 70 71 var ( 72 cpuprofile string 73 memprofile string 74 memprofilerate int64 75 ) 76 77 func startProfile() { 78 if cpuprofile != "" { 79 f, err := os.Create(cpuprofile) 80 if err != nil { 81 Fatal("%v", err) 82 } 83 if err := pprof.StartCPUProfile(f); err != nil { 84 Fatal("%v", err) 85 } 86 AtExit(pprof.StopCPUProfile) 87 } 88 if memprofile != "" { 89 if memprofilerate != 0 { 90 runtime.MemProfileRate = int(memprofilerate) 91 } 92 f, err := os.Create(memprofile) 93 if err != nil { 94 Fatal("%v", err) 95 } 96 AtExit(func() { 97 runtime.GC() // profile all outstanding allocations 98 if err := pprof.WriteHeapProfile(f); err != nil { 99 Fatal("%v", err) 100 } 101 }) 102 } 103 } 104