123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- //go:build go1.17 && !go1.25
- // +build go1.17,!go1.25
- /*
- * Copyright 2021 ByteDance Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package x86
- import (
- "fmt"
- "runtime"
- "strings"
- "unsafe"
- "github.com/bytedance/sonic/internal/encoder/ir"
- "github.com/bytedance/sonic/internal/encoder/vars"
- "github.com/bytedance/sonic/internal/jit"
- "github.com/twitchyliquid64/golang-asm/obj"
- )
- const _FP_debug = 128
- var (
- _Instr_End = ir.NewInsOp(ir.OP_is_nil)
- _F_gc = jit.Func(gc)
- _F_println = jit.Func(println_wrapper)
- _F_print = jit.Func(print)
- )
- func (self *Assembler) dsave(r ...obj.Addr) {
- for i, v := range r {
- if i > _FP_debug/8-1 {
- panic("too many registers to save")
- } else {
- self.Emit("MOVQ", v, jit.Ptr(_SP, _FP_fargs+_FP_saves+_FP_locals+int64(i)*8))
- }
- }
- }
- func (self *Assembler) dload(r ...obj.Addr) {
- for i, v := range r {
- if i > _FP_debug/8-1 {
- panic("too many registers to load")
- } else {
- self.Emit("MOVQ", jit.Ptr(_SP, _FP_fargs+_FP_saves+_FP_locals+int64(i)*8), v)
- }
- }
- }
- func println_wrapper(i int, op1 int, op2 int) {
- println(i, " Intrs ", op1, ir.OpNames[op1], "next: ", op2, ir.OpNames[op2])
- }
- func print(i int) {
- println(i)
- }
- func gc() {
- if !vars.DebugSyncGC {
- return
- }
- runtime.GC()
- // debug.FreeOSMemory()
- }
- func (self *Assembler) dcall(fn obj.Addr) {
- self.Emit("MOVQ", fn, _R10) // MOVQ ${fn}, R10
- self.Rjmp("CALL", _R10) // CALL R10
- }
- func (self *Assembler) debug_gc() {
- if !vars.DebugSyncGC {
- return
- }
- self.dsave(_REG_debug...)
- self.dcall(_F_gc)
- self.dload(_REG_debug...)
- }
- func (self *Assembler) debug_instr(i int, v *ir.Instr) {
- if vars.DebugSyncGC {
- if i+1 == len(self.p) {
- self.print_gc(i, v, &_Instr_End)
- } else {
- next := &(self.p[i+1])
- self.print_gc(i, v, next)
- name := ir.OpNames[next.Op()]
- if strings.Contains(name, "save") {
- return
- }
- }
- // self.debug_gc()
- }
- }
- //go:noescape
- //go:linkname checkptrBase runtime.checkptrBase
- func checkptrBase(p unsafe.Pointer) uintptr
- //go:noescape
- //go:linkname findObject runtime.findObject
- func findObject(p, refBase, refOff uintptr) (base uintptr, s unsafe.Pointer, objIndex uintptr)
- var (
- _F_checkptr = jit.Func(checkptr)
- _F_printptr = jit.Func(printptr)
- )
- var (
- _R10 = jit.Reg("R10")
- )
- var _REG_debug = []obj.Addr{
- jit.Reg("AX"),
- jit.Reg("BX"),
- jit.Reg("CX"),
- jit.Reg("DX"),
- jit.Reg("DI"),
- jit.Reg("SI"),
- jit.Reg("BP"),
- jit.Reg("SP"),
- jit.Reg("R8"),
- jit.Reg("R9"),
- jit.Reg("R10"),
- jit.Reg("R11"),
- jit.Reg("R12"),
- jit.Reg("R13"),
- jit.Reg("R14"),
- jit.Reg("R15"),
- }
- func checkptr(ptr uintptr) {
- if ptr == 0 {
- return
- }
- fmt.Printf("pointer: %x\n", ptr)
- f := checkptrBase(unsafe.Pointer(uintptr(ptr)))
- if f == 0 {
- fmt.Printf("! unknown-based pointer: %x\n", ptr)
- } else if f == 1 {
- fmt.Printf("! stack pointer: %x\n", ptr)
- } else {
- fmt.Printf("base: %x\n", f)
- }
- findobj(ptr)
- }
- func findobj(ptr uintptr) {
- base, s, objIndex := findObject(ptr, 0, 0)
- if s != nil && base == 0 {
- fmt.Printf("! invalid pointer: %x\n", ptr)
- }
- fmt.Printf("objIndex: %d\n", objIndex)
- }
- func (self *Assembler) check_ptr(ptr obj.Addr, lea bool) {
- if !vars.DebugCheckPtr {
- return
- }
- self.dsave(_REG_debug...)
- if lea {
- self.Emit("LEAQ", ptr, _R10)
- } else {
- self.Emit("MOVQ", ptr, _R10)
- }
- self.Emit("MOVQ", _R10, jit.Ptr(_SP, 0))
- self.dcall(_F_checkptr)
- self.dload(_REG_debug...)
- }
- func printptr(i int, ptr uintptr) {
- fmt.Printf("[%d] ptr: %x\n", i, ptr)
- }
- func (self *Assembler) print_ptr(i int, ptr obj.Addr, lea bool) {
- self.dsave(_REG_debug...)
- if lea {
- self.Emit("LEAQ", ptr, _R10)
- } else {
- self.Emit("MOVQ", ptr, _R10)
- }
- self.Emit("MOVQ", jit.Imm(int64(i)), _AX)
- self.Emit("MOVQ", _R10, _BX)
- self.dcall(_F_printptr)
- self.dload(_REG_debug...)
- }
|