github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/internal/decoder/norace_test.go (about)

     1  //go:build !race
     2  // +build !race
     3  
     4  /*
     5   * Copyright 2021 ByteDance Inc.
     6   *
     7   * Licensed under the Apache License, Version 2.0 (the "License");
     8   * you may not use this file except in compliance with the License.
     9   * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19  
    20  package decoder
    21  
    22  import (
    23      `runtime`
    24      `testing`
    25      `time`
    26      `unsafe`
    27  
    28      `github.com/bytedance/sonic/internal/rt`
    29  )
    30  
    31  var referred = false
    32  
    33  func TestStringReferring(t *testing.T) {
    34      str := []byte(`{"A":"0","B":"1"}`)
    35      sp := *(**byte)(unsafe.Pointer(&str))
    36      println("malloc *byte ", sp)
    37      runtime.SetFinalizer(sp, func(sp *byte){
    38          referred = false
    39          println("*byte ", sp, " got free 1")
    40      })
    41      runtime.GC()
    42      println("first GC")
    43      var obj struct{
    44          A string
    45          B string
    46      }
    47      dc := NewDecoder(rt.Mem2Str(str))
    48      dc.CopyString()
    49      referred = true
    50      if err := dc.Decode(&obj); err != nil {
    51          t.Fatal(err)
    52      }
    53      runtime.GC()
    54      println("second GC")
    55      time.Sleep(time.Millisecond)
    56      if referred {
    57          t.Fatal("*byte is being referred")
    58      }
    59  
    60      str2 := []byte(`{"A":"0","B":"1"}`)
    61      sp2 := *(**byte)(unsafe.Pointer(&str2))
    62      println("malloc *byte ", sp2)
    63      runtime.SetFinalizer(sp2, func(sp *byte){
    64          referred = false
    65          println("*byte ", sp, " got free")
    66      })
    67      runtime.GC()
    68      println("first GC")
    69      var obj2 interface{}
    70      dc2 := NewDecoder(rt.Mem2Str(str2))
    71      dc2.UseNumber()
    72      dc2.CopyString()
    73      referred = true
    74      if err := dc2.Decode(&obj2); err != nil {
    75          t.Fatal(err)
    76      }
    77      runtime.GC()
    78      println("second GC")
    79      time.Sleep(time.Millisecond)
    80      if referred {
    81          t.Fatal("*byte is being referred")
    82      }
    83      
    84      runtime.KeepAlive(&obj)
    85      runtime.KeepAlive(&obj2)
    86  }
    87  
    88  func TestDecoderErrorStackOverflower(t *testing.T) {
    89      src := `{"a":[]}`
    90      N := _MaxStack
    91      for i:=0; i<N; i++ {
    92          var obj map[string]string
    93          err := NewDecoder(src).Decode(&obj)
    94          if err == nil {
    95              t.Fatal(err)
    96          }
    97      }
    98  }