Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFadi Hanna <fadim@microsoft.com>2017-06-12 23:30:20 +0300
committerFadi Hanna <fadim@microsoft.com>2017-06-12 23:30:20 +0300
commit4656e2e04365746b8c214fec738fc2d5ab405448 (patch)
tree115951e088a86e836f477d644f3ffe9a492a6ce6
parente3be4f12df5eb685733f19978b442168b8e8d1f1 (diff)
Fixing bug 445667: AV in universal transition thunk.
The problem was that dynamically created MD arrays were getting the "HasSealedVtable" flag without really having a sealed vtable. The flag was coming from the template type. MD arrays should really not have a sealed vtable, and the runtime should use the dispatchmap/sealedvtable of the System.Array basetype instead. These changes fix the binder to not emit dispatch maps and sealed vtables for md arrays. Cleanup: Remove unused IsDynamicTypeWithSealedVTableEntriesFlag rare flag. [tfs-changeset: 1661447]
-rw-r--r--src/Common/src/Internal/Runtime/EEType.Constants.cs8
-rw-r--r--src/Common/src/Internal/Runtime/EEType.cs25
-rw-r--r--src/Native/Runtime/inc/eetype.h8
-rw-r--r--src/Native/Runtime/inc/eetype.inl48
-rw-r--r--src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs5
5 files changed, 40 insertions, 54 deletions
diff --git a/src/Common/src/Internal/Runtime/EEType.Constants.cs b/src/Common/src/Internal/Runtime/EEType.Constants.cs
index 63839949b..85309ed17 100644
--- a/src/Common/src/Internal/Runtime/EEType.Constants.cs
+++ b/src/Common/src/Internal/Runtime/EEType.Constants.cs
@@ -141,11 +141,9 @@ namespace Internal.Runtime
HasCctorFlag = 0x0000020,
/// <summary>
- /// This EEType has sealed vtable entries (note that this flag is only used for
- /// dynamically created types because they always have an optional field (hence the
- /// very explicit flag name).
+ /// Old unused flag
/// </summary>
- IsDynamicTypeWithSealedVTableEntriesFlag = 0x00000040,
+ UNUSED = 0x00000040,
/// <summary>
/// This EEType was constructed from a universal canonical template, and has
@@ -160,8 +158,6 @@ namespace Internal.Runtime
/// <summary>
/// This EEType has sealed vtable entries
- /// This is for statically generated types - we need two different flags because
- /// the sealed vtable entries are reached in different ways in the static and dynamic case
/// </summary>
HasSealedVTableEntriesFlag = 0x00000200,
diff --git a/src/Common/src/Internal/Runtime/EEType.cs b/src/Common/src/Internal/Runtime/EEType.cs
index 8fa5cd502..a8956b6a1 100644
--- a/src/Common/src/Internal/Runtime/EEType.cs
+++ b/src/Common/src/Internal/Runtime/EEType.cs
@@ -1005,6 +1005,7 @@ namespace Internal.Runtime
internal IntPtr GetSealedVirtualSlot(UInt16 slotNumber)
{
Debug.Assert(!IsNullable);
+ Debug.Assert((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0);
fixed (EEType* pThis = &this)
{
@@ -1315,19 +1316,21 @@ namespace Internal.Runtime
if (eField == EETypeField.ETF_SealedVirtualSlots)
return cbOffset;
- if (IsNullable || (RareFlags & EETypeRareFlags.IsDynamicTypeWithSealedVTableEntriesFlag) != 0)
+ if (IsNullable)
cbOffset += (UInt32)IntPtr.Size;
+ EETypeRareFlags rareFlags = RareFlags;
+
// in the case of sealed vtable entries on static types, we have a UInt sized relative pointer
- if ((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0)
- cbOffset += 4;
+ if ((rareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0)
+ cbOffset += (IsDynamicType ? (UInt32)IntPtr.Size : 4);
if (eField == EETypeField.ETF_DynamicDispatchMap)
{
Debug.Assert(IsDynamicType);
return cbOffset;
}
- if ((RareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0)
+ if ((rareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0)
cbOffset += (UInt32)IntPtr.Size;
if (eField == EETypeField.ETF_GenericDefinition)
@@ -1351,7 +1354,7 @@ namespace Internal.Runtime
return cbOffset;
}
- if ((RareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0)
+ if ((rareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0)
cbOffset += (UInt32)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicTemplateType)
@@ -1364,26 +1367,26 @@ namespace Internal.Runtime
if (eField == EETypeField.ETF_DynamicGcStatics)
{
- Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0);
+ Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0);
return cbOffset;
}
- if ((RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0)
+ if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0)
cbOffset += (UInt32)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicNonGcStatics)
{
- Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0);
+ Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0);
return cbOffset;
}
- if ((RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0)
+ if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0)
cbOffset += (UInt32)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicThreadStaticOffset)
{
- Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0);
+ Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0);
return cbOffset;
}
- if ((RareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0)
+ if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0)
cbOffset += 4;
Debug.Assert(false, "Unknown EEType field type");
diff --git a/src/Native/Runtime/inc/eetype.h b/src/Native/Runtime/inc/eetype.h
index 409b1f28b..65d082f9a 100644
--- a/src/Native/Runtime/inc/eetype.h
+++ b/src/Native/Runtime/inc/eetype.h
@@ -302,10 +302,8 @@ public:
// This EEType has a Class Constructor
HasCctorFlag = 0x0000020,
- // This EEType has sealed vtable entries (note that this flag is only used for
- // dynamically created types because they always have an optional field (hence the
- // very explicit flag name).
- IsDynamicTypeWithSealedVTableEntriesFlag = 0x00000040,
+ // Old unused flag
+ UNUSED = 0x00000040,
// This EEType was constructed from a universal canonical template, and has
// its own dynamically created DispatchMap (does not use the DispatchMap of its template type)
@@ -315,8 +313,6 @@ public:
IsHFAFlag = 0x00000100,
// This EEType has sealed vtable entries
- // This is for statically generated types - we need two different flags because
- // the sealed vtable entries are reached in different ways in the static and dynamic case
HasSealedVTableEntriesFlag = 0x00000200,
// This dynamically created type has gc statics
diff --git a/src/Native/Runtime/inc/eetype.inl b/src/Native/Runtime/inc/eetype.inl
index 0b4908f07..e286d6234 100644
--- a/src/Native/Runtime/inc/eetype.inl
+++ b/src/Native/Runtime/inc/eetype.inl
@@ -46,30 +46,21 @@ inline PTR_UInt8 FollowRelativePointer(const Int32 *pDist)
inline PTR_Code EEType::get_SealedVirtualSlot(UInt16 slotNumber)
{
ASSERT(!IsNullable());
+ ASSERT((get_RareFlags() & HasSealedVTableEntriesFlag) != 0);
if (IsDynamicType())
{
- if ((get_RareFlags() & IsDynamicTypeWithSealedVTableEntriesFlag) != 0)
- {
- UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(ETF_SealedVirtualSlots);
-
- PTR_PTR_Code pSealedVirtualsSlotTable = *(PTR_PTR_Code*)((PTR_UInt8)this + cbSealedVirtualSlotsTypeOffset);
-
- return pSealedVirtualsSlotTable[slotNumber];
- }
- else
- {
- return get_DynamicTemplateType()->get_SealedVirtualSlot(slotNumber);
- }
+ UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(ETF_SealedVirtualSlots);
+ PTR_PTR_Code pSealedVirtualsSlotTable = *(PTR_PTR_Code*)((PTR_UInt8)this + cbSealedVirtualSlotsTypeOffset);
+ return pSealedVirtualsSlotTable[slotNumber];
+ }
+ else
+ {
+ UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(ETF_SealedVirtualSlots);
+ PTR_Int32 pSealedVirtualsSlotTable = (PTR_Int32)FollowRelativePointer((PTR_Int32)((PTR_UInt8)this + cbSealedVirtualSlotsTypeOffset));
+ PTR_Code result = FollowRelativePointer(&pSealedVirtualsSlotTable[slotNumber]);
+ return result;
}
-
- UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(ETF_SealedVirtualSlots);
-
- PTR_Int32 pSealedVirtualsSlotTable = (PTR_Int32)FollowRelativePointer((PTR_Int32)((PTR_UInt8)this + cbSealedVirtualSlotsTypeOffset));
-
- PTR_Code result = FollowRelativePointer(&pSealedVirtualsSlotTable[slotNumber]);
-
- return result;
}
#endif // !BINDER && !DACCESS_COMPILE
@@ -565,7 +556,9 @@ inline DynamicModule * EEType::get_DynamicModule()
((ArrayClass*)pMT->GetClass())->GetApproxArrayElementTypeHandle().AsMethodTable() :
NULL;
- bool fHasSealedVirtuals = pMT->GetNumVirtuals() < (pMT->GetNumVtableSlots() + pMT->GetNumAdditionalVtableSlots());
+ bool isMdArray = pMT->IsArray() && ((ArrayClass*)pMT->GetClass())->GetRank() > 0;
+ bool fHasSealedVirtuals = !isMdArray && (pMT->GetNumVirtuals() < (pMT->GetNumVtableSlots() + pMT->GetNumAdditionalVtableSlots()));
+
return
// Do we need a padding size for value types or unsealed classes? that could be unboxed?
(!pMT->IsArray() &&
@@ -581,7 +574,7 @@ inline DynamicModule * EEType::get_DynamicModule()
(pMT->IsHFA()) ||
#endif
// Do we need a DispatchMap?
- (pMT->GetDispatchMap() != NULL && !pMT->GetDispatchMap()->IsEmpty()) ||
+ (!isMdArray && pMT->GetDispatchMap() != NULL && !pMT->GetDispatchMap()->IsEmpty()) ||
// Do we need to cache ICastable method vtable slots?
(pMT->IsICastable()) ||
// Is the class a Nullable<T> instantiation (need to store the flag and possibly a field offset)?
@@ -714,13 +707,14 @@ __forceinline UInt32 EEType::GetFieldOffset(EETypeField eField)
// Binder does not use DynamicTemplateType
#ifndef BINDER
- UInt32 rareFlags = get_RareFlags();
- if (IsNullable() || ((rareFlags & IsDynamicTypeWithSealedVTableEntriesFlag) != 0))
+ if (IsNullable())
cbOffset += sizeof(UIntTarget);
+ UInt32 rareFlags = get_RareFlags();
+
// in the case of sealed vtable entries on static types, we have a UInt sized relative pointer
if (rareFlags & HasSealedVTableEntriesFlag)
- cbOffset += sizeof(UInt32);
+ cbOffset += (IsDynamicType() ? sizeof(UIntTarget) : sizeof(UInt32));
if (eField == ETF_DynamicDispatchMap)
{
@@ -748,11 +742,11 @@ __forceinline UInt32 EEType::GetFieldOffset(EETypeField eField)
if (eField == ETF_DynamicModule)
{
- ASSERT((get_RareFlags() & HasDynamicModuleFlag) != 0);
+ ASSERT((rareFlags & HasDynamicModuleFlag) != 0);
return cbOffset;
}
- if ((get_RareFlags() & HasDynamicModuleFlag) != 0)
+ if ((rareFlags & HasDynamicModuleFlag) != 0)
cbOffset += sizeof(UIntTarget);
if (eField == ETF_DynamicTemplateType)
diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs
index 5ca8d36b0..e7b4b31dc 100644
--- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs
+++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs
@@ -296,12 +296,9 @@ namespace Internal.Runtime.TypeLoader
UInt32 rareFlags = optionalFields.GetFieldValue(EETypeOptionalFieldTag.RareFlags, 0);
rareFlags |= (uint)EETypeRareFlags.IsDynamicTypeFlag; // Set the IsDynamicTypeFlag
rareFlags &= ~(uint)EETypeRareFlags.NullableTypeViaIATFlag; // Remove the NullableTypeViaIATFlag flag
- rareFlags &= ~(uint)EETypeRareFlags.HasSealedVTableEntriesFlag;// Remove the HasSealedVTableEntriesFlag
- // we'll set IsDynamicTypeWithSealedVTableEntriesFlag instead
- // Set the IsDynamicTypeWithSealedVTableEntriesFlag if needed
if (state.NumSealedVTableEntries > 0)
- rareFlags |= (uint)EETypeRareFlags.IsDynamicTypeWithSealedVTableEntriesFlag;
+ rareFlags |= (uint)EETypeRareFlags.HasSealedVTableEntriesFlag;
if (requiresDynamicDispatchMap)
rareFlags |= (uint)EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag;