Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 371331f

Browse files
committed
Merge branch 'main' of github.com:dotnet/runtime into fix-alloc-throwifnull
2 parents ee83f6b + e1ab224 commit 371331f

File tree

129 files changed

+2352
-1444
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+2352
-1444
lines changed

docs/design/coreclr/botr/method-descriptor.md

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ DWORD MethodDesc::GetAttrs()
8585
Method Slots
8686
------------
8787

88-
Each MethodDesc has a slot, which contains the entry point of the method. The slot and entry point must exist for all methods, even the ones that never run like abstract methods. There are multiple places in the runtime that depend on the 1:1 mapping between entry points and MethodDescs, making this relationship an invariant.
88+
Each MethodDesc has a slot, which contains the current entry point of the method. The slot must exist for all methods, even the ones that never run like abstract methods. There are multiple places in the runtime that depend on mapping between entry points and MethodDescs.
89+
90+
Each MethodDesc logically has an entry point, but we do not allocate these eagerly at MethodDesc creation time. The invariant is that once the method is identified as a method to run, or is used in virtual overriding, we will allocate the entrypoint.
8991

9092
The slot is either in MethodTable or in MethodDesc itself. The location of the slot is determined by `mdcHasNonVtableSlot` bit on MethodDesc.
9193

@@ -185,8 +187,6 @@ The target of the temporary entry point is a PreStub, which is a special kind of
185187

186188
The **stable entry point** is either the native code or the precode. The **native code** is either jitted code or code saved in NGen image. It is common to talk about jitted code when we actually mean native code.
187189

188-
Temporary entry points are never saved into NGen images. All entry points in NGen images are stable entry points that are never changed. It is an important optimization that reduced private working set.
189-
190190
![Figure 2](images/methoddesc-fig2.png)
191191

192192
Figure 2 Entry Point State Diagram
@@ -208,6 +208,7 @@ The methods to get callable entry points from MethodDesc are:
208208

209209
- `MethodDesc::GetSingleCallableAddrOfCode`
210210
- `MethodDesc::GetMultiCallableAddrOfCode`
211+
- `MethodDesc::TryGetMultiCallableAddrOfCode`
211212
- `MethodDesc::GetSingleCallableAddrOfVirtualizedCode`
212213
- `MethodDesc::GetMultiCallableAddrOfVirtualizedCode`
213214

@@ -220,7 +221,7 @@ The type of precode has to be cheaply computable from the instruction sequence.
220221

221222
**StubPrecode**
222223

223-
StubPrecode is the basic precode type. It loads MethodDesc into a scratch register and then jumps. It must be implemented for precodes to work. It is used as fallback when no other specialized precode type is available.
224+
StubPrecode is the basic precode type. It loads MethodDesc into a scratch register<sup>2</sup> and then jumps. It must be implemented for precodes to work. It is used as fallback when no other specialized precode type is available.
224225

225226
All other precodes types are optional optimizations that the platform specific files turn on via HAS\_XXX\_PRECODE defines.
226227

@@ -236,7 +237,7 @@ StubPrecode looks like this on x86:
236237

237238
FixupPrecode is used when the final target does not require MethodDesc in scratch register<sup>2</sup>. The FixupPrecode saves a few cycles by avoiding loading MethodDesc into the scratch register.
238239

239-
The most common usage of FixupPrecode is for method fixups in NGen images.
240+
Most stubs used are the more efficient form, we currently can use this form for everything but interop methods when a specialized form of Precode is not required.
240241

241242
The initial state of the FixupPrecode on x86:
242243

@@ -254,67 +255,6 @@ Once it has been patched to point to final target:
254255

255256
<sup>2</sup> Passing MethodDesc in scratch register is sometimes referred to as **MethodDesc Calling Convention**.
256257

257-
**FixupPrecode chunks**
258-
259-
FixupPrecode chunk is a space efficient representation of multiple FixupPrecodes. It mirrors the idea of MethodDescChunk by hoisting the similar MethodDesc pointers from multiple FixupPrecodes to a shared area.
260-
261-
The FixupPrecode chunk saves space and improves code density of the precodes. The code density improvement from FixupPrecode chunks resulted in 1% - 2% gain in big server scenarios on x64.
262-
263-
The FixupPrecode chunks looks like this on x86:
264-
265-
jmp Target2
266-
pop edi // dummy instruction that marks the type of the precode
267-
db MethodDescChunkIndex
268-
db 2 (PrecodeChunkIndex)
269-
270-
jmp Target1
271-
pop edi
272-
db MethodDescChunkIndex
273-
db 1 (PrecodeChunkIndex)
274-
275-
jmp Target0
276-
pop edi
277-
db MethodDescChunkIndex
278-
db 0 (PrecodeChunkIndex)
279-
280-
dw pMethodDescBase
281-
282-
One FixupPrecode chunk corresponds to one MethodDescChunk. There is no 1:1 mapping between the FixupPrecodes in the chunk and MethodDescs in MethodDescChunk though. Each FixupPrecode has index of the method it belongs to. It allows allocating the FixupPrecode in the chunk only for methods that need it.
283-
284-
**Compact entry points**
285-
286-
Compact entry point is a space efficient implementation of temporary entry points.
287-
288-
Temporary entry points implemented using StubPrecode or FixupPrecode can be patched to point to the actual code. Jitted code can call temporary entry point directly. The temporary entry point can be multicallable entry points in this case.
289-
290-
Compact entry points cannot be patched to point to the actual code. Jitted code cannot call them directly. They are trading off speed for size. Calls to these entry points are indirected via slots in a table (FuncPtrStubs) that are patched to point to the actual entry point eventually. A request for a multicallable entry point allocates a StubPrecode or FixupPrecode on demand in this case.
291-
292-
The raw speed difference is the cost of an indirect call for a compact entry point vs. the cost of one direct call and one direct jump on the given platform. The later used to be faster by a few percent in large server scenario since it can be predicted by the hardware better (2005). It is not always the case on current (2015) hardware.
293-
294-
The compact entry points have been historically implemented on x86 only. Their additional complexity, space vs. speed trade-off and hardware advancements made them unjustified on other platforms.
295-
296-
The compact entry point on x86 looks like this:
297-
298-
entrypoint0:
299-
mov al,0
300-
jmp short Dispatch
301-
302-
entrypoint1:
303-
mov al,1
304-
jmp short Dispatch
305-
306-
entrypoint2:
307-
mov al,2
308-
jmp short Dispatch
309-
310-
Dispatch:
311-
movzx eax,al
312-
shl eax, 3
313-
add eax, pBaseMD
314-
jmp PreStub
315-
316-
The allocation of temporary entry points always tries to pick the smallest temporary entry point from the available choices. For example, a single compact entry point is bigger than a single StubPrecode on x86. The StubPrecode will be preferred over the compact entry point in this case. The allocation of the precode for a stable entry point will try to reuse an allocated temporary entry point precode if one exists of the matching type.
317-
318258
**ThisPtrRetBufPrecode**
319259

320260
ThisPtrRetBufPrecode is used to switch a return buffer and the this pointer for open instance delegates returning valuetypes. It is used to convert the calling convention of MyValueType Bar(Foo x) to the calling convention of MyValueType Foo::Bar().

docs/workflow/requirements/linux-requirements.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ Below are the requirements for toolchain setup, depending on your environment. P
2121

2222
Minimum RAM required to build is 1GB. The build is known to fail on 512 MB VMs ([dotnet/runtime#4069](https://github.com/dotnet/runtime/issues/4069)).
2323

24+
You can use this helper script to install dependencies on some platforms:
25+
26+
```bash
27+
sudo eng/install-native-dependencies.sh
28+
# or without 'sudo' if you are root
29+
```
2430

2531
### Debian-based / Ubuntu
2632

@@ -48,8 +54,8 @@ Install the following packages for the toolchain:
4854

4955
```bash
5056
sudo apt install -y cmake llvm lld clang build-essential \
51-
python-is-python3 curl git lldb libicu-dev liblttng-ust-dev \
52-
libssl-dev libkrb5-dev zlib1g-dev ninja-build
57+
python-is-python3 curl git lldb libicu-dev liblttng-ust-dev \
58+
libssl-dev libkrb5-dev zlib1g-dev ninja-build
5359
```
5460

5561
**NOTE**: As of now, Ubuntu's `apt` only has until CMake version 3.16.3 if you're using Ubuntu 20.04 LTS (less in older Ubuntu versions), and version 3.18.4 in Debian 11 (less in older Debian versions). This is lower than the required 3.20, which in turn makes it incompatible with the repo. For this case, we can use the `snap` package manager or the _Kitware APT feed_ to get a new enough version of CMake.
@@ -98,7 +104,7 @@ Install the following packages for the toolchain:
98104

99105
```bash
100106
sudo dnf install -y cmake llvm lld lldb clang python curl git libicu-devel openssl-devel \
101-
krb5-devel zlib-devel lttng-ust-devel ninja-build
107+
krb5-devel zlib-devel lttng-ust-devel ninja-build
102108
```
103109

104110
### Gentoo

eng/install-native-dependencies.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ case "$os" in
2727
libssl-dev libkrb5-dev zlib1g-dev
2828

2929
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
30+
elif [ "$ID" = "fedora" ]; then
31+
dnf install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel zlib-devel lttng-ust-devel
3032
elif [ "$ID" = "alpine" ]; then
3133
apk add build-base cmake bash curl clang llvm-dev krb5-dev lttng-ust-dev icu-dev zlib-dev openssl-dev
3234
else

src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@
197197
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CastHelpers.cs" />
198198
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ICastableHelpers.cs" />
199199
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.CoreCLR.cs" />
200-
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\StackAllocatedBox.cs" />
201200
<Compile Include="$(BclSourcesRoot)\System\Runtime\ControlledExecution.CoreCLR.cs" />
202201
<Compile Include="$(BclSourcesRoot)\System\Runtime\DependentHandle.cs" />
203202
<Compile Include="$(MSBuildThisFileDirectory)..\nativeaot\Common\src\System\Runtime\RhFailFastReason.cs" />

src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public abstract partial class WaitHandle
1111
[MethodImpl(MethodImplOptions.InternalCall)]
1212
private static extern int WaitOneCore(IntPtr waitHandle, int millisecondsTimeout, bool useTrivialWaits);
1313

14-
private static unsafe int WaitMultipleIgnoringSyncContextCore(Span<IntPtr> waitHandles, bool waitAll, int millisecondsTimeout)
14+
private static unsafe int WaitMultipleIgnoringSyncContextCore(ReadOnlySpan<IntPtr> waitHandles, bool waitAll, int millisecondsTimeout)
1515
{
1616
fixed (IntPtr* pWaitHandles = &MemoryMarshal.GetReference(waitHandles))
1717
{

src/coreclr/debug/daccess/daccess.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3239,6 +3239,10 @@ ClrDataAccess::QueryInterface(THIS_
32393239
{
32403240
ifaceRet = static_cast<ISOSDacInterface14*>(this);
32413241
}
3242+
else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface15)))
3243+
{
3244+
ifaceRet = static_cast<ISOSDacInterface15*>(this);
3245+
}
32423246
else
32433247
{
32443248
*iface = NULL;
@@ -8341,6 +8345,44 @@ HRESULT DacMemoryEnumerator::Next(unsigned int count, SOSMemoryRegion regions[],
83418345
return i < count ? S_FALSE : S_OK;
83428346
}
83438347

8348+
HRESULT DacMethodTableSlotEnumerator::Skip(unsigned int count)
8349+
{
8350+
mIteratorIndex += count;
8351+
return S_OK;
8352+
}
8353+
8354+
HRESULT DacMethodTableSlotEnumerator::Reset()
8355+
{
8356+
mIteratorIndex = 0;
8357+
return S_OK;
8358+
}
8359+
8360+
HRESULT DacMethodTableSlotEnumerator::GetCount(unsigned int* pCount)
8361+
{
8362+
if (!pCount)
8363+
return E_POINTER;
8364+
8365+
*pCount = mMethods.GetCount();
8366+
return S_OK;
8367+
}
8368+
8369+
HRESULT DacMethodTableSlotEnumerator::Next(unsigned int count, SOSMethodData methods[], unsigned int* pFetched)
8370+
{
8371+
if (!pFetched)
8372+
return E_POINTER;
8373+
8374+
if (!methods)
8375+
return E_POINTER;
8376+
8377+
unsigned int i = 0;
8378+
while (i < count && mIteratorIndex < mMethods.GetCount())
8379+
{
8380+
methods[i++] = mMethods.Get(mIteratorIndex++);
8381+
}
8382+
8383+
*pFetched = i;
8384+
return i < count ? S_FALSE : S_OK;
8385+
}
83448386

83458387
HRESULT DacGCBookkeepingEnumerator::Init()
83468388
{

src/coreclr/debug/daccess/dacimpl.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,8 @@ class ClrDataAccess
818818
public ISOSDacInterface11,
819819
public ISOSDacInterface12,
820820
public ISOSDacInterface13,
821-
public ISOSDacInterface14
821+
public ISOSDacInterface14,
822+
public ISOSDacInterface15
822823
{
823824
public:
824825
ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0);
@@ -1223,6 +1224,9 @@ class ClrDataAccess
12231224
virtual HRESULT STDMETHODCALLTYPE GetThreadStaticBaseAddress(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS thread, CLRDATA_ADDRESS *nonGCStaticsAddress, CLRDATA_ADDRESS *GCStaticsAddress);
12241225
virtual HRESULT STDMETHODCALLTYPE GetMethodTableInitializationFlags(CLRDATA_ADDRESS methodTable, MethodTableInitializationFlags *initializationStatus);
12251226

1227+
// ISOSDacInterface15
1228+
virtual HRESULT STDMETHODCALLTYPE GetMethodTableSlotEnumerator(CLRDATA_ADDRESS mt, ISOSMethodEnum **enumerator);
1229+
12261230
//
12271231
// ClrDataAccess.
12281232
//
@@ -1993,6 +1997,29 @@ class DacMemoryEnumerator : public DefaultCOMImpl<ISOSMemoryEnum, IID_ISOSMemory
19931997
unsigned int mIteratorIndex;
19941998
};
19951999

2000+
class DacMethodTableSlotEnumerator : public DefaultCOMImpl<ISOSMethodEnum, IID_ISOSMethodEnum>
2001+
{
2002+
public:
2003+
DacMethodTableSlotEnumerator() : mIteratorIndex(0)
2004+
{
2005+
}
2006+
2007+
virtual ~DacMethodTableSlotEnumerator() {}
2008+
2009+
HRESULT Init(PTR_MethodTable mTable);
2010+
2011+
HRESULT STDMETHODCALLTYPE Skip(unsigned int count);
2012+
HRESULT STDMETHODCALLTYPE Reset();
2013+
HRESULT STDMETHODCALLTYPE GetCount(unsigned int *pCount);
2014+
HRESULT STDMETHODCALLTYPE Next(unsigned int count, SOSMethodData methods[], unsigned int *pFetched);
2015+
2016+
protected:
2017+
DacReferenceList<SOSMethodData> mMethods;
2018+
2019+
private:
2020+
unsigned int mIteratorIndex;
2021+
};
2022+
19962023
class DacHandleTableMemoryEnumerator : public DacMemoryEnumerator
19972024
{
19982025
public:

0 commit comments

Comments
 (0)