Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit b4cf9fe

Browse files
committed
inline optimizations
1 parent 5e3736e commit b4cf9fe

File tree

2 files changed

+109
-67
lines changed

2 files changed

+109
-67
lines changed

src/gc/bits.d

Lines changed: 98 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct GCBits
5555
onOutOfMemoryError();
5656
}
5757

58+
pragma(inline,true)
5859
wordtype test(size_t i) const nothrow
5960
in
6061
{
@@ -65,6 +66,7 @@ struct GCBits
6566
return core.bitop.bt(data, i);
6667
}
6768

69+
pragma(inline,true)
6870
int set(size_t i) nothrow
6971
in
7072
{
@@ -75,6 +77,7 @@ struct GCBits
7577
return core.bitop.bts(data, i);
7678
}
7779

80+
pragma(inline,true)
7881
int clear(size_t i) nothrow
7982
in
8083
{
@@ -94,8 +97,36 @@ struct GCBits
9497
size_t lastOff = last & BITS_MASK;
9598
}
9699

100+
// extract loops to allow inlining the rest
101+
void clearWords(size_t firstWord, size_t lastWord) nothrow
102+
{
103+
for(size_t w = firstWord; w < lastWord; w++)
104+
data[w] = 0;
105+
}
106+
107+
void setWords(size_t firstWord, size_t lastWord) nothrow
108+
{
109+
for(size_t w = firstWord; w < lastWord; w++)
110+
data[w] = ~0;
111+
}
112+
113+
void copyWords(size_t firstWord, size_t lastWord, const(wordtype)* source) nothrow
114+
{
115+
for(size_t w = firstWord; w < lastWord; w++)
116+
data[w] = source[w - firstWord];
117+
}
118+
119+
void copyWordsShifted(size_t firstWord, size_t cntWords, size_t firstOff, const(wordtype)* source) nothrow
120+
{
121+
wordtype mask = ~BITS_0 << firstOff;
122+
data[firstWord] = (data[firstWord] & ~mask) | (source[0] << firstOff);
123+
for(size_t w = 1; w < cntWords; w++)
124+
data[firstWord + w] = (source[w - 1] >> (BITS_PER_WORD - firstOff)) | (source[w] << firstOff);
125+
}
126+
97127
// target = the biti to start the copy to
98128
// destlen = the number of bits to copy from source
129+
pragma(inline,true)
99130
void copyRange(size_t target, size_t len, const(wordtype)* source) nothrow
100131
{
101132
version(bitwise)
@@ -108,36 +139,36 @@ struct GCBits
108139
}
109140
else
110141
{
111-
if(len == 0)
112-
return;
142+
if(len > 0)
143+
copyRangeZ(target, len, source);
144+
}
145+
}
113146

114-
mixin RangeVars!();
147+
pragma(inline,true)
148+
void copyRangeZ(size_t target, size_t len, const(wordtype)* source) nothrow
149+
{
150+
mixin RangeVars!();
115151

116-
if(firstWord == lastWord)
117-
{
118-
wordtype mask = ((BITS_2 << (lastOff - firstOff)) - 1) << firstOff;
119-
data[firstWord] = (data[firstWord] & ~mask) | ((source[0] << firstOff) & mask);
120-
}
121-
else if(firstOff == 0)
122-
{
123-
for(size_t w = firstWord; w < lastWord; w++)
124-
data[w] = source[w - firstWord];
152+
if(firstWord == lastWord)
153+
{
154+
wordtype mask = ((BITS_2 << (lastOff - firstOff)) - 1) << firstOff;
155+
data[firstWord] = (data[firstWord] & ~mask) | ((source[0] << firstOff) & mask);
156+
}
157+
else if(firstOff == 0)
158+
{
159+
copyWords(firstWord, lastWord, source);
125160

126-
wordtype mask = (BITS_2 << lastOff) - 1;
127-
data[lastWord] = (data[lastWord] & ~mask) | (source[lastWord - firstWord] & mask);
128-
}
129-
else
130-
{
131-
size_t cntWords = lastWord - firstWord;
132-
wordtype mask = ~BITS_0 << firstOff;
133-
data[firstWord] = (data[firstWord] & ~mask) | (source[0] << firstOff);
134-
for(size_t w = 1; w < cntWords; w++)
135-
data[firstWord + w] = (source[w - 1] >> (BITS_PER_WORD - firstOff)) | (source[w] << firstOff);
136-
137-
wordtype src = (source[cntWords - 1] >> (BITS_PER_WORD - firstOff)) | (source[cntWords] << firstOff);
138-
mask = (BITS_2 << lastOff) - 1;
139-
data[lastWord] = (data[lastWord] & ~mask) | (src & mask);
140-
}
161+
wordtype mask = (BITS_2 << lastOff) - 1;
162+
data[lastWord] = (data[lastWord] & ~mask) | (source[lastWord - firstWord] & mask);
163+
}
164+
else
165+
{
166+
size_t cntWords = lastWord - firstWord;
167+
copyWordsShifted(firstWord, cntWords, firstOff, source);
168+
169+
wordtype src = (source[cntWords - 1] >> (BITS_PER_WORD - firstOff)) | (source[cntWords] << firstOff);
170+
wordtype mask = (BITS_2 << lastOff) - 1;
171+
data[lastWord] = (data[lastWord] & ~mask) | (src & mask);
141172
}
142173
}
143174

@@ -227,6 +258,7 @@ struct GCBits
227258
}
228259
}
229260

261+
pragma(inline,true)
230262
void setRange(size_t target, size_t len) nothrow
231263
{
232264
version(bitwise)
@@ -236,27 +268,31 @@ struct GCBits
236268
}
237269
else
238270
{
239-
if(len == 0)
240-
return;
271+
if(len > 0)
272+
setRangeZ(target, len);
273+
}
274+
}
241275

242-
mixin RangeVars!();
276+
pragma(inline,true)
277+
void setRangeZ(size_t target, size_t len) nothrow
278+
{
279+
mixin RangeVars!();
243280

244-
if(firstWord == lastWord)
245-
{
246-
wordtype mask = ((BITS_2 << (lastOff - firstOff)) - 1) << firstOff;
247-
data[firstWord] |= mask;
248-
}
249-
else
250-
{
251-
data[firstWord] |= ~BITS_0 << firstOff;
252-
for(size_t w = firstWord + 1; w < lastWord; w++)
253-
data[w] = ~0;
254-
wordtype mask = (BITS_2 << lastOff) - 1;
255-
data[lastWord] |= mask;
256-
}
281+
if(firstWord == lastWord)
282+
{
283+
wordtype mask = ((BITS_2 << (lastOff - firstOff)) - 1) << firstOff;
284+
data[firstWord] |= mask;
285+
}
286+
else
287+
{
288+
data[firstWord] |= ~BITS_0 << firstOff;
289+
setWords(firstWord + 1, lastWord);
290+
wordtype mask = (BITS_2 << lastOff) - 1;
291+
data[lastWord] |= mask;
257292
}
258293
}
259294

295+
pragma(inline,true)
260296
void clrRange(size_t target, size_t len) nothrow
261297
{
262298
version(bitwise)
@@ -266,24 +302,26 @@ struct GCBits
266302
}
267303
else
268304
{
269-
if(len == 0)
270-
return;
271-
272-
mixin RangeVars!();
305+
if(len > 0)
306+
clrRangeZ(target, len);
307+
}
308+
}
273309

274-
if(firstWord == lastWord)
275-
{
276-
wordtype mask = ((BITS_2 << (lastOff - firstOff)) - 1) << firstOff;
277-
data[firstWord] &= ~mask;
278-
}
279-
else
280-
{
281-
data[firstWord] &= ~(~BITS_0 << firstOff);
282-
for(size_t w = firstWord + 1; w < lastWord; w++)
283-
data[w] = 0;
284-
wordtype mask = (BITS_2 << lastOff) - 1;
285-
data[lastWord] &= ~mask;
286-
}
310+
pragma(inline,true)
311+
void clrRangeZ(size_t target, size_t len) nothrow
312+
{
313+
mixin RangeVars!();
314+
if(firstWord == lastWord)
315+
{
316+
wordtype mask = ((BITS_2 << (lastOff - firstOff)) - 1) << firstOff;
317+
data[firstWord] &= ~mask;
318+
}
319+
else
320+
{
321+
data[firstWord] &= ~(~BITS_0 << firstOff);
322+
clearWords(firstWord + 1, lastWord);
323+
wordtype mask = (BITS_2 << lastOff) - 1;
324+
data[lastWord] &= ~mask;
287325
}
288326
}
289327

src/gc/gc.d

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ struct GC
862862
{
863863
auto biti = cast(size_t)(p - pool.baseAddr) >> pool.shiftBy;
864864
if(!pool.noscan.test(biti))
865-
pool.setPointerBitmap(p, psize + sz * PAGESIZE, psize + sz * PAGESIZE, ti, true);
865+
pool.setPointerBitmap(p, psize + sz * PAGESIZE, psize + sz * PAGESIZE, ti, BlkAttr.REP_RTINFO);
866866
}
867867

868868
return (psz + sz) * PAGESIZE;
@@ -1209,7 +1209,7 @@ struct GC
12091209
size_t allocSize = len;
12101210
else
12111211
size_t allocSize = info.size - (p - info.base);
1212-
pool.setPointerBitmap(p, len, allocSize, ti, true);
1212+
pool.setPointerBitmap(p, len, allocSize, ti, BlkAttr.REP_RTINFO);
12131213
return true;
12141214
}
12151215

@@ -3133,13 +3133,15 @@ struct Pool
31333133
}
31343134
}
31353135

3136+
pragma(inline,true)
31363137
void setPointerBitmap(void* p, size_t s, size_t allocSize, uint attr, const TypeInfo ti) nothrow
31373138
{
31383139
if (!(attr & (BlkAttr.NO_SCAN | BlkAttr.NO_RTINFO)))
3139-
setPointerBitmap(p, s, allocSize, ti, (attr & BlkAttr.REP_RTINFO) != 0);
3140+
setPointerBitmap(p, s, allocSize, ti, attr);
31403141
}
31413142

3142-
void setPointerBitmap(void* p, size_t s, size_t allocSize, const TypeInfo ti, bool repeat) nothrow
3143+
pragma(inline,false)
3144+
void setPointerBitmap(void* p, size_t s, size_t allocSize, const TypeInfo ti, uint attr) nothrow
31433145
{
31443146
size_t offset = p - baseAddr;
31453147
//debug(PRINTF) printGCBits(&pool.is_pointer);
@@ -3149,7 +3151,7 @@ struct Pool
31493151

31503152
if (ti)
31513153
{
3152-
if (repeat)
3154+
if (attr & BlkAttr.REP_RTINFO)
31533155
s = allocSize;
31543156

31553157
auto rtInfo = cast(const(size_t)*)ti.rtInfo();
@@ -3171,7 +3173,7 @@ struct Pool
31713173
size_t element_size = * bitmap;
31723174
bitmap++;
31733175
size_t tocopy;
3174-
if(repeat)
3176+
if(attr & BlkAttr.REP_RTINFO)
31753177
{
31763178
tocopy = s/(void*).sizeof;
31773179
is_pointer.copyRangeRepeating(offset/(void*).sizeof, tocopy, bitmap, element_size/(void*).sizeof);
@@ -3204,7 +3206,9 @@ struct Pool
32043206
}
32053207
else
32063208
{
3207-
s = allocSize;
3209+
// limit pointers to actual size of allocation? might fail for arrays that append
3210+
// without notifying the GC
3211+
s = allocSize;
32083212

32093213
debug(PRINTF) printf("Allocating a block without TypeInfo\n");
32103214
is_pointer.setRange(offset/(void*).sizeof, s/(void*).sizeof);

0 commit comments

Comments
 (0)