summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/loader/internal/abi
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/loader/internal/abi')
-rw-r--r--vendor/github.com/bytedance/sonic/loader/internal/abi/abi.go197
-rw-r--r--vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go301
-rw-r--r--vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go215
-rw-r--r--vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go345
-rw-r--r--vendor/github.com/bytedance/sonic/loader/internal/abi/stubs.go35
5 files changed, 0 insertions, 1093 deletions
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi.go
deleted file mode 100644
index 524ab5330..000000000
--- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi.go
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2022 ByteDance Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package abi
-
-import (
- `fmt`
- `reflect`
- `sort`
- `strings`
-
- `github.com/bytedance/sonic/loader/internal/rt`
-)
-
-type FunctionLayout struct {
- FP uint32
- Args []Parameter
- Rets []Parameter
-}
-
-func (self FunctionLayout) String() string {
- return self.formatFn()
-}
-
-func (self FunctionLayout) ArgSize() uint32 {
- size := uintptr(0)
- for _, arg := range self.Args {
- size += arg.Type.Size()
- }
- return uint32(size)
-}
-
-type slot struct {
- p bool
- m uint32
-}
-
-func (self FunctionLayout) StackMap() *rt.StackMap {
- var st []slot
- var mb rt.StackMapBuilder
-
- /* add arguments */
- for _, v := range self.Args {
- st = append(st, slot {
- m: v.Mem,
- p: v.IsPointer,
- })
- }
-
- /* add stack-passed return values */
- for _, v := range self.Rets {
- if !v.InRegister {
- st = append(st, slot {
- m: v.Mem,
- p: v.IsPointer,
- })
- }
- }
-
- /* sort by memory offset */
- sort.Slice(st, func(i int, j int) bool {
- return st[i].m < st[j].m
- })
-
- /* add the bits */
- for _, v := range st {
- mb.AddField(v.p)
- }
-
- /* build the stack map */
- return mb.Build()
-}
-
-func (self FunctionLayout) formatFn() string {
- fp := self.FP
- return fmt.Sprintf("\n%#04x\nRets:\n%s\nArgs:\n%s", fp, self.formatSeq(self.Rets, &fp), self.formatSeq(self.Args, &fp))
-}
-
-func (self FunctionLayout) formatSeq(v []Parameter, fp *uint32) string {
- nb := len(v)
- mm := make([]string, 0, len(v))
-
- /* convert each part */
- for i := nb-1; i >=0; i-- {
- *fp -= PtrSize
- mm = append(mm, fmt.Sprintf("%#04x %s", *fp, v[i].String()))
- }
-
- /* join them together */
- return strings.Join(mm, "\n")
-}
-
-type Frame struct {
- desc *FunctionLayout
- locals []bool
- ccall bool
-}
-
-func NewFrame(desc *FunctionLayout, locals []bool, ccall bool) Frame {
- fr := Frame{}
- fr.desc = desc
- fr.locals = locals
- fr.ccall = ccall
- return fr
-}
-
-func (self *Frame) String() string {
- out := self.desc.String()
-
- off := -8
- out += fmt.Sprintf("\n%#4x [Return PC]", off)
- off -= 8
- out += fmt.Sprintf("\n%#4x [RBP]", off)
- off -= 8
-
- for _, v := range ReservedRegs(self.ccall) {
- out += fmt.Sprintf("\n%#4x [%v]", off, v)
- off -= PtrSize
- }
-
- for _, b := range self.locals {
- out += fmt.Sprintf("\n%#4x [%v]", off, b)
- off -= PtrSize
- }
-
- return out
-}
-
-func (self *Frame) Prev() uint32 {
- return self.Size() + PtrSize
-}
-
-func (self *Frame) Size() uint32 {
- return uint32(self.Offs() + PtrSize)
-}
-
-func (self *Frame) Offs() uint32 {
- return uint32(len(ReservedRegs(self.ccall)) * PtrSize + len(self.locals)*PtrSize)
-}
-
-func (self *Frame) ArgPtrs() *rt.StackMap {
- return self.desc.StackMap()
-}
-
-func (self *Frame) LocalPtrs() *rt.StackMap {
- var m rt.StackMapBuilder
- for _, b := range self.locals {
- m.AddFields(len(ReservedRegs(self.ccall)), b)
- }
- return m.Build()
-}
-
-func alignUp(n uint32, a int) uint32 {
- return (uint32(n) + uint32(a) - 1) &^ (uint32(a) - 1)
-}
-
-func isPointer(vt reflect.Type) bool {
- switch vt.Kind() {
- case reflect.Bool : fallthrough
- case reflect.Int : fallthrough
- case reflect.Int8 : fallthrough
- case reflect.Int16 : fallthrough
- case reflect.Int32 : fallthrough
- case reflect.Int64 : fallthrough
- case reflect.Uint : fallthrough
- case reflect.Uint8 : fallthrough
- case reflect.Uint16 : fallthrough
- case reflect.Uint32 : fallthrough
- case reflect.Uint64 : fallthrough
- case reflect.Float32 : fallthrough
- case reflect.Float64 : fallthrough
- case reflect.Uintptr : return false
- case reflect.Chan : fallthrough
- case reflect.Func : fallthrough
- case reflect.Map : fallthrough
- case reflect.Ptr : fallthrough
- case reflect.UnsafePointer : return true
- case reflect.Complex64 : fallthrough
- case reflect.Complex128 : fallthrough
- case reflect.Array : fallthrough
- case reflect.Struct : panic("abi: unsupported types")
- default : panic("abi: invalid value type")
- }
-} \ No newline at end of file
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go
deleted file mode 100644
index 2969c3bba..000000000
--- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright 2022 ByteDance Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package abi
-
-import (
- "fmt"
- "reflect"
- "unsafe"
-
- x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64"
-)
-
-type (
- Register = x64.Register
- Register64 = x64.Register64
- XMMRegister = x64.XMMRegister
- Program = x64.Program
- MemoryOperand = x64.MemoryOperand
- Label = x64.Label
-)
-
-var (
- Ptr = x64.Ptr
- DefaultArch = x64.DefaultArch
- CreateLabel = x64.CreateLabel
-)
-
-const (
- RAX = x64.RAX
- RSP = x64.RSP
- RBP = x64.RBP
- R12 = x64.R12
- R14 = x64.R14
- R15 = x64.R15
-)
-
-const (
- PtrSize = 8 // pointer size
- PtrAlign = 8 // pointer alignment
-)
-
-var iregOrderC = []Register{
- x64.RDI,
- x64.RSI,
- x64.RDX,
- x64.RCX,
- x64.R8,
- x64.R9,
-}
-
-var xregOrderC = []Register{
- x64.XMM0,
- x64.XMM1,
- x64.XMM2,
- x64.XMM3,
- x64.XMM4,
- x64.XMM5,
- x64.XMM6,
- x64.XMM7,
-}
-
-var (
- intType = reflect.TypeOf(0)
- ptrType = reflect.TypeOf(unsafe.Pointer(nil))
-)
-
-func (self *Frame) argv(i int) *MemoryOperand {
- return Ptr(RSP, int32(self.Prev()+self.desc.Args[i].Mem))
-}
-
-// spillv is used for growstack spill registers
-func (self *Frame) spillv(i int) *MemoryOperand {
- // remain one slot for caller return pc
- return Ptr(RSP, PtrSize+int32(self.desc.Args[i].Mem))
-}
-
-func (self *Frame) retv(i int) *MemoryOperand {
- return Ptr(RSP, int32(self.Prev()+self.desc.Rets[i].Mem))
-}
-
-func (self *Frame) resv(i int) *MemoryOperand {
- return Ptr(RSP, int32(self.Offs()-uint32((i+1)*PtrSize)))
-}
-
-func (self *Frame) emitGrowStack(p *Program, entry *Label) {
- // spill all register arguments
- for i, v := range self.desc.Args {
- if v.InRegister {
- if v.IsFloat == floatKind64 {
- p.MOVSD(v.Reg, self.spillv(i))
- } else if v.IsFloat == floatKind32 {
- p.MOVSS(v.Reg, self.spillv(i))
- } else {
- p.MOVQ(v.Reg, self.spillv(i))
- }
- }
- }
-
- // call runtime.morestack_noctxt
- p.MOVQ(F_morestack_noctxt, R12)
- p.CALLQ(R12)
- // load all register arguments
- for i, v := range self.desc.Args {
- if v.InRegister {
- if v.IsFloat == floatKind64 {
- p.MOVSD(self.spillv(i), v.Reg)
- } else if v.IsFloat == floatKind32 {
- p.MOVSS(self.spillv(i), v.Reg)
- } else {
- p.MOVQ(self.spillv(i), v.Reg)
- }
- }
- }
-
- // jump back to the function entry
- p.JMP(entry)
-}
-
-func (self *Frame) GrowStackTextSize() uint32 {
- p := DefaultArch.CreateProgram()
- // spill all register arguments
- for i, v := range self.desc.Args {
- if v.InRegister {
- if v.IsFloat == floatKind64 {
- p.MOVSD(v.Reg, self.spillv(i))
- } else if v.IsFloat == floatKind32 {
- p.MOVSS(v.Reg, self.spillv(i))
- } else {
- p.MOVQ(v.Reg, self.spillv(i))
- }
- }
- }
-
- // call runtime.morestack_noctxt
- p.MOVQ(F_morestack_noctxt, R12)
- p.CALLQ(R12)
- // load all register arguments
- for i, v := range self.desc.Args {
- if v.InRegister {
- if v.IsFloat == floatKind64 {
- p.MOVSD(self.spillv(i), v.Reg)
- } else if v.IsFloat == floatKind32 {
- p.MOVSS(self.spillv(i), v.Reg)
- } else {
- p.MOVQ(self.spillv(i), v.Reg)
- }
- }
- }
-
- // jump back to the function entry
- l := CreateLabel("")
- p.Link(l)
- p.JMP(l)
-
- return uint32(len(p.Assemble(0)))
-}
-
-func (self *Frame) emitPrologue(p *Program) {
- p.SUBQ(self.Size(), RSP)
- p.MOVQ(RBP, Ptr(RSP, int32(self.Offs())))
- p.LEAQ(Ptr(RSP, int32(self.Offs())), RBP)
-}
-
-func (self *Frame) emitEpilogue(p *Program) {
- p.MOVQ(Ptr(RSP, int32(self.Offs())), RBP)
- p.ADDQ(self.Size(), RSP)
- p.RET()
-}
-
-func (self *Frame) emitReserveRegs(p *Program) {
- // spill reserved registers
- for i, r := range ReservedRegs(self.ccall) {
- switch r.(type) {
- case Register64:
- p.MOVQ(r, self.resv(i))
- case XMMRegister:
- p.MOVSD(r, self.resv(i))
- default:
- panic(fmt.Sprintf("unsupported register type %t to reserve", r))
- }
- }
-}
-
-func (self *Frame) emitSpillPtrs(p *Program) {
- // spill pointer argument registers
- for i, r := range self.desc.Args {
- if r.InRegister && r.IsPointer {
- p.MOVQ(r.Reg, self.argv(i))
- }
- }
-}
-
-func (self *Frame) emitClearPtrs(p *Program) {
- // spill pointer argument registers
- for i, r := range self.desc.Args {
- if r.InRegister && r.IsPointer {
- p.MOVQ(int64(0), self.argv(i))
- }
- }
-}
-
-func (self *Frame) emitCallC(p *Program, addr uintptr) {
- p.MOVQ(addr, RAX)
- p.CALLQ(RAX)
-}
-
-type floatKind uint8
-
-const (
- notFloatKind floatKind = iota
- floatKind32
- floatKind64
-)
-
-type Parameter struct {
- InRegister bool
- IsPointer bool
- IsFloat floatKind
- Reg Register
- Mem uint32
- Type reflect.Type
-}
-
-func mkIReg(vt reflect.Type, reg Register64) (p Parameter) {
- p.Reg = reg
- p.Type = vt
- p.InRegister = true
- p.IsPointer = isPointer(vt)
- return
-}
-
-func isFloat(vt reflect.Type) floatKind {
- switch vt.Kind() {
- case reflect.Float32:
- return floatKind32
- case reflect.Float64:
- return floatKind64
- default:
- return notFloatKind
- }
-}
-
-func mkXReg(vt reflect.Type, reg XMMRegister) (p Parameter) {
- p.Reg = reg
- p.Type = vt
- p.InRegister = true
- p.IsFloat = isFloat(vt)
- return
-}
-
-func mkStack(vt reflect.Type, mem uint32) (p Parameter) {
- p.Mem = mem
- p.Type = vt
- p.InRegister = false
- p.IsPointer = isPointer(vt)
- p.IsFloat = isFloat(vt)
- return
-}
-
-func (self Parameter) String() string {
- if self.InRegister {
- return fmt.Sprintf("[%%%s, Pointer(%v), Float(%v)]", self.Reg, self.IsPointer, self.IsFloat)
- } else {
- return fmt.Sprintf("[%d(FP), Pointer(%v), Float(%v)]", self.Mem, self.IsPointer, self.IsFloat)
- }
-}
-
-func CallC(addr uintptr, fr Frame, maxStack uintptr) []byte {
- p := DefaultArch.CreateProgram()
-
- stack := CreateLabel("_stack_grow")
- entry := CreateLabel("_entry")
- p.Link(entry)
- fr.emitStackCheck(p, stack, maxStack)
- fr.emitPrologue(p)
- fr.emitReserveRegs(p)
- fr.emitSpillPtrs(p)
- fr.emitExchangeArgs(p)
- fr.emitCallC(p, addr)
- fr.emitExchangeRets(p)
- fr.emitRestoreRegs(p)
- fr.emitEpilogue(p)
- p.Link(stack)
- fr.emitGrowStack(p, entry)
-
- return p.Assemble(0)
-}
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go
deleted file mode 100644
index 722c0696f..000000000
--- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go
+++ /dev/null
@@ -1,215 +0,0 @@
-//go:build !go1.17
-// +build !go1.17
-
-/*
- * Copyright 2022 ByteDance Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package abi
-
-import (
- "fmt"
- "reflect"
- "runtime"
-)
-
-func ReservedRegs(callc bool) []Register {
- return nil
-}
-
-func salloc(p []Parameter, sp uint32, vt reflect.Type) (uint32, []Parameter) {
- switch vt.Kind() {
- case reflect.Bool:
- return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp))
- case reflect.Int:
- return sp + 8, append(p, mkStack(intType, sp))
- case reflect.Int8:
- return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp))
- case reflect.Int16:
- return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp))
- case reflect.Int32:
- return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp))
- case reflect.Int64:
- return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp))
- case reflect.Uint:
- return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp))
- case reflect.Uint8:
- return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp))
- case reflect.Uint16:
- return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp))
- case reflect.Uint32:
- return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp))
- case reflect.Uint64:
- return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp))
- case reflect.Uintptr:
- return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp))
- case reflect.Float32:
- return sp + 8, append(p, mkStack(reflect.TypeOf(float32(0)), sp))
- case reflect.Float64:
- return sp + 8, append(p, mkStack(reflect.TypeOf(float64(0)), sp))
- case reflect.Complex64:
- panic("abi: go116: not implemented: complex64")
- case reflect.Complex128:
- panic("abi: go116: not implemented: complex128")
- case reflect.Array:
- panic("abi: go116: not implemented: arrays")
- case reflect.Chan:
- return sp + 8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp))
- case reflect.Func:
- return sp + 8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp))
- case reflect.Map:
- return sp + 8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp))
- case reflect.Ptr:
- return sp + 8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp))
- case reflect.UnsafePointer:
- return sp + 8, append(p, mkStack(ptrType, sp))
- case reflect.Interface:
- return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp+8))
- case reflect.Slice:
- return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp+8), mkStack(intType, sp+16))
- case reflect.String:
- return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp+8))
- case reflect.Struct:
- panic("abi: go116: not implemented: structs")
- default:
- panic("abi: invalid value type")
- }
-}
-
-func NewFunctionLayout(ft reflect.Type) FunctionLayout {
- var sp uint32
- var fn FunctionLayout
-
- /* assign every arguments */
- for i := 0; i < ft.NumIn(); i++ {
- sp, fn.Args = salloc(fn.Args, sp, ft.In(i))
- }
-
- /* assign every return value */
- for i := 0; i < ft.NumOut(); i++ {
- sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i))
- }
-
- /* update function ID and stack pointer */
- fn.FP = sp
- return fn
-}
-
-func (self *Frame) emitExchangeArgs(p *Program) {
- iregArgs, xregArgs := 0, 0
- for _, v := range self.desc.Args {
- if v.IsFloat != notFloatKind {
- xregArgs += 1
- } else {
- iregArgs += 1
- }
- }
-
- if iregArgs > len(iregOrderC) {
- panic("too many arguments, only support at most 6 integer arguments now")
- }
- if xregArgs > len(xregOrderC) {
- panic("too many arguments, only support at most 8 float arguments now")
- }
-
- ic, xc := iregArgs, xregArgs
- for i := 0; i < len(self.desc.Args); i++ {
- arg := self.desc.Args[i]
- if arg.IsFloat == floatKind64 {
- p.MOVSD(self.argv(i), xregOrderC[xregArgs-xc])
- xc -= 1
- } else if arg.IsFloat == floatKind32 {
- p.MOVSS(self.argv(i), xregOrderC[xregArgs-xc])
- xc -= 1
- } else {
- p.MOVQ(self.argv(i), iregOrderC[iregArgs-ic])
- ic -= 1
- }
- }
-}
-
-func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) {
- // get the current goroutine
- switch runtime.GOOS {
- case "linux":
- p.MOVQ(Abs(-8), R14).FS()
- case "darwin":
- p.MOVQ(Abs(0x30), R14).GS()
- case "windows":
- break // windows always stores G pointer at R14
- default:
- panic("unsupported operating system")
- }
-
- // check the stack guard
- p.LEAQ(Ptr(RSP, -int32(self.Size()+uint32(maxStack))), RAX)
- p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
- p.JBE(to)
-}
-
-func (self *Frame) StackCheckTextSize() uint32 {
- p := DefaultArch.CreateProgram()
-
- // get the current goroutine
- switch runtime.GOOS {
- case "linux":
- p.MOVQ(Abs(-8), R14).FS()
- case "darwin":
- p.MOVQ(Abs(0x30), R14).GS()
- case "windows":
- break // windows always stores G pointer at R14
- default:
- panic("unsupported operating system")
- }
-
- // check the stack guard
- p.LEAQ(Ptr(RSP, -int32(self.Size())), RAX)
- p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
- l := CreateLabel("")
- p.Link(l)
- p.JBE(l)
-
- return uint32(len(p.Assemble(0)))
-}
-
-func (self *Frame) emitExchangeRets(p *Program) {
- if len(self.desc.Rets) > 1 {
- panic("too many results, only support one result now")
- }
- // store result
- if len(self.desc.Rets) == 1 {
- if self.desc.Rets[0].IsFloat == floatKind64 {
- p.MOVSD(xregOrderC[0], self.retv(0))
- } else if self.desc.Rets[0].IsFloat == floatKind32 {
- p.MOVSS(xregOrderC[0], self.retv(0))
- } else {
- p.MOVQ(RAX, self.retv(0))
- }
- }
-}
-
-func (self *Frame) emitRestoreRegs(p *Program) {
- // load reserved registers
- for i, r := range ReservedRegs(self.ccall) {
- switch r.(type) {
- case Register64:
- p.MOVQ(self.resv(i), r)
- case XMMRegister:
- p.MOVSD(self.resv(i), r)
- default:
- panic(fmt.Sprintf("unsupported register type %t to reserve", r))
- }
- }
-}
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go
deleted file mode 100644
index 95eae05fa..000000000
--- a/vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go
+++ /dev/null
@@ -1,345 +0,0 @@
-//go:build go1.17
-// +build go1.17
-
-/*
- * Copyright 2022 ByteDance Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Go Internal ABI implementation
- *
- * This module implements the function layout algorithm described by the Go internal ABI.
- * See https://github.com/golang/go/blob/master/src/cmd/compile/abi-internal.md for more info.
- */
-
-package abi
-
-import (
- "fmt"
- "reflect"
-
- x64 "github.com/bytedance/sonic/loader/internal/iasm/x86_64"
-)
-
-/** Frame Structure of the Generated Function
- FP +------------------------------+
- | . . . |
- | 2nd reg argument spill space |
- + 1st reg argument spill space |
- | <pointer-sized alignment> |
- | . . . |
- | 2nd stack-assigned result |
- + 1st stack-assigned result |
- | <pointer-sized alignment> |
- | . . . |
- | 2nd stack-assigned argument |
- | 1st stack-assigned argument |
- | stack-assigned receiver |
-prev() +------------------------------+ (Previous Frame)
- Return PC |
-size() -------------------------------|
- Saved RBP |
-offs() -------------------------------|
- 1th Reserved Registers |
- -------------------------------|
- 2th Reserved Registers |
- -------------------------------|
- Local Variables |
- RSP -------------------------------|↓ lower addresses
-*/
-
-const zeroRegGo = x64.XMM15
-
-var iregOrderGo = [...]Register64{
- x64.RAX, // RDI
- x64.RBX, // RSI
- x64.RCX, // RDX
- x64.RDI, // RCX
- x64.RSI, // R8
- x64.R8, // R9
- x64.R9,
- x64.R10,
- x64.R11,
-}
-
-var xregOrderGo = [...]XMMRegister{
- x64.XMM0,
- x64.XMM1,
- x64.XMM2,
- x64.XMM3,
- x64.XMM4,
- x64.XMM5,
- x64.XMM6,
- x64.XMM7,
- x64.XMM8,
- x64.XMM9,
- x64.XMM10,
- x64.XMM11,
- x64.XMM12,
- x64.XMM13,
- x64.XMM14,
-}
-
-func ReservedRegs(callc bool) []Register {
- if callc {
- return nil
- }
- return []Register{
- R14, // current goroutine
- R15, // GOT reference
- }
-}
-
-type stackAlloc struct {
- s uint32
- i int
- x int
-}
-
-func (self *stackAlloc) reset() {
- self.i, self.x = 0, 0
-}
-
-func (self *stackAlloc) ireg(vt reflect.Type) (p Parameter) {
- p = mkIReg(vt, iregOrderGo[self.i])
- self.i++
- return
-}
-
-func (self *stackAlloc) xreg(vt reflect.Type) (p Parameter) {
- p = mkXReg(vt, xregOrderGo[self.x])
- self.x++
- return
-}
-
-func (self *stackAlloc) stack(vt reflect.Type) (p Parameter) {
- p = mkStack(vt, self.s)
- self.s += uint32(vt.Size())
- return
-}
-
-func (self *stackAlloc) spill(n uint32, a int) uint32 {
- self.s = alignUp(self.s, a) + n
- return self.s
-}
-
-func (self *stackAlloc) alloc(p []Parameter, vt reflect.Type) []Parameter {
- nb := vt.Size()
- vk := vt.Kind()
-
- /* zero-sized objects are allocated on stack */
- if nb == 0 {
- return append(p, mkStack(intType, self.s))
- }
-
- /* check for value type */
- switch vk {
- case reflect.Bool:
- return self.valloc(p, reflect.TypeOf(false))
- case reflect.Int:
- return self.valloc(p, intType)
- case reflect.Int8:
- return self.valloc(p, reflect.TypeOf(int8(0)))
- case reflect.Int16:
- return self.valloc(p, reflect.TypeOf(int16(0)))
- case reflect.Int32:
- return self.valloc(p, reflect.TypeOf(uint32(0)))
- case reflect.Int64:
- return self.valloc(p, reflect.TypeOf(int64(0)))
- case reflect.Uint:
- return self.valloc(p, reflect.TypeOf(uint(0)))
- case reflect.Uint8:
- return self.valloc(p, reflect.TypeOf(uint8(0)))
- case reflect.Uint16:
- return self.valloc(p, reflect.TypeOf(uint16(0)))
- case reflect.Uint32:
- return self.valloc(p, reflect.TypeOf(uint32(0)))
- case reflect.Uint64:
- return self.valloc(p, reflect.TypeOf(uint64(0)))
- case reflect.Uintptr:
- return self.valloc(p, reflect.TypeOf(uintptr(0)))
- case reflect.Float32:
- return self.valloc(p, reflect.TypeOf(float32(0)))
- case reflect.Float64:
- return self.valloc(p, reflect.TypeOf(float64(0)))
- case reflect.Complex64:
- panic("abi: go117: not implemented: complex64")
- case reflect.Complex128:
- panic("abi: go117: not implemented: complex128")
- case reflect.Array:
- panic("abi: go117: not implemented: arrays")
- case reflect.Chan:
- return self.valloc(p, reflect.TypeOf((chan int)(nil)))
- case reflect.Func:
- return self.valloc(p, reflect.TypeOf((func())(nil)))
- case reflect.Map:
- return self.valloc(p, reflect.TypeOf((map[int]int)(nil)))
- case reflect.Ptr:
- return self.valloc(p, reflect.TypeOf((*int)(nil)))
- case reflect.UnsafePointer:
- return self.valloc(p, ptrType)
- case reflect.Interface:
- return self.valloc(p, ptrType, ptrType)
- case reflect.Slice:
- return self.valloc(p, ptrType, intType, intType)
- case reflect.String:
- return self.valloc(p, ptrType, intType)
- case reflect.Struct:
- panic("abi: go117: not implemented: structs")
- default:
- panic("abi: invalid value type")
- }
-}
-
-func (self *stackAlloc) valloc(p []Parameter, vts ...reflect.Type) []Parameter {
- for _, vt := range vts {
- enum := isFloat(vt)
- if enum != notFloatKind && self.x < len(xregOrderGo) {
- p = append(p, self.xreg(vt))
- } else if enum == notFloatKind && self.i < len(iregOrderGo) {
- p = append(p, self.ireg(vt))
- } else {
- p = append(p, self.stack(vt))
- }
- }
- return p
-}
-
-func NewFunctionLayout(ft reflect.Type) FunctionLayout {
- var sa stackAlloc
- var fn FunctionLayout
-
- /* assign every arguments */
- for i := 0; i < ft.NumIn(); i++ {
- fn.Args = sa.alloc(fn.Args, ft.In(i))
- }
-
- /* reset the register counter, and add a pointer alignment field */
- sa.reset()
-
- /* assign every return value */
- for i := 0; i < ft.NumOut(); i++ {
- fn.Rets = sa.alloc(fn.Rets, ft.Out(i))
- }
-
- sa.spill(0, PtrAlign)
-
- /* assign spill slots */
- for i := 0; i < len(fn.Args); i++ {
- if fn.Args[i].InRegister {
- fn.Args[i].Mem = sa.spill(PtrSize, PtrAlign) - PtrSize
- }
- }
-
- /* add the final pointer alignment field */
- fn.FP = sa.spill(0, PtrAlign)
- return fn
-}
-
-func (self *Frame) emitExchangeArgs(p *Program) {
- iregArgs := make([]Parameter, 0, len(self.desc.Args))
- xregArgs := 0
- for _, v := range self.desc.Args {
- if v.InRegister {
- if v.IsFloat != notFloatKind {
- xregArgs += 1
- } else {
- iregArgs = append(iregArgs, v)
- }
- } else {
- panic("not support stack-assigned arguments now")
- }
- }
- if xregArgs > len(xregOrderC) {
- panic("too many arguments, only support at most 8 integer register arguments now")
- }
-
- switch len(iregArgs) {
- case 0, 1, 2, 3:
- {
- //Fast-Path: when arguments count are less than four, just exchange the registers
- for i := 0; i < len(iregArgs); i++ {
- p.MOVQ(iregOrderGo[i], iregOrderC[i])
- }
- }
- case 4, 5, 6:
- {
- // need to spill 3th ~ regArgs registers before exchange
- for i := 3; i < len(iregArgs); i++ {
- arg := iregArgs[i]
- // pointer args have already been spilled
- if !arg.IsPointer {
- p.MOVQ(iregOrderGo[i], Ptr(RSP, int32(self.Prev()+arg.Mem)))
- }
- }
- p.MOVQ(iregOrderGo[0], iregOrderC[0])
- p.MOVQ(iregOrderGo[1], iregOrderC[1])
- p.MOVQ(iregOrderGo[2], iregOrderC[2])
- for i := 3; i < len(iregArgs); i++ {
- arg := iregArgs[i]
- p.MOVQ(Ptr(RSP, int32(self.Prev()+arg.Mem)), iregOrderC[i])
- }
- }
- default:
- panic("too many arguments, only support at most 6 integer register arguments now")
- }
-}
-
-func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) {
- p.LEAQ(Ptr(RSP, int32(-(self.Size()+uint32(maxStack)))), R12)
- p.CMPQ(Ptr(R14, _G_stackguard0), R12)
- p.JBE(to)
-}
-
-func (self *Frame) StackCheckTextSize() uint32 {
- p := DefaultArch.CreateProgram()
- p.LEAQ(Ptr(RSP, int32(-(self.Size()))), R12)
- p.CMPQ(Ptr(R14, _G_stackguard0), R12)
- to := CreateLabel("")
- p.Link(to)
- p.JBE(to)
- return uint32(len(p.Assemble(0)))
-}
-
-func (self *Frame) emitExchangeRets(p *Program) {
- if len(self.desc.Rets) > 1 {
- panic("too many results, only support one result now")
- }
- // store result
- if len(self.desc.Rets) == 1 && !self.desc.Rets[0].InRegister {
- if self.desc.Rets[0].IsFloat == floatKind64 {
- p.MOVSD(xregOrderC[0], self.retv(0))
- } else if self.desc.Rets[0].IsFloat == floatKind32 {
- p.MOVSS(xregOrderC[0], self.retv(0))
- } else {
- p.MOVQ(RAX, self.retv(0))
- }
- }
-}
-
-func (self *Frame) emitRestoreRegs(p *Program) {
- // load reserved registers
- for i, r := range ReservedRegs(self.ccall) {
- switch r.(type) {
- case Register64:
- p.MOVQ(self.resv(i), r)
- case XMMRegister:
- p.MOVSD(self.resv(i), r)
- default:
- panic(fmt.Sprintf("unsupported register type %t to reserve", r))
- }
- }
- // zero xmm15 for go abi
- p.XORPS(zeroRegGo, zeroRegGo)
-}
diff --git a/vendor/github.com/bytedance/sonic/loader/internal/abi/stubs.go b/vendor/github.com/bytedance/sonic/loader/internal/abi/stubs.go
deleted file mode 100644
index af9930156..000000000
--- a/vendor/github.com/bytedance/sonic/loader/internal/abi/stubs.go
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright 2023 ByteDance Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package abi
-
-import (
- _ `unsafe`
-
- `github.com/bytedance/sonic/loader/internal/rt`
-)
-
-const (
- _G_stackguard0 = 0x10
-)
-
-var (
- F_morestack_noctxt = uintptr(rt.FuncAddr(morestack_noctxt))
-)
-
-//go:linkname morestack_noctxt runtime.morestack_noctxt
-func morestack_noctxt()
-