debug_go117.go 4.2 KB

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