Skip to content

Commit 27f42da

Browse files
Simplify algorithm
1 parent 75f82df commit 27f42da

File tree

2 files changed

+14
-24
lines changed

2 files changed

+14
-24
lines changed

builder/sizes_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ func TestBinarySize(t *testing.T) {
4141
// This is a small number of very diverse targets that we want to test.
4242
tests := []sizeTest{
4343
// microcontrollers
44-
{"hifive1b", "examples/echo", 4720, 280, 0, 2252},
45-
{"microbit", "examples/serial", 2820, 388, 8, 2256},
44+
{"hifive1b", "examples/echo", 4716, 280, 0, 2252},
45+
{"microbit", "examples/serial", 2816, 388, 8, 2256},
4646
{"wioterminal", "examples/pininterrupt", 6091, 1485, 116, 6816},
4747

4848
// TODO: also check wasm. Right now this is difficult, because

src/runtime/gc_blocks.go

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -123,35 +123,25 @@ func (b gcBlock) address() uintptr {
123123
return addr
124124
}
125125

126-
// findHead returns the head (first block) of an object, assuming the block
127-
// points to an allocated object. It returns the same block if this block
128-
// already points to the head.
129126
func (b gcBlock) findHead() gcBlock {
130127
stateBytePtr := (*uint8)(unsafe.Add(metadataStart, b/blocksPerStateByte))
131128

132-
// XOR the stateByte with byte containing all tails to turn tail bits to 0
133-
// and shift out the bits that are not part of the object
134-
stateByte := ((*stateBytePtr) ^ blockStateByteAllTails) << ((blocksPerStateByte - (b%blocksPerStateByte + 1)) * stateBits)
135-
// if stateByte is 0 that means all blocks are tails so we loop trough subsequent states,
136-
// byte at a time to find the first byte that is not all tails
137-
if stateByte == 0 {
138-
// subtract the number of object blocks that were in the first byte
139-
b -= (b%blocksPerStateByte + 1)
140-
// skip to next byte
129+
// XOR the stateByte with byte containing all tails to turn tail bits to 0 and
130+
// mask out the bits that are not part of the object
131+
otherObjectBlocks := int(blocksPerStateByte - (b%blocksPerStateByte + 1))
132+
stateByte := ((*stateBytePtr) ^ blockStateByteAllTails) & (uint8(1<<(8-(otherObjectBlocks*stateBits))) - 1)
133+
134+
// loop until state byte is not all tails
135+
for stateByte == 0 {
141136
stateBytePtr = (*uint8)(unsafe.Add(unsafe.Pointer(stateBytePtr), -1))
142-
// loop until state byte is not all tails
143-
for (*stateBytePtr)^blockStateByteAllTails == 0 {
144-
stateBytePtr = (*uint8)(unsafe.Add(unsafe.Pointer(stateBytePtr), -1))
145-
b -= blocksPerStateByte
146-
}
147-
// set stateByte variable to the first byte that is not all tails and turn all tail bits to zeroes
148137
stateByte = (*stateBytePtr) ^ blockStateByteAllTails
138+
b -= blocksPerStateByte
149139
}
150140

151-
// at this point stateByte is set to the first state byte of the object that we encountered which is not all tails
152-
// and all tail bits in it are turned to zero. We count number of bytes that are 0 (tail) using LeadingZeros8
153-
// and divide it by stateBits to get the number of tail blocks in state bits.
154-
b -= gcBlock(bits.LeadingZeros8(stateByte) / stateBits)
141+
// in the first state byte which is not all tails, count the number of leading bits that are 0 and
142+
// divide it by stateBits to get the number of tail blocks. Subtract otherObjectBlocks to exclude
143+
// blocks that are not part of the object
144+
b -= gcBlock((bits.LeadingZeros8(stateByte) / stateBits) - otherObjectBlocks)
155145

156146
if gcAsserts {
157147
if b.state() != blockStateHead && b.state() != blockStateMark {

0 commit comments

Comments
 (0)