From 7b63a50976c379156a5e11f6394f958f892eaeb2 Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Sun, 20 Jan 2019 08:19:14 -0800 Subject: [PATCH 1/9] - Updated the CommandLineParser nuget package --- Source/Mosa.Tool.Compiler/Mosa.Tool.Compiler.csproj | 4 ++-- Source/Mosa.Tool.Compiler/packages.config | 2 +- .../Mosa.Tool.CreateBootImage.csproj | 4 ++-- Source/Mosa.Tool.CreateBootImage/packages.config | 2 +- .../Mosa.Tool.Disassembler.Intel.csproj | 4 ++-- Source/Mosa.Tool.Disassembler.Intel/packages.config | 2 +- Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj | 4 ++-- Source/Mosa.Tool.Explorer/packages.config | 2 +- Source/Mosa.Tool.GDBDebugger/Mosa.Tool.GDBDebugger.csproj | 4 ++-- Source/Mosa.Tool.GDBDebugger/packages.config | 2 +- Source/Mosa.Tool.Launcher/Mosa.Tool.Launcher.csproj | 4 ++-- Source/Mosa.Tool.Launcher/packages.config | 2 +- Source/Mosa.Tools.Package/Mosa.Tools.Package.csproj | 4 ++-- Source/Mosa.Tools.Package/packages.config | 2 +- Source/Mosa.Utility.Launcher/Mosa.Utility.Launcher.csproj | 4 ++-- Source/Mosa.Utility.Launcher/packages.config | 2 +- 16 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Source/Mosa.Tool.Compiler/Mosa.Tool.Compiler.csproj b/Source/Mosa.Tool.Compiler/Mosa.Tool.Compiler.csproj index 6ed7b242c1..b93c704bd8 100644 --- a/Source/Mosa.Tool.Compiler/Mosa.Tool.Compiler.csproj +++ b/Source/Mosa.Tool.Compiler/Mosa.Tool.Compiler.csproj @@ -65,8 +65,8 @@ Mosa.Tool.Compiler.Program - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll diff --git a/Source/Mosa.Tool.Compiler/packages.config b/Source/Mosa.Tool.Compiler/packages.config index 838d739ee7..98da6a2929 100644 --- a/Source/Mosa.Tool.Compiler/packages.config +++ b/Source/Mosa.Tool.Compiler/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Tool.CreateBootImage/Mosa.Tool.CreateBootImage.csproj b/Source/Mosa.Tool.CreateBootImage/Mosa.Tool.CreateBootImage.csproj index a7a4405810..675cf13538 100644 --- a/Source/Mosa.Tool.CreateBootImage/Mosa.Tool.CreateBootImage.csproj +++ b/Source/Mosa.Tool.CreateBootImage/Mosa.Tool.CreateBootImage.csproj @@ -62,8 +62,8 @@ - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll diff --git a/Source/Mosa.Tool.CreateBootImage/packages.config b/Source/Mosa.Tool.CreateBootImage/packages.config index 838d739ee7..98da6a2929 100644 --- a/Source/Mosa.Tool.CreateBootImage/packages.config +++ b/Source/Mosa.Tool.CreateBootImage/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Tool.Disassembler.Intel/Mosa.Tool.Disassembler.Intel.csproj b/Source/Mosa.Tool.Disassembler.Intel/Mosa.Tool.Disassembler.Intel.csproj index f4c17a2d4d..5ca0170ec8 100644 --- a/Source/Mosa.Tool.Disassembler.Intel/Mosa.Tool.Disassembler.Intel.csproj +++ b/Source/Mosa.Tool.Disassembler.Intel/Mosa.Tool.Disassembler.Intel.csproj @@ -103,8 +103,8 @@ - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll ..\packages\SharpDisasm.1.1.11\lib\net45\SharpDisasm.dll diff --git a/Source/Mosa.Tool.Disassembler.Intel/packages.config b/Source/Mosa.Tool.Disassembler.Intel/packages.config index 7c98940e88..8dedb39b8d 100644 --- a/Source/Mosa.Tool.Disassembler.Intel/packages.config +++ b/Source/Mosa.Tool.Disassembler.Intel/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj b/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj index e27cf30c05..855348791c 100644 --- a/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj +++ b/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj @@ -56,8 +56,8 @@ magnifier.ico - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll False diff --git a/Source/Mosa.Tool.Explorer/packages.config b/Source/Mosa.Tool.Explorer/packages.config index 7c98940e88..8dedb39b8d 100644 --- a/Source/Mosa.Tool.Explorer/packages.config +++ b/Source/Mosa.Tool.Explorer/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Tool.GDBDebugger/Mosa.Tool.GDBDebugger.csproj b/Source/Mosa.Tool.GDBDebugger/Mosa.Tool.GDBDebugger.csproj index 3504334cc1..bedceb41c5 100644 --- a/Source/Mosa.Tool.GDBDebugger/Mosa.Tool.GDBDebugger.csproj +++ b/Source/Mosa.Tool.GDBDebugger/Mosa.Tool.GDBDebugger.csproj @@ -46,8 +46,8 @@ bug.ico - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll ..\packages\SharpDisasm.1.1.11\lib\net45\SharpDisasm.dll diff --git a/Source/Mosa.Tool.GDBDebugger/packages.config b/Source/Mosa.Tool.GDBDebugger/packages.config index 4a01b89564..80dcf53996 100644 --- a/Source/Mosa.Tool.GDBDebugger/packages.config +++ b/Source/Mosa.Tool.GDBDebugger/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Tool.Launcher/Mosa.Tool.Launcher.csproj b/Source/Mosa.Tool.Launcher/Mosa.Tool.Launcher.csproj index ae2e381a11..cf726fcbdb 100644 --- a/Source/Mosa.Tool.Launcher/Mosa.Tool.Launcher.csproj +++ b/Source/Mosa.Tool.Launcher/Mosa.Tool.Launcher.csproj @@ -62,8 +62,8 @@ rocket.ico - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll False diff --git a/Source/Mosa.Tool.Launcher/packages.config b/Source/Mosa.Tool.Launcher/packages.config index dc70fe61af..4233deaa44 100644 --- a/Source/Mosa.Tool.Launcher/packages.config +++ b/Source/Mosa.Tool.Launcher/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Tools.Package/Mosa.Tools.Package.csproj b/Source/Mosa.Tools.Package/Mosa.Tools.Package.csproj index 47f0ca42f8..a915b79c83 100644 --- a/Source/Mosa.Tools.Package/Mosa.Tools.Package.csproj +++ b/Source/Mosa.Tools.Package/Mosa.Tools.Package.csproj @@ -64,8 +64,8 @@ - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll False diff --git a/Source/Mosa.Tools.Package/packages.config b/Source/Mosa.Tools.Package/packages.config index d5f10a925b..f58d423d32 100644 --- a/Source/Mosa.Tools.Package/packages.config +++ b/Source/Mosa.Tools.Package/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Source/Mosa.Utility.Launcher/Mosa.Utility.Launcher.csproj b/Source/Mosa.Utility.Launcher/Mosa.Utility.Launcher.csproj index 98f90293eb..199431e3aa 100644 --- a/Source/Mosa.Utility.Launcher/Mosa.Utility.Launcher.csproj +++ b/Source/Mosa.Utility.Launcher/Mosa.Utility.Launcher.csproj @@ -63,8 +63,8 @@ - - ..\packages\CommandLineParser.2.3.0\lib\net45\CommandLine.dll + + ..\packages\CommandLineParser.2.4.3\lib\netstandard2.0\CommandLine.dll False diff --git a/Source/Mosa.Utility.Launcher/packages.config b/Source/Mosa.Utility.Launcher/packages.config index 7c98940e88..8dedb39b8d 100644 --- a/Source/Mosa.Utility.Launcher/packages.config +++ b/Source/Mosa.Utility.Launcher/packages.config @@ -1,6 +1,6 @@  - + From f6c90d62c7793efda4c2f691ceffb30cfebd8238 Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Sun, 20 Jan 2019 10:12:31 -0800 Subject: [PATCH 2/9] - Move 32-bit division code to non-platform specific runtime --- .../Stages/IRSubstitutionStage.cs | 14 +- .../Stages/IRSubstitutionStage.cs | 27 +-- Source/Mosa.Runtime.x86/Division.cs | 163 ----------------- Source/Mosa.Runtime/Division.cs | 170 ++++++++++++++++++ Source/Mosa.Runtime/Mosa.Runtime.csproj | 1 + 5 files changed, 191 insertions(+), 184 deletions(-) create mode 100644 Source/Mosa.Runtime/Division.cs diff --git a/Source/Mosa.Platform.x64/Stages/IRSubstitutionStage.cs b/Source/Mosa.Platform.x64/Stages/IRSubstitutionStage.cs index ceeefdb547..b828b51473 100644 --- a/Source/Mosa.Platform.x64/Stages/IRSubstitutionStage.cs +++ b/Source/Mosa.Platform.x64/Stages/IRSubstitutionStage.cs @@ -26,7 +26,7 @@ private void RemFloatR4(InstructionNode node) Debug.Assert(node.Result.IsR4); Debug.Assert(node.Operand1.IsR4); - ReplaceWithDivisionCall(node, "RemR4", node.Result, node.Operand1, node.Operand2); + ReplaceWithPlatformDivisionCall(node, "RemR4", node.Result, node.Operand1, node.Operand2); } private void RemFloatR8(InstructionNode node) @@ -34,20 +34,12 @@ private void RemFloatR8(InstructionNode node) Debug.Assert(node.Result.IsR8); Debug.Assert(node.Operand1.IsR8); - ReplaceWithDivisionCall(node, "RemR8", node.Result, node.Operand1, node.Operand2); + ReplaceWithPlatformDivisionCall(node, "RemR8", node.Result, node.Operand1, node.Operand2); } #endregion Visitation Methods - /// - /// Replaces the with division call. - /// - /// The node. - /// Name of the method. - /// The result. - /// The operand1. - /// The operand2. - private void ReplaceWithDivisionCall(InstructionNode node, string methodName, Operand result, Operand operand1, Operand operand2) + private void ReplaceWithPlatformDivisionCall(InstructionNode node, string methodName, Operand result, Operand operand1, Operand operand2) { var type = TypeSystem.GetTypeByName("Mosa.Runtime.x64", "Division"); diff --git a/Source/Mosa.Platform.x86/Stages/IRSubstitutionStage.cs b/Source/Mosa.Platform.x86/Stages/IRSubstitutionStage.cs index 8e740ebb1a..569548262f 100644 --- a/Source/Mosa.Platform.x86/Stages/IRSubstitutionStage.cs +++ b/Source/Mosa.Platform.x86/Stages/IRSubstitutionStage.cs @@ -30,7 +30,7 @@ private void RemFloatR4(InstructionNode node) Debug.Assert(node.Result.IsR4); Debug.Assert(node.Operand1.IsR4); - ReplaceWithDivisionCall(node, "RemR4", node.Result, node.Operand1, node.Operand2); + ReplaceWithPlatformDivisionCall(node, "RemR4", node.Result, node.Operand1, node.Operand2); } private void RemFloatR8(InstructionNode node) @@ -38,7 +38,7 @@ private void RemFloatR8(InstructionNode node) Debug.Assert(node.Result.IsR8); Debug.Assert(node.Operand1.IsR8); - ReplaceWithDivisionCall(node, "RemR8", node.Result, node.Operand1, node.Operand2); + ReplaceWithPlatformDivisionCall(node, "RemR8", node.Result, node.Operand1, node.Operand2); } private void RemSigned64(InstructionNode node) @@ -63,15 +63,22 @@ private void DivUnsigned64(InstructionNode node) #endregion Visitation Methods - /// - /// Replaces the with division call. - /// - /// The node. - /// Name of the method. - /// The result. - /// The operand1. - /// The operand2. private void ReplaceWithDivisionCall(InstructionNode node, string methodName, Operand result, Operand operand1, Operand operand2) + { + var type = TypeSystem.GetTypeByName("Mosa.Runtime", "Division"); + + Debug.Assert(type != null, "Cannot find type: Mosa.Runtime.Division type"); + + var method = type.FindMethodByName(methodName); + + Debug.Assert(method != null, "Cannot find method: " + methodName); + + var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem); + + node.SetInstruction(IRInstruction.CallStatic, result, symbol, operand1, operand2); + } + + private void ReplaceWithPlatformDivisionCall(InstructionNode node, string methodName, Operand result, Operand operand1, Operand operand2) { var type = TypeSystem.GetTypeByName("Mosa.Runtime.x86", "Division"); diff --git a/Source/Mosa.Runtime.x86/Division.cs b/Source/Mosa.Runtime.x86/Division.cs index 8152378db0..58cccdb127 100644 --- a/Source/Mosa.Runtime.x86/Division.cs +++ b/Source/Mosa.Runtime.x86/Division.cs @@ -67,168 +67,5 @@ public static float RemR4(float n, float d) return Native.Remainder(n, d); } - - /* Divides unsigned 64-bit N by unsigned 64-bit D and returns the quotient. */ - - public static ulong udiv64(ulong n, ulong d) - { - DivUmod(n, d, out ulong quotient, out ulong remainder); - return quotient; - } - - /* Divides unsigned 64-bit N by unsigned 64-bit D and returns the remainder. */ - - public static ulong umod64(ulong n, ulong d) - { - DivUmod(n, d, out ulong quotient, out ulong remainder); - return remainder; - } - - /* Divides signed 64-bit N by signed 64-bit D and returns the quotient. */ - - public static long sdiv64(long n, long d) - { - DivMod(n, d, out long quotient, out long remainder); - return quotient; - } - - /* Divides signed 64-bit N by signed 64-bit D and returns the remainder. */ - - public static long smod64(long n, long d) - { - DivMod(n, d, out long quotient, out long remainder); - return remainder; - } - - public static void DivUmod(ulong dividend, ulong divisor, out ulong quotient, out ulong remainder) - { - bool isFlipped = false; - quotient = dividend; - remainder = 0; - for (int i = 0; i < 65; i++) - { - remainder <<= 1; - - if (isFlipped) - { - remainder |= 1; - } - - isFlipped = (quotient & 0x8000000000000000) != 0; - - quotient <<= 1; - - if (remainder >= divisor) - { - remainder -= divisor; - quotient++; - } - } - } - - public unsafe static void DivMod(long dividend, long divisor, out long quotient, out long remainder) - { - // Catch divide by zero and just return zero - if (dividend == 0 || divisor == 0) - { - quotient = 0; - remainder = 0; - return; - } - - // Catch divide by same number - if (dividend == divisor) - { - quotient = 1; - remainder = 0; - return; - } - - // Catch divide by one - if (divisor == 1 || divisor == -1) - { - quotient = dividend * divisor; - remainder = 0; - return; - } - - // Catch divide by same number but opposite sign - if (dividend == (divisor * -1)) - { - quotient = -1; - remainder = 0; - return; - } - - // Determine the sign of the results and make the operands positive. - int remainderSign = 1; - int quotientSign = 1; - ulong uQuotient = (ulong)dividend; - ulong uRemainder = 0; - ulong uDivisor = (ulong)divisor; - bool isFlipped = false; - if (dividend < 0) - { - if (dividend == -9223372036854775808) - uQuotient = (ulong)dividend; - else - uQuotient = (ulong)-dividend; - remainderSign = -1; - } - if (divisor < 0) - { - if (divisor == -9223372036854775808) - uDivisor = (ulong)divisor; - else - uDivisor = (ulong)-divisor; - quotientSign = -1; - } - - quotientSign *= remainderSign; - - for (int i = 0; i < 65; i++) - { - uRemainder <<= 1; - if (isFlipped) - { - uRemainder |= 1; - } - - isFlipped = (uQuotient & 0x8000000000000000) != 0; - - uQuotient <<= 1; - - if (uRemainder >= uDivisor) - { - uRemainder -= uDivisor; - uQuotient++; - } - } - unchecked - { - quotient = (long)uQuotient; - remainder = (long)uRemainder; - } - - // Adjust sign of the results. - if (quotient != 0) - { - int oldSign = ((ulong)quotient & 0x8000000000000000) != 0 ? -1 : 1; - - if (oldSign == -1 && quotientSign == -1) - quotient++; - - quotient *= quotientSign; - } - - if (remainder != 0) - { - int oldSign = ((ulong)remainder & 0x8000000000000000) != 0 ? -1 : 1; - if (oldSign == -1 && remainderSign == -1) - remainder++; - - remainder *= remainderSign; - } - } } } diff --git a/Source/Mosa.Runtime/Division.cs b/Source/Mosa.Runtime/Division.cs new file mode 100644 index 0000000000..c7fd4e951b --- /dev/null +++ b/Source/Mosa.Runtime/Division.cs @@ -0,0 +1,170 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +namespace Mosa.Runtime +{ + internal static class Division + { + /* Divides unsigned 64-bit N by unsigned 64-bit D and returns the quotient. */ + + public static ulong udiv64(ulong n, ulong d) + { + DivUmod(n, d, out ulong quotient, out ulong remainder); + return quotient; + } + + /* Divides unsigned 64-bit N by unsigned 64-bit D and returns the remainder. */ + + public static ulong umod64(ulong n, ulong d) + { + DivUmod(n, d, out ulong quotient, out ulong remainder); + return remainder; + } + + /* Divides signed 64-bit N by signed 64-bit D and returns the quotient. */ + + public static long sdiv64(long n, long d) + { + DivMod(n, d, out long quotient, out long remainder); + return quotient; + } + + /* Divides signed 64-bit N by signed 64-bit D and returns the remainder. */ + + public static long smod64(long n, long d) + { + DivMod(n, d, out long quotient, out long remainder); + return remainder; + } + + public static void DivUmod(ulong dividend, ulong divisor, out ulong quotient, out ulong remainder) + { + bool isFlipped = false; + quotient = dividend; + remainder = 0; + for (int i = 0; i < 65; i++) + { + remainder <<= 1; + + if (isFlipped) + { + remainder |= 1; + } + + isFlipped = (quotient & 0x8000000000000000) != 0; + + quotient <<= 1; + + if (remainder >= divisor) + { + remainder -= divisor; + quotient++; + } + } + } + + public unsafe static void DivMod(long dividend, long divisor, out long quotient, out long remainder) + { + // Catch divide by zero and just return zero + if (dividend == 0 || divisor == 0) + { + quotient = 0; + remainder = 0; + return; + } + + // Catch divide by same number + if (dividend == divisor) + { + quotient = 1; + remainder = 0; + return; + } + + // Catch divide by one + if (divisor == 1 || divisor == -1) + { + quotient = dividend * divisor; + remainder = 0; + return; + } + + // Catch divide by same number but opposite sign + if (dividend == (divisor * -1)) + { + quotient = -1; + remainder = 0; + return; + } + + // Determine the sign of the results and make the operands positive. + int remainderSign = 1; + int quotientSign = 1; + ulong uQuotient = (ulong)dividend; + ulong uRemainder = 0; + ulong uDivisor = (ulong)divisor; + bool isFlipped = false; + if (dividend < 0) + { + if (dividend == -9223372036854775808) + uQuotient = (ulong)dividend; + else + uQuotient = (ulong)-dividend; + remainderSign = -1; + } + if (divisor < 0) + { + if (divisor == -9223372036854775808) + uDivisor = (ulong)divisor; + else + uDivisor = (ulong)-divisor; + quotientSign = -1; + } + + quotientSign *= remainderSign; + + for (int i = 0; i < 65; i++) + { + uRemainder <<= 1; + if (isFlipped) + { + uRemainder |= 1; + } + + isFlipped = (uQuotient & 0x8000000000000000) != 0; + + uQuotient <<= 1; + + if (uRemainder >= uDivisor) + { + uRemainder -= uDivisor; + uQuotient++; + } + } + unchecked + { + quotient = (long)uQuotient; + remainder = (long)uRemainder; + } + + // Adjust sign of the results. + if (quotient != 0) + { + int oldSign = ((ulong)quotient & 0x8000000000000000) != 0 ? -1 : 1; + + if (oldSign == -1 && quotientSign == -1) + quotient++; + + quotient *= quotientSign; + } + + if (remainder != 0) + { + int oldSign = ((ulong)remainder & 0x8000000000000000) != 0 ? -1 : 1; + if (oldSign == -1 && remainderSign == -1) + remainder++; + + remainder *= remainderSign; + } + } + } +} diff --git a/Source/Mosa.Runtime/Mosa.Runtime.csproj b/Source/Mosa.Runtime/Mosa.Runtime.csproj index 8e9902c56a..732a677aa9 100644 --- a/Source/Mosa.Runtime/Mosa.Runtime.csproj +++ b/Source/Mosa.Runtime/Mosa.Runtime.csproj @@ -67,6 +67,7 @@ false + From 0af5bffacf1f467eff811df6cd287c2ce73debcd Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Sun, 20 Jan 2019 20:45:36 -0800 Subject: [PATCH 3/9] - WIP --- .../CIL/IInstructionDecoder.cs | 14 ++- .../CIL/InvokeInstruction.cs | 2 +- .../CIL/LdfldInstruction.cs | 2 +- .../CIL/LdfldaInstruction.cs | 2 +- .../CIL/LdftnInstruction.cs | 2 +- .../CIL/LdsfldInstruction.cs | 2 +- .../CIL/LdsfldaInstruction.cs | 2 +- .../CIL/NewobjInstruction.cs | 3 - .../CIL/StfldInstruction.cs | 2 +- .../CIL/StsfldInstruction.cs | 2 +- .../CompilationScheduler.cs | 15 --- Source/Mosa.Compiler.Framework/Compiler.cs | 7 ++ .../CompilerOptions.cs | 6 + .../TypeInitializerSchedulerStage.cs | 6 +- .../Mosa.Compiler.Framework/MethodScanner.cs | 116 ++++++++++++++++++ .../Mosa.Compiler.Framework.csproj | 1 + .../Mosa.Compiler.Framework/MosaCompiler.cs | 14 ++- .../Stages/CILDecodingStage.cs | 11 +- .../Stages/CILTransformationStage.cs | 2 + .../Stages/CallStage.cs | 18 +++ .../Stages/ExceptionStage.cs | 4 + .../Stages/LowerIRStage.cs | 8 ++ .../CompilerStages/StartUpStage.cs | 4 + .../CompilerStages/MultibootV1Stage.cs | 6 +- .../CompilerStages/MultibootV1Stage.cs | 6 +- .../Intrinsic/GetIDTJumpLocation.cs | 2 + Source/Mosa.Platform.x86/Intrinsic/IRQs.cs | 2 + .../Stages/IRSubstitutionStage.cs | 4 + .../Mosa.Tool.Launcher/MainForm.Designer.cs | 67 +++++----- Source/Mosa.Tool.Launcher/MainForm.cs | 4 +- Source/Mosa.Utility.Launcher/Builder.cs | 2 +- Source/Mosa.Utility.Launcher/Options.cs | 9 +- .../Mosa.Utility.UnitTests/UnitTestEngine.cs | 1 - 33 files changed, 262 insertions(+), 86 deletions(-) create mode 100644 Source/Mosa.Compiler.Framework/MethodScanner.cs diff --git a/Source/Mosa.Compiler.Framework/CIL/IInstructionDecoder.cs b/Source/Mosa.Compiler.Framework/CIL/IInstructionDecoder.cs index 75de374cae..3a2ea319a4 100644 --- a/Source/Mosa.Compiler.Framework/CIL/IInstructionDecoder.cs +++ b/Source/Mosa.Compiler.Framework/CIL/IInstructionDecoder.cs @@ -20,17 +20,19 @@ public interface IInstructionDecoder MosaMethod Method { get; } /// - /// Gets the instruction being decoded. + /// Gets the type system. /// - MosaInstruction Instruction { get; } + TypeSystem TypeSystem { get; } /// /// Gets the type system. /// - /// - /// The type system. - /// - TypeSystem TypeSystem { get; } + MethodScanner MethodScanner { get; } + + /// + /// Gets the instruction being decoded. + /// + MosaInstruction Instruction { get; } /// /// Gets the block. diff --git a/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs index 36ee87acf2..3b04ee1602 100644 --- a/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs @@ -114,7 +114,7 @@ protected static MosaMethod DecodeInvocationTarget(InstructionNode node, IInstru { var method = (MosaMethod)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackMethodInvoked(method); + //decoder.MethodScanner.TrackMethodInvoked(method); node.InvokeMethod = method; diff --git a/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs index ec00ebc202..ff7c4ffe9e 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs @@ -37,7 +37,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); + //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); node.Result = AllocateVirtualRegisterOrStackSlot(decoder.MethodCompiler, field.FieldType); node.MosaField = field; diff --git a/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs index 374790f618..bd7cee6b14 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs @@ -36,7 +36,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); + //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); node.MosaField = field; node.Result = AllocateVirtualRegisterOrStackSlot(decoder.MethodCompiler, field.FieldType.ToManagedPointer()); diff --git a/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs index c4c62835f8..b011eecb2c 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs @@ -36,7 +36,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var method = (MosaMethod)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackMethodInvoked(method); + //decoder.MethodScanner.TrackMethodInvoked(method); node.Result = decoder.MethodCompiler.CreateVirtualRegister(decoder.TypeSystem.ToFnPtr(method.Signature)); node.InvokeMethod = method; diff --git a/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs index d613e053dd..f68ba44a44 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs @@ -38,7 +38,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); + //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); Debug.Assert(field.IsStatic, "Static field access on non-static field."); diff --git a/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs index b2dfb74db2..f0f020876e 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs @@ -31,7 +31,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); + //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); node.MosaField = field; node.Result = decoder.MethodCompiler.CreateVirtualRegister(field.FieldType.ToManagedPointer()); diff --git a/Source/Mosa.Compiler.Framework/CIL/NewobjInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/NewobjInstruction.cs index 6d3b439806..579e0789d1 100644 --- a/Source/Mosa.Compiler.Framework/CIL/NewobjInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/NewobjInstruction.cs @@ -90,9 +90,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) // Remove the this argument from the invocation, it's not on the stack yet. node.OperandCount--; - decoder.MethodCompiler.Scheduler.TrackTypeAllocated(ctor.DeclaringType); - decoder.MethodCompiler.Scheduler.TrackTypeAllocated(node.InvokeMethod.DeclaringType); - // Set a return value according to the type of the object allocated node.Result = decoder.MethodCompiler.AllocateVirtualRegisterOrStackSlot(ctor.DeclaringType); node.ResultCount = 1; diff --git a/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs index 6c4dd7526a..75bb75c925 100644 --- a/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs @@ -37,7 +37,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); + //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); node.MosaField = field; } diff --git a/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs index bf6ec93d08..61ad3092ae 100644 --- a/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs @@ -37,7 +37,7 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); + //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); node.MosaField = field; } diff --git a/Source/Mosa.Compiler.Framework/CompilationScheduler.cs b/Source/Mosa.Compiler.Framework/CompilationScheduler.cs index d670edbcda..4fb4b05a94 100644 --- a/Source/Mosa.Compiler.Framework/CompilationScheduler.cs +++ b/Source/Mosa.Compiler.Framework/CompilationScheduler.cs @@ -103,19 +103,6 @@ public bool IsScheduled(MosaMethod method) } } - public void TrackTypeAllocated(MosaType type) - { - } - - public void TrackMethodInvoked(MosaMethod method) - { - } - - public void TrackFieldReferenced(MosaField field) - { - // TODO - } - public MosaMethod GetMethodToCompile() { return queue.Dequeue(); @@ -125,8 +112,6 @@ public void AddToInlineQueue(CompilerMethodData methodData) { Debug.Assert(!methodData.Method.HasOpenGenericParams); - //Debug.Assert(!methodData.Method.IsLinkerGenerated); - inlineQueue.Enqueue(methodData); } diff --git a/Source/Mosa.Compiler.Framework/Compiler.cs b/Source/Mosa.Compiler.Framework/Compiler.cs index 21587085e9..e40127e0cc 100644 --- a/Source/Mosa.Compiler.Framework/Compiler.cs +++ b/Source/Mosa.Compiler.Framework/Compiler.cs @@ -64,6 +64,11 @@ public sealed class Compiler /// The compiler options. public CompilerOptions CompilerOptions { get; } + /// + /// Gets the method scanner. + /// + public MethodScanner MethodScanner { get; } + /// /// Gets the counters. /// @@ -207,6 +212,8 @@ public Compiler(MosaCompiler mosaCompiler) CompilationScheduler = mosaCompiler.CompilationScheduler; Linker = mosaCompiler.Linker; + MethodScanner = new MethodScanner(this); + CompilerExtensions.AddRange(mosaCompiler.CompilerExtensions); methodStagePipelines = new Pipeline[mosaCompiler.MaxThreads]; diff --git a/Source/Mosa.Compiler.Framework/CompilerOptions.cs b/Source/Mosa.Compiler.Framework/CompilerOptions.cs index 8d53adbb2d..c1ec96546c 100644 --- a/Source/Mosa.Compiler.Framework/CompilerOptions.cs +++ b/Source/Mosa.Compiler.Framework/CompilerOptions.cs @@ -141,6 +141,11 @@ public class CompilerOptions /// public List SourceFiles { get; set; } = new List(); + /// + /// Gets or sets a value indicating whether [enable method scanner]. + /// + public bool EnableMethodScanner { get; set; } + /// /// Adds additional sections to the Elf-File. /// @@ -311,6 +316,7 @@ public CompilerOptions() EnableValueNumbering = true; EnableLoopInvariantCodeMotion = true; EnablePlatformOptimizations = true; + EnableMethodScanner = false; } } } diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs index 63381612db..388b667d7e 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs @@ -75,9 +75,11 @@ protected override void RunPreCompile() typeInitializerMethod = Compiler.CreateLinkerMethod(TypeInitializerName); var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp"); - var startUpMethod = startUpType.FindMethodByName("InitializeAssembly"); + var initializeAssemblyMethod = startUpType.FindMethodByName("InitializeAssembly"); - Compiler.PlugSystem.CreatePlug(startUpMethod, typeInitializerMethod); + Compiler.PlugSystem.CreatePlug(initializeAssemblyMethod, typeInitializerMethod); + + Compiler.MethodScanner.MethodInvoked(typeInitializerMethod); } protected override void RunPostCompile() diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs new file mode 100644 index 0000000000..25507dca5e --- /dev/null +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -0,0 +1,116 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.MosaTypeSystem; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Mosa.Compiler.Framework +{ + public class MethodScanner + { + public bool IsEnabled { get; set; } + + private Compiler Compiler { get; } + private HashSet allocatedTypes = new HashSet(); + private HashSet invokedMethods = new HashSet(); + + private object _lock = new object(); + + public MethodScanner(Compiler compiler) + { + Compiler = compiler; + IsEnabled = compiler.CompilerOptions.EnableMethodScanner; + + Initialize(); + } + + public void TypeAllocated(MosaType type) + { + if (!IsEnabled) + return; + + lock (allocatedTypes) + { + if (allocatedTypes.Contains(type)) + return; + + allocatedTypes.Add(type); + + Debug.WriteLine("New Type Allocated: " + type.FullName); + + // find all invoked methods for this type + lock (_lock) + { + foreach (var method in type.Methods) + { + if (invokedMethods.Contains(method)) + { + ScheduleMethod(method); + } + } + + foreach (var property in type.Properties) + { + if (property.GetterMethod != null && invokedMethods.Contains(property.GetterMethod)) + { + ScheduleMethod(property.GetterMethod); + } + + if (property.SetterMethod != null && invokedMethods.Contains(property.SetterMethod)) + { + ScheduleMethod(property.SetterMethod); + } + } + } + } + } + + public void MethodInvoked(MosaMethod method) + { + if (!IsEnabled) + return; + + lock (_lock) + { + if (invokedMethods.Contains(method)) + return; + + invokedMethods.Add(method); + + if (method.IsStatic) + { + ScheduleMethod(method); + } + } + } + + private void ScheduleMethod(MosaMethod method) + { + Debug.WriteLine("Scanner Scheduling: " + method.ToString()); + Compiler.CompilationScheduler.Schedule(method); + } + + public void Initialize() + { + var entryPoint = Compiler.TypeSystem.EntryPoint; + + if (entryPoint != null) + { + invokedMethods.Add(entryPoint); + ScheduleMethod(entryPoint); + } + + //foreach (var type in Compiler.TypeSystem.AllTypes) + //{ + // foreach (var method in type.Methods) + // { + // // TODO + // } + //} + } + } +} diff --git a/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj b/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj index d192b79d70..840276018b 100644 --- a/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj +++ b/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj @@ -329,6 +329,7 @@ + diff --git a/Source/Mosa.Compiler.Framework/MosaCompiler.cs b/Source/Mosa.Compiler.Framework/MosaCompiler.cs index 23e9844626..036e3888dc 100644 --- a/Source/Mosa.Compiler.Framework/MosaCompiler.cs +++ b/Source/Mosa.Compiler.Framework/MosaCompiler.cs @@ -64,7 +64,12 @@ public void Execute() { Initialize(); PreCompile(); - ScheduleAll(); + + if (!CompilerOptions.EnableMethodScanner) + { + ScheduleAll(); + } + Compile(); PostCompile(); } @@ -73,7 +78,12 @@ public void ExecuteThreaded() { Initialize(); PreCompile(); - ScheduleAll(); + + if (!CompilerOptions.EnableMethodScanner) + { + ScheduleAll(); + } + Compiler.ExecuteThreadedCompile(MaxThreads); PostCompile(); } diff --git a/Source/Mosa.Compiler.Framework/Stages/CILDecodingStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILDecodingStage.cs index 3fe9aa2249..c9f804d65d 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILDecodingStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILDecodingStage.cs @@ -268,14 +268,19 @@ private BasicBlock GetBlockByLabel(int label) MosaMethod IInstructionDecoder.Method { get { return MethodCompiler.Method; } } /// - /// Gets the Instruction being decoded. + /// Gets the type system. /// - MosaInstruction IInstructionDecoder.Instruction { get { return instruction; } } + TypeSystem IInstructionDecoder.TypeSystem { get { return TypeSystem; } } /// /// Gets the type system. /// - TypeSystem IInstructionDecoder.TypeSystem { get { return TypeSystem; } } + MethodScanner IInstructionDecoder.MethodScanner { get { return MethodCompiler.Compiler.MethodScanner; } } + + /// + /// Gets the Instruction being decoded. + /// + MosaInstruction IInstructionDecoder.Instruction { get { return instruction; } } /// /// Gets the block. diff --git a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs index c861960907..bdaaffe5df 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs @@ -1192,6 +1192,7 @@ private void Newarr(InstructionNode node) var runtimeTypeHandle = GetRuntimeTypeHandle(arrayType); var size = CreateConstant(elementSize); node.SetInstruction(IRInstruction.NewArray, result, runtimeTypeHandle, size, elements); + node.MosaType = arrayType; } /// @@ -1242,6 +1243,7 @@ private void Newobj(Context context) var runtimeTypeHandle = GetRuntimeTypeHandle(classType); var size = CreateConstant(TypeLayout.GetTypeSize(classType)); before.SetInstruction(IRInstruction.NewObject, result, runtimeTypeHandle, size); + before.MosaType = classType; operands.Insert(0, result); } diff --git a/Source/Mosa.Compiler.Framework/Stages/CallStage.cs b/Source/Mosa.Compiler.Framework/Stages/CallStage.cs index e9cb2dd847..faaa74d9a3 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CallStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CallStage.cs @@ -98,6 +98,10 @@ private void CallStatic(InstructionNode node) context.Empty(); MakeCall(context, call, result, operands); + + Debug.Assert(method == call.Method); + + MethodCompiler.Compiler.MethodScanner.MethodInvoked(call.Method); } private void CallDynamic(InstructionNode node) @@ -113,6 +117,11 @@ private void CallDynamic(InstructionNode node) context.Empty(); MakeCall(context, call, result, operands); + + if (call.Method != null) + { + MethodCompiler.Compiler.MethodScanner.MethodInvoked(call.Method); + } } private void CallVirtual(InstructionNode node) @@ -144,6 +153,8 @@ private void CallVirtual(InstructionNode node) context.AppendInstruction(loadInstruction, callTarget, typeDefinition, CreateConstant(methodPointerOffset)); MakeCall(context, callTarget, result, operands); + + MethodCompiler.Compiler.MethodScanner.MethodInvoked(method); } private int CalculateInterfaceSlot(MosaType interaceType) @@ -208,6 +219,8 @@ private void CallInterface(InstructionNode node) context.AppendInstruction(loadInstruction, callTarget, methodDefinition, CreateConstant(methodPointerOffset)); MakeCall(context, callTarget, result, operands); + + MethodCompiler.Compiler.MethodScanner.MethodInvoked(method); } private void MakeCall(Context context, Operand target, Operand result, List operands) @@ -223,6 +236,11 @@ private void MakeCall(Context context, Operand target, Operand result, List IncludeFiles { get; set; } public List Paths { get; set; } diff --git a/Source/Mosa.Utility.UnitTests/UnitTestEngine.cs b/Source/Mosa.Utility.UnitTests/UnitTestEngine.cs index dff5d22947..44c237386c 100644 --- a/Source/Mosa.Utility.UnitTests/UnitTestEngine.cs +++ b/Source/Mosa.Utility.UnitTests/UnitTestEngine.cs @@ -83,7 +83,6 @@ public UnitTestEngine() BaseAddress = 0x00500000, EmitStaticRelocations = false, EmitAllSymbols = false, - Emitx86IRQMethods = true, SerialConnectionOption = SerialConnectionOption.TCPServer, SerialConnectionPort = 9999, SerialConnectionHost = "127.0.0.1", From c97f2b902e8560224eec7fad6e041e6fce7222d7 Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Mon, 21 Jan 2019 00:45:25 -0800 Subject: [PATCH 4/9] - WIP --- .../CIL/InvokeInstruction.cs | 2 - .../CIL/LdfldInstruction.cs | 2 - .../CIL/LdfldaInstruction.cs | 2 - .../CIL/LdftnInstruction.cs | 2 - .../CIL/LdsfldInstruction.cs | 2 - .../CIL/LdsfldaInstruction.cs | 2 - .../CIL/StfldInstruction.cs | 2 - .../CIL/StsfldInstruction.cs | 2 - .../Mosa.Compiler.Framework/MethodScanner.cs | 28 +++++--- .../Stages/CILTransformationStage.cs | 6 +- .../Stages/DevirtualizeCallStage.cs | 2 + Source/Mosa.Platform.x64/Architecture.cs | 4 -- .../CompilerStages/InterruptVectorStage.cs | 66 ------------------- .../Mosa.Platform.x64.csproj | 1 - Source/Mosa.TestWorld.x86/Tests/OtherTest.cs | 58 +++++++++++++++- 15 files changed, 82 insertions(+), 99 deletions(-) delete mode 100644 Source/Mosa.Platform.x64/CompilerStages/InterruptVectorStage.cs diff --git a/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs index 3b04ee1602..bbfc12d712 100644 --- a/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/InvokeInstruction.cs @@ -114,8 +114,6 @@ protected static MosaMethod DecodeInvocationTarget(InstructionNode node, IInstru { var method = (MosaMethod)decoder.Instruction.Operand; - //decoder.MethodScanner.TrackMethodInvoked(method); - node.InvokeMethod = method; // Fix the parameter list diff --git a/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs index ff7c4ffe9e..70995e4e1c 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdfldInstruction.cs @@ -37,8 +37,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); - node.Result = AllocateVirtualRegisterOrStackSlot(decoder.MethodCompiler, field.FieldType); node.MosaField = field; } diff --git a/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs index bd7cee6b14..de6a5258d6 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdfldaInstruction.cs @@ -36,8 +36,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); - node.MosaField = field; node.Result = AllocateVirtualRegisterOrStackSlot(decoder.MethodCompiler, field.FieldType.ToManagedPointer()); } diff --git a/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs index b011eecb2c..2828bf14e6 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdftnInstruction.cs @@ -36,8 +36,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var method = (MosaMethod)decoder.Instruction.Operand; - //decoder.MethodScanner.TrackMethodInvoked(method); - node.Result = decoder.MethodCompiler.CreateVirtualRegister(decoder.TypeSystem.ToFnPtr(method.Signature)); node.InvokeMethod = method; } diff --git a/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs index f68ba44a44..1e90e119c2 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdsfldInstruction.cs @@ -38,8 +38,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); - Debug.Assert(field.IsStatic, "Static field access on non-static field."); node.MosaField = field; diff --git a/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs index f0f020876e..6cffb22bbf 100644 --- a/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/LdsfldaInstruction.cs @@ -31,8 +31,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); - node.MosaField = field; node.Result = decoder.MethodCompiler.CreateVirtualRegister(field.FieldType.ToManagedPointer()); } diff --git a/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs index 75bb75c925..647953eb73 100644 --- a/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/StfldInstruction.cs @@ -37,8 +37,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); - node.MosaField = field; } diff --git a/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs b/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs index 61ad3092ae..42bf35860e 100644 --- a/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs +++ b/Source/Mosa.Compiler.Framework/CIL/StsfldInstruction.cs @@ -37,8 +37,6 @@ public override void Decode(InstructionNode node, IInstructionDecoder decoder) var field = (MosaField)decoder.Instruction.Operand; - //decoder.MethodCompiler.Scheduler.TrackFieldReferenced(field); - node.MosaField = field; } diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs index 25507dca5e..f7a728518d 100644 --- a/Source/Mosa.Compiler.Framework/MethodScanner.cs +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -1,12 +1,8 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. using Mosa.Compiler.MosaTypeSystem; -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Mosa.Compiler.Framework { @@ -18,6 +14,8 @@ public class MethodScanner private HashSet allocatedTypes = new HashSet(); private HashSet invokedMethods = new HashSet(); + private HashSet scheduledMethods = new HashSet(); + private object _lock = new object(); public MethodScanner(Compiler compiler) @@ -40,14 +38,14 @@ public void TypeAllocated(MosaType type) allocatedTypes.Add(type); - Debug.WriteLine("New Type Allocated: " + type.FullName); + Debug.WriteLine("***New Type Allocated: " + type.FullName); // find all invoked methods for this type lock (_lock) { foreach (var method in type.Methods) { - if (invokedMethods.Contains(method)) + if (!method.IsStatic && invokedMethods.Contains(method)) { ScheduleMethod(method); } @@ -55,12 +53,12 @@ public void TypeAllocated(MosaType type) foreach (var property in type.Properties) { - if (property.GetterMethod != null && invokedMethods.Contains(property.GetterMethod)) + if (property.GetterMethod != null && !property.GetterMethod.IsStatic && invokedMethods.Contains(property.GetterMethod)) { ScheduleMethod(property.GetterMethod); } - if (property.SetterMethod != null && invokedMethods.Contains(property.SetterMethod)) + if (property.SetterMethod != null && !property.SetterMethod.IsStatic && invokedMethods.Contains(property.SetterMethod)) { ScheduleMethod(property.SetterMethod); } @@ -81,6 +79,8 @@ public void MethodInvoked(MosaMethod method) invokedMethods.Add(method); + Debug.WriteLine("Method Invoked: " + method.FullName + (method.IsStatic ? " [Static]" : " [Virtual]")); + if (method.IsStatic) { ScheduleMethod(method); @@ -90,8 +90,16 @@ public void MethodInvoked(MosaMethod method) private void ScheduleMethod(MosaMethod method) { - Debug.WriteLine("Scanner Scheduling: " + method.ToString()); - Compiler.CompilationScheduler.Schedule(method); + lock (scheduledMethods) + { + if (scheduledMethods.Contains(method)) + return; + + scheduledMethods.Add(method); + + Debug.WriteLine(" Scheduling: " + method.ToString() + (method.IsStatic ? " [Static]" : " [Virtual]")); + Compiler.CompilationScheduler.Schedule(method); + } } public void Initialize() diff --git a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs index bdaaffe5df..7da6bdc3ae 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs @@ -969,7 +969,11 @@ private void Ldflda(InstructionNode node) /// The node. private void Ldftn(InstructionNode node) { - node.SetInstruction(Select(IRInstruction.MoveInt32, IRInstruction.MoveInt64), node.Result, Operand.CreateSymbolFromMethod(node.InvokeMethod, TypeSystem)); + var invokedMethod = node.InvokeMethod; + + node.SetInstruction(Select(IRInstruction.MoveInt32, IRInstruction.MoveInt64), node.Result, Operand.CreateSymbolFromMethod(invokedMethod, TypeSystem)); + + MethodCompiler.Compiler.MethodScanner.MethodInvoked(invokedMethod); } /// diff --git a/Source/Mosa.Compiler.Framework/Stages/DevirtualizeCallStage.cs b/Source/Mosa.Compiler.Framework/Stages/DevirtualizeCallStage.cs index 375d6cd0df..76929119b7 100644 --- a/Source/Mosa.Compiler.Framework/Stages/DevirtualizeCallStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/DevirtualizeCallStage.cs @@ -59,6 +59,8 @@ private void CallVirtual(InstructionNode node) DevirtualizedCount++; node.SetInstruction(IRInstruction.CallStatic, node.Result, symbol, operands); + + MethodCompiler.Compiler.MethodScanner.MethodInvoked(method); } } } diff --git a/Source/Mosa.Platform.x64/Architecture.cs b/Source/Mosa.Platform.x64/Architecture.cs index c6e7e2235a..e21475beb8 100644 --- a/Source/Mosa.Platform.x64/Architecture.cs +++ b/Source/Mosa.Platform.x64/Architecture.cs @@ -185,10 +185,6 @@ public override void ExtendCompilerPipeline(Pipeline compiler compilerPipeline.Add( new Intel.CompilerStages.StartUpStage() ); - - compilerPipeline.Add( - new InterruptVectorStage() - ); } /// diff --git a/Source/Mosa.Platform.x64/CompilerStages/InterruptVectorStage.cs b/Source/Mosa.Platform.x64/CompilerStages/InterruptVectorStage.cs deleted file mode 100644 index 794fa19874..0000000000 --- a/Source/Mosa.Platform.x64/CompilerStages/InterruptVectorStage.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; -using Mosa.Compiler.MosaTypeSystem; -using Mosa.Platform.Intel; - -namespace Mosa.Platform.x64.CompilerStages -{ - /// - /// Interrupt Vector Stage - /// - /// - public sealed class InterruptVectorStage : BaseCompilerStage - { - protected override void RunPreCompile() - { - CreateInterruptVectors(); - } - - /// - /// Creates the interrupt service routine (ISR) methods. - /// - private void CreateInterruptVectors() - { - var type = TypeSystem.GetTypeByName("Mosa.Kernel.x64", "IDT"); - - if (type == null) - return; - - var method = type.FindMethodByName("ProcessInterrupt"); - - if (method == null) - return; - - var interrupt = Operand.CreateSymbolFromMethod(method, TypeSystem); - - var esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); - - for (int i = 0; i <= 255; i++) - { - var basicBlocks = new BasicBlocks(); - var block = basicBlocks.CreateBlock(BasicBlock.PrologueLabel); - basicBlocks.AddHeadBlock(block); - var ctx = new Context(block); - - ctx.AppendInstruction(X64.Cli); - if (i <= 7 || (i >= 16 | i == 9)) // For IRQ 8, 10, 11, 12, 13, 14 the cpu will automatically pushed the error code - { - ctx.AppendInstruction(X64.Push64, null, CreateConstant(0)); - } - ctx.AppendInstruction(X64.Push64, null, CreateConstant(i)); - ctx.AppendInstruction(X64.Pushad); - ctx.AppendInstruction(X64.Push64, null, esp); - ctx.AppendInstruction(X64.Call, null, interrupt); - ctx.AppendInstruction(X64.Pop64, esp); - ctx.AppendInstruction(X64.Popad); - ctx.AppendInstruction(X64.Add64, esp, esp, CreateConstant(8)); - ctx.AppendInstruction(X64.Sti); - ctx.AppendInstruction(X64.IRetd); - - var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString()); - Compiler.CompileMethod(interruptMethod, basicBlocks); - } - } - } -} diff --git a/Source/Mosa.Platform.x64/Mosa.Platform.x64.csproj b/Source/Mosa.Platform.x64/Mosa.Platform.x64.csproj index 5dac970269..7eb349b23d 100644 --- a/Source/Mosa.Platform.x64/Mosa.Platform.x64.csproj +++ b/Source/Mosa.Platform.x64/Mosa.Platform.x64.csproj @@ -84,7 +84,6 @@ - diff --git a/Source/Mosa.TestWorld.x86/Tests/OtherTest.cs b/Source/Mosa.TestWorld.x86/Tests/OtherTest.cs index c577b84550..23191f1be0 100644 --- a/Source/Mosa.TestWorld.x86/Tests/OtherTest.cs +++ b/Source/Mosa.TestWorld.x86/Tests/OtherTest.cs @@ -34,6 +34,7 @@ public OtherTest() testMethods.Add(NullableTest4); testMethods.Add(NullableTest5); testMethods.Add(ForeachU1Test); + testMethods.Add(MethodScanner); } private const uint StaticValue = 0x200000; @@ -325,7 +326,16 @@ public uint AddressOfThis public static bool BoxTestEqualsI4() { - return Mosa.UnitTests.BoxingTests.EqualsI4(10); + return UnitTests.BoxingTests.EqualsI4(10); + } + + public static bool MethodScanner() + { + var shape = new VeryOddBox(); + + var i = shape.GetArea(); + + return true; } } @@ -361,4 +371,50 @@ public struct TestClassAA { public int I; } + + public abstract class Shape + { + public abstract int GetArea(); + + public int GetPerimeter() + { + return 0; + } + } + + public class Box : Shape + { + public override int GetArea() + { + return 10; + } + } + + public class Circle : Shape + { + public override int GetArea() + { + return 10; + } + } + + public class Rectangle : Box + { + public override int GetArea() + { + return 20; + } + } + + public class OddBox : Rectangle + { + public override int GetArea() + { + return 30; + } + } + + public class VeryOddBox : OddBox + { + } } From 08d3b46e0e7e55b93f282dbfa5703cf8947a002b Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Mon, 21 Jan 2019 12:19:44 -0800 Subject: [PATCH 5/9] - Added filter to the Explorer Tool (#574) --- .../Mosa.Compiler.Common/HasSetExtension.cs | 17 ++ Source/Mosa.Compiler.Common/ListExtension.cs | 21 --- .../Mosa.Compiler.Common.csproj | 1 + .../Mosa.Tool.Explorer/MainForm.Designer.cs | 57 ++++-- Source/Mosa.Tool.Explorer/MainForm.cs | 128 +++++++++++++- .../Mosa.Tool.Explorer.csproj | 4 + Source/Mosa.Tool.Explorer/Options.cs | 15 +- .../Mosa.Utility.GUI.Common/TypeSystemTree.cs | 163 +++++++++++------- 8 files changed, 305 insertions(+), 101 deletions(-) create mode 100644 Source/Mosa.Compiler.Common/HasSetExtension.cs diff --git a/Source/Mosa.Compiler.Common/HasSetExtension.cs b/Source/Mosa.Compiler.Common/HasSetExtension.cs new file mode 100644 index 0000000000..3bd0454ede --- /dev/null +++ b/Source/Mosa.Compiler.Common/HasSetExtension.cs @@ -0,0 +1,17 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Collections.Generic; + +namespace Mosa.Compiler.Common +{ + public static class HasSetExtension + { + public static void AddIfNew(this HashSet hashSet, T item) + { + if (hashSet.Contains(item)) + return; + + hashSet.Add(item); + } + } +} diff --git a/Source/Mosa.Compiler.Common/ListExtension.cs b/Source/Mosa.Compiler.Common/ListExtension.cs index bddb4cf00e..a867a4fc54 100644 --- a/Source/Mosa.Compiler.Common/ListExtension.cs +++ b/Source/Mosa.Compiler.Common/ListExtension.cs @@ -6,13 +6,6 @@ namespace Mosa.Compiler.Common { public static class ListExtension { - /// - /// Adds if new. - /// - /// - /// The list. - /// The item. - /// public static void AddIfNew(this List list, T item) { if (list.Contains(item)) @@ -21,20 +14,6 @@ public static void AddIfNew(this List list, T item) list.Add(item); } - public static void AddIfNew(this HashSet list, T item) - { - if (list.Contains(item)) - return; - - list.Add(item); - } - - /// - /// Determines whether the two lists' elements are equal. - /// - /// - /// The list. - /// The other list. public static bool SequenceEquals(this IList list, IList other) { if (list.Count != other.Count) diff --git a/Source/Mosa.Compiler.Common/Mosa.Compiler.Common.csproj b/Source/Mosa.Compiler.Common/Mosa.Compiler.Common.csproj index 6e859e9df1..adec615b2f 100644 --- a/Source/Mosa.Compiler.Common/Mosa.Compiler.Common.csproj +++ b/Source/Mosa.Compiler.Common/Mosa.Compiler.Common.csproj @@ -46,6 +46,7 @@ + diff --git a/Source/Mosa.Tool.Explorer/MainForm.Designer.cs b/Source/Mosa.Tool.Explorer/MainForm.Designer.cs index 5f6c8150c5..f6fe64fb68 100644 --- a/Source/Mosa.Tool.Explorer/MainForm.Designer.cs +++ b/Source/Mosa.Tool.Explorer/MainForm.Designer.cs @@ -58,10 +58,13 @@ private void InitializeComponent() this.padInstructions = new System.Windows.Forms.ToolStripMenuItem(); this.showSizes = new System.Windows.Forms.ToolStripMenuItem(); this.advanceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.cbEnableMethodScanner = new System.Windows.Forms.ToolStripMenuItem(); this.dumpAllMethodStagesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); this.treeView = new System.Windows.Forms.TreeView(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.label2 = new System.Windows.Forms.Label(); + this.tbFilter = new System.Windows.Forms.TextBox(); this.tabControl1 = new System.Windows.Forms.TabControl(); this.tbStages = new System.Windows.Forms.TabPage(); this.cbLabels = new System.Windows.Forms.ComboBox(); @@ -358,12 +361,20 @@ private void InitializeComponent() // // advanceToolStripMenuItem // + this.advanceToolStripMenuItem.CheckOnClick = true; this.advanceToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cbEnableMethodScanner, this.dumpAllMethodStagesToolStripMenuItem}); this.advanceToolStripMenuItem.Name = "advanceToolStripMenuItem"; this.advanceToolStripMenuItem.Size = new System.Drawing.Size(65, 20); this.advanceToolStripMenuItem.Text = "Advance"; // + // cbEnableMethodScanner + // + this.cbEnableMethodScanner.Name = "cbEnableMethodScanner"; + this.cbEnableMethodScanner.Size = new System.Drawing.Size(206, 22); + this.cbEnableMethodScanner.Text = "Enable Method Scanner"; + // // dumpAllMethodStagesToolStripMenuItem // this.dumpAllMethodStagesToolStripMenuItem.Name = "dumpAllMethodStagesToolStripMenuItem"; @@ -381,11 +392,12 @@ private void InitializeComponent() this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.treeView.Location = new System.Drawing.Point(0, 0); + this.treeView.Location = new System.Drawing.Point(0, 25); this.treeView.Name = "treeView"; - this.treeView.Size = new System.Drawing.Size(239, 427); + this.treeView.Size = new System.Drawing.Size(239, 402); this.treeView.TabIndex = 3; this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.TreeView_AfterSelect); + this.treeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView_NodeMouseDoubleClick); // // splitContainer1 // @@ -398,6 +410,8 @@ private void InitializeComponent() // // splitContainer1.Panel1 // + this.splitContainer1.Panel1.Controls.Add(this.label2); + this.splitContainer1.Panel1.Controls.Add(this.tbFilter); this.splitContainer1.Panel1.Controls.Add(this.treeView); this.splitContainer1.Panel1.RightToLeft = System.Windows.Forms.RightToLeft.No; // @@ -411,6 +425,25 @@ private void InitializeComponent() this.splitContainer1.SplitterWidth = 6; this.splitContainer1.TabIndex = 26; // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(1, 8); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(32, 13); + this.label2.TabIndex = 5; + this.label2.Text = "Filter:"; + // + // tbFilter + // + this.tbFilter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbFilter.Location = new System.Drawing.Point(33, 4); + this.tbFilter.Name = "tbFilter"; + this.tbFilter.Size = new System.Drawing.Size(203, 20); + this.tbFilter.TabIndex = 4; + this.tbFilter.TextChanged += new System.EventHandler(this.tbFilter_TextChanged); + // // tabControl1 // this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -429,7 +462,7 @@ private void InitializeComponent() this.tabControl1.Name = "tabControl1"; this.tabControl1.Padding = new System.Drawing.Point(0, 0); this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(639, 424); + this.tabControl1.Size = new System.Drawing.Size(633, 424); this.tabControl1.TabIndex = 38; // // tbStages @@ -443,7 +476,7 @@ private void InitializeComponent() this.tbStages.Location = new System.Drawing.Point(4, 25); this.tbStages.Margin = new System.Windows.Forms.Padding(0); this.tbStages.Name = "tbStages"; - this.tbStages.Size = new System.Drawing.Size(631, 395); + this.tbStages.Size = new System.Drawing.Size(625, 395); this.tbStages.TabIndex = 0; this.tbStages.Text = "Instructions"; // @@ -496,7 +529,7 @@ private void InitializeComponent() this.tbDebug.Location = new System.Drawing.Point(4, 25); this.tbDebug.Margin = new System.Windows.Forms.Padding(0); this.tbDebug.Name = "tbDebug"; - this.tbDebug.Size = new System.Drawing.Size(631, 395); + this.tbDebug.Size = new System.Drawing.Size(625, 395); this.tbDebug.TabIndex = 1; this.tbDebug.Text = "Debug"; // @@ -531,7 +564,7 @@ private void InitializeComponent() this.tbMethodCounters.Controls.Add(this.rbMethodCounters); this.tbMethodCounters.Location = new System.Drawing.Point(4, 25); this.tbMethodCounters.Name = "tbMethodCounters"; - this.tbMethodCounters.Size = new System.Drawing.Size(631, 395); + this.tbMethodCounters.Size = new System.Drawing.Size(625, 395); this.tbMethodCounters.TabIndex = 6; this.tbMethodCounters.Text = "Counters"; this.tbMethodCounters.UseVisualStyleBackColor = true; @@ -556,7 +589,7 @@ private void InitializeComponent() this.tbGlobalCounters.Location = new System.Drawing.Point(4, 25); this.tbGlobalCounters.Name = "tbGlobalCounters"; this.tbGlobalCounters.Padding = new System.Windows.Forms.Padding(3); - this.tbGlobalCounters.Size = new System.Drawing.Size(631, 395); + this.tbGlobalCounters.Size = new System.Drawing.Size(625, 395); this.tbGlobalCounters.TabIndex = 4; this.tbGlobalCounters.Text = "Global Counters"; // @@ -580,7 +613,7 @@ private void InitializeComponent() this.tbLogs.Location = new System.Drawing.Point(4, 25); this.tbLogs.Name = "tbLogs"; this.tbLogs.Padding = new System.Windows.Forms.Padding(3); - this.tbLogs.Size = new System.Drawing.Size(631, 395); + this.tbLogs.Size = new System.Drawing.Size(625, 395); this.tbLogs.TabIndex = 3; this.tbLogs.Text = "Log"; // @@ -604,7 +637,7 @@ private void InitializeComponent() this.tbErrors.Location = new System.Drawing.Point(4, 25); this.tbErrors.Name = "tbErrors"; this.tbErrors.Padding = new System.Windows.Forms.Padding(3); - this.tbErrors.Size = new System.Drawing.Size(631, 395); + this.tbErrors.Size = new System.Drawing.Size(625, 395); this.tbErrors.TabIndex = 2; this.tbErrors.Text = "Errors"; // @@ -627,7 +660,7 @@ private void InitializeComponent() this.tbExceptions.Location = new System.Drawing.Point(4, 25); this.tbExceptions.Name = "tbExceptions"; this.tbExceptions.Padding = new System.Windows.Forms.Padding(3); - this.tbExceptions.Size = new System.Drawing.Size(631, 395); + this.tbExceptions.Size = new System.Drawing.Size(625, 395); this.tbExceptions.TabIndex = 5; this.tbExceptions.Text = "Exceptions"; this.tbExceptions.UseVisualStyleBackColor = true; @@ -734,6 +767,7 @@ private void InitializeComponent() this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); this.splitContainer1.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); @@ -810,5 +844,8 @@ private void InitializeComponent() private System.Windows.Forms.TabPage tbExceptions; private System.Windows.Forms.RichTextBox rbException; private System.Windows.Forms.ToolStripMenuItem cbEnableValueNumbering; + private System.Windows.Forms.ToolStripMenuItem cbEnableMethodScanner; + private System.Windows.Forms.TextBox tbFilter; + private System.Windows.Forms.Label label2; } } diff --git a/Source/Mosa.Tool.Explorer/MainForm.cs b/Source/Mosa.Tool.Explorer/MainForm.cs index 388f8af843..527832b6f4 100644 --- a/Source/Mosa.Tool.Explorer/MainForm.cs +++ b/Source/Mosa.Tool.Explorer/MainForm.cs @@ -1,6 +1,7 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. using CommandLine; +using Mosa.Compiler.Common; using Mosa.Compiler.Framework; using Mosa.Compiler.Framework.Linker; using Mosa.Compiler.Framework.Trace; @@ -103,6 +104,9 @@ public void LoadArguments(string[] args) cbEnableSSA.Checked = !options.NoSSA; cbEnableIROptimizations.Checked = !options.NoIROptimizations; cbEnableSparseConditionalConstantPropagation.Checked = !options.NoSparse; + cbEnableMethodScanner.Checked = options.EnableMethodScanner; + + tbFilter.Text = options.Filter; if (options.X86) cbPlatform.SelectedIndex = 0; @@ -148,7 +152,110 @@ protected void CreateTree() return; } - typeSystemTree = new TypeSystemTree(treeView, Compiler.TypeSystem, Compiler.TypeLayout, showSizes.Checked); + var include = GetIncluded(tbFilter.Text, out MosaUnit selected); + + typeSystemTree = new TypeSystemTree(treeView, Compiler.TypeSystem, Compiler.TypeLayout, showSizes.Checked, include); + + Select(selected); + } + + protected void Select(MosaUnit selected) + { + if (selected == null) + return; + + foreach (TreeNode node in treeView.Nodes) + { + if (Select(node, selected)) + return; + } + } + + protected bool Select(TreeNode node, MosaUnit selected) + { + if (node == null) + return false; + + if (node.Tag != null) + { + if (node.Tag == selected) + { + treeView.SelectedNode = node; + node.EnsureVisible(); + return true; + } + } + + foreach (TreeNode children in node.Nodes) + { + if (Select(children, selected)) + return true; + } + + return false; + } + + protected HashSet GetIncluded(string value, out MosaUnit selected) + { + selected = null; + + value = value.Trim(); + + if (string.IsNullOrWhiteSpace(value)) + return null; + + if (value.Length < 1) + return null; + + var include = new HashSet(); + + MosaUnit typeSelected = null; + MosaUnit methodSelected = null; + + foreach (var type in Compiler.TypeSystem.AllTypes) + { + bool typeIncluded = false; + + var typeMatch = type.FullName.Contains(value); + + if (typeMatch) + { + include.Add(type); + include.AddIfNew(type.Module); + + if (typeSelected == null) + typeSelected = type; + } + + foreach (var method in type.Methods) + { + bool methodMatch = method.FullName.Contains(value); + + if (typeMatch || methodMatch) + { + include.Add(method); + include.AddIfNew(type); + include.AddIfNew(type.Module); + + if (methodMatch && methodSelected == null) + methodSelected = method; + } + } + + foreach (var property in type.Properties) + { + if (typeIncluded || property.FullName.Contains(value)) + { + include.Add(property); + include.AddIfNew(type); + include.AddIfNew(type.Module); + } + } + } + + selected = methodSelected ?? typeSelected; + + return include; } protected void UpdateTree() @@ -226,6 +333,7 @@ private void SetCompilerOptions() Compiler.CompilerOptions.InlinedIRMaximum = 12; Compiler.CompilerOptions.TwoPassOptimizations = cbEnableTwoPassOptimizations.Checked; Compiler.CompilerOptions.TraceLevel = 100; + Compiler.CompilerOptions.EnableMethodScanner = cbEnableMethodScanner.Checked; } private void CleanGUI() @@ -301,6 +409,7 @@ private static BaseArchitecture GetArchitecture(string platform) case "x86": return Platform.x86.Architecture.CreateArchitecture(Platform.x86.ArchitectureFeatureFlags.AutoDetect); case "x64": return Platform.x64.Architecture.CreateArchitecture(Platform.x64.ArchitectureFeatureFlags.AutoDetect); case "armv6": return Platform.ARMv6.Architecture.CreateArchitecture(Platform.ARMv6.ArchitectureFeatureFlags.AutoDetect); + case "esp32": return Platform.ESP32.Architecture.CreateArchitecture(Platform.ESP32.ArchitectureFeatureFlags.AutoDetect); default: return Platform.x86.Architecture.CreateArchitecture(Platform.x86.ArchitectureFeatureFlags.AutoDetect); } } @@ -495,6 +604,11 @@ private void UpdateDebugResults() } private void TreeView_AfterSelect(object sender, TreeViewEventArgs e) + { + NodeSelected(); + } + + private void NodeSelected() { tbResult.Text = string.Empty; @@ -505,7 +619,7 @@ private void TreeView_AfterSelect(object sender, TreeViewEventArgs e) PreCompile(); - if (!Compiler.CompilationScheduler.IsScheduled(method)) + if (Compiler.Linker != null && !Compiler.CompilationScheduler.IsScheduled(method)) { Compiler.Schedule(method); Compiler.Compile(); @@ -729,5 +843,15 @@ private void showOperandTypes_CheckStateChanged(object sender, EventArgs e) { UpdateResults(); } + + private void tbFilter_TextChanged(object sender, EventArgs e) + { + CreateTree(); + } + + private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) + { + NodeSelected(); + } } } diff --git a/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj b/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj index 855348791c..d0cb4a290c 100644 --- a/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj +++ b/Source/Mosa.Tool.Explorer/Mosa.Tool.Explorer.csproj @@ -118,6 +118,10 @@ {0fb92651-3ee8-441d-84f2-c4dfda68e8a5} Mosa.Platform.ARMv6 + + {5b45af28-3b67-4542-a0c9-947f3cdd9741} + Mosa.Platform.ESP32 + {f445db8e-e25a-41ef-a158-c742f14e94e4} Mosa.Platform.x64 diff --git a/Source/Mosa.Tool.Explorer/Options.cs b/Source/Mosa.Tool.Explorer/Options.cs index 810dd52587..054d30c724 100644 --- a/Source/Mosa.Tool.Explorer/Options.cs +++ b/Source/Mosa.Tool.Explorer/Options.cs @@ -28,19 +28,32 @@ internal class Options [Option("no-sparse")] public bool NoSparse { get; set; } + [Option("scanner")] + public bool EnableMethodScanner { get; set; } + [Option("x64")] public bool X64 { get; set; } [Option("x86")] public bool X86 { get; set; } + [Option("esp32")] + public bool ESP32 { get; set; } + + [Option("armv6")] + public bool ARMv6 { get; set; } + + [Option("filter")] + public string Filter { get; set; } + [Value(0)] public IEnumerable Files { get; set; } public Options() { - X64 = false; X86 = true; + X64 = false; + ESP32 = false; } } } diff --git a/Source/Mosa.Utility.GUI.Common/TypeSystemTree.cs b/Source/Mosa.Utility.GUI.Common/TypeSystemTree.cs index 3f08f96996..4007c5bbb3 100644 --- a/Source/Mosa.Utility.GUI.Common/TypeSystemTree.cs +++ b/Source/Mosa.Utility.GUI.Common/TypeSystemTree.cs @@ -19,13 +19,18 @@ public class TypeSystemTree private Dictionary map = new Dictionary(); private HashSet contains = new HashSet(); - public TypeSystemTree(TreeView treeView, TypeSystem typeSystem, MosaTypeLayout typeLayout, bool showSizes = true) + private HashSet Include; + + public bool HasFilter { get { return Include != null && Include.Count != 0; } } + + public TypeSystemTree(TreeView treeView, TypeSystem typeSystem, MosaTypeLayout typeLayout, bool showSizes = true, HashSet include = null) { TreeView = treeView; TypeSystem = typeSystem; TypeLayout = typeLayout; ShowSizes = showSizes; + Include = include; TreeView.BeginUpdate(); @@ -44,9 +49,15 @@ public void Update() foreach (var type in TypeSystem.AllTypes) { - foreach (var method in type.Methods) + if (Include == null || Include.Contains(type)) { - GetOrCreateNode(method); + foreach (var method in type.Methods) + { + if (Include == null || Include.Contains(method)) + { + GetOrCreateNode(method); + } + } } } @@ -57,7 +68,10 @@ public void Update(MosaMethod method) { //TreeView.BeginUpdate(); - GetOrCreateNode(method); + if (Include == null || Include.Contains(method)) + { + GetOrCreateNode(method); + } //TreeView.EndUpdate(); } @@ -66,7 +80,10 @@ private void CreateTreeBase() { foreach (var module in TypeSystem.Modules) { - GetOrCreateNode(module); + if (Include == null || Include.Contains(module)) + { + GetOrCreateNode(module); + } } } @@ -76,7 +93,10 @@ private void CreateInitialTree() foreach (var type in typeList) { - GetOrCreateNode(type); + if (Include == null || Include.Contains(type)) + { + GetOrCreateNode(type); + } } } @@ -213,88 +233,91 @@ private TreeNode GetOrCreateNode(MosaType type) foreach (var property in type.Properties) { - var propertyNode = new TreeNode(property.ShortName) { Tag = property }; - propertiesNode.Nodes.Add(propertyNode); - - if (property.GetterMethod != null) + if (Include == null || Include.Contains(property)) { - var getterNode = new TreeNode(property.GetterMethod.ShortName) { Tag = property.GetterMethod }; + var propertyNode = new TreeNode(property.ShortName) { Tag = property }; + propertiesNode.Nodes.Add(propertyNode); - propertyNode.Nodes.Add(getterNode); + if (property.GetterMethod != null) + { + var getterNode = new TreeNode(property.GetterMethod.ShortName) { Tag = property.GetterMethod }; - if (property.GetterMethod.IsStatic) - getterNode.Text += " [Static]"; + propertyNode.Nodes.Add(getterNode); - if (property.GetterMethod.IsAbstract) - getterNode.Text += " [Abstract]"; + if (property.GetterMethod.IsStatic) + getterNode.Text += " [Static]"; - if (property.GetterMethod.IsNewSlot) - { - getterNode.Text += " [NewSlot]"; - } + if (property.GetterMethod.IsAbstract) + getterNode.Text += " [Abstract]"; - if (property.GetterMethod.IsVirtual) - getterNode.Text += " [Virtual]"; + if (property.GetterMethod.IsNewSlot) + { + getterNode.Text += " [NewSlot]"; + } - if (property.GetterMethod.IsFinal) - { - getterNode.Text += " [Final]"; - } + if (property.GetterMethod.IsVirtual) + getterNode.Text += " [Virtual]"; - if (property.GetterMethod.IsSpecialName) - getterNode.Text += " [SpecialName]"; + if (property.GetterMethod.IsFinal) + { + getterNode.Text += " [Final]"; + } - if (property.GetterMethod.IsRTSpecialName) - getterNode.Text += " [RTSpecialName]"; + if (property.GetterMethod.IsSpecialName) + getterNode.Text += " [SpecialName]"; - if (property.GetterMethod.GenericArguments.Count != 0) - { - var genericParameterNodes = new TreeNode("Generic Arguments Types"); - getterNode.Nodes.Add(genericParameterNodes); + if (property.GetterMethod.IsRTSpecialName) + getterNode.Text += " [RTSpecialName]"; - foreach (var genericParameter in property.GetterMethod.GenericArguments) + if (property.GetterMethod.GenericArguments.Count != 0) { - var GenericParameterNode = new TreeNode(genericParameter.Name); - genericParameterNodes.Nodes.Add(GenericParameterNode); + var genericParameterNodes = new TreeNode("Generic Arguments Types"); + getterNode.Nodes.Add(genericParameterNodes); + + foreach (var genericParameter in property.GetterMethod.GenericArguments) + { + var GenericParameterNode = new TreeNode(genericParameter.Name); + genericParameterNodes.Nodes.Add(GenericParameterNode); + } } } - } - if (property.SetterMethod != null) - { - var setterNode = new TreeNode(property.SetterMethod.ShortName) { Tag = property.SetterMethod }; - propertyNode.Nodes.Add(setterNode); - - if (property.SetterMethod.IsStatic) - setterNode.Text += " [Static]"; + if (property.SetterMethod != null) + { + var setterNode = new TreeNode(property.SetterMethod.ShortName) { Tag = property.SetterMethod }; + propertyNode.Nodes.Add(setterNode); - if (property.SetterMethod.IsAbstract) - setterNode.Text += " [Abstract]"; + if (property.SetterMethod.IsStatic) + setterNode.Text += " [Static]"; - if (property.SetterMethod.IsNewSlot) - setterNode.Text += " [NewSlot]"; + if (property.SetterMethod.IsAbstract) + setterNode.Text += " [Abstract]"; - if (property.SetterMethod.IsVirtual) - setterNode.Text += " [Virtual]"; + if (property.SetterMethod.IsNewSlot) + setterNode.Text += " [NewSlot]"; - if (property.SetterMethod.IsFinal) - setterNode.Text += " [Final]"; + if (property.SetterMethod.IsVirtual) + setterNode.Text += " [Virtual]"; - if (property.SetterMethod.IsSpecialName) - setterNode.Text += " [SpecialName]"; + if (property.SetterMethod.IsFinal) + setterNode.Text += " [Final]"; - if (property.SetterMethod.IsRTSpecialName) - setterNode.Text += " [RTSpecialName]"; + if (property.SetterMethod.IsSpecialName) + setterNode.Text += " [SpecialName]"; - if (property.SetterMethod.GenericArguments.Count != 0) - { - var genericParameterNodes = new TreeNode("Generic Arguments Types"); - setterNode.Nodes.Add(genericParameterNodes); + if (property.SetterMethod.IsRTSpecialName) + setterNode.Text += " [RTSpecialName]"; - foreach (var genericParameter in property.SetterMethod.GenericArguments) + if (property.SetterMethod.GenericArguments.Count != 0) { - var GenericParameterNode = new TreeNode(genericParameter.Name); - genericParameterNodes.Nodes.Add(GenericParameterNode); + var genericParameterNodes = new TreeNode("Generic Arguments Types"); + setterNode.Nodes.Add(genericParameterNodes); + + foreach (var genericParameter in property.SetterMethod.GenericArguments) + { + var GenericParameterNode = new TreeNode(genericParameter.Name); + genericParameterNodes.Nodes.Add(GenericParameterNode); + } } } } @@ -310,7 +333,10 @@ private TreeNode GetOrCreateNode(MosaType type) // Methods foreach (var method in type.Methods) { - var methonode = GetOrCreateNode(method); + if (Include == null || Include.Contains(method)) + { + var methonode = GetOrCreateNode(method); + } } } @@ -324,8 +350,11 @@ private TreeNode GetOrCreateNode(MosaType type) foreach (var method in methodList) { - var methodNode = new TreeNode(method.ShortName) { Tag = method }; - methodTableNode.Nodes.Add(methodNode); + if (Include == null || Include.Contains(method)) + { + var methodNode = new TreeNode(method.ShortName) { Tag = method }; + methodTableNode.Nodes.Add(methodNode); + } } } From 83dac07ec7e34ff8074c1a5fc3e05fcd2d56acb2 Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Mon, 21 Jan 2019 16:10:09 -0800 Subject: [PATCH 6/9] - WIP --- Source/Mosa.Compiler.Framework/MethodScanner.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs index f7a728518d..9bd7fc2ebb 100644 --- a/Source/Mosa.Compiler.Framework/MethodScanner.cs +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -85,6 +85,10 @@ public void MethodInvoked(MosaMethod method) { ScheduleMethod(method); } + else if (allocatedTypes.Contains(method.DeclaringType)) + { + ScheduleMethod(method); + } } } From ee4e2b830b6569f851a6a65cb15c619bd0fe4929 Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Tue, 22 Jan 2019 00:41:06 -0800 Subject: [PATCH 7/9] - WIP --- .../Mosa.Compiler.Framework/MethodScanner.cs | 69 +++++++++++++++--- .../Mosa.Compiler.Framework/MosaTypeLayout.cs | 73 +++++++++++++++---- .../Stages/CILTransformationStage.cs | 2 +- .../Stages/CallStage.cs | 4 +- 4 files changed, 121 insertions(+), 27 deletions(-) diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs index 9bd7fc2ebb..d631ec7e2e 100644 --- a/Source/Mosa.Compiler.Framework/MethodScanner.cs +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -43,13 +43,15 @@ public void TypeAllocated(MosaType type) // find all invoked methods for this type lock (_lock) { - foreach (var method in type.Methods) - { - if (!method.IsStatic && invokedMethods.Contains(method)) - { - ScheduleMethod(method); - } - } + ScheduleMethods(type); + + //foreach (var method in type.Methods) + //{ + // if (!method.IsStatic && invokedMethods.Contains(method)) + // { + // ScheduleMethod(method); + // } + //} foreach (var property in type.Properties) { @@ -85,10 +87,59 @@ public void MethodInvoked(MosaMethod method) { ScheduleMethod(method); } - else if (allocatedTypes.Contains(method.DeclaringType)) + else { - ScheduleMethod(method); + var slot = Compiler.TypeLayout.GetMethodSlot(method); + var type = method.DeclaringType; + + ScheduleDerivedMethods(type, slot); + } + } + } + + private void ScheduleDerivedMethods(MosaType type, int slot) + { + var children = Compiler.TypeLayout.GetDerivedTypes(type); + + if (children == null) + return; + + foreach (var derived in children) + { + if (!allocatedTypes.Contains(derived)) + continue; + + var derivedMethod = Compiler.TypeLayout.GetMethodBySlot(derived, slot); + + ScheduleMethod(derivedMethod); + + ScheduleDerivedMethods(derived, slot); + } + } + + private void ScheduleMethods(MosaType type) + { + var currentType = type; + + var slots = new bool[Compiler.TypeLayout.GetMethodTable(type).Count]; + + while (currentType != null) + { + foreach (var method in currentType.Methods) + { + if (!method.IsStatic && invokedMethods.Contains(method)) + { + int slot = Compiler.TypeLayout.GetMethodSlot(method); + + if (slots[slot]) + continue; + + slots[slot] = true; + ScheduleMethod(method); + } } + + currentType = currentType.BaseType; } } diff --git a/Source/Mosa.Compiler.Framework/MosaTypeLayout.cs b/Source/Mosa.Compiler.Framework/MosaTypeLayout.cs index f70f3d975d..f854aad1fb 100644 --- a/Source/Mosa.Compiler.Framework/MosaTypeLayout.cs +++ b/Source/Mosa.Compiler.Framework/MosaTypeLayout.cs @@ -26,9 +26,9 @@ public class MosaTypeLayout private readonly List interfaces = new List(); /// - /// Holds the method table offsets value for each method + /// Holds the method table slot index /// - private readonly Dictionary methodTableOffsets = new Dictionary(new MosaMethodFullNameComparer()); + private readonly Dictionary methodSlots = new Dictionary(new MosaMethodFullNameComparer()); /// /// Holds the slot value for each interface @@ -75,6 +75,11 @@ public class MosaTypeLayout /// private readonly HashSet overriddenMethods = new HashSet(new MosaMethodFullNameComparer()); + /// + /// The derived children of the base type + /// + private readonly Dictionary> derivedTypes = new Dictionary>(); + private readonly object _lock = new object(); #endregion Data Members @@ -136,25 +141,37 @@ public MosaTypeLayout(TypeSystem typeSystem, int nativePointerSize, int nativePo } /// - /// Gets the method table offset. + /// Gets the method slot number /// /// The method. /// - public int GetMethodTableOffset(MosaMethod method) + public int GetMethodSlot(MosaMethod method) { lock (_lock) { ResolveType(method.DeclaringType); - return methodTableOffsets[method]; + return methodSlots[method]; + } + } + + public MosaMethod GetMethodBySlot(MosaType type, int slot) + { + lock (_lock) + { + ResolveType(type); + + var methodTable = GetMethodTable(type); + + return methodTable[slot]; } } /// - /// Gets the interface slot offset. + /// Gets the interface slot number /// /// The type. /// - public int GetInterfaceSlotOffset(MosaType type) + public int GetInterfaceSlot(MosaType type) { lock (_lock) { @@ -301,7 +318,7 @@ public bool IsMethodOverridden(MosaMethod method) if (overriddenMethods.Contains(method)) return true; - int slot = methodTableOffsets[method]; + int slot = methodSlots[method]; var type = method.DeclaringType.BaseType; while (type != null) @@ -327,6 +344,19 @@ public bool IsMethodOverridden(MosaMethod method) } } + public MosaType[] GetDerivedTypes(MosaType baseType) + { + lock (_lock) + { + if (derivedTypes.TryGetValue(baseType, out List derivedList)) + { + return derivedList.ToArray(); + } + } + + return null; + } + #region Internal - Layout /// @@ -367,6 +397,8 @@ private void ResolveType(MosaType type) if (type.BaseType != null) { ResolveType(type.BaseType); + + Addchildren(type.BaseType, type); } if (type.IsInterface) @@ -646,7 +678,7 @@ private List CreateMethodTable(MosaType type) { int slot = methodTable.Count; methodTable.Add(method); - methodTableOffsets.Add(method, slot); + methodSlots.Add(method, slot); } else { @@ -654,14 +686,14 @@ private List CreateMethodTable(MosaType type) if (slot != -1) { methodTable[slot] = method; - methodTableOffsets.Add(method, slot); + methodSlots.Add(method, slot); SetMethodOverridden(method, slot); } else { slot = methodTable.Count; methodTable.Add(method); - methodTableOffsets.Add(method, slot); + methodSlots.Add(method, slot); } } } @@ -671,13 +703,13 @@ private List CreateMethodTable(MosaType type) { int slot = methodTable.Count; methodTable.Add(method); - methodTableOffsets.Add(method, slot); + methodSlots.Add(method, slot); } else if (!method.IsInternal && !method.IsExternal) { int slot = methodTable.Count; methodTable.Add(method); - methodTableOffsets.Add(method, slot); + methodSlots.Add(method, slot); } } } @@ -714,9 +746,9 @@ private int FindOverrideSlot(IList methodTable, MosaMethod method) if (baseMethod.Name.Equals(method.Name) && baseMethod.Equals(method)) { if (baseMethod.GenericArguments.Count == 0) - return methodTableOffsets[baseMethod]; + return methodSlots[baseMethod]; else - slot = methodTableOffsets[baseMethod]; + slot = methodSlots[baseMethod]; } } @@ -756,6 +788,17 @@ private void SetMethodOverridden(MosaMethod method, int slot) } } + private void Addchildren(MosaType baseType, MosaType child) + { + if (!derivedTypes.TryGetValue(baseType, out List children)) + { + children = new List(); + derivedTypes.Add(baseType, children); + } + + children.Add(child); + } + #endregion Internal public static bool IsStoredOnStack(MosaType type) diff --git a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs index 7da6bdc3ae..5649104638 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs @@ -415,7 +415,7 @@ private void Break(InstructionNode node) private int CalculateInterfaceSlot(MosaType interaceType) { - return TypeLayout.GetInterfaceSlotOffset(interaceType); + return TypeLayout.GetInterfaceSlot(interaceType); } /// diff --git a/Source/Mosa.Compiler.Framework/Stages/CallStage.cs b/Source/Mosa.Compiler.Framework/Stages/CallStage.cs index faaa74d9a3..db297168e4 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CallStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CallStage.cs @@ -77,7 +77,7 @@ private void SetReturnCompound(Context context) private int CalculateMethodTableOffset(MosaMethod invokeTarget) { - int slot = TypeLayout.GetMethodTableOffset(invokeTarget); + int slot = TypeLayout.GetMethodSlot(invokeTarget); return NativePointerSize * slot; } @@ -159,7 +159,7 @@ private void CallVirtual(InstructionNode node) private int CalculateInterfaceSlot(MosaType interaceType) { - return TypeLayout.GetInterfaceSlotOffset(interaceType); + return TypeLayout.GetInterfaceSlot(interaceType); } private int CalculateInterfaceSlotOffset(MosaMethod invokeTarget) From c2dd59f327faa643a4e42044b847eb2d61e78e7d Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Tue, 22 Jan 2019 23:34:36 -0800 Subject: [PATCH 8/9] - WIP --- .../BaseMethodCompilerStage.cs | 2 +- .../CompilationScheduler.cs | 4 +- .../Mosa.Compiler.Framework/CompilerData.cs | 18 ++++----- .../DebugFileGenerationStage.cs | 2 +- .../Mosa.Compiler.Framework/MethodCompiler.cs | 4 +- .../{CompilerMethodData.cs => MethodData.cs} | 4 +- .../Mosa.Compiler.Framework/MethodScanner.cs | 37 +++++++++---------- .../Mosa.Compiler.Framework.csproj | 4 +- .../Stages/CILTransformationStage.cs | 2 +- .../Stages/InlineEvaluationStage.cs | 2 +- .../Stages/InlineStage.cs | 4 +- .../Stages/UnboxValueTypeStage.cs | 2 +- .../{CompilerTypeData.cs => TypeData.cs} | 4 +- .../Units/MosaMethod.cs | 4 ++ 14 files changed, 47 insertions(+), 46 deletions(-) rename Source/Mosa.Compiler.Framework/{CompilerMethodData.cs => MethodData.cs} (95%) rename Source/Mosa.Compiler.Framework/{CompilerTypeData.cs => TypeData.cs} (85%) diff --git a/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs b/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs index dc243efa2c..f52480f9a9 100644 --- a/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs +++ b/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs @@ -114,7 +114,7 @@ public abstract class BaseMethodCompilerStage : ITraceFactory /// /// Gets the method data. /// - protected CompilerMethodData MethodData { get { return MethodCompiler.MethodData; } } + protected MethodData MethodData { get { return MethodCompiler.MethodData; } } /// /// Gets the linker. diff --git a/Source/Mosa.Compiler.Framework/CompilationScheduler.cs b/Source/Mosa.Compiler.Framework/CompilationScheduler.cs index 4fb4b05a94..d4cba0e5e9 100644 --- a/Source/Mosa.Compiler.Framework/CompilationScheduler.cs +++ b/Source/Mosa.Compiler.Framework/CompilationScheduler.cs @@ -17,7 +17,7 @@ public sealed class CompilationScheduler private readonly UniqueQueueThreadSafe queue = new UniqueQueueThreadSafe(); private readonly HashSet methods = new HashSet(); - private readonly UniqueQueueThreadSafe inlineQueue = new UniqueQueueThreadSafe(); + private readonly UniqueQueueThreadSafe inlineQueue = new UniqueQueueThreadSafe(); #endregion Data Members @@ -108,7 +108,7 @@ public MosaMethod GetMethodToCompile() return queue.Dequeue(); } - public void AddToInlineQueue(CompilerMethodData methodData) + public void AddToInlineQueue(MethodData methodData) { Debug.Assert(!methodData.Method.HasOpenGenericParams); diff --git a/Source/Mosa.Compiler.Framework/CompilerData.cs b/Source/Mosa.Compiler.Framework/CompilerData.cs index ab04fe71b0..2586e961cd 100644 --- a/Source/Mosa.Compiler.Framework/CompilerData.cs +++ b/Source/Mosa.Compiler.Framework/CompilerData.cs @@ -12,13 +12,13 @@ public sealed class CompilerData { #region Data Members - private readonly Dictionary types = new Dictionary(); + private readonly Dictionary types = new Dictionary(); - private readonly Dictionary methods = new Dictionary(); + private readonly Dictionary methods = new Dictionary(); #endregion Data Members - public IEnumerable MethodData + public IEnumerable MethodData { get { @@ -31,13 +31,13 @@ public IEnumerable MethodData #region Methods - public CompilerTypeData GetCompilerTypeData(MosaType type) + public TypeData GetTypeData(MosaType type) { lock (types) { - if (!types.TryGetValue(type, out CompilerTypeData compilerType)) + if (!types.TryGetValue(type, out TypeData compilerType)) { - compilerType = new CompilerTypeData(type); + compilerType = new TypeData(type); types.Add(type, compilerType); } @@ -45,13 +45,13 @@ public CompilerTypeData GetCompilerTypeData(MosaType type) } } - public CompilerMethodData GetCompilerMethodData(MosaMethod method) + public MethodData GetMethodData(MosaMethod method) { lock (methods) { - if (!methods.TryGetValue(method, out CompilerMethodData compilerMethod)) + if (!methods.TryGetValue(method, out MethodData compilerMethod)) { - compilerMethod = new CompilerMethodData(method); + compilerMethod = new MethodData(method); methods.Add(method, compilerMethod); } diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileGenerationStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileGenerationStage.cs index dd3f600ae0..cca8f610c9 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileGenerationStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileGenerationStage.cs @@ -132,7 +132,7 @@ private void EmitMethods() foreach (var method in type.Methods) { var symbol = Linker.GetSymbol(method.FullName); - var methodData = Compiler.CompilerData.GetCompilerMethodData(method); + var methodData = Compiler.CompilerData.GetMethodData(method); writer.WriteLine( "{0}\t{1:x8}\t{2}\t{3:x8}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}", diff --git a/Source/Mosa.Compiler.Framework/MethodCompiler.cs b/Source/Mosa.Compiler.Framework/MethodCompiler.cs index 04a0858242..321758595c 100644 --- a/Source/Mosa.Compiler.Framework/MethodCompiler.cs +++ b/Source/Mosa.Compiler.Framework/MethodCompiler.cs @@ -151,7 +151,7 @@ public sealed class MethodCompiler /// /// Gets the compiler method data. /// - public CompilerMethodData MethodData { get; } + public MethodData MethodData { get; } /// /// The stack frame @@ -237,7 +237,7 @@ public MethodCompiler(Compiler compiler, MosaMethod method, BasicBlocks basicBlo IsCILDecodeRequired = true; IsStackFrameRequired = true; - MethodData = compiler.CompilerData.GetCompilerMethodData(Method); + MethodData = compiler.CompilerData.GetMethodData(Method); MethodData.Counters.Reset(); EvaluateParameterOperands(); diff --git a/Source/Mosa.Compiler.Framework/CompilerMethodData.cs b/Source/Mosa.Compiler.Framework/MethodData.cs similarity index 95% rename from Source/Mosa.Compiler.Framework/CompilerMethodData.cs rename to Source/Mosa.Compiler.Framework/MethodData.cs index a9d4909147..64a50089bc 100644 --- a/Source/Mosa.Compiler.Framework/CompilerMethodData.cs +++ b/Source/Mosa.Compiler.Framework/MethodData.cs @@ -10,7 +10,7 @@ namespace Mosa.Compiler.Framework /// /// Compiler Metho dData /// - public sealed class CompilerMethodData + public sealed class MethodData { private readonly object _lock = new object(); @@ -68,7 +68,7 @@ public sealed class CompilerMethodData #endregion Properties - public CompilerMethodData(MosaMethod mosaMethod) + public MethodData(MosaMethod mosaMethod) { Method = mosaMethod ?? throw new ArgumentNullException(nameof(mosaMethod)); diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs index d631ec7e2e..b52e2c50a9 100644 --- a/Source/Mosa.Compiler.Framework/MethodScanner.cs +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -40,31 +40,25 @@ public void TypeAllocated(MosaType type) Debug.WriteLine("***New Type Allocated: " + type.FullName); + Compiler.CompilerData.GetTypeData(type).IsTypeAllocated = true; + // find all invoked methods for this type lock (_lock) { ScheduleMethods(type); - //foreach (var method in type.Methods) + //foreach (var property in type.Properties) //{ - // if (!method.IsStatic && invokedMethods.Contains(method)) + // if (property.GetterMethod != null && !property.GetterMethod.IsStatic && invokedMethods.Contains(property.GetterMethod)) // { - // ScheduleMethod(method); + // ScheduleMethod(property.GetterMethod); // } - //} - foreach (var property in type.Properties) - { - if (property.GetterMethod != null && !property.GetterMethod.IsStatic && invokedMethods.Contains(property.GetterMethod)) - { - ScheduleMethod(property.GetterMethod); - } - - if (property.SetterMethod != null && !property.SetterMethod.IsStatic && invokedMethods.Contains(property.SetterMethod)) - { - ScheduleMethod(property.SetterMethod); - } - } + // if (property.SetterMethod != null && !property.SetterMethod.IsStatic && invokedMethods.Contains(property.SetterMethod)) + // { + // ScheduleMethod(property.SetterMethod); + // } + //} } } } @@ -81,9 +75,10 @@ public void MethodInvoked(MosaMethod method) invokedMethods.Add(method); - Debug.WriteLine("Method Invoked: " + method.FullName + (method.IsStatic ? " [Static]" : " [Virtual]")); + if (!method.IsStatic || method.IsConstructor) + Debug.WriteLine("Method Invoked: " + method.FullName + (method.IsStatic ? " [Static]" : " [Virtual]")); - if (method.IsStatic) + if (method.IsStatic || method.IsConstructor) { ScheduleMethod(method); } @@ -127,7 +122,7 @@ private void ScheduleMethods(MosaType type) { foreach (var method in currentType.Methods) { - if (!method.IsStatic && invokedMethods.Contains(method)) + if (invokedMethods.Contains(method)) // !(method.IsStatic || method.IsConstructor) && { int slot = Compiler.TypeLayout.GetMethodSlot(method); @@ -152,7 +147,9 @@ private void ScheduleMethod(MosaMethod method) scheduledMethods.Add(method); - Debug.WriteLine(" Scheduling: " + method.ToString() + (method.IsStatic ? " [Static]" : " [Virtual]")); + if (!method.IsStatic || method.IsConstructor) + Debug.WriteLine(" Scheduling: " + method.ToString() + (method.IsStatic ? " [Static]" : " [Virtual]")); + Compiler.CompilationScheduler.Schedule(method); } } diff --git a/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj b/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj index 840276018b..fd87bace55 100644 --- a/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj +++ b/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj @@ -333,8 +333,8 @@ - - + + diff --git a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs index 5649104638..1735dba02e 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs @@ -2129,7 +2129,7 @@ private bool ReplaceWithInternalCall(InstructionNode node) { var method = node.InvokeMethod; - if (!method.IsInternal || method.Name != ".ctor") + if (!method.IsInternal || !method.IsConstructor) return false; var newmethod = method.DeclaringType.FindMethodByNameAndParameters("Ctor", method.Signature.Parameters); diff --git a/Source/Mosa.Compiler.Framework/Stages/InlineEvaluationStage.cs b/Source/Mosa.Compiler.Framework/Stages/InlineEvaluationStage.cs index 5549a1d8bf..e5bd5b3238 100644 --- a/Source/Mosa.Compiler.Framework/Stages/InlineEvaluationStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/InlineEvaluationStage.cs @@ -156,7 +156,7 @@ protected override void Run() GeneratedBlocksCount.Set(MethodData.CanInline); } - public bool CanInline(CompilerMethodData method) + public bool CanInline(MethodData method) { if (method.HasDoNotInlineAttribute) return false; diff --git a/Source/Mosa.Compiler.Framework/Stages/InlineStage.cs b/Source/Mosa.Compiler.Framework/Stages/InlineStage.cs index cacd747114..aa7c8c683f 100644 --- a/Source/Mosa.Compiler.Framework/Stages/InlineStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/InlineStage.cs @@ -57,7 +57,7 @@ protected override void Run() callSites.Add(node); - var invoked = MethodCompiler.Compiler.CompilerData.GetCompilerMethodData(invokedMethod); + var invoked = MethodCompiler.Compiler.CompilerData.GetMethodData(invokedMethod); MethodData.Calls.AddIfNew(invokedMethod); @@ -74,7 +74,7 @@ protected override void Run() { var invokedMethod = callSiteNode.Operand1.Method; - var callee = MethodCompiler.Compiler.CompilerData.GetCompilerMethodData(invokedMethod); + var callee = MethodCompiler.Compiler.CompilerData.GetMethodData(invokedMethod); if (!callee.CanInline) continue; diff --git a/Source/Mosa.Compiler.Framework/Stages/UnboxValueTypeStage.cs b/Source/Mosa.Compiler.Framework/Stages/UnboxValueTypeStage.cs index 3fe40af88e..90ce0562d1 100644 --- a/Source/Mosa.Compiler.Framework/Stages/UnboxValueTypeStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/UnboxValueTypeStage.cs @@ -18,7 +18,7 @@ protected override void Run() return; // If the method is static, non-virtual or is a constructor then don't process - if (Method.IsStatic || !Method.IsVirtual || Method.Name.Equals(".ctor")) + if (Method.IsStatic || !Method.IsVirtual || Method.IsConstructor) return; // If the method does not belong to an interface then don't process diff --git a/Source/Mosa.Compiler.Framework/CompilerTypeData.cs b/Source/Mosa.Compiler.Framework/TypeData.cs similarity index 85% rename from Source/Mosa.Compiler.Framework/CompilerTypeData.cs rename to Source/Mosa.Compiler.Framework/TypeData.cs index 894e75ee3c..66defccf03 100644 --- a/Source/Mosa.Compiler.Framework/CompilerTypeData.cs +++ b/Source/Mosa.Compiler.Framework/TypeData.cs @@ -8,7 +8,7 @@ namespace Mosa.Compiler.Framework /// /// Compiler Type Data /// - public sealed class CompilerTypeData + public sealed class TypeData { #region Properties @@ -20,7 +20,7 @@ public sealed class CompilerTypeData #region Methods - public CompilerTypeData(MosaType mosaType) + public TypeData(MosaType mosaType) { if (mosaType == null) throw new ArgumentNullException(nameof(mosaType)); diff --git a/Source/Mosa.Compiler.MosaTypeSystem/Units/MosaMethod.cs b/Source/Mosa.Compiler.MosaTypeSystem/Units/MosaMethod.cs index 666c77538b..9f0a473fd4 100644 --- a/Source/Mosa.Compiler.MosaTypeSystem/Units/MosaMethod.cs +++ b/Source/Mosa.Compiler.MosaTypeSystem/Units/MosaMethod.cs @@ -70,6 +70,10 @@ public sealed class MosaMethod : MosaUnit, IEquatable public string ExternMethodModule { get; private set; } + public bool IsConstructor { get { return Name == ".ctor"; } } + + public bool IsTypeConstructor { get { return Name == ".cctor"; } } + internal MosaMethod() { GenericArguments = (genericArguments = new List()).AsReadOnly(); From b0dd00eb5336889090684fa6717c3e02426cc197 Mon Sep 17 00:00:00 2001 From: Phil Garcia Date: Wed, 23 Jan 2019 23:37:24 -0800 Subject: [PATCH 9/9] - WIP --- Source/Mosa.Compiler.Framework/Compiler.cs | 1 + .../CompilerStages/MetadataStage.cs | 27 +++--------- .../CompilerStages/MethodLookupTableStage.cs | 3 ++ .../CompilerStages/StaticFieldStage.cs | 44 +++++++++++++++++++ .../TypeInitializerSchedulerStage.cs | 2 +- .../Linker/Elf/ElfLinker.cs | 9 ++++ .../Mosa.Compiler.Framework/MethodScanner.cs | 38 +++++++++++++--- .../Mosa.Compiler.Framework.csproj | 1 + .../Stages/CILTransformationStage.cs | 2 +- .../Stages/CallStage.cs | 10 ++--- .../Stages/DevirtualizeCallStage.cs | 2 +- .../Stages/ExceptionStage.cs | 4 +- .../Stages/LowerIRStage.cs | 6 +-- .../CompilerStages/StartUpStage.cs | 4 +- .../CompilerStages/MultibootV1Stage.cs | 2 +- .../CompilerStages/MultibootV1Stage.cs | 2 +- .../Intrinsic/GetIDTJumpLocation.cs | 2 +- Source/Mosa.Platform.x86/Intrinsic/IRQs.cs | 2 +- .../Stages/IRSubstitutionStage.cs | 4 +- 19 files changed, 115 insertions(+), 50 deletions(-) create mode 100644 Source/Mosa.Compiler.Framework/CompilerStages/StaticFieldStage.cs diff --git a/Source/Mosa.Compiler.Framework/Compiler.cs b/Source/Mosa.Compiler.Framework/Compiler.cs index e40127e0cc..6ba5f771d2 100644 --- a/Source/Mosa.Compiler.Framework/Compiler.cs +++ b/Source/Mosa.Compiler.Framework/Compiler.cs @@ -131,6 +131,7 @@ private static List GetDefaultCompilerPipeline(CompilerOption { return new List { new TypeInitializerSchedulerStage(), + new StaticFieldStage(), new MethodLookupTableStage(), new MethodExceptionLookupTableStage(), new MetadataStage(), diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/MetadataStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/MetadataStage.cs index d94477257b..aff3306e24 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/MetadataStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/MetadataStage.cs @@ -29,6 +29,9 @@ protected override void Setup() protected override void RunPostCompile() { + //if (CompilerOptions.EnableMethodScanner) // FIXME: Temp - REMOVE ME!!! + // return; // FIXME: Temp - REMOVE ME!!! + CreateDefinitionTables(); } @@ -186,7 +189,7 @@ private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTa // 9. Constructor that accepts no parameters, if any, for this type foreach (var method in type.Methods) { - if (!method.Name.Equals(".ctor") || method.Signature.Parameters.Count != 0 || method.HasOpenGenericParams) + if (!method.IsConstructor || method.Signature.Parameters.Count != 0 || method.HasOpenGenericParams) continue; Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, Metadata.MethodDefinition + method.FullName, 0); @@ -449,26 +452,6 @@ private LinkerSymbol CreateFieldDefinitions(MosaType type) writer2.Write(TypeLayout.GetFieldOffset(field), TypeLayout.NativePointerSize); } - // Create another symbol with field data if any - if (field.IsStatic) - { - // Assign a memory slot to the static & initialize it, if there's initial data set - // Determine the size of the type & alignment requirements - //Architecture.GetTypeRequirements(TypeLayout, field.FieldType, out int size, out int alignment); - - int size = TypeLayout.GetFieldSize(field); - - // The linker section to move this field into - var section = field.Data != null ? SectionKind.ROData : SectionKind.BSS; - - var symbol = Compiler.Linker.DefineSymbol(field.FullName, section, Architecture.NativeAlignment, size); - - if (field.Data != null) - { - symbol.Stream.Write(field.Data, 0, size); - } - } - // Add pointer to field list Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldsTableSymbol, (int)writer1.Position, fieldDefSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); @@ -583,7 +566,7 @@ private LinkerSymbol CreateMethodDefinition(MosaMethod method) writer1.Write((uint)method.MethodAttributes, TypeLayout.NativePointerSize); // 4. Local Stack Size (16 Bits) && Parameter Stack Size (16 Bits) - var methodData = Compiler.CompilerData.GetCompilerMethodData(method); + var methodData = Compiler.CompilerData.GetMethodData(method); int value = methodData.LocalMethodStackSize | (methodData.ParameterStackSize << 16); writer1.Write(value, TypeLayout.NativePointerSize); diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/MethodLookupTableStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/MethodLookupTableStage.cs index d9cf23c6b0..3d99423695 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/MethodLookupTableStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/MethodLookupTableStage.cs @@ -28,6 +28,9 @@ protected override void Setup() protected override void RunPostCompile() { + //if (CompilerOptions.EnableMethodScanner) // FIXME: Temp - REMOVE ME!!! + // return; // FIXME: Temp - REMOVE ME!!! + // Emit assembly list var methodLookupTable = Linker.DefineSymbol(Metadata.MethodLookupTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new EndianAwareBinaryWriter(methodLookupTable.Stream, Architecture.Endianness); diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/StaticFieldStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/StaticFieldStage.cs new file mode 100644 index 0000000000..30dbb45474 --- /dev/null +++ b/Source/Mosa.Compiler.Framework/CompilerStages/StaticFieldStage.cs @@ -0,0 +1,44 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Common; +using Mosa.Compiler.Framework.Linker; +using Mosa.Compiler.MosaTypeSystem; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace Mosa.Compiler.Framework.CompilerStages +{ + /// + /// Emits metadata for assemblies and types + /// + /// + public sealed class StaticFieldStage : BaseCompilerStage + { + protected override void RunPostCompile() + { + foreach (var type in TypeSystem.AllTypes) + { + foreach (var field in type.Fields) + { + if (field.IsStatic) + { + // TODO: Don't emit if method scanner is enabled and field never references + // if (!CompilerOptions.EnableMethodScanner) + + var section = field.Data != null ? SectionKind.ROData : SectionKind.BSS; + int size = TypeLayout.GetFieldSize(field); + + var symbol = Compiler.Linker.DefineSymbol(field.FullName, section, Architecture.NativeAlignment, size); + + if (field.Data != null) + { + symbol.Stream.Write(field.Data, 0, size); + } + } + } + } + } + } +} diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs index 388b667d7e..95a841df47 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerSchedulerStage.cs @@ -79,7 +79,7 @@ protected override void RunPreCompile() Compiler.PlugSystem.CreatePlug(initializeAssemblyMethod, typeInitializerMethod); - Compiler.MethodScanner.MethodInvoked(typeInitializerMethod); + Compiler.MethodScanner.MethodInvoked(typeInitializerMethod, typeInitializerMethod); } protected override void RunPostCompile() diff --git a/Source/Mosa.Compiler.Framework/Linker/Elf/ElfLinker.cs b/Source/Mosa.Compiler.Framework/Linker/Elf/ElfLinker.cs index 00e0369127..df3773a16e 100644 --- a/Source/Mosa.Compiler.Framework/Linker/Elf/ElfLinker.cs +++ b/Source/Mosa.Compiler.Framework/Linker/Elf/ElfLinker.cs @@ -438,6 +438,15 @@ private void WriteSymbolSection(Section section, EndianAwareBinaryWriter writer) foreach (var symbol in linker.Symbols) { + // FIXME: Temp!!! + { + if (symbol.SectionKind == SectionKind.Unknown) + { + Debug.WriteLine("Unresolved Symbol: " + symbol.Name); + continue; + } + } + Debug.Assert(symbol.SectionKind != SectionKind.Unknown, "symbol.SectionKind != SectionKind.Unknown"); if (!(symbol.IsExport || linker.EmitAllSymbols)) diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs index b52e2c50a9..26f0eac40b 100644 --- a/Source/Mosa.Compiler.Framework/MethodScanner.cs +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -16,6 +16,8 @@ public class MethodScanner private HashSet scheduledMethods = new HashSet(); + private MosaMethod lastSource; + private object _lock = new object(); public MethodScanner(Compiler compiler) @@ -26,7 +28,7 @@ public MethodScanner(Compiler compiler) Initialize(); } - public void TypeAllocated(MosaType type) + public void TypeAllocated(MosaType type, MosaMethod source) { if (!IsEnabled) return; @@ -38,7 +40,13 @@ public void TypeAllocated(MosaType type) allocatedTypes.Add(type); - Debug.WriteLine("***New Type Allocated: " + type.FullName); + if (lastSource == null || lastSource != source) + { + Debug.WriteLine("> Method: " + source.FullName); + lastSource = source; + } + + Debug.WriteLine(" >>> Allocated: " + type.FullName); Compiler.CompilerData.GetTypeData(type).IsTypeAllocated = true; @@ -63,7 +71,7 @@ public void TypeAllocated(MosaType type) } } - public void MethodInvoked(MosaMethod method) + public void MethodInvoked(MosaMethod method, MosaMethod source) { if (!IsEnabled) return; @@ -75,8 +83,16 @@ public void MethodInvoked(MosaMethod method) invokedMethods.Add(method); + if (lastSource == null || lastSource != source) + { + Debug.WriteLine("> Method: " + source.FullName); + lastSource = source; + } + if (!method.IsStatic || method.IsConstructor) - Debug.WriteLine("Method Invoked: " + method.FullName + (method.IsStatic ? " [Static]" : " [Virtual]")); + { + Debug.WriteLine(" >> Invoked: " + method.FullName + (method.IsStatic ? " [Static]" : " [Virtual]")); + } if (method.IsStatic || method.IsConstructor) { @@ -84,10 +100,14 @@ public void MethodInvoked(MosaMethod method) } else { + if (allocatedTypes.Contains(method.DeclaringType)) + { + ScheduleMethod(method); + } + var slot = Compiler.TypeLayout.GetMethodSlot(method); - var type = method.DeclaringType; - ScheduleDerivedMethods(type, slot); + ScheduleDerivedMethods(method.DeclaringType, slot); } } } @@ -148,7 +168,7 @@ private void ScheduleMethod(MosaMethod method) scheduledMethods.Add(method); if (!method.IsStatic || method.IsConstructor) - Debug.WriteLine(" Scheduling: " + method.ToString() + (method.IsStatic ? " [Static]" : " [Virtual]")); + Debug.WriteLine(" ==> Scheduling: " + method.ToString() + (method.IsStatic ? " [Static]" : " [Virtual]")); Compiler.CompilationScheduler.Schedule(method); } @@ -164,6 +184,10 @@ public void Initialize() ScheduleMethod(entryPoint); } + var stringType = Compiler.TypeSystem.GetTypeByName("System", "String"); + + allocatedTypes.Add(stringType); + //foreach (var type in Compiler.TypeSystem.AllTypes) //{ // foreach (var method in type.Methods) diff --git a/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj b/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj index fd87bace55..a5a1ae1b10 100644 --- a/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj +++ b/Source/Mosa.Compiler.Framework/Mosa.Compiler.Framework.csproj @@ -91,6 +91,7 @@ + diff --git a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs index 1735dba02e..e9e0b64fb9 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILTransformationStage.cs @@ -973,7 +973,7 @@ private void Ldftn(InstructionNode node) node.SetInstruction(Select(IRInstruction.MoveInt32, IRInstruction.MoveInt64), node.Result, Operand.CreateSymbolFromMethod(invokedMethod, TypeSystem)); - MethodCompiler.Compiler.MethodScanner.MethodInvoked(invokedMethod); + MethodCompiler.Compiler.MethodScanner.MethodInvoked(invokedMethod, this.Method); } /// diff --git a/Source/Mosa.Compiler.Framework/Stages/CallStage.cs b/Source/Mosa.Compiler.Framework/Stages/CallStage.cs index db297168e4..539ea6290a 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CallStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CallStage.cs @@ -101,7 +101,7 @@ private void CallStatic(InstructionNode node) Debug.Assert(method == call.Method); - MethodCompiler.Compiler.MethodScanner.MethodInvoked(call.Method); + MethodCompiler.Compiler.MethodScanner.MethodInvoked(call.Method, this.Method); } private void CallDynamic(InstructionNode node) @@ -120,7 +120,7 @@ private void CallDynamic(InstructionNode node) if (call.Method != null) { - MethodCompiler.Compiler.MethodScanner.MethodInvoked(call.Method); + MethodCompiler.Compiler.MethodScanner.MethodInvoked(call.Method, this.Method); } } @@ -154,7 +154,7 @@ private void CallVirtual(InstructionNode node) MakeCall(context, callTarget, result, operands); - MethodCompiler.Compiler.MethodScanner.MethodInvoked(method); + MethodCompiler.Compiler.MethodScanner.MethodInvoked(method, this.Method); } private int CalculateInterfaceSlot(MosaType interaceType) @@ -220,7 +220,7 @@ private void CallInterface(InstructionNode node) MakeCall(context, callTarget, result, operands); - MethodCompiler.Compiler.MethodScanner.MethodInvoked(method); + MethodCompiler.Compiler.MethodScanner.MethodInvoked(method, this.Method); } private void MakeCall(Context context, Operand target, Operand result, List operands) @@ -238,7 +238,7 @@ private void MakeCall(Context context, Operand target, Operand result, List