github.com/tencent/goom@v1.0.1/internal/bytecode/memory/icache_arm64.go (about) 1 package memory 2 3 import ( 4 "reflect" 5 "unsafe" 6 7 "github.com/tencent/goom/internal/logger" 8 "github.com/tencent/goom/internal/unexports" 9 ) 10 11 // 指令生成相关 12 // nolint 13 const ( 14 _0b1 = 1 // 0b1 15 _0b10 = 2 // 0b10 16 _0b11 = 3 // 0b11 17 _0b100101 = 37 // 0b100101 18 _X0 = 0 // X0 寄存器 19 _X1 = 1 // X1 寄存器 20 ) 21 22 // cacheSize 需要失效的缓存长度, 一般情况不会超过这个数 23 const cacheSize = 2 * 1024 24 25 // clearFuncCache 缓存已经生成的函数 26 var clearFuncCache func(uintptr) 27 28 // ClearICache 清除指令缓存 29 func ClearICache(addr uintptr) { 30 if clearFuncCache != nil { 31 clearFuncCache(addr) 32 return 33 } 34 if ok := initClearICacheFunc(); !ok { 35 return 36 } 37 clearFuncCache(addr) 38 } 39 40 // initClearICacheFunc 初始化 clearFuncCache 41 func initClearICacheFunc() bool { 42 f, err := makeFunc() 43 if err != nil { 44 clearFuncCache = func(uintptr) {} 45 logger.Warningf("ClearICache failed: %v", err) 46 return false 47 } 48 clearFuncCache = f 49 return true 50 } 51 52 // makeFunc 构造 clearICacheIns 的函数实例 53 func makeFunc() (func(uintptr), error) { 54 code := make([]byte, 0, 256) 55 code = append(code, insPadding...) 56 code = append(code, movAddr(_X1, uintptr(cacheSize))...) 57 code = append(code, clearICacheIns...) 58 code = append(code, clearICacheIns1...) 59 code = append(code, clearICacheIns2...) 60 61 var ( 62 addr uintptr 63 err error 64 ) 65 if addr, err = WriteICacheFn(code); err != nil { 66 return nil, err 67 } 68 var f func(uintptr) 69 fn := unexports.NewFuncWithCodePtr(reflect.TypeOf(f), addr).Interface() 70 return (fn).(func(uintptr)), nil 71 } 72 73 // WriteICacheFn 写入 icache clear 函数数据 74 // 75 //go:linkname WriteICacheFn github.com/tencent/goom/internal/bytecode/stub.WriteICacheFn 76 func WriteICacheFn([]byte) (uintptr, error) 77 78 // movAddr 生成 mov x[?] [addr] 四个指令 79 func movAddr(r uint32, addr uintptr) (value []byte) { 80 res := make([]byte, 0, 24) 81 d0d1 := addr & 0xFFFF 82 d2d3 := addr >> 16 & 0xFFFF 83 d4d5 := addr >> 32 & 0xFFFF 84 d6d7 := addr >> 48 & 0xFFFF 85 86 res = append(res, movImm(r, _0b10, 0, d0d1)...) // MOVZ x0, double[16:0] 87 res = append(res, movImm(r, _0b11, 1, d2d3)...) // MOVK x0, double[32:16] 88 res = append(res, movImm(r, _0b11, 2, d4d5)...) // MOVK x0, double[48:32] 89 res = append(res, movImm(r, _0b11, 3, d6d7)...) // MOVK x0, double[64:48] 90 return res 91 } 92 93 // movImm 动态生成 mov 指令 94 // r 寄存器 X0~x27 95 // opc 操作数, MOVZ/MOVK 96 // shift 寄存器高低位段 97 // val 值数据 98 func movImm(r uint32, opc, shift int, val uintptr) []byte { 99 var m uint32 = r // rd 100 m |= uint32(val) << 5 // imm16 101 m |= uint32(shift&3) << 21 // hw 102 m |= _0b100101 << 23 // const 103 m |= uint32(opc&0x3) << 29 // opc 104 m |= _0b1 << 31 // sf 105 res := make([]byte, 4) 106 *(*uint32)(unsafe.Pointer(&res[0])) = m 107 return res 108 }