Skip to content

Commit 01c5b16

Browse files
author
Vyacheslav
committed
feat: The size of an IntPtr is system dependent. Therefore, if there is one in the properties, we calculate the size and offsets when the project is launched and not when it is generated.
1 parent e207e57 commit 01c5b16

File tree

13 files changed

+562
-385
lines changed

13 files changed

+562
-385
lines changed

Src/Benchmarks/Stack/Optimal/ClassOptimalJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void StackMemory()
1616
{
1717
unsafe
1818
{
19-
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobClassHelper.GetSize() + (JobClassHelper.GetSize() * (nuint)Size)))
19+
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobClassHelper.SizeOf + (JobClassHelper.SizeOf * (nuint)Size)))
2020
{
2121
var item = new Benchmark.Struct.JobClassWrapper(&memory);
2222
for (int j = 0; j < 100; j++)

Src/Benchmarks/Stack/Optimal/StructOptimalJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void StackMemory()
1616
{
1717
unsafe
1818
{
19-
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobStructHelper.GetSize() * (nuint)Size))
19+
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobStructHelper.SizeOf * (nuint)Size))
2020
{
2121
var item = new JobStruct(0, 0);
2222
for (int j = 0; j < 100; j++)

Src/Benchmarks/Stack/Simple/ClassSimpleJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void StackMemory()
1616
{
1717
unsafe
1818
{
19-
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobClassHelper.GetSize() + (JobClassHelper.GetSize() * (nuint)Size)))
19+
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobClassHelper.SizeOf + (JobClassHelper.SizeOf * (nuint)Size)))
2020
{
2121
var item = new Benchmark.Struct.JobClassWrapper(&memory);
2222
using var stack = new Benchmark.Struct.StackOfJobClass((nuint)Size, &memory);

Src/Benchmarks/Stack/Simple/StructSimpleJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void StackMemory()
1616
{
1717
unsafe
1818
{
19-
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobStructHelper.GetSize() * (nuint)Size))
19+
using (var memory = new StackMemoryCollections.Struct.StackMemory(JobStructHelper.SizeOf * (nuint)Size))
2020
{
2121
var item = new JobStruct(0, 0);
2222
using var stack = new Benchmark.Struct.StackOfJobStruct((nuint)Size, &memory);

Src/StackMemoryCollections/GenerateHelpers.cs

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.CodeAnalysis;
22
using System;
33
using System.Collections.Generic;
4-
using System.Linq;
54
using System.Text;
65

76
namespace StackMemoryCollections
@@ -26,36 +25,39 @@ in StringBuilder builder
2625
}
2726

2827
GenerateStart(in builder, in currentType);
29-
GenerateSize(in builder, in typeInfo);
28+
GenerateOffsetsAndSize(in builder, in typeInfo);
3029
GenerateIsNullable(in builder, in typeInfo);
3130

32-
3331
for (int j = 0; j < typeInfo.Members.Count; j++)
3432
{
3533
MemberInfo memberInfo = typeInfo.Members[j];
36-
GenerateGetPtr(in builder, in memberInfo);
34+
var offsetStr = memberInfo.IsRuntimeOffsetCalculated ? $"{currentType.Name}Helper.{memberInfo.MemberName}Offset" : $"{memberInfo.Offset}";
35+
GenerateGetPtr(in builder, in memberInfo, in offsetStr);
3736

3837
if (memberInfo.IsPrimitive)
3938
{
40-
GenerateGetPrimitiveValue(in builder, in memberInfo);
41-
GenerateGetPrimitiveValueRef(in builder, in memberInfo);
42-
GenerateGetPrimitiveValueOut(in builder, in memberInfo);
39+
GenerateGetPrimitiveValue(in builder, in memberInfo, in offsetStr);
40+
GenerateGetPrimitiveValueRef(in builder, in memberInfo, in offsetStr);
41+
GenerateGetPrimitiveValueOut(in builder, in memberInfo, in offsetStr);
4342

44-
GenerateSetPrimitiveValue(in builder, in memberInfo);
45-
GenerateSetPrimitiveValueFromPtr(in builder, in memberInfo);
46-
GenerateSetPrimitiveValueFrom(in builder, in memberInfo, in currentType);
43+
GenerateSetPrimitiveValue(in builder, in memberInfo, in offsetStr);
44+
GenerateSetPrimitiveValueFromPtr(in builder, in memberInfo, in offsetStr);
45+
GenerateSetPrimitiveValueFrom(in builder, in memberInfo, in currentType, in offsetStr);
4746
}
4847
else
4948
{
50-
GenerateGetСompositeValue(in builder, in memberInfo, in currentType);
51-
GenerateSetСompositeValueFrom(in builder, in memberInfo, in currentType);
49+
GenerateGetСompositeValue(in builder, in memberInfo, in currentType, in offsetStr);
50+
GenerateSetСompositeValueFrom(in builder, in memberInfo, in currentType, in offsetStr);
5251
}
5352
}
5453

5554
GenerateCopyToPtr(in builder, in typeInfo, in currentType);
5655
GenerateCopyToValue(in builder, in typeInfo, in currentType);
5756
GenerateCopyToValueOut(in builder, in typeInfo, in currentType);
58-
GenerateCopy(in builder, in typeInfo);
57+
58+
var sizeOfStr = typeInfo.IsRuntimeCalculatedSize ? $"{currentType.Name}Helper.SizeOf" : $"{typeInfo.Size}";
59+
GenerateCopy(in builder, in typeInfo, in sizeOfStr);
60+
5961
GenerateEnd(in builder);
6062

6163
context.AddSource($"{currentType.Name}Helper.g.cs", builder.ToString());
@@ -83,18 +85,24 @@ public unsafe static class {currentType.Name}Helper
8385
");
8486
}
8587

86-
private void GenerateSize(
88+
private void GenerateOffsetsAndSize(
8789
in StringBuilder builder,
8890
in TypeInfo typeInfo
8991
)
9092
{
9193
builder.Append($@"
92-
public static nuint GetSize()
93-
{{
94-
return {typeInfo.Members.Sum(s => s.Size) + (typeInfo.IsValueType ? 0 : 1)};
95-
}}
94+
public static readonly nuint SizeOf = {typeInfo.SizeOf};
95+
");
9696

97+
foreach (var memberInfo in typeInfo.Members)
98+
{
99+
if(memberInfo.IsRuntimeOffsetCalculated)
100+
{
101+
builder.Append($@"
102+
public static readonly nuint {memberInfo.MemberName}Offset = {memberInfo.OffsetStr};
97103
");
104+
}
105+
}
98106
}
99107

100108
private void GenerateIsNullable(
@@ -113,66 +121,71 @@ public static bool IsNullable()
113121

114122
private void GenerateGetPtr(
115123
in StringBuilder builder,
116-
in MemberInfo memberInfo
124+
in MemberInfo memberInfo,
125+
in string offsetStr
117126
)
118127
{
119128
builder.Append($@"
120129
public static void* Get{memberInfo.MemberName}Ptr(in void* ptr)
121130
{{
122-
return (byte*)ptr + {memberInfo.Offset};
131+
return (byte*)ptr + {offsetStr};
123132
}}
124133
125134
");
126135
}
127136

128137
private void GenerateGetPrimitiveValue(
129138
in StringBuilder builder,
130-
in MemberInfo memberInfo
139+
in MemberInfo memberInfo,
140+
in string offsetStr
131141
)
132142
{
133143
builder.Append($@"
134144
public static {memberInfo.TypeName} Get{memberInfo.MemberName}Value(in void* ptr)
135145
{{
136-
return *({memberInfo.TypeName}*)((byte*)ptr + {memberInfo.Offset});
146+
return *({memberInfo.TypeName}*)((byte*)ptr + {offsetStr});
137147
}}
138148
");
139149
}
140150

141151
private void GenerateGetPrimitiveValueRef(
142152
in StringBuilder builder,
143-
in MemberInfo memberInfo
153+
in MemberInfo memberInfo,
154+
in string offsetStr
144155
)
145156
{
146157
builder.Append($@"
147158
public static void GetRef{memberInfo.MemberName}Value(in void* ptr, ref {memberInfo.TypeName} item)
148159
{{
149-
item = *({memberInfo.TypeName}*)((byte*)ptr + {memberInfo.Offset});
160+
item = *({memberInfo.TypeName}*)((byte*)ptr + {offsetStr});
150161
}}
151162
");
152163
}
153164

154165
private void GenerateGetPrimitiveValueOut(
155166
in StringBuilder builder,
156-
in MemberInfo memberInfo
167+
in MemberInfo memberInfo,
168+
in string offsetStr
157169
)
158170
{
159171
builder.Append($@"
160172
public static void GetOut{memberInfo.MemberName}Value(in void* ptr, out {memberInfo.TypeName} item)
161173
{{
162-
item = *({memberInfo.TypeName}*)((byte*)ptr + {memberInfo.Offset});
174+
item = *({memberInfo.TypeName}*)((byte*)ptr + {offsetStr});
163175
}}
164176
");
165177
}
166178

167179
private void GenerateSetPrimitiveValue(
168180
in StringBuilder builder,
169-
in MemberInfo memberInfo
181+
in MemberInfo memberInfo,
182+
in string offsetStr
170183
)
171184
{
172185
builder.Append($@"
173186
public static void Set{memberInfo.MemberName}Value(in void* ptr, in {memberInfo.TypeName} value)
174187
{{
175-
*({memberInfo.TypeName}*)((byte*)ptr + {memberInfo.Offset}) = value;
188+
*({memberInfo.TypeName}*)((byte*)ptr + {offsetStr}) = value;
176189
}}
177190
178191
");
@@ -181,27 +194,29 @@ in MemberInfo memberInfo
181194
private void GenerateSetPrimitiveValueFrom(
182195
in StringBuilder builder,
183196
in MemberInfo memberInfo,
184-
in INamedTypeSymbol currentType
197+
in INamedTypeSymbol currentType,
198+
in string offsetStr
185199
)
186200
{
187201
builder.Append($@"
188202
public static void Set{memberInfo.MemberName}Value(in void* ptr, in {currentType.Name} value)
189203
{{
190-
*({memberInfo.TypeName}*)((byte*)ptr + {memberInfo.Offset}) = value.{memberInfo.MemberName};
204+
*({memberInfo.TypeName}*)((byte*)ptr + {offsetStr}) = value.{memberInfo.MemberName};
191205
}}
192206
193207
");
194208
}
195209

196210
private void GenerateSetPrimitiveValueFromPtr(
197211
in StringBuilder builder,
198-
in MemberInfo memberInfo
212+
in MemberInfo memberInfo,
213+
in string offsetStr
199214
)
200215
{
201216
builder.Append($@"
202217
public static void Set{memberInfo.MemberName}Value(in void* ptr, in {memberInfo.TypeName}* valuePtr)
203218
{{
204-
*({memberInfo.TypeName}*)((byte*)ptr + {memberInfo.Offset}) = *valuePtr;
219+
*({memberInfo.TypeName}*)((byte*)ptr + {offsetStr}) = *valuePtr;
205220
}}
206221
207222
");
@@ -211,7 +226,8 @@ in MemberInfo memberInfo
211226
private void GenerateGetСompositeValue(
212227
in StringBuilder builder,
213228
in MemberInfo memberInfo,
214-
in INamedTypeSymbol currentType
229+
in INamedTypeSymbol currentType,
230+
in string offsetStr
215231
)
216232
{
217233
if (memberInfo.IsValueType)
@@ -234,7 +250,7 @@ in INamedTypeSymbol currentType
234250
builder.Append($@"
235251
{memberInfo.TypeName} result;
236252
Unsafe.SkipInit(out result);
237-
{memberInfo.TypeName}Helper.CopyToValue((byte*)ptr + {memberInfo.Offset}, ref result);
253+
{memberInfo.TypeName}Helper.CopyToValue((byte*)ptr + {offsetStr}, ref result);
238254
239255
return result;
240256
}}
@@ -258,13 +274,13 @@ in INamedTypeSymbol currentType
258274
}
259275

260276
builder.Append($@"
261-
if(*((byte*)ptr + {memberInfo.Offset}) == 0)
277+
if(*((byte*)ptr + {offsetStr}) == 0)
262278
{{
263279
return null;
264280
}}
265281
266282
{memberInfo.TypeName} result = new {memberInfo.TypeName}();
267-
{memberInfo.TypeName}Helper.CopyToValue((byte*)ptr + {memberInfo.Offset}, ref result);
283+
{memberInfo.TypeName}Helper.CopyToValue((byte*)ptr + {offsetStr}, ref result);
268284
return result;
269285
}}
270286
");
@@ -274,7 +290,8 @@ in INamedTypeSymbol currentType
274290
private void GenerateSetСompositeValueFrom(
275291
in StringBuilder builder,
276292
in MemberInfo memberInfo,
277-
in INamedTypeSymbol currentType
293+
in INamedTypeSymbol currentType,
294+
in string offsetStr
278295
)
279296
{
280297
if(memberInfo.IsValueType)
@@ -294,7 +311,7 @@ in INamedTypeSymbol currentType
294311
}
295312

296313
builder.Append($@"
297-
{memberInfo.TypeName}Helper.CopyToPtr(value.{memberInfo.MemberName}, (byte*)ptr + {memberInfo.Offset});
314+
{memberInfo.TypeName}Helper.CopyToPtr(value.{memberInfo.MemberName}, (byte*)ptr + {offsetStr});
298315
}}
299316
");
300317
}
@@ -317,11 +334,11 @@ in INamedTypeSymbol currentType
317334
builder.Append($@"
318335
if(value.{memberInfo.MemberName} == null)
319336
{{
320-
*((byte*)ptr + {memberInfo.Offset}) = 0;
337+
*((byte*)ptr + {currentType.Name}Helper.{memberInfo.MemberName}) = 0;
321338
return;
322339
}}
323340
324-
{memberInfo.TypeName}Helper.CopyToPtr(value.{memberInfo.MemberName}, (byte*)ptr + {memberInfo.Offset});
341+
{memberInfo.TypeName}Helper.CopyToPtr(value.{memberInfo.MemberName}, (byte*)ptr + {offsetStr});
325342
}}
326343
");
327344
}
@@ -459,7 +476,8 @@ public static void CopyToValueOut(in void* ptr, out {currentType.Name} value)
459476

460477
private void GenerateCopy(
461478
in StringBuilder builder,
462-
in TypeInfo typeInfo
479+
in TypeInfo typeInfo,
480+
in string sizeOfStr
463481
)
464482
{
465483
if (typeInfo.IsValueType)
@@ -470,8 +488,8 @@ public static void Copy(in void* ptrSource, in void* ptrDest)
470488
Buffer.MemoryCopy(
471489
ptrSource,
472490
ptrDest,
473-
{typeInfo.Members.Sum(s => s.Size) + (typeInfo.IsValueType ? 0 : 1)},
474-
{typeInfo.Members.Sum(s => s.Size) + (typeInfo.IsValueType ? 0 : 1)}
491+
{sizeOfStr},
492+
{sizeOfStr}
475493
);
476494
}}
477495
");
@@ -490,8 +508,8 @@ public static void Copy(in void* ptrSource, in void* ptrDest)
490508
Buffer.MemoryCopy(
491509
ptrSource,
492510
ptrDest,
493-
{typeInfo.Members.Sum(s => s.Size) + (typeInfo.IsValueType ? 0 : 1)},
494-
{typeInfo.Members.Sum(s => s.Size) + (typeInfo.IsValueType ? 0 : 1)}
511+
{sizeOfStr},
512+
{sizeOfStr}
495513
);
496514
}}
497515
");

0 commit comments

Comments
 (0)