Skip to content

Commit bb7a67c

Browse files
committed
Get rid of ValuePointerS structure to decrease stack allocation size and to improve performance
1 parent 4bb6b2b commit bb7a67c

1 file changed

Lines changed: 42 additions & 58 deletions

File tree

Orm/Xtensive.Orm/Tuples/Packed/TupleLayout.cs

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,6 @@ internal static class TupleLayout
1818
private const int Val008Rank = 3;
1919

2020
private const int Val064BitCount = 1 << Val064Rank;
21-
private const int Val032BitCount = 1 << Val032Rank;
22-
private const int Modulo064RemainderMask = Val064BitCount - 1;
23-
private const int Modulo032RemainderMask = Val032BitCount - 1;
24-
25-
private ref struct ValPointers
26-
{
27-
public int Val001Pointer;
28-
public int Val008Pointer;
29-
public int Val016Pointer;
30-
public int Val032Pointer;
31-
public int Val064Pointer;
32-
public int Val128Pointer;
33-
}
3421

3522
private ref struct ValCounters
3623
{
@@ -139,7 +126,7 @@ ValueFieldAccessor ResolveByNullableType(Type type) =>
139126

140127
private delegate void CounterIncrementer(ref ValCounters valCounters);
141128

142-
private delegate void PositionUpdater(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers);
129+
private delegate void PositionUpdater(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters);
143130

144131
private static readonly ObjectFieldAccessor ObjectAccessor = new ObjectFieldAccessor();
145132
private static readonly CounterIncrementer[] IncrementerByRank;
@@ -213,48 +200,45 @@ public static void Configure(Type[] fieldTypes, PackedFieldDescriptor[] fieldDes
213200
out int objectsLength)
214201
{
215202
var fieldCount = fieldTypes.Length;
216-
const int statesPerLong = Val064BitCount / 2;
217-
var stateBitCount = ((fieldCount + (statesPerLong - 1)) >> Val032Rank) << Val064Rank;
218-
219203
var valCounters = new ValCounters();
220204
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
221205
ConfigureFieldPhase1(ref fieldDescriptors[fieldIndex], ref valCounters, fieldTypes, fieldIndex);
222206
}
223207

224-
var vPointers = new ValPointers();
225-
var totalBitCount = InitValPointers(stateBitCount, ref valCounters, ref vPointers);
208+
const int statesPerLong = Val064BitCount / 2;
226209

227-
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
228-
ConfigureFieldPhase2(ref fieldDescriptors[fieldIndex], ref vPointers);
229-
}
210+
var totalBitCount = ((fieldCount + (statesPerLong - 1)) >> Val032Rank) << Val064Rank;
211+
var prevCount = valCounters.Val128Counter;
212+
valCounters.Val128Counter = totalBitCount;
230213

231-
valuesLength = (totalBitCount + (Val064BitCount - 1)) >> Val064Rank;
232-
objectsLength = valCounters.ObjectCounter;
233-
}
214+
totalBitCount += prevCount << Val128Rank;
215+
prevCount = valCounters.Val064Counter;
216+
valCounters.Val064Counter = totalBitCount;
234217

235-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
236-
private static int InitValPointers(int stateBitCount, ref ValCounters valCounters, ref ValPointers vPointers)
237-
{
238-
var totalBitCount = stateBitCount;
239-
vPointers.Val128Pointer = totalBitCount;
218+
totalBitCount += prevCount << Val064Rank;
219+
prevCount = valCounters.Val032Counter;
220+
valCounters.Val032Counter = totalBitCount;
240221

241-
totalBitCount += valCounters.Val128Counter << Val128Rank;
242-
vPointers.Val064Pointer = totalBitCount;
222+
totalBitCount += prevCount << Val032Rank;
223+
prevCount = valCounters.Val016Counter;
224+
valCounters.Val016Counter = totalBitCount;
243225

244-
totalBitCount += valCounters.Val064Counter << Val064Rank;
245-
vPointers.Val032Pointer = totalBitCount;
226+
totalBitCount += prevCount << Val016Rank;
227+
prevCount = valCounters.Val008Counter;
228+
valCounters.Val008Counter = totalBitCount;
246229

247-
totalBitCount += valCounters.Val032Counter << Val032Rank;
248-
vPointers.Val016Pointer = totalBitCount;
230+
totalBitCount += prevCount << Val008Rank;
231+
prevCount = valCounters.Val001Counter;
232+
valCounters.Val001Counter = totalBitCount;
249233

250-
totalBitCount += valCounters.Val016Counter << Val016Rank;
251-
vPointers.Val008Pointer = totalBitCount;
234+
totalBitCount += prevCount;
252235

253-
totalBitCount += valCounters.Val008Counter << Val008Rank;
254-
vPointers.Val001Pointer = totalBitCount;
236+
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
237+
ConfigureFieldPhase2(ref fieldDescriptors[fieldIndex], ref valCounters);
238+
}
255239

256-
totalBitCount += valCounters.Val001Counter;
257-
return totalBitCount;
240+
valuesLength = (totalBitCount + (Val064BitCount - 1)) >> Val064Rank;
241+
objectsLength = valCounters.ObjectCounter;
258242
}
259243

260244
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -285,14 +269,14 @@ private static void ConfigureFieldPhase1(ref PackedFieldDescriptor descriptor, r
285269
}
286270

287271
[MethodImpl(MethodImplOptions.AggressiveInlining)]
288-
private static void ConfigureFieldPhase2(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
272+
private static void ConfigureFieldPhase2(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
289273
{
290274
if (descriptor.IsObjectField) {
291275
return;
292276
}
293277

294278
// d.PackingType == FieldPackingType.Value
295-
PositionUpdaterByRank[descriptor.Accessor.Rank].Invoke(ref descriptor, ref valPointers);
279+
PositionUpdaterByRank[descriptor.Accessor.Rank].Invoke(ref descriptor, ref valCounters);
296280
}
297281

298282
static TupleLayout()
@@ -309,22 +293,22 @@ static TupleLayout()
309293
};
310294

311295
PositionUpdaterByRank = new PositionUpdater[] {
312-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
313-
=> UpdateDescriptorPosition(ref descriptor, ref valPointers.Val001Pointer),
314-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
296+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
297+
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val001Counter),
298+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
315299
=> throw new NotSupportedException(),
316-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
300+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
317301
=> throw new NotSupportedException(),
318-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
319-
=> UpdateDescriptorPosition(ref descriptor, ref valPointers.Val008Pointer),
320-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
321-
=> UpdateDescriptorPosition(ref descriptor, ref valPointers.Val016Pointer),
322-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
323-
=> UpdateDescriptorPosition(ref descriptor, ref valPointers.Val032Pointer),
324-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
325-
=> UpdateDescriptorPosition(ref descriptor, ref valPointers.Val064Pointer),
326-
(ref PackedFieldDescriptor descriptor, ref ValPointers valPointers)
327-
=> UpdateDescriptorPosition(ref descriptor, ref valPointers.Val128Pointer)
302+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
303+
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val008Counter),
304+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
305+
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val016Counter),
306+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
307+
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val032Counter),
308+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
309+
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val064Counter),
310+
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
311+
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val128Counter)
328312
};
329313
}
330314
}

0 commit comments

Comments
 (0)