...
1
2
3
4
19
20 package decoder
21
22 import (
23 `runtime`
24 `testing`
25 `time`
26 `unsafe`
27
28 `github.com/bytedance/sonic/internal/rt`
29 )
30
31 var referred = false
32
33 func TestStringReferring(t *testing.T) {
34 str := []byte(`{"A":"0","B":"1"}`)
35 sp := *(**byte)(unsafe.Pointer(&str))
36 println("malloc *byte ", sp)
37 runtime.SetFinalizer(sp, func(sp *byte){
38 referred = false
39 println("*byte ", sp, " got free 1")
40 })
41 runtime.GC()
42 println("first GC")
43 var obj struct{
44 A string
45 B string
46 }
47 dc := NewDecoder(rt.Mem2Str(str))
48 dc.CopyString()
49 referred = true
50 if err := dc.Decode(&obj); err != nil {
51 t.Fatal(err)
52 }
53 runtime.GC()
54 println("second GC")
55 time.Sleep(time.Millisecond)
56 if referred {
57 t.Fatal("*byte is being referred")
58 }
59
60 str2 := []byte(`{"A":"0","B":"1"}`)
61 sp2 := *(**byte)(unsafe.Pointer(&str2))
62 println("malloc *byte ", sp2)
63 runtime.SetFinalizer(sp2, func(sp *byte){
64 referred = false
65 println("*byte ", sp, " got free")
66 })
67 runtime.GC()
68 println("first GC")
69 var obj2 interface{}
70 dc2 := NewDecoder(rt.Mem2Str(str2))
71 dc2.UseNumber()
72 dc2.CopyString()
73 referred = true
74 if err := dc2.Decode(&obj2); err != nil {
75 t.Fatal(err)
76 }
77 runtime.GC()
78 println("second GC")
79 time.Sleep(time.Millisecond)
80 if referred {
81 t.Fatal("*byte is being referred")
82 }
83
84 runtime.KeepAlive(&obj)
85 runtime.KeepAlive(&obj2)
86 }
87
88 func TestDecoderErrorStackOverflower(t *testing.T) {
89 src := `{"a":[]}`
90 N := _MaxStack
91 for i:=0; i<N; i++ {
92 var obj map[string]string
93 err := NewDecoder(src).Decode(&obj)
94 if err == nil {
95 t.Fatal(err)
96 }
97 }
98 }
View as plain text