diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-06-15 05:32:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-15 05:32:28 +0300 |
commit | f60512cb5616edd1ed31ec5316c342655b5f8bae (patch) | |
tree | 3e322a1f174460976dde8759ffe0a37b05243342 | |
parent | 2861da59da6ff383e4620e932c2c861d468ca52b (diff) | |
parent | cd13b4609cbc6795d8a776d579f872d076d61bf9 (diff) |
Merge pull request #3889 from dotnet-bot/from-tfs
Merge changes from TFS
-rw-r--r-- | src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs | 18 | ||||
-rw-r--r-- | src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs | 39 |
2 files changed, 57 insertions, 0 deletions
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 e7b4b31dc..4942325c6 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs @@ -338,6 +338,24 @@ namespace Internal.Runtime.TypeLoader else rareFlags &= ~(uint)EETypeRareFlags.IsByRefLikeFlag; + if (isNullable) + { + rareFlags |= (uint)EETypeRareFlags.IsNullableFlag; + uint nullableValueOffset = state.NullableValueOffset; + + // The stored offset is never zero (Nullable has a boolean there indicating whether the value is valid). + // If the real offset is one, then the field isn't set. Otherwise the offset is encoded - 1 to save space. + if (nullableValueOffset == 1) + optionalFields.ClearField(EETypeOptionalFieldTag.NullableValueOffset); + else + optionalFields.SetFieldValue(EETypeOptionalFieldTag.NullableValueOffset, checked(nullableValueOffset - 1)); + } + else + { + rareFlags &= ~(uint)EETypeRareFlags.IsNullableFlag; + optionalFields.ClearField(EETypeOptionalFieldTag.NullableValueOffset); + } + rareFlags |= (uint)EETypeRareFlags.HasDynamicModuleFlag; optionalFields.SetFieldValue(EETypeOptionalFieldTag.RareFlags, rareFlags); diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs index cd0142b0f..234de598b 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs @@ -1010,6 +1010,45 @@ namespace Internal.Runtime.TypeLoader } } + public uint NullableValueOffset + { + get + { + if (!TypeBeingBuilt.IsNullable) + return 0; + + if (TypeBeingBuilt.IsTemplateCanonical()) + { + // Pull the GC Desc from the canonical instantiation + TypeDesc templateType = TypeBeingBuilt.ComputeTemplate(); + bool success = templateType.RetrieveRuntimeTypeHandleIfPossible(); + Debug.Assert(success); + unsafe + { + return templateType.RuntimeTypeHandle.ToEETypePtr()->NullableValueOffset; + } + } + else + { + int fieldCount = 0; + uint nullableValueOffset = 0; + + foreach (FieldDesc f in GetFieldsForGCLayout()) + { + if (fieldCount == 1) + { + nullableValueOffset = checked((uint)f.Offset.AsInt); + } + fieldCount++; + } + + // Nullable<T> only has two fields. HasValue and Value + Debug.Assert(fieldCount == 2); + return nullableValueOffset; + } + } + } + public bool IsHFA { get |