static void CallTestAndVerifyAllocation(Test test, int expectedResult, AllocationKind expectedAllocationsKind) { long allocatedBytesBefore = GC.GetAllocatedBytesForCurrentThread(); int testResult = test(); long allocatedBytesAfter = GC.GetAllocatedBytesForCurrentThread(); string methodName = test.Method.Name; if (testResult != expectedResult) { Console.WriteLine($"FAILURE ({methodName}): expected {expectedResult}, got {testResult}"); methodResult = -1; } else if ((expectedAllocationsKind == AllocationKind.Stack) && (allocatedBytesBefore != allocatedBytesAfter)) { Console.WriteLine($"FAILURE ({methodName}): unexpected allocation of {allocatedBytesAfter - allocatedBytesBefore} bytes"); methodResult = -1; } else if ((expectedAllocationsKind == AllocationKind.Heap) && (allocatedBytesBefore == allocatedBytesAfter)) { Console.WriteLine($"FAILURE ({methodName}): unexpected stack allocation"); methodResult = -1; } else { Console.WriteLine($"SUCCESS ({methodName})"); } }
public static int Main() { AllocationKind expectedAllocationKind = AllocationKind.Stack; if (GCStressEnabled()) { expectedAllocationKind = AllocationKind.Undefined; } else if (!SPCOptimizationsEnabled()) { expectedAllocationKind = AllocationKind.Heap; } CallTestAndVerifyAllocation(AllocateSimpleClassAndAddFields, 12, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassesAndEQCompareThem, 0, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassesAndNECompareThem, 1, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassAndGetField, 7, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateClassWithNestedStructAndGetField, 5, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateClassWithNestedStructAndAddFields, 24, expectedAllocationKind); // The remaining tests currently never allocate on the stack if (expectedAllocationKind == AllocationKind.Stack) { expectedAllocationKind = AllocationKind.Heap; } // This test calls CORINFO_HELP_ISINSTANCEOFCLASS CallTestAndVerifyAllocation(AllocateSimpleClassAndCheckType, 1, expectedAllocationKind); // This test calls CORINFO_HELP_CHKCASTCLASS_SPECIAL CallTestAndVerifyAllocation(AllocateSimpleClassAndCast, 7, expectedAllocationKind); // Stack allocation of classes with GC fields is currently disabled CallTestAndVerifyAllocation(AllocateSimpleClassWithGCFieldAndAddFields, 12, expectedAllocationKind); // Assigning class ref to a field of another object currently always disables stack allocation CallTestAndVerifyAllocation(AllocateSimpleClassAndAssignRefToAField, 12, expectedAllocationKind); // Stack allocation of boxed structs is currently disabled CallTestAndVerifyAllocation(BoxSimpleStructAndAddFields, 12, expectedAllocationKind); return(methodResult); }
public static int Main() { AllocationKind expectedAllocationKind = AllocationKind.Stack; if (GCStressEnabled()) { Console.WriteLine("GCStress is enabled"); expectedAllocationKind = AllocationKind.Undefined; } else if (!SPCOptimizationsEnabled()) { Console.WriteLine("System.Private.CoreLib.dll optimizations are disabled"); expectedAllocationKind = AllocationKind.Heap; } classA = new SimpleClassA(f1, f2); classWithGCField = new SimpleClassWithGCField(f1, f2, null); str0 = "str_zero"; str1 = "str_one"; str2 = "str_two"; str3 = "str_three"; str4 = "str_four"; CallTestAndVerifyAllocation(AllocateSimpleClassAndAddFields, 12, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassesAndEQCompareThem, 0, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassesAndNECompareThem, 1, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassAndGetField, 7, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateClassWithNestedStructAndGetField, 5, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateClassWithNestedStructAndAddFields, 24, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassAndCheckTypeNoHelper, 1, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassWithGCFieldAndAddFields, 12, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassAndAssignRefToAField, 12, expectedAllocationKind); CallTestAndVerifyAllocation(TestMixOfReportingAndWriteBarriers, 34, expectedAllocationKind); // The remaining tests currently never allocate on the stack if (expectedAllocationKind == AllocationKind.Stack) { expectedAllocationKind = AllocationKind.Heap; } // This test calls CORINFO_HELP_ISINSTANCEOFCLASS CallTestAndVerifyAllocation(AllocateSimpleClassAndCheckTypeHelper, 1, expectedAllocationKind); // This test calls CORINFO_HELP_CHKCASTCLASS_SPECIAL CallTestAndVerifyAllocation(AllocateSimpleClassAndCast, 7, expectedAllocationKind); // Stack allocation of boxed structs is currently disabled CallTestAndVerifyAllocation(BoxSimpleStructAndAddFields, 12, expectedAllocationKind); return(methodResult); }
public static int Main() { AllocationKind expectedAllocationKind = AllocationKind.Stack; if (GCStressEnabled()) { Console.WriteLine("GCStress is enabled"); expectedAllocationKind = AllocationKind.Undefined; } else if (!SPCOptimizationsEnabled() && !Crossgen2Test()) { Console.WriteLine("System.Private.CoreLib.dll optimizations are disabled"); expectedAllocationKind = AllocationKind.Heap; } classA = new SimpleClassA(f1, f2); classWithGCField = new SimpleClassWithGCField(f1, f2, null); str0 = "str_zero"; str1 = "str_one"; str2 = "str_two"; str3 = "str_three"; str4 = "str_four"; CallTestAndVerifyAllocation(AllocateSimpleClassAndAddFields, 12, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassesAndEQCompareThem, 0, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassesAndNECompareThem, 1, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassAndGetField, 7, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateClassWithNestedStructAndGetField, 5, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateClassWithNestedStructAndAddFields, 24, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassWithGCFieldAndAddFields, 12, expectedAllocationKind); CallTestAndVerifyAllocation(AllocateSimpleClassAndAssignRefToAField, 12, expectedAllocationKind); CallTestAndVerifyAllocation(TestMixOfReportingAndWriteBarriers, 34, expectedAllocationKind); // The object is currently allocated on the stack when this method is jitted and on the heap when it's R2R-compiled. // The reason is that we always do the type check via helper in R2R mode, which blocks stack allocation. // We don't have to use a helper in this case (even for R2R), https://github.com/dotnet/coreclr/issues/22086 tracks fixing that. CallTestAndVerifyAllocation(AllocateSimpleClassAndCheckTypeNoHelper, 1, AllocationKind.Undefined); CallTestAndVerifyAllocation(AllocateClassWithGcFieldAndInt, 5, expectedAllocationKind); // The remaining tests currently never allocate on the stack if (expectedAllocationKind == AllocationKind.Stack) { expectedAllocationKind = AllocationKind.Heap; } // This test calls CORINFO_HELP_ISINSTANCEOFCLASS CallTestAndVerifyAllocation(AllocateSimpleClassAndCheckTypeHelper, 1, expectedAllocationKind); // This test calls CORINFO_HELP_CHKCASTCLASS_SPECIAL CallTestAndVerifyAllocation(AllocateSimpleClassAndCast, 7, expectedAllocationKind); // Stack allocation of boxed structs is currently disabled CallTestAndVerifyAllocation(BoxSimpleStructAndAddFields, 12, expectedAllocationKind); return(methodResult); }