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:
authorJan Kotas <jkotas@microsoft.com>2015-12-11 06:36:06 +0300
committerJan Kotas <jkotas@microsoft.com>2015-12-11 06:36:06 +0300
commit78d9cf9f7a3d3d68a5a7a626e2193a4de7b38370 (patch)
treee9fd5002140029642e08f183c27e608db1e81c5c /src/Common
parentaca70b738cd7c5c3c5c693c0aac1db8c2c26ed72 (diff)
parent0b395e6ba4476b5b63e3610032e7c970b0e925cb (diff)
Merge pull request #507 from nattress/eetype_optional_fields
Populate EEType Optional Fields
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/src/Internal/Runtime/EEType.Constants.cs (renamed from src/Common/src/Internal/Runtime/EETypeFlags.cs)92
-rw-r--r--src/Common/src/Internal/Runtime/EEType.cs56
-rw-r--r--src/Common/src/Internal/Runtime/EETypeOptionalFieldsBuilder.cs106
-rw-r--r--src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs8
4 files changed, 262 insertions, 0 deletions
diff --git a/src/Common/src/Internal/Runtime/EETypeFlags.cs b/src/Common/src/Internal/Runtime/EEType.Constants.cs
index ac0aca03b..580c9b2e6 100644
--- a/src/Common/src/Internal/Runtime/EETypeFlags.cs
+++ b/src/Common/src/Internal/Runtime/EEType.Constants.cs
@@ -101,4 +101,96 @@ namespace Internal.Runtime
/// </summary>
GenericTypeDefEEType = 0x0003,
}
+
+ /// <summary>
+ /// These are flag values that are rarely set for types. If any of them are set then an optional field will
+ /// be associated with the EEType to represent them.
+ /// </summary>
+ [Flags]
+ internal enum EETypeRareFlags : int
+ {
+ /// <summary>
+ /// This type requires 8-byte alignment for its fields on certain platforms (only ARM currently).
+ /// </summary>
+ RequiresAlign8Flag = 0x00000001,
+
+ /// <summary>
+ /// Type implements ICastable to allow dynamic resolution of interface casts.
+ /// </summary>
+ ICastableFlag = 0x00000002,
+
+ /// <summary>
+ /// Type is an instantiation of Nullable<T>.
+ /// </summary>
+ IsNullableFlag = 0x00000004,
+
+ /// <summary>
+ /// Nullable target type stashed in the EEType is indirected via the IAT.
+ /// </summary>
+ NullableTypeViaIATFlag = 0x00000008,
+
+ /// <summary>
+ /// This EEType was created by generic instantiation loader
+ /// </summary>
+ IsDynamicTypeFlag = 0x00000010,
+
+ /// <summary>
+ /// This EEType has a Class Constructor
+ /// </summary>
+ 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).
+ /// </summary>
+ IsDynamicTypeWithSealedVTableEntriesFlag = 0x00000040,
+
+ /// <summary>
+ /// 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)
+ /// </summary>
+ HasDynamicallyAllocatedDispatchMapFlag = 0x00000080,
+
+ /// <summary>
+ /// This EEType represents a structure that is an HFA
+ /// </summary>
+ IsHFAFlag = 0x00000100,
+ }
+
+ internal enum EETypeOptionalFieldsElement : byte
+ {
+ /// <summary>
+ /// Extra <c>EEType</c> flags not commonly used such as HasClassConstructor
+ /// </summary>
+ RareFlags,
+
+ /// <summary>
+ /// VTable slot of <see cref="ICastable.IsInstanceOfInterface"/> for direct invocation without interface dispatch overhead
+ /// </summary>
+ ICastableIsInstSlot,
+
+ /// <summary>
+ /// Index of the dispatch map pointer in the DispathMap table
+ /// </summary>
+ DispatchMap,
+
+ /// <summary>
+ /// Padding added to a value type when allocated on the GC heap
+ /// </summary>
+ ValueTypeFieldPadding,
+
+ /// <summary>
+ /// VTable slot of <see cref="ICastable.GetImplType"/> for direct invocation without interface dispatch overhead
+ /// </summary>
+ ICastableGetImplTypeSlot,
+
+ /// <summary>
+ /// Offset in Nullable&lt;T&gt; of the value field
+ /// </summary>
+ NullableValueOffset,
+
+ // Number of field types we support
+ Count
+ }
}
diff --git a/src/Common/src/Internal/Runtime/EEType.cs b/src/Common/src/Internal/Runtime/EEType.cs
new file mode 100644
index 000000000..f7c7bc4ee
--- /dev/null
+++ b/src/Common/src/Internal/Runtime/EEType.cs
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Diagnostics;
+
+namespace Internal.Runtime
+{
+ internal partial class EEType
+ {
+ // These masks and paddings have been chosen so that the ValueTypePadding field can always fit in a byte of data
+ // if the alignment is 8 bytes or less. If the alignment is higher then there may be a need for more bits to hold
+ // the rest of the padding data.
+ // If paddings of greater than 7 bytes are necessary, then the high bits of the field represent that padding
+ private const UInt32 ValueTypePaddingLowMask = 0x7;
+ private const UInt32 ValueTypePaddingHighMask = 0xFFFFFF00;
+ private const UInt32 ValueTypePaddingMax = 0x07FFFFFF;
+ private const int ValueTypePaddingHighShift = 8;
+ private const UInt32 ValueTypePaddingAlignmentMask = 0xF8;
+ private const int ValueTypePaddingAlignmentShift = 3;
+
+ /// <summary>
+ /// Compute the encoded value type padding and alignment that are stored as optional fields on an
+ /// <c>EEType</c>. This padding as added to naturally align value types when laid out as fields
+ /// of objects on the GCHeap. The amount of padding is recorded to allow unboxing to locals /
+ /// arrays of value types which don't need it.
+ /// </summary>
+ internal static UInt32 ComputeValueTypeFieldPaddingFieldValue(UInt32 padding, UInt32 alignment)
+ {
+ // For the default case, return 0
+ if ((padding == 0) && (alignment == IntPtr.Size))
+ return 0;
+
+ UInt32 alignmentLog2 = 0;
+ Debug.Assert(alignment != 0);
+
+ while ((alignment & 1) == 0)
+ {
+ alignmentLog2++;
+ alignment = alignment >> 1;
+ }
+ Debug.Assert(alignment == 1);
+
+ Debug.Assert(ValueTypePaddingMax >= padding);
+
+ // Our alignment values here are adjusted by one to allow for a default of 0 (which represents pointer alignment)
+ alignmentLog2++;
+
+ UInt32 paddingLowBits = padding & ValueTypePaddingLowMask;
+ UInt32 paddingHighBits = ((padding & ~ValueTypePaddingLowMask) >> ValueTypePaddingAlignmentShift) << ValueTypePaddingHighShift;
+ UInt32 alignmentLog2Bits = alignmentLog2 << ValueTypePaddingAlignmentShift;
+ Debug.Assert((alignmentLog2Bits & ~ValueTypePaddingAlignmentMask) == 0);
+ return paddingLowBits | paddingHighBits | alignmentLog2Bits;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Common/src/Internal/Runtime/EETypeOptionalFieldsBuilder.cs b/src/Common/src/Internal/Runtime/EETypeOptionalFieldsBuilder.cs
new file mode 100644
index 000000000..01d4f4f8d
--- /dev/null
+++ b/src/Common/src/Internal/Runtime/EETypeOptionalFieldsBuilder.cs
@@ -0,0 +1,106 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Runtime.InteropServices;
+using Internal.Runtime;
+using Internal.NativeFormat;
+using System.Diagnostics;
+using System.Text;
+
+namespace Internal.Runtime
+{
+ internal unsafe partial class EETypeOptionalFieldsBuilder
+ {
+ NativePrimitiveEncoder _encoder;
+ OptionalField[] _rgFields = new OptionalField[(int)EETypeOptionalFieldsElement.Count];
+
+ struct OptionalField
+ {
+ internal bool _fieldPresent;
+ internal UInt32 _value;
+ }
+
+ internal EETypeOptionalFieldsBuilder() {}
+
+ internal UInt32 GetFieldValue(EETypeOptionalFieldsElement eTag, UInt32 defaultValueIfNotFound)
+ {
+ return _rgFields[(int)eTag]._fieldPresent ? _rgFields[(int)eTag]._value : defaultValueIfNotFound;
+ }
+
+ internal void SetFieldValue(EETypeOptionalFieldsElement eTag, UInt32 value)
+ {
+ _rgFields[(int)eTag]._fieldPresent = true;
+ _rgFields[(int)eTag]._value = value;
+ }
+
+ internal void ClearField(EETypeOptionalFieldsElement eTag)
+ {
+ _rgFields[(int)eTag]._fieldPresent = false;
+ }
+
+ private int Encode()
+ {
+ EETypeOptionalFieldsElement eLastTag = EETypeOptionalFieldsElement.Count;
+
+ for (EETypeOptionalFieldsElement eTag = 0; eTag < EETypeOptionalFieldsElement.Count; eTag++)
+ eLastTag = _rgFields[(int)eTag]._fieldPresent ? eTag : eLastTag;
+
+ if (eLastTag == EETypeOptionalFieldsElement.Count)
+ return 0;
+
+ _encoder = new NativePrimitiveEncoder();
+ _encoder.Init();
+
+ for (EETypeOptionalFieldsElement eTag = 0; eTag < EETypeOptionalFieldsElement.Count; eTag++)
+ {
+ if (!_rgFields[(int)eTag]._fieldPresent)
+ continue;
+
+ _encoder.WriteByte((byte)((byte)eTag | (eTag == eLastTag ? 0x80 : 0)));
+ _encoder.WriteUnsigned(_rgFields[(int)eTag]._value);
+ }
+
+ return _encoder.Size;
+ }
+
+ public byte[] GetBytes()
+ {
+ Debug.Assert(IsAtLeastOneFieldUsed());
+ if (_encoder.Size == 0)
+ {
+ Encode();
+ }
+
+ return _encoder.GetBytes();
+ }
+
+ public bool IsAtLeastOneFieldUsed()
+ {
+ for (int i = 0; i < (int)EETypeOptionalFieldsElement.Count; i++)
+ {
+ if (_rgFields[i]._fieldPresent)
+ return true;
+ }
+
+ return false;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < (int)EETypeOptionalFieldsElement.Count; i++)
+ {
+ sb.Append(_rgFields[i]._value.ToString());
+
+ if (i != (int)EETypeOptionalFieldsElement.Count - 1)
+ {
+ sb.Append("_");
+ }
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs b/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs
index 437c51d6e..51604a385 100644
--- a/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs
+++ b/src/Common/src/TypeSystem/Common/DefType.FieldLayout.cs
@@ -230,6 +230,14 @@ namespace Internal.TypeSystem
}
}
+ /// <summary>
+ /// Do the fields of the type satisfy the Homogeneous Float Aggregate classification on ARM architecture?
+ /// </summary>
+ public virtual bool IsHFA()
+ {
+ return false;
+ }
+
internal void ComputeInstanceFieldLayout()
{
var computedLayout = this.Context.GetLayoutAlgorithmForType(this).ComputeInstanceFieldLayout(this);