github.com/wasilibs/nottinygc@v0.7.2-0.20240312114022-d59c9478ef51/bitmap_test.go (about)

     1  // Copyright wasilibs authors
     2  // SPDX-License-Identifier: MIT
     3  
     4  package nottinygc
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  )
    10  
    11  func TestBitmap32Bits(t *testing.T) {
    12  	tests := []uintptr{
    13  		0,
    14  		0b1,
    15  		0b101,
    16  		0b111,
    17  		0b0001,
    18  		0b1000001,
    19  		0xFFFFFFFF,
    20  		0x11111111,
    21  		0x01010101,
    22  		0x0F0F0F0F,
    23  	}
    24  
    25  	for _, tc := range tests {
    26  		tc := tc
    27  		t.Run(fmt.Sprintf("%v", tc), func(t *testing.T) {
    28  			bm := newBitmap(32)
    29  			defer bm.free()
    30  
    31  			if len(bm.words) != 1 {
    32  				t.Fatalf("expected 1 word, got %v", len(bm.words))
    33  			}
    34  			for i := 0; i < 32; i++ {
    35  				if tc&(1<<i) != 0 {
    36  					bm.set(uintptr(i))
    37  				}
    38  			}
    39  
    40  			for i := 0; i < 32; i++ {
    41  				got := bm.get(uintptr(i))
    42  				if tc&(1<<i) != 0 {
    43  					if got == 0 {
    44  						t.Fatalf("expected bit %v to be set", i)
    45  					}
    46  				} else {
    47  					if got != 0 {
    48  						t.Fatalf("expected bit %v to be unset", i)
    49  					}
    50  				}
    51  			}
    52  		})
    53  	}
    54  }
    55  
    56  // Test for multiple words, we pick larger than 64-bits to have more than one word on Go
    57  // as well. We don't actually run CI with Go but it can be helpful for development.
    58  func TestBitmap128Bits(t *testing.T) {
    59  	// We'll just repeat these.
    60  	tests := []uintptr{
    61  		0,
    62  		0b1,
    63  		0b101,
    64  		0b111,
    65  		0b0001,
    66  		0b1000001,
    67  		0xFFFFFFFF,
    68  		0x11111111,
    69  		0x01010101,
    70  		0x0F0F0F0F,
    71  	}
    72  
    73  	for _, tc := range tests {
    74  		tc := tc
    75  		t.Run(fmt.Sprintf("%v", tc), func(t *testing.T) {
    76  			bm := newBitmap(128)
    77  			defer bm.free()
    78  
    79  			if cppWordsz == 32 && len(bm.words) != 4 || cppWordsz == 64 && len(bm.words) != 2 {
    80  				t.Fatalf("got %v words", len(bm.words))
    81  			}
    82  			for j := 0; j < 4; j++ {
    83  				for i := 0; i < 32; i++ {
    84  					if tc&(1<<(32*j+i)) != 0 {
    85  						bm.set(uintptr(i))
    86  					}
    87  				}
    88  			}
    89  
    90  			for j := 0; j < 4; j++ {
    91  				for i := 0; i < 32; i++ {
    92  					got := bm.get(uintptr(32*j + i))
    93  					if tc&(1<<(32*j+i)) != 0 {
    94  						if got == 0 {
    95  							t.Fatalf("expected bit %v to be set", i)
    96  						}
    97  					} else {
    98  						if got != 0 {
    99  							t.Fatalf("expected bit %v to be unset", i)
   100  						}
   101  					}
   102  				}
   103  			}
   104  		})
   105  	}
   106  }