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

Skip to content

Commit 7f0594b

Browse files
authored
Merge branch 'main' into user/sergiopedri/get-generic-type-definition-intrinsic
2 parents 78281de + 5fd965d commit 7f0594b

File tree

32 files changed

+891
-260
lines changed

32 files changed

+891
-260
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Contract Object
2+
3+
This contract is for getting information about well-known managed objects
4+
5+
## APIs of contract
6+
7+
``` csharp
8+
// Get the method table address for the object
9+
TargetPointer GetMethodTableAddress(TargetPointer address);
10+
11+
// Get the string corresponding to a managed string object. Error if address does not represent a string.
12+
string GetStringValue(TargetPointer address);
13+
```
14+
15+
## Version 1
16+
17+
Data descriptors used:
18+
| Data Descriptor Name | Field | Meaning |
19+
| --- | --- | --- |
20+
| `Object` | `m_pMethTab` | Method table for the object |
21+
| `String` | `m_FirstChar` | First character of the string - `m_StringLength` can be used to read the full string (encoded in UTF-16) |
22+
| `String` | `m_StringLength` | Length of the string in characters (encoded in UTF-16) |
23+
24+
Global variables used:
25+
| Global Name | Type | Purpose |
26+
| --- | --- | --- |
27+
| `ObjectToMethodTableUnmask` | uint8 | Bits to clear for converting to a method table address |
28+
| `StringMethodTable` | TargetPointer | The method table for System.String |
29+
30+
``` csharp
31+
TargetPointer GetMethodTableAddress(TargetPointer address)
32+
{
33+
TargetPointer mt = _targetPointer.ReadPointer(address + /* Object::m_pMethTab offset */);
34+
return mt.Value & ~target.ReadGlobal<byte>("ObjectToMethodTableUnmask");
35+
}
36+
37+
string GetStringValue(TargetPointer address)
38+
{
39+
TargetPointer mt = GetMethodTableAddress(address);
40+
TargetPointer stringMethodTable = target.ReadPointer(target.ReadGlobalPointer("StringMethodTable"));
41+
if (mt != stringMethodTable)
42+
throw new ArgumentException("Address does not represent a string object", nameof(address));
43+
44+
// Validates the method table
45+
_ = target.Contracts.RuntimeTypeSystem.GetTypeHandle(mt);
46+
47+
Data.String str = _target.ProcessedData.GetOrAdd<Data.String>(address);
48+
uint length = target.Read<uint>(address + /* String::m_StringLength offset */);
49+
Span<byte> span = stackalloc byte[(int)length * sizeof(char)];
50+
target.ReadBuffer(address + /* String::m_FirstChar offset */, span);
51+
return new string(MemoryMarshal.Cast<byte, char>(span));
52+
}
53+
```

src/coreclr/debug/daccess/dacimpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ class ClrDataAccess
12411241
HRESULT GetMethodTableForEEClassImpl (CLRDATA_ADDRESS eeClassReallyMT, CLRDATA_ADDRESS *value);
12421242
HRESULT GetMethodTableNameImpl(CLRDATA_ADDRESS mt, unsigned int count, _Inout_updates_z_(count) WCHAR *mtName, unsigned int *pNeeded);
12431243
HRESULT GetObjectExceptionDataImpl(CLRDATA_ADDRESS objAddr, struct DacpExceptionObjectData *data);
1244+
HRESULT GetObjectStringDataImpl(CLRDATA_ADDRESS obj, unsigned int count, _Inout_updates_z_(count) WCHAR *stringData, unsigned int *pNeeded);
12441245

12451246
BOOL IsExceptionFromManagedCode(EXCEPTION_RECORD * pExceptionRecord);
12461247
#ifndef TARGET_UNIX

src/coreclr/debug/daccess/request.cpp

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@ ClrDataAccess::GetDomainFromContext(CLRDATA_ADDRESS contextAddr, CLRDATA_ADDRESS
16011601

16021602

16031603
HRESULT
1604-
ClrDataAccess::GetObjectStringData(CLRDATA_ADDRESS obj, unsigned int count, _Inout_updates_z_(count) WCHAR *stringData, unsigned int *pNeeded)
1604+
ClrDataAccess::GetObjectStringData(CLRDATA_ADDRESS obj, unsigned int count, _Inout_updates_z_(count) WCHAR* stringData, unsigned int* pNeeded)
16051605
{
16061606
if (obj == 0)
16071607
return E_INVALIDARG;
@@ -1611,44 +1611,73 @@ ClrDataAccess::GetObjectStringData(CLRDATA_ADDRESS obj, unsigned int count, _Ino
16111611

16121612
SOSDacEnter();
16131613

1614+
if (m_cdacSos != NULL)
1615+
{
1616+
hr = m_cdacSos->GetObjectStringData(obj, count, stringData, pNeeded);
1617+
if (FAILED(hr))
1618+
{
1619+
hr = GetObjectStringDataImpl(obj, count, stringData, pNeeded);
1620+
}
1621+
#ifdef _DEBUG
1622+
else
1623+
{
1624+
unsigned int neededLocal;
1625+
SString stringDataLocal;
1626+
HRESULT hrLocal = GetObjectStringDataImpl(obj, count, stringDataLocal.OpenUnicodeBuffer(count), &neededLocal);
1627+
_ASSERTE(hr == hrLocal);
1628+
_ASSERTE(pNeeded == NULL || *pNeeded == neededLocal);
1629+
_ASSERTE(u16_strncmp(stringData, stringDataLocal, count) == 0);
1630+
}
1631+
#endif
1632+
}
1633+
else
1634+
{
1635+
hr = GetObjectStringDataImpl(obj, count, stringData, pNeeded);
1636+
}
1637+
1638+
SOSDacLeave();
1639+
return hr;
1640+
}
1641+
1642+
HRESULT
1643+
ClrDataAccess::GetObjectStringDataImpl(CLRDATA_ADDRESS obj, unsigned int count, _Inout_updates_z_(count) WCHAR *stringData, unsigned int *pNeeded)
1644+
{
16141645
TADDR mtTADDR = DACGetMethodTableFromObjectPointer(TO_TADDR(obj), m_pTarget);
16151646
PTR_MethodTable mt = PTR_MethodTable(mtTADDR);
16161647

16171648
// Object must be a string
16181649
BOOL bFree = FALSE;
16191650
if (!DacValidateMethodTable(mt, bFree))
1620-
hr = E_INVALIDARG;
1621-
else if (HOST_CDADDR(mt) != HOST_CDADDR(g_pStringClass))
1622-
hr = E_INVALIDARG;
1651+
return E_INVALIDARG;
16231652

1624-
if (SUCCEEDED(hr))
1625-
{
1626-
PTR_StringObject str(TO_TADDR(obj));
1627-
ULONG32 needed = (ULONG32)str->GetStringLength() + 1;
1653+
if (HOST_CDADDR(mt) != HOST_CDADDR(g_pStringClass))
1654+
return E_INVALIDARG;
16281655

1629-
if (stringData && count > 0)
1630-
{
1631-
if (count > needed)
1632-
count = needed;
1656+
PTR_StringObject str(TO_TADDR(obj));
1657+
ULONG32 needed = (ULONG32)str->GetStringLength() + 1;
16331658

1634-
TADDR pszStr = TO_TADDR(obj)+offsetof(StringObject, m_FirstChar);
1635-
hr = m_pTarget->ReadVirtual(pszStr, (PBYTE)stringData, count * sizeof(WCHAR), &needed);
1659+
HRESULT hr;
1660+
if (stringData && count > 0)
1661+
{
1662+
if (count > needed)
1663+
count = needed;
16361664

1637-
if (SUCCEEDED(hr))
1638-
stringData[count - 1] = W('\0');
1639-
else
1640-
stringData[0] = W('\0');
1641-
}
1642-
else
1643-
{
1644-
hr = E_INVALIDARG;
1645-
}
1665+
TADDR pszStr = TO_TADDR(obj)+offsetof(StringObject, m_FirstChar);
1666+
hr = m_pTarget->ReadVirtual(pszStr, (PBYTE)stringData, count * sizeof(WCHAR), &needed);
16461667

1647-
if (pNeeded)
1648-
*pNeeded = needed;
1668+
if (SUCCEEDED(hr))
1669+
stringData[count - 1] = W('\0');
1670+
else
1671+
stringData[0] = W('\0');
1672+
}
1673+
else
1674+
{
1675+
hr = E_INVALIDARG;
16491676
}
16501677

1651-
SOSDacLeave();
1678+
if (pNeeded)
1679+
*pNeeded = needed;
1680+
16521681
return hr;
16531682
}
16541683

src/coreclr/debug/runtimeinfo/contracts.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"DacStreams": 1,
1313
"Exception": 1,
1414
"Loader": 1,
15+
"Object": 1,
1516
"RuntimeTypeSystem": 1,
1617
"Thread": 1
1718
}

src/coreclr/debug/runtimeinfo/datadescriptor.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,17 @@ CDAC_TYPE_BEGIN(GCHandle)
172172
CDAC_TYPE_SIZE(sizeof(OBJECTHANDLE))
173173
CDAC_TYPE_END(GCHandle)
174174

175+
CDAC_TYPE_BEGIN(Object)
176+
CDAC_TYPE_INDETERMINATE(Object)
177+
CDAC_TYPE_FIELD(Object, /*pointer*/, m_pMethTab, cdac_offsets<Object>::m_pMethTab)
178+
CDAC_TYPE_END(Object)
179+
180+
CDAC_TYPE_BEGIN(String)
181+
CDAC_TYPE_INDETERMINATE(String)
182+
CDAC_TYPE_FIELD(String, /*pointer*/, m_FirstChar, cdac_offsets<StringObject>::m_FirstChar)
183+
CDAC_TYPE_FIELD(String, /*uint32*/, m_StringLength, cdac_offsets<StringObject>::m_StringLength)
184+
CDAC_TYPE_END(String)
185+
175186
// Loader
176187

177188
CDAC_TYPE_BEGIN(Module)
@@ -264,8 +275,15 @@ CDAC_GLOBAL(FeatureEHFunclets, uint8, 1)
264275
#else
265276
CDAC_GLOBAL(FeatureEHFunclets, uint8, 0)
266277
#endif
278+
// See Object::GetGCSafeMethodTable
279+
#ifdef TARGET_64BIT
280+
CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1 | 1 << 2)
281+
#else
282+
CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1)
283+
#endif //TARGET_64BIT
267284
CDAC_GLOBAL(SOSBreakingChangeVersion, uint8, SOS_BREAKING_CHANGE_VERSION)
268285
CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable)
286+
CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass)
269287
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
270288
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)
271289
CDAC_GLOBALS_END()

src/coreclr/jit/compiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4514,6 +4514,7 @@ class Compiler
45144514

45154515
GenTree* impStoreNullableFields(CORINFO_CLASS_HANDLE nullableCls,
45164516
GenTree* value);
4517+
GenTree* impInlineUnboxNullable(CORINFO_CLASS_HANDLE nullableCls, GenTree* nullableClsNode, GenTree* obj);
45174518
void impLoadNullableFields(GenTree* nullableObj, CORINFO_CLASS_HANDLE nullableCls, GenTree** hasValueFld, GenTree** valueFld);
45184519

45194520
int impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken,
@@ -7649,6 +7650,8 @@ class Compiler
76497650
LoopLocalOccurrences* loopLocals);
76507651
bool optCanAndShouldChangeExitTest(GenTree* cond, bool dump);
76517652
bool optPrimaryIVHasNonLoopUses(unsigned lclNum, FlowGraphNaturalLoop* loop, LoopLocalOccurrences* loopLocals);
7653+
7654+
bool optWidenIVs(ScalarEvolutionContext& scevContext, FlowGraphNaturalLoop* loop, LoopLocalOccurrences* loopLocals);
76527655
bool optWidenPrimaryIV(FlowGraphNaturalLoop* loop,
76537656
unsigned lclNum,
76547657
ScevAddRec* addRec,
@@ -7665,6 +7668,9 @@ class Compiler
76657668
void optReplaceWidenedIV(unsigned lclNum, unsigned ssaNum, unsigned newLclNum, Statement* stmt);
76667669
void optSinkWidenedIV(unsigned lclNum, unsigned newLclNum, FlowGraphNaturalLoop* loop);
76677670

7671+
bool optRemoveUnusedIVs(FlowGraphNaturalLoop* loop, LoopLocalOccurrences* loopLocals);
7672+
bool optIsUpdateOfIVWithoutSideEffects(GenTree* tree, unsigned lclNum);
7673+
76687674
// Redundant branch opts
76697675
//
76707676
PhaseStatus optRedundantBranches();

0 commit comments

Comments
 (0)