diff options
author | David Wrighton <davidwr@microsoft.com> | 2017-05-17 04:42:43 +0300 |
---|---|---|
committer | David Wrighton <davidwr@microsoft.com> | 2017-05-17 04:42:43 +0300 |
commit | 0fb20786300a52505a011d84b44ff6ebc5475556 (patch) | |
tree | 5326a3029e3ac2c06abe43c559b394dac94fc72b /src | |
parent | d762c0277e666f85c3cbe60ca73a772ae31cd8b4 (diff) |
Lazy Generics
- Instead of performing lazy lookups at individual use sites, perform a single lazy lookup to get a dictionary, and then use normal canonical lookups from there
- Shares logic with USG dictionary acquisition, and with normal canonical codegen
- Add LazyGenericPolicy nob to CoreRT environment to control policy
Universal Shared Generics Changes
- Fixup EETypeNode generation for USG types
- Consider TemplateTypeLayout necessary for all universal generic canon types
- Use RhAllocLocal2 which returns a byref to the first field of the "local" object instead of the start of the object.
- Tweak USG field invoke map generation to not stop compilation. Still needs to be implemented.
[tfs-changeset: 1658670]
Diffstat (limited to 'src')
18 files changed, 136 insertions, 25 deletions
diff --git a/src/Common/src/TypeSystem/Common/TypeSystemHelpers.cs b/src/Common/src/TypeSystem/Common/TypeSystemHelpers.cs index 255eb7cfd..42ef2c736 100644 --- a/src/Common/src/TypeSystem/Common/TypeSystemHelpers.cs +++ b/src/Common/src/TypeSystem/Common/TypeSystemHelpers.cs @@ -70,7 +70,7 @@ namespace Internal.TypeSystem { if (type.IsValueType) { - return ((MetadataType)type).InstanceFieldSize; + return ((DefType)type).InstanceFieldSize; } else { diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs index 27a8aa07b..ae705d507 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs @@ -50,6 +50,9 @@ namespace ILCompiler.DependencyAnalysis dependencyList.Add(factory.VTable(_type), "VTable"); + if (_type.IsCanonicalSubtype(CanonicalFormKind.Universal)) + dependencyList.Add(factory.NativeLayout.TemplateTypeLayout(_type), "Universal generic types always have template layout"); + return dependencyList; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs index d4779341e..40438a24e 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs @@ -246,9 +246,17 @@ namespace ILCompiler.DependencyAnalysis { if (_type.IsArray) { - int elementSize = ((ArrayType)_type).ElementType.GetElementSize().AsInt; - // We validated that this will fit the short when the node was constructed. No need for nice messages. - objData.EmitShort((short)checked((ushort)elementSize)); + TypeDesc elementType = ((ArrayType)_type).ElementType; + if (elementType == elementType.Context.UniversalCanonType) + { + objData.EmitShort(0); + } + else + { + int elementSize = elementType.GetElementSize().AsInt; + // We validated that this will fit the short when the node was constructed. No need for nice messages. + objData.EmitShort((short)checked((ushort)elementSize)); + } } else if (_type.IsString) { @@ -303,8 +311,20 @@ namespace ILCompiler.DependencyAnalysis if (_type.IsDefType) { - objectSize = pointerSize + - ((DefType)_type).InstanceByteCount.AsInt; // +pointerSize for SyncBlock + LayoutInt instanceByteCount = ((DefType)_type).InstanceByteCount; + + if (instanceByteCount.IsIndeterminate) + { + // Some value must be put in, but the specific value doesn't matter as it + // isn't used for specific instantiations, and the universal canon eetype + // is never associated with an allocated object. + objectSize = pointerSize; + } + else + { + objectSize = pointerSize + + ((DefType)_type).InstanceByteCount.AsInt; // +pointerSize for SyncBlock + } if (_type.IsValueType) objectSize += pointerSize; // + EETypePtr field inherited from System.Object @@ -417,7 +437,7 @@ namespace ILCompiler.DependencyAnalysis { // Note: Canonical type instantiations always have a generic dictionary vtable slot, but it's empty // TODO: emit the correction dictionary slot for interfaces (needed when we start supporting static methods on interfaces) - if (declType.IsInterface || declType.IsCanonicalSubtype(CanonicalFormKind.Any)) + if (declType.IsInterface || declType.IsCanonicalSubtype(CanonicalFormKind.Any) || factory.LazyGenericsPolicy.UsesLazyGenerics(declType)) objData.EmitZeroPointer(); else objData.EmitPointerReloc(factory.TypeGenericDictionary(declType)); @@ -649,8 +669,17 @@ namespace ILCompiler.DependencyAnalysis DefType defType = _type as DefType; Debug.Assert(defType != null); - uint valueTypeFieldPadding = checked((uint)(defType.InstanceByteCount.AsInt - defType.InstanceByteCountUnaligned.AsInt)); - uint valueTypeFieldPaddingEncoded = EETypeBuilderHelpers.ComputeValueTypeFieldPaddingFieldValue(valueTypeFieldPadding, (uint)defType.InstanceFieldAlignment.AsInt); + uint valueTypeFieldPaddingEncoded; + + if (defType.InstanceByteCount.IsIndeterminate) + { + valueTypeFieldPaddingEncoded = EETypeBuilderHelpers.ComputeValueTypeFieldPaddingFieldValue(0, 1); + } + else + { + uint valueTypeFieldPadding = checked((uint)(defType.InstanceByteCount.AsInt - defType.InstanceByteCountUnaligned.AsInt)); + valueTypeFieldPaddingEncoded = EETypeBuilderHelpers.ComputeValueTypeFieldPaddingFieldValue(valueTypeFieldPadding, (uint)defType.InstanceFieldAlignment.AsInt); + } if (valueTypeFieldPaddingEncoded != 0) { @@ -757,8 +786,8 @@ namespace ILCompiler.DependencyAnalysis throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } - int elementSize = parameterType.GetElementSize().AsInt; - if (elementSize >= ushort.MaxValue) + LayoutInt elementSize = parameterType.GetElementSize(); + if (!elementSize.IsIndeterminate && elementSize.AsInt >= ushort.MaxValue) { // Element size over 64k can't be encoded in the GCDesc throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadValueClassTooLarge, parameterType); diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs index dabde0809..95d1cccf0 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs @@ -233,6 +233,11 @@ namespace ILCompiler.DependencyAnalysis Debug.Assert(builder.CountBytes == ((ISymbolDefinitionNode)this).Offset); + // Lazy method dictionaries are generated by the compiler, but they have no entries within them. (They are used solely to identify the exact method) + // The dictionary layout may be filled in by various needs for generic lookups, but those are handled in a lazy fashion. + if (factory.LazyGenericsPolicy.UsesLazyGenerics(OwningMethod)) + return; + base.EmitDataInternal(ref builder, factory); } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs index 0a684b8f5..8de26b4e6 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs @@ -16,7 +16,7 @@ namespace ILCompiler.DependencyAnalysis public sealed class ILScanNodeFactory : NodeFactory { public ILScanNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler) - : base(context, compilationModuleGroup, metadataManager, nameMangler) + : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy()) { } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ImportedGenericDictionaryNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ImportedGenericDictionaryNode.cs index 13b629c0e..ab42f5c55 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ImportedGenericDictionaryNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ImportedGenericDictionaryNode.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using Internal.TypeSystem; +using System.Diagnostics; namespace ILCompiler.DependencyAnalysis { @@ -26,6 +27,7 @@ namespace ILCompiler.DependencyAnalysis public ImportedTypeGenericDictionaryNode(NodeFactory factory, TypeDesc owningType) : base("__imp_" + TypeGenericDictionaryNode.GetMangledName(factory.NameMangler, owningType)) { + Debug.Assert(!factory.LazyGenericsPolicy.UsesLazyGenerics(owningType)); _owningType = owningType; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index bd7092774..a4425efee 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -689,18 +689,20 @@ namespace ILCompiler.DependencyAnalysis public sealed class NativeLayoutDictionarySignatureNode : NativeLayoutSavedVertexNode { private TypeSystemEntity _owningMethodOrType; - public NativeLayoutDictionarySignatureNode(TypeSystemEntity owningMethodOrType) + public NativeLayoutDictionarySignatureNode(NodeFactory nodeFactory, TypeSystemEntity owningMethodOrType) { if (owningMethodOrType is MethodDesc) { MethodDesc owningMethod = (MethodDesc)owningMethodOrType; - Debug.Assert(owningMethod.IsCanonicalMethod(CanonicalFormKind.Universal)); + Debug.Assert(owningMethod.IsCanonicalMethod(CanonicalFormKind.Universal) || nodeFactory.LazyGenericsPolicy.UsesLazyGenerics(owningMethod)); + Debug.Assert(owningMethod.IsCanonicalMethod(CanonicalFormKind.Any)); Debug.Assert(owningMethod.HasInstantiation); } else { TypeDesc owningType = (TypeDesc)owningMethodOrType; - Debug.Assert(owningType.IsCanonicalSubtype(CanonicalFormKind.Universal)); + Debug.Assert(owningType.IsCanonicalSubtype(CanonicalFormKind.Universal) || nodeFactory.LazyGenericsPolicy.UsesLazyGenerics(owningType)); + Debug.Assert(owningType.IsCanonicalSubtype(CanonicalFormKind.Any)); } _owningMethodOrType = owningMethodOrType; @@ -812,7 +814,7 @@ namespace ILCompiler.DependencyAnalysis DictionaryLayoutNode associatedLayout = factory.GenericDictionaryLayout(_method); ICollection<NativeLayoutVertexNode> templateLayout = associatedLayout.GetTemplateEntries(factory); - if (!_method.IsCanonicalMethod(CanonicalFormKind.Universal) && (templateLayout.Count > 0)) + if (!(_method.IsCanonicalMethod(CanonicalFormKind.Universal) || (factory.LazyGenericsPolicy.UsesLazyGenerics(_method))) && (templateLayout.Count > 0)) { List<NativeLayoutVertexNode> dictionaryVertices = new List<NativeLayoutVertexNode>(); @@ -1076,7 +1078,7 @@ namespace ILCompiler.DependencyAnalysis layoutInfo.Append(BagElementKind.ImplementedInterfaces, implementedInterfaces.WriteVertex(factory)); } - if (!_isUniversalCanon && (templateLayout.Count > 0)) + if (!(_isUniversalCanon || (factory.LazyGenericsPolicy.UsesLazyGenerics(_type)) )&& (templateLayout.Count > 0)) { List<NativeLayoutVertexNode> dictionaryVertices = new List<NativeLayoutVertexNode>(); diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs index 0c0336376..36e05bb04 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs @@ -191,7 +191,7 @@ namespace ILCompiler.DependencyAnalysis _dictionarySignatures = new NodeCache<TypeSystemEntity, NativeLayoutDictionarySignatureNode>(owningMethodOrType => { - return new NativeLayoutDictionarySignatureNode(owningMethodOrType); + return new NativeLayoutDictionarySignatureNode(_factory, owningMethodOrType); }); _integerSlots = new NodeCache<int, NativeLayoutIntegerDictionarySlotNode>(value => diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs index d12b20203..4e4b35357 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs @@ -26,7 +26,7 @@ namespace ILCompiler.DependencyAnalysis private bool _markingComplete; public NodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, - MetadataManager metadataManager, NameMangler nameMangler) + MetadataManager metadataManager, NameMangler nameMangler, LazyGenericsPolicy lazyGenericsPolicy) { _target = context.Target; _context = context; @@ -35,6 +35,7 @@ namespace ILCompiler.DependencyAnalysis InteropStubManager = new InteropStubManager(compilationModuleGroup, context, new InteropStateManager(compilationModuleGroup.GeneratedAssembly)); CreateNodeCaches(); MetadataManager = metadataManager; + LazyGenericsPolicy = lazyGenericsPolicy; } public void SetMarkingComplete() @@ -52,6 +53,7 @@ namespace ILCompiler.DependencyAnalysis } } + public LazyGenericsPolicy LazyGenericsPolicy { get; } public CompilationModuleGroup CompilationModuleGroup { get @@ -412,6 +414,7 @@ namespace ILCompiler.DependencyAnalysis { if (CompilationModuleGroup.ContainsType(type)) { + Debug.Assert(!this.LazyGenericsPolicy.UsesLazyGenerics(type)); return new TypeGenericDictionaryNode(type); } else diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonExternMethodSymbolNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonExternMethodSymbolNode.cs index 5543e12f3..d097d512f 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonExternMethodSymbolNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonExternMethodSymbolNode.cs @@ -45,7 +45,7 @@ namespace ILCompiler.DependencyAnalysis _hasCompiledBody = true; } - public void AddCompilationDiscoveredDependency(DependencyNodeCore<NodeFactory> node, string reason) + public void AddCompilationDiscoveredDependency(IDependencyNode<NodeFactory> node, string reason) { Debug.Assert(!_dependenciesQueried); if (_compilationDiscoveredDependencies == null) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs index aa551dc80..c063aecaa 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs @@ -139,7 +139,8 @@ namespace ILCompiler.DependencyAnalysis if ((flags & FieldTableFlags.IsUniversalCanonicalEntry) != 0) { - throw new NotImplementedException(); + // TODO: USG + continue; } else { diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs index 9e45d1a3e..19ef3ddd5 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs @@ -13,7 +13,7 @@ namespace ILCompiler.DependencyAnalysis public sealed class RyuJitNodeFactory : NodeFactory { public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler) - : base(context, compilationModuleGroup, metadataManager, nameMangler) + : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy()) { } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs index a921bb9a0..77b3595db 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs @@ -70,7 +70,7 @@ namespace ILCompiler } public UtcNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, IEnumerable<ModuleDesc> inputModules, string metadataFile, string outputFile, UTCNameMangler nameMangler) - : base(context, compilationModuleGroup, PickMetadataManager(context, compilationModuleGroup, inputModules, metadataFile), nameMangler) + : base(context, compilationModuleGroup, PickMetadataManager(context, compilationModuleGroup, inputModules, metadataFile), nameMangler, new AttributeDrivenLazyGenericsPolicy()) { CreateHostedNodeCaches(); CompilationUnitPrefix = nameMangler.CompilationUnitPrefix; diff --git a/src/ILCompiler.Compiler/src/Compiler/LazyGenericsPolicy.cs b/src/ILCompiler.Compiler/src/Compiler/LazyGenericsPolicy.cs new file mode 100644 index 000000000..738fd18e6 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/LazyGenericsPolicy.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Internal.TypeSystem; + +namespace ILCompiler +{ + public abstract class LazyGenericsPolicy + { + public abstract bool UsesLazyGenerics(MethodDesc method); + public abstract bool UsesLazyGenerics(TypeDesc type); + public abstract bool UsesLazyGenerics(MetadataType type); + } + + public sealed class AttributeDrivenLazyGenericsPolicy : LazyGenericsPolicy + { + public sealed override bool UsesLazyGenerics(MethodDesc method) + { + if (method.HasInstantiation) + return method.IsVirtual || method.HasCustomAttribute("System.Runtime.CompilerServices", "ForceLazyDictionaryAttribute"); + else + return UsesLazyGenerics(method.OwningType); + } + + public sealed override bool UsesLazyGenerics(TypeDesc type) + { + if (type is MetadataType) + return UsesLazyGenerics(type as MetadataType); + else + return false; + } + + public sealed override bool UsesLazyGenerics(MetadataType type) + { + return type.HasCustomAttribute("System.Runtime.CompilerServices", "ForceLazyDictionaryAttribute"); + } + } + + public sealed class LazyGenericsDisabledPolicy : LazyGenericsPolicy + { + public sealed override bool UsesLazyGenerics(MethodDesc method) => false; + public sealed override bool UsesLazyGenerics(TypeDesc type) => false; + public sealed override bool UsesLazyGenerics(MetadataType type) => false; + } +} diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index dc0d6d3a9..8c8ac269d 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -263,6 +263,7 @@ <Compile Include="Compiler\ExportedMethodsRootProvider.cs" /> <Compile Include="Compiler\IRootingServiceProvider.cs" /> <Compile Include="Compiler\JitHelper.cs" /> + <Compile Include="Compiler\LazyGenericsPolicy.cs" /> <Compile Include="Compiler\LibraryRootProvider.cs" /> <Compile Include="Compiler\MainMethodRootProvider.cs" /> <Compile Include="Compiler\MemoryHelper.cs" /> diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs index aac834c7d..ddd5e2fa8 100644 --- a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs +++ b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs @@ -10,7 +10,7 @@ namespace ILCompiler.DependencyAnalysis { public sealed class CppCodegenNodeFactory : NodeFactory { - public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler) + public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler, new LazyGenericsDisabledPolicy()) : base(context, compilationModuleGroup, metadataManager, nameMangler) { } diff --git a/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs index eb5c5e432..3c8868bf5 100644 --- a/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -270,6 +270,25 @@ namespace System.Runtime return new Wrapper(); } + // RhAllocLocal2 helper returns the pointer to the data region directly + // instead of relying on the code generator to offset the local by the + // size of a pointer to get the data region. + [RuntimeExport("RhAllocLocal2")] + public static unsafe ref byte RhAllocLocal2(EETypePtr pEEType) + { + EEType* ptrEEType = (EEType*)pEEType.ToPointer(); + if (ptrEEType->IsValueType) + { +#if FEATURE_64BIT_ALIGNMENT + if (ptrEEType->RequiresAlign8) + return ref InternalCalls.RhpNewFastMisalign(ptrEEType).GetRawData(); +#endif + return ref InternalCalls.RhpNewFast(ptrEEType).GetRawData(); + } + else + return ref new Wrapper().GetRawData(); + } + [RuntimeExport("RhMemberwiseClone")] public static unsafe object RhMemberwiseClone(object src) { diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 056cde86c..830e4dfae 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -1664,7 +1664,7 @@ namespace Internal.Runtime.TypeLoader // The second is the offset into the native layout info blob in that TypeManager, where the native signature is encoded. IntPtr** lazySignature = (IntPtr**)signature.ToPointer(); typeManager = new TypeManagerHandle(lazySignature[0][0]); - offset = checked((uint)lazySignature[0][1].ToInt32()); + offset = checked((uint)new IntPtr(lazySignature[1]).ToInt32()); reader = TypeLoaderEnvironment.Instance.GetNativeLayoutInfoReader(typeManager); } #if !CORERT |