podman

Форк
0
205 строк · 4.7 Кб
1
// +build go1.17,!go1.22
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
}
206

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.