abi是啥具体我也不先说了,先按我的了解翻译了一遍,他就是寄存器还是堆栈调配的规约,我也是在学习,大家审慎观看哦

// Copyright 2021 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package reflectimport (    "internal/abi"    "internal/goexperiment"    "unsafe")// These variables are used by the register assignment// algorithm in this file.//// They should be modified with care (no other reflect code// may be executing) and are generally only modified// when testing this package.//// They should never be set higher than their internal/abi// constant counterparts, because the system relies on a// structure that is at least large enough to hold the// registers the system supports.//// Currently they're set to zero because using the actual// constants will break every part of the toolchain that// uses reflect to call functions (e.g. go test, or anything// that uses text/template). The values that are currently// commented out there should be the actual values once// we're ready to use the register ABI everywhere.// 这些变量都是用来作为寄存器调配算法的var (    intArgRegs   = abi.IntArgRegs * goexperiment.RegabiArgsInt // 整数寄存器的数量    floatArgRegs = abi.FloatArgRegs * goexperiment.RegabiArgsInt // 浮点数寄存器的数量    floatRegSize = uintptr(abi.EffectiveFloatRegSize * goexperiment.RegabiArgsInt) // 浮点数寄存器的宽度。可能为0、4、8。0代表没有,或者是通过softfloat ABI进行传递)// ABI 应用程序二进制接口。go运行时必须恪守的编程约定。ABI总是蕴含一系列的零碎调用和应用这些零碎调用的办法,// 以及对于程序能够应用的内存地址和应用机器寄存器的规定。// abiStep represents an ABI "instruction." Each instruction// describes one part of how to translate between a Go value// in memory and a call frame.// abiStep 就是一个ABI指令的形容。他形容了 go的值和函数栈帧之间的转换type abiStep struct {    kind abiStepKind // 分几种类型,栈传递,整数寄存器值传递,整数寄存器指针传递,浮点数寄存器传递    // offset and size together describe a part of a Go value    // in memory.    // 传递值在内存中的偏移和大小    offset uintptr    size   uintptr // size in bytes of the part    // These fields describe the ABI side of the translation.    // 如果是栈传递,他的偏移地址    stkOff uintptr // stack offset, used if kind == abiStepStack    // 如果是整数寄存器传递(包含整数指针传递),他的索引    ireg   int     // integer register index, used if kind == abiStepIntReg or kind == abiStepPointer    // 如果是浮点数寄存器传递,他的索引    freg   int     // FP register index, used if kind == abiStepFloatReg}// abiStepKind is the "op-code" for an abiStep instruction.type abiStepKind intconst (    abiStepBad      abiStepKind = iota    abiStepStack                // copy to/from stack    abiStepIntReg               // copy to/from integer register    abiStepPointer              // copy pointer to/from integer register    abiStepFloatReg             // copy to/from FP register)// abiSeq represents a sequence of ABI instructions for copying// from a series of reflect.Values to a call frame (for call arguments)// or vice-versa (for call results).//// An abiSeq should be populated by calling its addArg method.// abiSeq就是一些列abiStep的总和,加上了堆栈空间,和寄存器的应用type abiSeq struct {    // steps is the set of instructions.    //    // The instructions are grouped together by whole arguments,    // with the starting index for the instructions    // of the i'th Go value available in valueStart.    //    // For instance, if this abiSeq represents 3 arguments    // passed to a function, then the 2nd argument's steps    // begin at steps[valueStart[1]].    //    // Because reflect accepts Go arguments in distinct    // Values and each Value is stored separately, each abiStep    // that begins a new argument will have its offset    // field == 0.    // 这块就是理论的ABI形容列表,他是一组参数传递,或者是返回值传递    steps      []abiStep    // 这个标记了第i个参数或返回值的abiStep地位,好比以后是参数传递,要传第一个参数,那么就是steps[valueStart[0]],以此类推    valueStart []int    // 栈应用空间    stackBytes   uintptr // stack space used    // 寄存器应用状况    iregs, fregs int     // registers used}// 这个就是调试func (a *abiSeq) dump() {    for i, p := range a.steps {        println("part", i, p.kind, p.offset, p.size, p.stkOff, p.ireg, p.freg)    }    print("values ")    for _, i := range a.valueStart {        print(i, " ")    }    println()    println("stack", a.stackBytes)    println("iregs", a.iregs)    println("fregs", a.fregs)}// stepsForValue returns the ABI instructions for translating// the i'th Go argument or return value represented by this// abiSeq to the Go ABI.// stepsForValue失去第i个参数产地的ABI指令形容序列// 失去第i个参数的ABI指令形容序列func (a *abiSeq) stepsForValue(i int) []abiStep {    // s是开始地位    s := a.valueStart[i]    var e int    // a.steps和a.valueStart数量不对应,反正目标是为了获取下一个参数传递形容信息的一组ABI序列    if i == len(a.valueStart)-1 {        e = len(a.steps)    } else {        e = a.valueStart[i+1]    }    return a.steps[s:e]}// addArg extends the abiSeq with a new Go value of type t.//// If the value was stack-assigned, returns the single// abiStep describing that translation, and nil otherwise.// 用一个新的t类型的值扩大abiSeq序列// 如果是栈调配,就返回单个abiStep,不然就返回nil// 给seq增加一个参数传递的ABI序列func (a *abiSeq) addArg(t *rtype) *abiStep {    // We'll always be adding a new value, so do that first.    // 获取总长度,因为要增加的参数必定是在这个地位开始的。这个就是更新a.valueStart的标记    pStart := len(a.steps)    a.valueStart = append(a.valueStart, pStart)    // 如果增加的类型的长度为0    if t.size == 0 {        // If the size of the argument type is zero, then        // in order to degrade gracefully into ABI0, we need        // to stack-assign this type. The reason is that        // although zero-sized types take up no space on the        // stack, they do cause the next argument to be aligned.        // So just do that here, but don't bother actually        // generating a new ABI step for it (there's nothing to        // actually copy).        //        // We cannot handle this in the recursive case of        // regAssign because zero-sized *fields* of a        // non-zero-sized struct do not cause it to be        // stack-assigned. So we need a special case here        // at the top.        // 如果这个类型大小为0,为了降级到ABI0(稳固的ABI版本),咱们须要堆栈调配,尽管他        // 不占据空间,但他会影响下一次内存对其,因而咱们还是须要执行此操作,但没有必要生成一个step        // 大小尽管为0.然而会影响对齐,咱们还是要对他进行肯定的解决        // align将a.stackBytes舍入为uintptr(t.align)的倍数,就是将a.stackBytes增大到增加元素的对其倍数上        a.stackBytes = align(a.stackBytes, uintptr(t.align))        return nil    }    // Hold a copy of "a" so that we can roll back if    // register assignment fails.    // 保留a的正本,不便咱们寄存器调配失败时回滚    aOld := *a    // 寄存器调配开始,offset=0,调配失败的话,就须要回滚,而后进行栈调配    if !a.regAssign(t, 0) {        // Register assignment failed. Roll back any changes        // and stack-assign.        *a = aOld        // 栈调配胜利会返回最初一个步骤的step        a.stackAssign(t.size, uintptr(t.align))        return &a.steps[len(a.steps)-1]    }    return nil}// addRcvr extends the abiSeq with a new method call// receiver according to the interface calling convention.//// If the receiver was stack-assigned, returns the single// abiStep describing that translation, and nil otherwise.// Returns true if the receiver is a pointer.// 增加一个接受者,这个是办法应用的func (a *abiSeq) addRcvr(rcvr *rtype) (*abiStep, bool) {    // The receiver is always one word.    // 接受者永远是一个word    a.valueStart = append(a.valueStart, len(a.steps))    var ok, ptr bool    // 返回rcvr是否在接口中,并且其中是否蕴含指针,如果有指针或者是在接口中,进行寄存器传值,ptrMap 0b1,二进制的1代表这个是一个指针,波及到GC回收    if ifaceIndir(rcvr) || rcvr.pointers() {        ok = a.assignIntN(0, ptrSize, 1, 0b1)        ptr = true    } else {        // TODO(mknyszek): Is this case even possible?        // The interface data work never contains a non-pointer        // value. This case was copied over from older code        // in the reflect package which only conditionally added        // a pointer bit to the reflect.(Value).Call stack frame's        // GC bitmap.        ok = a.assignIntN(0, ptrSize, 1, 0b0)        ptr = false    }    if !ok {        a.stackAssign(ptrSize, ptrSize)        return &a.steps[len(a.steps)-1], ptr    }    return nil, ptr}// regAssign attempts to reserve argument registers for a value of// type t, stored at some offset.//// It returns whether or not the assignment succeeded, but// leaves any changes it made to a.steps behind, so the caller// must undo that work by adjusting a.steps if it fails.//// This method along with the assign* methods represent the// complete register-assignment algorithm for the Go ABI.// 他将t类型的值保留在偏移量offset的地位上,这就是寄存器调配算法func (a *abiSeq) regAssign(t *rtype, offset uintptr) bool {    // 看t的kind    switch t.Kind() {        // 和指针相干的整数,他们调配都是,0b1    case UnsafePointer, Ptr, Chan, Map, Func:        return a.assignIntN(offset, t.size, 1, 0b1)        // 一般整数,就是0b0    case Bool, Int, Uint, Int8, Uint8, Int16, Uint16, Int32, Uint32, Uintptr:        return a.assignIntN(offset, t.size, 1, 0b0)        // 这个就是看大小辨别了,不过个别都是第二个抉择    case Int64, Uint64:        switch ptrSize {        case 4:            return a.assignIntN(offset, 4, 2, 0b0)        case 8:            return a.assignIntN(offset, 8, 1, 0b0)        }    case Float32, Float64:        return a.assignFloatN(offset, t.size, 1)    case Complex64:        return a.assignFloatN(offset, 4, 2)    case Complex128:        return a.assignFloatN(offset, 8, 2)    case String:        // 字符串,整形寄存器        return a.assignIntN(offset, ptrSize, 2, 0b01)    case Interface:        // interface是2,其余有指针都是1,一般数据是0        return a.assignIntN(offset, ptrSize, 2, 0b10)    case Slice:        return a.assignIntN(offset, ptrSize, 3, 0b01)    case Array:        // 数组的话,首先先把t的rtype类型转换为arrayType类型,他一开始的确是rtype,后续就是本人的类型信息        // 相当于扩大内存了        tt := (*arrayType)(unsafe.Pointer(t))        // 判断tt的长度,如果长度为0,不必调配,长度为1,就调配一下,如果长度大于1,就返回失败,通过栈调配吧        switch tt.len {        case 0:            // There's nothing to assign, so don't modify            // a.steps but succeed so the caller doesn't            // try to stack-assign this value.            return true        case 1:            return a.regAssign(tt.elem, offset)        default:            return false        }    case Struct:        // 构造体数据,也是先映射回去,再把所有的一个一个存进去,如果有一个失败,就返回失败,里面会回滚的        st := (*structType)(unsafe.Pointer(t))        for i := range st.fields {            f := &st.fields[i]            if !a.regAssign(f.typ, offset+f.offset()) {                return false            }        }        return true    default:        print("t.Kind == ", t.Kind(), "\n")        panic("unknown type kind")    }    panic("unhandled register assignment path")}// assignIntN assigns n values to registers, each "size" bytes large,// from the data at [offset, offset+n*size) in memory. Each value at// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the// next n integer registers.//// Bit i in ptrMap indicates whether the i'th value is a pointer.// n must be <= 8.//// Returns whether assignment succeeded.// 就是调配从offset开始的内存地址,调配n个寄存器,每个寄存器的大小为sizefunc (a *abiSeq) assignIntN(offset, size uintptr, n int, ptrMap uint8) bool {    if n > 8 || n < 0 {        panic("invalid n")    }    // ptrMap != 0代表着有指针,须要,并且    if ptrMap != 0 && size != ptrSize {        panic("non-empty pointer map passed for non-pointer-size values")    }    // a.iregs+n 是咱们以后a占有的寄存器数量,intArgRegs是总数量    if a.iregs+n > intArgRegs {        return false    }    // 开始调配    for i := 0; i < n; i++ {        kind := abiStepIntReg        if ptrMap&(uint8(1)<<i) != 0 {            kind = abiStepPointer        }        a.steps = append(a.steps, abiStep{            kind:   kind,            offset: offset + uintptr(i)*size,            size:   size,            ireg:   a.iregs,        })        // 寄存器应用数量        a.iregs++    }    return true}// assignFloatN assigns n values to registers, each "size" bytes large,// from the data at [offset, offset+n*size) in memory. Each value at// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the// next n floating-point registers.//// Returns whether assignment succeeded.// 跟下面的差不多func (a *abiSeq) assignFloatN(offset, size uintptr, n int) bool {    if n < 0 {        panic("invalid n")    }    if a.fregs+n > floatArgRegs || floatRegSize < size {        return false    }    for i := 0; i < n; i++ {        a.steps = append(a.steps, abiStep{            kind:   abiStepFloatReg,            offset: offset + uintptr(i)*size,            size:   size,            freg:   a.fregs,        })        a.fregs++    }    return true}// stackAssign reserves space for one value that is "size" bytes// large with alignment "alignment" to the stack.//// Should not be called directly; use addArg instead.// 栈调配,这个不应该间接调用,应该调用addArg或者addRcvr// 这个栈调配func (a *abiSeq) stackAssign(size, alignment uintptr) {    // 第一步内存对其    a.stackBytes = align(a.stackBytes, alignment)    // 增加一个形容到abiSeq    a.steps = append(a.steps, abiStep{        kind:   abiStepStack,        offset: 0, // Only used for whole arguments, so the memory offset is 0.        size:   size,        stkOff: a.stackBytes,    })    a.stackBytes += size}// abiDesc describes the ABI for a function or method.// 这个才是为函数和办法定义的一组abi指令形容集type abiDesc struct {    // call and ret represent the translation steps for    // the call and return paths of a Go function.    // 这就是两个局部,调用传参,和返回值俩个步骤,都是abiSeq    call, ret abiSeq    // These fields describe the stack space allocated    // for the call. stackCallArgsSize is the amount of space    // reserved for arguments but not return values. retOffset    // is the offset at which return values begin, and    // spill is the size in bytes of additional space reserved    // to spill argument registers into in case of preemption in    // reflectcall's stack frame.    // stackCallArgsSize参数空间大小    // retOffset返回值偏移地位    // spill额定的空间,避免参数寄存器溢出    // 栈参数空间大小,返回值偏移地址,spill是额定空间,和旧版的栈调配一样,为了避免寄存器放不下了,跟旧版寄存办法一样,好读取数据    stackCallArgsSize, retOffset, spill uintptr    // stackPtrs is a bitmap that indicates whether    // each word in the ABI stack space (stack-assigned    // args + return values) is a pointer. Used    // as the heap pointer bitmap for stack space    // passed to reflectcall.    // 一个位图,指ABI参数和返回值是否是一个指针,用作栈空间反射调用堆指针空间位图    // 与runtime.bitvector.统一    stackPtrs *bitVector    // inRegPtrs is a bitmap whose i'th bit indicates    // whether the i'th integer argument register contains    // a pointer. Used by makeFuncStub and methodValueCall    // to make result pointers visible to the GC.    //    // outRegPtrs is the same, but for result values.    // Used by reflectcall to make result pointers visible    // to the GC.    // inRegPtrs,入参 应用makeFuncStub methodValueCall使对GC可见    // outRegPtrs,返回 应用reflectcall使对GC可见    // 第i位是否蕴含指针    // 这俩个和GC无关,用来裸露给GC    // 这个IntArgRegBitmap是[(IntArgRegs + 7) / 8]uint8    inRegPtrs, outRegPtrs abi.IntArgRegBitmap}func (a *abiDesc) dump() {    println("ABI")    println("call")    a.call.dump()    println("ret")    a.ret.dump()    println("stackCallArgsSize", a.stackCallArgsSize)    println("retOffset", a.retOffset)    println("spill", a.spill)    print("inRegPtrs:")    dumpPtrBitMap(a.inRegPtrs)    println()    print("outRegPtrs:")    dumpPtrBitMap(a.outRegPtrs)    println()}func dumpPtrBitMap(b abi.IntArgRegBitmap) {    for i := 0; i < intArgRegs; i++ {        x := 0        if b.Get(i) {            x = 1        }        print(" ", x)    }}// 封装一个参数传递过程func newAbiDesc(t *funcType, rcvr *rtype) abiDesc {    // We need to add space for this argument to    // the frame so that it can spill args into it.    //    // The size of this space is just the sum of the sizes    // of each register-allocated type.    //    // TODO(mknyszek): Remove this when we no longer have    // caller reserved spill space.    // 咱们须要调配一个空间,能够将参数溢出到这里    // 这个大小只是每个寄存器调配类型的大小总和    // 当咱们不再有调用者时删除他    spill := uintptr(0)    // Compute gc program & stack bitmap for stack arguments    // 计算堆栈参数gc程序和堆栈位图    stackPtrs := new(bitVector)    // Compute the stack frame pointer bitmap and register    // pointer bitmap for arguments.    // 计算参数的堆栈帧指针位图和寄存器指针位图。    inRegPtrs := abi.IntArgRegBitmap{}    // Compute abiSeq for input parameters.    // 计算入参的seq    var in abiSeq    if rcvr != nil {        // rcvr作为第一个参数传递进去        stkStep, isPtr := in.addRcvr(rcvr)        if stkStep != nil {            if isPtr {                stackPtrs.append(1)            } else {                stackPtrs.append(0)            }        } else {            spill += ptrSize        }    }    for i, arg := range t.in() {        stkStep := in.addArg(arg)        if stkStep != nil {            addTypeBits(stackPtrs, stkStep.stkOff, arg)        } else {            spill = align(spill, uintptr(arg.align))            spill += arg.size            for _, st := range in.stepsForValue(i) {                if st.kind == abiStepPointer {                    inRegPtrs.Set(st.ireg)                }            }        }    }    spill = align(spill, ptrSize)    // From the input parameters alone, we now know    // the stackCallArgsSize and retOffset.    stackCallArgsSize := in.stackBytes    retOffset := align(in.stackBytes, ptrSize)    // Compute the stack frame pointer bitmap and register    // pointer bitmap for return values.    outRegPtrs := abi.IntArgRegBitmap{}    // Compute abiSeq for output parameters.    var out abiSeq    // Stack-assigned return values do not share    // space with arguments like they do with registers,    // so we need to inject a stack offset here.    // Fake it by artificially extending stackBytes by    // the return offset.    out.stackBytes = retOffset    for i, res := range t.out() {        stkStep := out.addArg(res)        if stkStep != nil {            addTypeBits(stackPtrs, stkStep.stkOff, res)        } else {            for _, st := range out.stepsForValue(i) {                if st.kind == abiStepPointer {                    outRegPtrs.Set(st.ireg)                }            }        }    }    // Undo the faking from earlier so that stackBytes    // is accurate.    out.stackBytes -= retOffset    return abiDesc{in, out, stackCallArgsSize, retOffset, spill, stackPtrs, inRegPtrs, outRegPtrs}}