summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go')
-rw-r--r--vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go181
1 files changed, 181 insertions, 0 deletions
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go b/vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go
new file mode 100644
index 000000000..84ed9a95f
--- /dev/null
+++ b/vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go
@@ -0,0 +1,181 @@
+/**
+ * Copyright 2023 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 rt
+
+import (
+ `fmt`
+ `strings`
+ `unsafe`
+
+)
+
+type Bitmap struct {
+ N int
+ B []byte
+}
+
+func (self *Bitmap) grow() {
+ if self.N >= len(self.B) * 8 {
+ self.B = append(self.B, 0)
+ }
+}
+
+func (self *Bitmap) mark(i int, bv int) {
+ if bv != 0 {
+ self.B[i / 8] |= 1 << (i % 8)
+ } else {
+ self.B[i / 8] &^= 1 << (i % 8)
+ }
+}
+
+func (self *Bitmap) Set(i int, bv int) {
+ if i >= self.N {
+ panic("bitmap: invalid bit position")
+ } else {
+ self.mark(i, bv)
+ }
+}
+
+func (self *Bitmap) Append(bv int) {
+ self.grow()
+ self.mark(self.N, bv)
+ self.N++
+}
+
+func (self *Bitmap) AppendMany(n int, bv int) {
+ for i := 0; i < n; i++ {
+ self.Append(bv)
+ }
+}
+
+// var (
+// _stackMapLock = sync.Mutex{}
+// _stackMapCache = make(map[*StackMap]struct{})
+// )
+
+type BitVec struct {
+ N uintptr
+ B unsafe.Pointer
+}
+
+func (self BitVec) Bit(i uintptr) byte {
+ return (*(*byte)(unsafe.Pointer(uintptr(self.B) + i / 8)) >> (i % 8)) & 1
+}
+
+func (self BitVec) String() string {
+ var i uintptr
+ var v []string
+
+ /* add each bit */
+ for i = 0; i < self.N; i++ {
+ v = append(v, fmt.Sprintf("%d", self.Bit(i)))
+ }
+
+ /* join them together */
+ return fmt.Sprintf(
+ "BitVec { %s }",
+ strings.Join(v, ", "),
+ )
+}
+
+type StackMap struct {
+ N int32
+ L int32
+ B [1]byte
+}
+
+// func (self *StackMap) add() {
+// _stackMapLock.Lock()
+// _stackMapCache[self] = struct{}{}
+// _stackMapLock.Unlock()
+// }
+
+func (self *StackMap) Pin() uintptr {
+ // self.add()
+ return uintptr(unsafe.Pointer(self))
+}
+
+func (self *StackMap) Get(i int32) BitVec {
+ return BitVec {
+ N: uintptr(self.L),
+ B: unsafe.Pointer(uintptr(unsafe.Pointer(&self.B)) + uintptr(i * ((self.L + 7) >> 3))),
+ }
+}
+
+func (self *StackMap) String() string {
+ sb := strings.Builder{}
+ sb.WriteString("StackMap {")
+
+ /* dump every stack map */
+ for i := int32(0); i < self.N; i++ {
+ sb.WriteRune('\n')
+ sb.WriteString(" " + self.Get(i).String())
+ }
+
+ /* close the stackmap */
+ sb.WriteString("\n}")
+ return sb.String()
+}
+
+func (self *StackMap) MarshalBinary() ([]byte, error) {
+ size := int(self.N) * int(self.L) + int(unsafe.Sizeof(self.L)) + int(unsafe.Sizeof(self.N))
+ return BytesFrom(unsafe.Pointer(self), size, size), nil
+}
+
+var (
+ byteType = UnpackEface(byte(0)).Type
+)
+
+const (
+ _StackMapSize = unsafe.Sizeof(StackMap{})
+)
+
+//go:linkname mallocgc runtime.mallocgc
+//goland:noinspection GoUnusedParameter
+func mallocgc(nb uintptr, vt *GoType, zero bool) unsafe.Pointer
+
+type StackMapBuilder struct {
+ b Bitmap
+}
+
+//go:nocheckptr
+func (self *StackMapBuilder) Build() (p *StackMap) {
+ nb := len(self.b.B)
+ bm := mallocgc(_StackMapSize + uintptr(nb) - 1, byteType, false)
+
+ /* initialize as 1 bitmap of N bits */
+ p = (*StackMap)(bm)
+ p.N, p.L = 1, int32(self.b.N)
+ copy(BytesFrom(unsafe.Pointer(&p.B), nb, nb), self.b.B)
+ return
+}
+
+func (self *StackMapBuilder) AddField(ptr bool) {
+ if ptr {
+ self.b.Append(1)
+ } else {
+ self.b.Append(0)
+ }
+}
+
+func (self *StackMapBuilder) AddFields(n int, ptr bool) {
+ if ptr {
+ self.b.AppendMany(n, 1)
+ } else {
+ self.b.AppendMany(n, 0)
+ }
+} \ No newline at end of file