github.com/cloudwego/frugal@v0.1.7/internal/atm/pgen/pgen_gcwb_amd64.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package pgen 18 19 import ( 20 `github.com/chenzhuoyu/iasm/x86_64` 21 `github.com/cloudwego/frugal/internal/atm/hir` 22 `github.com/cloudwego/frugal/internal/atm/rtx` 23 ) 24 25 func (self *CodeGen) wbStorePointer(p *x86_64.Program, s hir.PointerRegister, d *x86_64.MemoryOperand) { 26 wb := x86_64.CreateLabel("_wb_store") 27 rt := x86_64.CreateLabel("_wb_return") 28 29 /* check for write barrier */ 30 p.MOVQ (uintptr(rtx.V_pWriteBarrier), RAX) 31 p.CMPB (0, Ptr(RAX, 0)) 32 p.JNE (wb) 33 34 /* check for storing nil */ 35 if s == hir.Pn { 36 p.MOVQ(0, d) 37 } else { 38 p.MOVQ(self.r(s), d) 39 } 40 41 /* set source pointer */ 42 wbSetSrc := func() { 43 if s == hir.Pn { 44 p.XORL(EAX, EAX) 45 } else { 46 p.MOVQ(self.r(s), RAX) 47 } 48 } 49 50 /* set target slot pointer */ 51 wbSetSlot := func() { 52 if !isSimpleMem(d) { 53 p.LEAQ(d.Retain(), RDI) 54 } else { 55 p.MOVQ(d.Addr.Memory.Base, RDI) 56 } 57 } 58 59 /* write barrier wrapper */ 60 wbStoreFn := func(p *x86_64.Program) { 61 wbSetSrc () 62 wbSetSlot () 63 self.abiSpillReserved (p) 64 self.abiLoadReserved (p) 65 p.MOVQ (uintptr(rtx.F_gcWriteBarrier), RSI) 66 p.CALLQ (RSI) 67 self.abiSaveReserved (p) 68 self.abiRestoreReserved (p) 69 p.JMP (rt) 70 } 71 72 /* defer the call to the end of generated code */ 73 p.Link(rt) 74 self.later(wb, wbStoreFn) 75 }