podman

Форк
0
193 строки · 4.5 Кб
1
/*
2
 * Copyright 2021 ByteDance Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package encoder
18

19
import (
20
    `bytes`
21
    `sync`
22
    `unsafe`
23
    `errors`
24
    `reflect`
25

26
    `github.com/bytedance/sonic/internal/caching`
27
    `github.com/bytedance/sonic/option`
28
    `github.com/bytedance/sonic/internal/rt`
29
)
30

31
const (
32
    _MaxStack  = 4096      // 4k states
33

34
    _StackSize = unsafe.Sizeof(_Stack{})
35
)
36

37
var (
38
    bytesPool    = sync.Pool{}
39
    stackPool    = sync.Pool{}
40
    bufferPool   = sync.Pool{}
41
    programCache = caching.CreateProgramCache()
42
)
43

44
type _State struct {
45
    x int
46
    f uint64
47
    p unsafe.Pointer
48
    q unsafe.Pointer
49
}
50

51
type _Stack struct {
52
    sp uint64
53
    sb [_MaxStack]_State
54
}
55

56
type _Encoder func(
57
    rb *[]byte,
58
    vp unsafe.Pointer,
59
    sb *_Stack,
60
    fv uint64,
61
) error
62

63
var _KeepAlive struct {
64
    rb *[]byte
65
    vp unsafe.Pointer
66
    sb *_Stack
67
    fv uint64
68
    err error
69
    frame [_FP_offs]byte
70
}
71

72
var errCallShadow = errors.New("DON'T CALL THIS!")
73

74
// Faker func of _Encoder, used to export its stackmap as _Encoder's
75
func _Encoder_Shadow(rb *[]byte, vp unsafe.Pointer, sb *_Stack, fv uint64) (err error) {
76
    // align to assembler_amd64.go: _FP_offs
77
    var frame [_FP_offs]byte
78

79
    // must keep all args and frames noticeable to GC
80
    _KeepAlive.rb = rb
81
    _KeepAlive.vp = vp
82
    _KeepAlive.sb = sb
83
    _KeepAlive.fv = fv
84
    _KeepAlive.err = err
85
    _KeepAlive.frame = frame
86

87
    return errCallShadow
88
}
89

90
func newBytes() []byte {
91
    if ret := bytesPool.Get(); ret != nil {
92
        return ret.([]byte)
93
    } else {
94
        return make([]byte, 0, option.DefaultEncoderBufferSize)
95
    }
96
}
97

98
func newStack() *_Stack {
99
    if ret := stackPool.Get(); ret == nil {
100
        return new(_Stack)
101
    } else {
102
        return ret.(*_Stack)
103
    }
104
}
105

106
func resetStack(p *_Stack) {
107
    memclrNoHeapPointers(unsafe.Pointer(p), _StackSize)
108
}
109

110
func newBuffer() *bytes.Buffer {
111
    if ret := bufferPool.Get(); ret != nil {
112
        return ret.(*bytes.Buffer)
113
    } else {
114
        return bytes.NewBuffer(make([]byte, 0, option.DefaultEncoderBufferSize))
115
    }
116
}
117

118
func freeBytes(p []byte) {
119
    p = p[:0]
120
    bytesPool.Put(p)
121
}
122

123
func freeStack(p *_Stack) {
124
    p.sp = 0
125
    stackPool.Put(p)
126
}
127

128
func freeBuffer(p *bytes.Buffer) {
129
    p.Reset()
130
    bufferPool.Put(p)
131
}
132

133
func makeEncoder(vt *rt.GoType, ex ...interface{}) (interface{}, error) {
134
    if pp, err := newCompiler().compile(vt.Pack(), ex[0].(bool)); err != nil {
135
        return nil, err
136
    } else {
137
        as := newAssembler(pp)
138
        as.name = vt.String()
139
        return as.Load(), nil
140
    }
141
}
142

143
func findOrCompile(vt *rt.GoType, pv bool) (_Encoder, error) {
144
    if val := programCache.Get(vt); val != nil {
145
        return val.(_Encoder), nil
146
    } else if ret, err := programCache.Compute(vt, makeEncoder, pv); err == nil {
147
        return ret.(_Encoder), nil
148
    } else {
149
        return nil, err
150
    }
151
}
152

153
func pretouchType(_vt reflect.Type, opts option.CompileOptions, v uint8) (map[reflect.Type]uint8, error) {
154
    /* compile function */
155
    compiler := newCompiler().apply(opts)
156
    encoder := func(vt *rt.GoType, ex ...interface{}) (interface{}, error) {
157
        if pp, err := compiler.compile(_vt, ex[0].(bool)); err != nil {
158
            return nil, err
159
        } else {
160
            as := newAssembler(pp)
161
            as.name = vt.String()
162
            return as.Load(), nil
163
        }
164
    }
165

166
    /* find or compile */
167
    vt := rt.UnpackType(_vt)
168
    if val := programCache.Get(vt); val != nil {
169
        return nil, nil
170
    } else if _, err := programCache.Compute(vt, encoder, v == 1); err == nil {
171
        return compiler.rec, nil
172
    } else {
173
        return nil, err
174
    }
175
}
176

177
func pretouchRec(vtm map[reflect.Type]uint8, opts option.CompileOptions) error {
178
    if opts.RecursiveDepth < 0 || len(vtm) == 0 {
179
        return nil
180
    }
181
    next := make(map[reflect.Type]uint8)
182
    for vt, v := range vtm {
183
        sub, err := pretouchType(vt, opts, v)
184
        if err != nil {
185
            return err
186
        }
187
        for svt, v := range sub {
188
            next[svt] = v
189
        }
190
    }
191
    opts.RecursiveDepth -= 1
192
    return pretouchRec(next, opts)
193
}
194

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

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

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

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