debug_go117.go 4.7 KB

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