github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/internal/decoder/asm_stubs_amd64_go121.go (about) 1 // +build go1.21,!go1.23 2 3 // Copyright 2023 CloudWeGo Authors 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 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 //go:linkname _runtime_writeBarrier runtime.writeBarrier 29 var _runtime_writeBarrier uintptr 30 31 //go:nosplit 32 //go:linkname gcWriteBarrier2 runtime.gcWriteBarrier2 33 func gcWriteBarrier2() 34 35 // Notice: gcWriteBarrier must use R11 register!! 36 var _R11 = _IC 37 38 var ( 39 _V_writeBarrier = jit.Imm(int64(uintptr(unsafe.Pointer(&_runtime_writeBarrier)))) 40 41 _F_gcWriteBarrier2 = jit.Func(gcWriteBarrier2) 42 ) 43 44 func (self *_Assembler) WritePtrAX(i int, rec obj.Addr, saveDI bool) { 45 self.Emit("MOVQ", _V_writeBarrier, _R9) 46 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 47 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 48 if saveDI { 49 self.save(_DI, _R11) 50 } else { 51 self.save(_R11) 52 } 53 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 54 self.Rjmp("CALL", _R11) 55 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 0)) 56 self.Emit("MOVQ", rec, _DI) 57 self.Emit("MOVQ", _DI, jit.Ptr(_R11, 8)) 58 if saveDI { 59 self.load(_DI, _R11) 60 } else { 61 self.load(_R11) 62 } 63 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 64 self.Emit("MOVQ", _AX, rec) 65 } 66 67 func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool, saveAX bool) { 68 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { 69 panic("rec contains AX!") 70 } 71 self.Emit("MOVQ", _V_writeBarrier, _R9) 72 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 73 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 74 if saveAX { 75 self.save(_AX, _R11) 76 } else { 77 self.save(_R11) 78 } 79 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 80 self.Rjmp("CALL", _R11) 81 self.Emit("MOVQ", ptr, jit.Ptr(_R11, 0)) 82 self.Emit("MOVQ", rec, _AX) 83 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 8)) 84 if saveAX { 85 self.load(_AX, _R11) 86 } else { 87 self.load(_R11) 88 } 89 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 90 self.Emit("MOVQ", ptr, rec) 91 } 92 93 func (self *_ValueDecoder) WritePtrAX(i int, rec obj.Addr, saveDI bool) { 94 self.Emit("MOVQ", _V_writeBarrier, _R9) 95 self.Emit("CMPL", jit.Ptr(_R9, 0), jit.Imm(0)) 96 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 97 if saveDI { 98 self.save(_DI, _R11) 99 } else { 100 self.save(_R11) 101 } 102 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 103 self.Rjmp("CALL", _R11) 104 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 0)) 105 self.Emit("MOVQ", rec, _DI) 106 self.Emit("MOVQ", _DI, jit.Ptr(_R11, 8)) 107 if saveDI { 108 self.load(_DI, _R11) 109 } else { 110 self.load(_R11) 111 } 112 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 113 self.Emit("MOVQ", _AX, rec) 114 } 115 116 func (self *_ValueDecoder) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI bool) { 117 if rec.Reg == x86.REG_AX || rec.Index == x86.REG_AX { 118 panic("rec contains AX!") 119 } 120 self.Emit("MOVQ", _V_writeBarrier, _AX) 121 self.Emit("CMPL", jit.Ptr(_AX, 0), jit.Imm(0)) 122 self.Sjmp("JE", "_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 123 self.save(_R11) 124 self.Emit("MOVQ", _F_gcWriteBarrier2, _R11) 125 self.Rjmp("CALL", _R11) 126 self.Emit("MOVQ", ptr, jit.Ptr(_R11, 0)) 127 self.Emit("MOVQ", rec, _AX) 128 self.Emit("MOVQ", _AX, jit.Ptr(_R11, 8)) 129 self.load(_R11) 130 self.Link("_no_writeBarrier" + strconv.Itoa(i) + "_{n}") 131 self.Emit("MOVQ", ptr, rec) 132 }