github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/internal/encoder/debug_go117.go (about)

     1  // +build go1.17,!go1.23
     2  
     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  
    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      // debug.FreeOSMemory()
    82  }
    83  
    84  func (self *_Assembler) dcall(fn obj.Addr) {
    85      self.Emit("MOVQ", fn, _R10)  // MOVQ ${fn}, R10
    86      self.Rjmp("CALL", _R10)       // 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          // self.debug_gc()
   111      }
   112  }
   113  
   114  //go:noescape
   115  //go:linkname checkptrBase runtime.checkptrBase
   116  func checkptrBase(p unsafe.Pointer) uintptr
   117  
   118  //go:noescape
   119  //go:linkname findObject runtime.findObject
   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  }