mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-01-23 14:50:21 +00:00
146 lines
2.9 KiB
Go
146 lines
2.9 KiB
Go
|
/**
|
||
|
* Copyright 2024 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 vars
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"sync"
|
||
|
"unsafe"
|
||
|
|
||
|
"github.com/bytedance/sonic/internal/caching"
|
||
|
"github.com/bytedance/sonic/internal/rt"
|
||
|
"github.com/bytedance/sonic/option"
|
||
|
)
|
||
|
|
||
|
type State struct {
|
||
|
x int
|
||
|
f uint64
|
||
|
p unsafe.Pointer
|
||
|
q unsafe.Pointer
|
||
|
}
|
||
|
|
||
|
type Stack struct {
|
||
|
sp uintptr
|
||
|
sb [MaxStack]State
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
bytesPool = sync.Pool{}
|
||
|
stackPool = sync.Pool{
|
||
|
New: func() interface{} {
|
||
|
return &Stack{}
|
||
|
},
|
||
|
}
|
||
|
bufferPool = sync.Pool{}
|
||
|
programCache = caching.CreateProgramCache()
|
||
|
)
|
||
|
|
||
|
func NewBytes() *[]byte {
|
||
|
if ret := bytesPool.Get(); ret != nil {
|
||
|
return ret.(*[]byte)
|
||
|
} else {
|
||
|
ret := make([]byte, 0, option.DefaultEncoderBufferSize)
|
||
|
return &ret
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func NewStack() *Stack {
|
||
|
ret := stackPool.Get().(*Stack)
|
||
|
ret.sp = 0
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func ResetStack(p *Stack) {
|
||
|
rt.MemclrNoHeapPointers(unsafe.Pointer(p), StackSize)
|
||
|
}
|
||
|
|
||
|
func (s *Stack) Top() *State {
|
||
|
return (*State)(rt.Add(unsafe.Pointer(&s.sb[0]), s.sp))
|
||
|
}
|
||
|
|
||
|
func (s *Stack) Cur() *State {
|
||
|
return (*State)(rt.Add(unsafe.Pointer(&s.sb[0]), s.sp - uintptr(StateSize)))
|
||
|
}
|
||
|
|
||
|
const _MaxStackSP = uintptr(MaxStack * StateSize)
|
||
|
|
||
|
func (s *Stack) Push(v State) bool {
|
||
|
if uintptr(s.sp) >= _MaxStackSP {
|
||
|
return false
|
||
|
}
|
||
|
st := s.Top()
|
||
|
*st = v
|
||
|
s.sp += uintptr(StateSize)
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func (s *Stack) Pop() State {
|
||
|
s.sp -= uintptr(StateSize)
|
||
|
st := s.Top()
|
||
|
ret := *st
|
||
|
*st = State{}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func (s *Stack) Load() (int, uint64, unsafe.Pointer, unsafe.Pointer) {
|
||
|
st := s.Cur()
|
||
|
return st.x, st.f, st.p, st.q
|
||
|
}
|
||
|
|
||
|
func (s *Stack) Save(x int, f uint64, p unsafe.Pointer, q unsafe.Pointer) bool {
|
||
|
return s.Push(State{x: x, f:f, p: p, q: q})
|
||
|
}
|
||
|
|
||
|
func (s *Stack) Drop() (int, uint64, unsafe.Pointer, unsafe.Pointer) {
|
||
|
st := s.Pop()
|
||
|
return st.x, st.f, st.p, st.q
|
||
|
}
|
||
|
|
||
|
func NewBuffer() *bytes.Buffer {
|
||
|
if ret := bufferPool.Get(); ret != nil {
|
||
|
return ret.(*bytes.Buffer)
|
||
|
} else {
|
||
|
return bytes.NewBuffer(make([]byte, 0, option.DefaultEncoderBufferSize))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func FreeBytes(p *[]byte) {
|
||
|
if rt.CanSizeResue(cap(*p)) {
|
||
|
(*p) = (*p)[:0]
|
||
|
bytesPool.Put(p)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func FreeStack(p *Stack) {
|
||
|
p.sp = 0
|
||
|
stackPool.Put(p)
|
||
|
}
|
||
|
|
||
|
func FreeBuffer(p *bytes.Buffer) {
|
||
|
if rt.CanSizeResue(cap(p.Bytes())) {
|
||
|
p.Reset()
|
||
|
bufferPool.Put(p)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
ArgPtrs = []bool{true, true, true, false}
|
||
|
LocalPtrs = []bool{}
|
||
|
|
||
|
ArgPtrs_generic = []bool{true}
|
||
|
LocalPtrs_generic = []bool{}
|
||
|
)
|