Skip to content

Commit bbbf759

Browse files
Simplify algorithm
1 parent a82b085 commit bbbf759

File tree

2 files changed

+12
-28
lines changed

2 files changed

+12
-28
lines changed

builder/sizes_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,10 @@ 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-
<<<<<<< HEAD
45-
{"hifive1b", "examples/echo", 4568, 280, 0, 2268},
46-
{"microbit", "examples/serial", 2868, 388, 8, 2272},
47-
{"wioterminal", "examples/pininterrupt", 6104, 1484, 116, 6832},
48-
=======
4944

5045
{"hifive1b", "examples/echo", 4720, 280, 0, 2252},
5146
{"microbit", "examples/serial", 2820, 388, 8, 2256},
5247
{"wioterminal", "examples/pininterrupt", 6091, 1485, 116, 6816},
53-
>>>>>>> 3214fcb5 (changed expected size so all tests can run)
5448

5549
// TODO: also check wasm. Right now this is difficult, because
5650
// wasm binaries are run through wasm-opt and therefore the

src/runtime/gc_blocks.go

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

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

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

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

158148
if gcAsserts {
159149
if b.state() != blockStateHead && b.state() != blockStateMark {

0 commit comments

Comments
 (0)