diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2018-07-30 09:33:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-30 09:33:20 +0300 |
commit | 5dbb1ef9848e9580a30fbbd4caedba7aa7bc0502 (patch) | |
tree | c6f3eca265e9f5deadab2773b5f74fe656684e23 /src/ILCompiler.Compiler | |
parent | ba8cd5822bb7c2d9007df9c71cae9f859cf10f64 (diff) |
Add support for sealed vtables in CppCodegen (#6148)
This cleans up the codebase by removing a bunch of workarounds. This was pretty easy after 045a28051c6b85b82fe42e944fcb2267768ebbe2 gave us the option to emit different data structures for places that don't support relative pointers and be able to switch dynamically at runtime.
Diffstat (limited to 'src/ILCompiler.Compiler')
3 files changed, 16 insertions, 12 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs index 1d2c7832d..6299c3fff 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs @@ -774,7 +774,7 @@ namespace ILCompiler.DependencyAnalysis // Final NewSlot methods cannot be overridden, and therefore can be placed in the sealed-vtable to reduce the size of the vtable // of this type and any type that inherits from it. - if (declMethod.CanMethodBeInSealedVTable() && !declType.IsArrayTypeWithoutGenericInterfaces() && !factory.IsCppCodegenTemporaryWorkaround) + if (declMethod.CanMethodBeInSealedVTable() && !declType.IsArrayTypeWithoutGenericInterfaces()) continue; if (!implMethod.IsAbstract) @@ -838,7 +838,12 @@ namespace ILCompiler.DependencyAnalysis SealedVTableNode sealedVTable = factory.SealedVTable(_type.ConvertToCanonForm(CanonicalFormKind.Specific)); if (sealedVTable.BuildSealedVTableSlots(factory, relocsOnly) && sealedVTable.NumSealedVTableEntries > 0) - objData.EmitReloc(sealedVTable, RelocType.IMAGE_REL_BASED_RELPTR32); + { + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(sealedVTable, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(sealedVTable); + } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs index 942e14dc4..dac6d8dbc 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs @@ -90,10 +90,6 @@ namespace ILCompiler.DependencyAnalysis _sealedVTableEntries = new List<MethodDesc>(); - // Cpp codegen does not support sealed vtables - if (factory.IsCppCodegenTemporaryWorkaround) - return true; - IReadOnlyList<MethodDesc> virtualSlots = factory.VTable(declType).Slots; for (int i = 0; i < virtualSlots.Count; i++) @@ -153,7 +149,12 @@ namespace ILCompiler.DependencyAnalysis for (int i = 0; i < _sealedVTableEntries.Count; i++) { MethodDesc canonImplMethod = _sealedVTableEntries[i].GetCanonMethodTarget(CanonicalFormKind.Specific); - objData.EmitReloc(factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType), RelocType.IMAGE_REL_BASED_RELPTR32); + IMethodNode relocTarget = factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType); + + if (factory.Target.SupportsRelativePointers) + objData.EmitReloc(relocTarget, RelocType.IMAGE_REL_BASED_RELPTR32); + else + objData.EmitPointerReloc(relocTarget); } } diff --git a/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs b/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs index 8266ed8df..19da1f6ae 100644 --- a/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs +++ b/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs @@ -18,9 +18,7 @@ namespace ILCompiler /// </summary> public static int GetVirtualMethodSlot(NodeFactory factory, MethodDesc method, TypeDesc implType, bool countDictionarySlots = true) { - // CppCodegen does not yet support sealed vtables. - - if (method.CanMethodBeInSealedVTable() && !factory.IsCppCodegenTemporaryWorkaround) + if (method.CanMethodBeInSealedVTable()) { // If the method is a sealed newslot method, it will be put in the sealed vtable instead of the type's vtable. In this // case, the slot index return should be the index in the sealed vtable, plus the total number of vtable slots. @@ -71,7 +69,7 @@ namespace ILCompiler int numSealedVTableEntries = 0; for (int slot = 0; slot < virtualSlots.Count; slot++) { - if (virtualSlots[slot].CanMethodBeInSealedVTable() && !factory.IsCppCodegenTemporaryWorkaround) + if (virtualSlots[slot].CanMethodBeInSealedVTable()) { numSealedVTableEntries++; continue; @@ -133,7 +131,7 @@ namespace ILCompiler foreach (var vtableMethod in baseVirtualSlots) { // Methods in the sealed vtable should be excluded from the count - if (vtableMethod.CanMethodBeInSealedVTable() && !factory.IsCppCodegenTemporaryWorkaround) + if (vtableMethod.CanMethodBeInSealedVTable()) continue; baseSlots++; } |