1
2
3
18
19 package encoder
20
21 import (
22 `fmt`
23 `os`
24 `runtime`
25 `strings`
26 `unsafe`
27
28 `github.com/bytedance/sonic/internal/jit`
29 `github.com/twitchyliquid64/golang-asm/obj`
30 )
31
32 const _FP_debug = 128
33
34 var (
35 debugSyncGC = os.Getenv("SONIC_SYNC_GC") != ""
36 debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == ""
37 debugCheckPtr = os.Getenv("SONIC_CHECK_POINTER") != ""
38 )
39
40 var (
41 _Instr_End = newInsOp(_OP_is_nil)
42
43 _F_gc = jit.Func(gc)
44 _F_println = jit.Func(println_wrapper)
45 _F_print = jit.Func(print)
46 )
47
48 func (self *_Assembler) dsave(r ...obj.Addr) {
49 for i, v := range r {
50 if i > _FP_debug / 8 - 1 {
51 panic("too many registers to save")
52 } else {
53 self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs + _FP_saves + _FP_locals + int64(i) * 8))
54 }
55 }
56 }
57
58 func (self *_Assembler) dload(r ...obj.Addr) {
59 for i, v := range r {
60 if i > _FP_debug / 8 - 1 {
61 panic("too many registers to load")
62 } else {
63 self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs + _FP_saves + _FP_locals + int64(i) * 8), v)
64 }
65 }
66 }
67
68 func println_wrapper(i int, op1 int, op2 int){
69 println(i, " Intrs ", op1, _OpNames[op1], "next: ", op2, _OpNames[op2])
70 }
71
72 func print(i int){
73 println(i)
74 }
75
76 func gc() {
77 if !debugSyncGC {
78 return
79 }
80 runtime.GC()
81
82 }
83
84 func (self *_Assembler) dcall(fn obj.Addr) {
85 self.Emit("MOVQ", fn, _R10)
86 self.Rjmp("CALL", _R10)
87 }
88
89 func (self *_Assembler) debug_gc() {
90 if !debugSyncGC {
91 return
92 }
93 self.dsave(_REG_debug...)
94 self.dcall(_F_gc)
95 self.dload(_REG_debug...)
96 }
97
98 func (self *_Assembler) debug_instr(i int, v *_Instr) {
99 if debugSyncGC {
100 if i+1 == len(self.p) {
101 self.print_gc(i, v, &_Instr_End)
102 } else {
103 next := &(self.p[i+1])
104 self.print_gc(i, v, next)
105 name := _OpNames[next.op()]
106 if strings.Contains(name, "save") {
107 return
108 }
109 }
110
111 }
112 }
113
114
115
116 func checkptrBase(p unsafe.Pointer) uintptr
117
118
119
120 func findObject(p, refBase, refOff uintptr) (base uintptr, s unsafe.Pointer, objIndex uintptr)
121
122 var (
123 _F_checkptr = jit.Func(checkptr)
124 _F_printptr = jit.Func(printptr)
125 )
126
127 var (
128 _R10 = jit.Reg("R10")
129 )
130 var _REG_debug = []obj.Addr {
131 jit.Reg("AX"),
132 jit.Reg("BX"),
133 jit.Reg("CX"),
134 jit.Reg("DX"),
135 jit.Reg("DI"),
136 jit.Reg("SI"),
137 jit.Reg("BP"),
138 jit.Reg("SP"),
139 jit.Reg("R8"),
140 jit.Reg("R9"),
141 jit.Reg("R10"),
142 jit.Reg("R11"),
143 jit.Reg("R12"),
144 jit.Reg("R13"),
145 jit.Reg("R14"),
146 jit.Reg("R15"),
147 }
148
149 func checkptr(ptr uintptr) {
150 if ptr == 0 {
151 return
152 }
153 fmt.Printf("pointer: %x\n", ptr)
154 f := checkptrBase(unsafe.Pointer(uintptr(ptr)))
155 if f == 0 {
156 fmt.Printf("! unknown-based pointer: %x\n", ptr)
157 } else if f == 1 {
158 fmt.Printf("! stack pointer: %x\n", ptr)
159 } else {
160 fmt.Printf("base: %x\n", f)
161 }
162 findobj(ptr)
163 }
164
165 func findobj(ptr uintptr) {
166 base, s, objIndex := findObject(ptr, 0, 0)
167 if s != nil && base == 0 {
168 fmt.Printf("! invalid pointer: %x\n", ptr)
169 }
170 fmt.Printf("objIndex: %d\n", objIndex)
171 }
172
173 func (self *_Assembler) check_ptr(ptr obj.Addr, lea bool) {
174 if !debugCheckPtr {
175 return
176 }
177
178 self.dsave(_REG_debug...)
179 if lea {
180 self.Emit("LEAQ", ptr, _R10)
181 } else {
182 self.Emit("MOVQ", ptr, _R10)
183 }
184 self.Emit("MOVQ", _R10, jit.Ptr(_SP, 0))
185 self.dcall(_F_checkptr)
186 self.dload(_REG_debug...)
187 }
188
189 func printptr(i int, ptr uintptr) {
190 fmt.Printf("[%d] ptr: %x\n", i, ptr)
191 }
192
193 func (self *_Assembler) print_ptr(i int, ptr obj.Addr, lea bool) {
194 self.dsave(_REG_debug...)
195 if lea {
196 self.Emit("LEAQ", ptr, _R10)
197 } else {
198 self.Emit("MOVQ", ptr, _R10)
199 }
200
201 self.Emit("MOVQ", jit.Imm(int64(i)), _AX)
202 self.Emit("MOVQ", _R10, _BX)
203 self.dcall(_F_printptr)
204 self.dload(_REG_debug...)
205 }
206
View as plain text