github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/encoder/debug_go117.go (about) 1 //go:build go1.17 && !go1.22 2 // +build go1.17,!go1.22 3 4 /* 5 * Copyright 2021 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package encoder 21 22 import ( 23 "fmt" 24 "os" 25 "runtime" 26 "strings" 27 "unsafe" 28 29 "github.com/goshafaq/sonic/internal/jit" 30 "github.com/twitchyliquid64/golang-asm/obj" 31 ) 32 33 const _FP_debug = 128 34 35 var ( 36 debugSyncGC = os.Getenv("SONIC_SYNC_GC") != "" 37 debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == "" 38 debugCheckPtr = os.Getenv("SONIC_CHECK_POINTER") != "" 39 ) 40 41 var ( 42 _Instr_End = newInsOp(_OP_is_nil) 43 44 _F_gc = jit.Func(gc) 45 _F_println = jit.Func(println_wrapper) 46 _F_print = jit.Func(print) 47 ) 48 49 func (self *_Assembler) dsave(r ...obj.Addr) { 50 for i, v := range r { 51 if i > _FP_debug/8-1 { 52 panic("too many registers to save") 53 } else { 54 self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs+_FP_saves+_FP_locals+int64(i)*8)) 55 } 56 } 57 } 58 59 func (self *_Assembler) dload(r ...obj.Addr) { 60 for i, v := range r { 61 if i > _FP_debug/8-1 { 62 panic("too many registers to load") 63 } else { 64 self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs+_FP_saves+_FP_locals+int64(i)*8), v) 65 } 66 } 67 } 68 69 func println_wrapper(i int, op1 int, op2 int) { 70 println(i, " Intrs ", op1, _OpNames[op1], "next: ", op2, _OpNames[op2]) 71 } 72 73 func print(i int) { 74 println(i) 75 } 76 77 func gc() { 78 if !debugSyncGC { 79 return 80 } 81 runtime.GC() 82 // debug.FreeOSMemory() 83 } 84 85 func (self *_Assembler) dcall(fn obj.Addr) { 86 self.Emit("MOVQ", fn, _R10) // MOVQ ${fn}, R10 87 self.Rjmp("CALL", _R10) // CALL R10 88 } 89 90 func (self *_Assembler) debug_gc() { 91 if !debugSyncGC { 92 return 93 } 94 self.dsave(_REG_debug...) 95 self.dcall(_F_gc) 96 self.dload(_REG_debug...) 97 } 98 99 func (self *_Assembler) debug_instr(i int, v *_Instr) { 100 if debugSyncGC { 101 if i+1 == len(self.p) { 102 self.print_gc(i, v, &_Instr_End) 103 } else { 104 next := &(self.p[i+1]) 105 self.print_gc(i, v, next) 106 name := _OpNames[next.op()] 107 if strings.Contains(name, "save") { 108 return 109 } 110 } 111 // self.debug_gc() 112 } 113 } 114 115 //go:noescape 116 //go:linkname checkptrBase runtime.checkptrBase 117 func checkptrBase(p unsafe.Pointer) uintptr 118 119 //go:noescape 120 //go:linkname findObject runtime.findObject 121 func findObject(p, refBase, refOff uintptr) (base uintptr, s unsafe.Pointer, objIndex uintptr) 122 123 var ( 124 _F_checkptr = jit.Func(checkptr) 125 _F_printptr = jit.Func(printptr) 126 ) 127 128 var ( 129 _R10 = jit.Reg("R10") 130 ) 131 var _REG_debug = []obj.Addr{ 132 jit.Reg("AX"), 133 jit.Reg("BX"), 134 jit.Reg("CX"), 135 jit.Reg("DX"), 136 jit.Reg("DI"), 137 jit.Reg("SI"), 138 jit.Reg("BP"), 139 jit.Reg("SP"), 140 jit.Reg("R8"), 141 jit.Reg("R9"), 142 jit.Reg("R10"), 143 jit.Reg("R11"), 144 jit.Reg("R12"), 145 jit.Reg("R13"), 146 jit.Reg("R14"), 147 jit.Reg("R15"), 148 } 149 150 func checkptr(ptr uintptr) { 151 if ptr == 0 { 152 return 153 } 154 fmt.Printf("pointer: %x\n", ptr) 155 f := checkptrBase(unsafe.Pointer(uintptr(ptr))) 156 if f == 0 { 157 fmt.Printf("! unknown-based pointer: %x\n", ptr) 158 } else if f == 1 { 159 fmt.Printf("! stack pointer: %x\n", ptr) 160 } else { 161 fmt.Printf("base: %x\n", f) 162 } 163 findobj(ptr) 164 } 165 166 func findobj(ptr uintptr) { 167 base, s, objIndex := findObject(ptr, 0, 0) 168 if s != nil && base == 0 { 169 fmt.Printf("! invalid pointer: %x\n", ptr) 170 } 171 fmt.Printf("objIndex: %d\n", objIndex) 172 } 173 174 func (self *_Assembler) check_ptr(ptr obj.Addr, lea bool) { 175 if !debugCheckPtr { 176 return 177 } 178 179 self.dsave(_REG_debug...) 180 if lea { 181 self.Emit("LEAQ", ptr, _R10) 182 } else { 183 self.Emit("MOVQ", ptr, _R10) 184 } 185 self.Emit("MOVQ", _R10, jit.Ptr(_SP, 0)) 186 self.dcall(_F_checkptr) 187 self.dload(_REG_debug...) 188 } 189 190 func printptr(i int, ptr uintptr) { 191 fmt.Printf("[%d] ptr: %x\n", i, ptr) 192 } 193 194 func (self *_Assembler) print_ptr(i int, ptr obj.Addr, lea bool) { 195 self.dsave(_REG_debug...) 196 if lea { 197 self.Emit("LEAQ", ptr, _R10) 198 } else { 199 self.Emit("MOVQ", ptr, _R10) 200 } 201 202 self.Emit("MOVQ", jit.Imm(int64(i)), _AX) 203 self.Emit("MOVQ", _R10, _BX) 204 self.dcall(_F_printptr) 205 self.dload(_REG_debug...) 206 }