stack.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * Copyright 2024 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. package vars
  17. import (
  18. "bytes"
  19. "sync"
  20. "unsafe"
  21. "github.com/bytedance/sonic/internal/caching"
  22. "github.com/bytedance/sonic/internal/rt"
  23. "github.com/bytedance/sonic/option"
  24. )
  25. type State struct {
  26. x int
  27. f uint64
  28. p unsafe.Pointer
  29. q unsafe.Pointer
  30. }
  31. type Stack struct {
  32. sp uintptr
  33. sb [MaxStack]State
  34. }
  35. var (
  36. bytesPool = sync.Pool{}
  37. stackPool = sync.Pool{
  38. New: func() interface{} {
  39. return &Stack{}
  40. },
  41. }
  42. bufferPool = sync.Pool{}
  43. programCache = caching.CreateProgramCache()
  44. )
  45. func NewBytes() *[]byte {
  46. if ret := bytesPool.Get(); ret != nil {
  47. return ret.(*[]byte)
  48. } else {
  49. ret := make([]byte, 0, option.DefaultEncoderBufferSize)
  50. return &ret
  51. }
  52. }
  53. func NewStack() *Stack {
  54. ret := stackPool.Get().(*Stack)
  55. ret.sp = 0
  56. return ret
  57. }
  58. func ResetStack(p *Stack) {
  59. rt.MemclrNoHeapPointers(unsafe.Pointer(p), StackSize)
  60. }
  61. func (s *Stack) Top() *State {
  62. return (*State)(rt.Add(unsafe.Pointer(&s.sb[0]), s.sp))
  63. }
  64. func (s *Stack) Cur() *State {
  65. return (*State)(rt.Add(unsafe.Pointer(&s.sb[0]), s.sp - uintptr(StateSize)))
  66. }
  67. const _MaxStackSP = uintptr(MaxStack * StateSize)
  68. func (s *Stack) Push(v State) bool {
  69. if uintptr(s.sp) >= _MaxStackSP {
  70. return false
  71. }
  72. st := s.Top()
  73. *st = v
  74. s.sp += uintptr(StateSize)
  75. return true
  76. }
  77. func (s *Stack) Pop() State {
  78. s.sp -= uintptr(StateSize)
  79. st := s.Top()
  80. ret := *st
  81. *st = State{}
  82. return ret
  83. }
  84. func (s *Stack) Load() (int, uint64, unsafe.Pointer, unsafe.Pointer) {
  85. st := s.Cur()
  86. return st.x, st.f, st.p, st.q
  87. }
  88. func (s *Stack) Save(x int, f uint64, p unsafe.Pointer, q unsafe.Pointer) bool {
  89. return s.Push(State{x: x, f:f, p: p, q: q})
  90. }
  91. func (s *Stack) Drop() (int, uint64, unsafe.Pointer, unsafe.Pointer) {
  92. st := s.Pop()
  93. return st.x, st.f, st.p, st.q
  94. }
  95. func NewBuffer() *bytes.Buffer {
  96. if ret := bufferPool.Get(); ret != nil {
  97. return ret.(*bytes.Buffer)
  98. } else {
  99. return bytes.NewBuffer(make([]byte, 0, option.DefaultEncoderBufferSize))
  100. }
  101. }
  102. func FreeBytes(p *[]byte) {
  103. if rt.CanSizeResue(cap(*p)) {
  104. (*p) = (*p)[:0]
  105. bytesPool.Put(p)
  106. }
  107. }
  108. func FreeStack(p *Stack) {
  109. p.sp = 0
  110. stackPool.Put(p)
  111. }
  112. func FreeBuffer(p *bytes.Buffer) {
  113. if rt.CanSizeResue(cap(p.Bytes())) {
  114. p.Reset()
  115. bufferPool.Put(p)
  116. }
  117. }
  118. var (
  119. ArgPtrs = []bool{true, true, true, false}
  120. LocalPtrs = []bool{}
  121. ArgPtrs_generic = []bool{true}
  122. LocalPtrs_generic = []bool{}
  123. )