github.com/tencent/goom@v1.0.1/internal/bytecode/stub/space_arm64.go (about)

     1  package stub
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/tencent/goom/internal/bytecode"
     8  	"github.com/tencent/goom/internal/bytecode/memory"
     9  	"github.com/tencent/goom/internal/logger"
    10  )
    11  
    12  const spaceLen = 128
    13  
    14  var iCacheHolderAddr uintptr
    15  
    16  // ICachePaddingLeft ClearICache 左侧占位
    17  func ICachePaddingLeft()
    18  
    19  // ClearICache 汇编函数声明: 清理 icache 缓存
    20  func ClearICache()
    21  
    22  func init() {
    23  	iCacheHolderAddr = reflect.ValueOf(ClearICache).Pointer()
    24  	// 兼容 go 1.17(1.17以上会对 assembler 函数进行 wrap, 需要找到其内部的调用)
    25  	innerAddr, err := bytecode.GetInnerFunc(64, iCacheHolderAddr)
    26  	if innerAddr > 0 && err == nil {
    27  		iCacheHolderAddr = innerAddr
    28  	}
    29  	offset := reflect.ValueOf(ICachePaddingLeft).Pointer()
    30  	logger.Debugf("icache func init success: %x", offset)
    31  }
    32  
    33  // WriteICacheFn 写入 icache clear 函数数据
    34  func WriteICacheFn(data []byte) (uintptr, error) {
    35  	s, err := acquireICacheFn()
    36  	if err != nil {
    37  		return 0, err
    38  	}
    39  	switch s.typ {
    40  	case TypeMMap:
    41  		copy(*s.Space, data[:])
    42  		return s.Addr, nil
    43  	case TypeHolder:
    44  		return s.Addr, memory.WriteToNoFlushNoLock(s.Addr, data)
    45  	default:
    46  		return 0, fmt.Errorf("ICacheFn write fail, illegal type: %d", s.typ)
    47  	}
    48  }
    49  
    50  // acquireICacheFn 获取 icache 执行空间
    51  func acquireICacheFn() (*Space, error) {
    52  	if addr, space, err := acquireFromMMap(spaceLen); err == nil {
    53  		return &Space{
    54  			Addr:  addr,
    55  			Space: space,
    56  			typ:   TypeMMap,
    57  		}, nil
    58  	}
    59  
    60  	return &Space{
    61  		Addr:  iCacheHolderAddr,
    62  		Space: nil,
    63  		typ:   TypeHolder,
    64  	}, nil
    65  }