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/bytedance/sonic/internal/rt`
25 `github.com/twitchyliquid64/golang-asm/obj`
26 `github.com/twitchyliquid64/golang-asm/obj/x86`
27 )
28
29 var _runtime_writeBarrier uintptr = rt.GcwbAddr()
30
31
32 func gcWriteBarrierAX()
33
34 var (
35 _V_writeBarrier = jit.Imm(int64(_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, _R10)
42 self.Emit("CMPL", jit.Ptr(_R10, 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.Emit("MOVQ", _F_gcWriteBarrierAX, _R10)
49 self.Rjmp("CALL", _R10)
50 if saveDI {
51 self.load(_DI)
52 }
53 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
54 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
55 self.Emit("MOVQ", _AX, rec)
56 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
57 }
58
59 func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) {
60 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
61 panic("rec contains AX!")
62 }
63 self.Emit("MOVQ", _V_writeBarrier, _R10)
64 self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
65 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
66 if saveAX {
67 self.Emit("XCHGQ", ptr, _AX)
68 } else {
69 self.Emit("MOVQ", ptr, _AX)
70 }
71 if saveDI {
72 self.save(_DI)
73 }
74 self.Emit("LEAQ", rec, _DI)
75 self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10)
76 self.Rjmp("CALL", _R10)
77 if saveDI {
78 self.load(_DI)
79 }
80 if saveAX {
81 self.Emit("XCHGQ", ptr, _AX)
82 }
83 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
84 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
85 self.Emit("MOVQ", ptr, rec)
86 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
87 }
88
89
90 func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) {
91 self.Emit("MOVQ", _V_writeBarrier, _R10)
92 self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
93 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
94 if saveDI {
95 self.save(_DI)
96 }
97 self.Emit("LEAQ", rec, _DI)
98 self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10)
99 self.Rjmp("CALL", _R10)
100 if saveDI {
101 self.load(_DI)
102 }
103 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
104 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
105 self.Emit("MOVQ", _AX, rec)
106 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
107 }
108
109 func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) {
110 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX {
111 panic("rec contains AX!")
112 }
113 self.Emit("MOVQ", _V_writeBarrier, _R10)
114 self.Emit("CMPL", jit.Ptr(_R10, 0), jit.Imm(0))
115 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
116 self.Emit("MOVQ", ptr, _AX)
117 if saveDI {
118 self.save(_DI)
119 }
120 self.Emit("LEAQ", rec, _DI)
121 self.Emit("MOVQ", _F_gcWriteBarrierAX, _R10)
122 self.Rjmp("CALL", _R10)
123 if saveDI {
124 self.load(_DI)
125 }
126 self.Sjmp("JMP", "_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
127 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}")
128 self.Emit("MOVQ", ptr, rec)
129 self.Link("_end_writeBarrier" + strconv.Itoa(i) + "_{n}")
130 }
131
View as plain text