github.com/cloudwego/frugal@v0.1.15/internal/atm/pgen/pgen_gcwb_go116_120_amd64.go (about)

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