Skip to content

Commit

Permalink
Bring static pointers back to the static table
Browse files Browse the repository at this point in the history
  • Loading branch information
pelletier committed Sep 20, 2023
1 parent e1dfb73 commit d280bc6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
7 changes: 7 additions & 0 deletions internal/serde/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ func serializePointedAt(s *Serializer, t reflect.Type, p unsafe.Pointer) {
return
}

if static(p) {
serializeVarint(s, -1)
off := staticOffset(p)
serializeVarint(s, off)
return
}

id, new := s.assignPointerID(p)
serializeVarint(s, int(id))
if !new {
Expand Down
9 changes: 9 additions & 0 deletions internal/serde/serde.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ func newDeserializer(b []byte) *Deserializer {
func (d *Deserializer) readPtr() (unsafe.Pointer, sID) {
x, n := binary.Varint(d.b)
d.b = d.b[n:]

// pointer into static uint64 table
if x == -1 {
x, n = binary.Varint(d.b)
d.b = d.b[n:]
p := staticPointer(int(x))
return p, 0
}

i := sID(x)
p := d.ptrs[i]
return p, i
Expand Down
20 changes: 20 additions & 0 deletions internal/serde/unsafe.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,23 @@ func inlined(t reflect.Type) bool {
return false
}
}

var staticuint64s unsafe.Pointer

func init() {
zero := 0
var x interface{} = zero
staticuint64s = (*iface)(unsafe.Pointer(&x)).ptr
}

func static(p unsafe.Pointer) bool {
return uintptr(p) >= uintptr(staticuint64s) && uintptr(p) < uintptr(staticuint64s)+256
}

func staticOffset(p unsafe.Pointer) int {
return int(uintptr(p) - uintptr(staticuint64s))
}

func staticPointer(offset int) unsafe.Pointer {
return unsafe.Add(staticuint64s, offset)
}
10 changes: 10 additions & 0 deletions serde/serde_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ func TestReflect(t *testing.T) {
})
}

func TestInt257(t *testing.T) {
one := 1
x := []any{
true,
one,
}
serde.RegisterType[[]any]()
assertRoundTrip(t, x)
}

func TestReflectCustom(t *testing.T) {
ser := func(s *serde.Serializer, x *int) error {
str := strconv.Itoa(*x)
Expand Down

0 comments on commit d280bc6

Please sign in to comment.