gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

gcwb.go (3082B)


      1 /*
      2  * Copyright 2021 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 rt
     18 
     19 import (
     20     `os`
     21     `sync/atomic`
     22     `unsafe`
     23 
     24     `golang.org/x/arch/x86/x86asm`
     25 )
     26 
     27 const (
     28     _MaxInstr = 15
     29 )
     30 
     31 func isvar(arg x86asm.Arg) bool {
     32     v, ok := arg.(x86asm.Mem)
     33     return ok && v.Base == x86asm.RIP
     34 }
     35 
     36 func iszero(arg x86asm.Arg) bool {
     37     v, ok := arg.(x86asm.Imm)
     38     return ok && v == 0
     39 }
     40 
     41 func GcwbAddr() uintptr {
     42     var err error
     43     var off uintptr
     44     var ins x86asm.Inst
     45 
     46     /* get the function address */
     47     pc := uintptr(0)
     48     fp := FuncAddr(atomic.StorePointer)
     49 
     50     /* search within the first 16 instructions */
     51     for i := 0; i < 16; i++ {
     52         mem := unsafe.Pointer(uintptr(fp) + pc)
     53         buf := BytesFrom(mem, _MaxInstr, _MaxInstr)
     54 
     55         /* disassemble the instruction */
     56         if ins, err = x86asm.Decode(buf, 64); err != nil {
     57             panic("gcwbaddr: " + err.Error())
     58         }
     59 
     60         /* check for a byte comparison with zero */
     61         if ins.Op == x86asm.CMP && ins.MemBytes == 1 && isvar(ins.Args[0]) && iszero(ins.Args[1]) {
     62             off = pc + uintptr(ins.Len) + uintptr(ins.Args[0].(x86asm.Mem).Disp)
     63             break
     64         }
     65 
     66         /* move to next instruction */
     67         nb := ins.Len
     68         pc += uintptr(nb)
     69     }
     70 
     71     /* check for address */
     72     if off == 0 {
     73         panic("gcwbaddr: could not locate the variable `writeBarrier`")
     74     } else {
     75         return uintptr(fp) + off
     76     }
     77 }
     78 
     79 // StopProfiling is used to stop traceback introduced by SIGPROF while native code is running.
     80 // WARN: this option is only a workaround for traceback issue (https://github.com/bytedance/sonic/issues/310),
     81 // and will be dropped when the issue is fixed.
     82 var StopProfiling = os.Getenv("SONIC_STOP_PROFILING") != ""
     83 
     84 // WARN: must be aligned with runtime.Prof
     85 // type Prof struct {
     86 //     signalLock uint32
     87 // 	hz int32
     88 // }
     89 
     90 var (
     91     // // go:linkname runtimeProf runtime.prof
     92     // runtimeProf Prof
     93 
     94     // count of native-C calls
     95     yieldCount uint32
     96 
     97     // previous value of runtimeProf.hz
     98     oldHz int32
     99 )
    100 
    101 //go:nosplit
    102 func MoreStack(size uintptr)
    103 
    104 func StopProf()
    105 
    106 // func StopProf() {
    107 //     atomic.AddUint32(&yieldCount, 1)
    108 //     if runtimeProf.hz != 0 {
    109 //         oldHz = runtimeProf.hz
    110 //         runtimeProf.hz = 0
    111 //     }
    112 // }
    113 
    114 func StartProf()
    115 
    116 // func StartProf() {
    117 //     atomic.AddUint32(&yieldCount, ^uint32(0))
    118 //     if yieldCount == 0 && runtimeProf.hz == 0 {
    119 //         if oldHz == 0 {
    120 //             oldHz = 100
    121 //         }
    122 //         runtimeProf.hz = oldHz
    123 //     }
    124 // }