gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

debug_go117.go (4814B)


      1 // +build go1.17,!go1.21
      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 }