Skip to content

Commit f1266b6

Browse files
authored
reduce size of Array!T from 32 to 16 bytes (#23404)
- allocates a maximum of uint.max entries - overlaps single entry with pointer to array
1 parent 9e5aeed commit f1266b6

5 files changed

Lines changed: 102 additions & 98 deletions

File tree

compiler/include/dmd/root/array.h

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,32 @@
1414
template <typename TYPE>
1515
struct Array
1616
{
17-
d_size_t length;
17+
uint32_t length;
1818

1919
private:
20-
DArray<TYPE> data;
20+
uint32_t allocated;
2121
#define SMALLARRAYCAP 1
22-
TYPE smallarray[SMALLARRAYCAP]; // inline storage for small arrays
22+
union
23+
{
24+
TYPE smallarray[SMALLARRAYCAP]; // inline storage for small arrays
25+
TYPE* _ptr;
26+
};
27+
TYPE* data() { return allocated <= SMALLARRAYCAP ? smallarray : _ptr; }
28+
const TYPE* data() const { return allocated <= SMALLARRAYCAP ? smallarray : _ptr; }
2329

2430
Array(const Array&);
2531

2632
public:
2733
Array()
2834
{
29-
data.ptr = nullptr;
3035
length = 0;
31-
data.length = 0;
36+
allocated = SMALLARRAYCAP;
3237
}
3338

3439
~Array()
3540
{
36-
if (data.ptr != &smallarray[0])
37-
mem.xfree(data.ptr);
41+
if (allocated > SMALLARRAYCAP)
42+
mem.xfree(_ptr);
3843
}
3944

4045
char *toChars() const
@@ -43,7 +48,7 @@ struct Array
4348
d_size_t len = 2;
4449
for (d_size_t u = 0; u < length; u++)
4550
{
46-
buf[u] = ((TYPE)data.ptr[u])->toChars();
51+
buf[u] = (data()[u])->toChars();
4752
len += strlen(buf[u]) + 1;
4853
}
4954
char *str = (char *)mem.xmalloc(len);
@@ -67,7 +72,7 @@ struct Array
6772
void push(TYPE ptr)
6873
{
6974
reserve(1);
70-
data.ptr[length++] = ptr;
75+
data()[length++] = ptr;
7176
}
7277

7378
void append(Array *a)
@@ -77,67 +82,67 @@ struct Array
7782

7883
void reserve(d_size_t nentries)
7984
{
80-
//printf("Array::reserve: length = %d, data.length = %d, nentries = %d\n", (int)length, (int)data.length, (int)nentries);
81-
if (data.length - length < nentries)
85+
//printf("Array::reserve: length = %d, allocated = %d, nentries = %d\n", (int)length, (int)allocated, (int)nentries);
86+
if (allocated - length < nentries)
8287
{
83-
if (data.length == 0)
88+
if (allocated == 0)
8489
{
8590
// Not properly initialized, someone memset it to zero
8691
if (nentries <= SMALLARRAYCAP)
8792
{
88-
data.length = SMALLARRAYCAP;
89-
data.ptr = SMALLARRAYCAP ? &smallarray[0] : nullptr;
93+
allocated = SMALLARRAYCAP;
9094
}
9195
else
9296
{
93-
data.length = nentries;
94-
data.ptr = (TYPE *)mem.xmalloc(data.length * sizeof(TYPE));
97+
allocated = nentries;
98+
_ptr = (TYPE *)mem.xmalloc(allocated * sizeof(TYPE));
9599
}
96100
}
97-
else if (data.length == SMALLARRAYCAP)
101+
else if (allocated <= SMALLARRAYCAP)
98102
{
99-
data.length = length + nentries;
100-
data.ptr = (TYPE *)mem.xmalloc(data.length * sizeof(TYPE));
101-
memcpy(data.ptr, &smallarray[0], length * sizeof(TYPE));
103+
allocated = length + nentries;
104+
TYPE* p = (TYPE *)mem.xmalloc(allocated * sizeof(TYPE));
105+
memcpy(p, &smallarray[0], length * sizeof(TYPE));
106+
_ptr = p;
102107
}
103108
else
104109
{
105110
/* Increase size by 1.5x to avoid excessive memory fragmentation
106111
*/
107-
d_size_t increment = length / 2;
112+
auto increment = length / 2;
108113
if (nentries > increment) // if 1.5 is not enough
109-
increment = nentries;
110-
data.length = length + increment;
111-
data.ptr = (TYPE *)mem.xrealloc(data.ptr, data.length * sizeof(TYPE));
114+
increment = (uint32_t)nentries;
115+
allocated = length + increment;
116+
_ptr = (TYPE *)mem.xrealloc(_ptr, allocated * sizeof(TYPE));
112117
}
113118
}
114119
}
115120

116121
void remove(d_size_t i)
117122
{
118123
if (length - i - 1)
119-
memmove(data.ptr + i, data.ptr + i + 1, (length - i - 1) * sizeof(TYPE));
124+
memmove(data() + i, data() + i + 1, (length - i - 1) * sizeof(TYPE));
120125
length--;
121126
}
122127

123128
void insert(d_size_t index, Array *a)
124129
{
125130
if (a)
126131
{
127-
d_size_t d = a->length;
132+
auto d = a->length;
128133
reserve(d);
129134
if (length != index)
130-
memmove(data.ptr + index + d, data.ptr + index, (length - index) * sizeof(TYPE));
131-
memcpy(data.ptr + index, a->data.ptr, d * sizeof(TYPE));
135+
memmove(data() + index + d, data() + index, (length - index) * sizeof(TYPE));
136+
memcpy(data() + index, a->data(), d * sizeof(TYPE));
132137
length += d;
133138
}
134139
}
135140

136141
void insert(d_size_t index, TYPE ptr)
137142
{
138143
reserve(1);
139-
memmove(data.ptr + index + 1, data.ptr + index, (length - index) * sizeof(TYPE));
140-
data.ptr[index] = ptr;
144+
memmove(data() + index + 1, data() + index, (length - index) * sizeof(TYPE));
145+
data()[index] = ptr;
141146
length++;
142147
}
143148

@@ -154,7 +159,7 @@ struct Array
154159
{
155160
for (d_size_t i = 0; i < length; i++)
156161
{
157-
if (data.ptr[i] == ptr)
162+
if (data()[i] == ptr)
158163
return i;
159164
}
160165
return SIZE_MAX;
@@ -170,37 +175,37 @@ struct Array
170175
#ifdef DEBUG
171176
assert(index < length);
172177
#endif
173-
return data.ptr[index];
178+
return data()[index];
174179
}
175180

176181
TYPE *tdata()
177182
{
178-
return data.ptr;
183+
return data();
179184
}
180185

181186
Array *copy()
182187
{
183188
Array *a = new Array();
184189
a->setDim(length);
185-
memcpy(a->data.ptr, data.ptr, length * sizeof(TYPE));
190+
memcpy(a->data(), data(), length * sizeof(TYPE));
186191
return a;
187192
}
188193

189194
void shift(TYPE ptr)
190195
{
191196
reserve(1);
192-
memmove(data.ptr + 1, data.ptr, length * sizeof(TYPE));
193-
data.ptr[0] = ptr;
197+
memmove(data() + 1, data(), length * sizeof(TYPE));
198+
data()[0] = ptr;
194199
length++;
195200
}
196201

197202
void zero()
198203
{
199-
memset(data.ptr, 0, length * sizeof(TYPE));
204+
memset(data(), 0, length * sizeof(TYPE));
200205
}
201206

202207
TYPE pop()
203208
{
204-
return data.ptr[--length];
209+
return data()[--length];
205210
}
206211
};

compiler/src/dmd/dinterpret.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6903,7 +6903,7 @@ private Expression interpret_aaDel(UnionExp* pue, InterState* istate, Expression
69036903
AssocArrayLiteralExp aae = agg.isAssocArrayLiteralExp();
69046904
Expressions* keysx = aae.keys;
69056905
Expressions* valuesx = aae.values;
6906-
size_t removed = 0;
6906+
uint removed = 0;
69076907
foreach (j, evalue; *valuesx)
69086908
{
69096909
Expression ekey = (*keysx)[j];

compiler/src/dmd/doc.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5083,7 +5083,7 @@ void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
50835083

50845084
// build the template parameters
50855085
Array!(size_t) paramLens;
5086-
paramLens.reserve(td.parameters.length);
5086+
paramLens.setDim(td.parameters.length);
50875087

50885088
OutBuffer parametersBuf;
50895089
HdrGenState hgs;

0 commit comments

Comments
 (0)