1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package decoder
18
19 import (
20 `strconv`
21 `unsafe`
22
23 `github.com/bytedance/sonic/internal/jit`
24 `github.com/twitchyliquid64/golang-asm/obj`
25 `github.com/twitchyliquid64/golang-asm/obj/x86`
26 )
27
28
29 var _runtime_writeBarrier uintptr
30
31
32 func gcWriteBarrierAX()
33
34 var (
35 _V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier))))
36
37 _F_gcWriteBarrierAX = jit.Func(gcWriteBarrierAX)
38 )
39
40 func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) {
41 self.Emit("MOVQ", _V_writeBarrier, _R9)
42 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0))
43 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
44 if saveDI {
45 self.save(_DI)
46 }
47 self.Emit("LEAQ", rec, _DI)
48 self.call(_F_gcWriteBarrierAX)
49 if saveDI {
50 self.load(_DI)
51 }
52 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
53 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
54 self.Emit("MOVQ", _AX, rec)
55 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
56 }
57
58 func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) {
59 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
60 panic("rec contains AX!")
61 }
62 self.Emit("MOVQ", _V_writeBarrier, _R9)
63 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0))
64 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
65 if saveAX {
66 self.Emit("XCHGQ", ptr, _AX)
67 } else {
68 self.Emit("MOVQ", ptr, _AX)
69 }
70 if saveDI {
71 self.save(_DI)
72 }
73 self.Emit("LEAQ", rec, _DI)
74 self.call(_F_gcWriteBarrierAX)
75 if saveDI {
76 self.load(_DI)
77 }
78 if saveAX {
79 self.Emit("XCHGQ", ptr, _AX)
80 }
81 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
82 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
83 self.Emit("MOVQ", ptr, rec)
84 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
85 }
86
87
88 func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) {
89 self.Emit("MOVQ", _V_writeBarrier, _R9)
90 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0))
91 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
92 if saveDI {
93 self.save(_DI)
94 }
95 self.Emit("LEAQ", rec, _DI)
96 self.call(_F_gcWriteBarrierAX)
97 if saveDI {
98 self.load(_DI)
99 }
100 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
101 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
102 self.Emit("MOVQ", _AX, rec)
103 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
104 }
105
106 func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) {
107 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
108 panic("rec contains AX!")
109 }
110 self.Emit("MOVQ", _V_writeBarrier, _AX)
111 self.Emit("CMPL", jit.Ptr(_AX, 0), jit.Imm(0))
112 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
113 self.Emit("MOVQ", ptr, _AX)
114 if saveDI {
115 self.save(_DI)
116 }
117 self.Emit("LEAQ", rec, _DI)
118 self.call(_F_gcWriteBarrierAX)
119 if saveDI {
120 self.load(_DI)
121 }
122 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
123 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
124 self.Emit("MOVQ", ptr, rec)
125 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
126 }
127
View as plain text