github.com/cloudwego/frugal@v0.1.15/internal/atm/rtx/memzero_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 rtx
    18  
    19  import (
    20      `fmt`
    21      `unsafe`
    22  
    23      `github.com/cloudwego/iasm/x86_64`
    24      `github.com/cloudwego/frugal/internal/loader`
    25      `github.com/cloudwego/frugal/internal/rt`
    26  )
    27  
    28  const (
    29      ZeroStep    = 16
    30      MaxZeroSize = 65536
    31  )
    32  
    33  func toaddr(p *x86_64.Label) uintptr {
    34      if v, err := p.Evaluate(); err != nil {
    35          panic(err)
    36      } else {
    37          return uintptr(v)
    38      }
    39  }
    40  
    41  func asmmemzero() MemZeroFn {
    42      p := x86_64.DefaultArch.CreateProgram()
    43      x := make([]*x86_64.Label, MaxZeroSize / ZeroStep + 1)
    44  
    45      /* create all the labels */
    46      for i := range x {
    47          x[i] = x86_64.CreateLabel(fmt.Sprintf("zero_%d", i * ZeroStep))
    48      }
    49  
    50      /* fill backwards */
    51      for n := MaxZeroSize; n >= ZeroStep; n -= ZeroStep {
    52          p.Link(x[n / ZeroStep])
    53          p.MOVDQU(x86_64.XMM15, x86_64.Ptr(x86_64.RDI, int32(n - ZeroStep)))
    54      }
    55  
    56      /* finish the function */
    57      p.Link(x[0])
    58      p.RET()
    59  
    60      /* assemble the function */
    61      c := p.Assemble(0)
    62      r := make([]uintptr, len(x))
    63  
    64      /* resolve all the labels */
    65      for i, v := range x {
    66          r[i] = toaddr(v)
    67      }
    68  
    69      /* load the function */
    70      defer p.Free()
    71      return MemZeroFn {
    72          Sz: r,
    73          Fn: *(*unsafe.Pointer)(loader.Loader(c).Load("_frugal_memzero", rt.Frame{})),
    74      }
    75  }