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  }