github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/native/dispatch_amd64.go (about)

     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 native
    18  
    19  import (
    20  	"unsafe"
    21  
    22  	"github.com/goshafaq/sonic/internal/cpu"
    23  	"github.com/goshafaq/sonic/internal/native/avx"
    24  	"github.com/goshafaq/sonic/internal/native/avx2"
    25  	"github.com/goshafaq/sonic/internal/native/sse"
    26  	"github.com/goshafaq/sonic/internal/native/types"
    27  	"github.com/goshafaq/sonic/internal/rt"
    28  	"github.com/goshafaq/sonic/loader"
    29  )
    30  
    31  const (
    32  	MaxFrameSize   uintptr = 400
    33  	BufPaddingSize int     = 64
    34  )
    35  
    36  var (
    37  	S_f64toa uintptr
    38  	S_f32toa uintptr
    39  	S_i64toa uintptr
    40  	S_u64toa uintptr
    41  	S_lspace uintptr
    42  )
    43  
    44  var (
    45  	S_quote       uintptr
    46  	S_unquote     uintptr
    47  	S_html_escape uintptr
    48  )
    49  
    50  var (
    51  	S_value     uintptr
    52  	S_vstring   uintptr
    53  	S_vnumber   uintptr
    54  	S_vsigned   uintptr
    55  	S_vunsigned uintptr
    56  )
    57  
    58  var (
    59  	S_skip_one      uintptr
    60  	S_skip_one_fast uintptr
    61  	S_get_by_path   uintptr
    62  	S_skip_array    uintptr
    63  	S_skip_object   uintptr
    64  	S_skip_number   uintptr
    65  )
    66  
    67  var (
    68  	S_validate_one       uintptr
    69  	S_validate_utf8      uintptr
    70  	S_validate_utf8_fast uintptr
    71  )
    72  
    73  var (
    74  	__Quote func(s unsafe.Pointer, nb int, dp unsafe.Pointer, dn unsafe.Pointer, flags uint64) int
    75  
    76  	__Unquote func(s unsafe.Pointer, nb int, dp unsafe.Pointer, ep unsafe.Pointer, flags uint64) int
    77  
    78  	__HTMLEscape func(s unsafe.Pointer, nb int, dp unsafe.Pointer, dn unsafe.Pointer) int
    79  
    80  	__Value func(s unsafe.Pointer, n int, p int, v unsafe.Pointer, flags uint64) int
    81  
    82  	__SkipOne func(s unsafe.Pointer, p unsafe.Pointer, m unsafe.Pointer, flags uint64) int
    83  
    84  	__SkipOneFast func(s unsafe.Pointer, p unsafe.Pointer) int
    85  
    86  	__GetByPath func(s unsafe.Pointer, p unsafe.Pointer, path unsafe.Pointer, m unsafe.Pointer) int
    87  
    88  	__ValidateOne func(s unsafe.Pointer, p unsafe.Pointer, m unsafe.Pointer) int
    89  
    90  	__I64toa func(out unsafe.Pointer, val int64) (ret int)
    91  
    92  	__U64toa func(out unsafe.Pointer, val uint64) (ret int)
    93  
    94  	__F64toa func(out unsafe.Pointer, val float64) (ret int)
    95  
    96  	__ValidateUTF8 func(s unsafe.Pointer, p unsafe.Pointer, m unsafe.Pointer) (ret int)
    97  
    98  	__ValidateUTF8Fast func(s unsafe.Pointer) (ret int)
    99  )
   100  
   101  //go:nosplit
   102  func Quote(s unsafe.Pointer, nb int, dp unsafe.Pointer, dn *int, flags uint64) int {
   103  	return __Quote(rt.NoEscape(unsafe.Pointer(s)), nb, rt.NoEscape(unsafe.Pointer(dp)), rt.NoEscape(unsafe.Pointer(dn)), flags)
   104  }
   105  
   106  //go:nosplit
   107  func Unquote(s unsafe.Pointer, nb int, dp unsafe.Pointer, ep *int, flags uint64) int {
   108  	return __Unquote(rt.NoEscape(unsafe.Pointer(s)), nb, rt.NoEscape(unsafe.Pointer(dp)), rt.NoEscape(unsafe.Pointer(ep)), flags)
   109  }
   110  
   111  //go:nosplit
   112  func HTMLEscape(s unsafe.Pointer, nb int, dp unsafe.Pointer, dn *int) int {
   113  	return __HTMLEscape(rt.NoEscape(unsafe.Pointer(s)), nb, rt.NoEscape(unsafe.Pointer(dp)), rt.NoEscape(unsafe.Pointer(dn)))
   114  }
   115  
   116  //go:nosplit
   117  func Value(s unsafe.Pointer, n int, p int, v *types.JsonState, flags uint64) int {
   118  	return __Value(rt.NoEscape(unsafe.Pointer(s)), n, p, rt.NoEscape(unsafe.Pointer(v)), flags)
   119  }
   120  
   121  //go:nosplit
   122  func SkipOne(s *string, p *int, m *types.StateMachine, flags uint64) int {
   123  	return __SkipOne(rt.NoEscape(unsafe.Pointer(s)), rt.NoEscape(unsafe.Pointer(p)), rt.NoEscape(unsafe.Pointer(m)), flags)
   124  }
   125  
   126  //go:nosplit
   127  func SkipOneFast(s *string, p *int) int {
   128  	return __SkipOneFast(rt.NoEscape(unsafe.Pointer(s)), rt.NoEscape(unsafe.Pointer(p)))
   129  }
   130  
   131  //go:nosplit
   132  func GetByPath(s *string, p *int, path *[]interface{}, m *types.StateMachine) int {
   133  	return __GetByPath(rt.NoEscape(unsafe.Pointer(s)), rt.NoEscape(unsafe.Pointer(p)), rt.NoEscape(unsafe.Pointer(path)), rt.NoEscape(unsafe.Pointer(m)))
   134  }
   135  
   136  //go:nosplit
   137  func ValidateOne(s *string, p *int, m *types.StateMachine) int {
   138  	return __ValidateOne(rt.NoEscape(unsafe.Pointer(s)), rt.NoEscape(unsafe.Pointer(p)), rt.NoEscape(unsafe.Pointer(m)))
   139  }
   140  
   141  //go:nosplit
   142  func I64toa(out *byte, val int64) (ret int) {
   143  	return __I64toa(rt.NoEscape(unsafe.Pointer(out)), val)
   144  }
   145  
   146  //go:nosplit
   147  func U64toa(out *byte, val uint64) (ret int) {
   148  	return __U64toa(rt.NoEscape(unsafe.Pointer(out)), val)
   149  }
   150  
   151  //go:nosplit
   152  func F64toa(out *byte, val float64) (ret int) {
   153  	return __F64toa(rt.NoEscape(unsafe.Pointer(out)), val)
   154  }
   155  
   156  //go:nosplit
   157  func ValidateUTF8(s *string, p *int, m *types.StateMachine) (ret int) {
   158  	return __ValidateUTF8(rt.NoEscape(unsafe.Pointer(s)), rt.NoEscape(unsafe.Pointer(p)), rt.NoEscape(unsafe.Pointer(m)))
   159  }
   160  
   161  //go:nosplit
   162  func ValidateUTF8Fast(s *string) (ret int) {
   163  	return __ValidateUTF8Fast(rt.NoEscape(unsafe.Pointer(s)))
   164  }
   165  
   166  var stubs = []loader.GoC{
   167  	{"_f64toa", &S_f64toa, &__F64toa},
   168  	{"_f32toa", &S_f32toa, nil},
   169  	{"_i64toa", &S_i64toa, &__I64toa},
   170  	{"_u64toa", &S_u64toa, &__U64toa},
   171  	{"_lspace", &S_lspace, nil},
   172  	{"_quote", &S_quote, &__Quote},
   173  	{"_unquote", &S_unquote, &__Unquote},
   174  	{"_html_escape", &S_html_escape, &__HTMLEscape},
   175  	{"_value", &S_value, &__Value},
   176  	{"_vstring", &S_vstring, nil},
   177  	{"_vnumber", &S_vnumber, nil},
   178  	{"_vsigned", &S_vsigned, nil},
   179  	{"_vunsigned", &S_vunsigned, nil},
   180  	{"_skip_one", &S_skip_one, &__SkipOne},
   181  	{"_skip_one_fast", &S_skip_one_fast, &__SkipOneFast},
   182  	{"_get_by_path", &S_get_by_path, &__GetByPath},
   183  	{"_skip_array", &S_skip_array, nil},
   184  	{"_skip_object", &S_skip_object, nil},
   185  	{"_skip_number", &S_skip_number, nil},
   186  	{"_validate_one", &S_validate_one, &__ValidateOne},
   187  	{"_validate_utf8", &S_validate_utf8, &__ValidateUTF8},
   188  	{"_validate_utf8_fast", &S_validate_utf8_fast, &__ValidateUTF8Fast},
   189  }
   190  
   191  func useAVX() {
   192  	loader.WrapGoC(avx.Text__native_entry__, avx.Funcs, stubs, "avx", "avx/native.c")
   193  }
   194  
   195  func useAVX2() {
   196  	loader.WrapGoC(avx2.Text__native_entry__, avx2.Funcs, stubs, "avx2", "avx2/native.c")
   197  }
   198  
   199  func useSSE() {
   200  	loader.WrapGoC(sse.Text__native_entry__, sse.Funcs, stubs, "sse", "sse/native.c")
   201  }
   202  
   203  func init() {
   204  	if cpu.HasAVX2 {
   205  		useAVX2()
   206  	} else if cpu.HasAVX {
   207  		useAVX()
   208  	} else if cpu.HasSSE {
   209  		useSSE()
   210  	} else {
   211  		panic("Unsupported CPU, maybe it's too old to run Sonic.")
   212  	}
   213  }