diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/internal/encoder/vars/stack.go')
-rw-r--r-- | vendor/github.com/bytedance/sonic/internal/encoder/vars/stack.go | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/github.com/bytedance/sonic/internal/encoder/vars/stack.go b/vendor/github.com/bytedance/sonic/internal/encoder/vars/stack.go new file mode 100644 index 000000000..28a630b40 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/internal/encoder/vars/stack.go @@ -0,0 +1,146 @@ +/** + * 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{} +)
\ No newline at end of file |