Skip to content

Commit bc607da

Browse files
committed
Cache AddressRange in some IMemorySpace implementations to avoid repeated recomputation
1 parent 57b9c22 commit bc607da

File tree

3 files changed

+42
-28
lines changed

3 files changed

+42
-28
lines changed

src/Core/Echo/Memory/BasicMemorySpace.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace Echo.Memory
88
/// </summary>
99
public class BasicMemorySpace : IMemorySpace
1010
{
11-
private long _baseAddress;
12-
11+
private AddressRange _addressRange;
12+
1313
/// <summary>
1414
/// Creates a new memory space.
1515
/// </summary>
@@ -19,23 +19,25 @@ public BasicMemorySpace(int size, bool initialize)
1919
: this(new BitVector(size * 8, initialize))
2020
{
2121
}
22-
22+
2323
/// <summary>
2424
/// Wraps a byte array into a memory space.
2525
/// </summary>
2626
/// <param name="backBuffer">The data of the memory space.</param>
2727
public BasicMemorySpace(byte[] backBuffer)
2828
{
2929
BackBuffer = new BitVector(backBuffer);
30+
_addressRange = new AddressRange(0, BackBuffer.Count / 8);
3031
}
31-
32+
3233
/// <summary>
3334
/// Wraps a bit vector into a memory space.
3435
/// </summary>
3536
/// <param name="backBuffer">The data of the memory space.</param>
3637
public BasicMemorySpace(BitVector backBuffer)
3738
{
3839
BackBuffer = backBuffer;
40+
_addressRange = new AddressRange(0, BackBuffer.Count / 8);
3941
}
4042

4143
/// <summary>
@@ -47,30 +49,33 @@ public BitVector BackBuffer
4749
}
4850

4951
/// <inheritdoc />
50-
public AddressRange AddressRange => new(_baseAddress, _baseAddress + BackBuffer.Count / 8);
52+
public AddressRange AddressRange => _addressRange;
5153

5254
/// <inheritdoc />
53-
public bool IsValidAddress(long address) => AddressRange.Contains(address);
55+
public bool IsValidAddress(long address) => _addressRange.Contains(address);
5456

5557
/// <inheritdoc />
56-
public void Rebase(long baseAddress) => _baseAddress = baseAddress;
58+
public void Rebase(long baseAddress)
59+
{
60+
_addressRange = new AddressRange(baseAddress, baseAddress + BackBuffer.Count / 8);
61+
}
5762

5863
/// <inheritdoc />
5964
public void Read(long address, BitVectorSpan buffer)
6065
{
61-
BackBuffer.AsSpan((int) (address - _baseAddress) * 8, buffer.Count).CopyTo(buffer);
66+
BackBuffer.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count).CopyTo(buffer);
6267
}
6368

6469
/// <inheritdoc />
6570
public void Write(long address, BitVectorSpan buffer)
6671
{
67-
buffer.CopyTo(BackBuffer.AsSpan((int) (address - _baseAddress) * 8, buffer.Count));
72+
buffer.CopyTo(BackBuffer.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count));
6873
}
6974

7075
/// <inheritdoc />
7176
public void Write(long address, ReadOnlySpan<byte> buffer)
7277
{
73-
BackBuffer.AsSpan((int) ((address - _baseAddress) * 8)).Write(buffer);
78+
BackBuffer.AsSpan((int) ((address - _addressRange.Start) * 8)).Write(buffer);
7479
}
7580
}
7681
}

src/Platforms/Echo.Platforms.AsmResolver/Emulation/Heap/HostObject.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class HostObject : IMemorySpace
1717
private readonly Dictionary<uint, FieldInfo> _fields = new();
1818
private readonly CilVirtualMachine _machine;
1919
private readonly TypeMemoryLayout _virtualLayout;
20-
private long _baseAddress;
20+
private AddressRange _addressRange;
2121

2222
/// <summary>
2323
/// Creates a new managed object embedding.
@@ -29,6 +29,7 @@ public HostObject(object o, CilVirtualMachine machine)
2929
Object = o ?? throw new ArgumentNullException(nameof(o));
3030
_virtualLayout = GetLayout(machine.ValueFactory, o);
3131
_machine = machine;
32+
_addressRange = new AddressRange(0, machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
3233
}
3334

3435
/// <summary>
@@ -44,21 +45,24 @@ public object Object
4445
/// </summary>
4546

4647
/// <inheritdoc />
47-
public AddressRange AddressRange => new(_baseAddress, _baseAddress + _machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
48+
public AddressRange AddressRange => _addressRange;
4849

4950
/// <inheritdoc />
50-
public bool IsValidAddress(long address) => AddressRange.Contains(address);
51+
public bool IsValidAddress(long address) => _addressRange.Contains(address);
5152

5253
/// <inheritdoc />
53-
public void Rebase(long baseAddress) => _baseAddress = baseAddress;
54+
public void Rebase(long baseAddress)
55+
{
56+
_addressRange = new AddressRange(baseAddress, baseAddress + _machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
57+
}
5458

5559
/// <inheritdoc />
5660
public void Read(long address, BitVectorSpan buffer)
5761
{
5862
buffer.MarkFullyUnknown();
5963

6064
// First field in an object is always its method table (i.e., pointer to its type).
61-
uint offset = (uint) (address - _baseAddress);
65+
uint offset = (uint) (address - _addressRange.Start);
6266
if (offset == 0)
6367
{
6468
long methodTable = _machine.ValueFactory.ClrMockMemory.MethodTables.GetAddress(_virtualLayout.Type);
@@ -108,7 +112,7 @@ private void ReadFromObject(uint offset, BitVectorSpan buffer)
108112
/// <inheritdoc />
109113
public void Write(long address, BitVectorSpan buffer)
110114
{
111-
uint offset = (uint) (address - _baseAddress);
115+
uint offset = (uint) (address - _addressRange.Start);
112116

113117
if (Object.GetType().IsArray)
114118
WriteToArray(offset, buffer);

src/Platforms/Echo.Platforms.AsmResolver/Emulation/Stack/CallFrame.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public partial class CallFrame : IMemorySpace
3030
private readonly List<uint> _offsets = new();
3131
private readonly List<ExceptionHandlerFrame> _exceptionHandlers = new();
3232
private BitVector _localStorage;
33-
private long _baseAddress;
33+
private AddressRange _addressRange;
3434

3535
/// <summary>
3636
/// Constructs a new call stack frame.
@@ -89,7 +89,8 @@ internal CallFrame(IMethodDescriptor method, ValueFactory factory, bool isRoot)
8989

9090
// Actually reserve space for the entire frame.
9191
_localStorage = new BitVector((int) (currentOffset * 8), false);
92-
92+
_addressRange = new AddressRange(0, _localStorage.ByteCount);
93+
9394
// Initialize locals to zero when method body says we should.
9495
if (_initializeLocals)
9596
{
@@ -172,10 +173,10 @@ void AllocateFrameField(TypeSignature type)
172173
public ITypeDescriptor? ConstrainedType { get; set; }
173174

174175
/// <inheritdoc />
175-
public AddressRange AddressRange => new(_baseAddress, _baseAddress + _localStorage.ByteCount);
176+
public AddressRange AddressRange => _addressRange;
176177

177178
/// <inheritdoc />
178-
public bool IsValidAddress(long address) => AddressRange.Contains(address);
179+
public bool IsValidAddress(long address) => _addressRange.Contains(address);
179180

180181
/// <summary>
181182
/// Allocates local stack memory in the stack frame.
@@ -189,17 +190,21 @@ public long Allocate(int size)
189190
if (size < 0)
190191
throw new ArgumentOutOfRangeException(nameof(size));
191192

192-
long address = AddressRange.End;
193+
long address = _addressRange.End;
193194
int originalSize = _localStorage.Count;
194195
_localStorage = _localStorage.Resize(originalSize + size * 8, false);
195196
if (!_initializeLocals)
196197
_localStorage.AsSpan(originalSize, _localStorage.Count - originalSize).MarkFullyUnknown();
197-
198+
199+
_addressRange = new AddressRange(_addressRange.Start, _addressRange.Start + _localStorage.ByteCount);
198200
return address;
199201
}
200202

201203
/// <inheritdoc />
202-
public void Rebase(long baseAddress) => _baseAddress = baseAddress;
204+
public void Rebase(long baseAddress)
205+
{
206+
_addressRange = new AddressRange(baseAddress, baseAddress + _localStorage.ByteCount);
207+
}
203208

204209
/// <summary>
205210
/// Gets the address (relative to the start of the frame) to a local variable in the frame.
@@ -208,7 +213,7 @@ public long Allocate(int size)
208213
/// <returns>The address</returns>
209214
/// <exception cref="ArgumentOutOfRangeException">Occurs when the local index is invalid.</exception>
210215
public long GetLocalAddress(int index) => index < LocalsCount
211-
? _baseAddress + _offsets[index]
216+
? _addressRange.Start + _offsets[index]
212217
: throw new ArgumentOutOfRangeException(nameof(index));
213218

214219
/// <summary>
@@ -251,7 +256,7 @@ public BitVector ReadLocal(int index)
251256
/// <returns>The address</returns>
252257
/// <exception cref="ArgumentOutOfRangeException">Occurs when the argument index is invalid.</exception>
253258
public long GetArgumentAddress(int index) => index < Method.Signature!.GetTotalParameterCount()
254-
? _baseAddress + _offsets[LocalsCount + 1 + index]
259+
? _addressRange.Start + _offsets[LocalsCount + 1 + index]
255260
: throw new ArgumentOutOfRangeException(nameof(index));
256261

257262
/// <summary>
@@ -290,19 +295,19 @@ public BitVector ReadArgument(int index)
290295
/// <inheritdoc />
291296
public void Read(long address, BitVectorSpan buffer)
292297
{
293-
_localStorage.AsSpan((int) (address - _baseAddress) * 8, buffer.Count).CopyTo(buffer);
298+
_localStorage.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count).CopyTo(buffer);
294299
}
295300

296301
/// <inheritdoc />
297302
public void Write(long address, BitVectorSpan buffer)
298303
{
299-
buffer.CopyTo(_localStorage.AsSpan((int) (address - _baseAddress) * 8, buffer.Count));
304+
buffer.CopyTo(_localStorage.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count));
300305
}
301306

302307
/// <inheritdoc />
303308
public void Write(long address, ReadOnlySpan<byte> buffer)
304309
{
305-
_localStorage.AsSpan((int) (address - _baseAddress) * 8, buffer.Length).Write(buffer);
310+
_localStorage.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Length).Write(buffer);
306311
}
307312

308313
private void InitializeExceptionHandlerFrames()

0 commit comments

Comments
 (0)