Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend "auto tailcall" functionality similar to explicit tail.call. #9620

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
033c03b
Disable tailcall for symbolicate tests.
jaykrell Jul 18, 2018
96ad801
Remove a tailcall from System.Runtime.Serialization test that,
jaykrell Jul 20, 2018
5c14539
Remove tailcalls from System.Web.Extensions tests, that if optimized,…
jaykrell Jul 20, 2018
67992b5
Turn off tailcall optimization in System.Web tests as it breaks them
jaykrell Jul 20, 2018
68000cb
Turn off tailcall optimizations for debugger tests.
jaykrell Jul 20, 2018
9a7b236
Eliminate two tailcalls in corlib tests that, if optimized, break the…
jaykrell Jul 20, 2018
eebfebd
Disable tailcall optimization in profiler tests.
jaykrell Jul 20, 2018
7c51772
Add some tests for aggressive (C#) tailcall.
jaykrell Jul 20, 2018
36a5ad3
Add tailcall to default optimization.
jaykrell Jul 20, 2018
883688b
Some debugging code.
jaykrell Jul 20, 2018
8ae2dca
Tailcall optimization w/o tail. prefix.
jaykrell Jul 20, 2018
cbd52ed
Give x86, arm, arm64, AOT a chance.
jaykrell Jul 20, 2018
22d6a71
Remove tailcalls from exception18 that counts stack frames.
jaykrell Jul 20, 2018
6998b3d
Don't skip a stack frame in RegisterObjectCreationCallback when walki…
jaykrell Jul 20, 2018
d4892ad
Disable autotail for arm, arm64; skip the gsharedvt sensitive autotai…
jaykrell Jul 20, 2018
ea0c541
Ratchet up for AOT but still only amd64.
jaykrell Jul 20, 2018
28f2b39
Add NoInlining on NoTailcall.
jaykrell Jul 20, 2018
5a6e271
Disable x86 again, needs work.
jaykrell Jul 20, 2018
777567d
Update line numbers.
jaykrell Jul 21, 2018
24920f2
Evade bad corlib counter.
jaykrell Jul 21, 2018
7a4e0d9
Disable x86 again.
jaykrell Jul 21, 2018
3cde7c1
This code is measuring the call depth within BCL
jaykrell Jul 21, 2018
4fe601a
Revert "Add tailcall to default optimization."
jaykrell Jul 21, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3`
# This can be reset to 0 when Mono's version number is bumped
# since it's part of the corlib version (the prefix '1' in the full
# version number is to ensure the number isn't treated as octal in C)
MONO_CORLIB_COUNTER=25
MONO_CORLIB_COUNTER=31
MONO_CORLIB_VERSION=`printf "1%02d%02d%02d%03d" $MONO_VERSION_MAJOR $MONO_VERSION_MINOR 0 $MONO_CORLIB_COUNTER`

AC_DEFINE_UNQUOTED(MONO_CORLIB_VERSION,$MONO_CORLIB_VERSION,[Version of the corlib-runtime interface])
Expand Down
8 changes: 8 additions & 0 deletions mcs/class/Mono.Debugger.Soft/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
thisdir = class/Mono.Debugger.Soft
include ../../build/rules.make

# FIXME Turn off tailcall optimizations for debugger tests.
# Most of the tailcalls can be manually eliminated, however
# there are two tests that check for a precise stack within the BCL,
# and either we'd have to remove those tailcalls, or turn off tailcall like here,
# or maybe split up the debugger tests into tailcall and non-tailcall versions,
# where non-tailcall is quite small.
TEST_RUNTIME_FLAGS += --optimize=-tailc

LIBRARY = Mono.Debugger.Soft.dll
LIBRARY_SNK = ../mono.snk

Expand Down
5 changes: 5 additions & 0 deletions mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1496,13 +1496,17 @@ internal static Delegate create_filter_delegate (Delegate dlg, MethodInfo filter

ig.Emit (OpCodes.Ldstr, "FOO");
ig.Emit (OpCodes.Call, typeof (Tests).GetMethod ("dyn_call"));
ig.Emit (OpCodes.Call, typeof (Tests).GetMethod ("NoTailcall"));
ig.Emit (OpCodes.Ret);

var del = (Action<int>)m.CreateDelegate (typeof (Action<int>));

del (0);
}

[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void NoTailcall () { }

public static void dyn_call (string s) {
}

Expand All @@ -1522,6 +1526,7 @@ internal static Delegate create_filter_delegate (Delegate dlg, MethodInfo filter
ILGenerator ig = mb.GetILGenerator ();
ig.Emit (OpCodes.Ldstr, "FOO");
ig.Emit (OpCodes.Call, typeof (Tests).GetMethod ("ref_emit_call"));
ig.Emit (OpCodes.Call, typeof (Tests).GetMethod ("NoTailcall"));
ig.Emit (OpCodes.Ret);

Type t = tb.CreateType ();
Expand Down
10 changes: 8 additions & 2 deletions mcs/class/Mono.Debugger.Soft/Test/dtest-excfilter.il
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
{
.entrypoint
call void class ExceptionFilterTest::Test ()
ret
}
call void class ExceptionFilterTest::NoTailcall ()
ret }

.method public static int32 Filter ([mscorlib]System.Exception exc) cil managed noinlining
{
Expand Down Expand Up @@ -46,4 +46,10 @@
end:
ret
}

.method static void NoTailcall () noinlining
{
ret
}

}
3 changes: 3 additions & 0 deletions mcs/class/Mono.Debugger.Soft/Test/dtest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3748,6 +3748,7 @@ Event step_out_await (string method, Event e)
// FIXME: This is racy
vm.Resume ();

// FIXME This test does not allow for tailcall optimization in Sleep.
Thread.Sleep (100);

vm.Suspend ();
Expand Down Expand Up @@ -4252,6 +4253,8 @@ Event step_out_await (string method, Event e)
vm.Suspend ();
Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");

// FIXME This test is deeply tied to BCL internals.
// FIXME This test does not allow for tailcall optimizations therein.
frames = thread.GetFrames ();
Assert.AreEqual (8, frames.Length, "#7");
Assert.AreEqual ("Wait_internal", frames [0].Method.Name, "#8.0");
Expand Down
3 changes: 2 additions & 1 deletion mcs/class/Mono.Profiler.Log/Test/ProfilerTestRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void RunTest ()
proc.StartInfo = new ProcessStartInfo {
UseShellExecute = false,
FileName = Path.GetFullPath (Path.Combine ("..", "..", "..", "runtime", "mono-wrapper")),
Arguments = $"--debug --profile=log:nodefaults,output={_output},{Options} log-profiler-test.exe {Name}",
// FIXME profiler test is broken by tailcall optimization
Arguments = $"--optimize=-tailc --debug --profile=log:nodefaults,output={_output},{Options} log-profiler-test.exe {Name}",
};

proc.Start ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
using System.Xml.Schema;
using System.Xml.Serialization;
using NUnit.Framework;
using System.Runtime.CompilerServices;

namespace MonoTests.System.Runtime.Serialization
{
Expand Down Expand Up @@ -75,6 +76,9 @@ public void UseCase1 ()

public class MyResolver : DataContractResolver
{
[MethodImplAttribute (MethodImplOptions.NoInlining)]
static void NoTailcall () { }

public override bool TryResolveType (Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
{
//Console.WriteLine ("TryResolveType: {0} {1}", type, declaredType);
Expand All @@ -96,7 +100,9 @@ bool SafeResolveType (Type type, out XmlDictionaryString name, out XmlDictionary
public override Type ResolveName (string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
{
//Console.WriteLine ("ResolveName: {0} {1} {2}", typeName, typeNamespace, declaredType);
return knownTypeResolver.ResolveName (typeName, typeNamespace, declaredType, null) ?? RecoveringResolveName (typeName, typeNamespace);
var a = knownTypeResolver.ResolveName (typeName, typeNamespace, declaredType, null) ?? RecoveringResolveName (typeName, typeNamespace);
NoTailcall ();
return a;
}

Type RecoveringResolveName (string typeName, string typeNamespace)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Runtime.CompilerServices;

using NUnit.Framework;

Expand All @@ -42,12 +43,16 @@ class DataPagerFieldCollectionPoker : DataPagerFieldCollection
{
EventRecorder recorder;

[MethodImplAttribute (MethodImplOptions.NoInlining)]
static void NoTailcall () { }

void RecordEvent (string suffix)
{
if (recorder == null)
return;

recorder.Record (suffix);
NoTailcall ();
}

public DataPagerFieldCollectionPoker ()
Expand Down Expand Up @@ -79,6 +84,7 @@ public object DoCreateKnownType (int index)
public void DoOnValidate (object value)
{
OnValidate (value);
NoTailcall ();
}

public void CatchFieldsChangedEvent ()
Expand All @@ -91,33 +97,38 @@ protected override void OnValidate (object o)
RecordEvent ("Enter");
base.OnValidate (o);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnClearComplete ()
{
RecordEvent ("Enter");
base.OnClearComplete ();
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnInsertComplete (int index, object value)
{
RecordEvent ("Enter");
base.OnInsertComplete (index, value);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnRemoveComplete (int index, object value)
{
RecordEvent ("Enter");
base.OnRemoveComplete (index, value);
RecordEvent ("Leave");
NoTailcall ();
}

void OnFieldsChanged (object sender, EventArgs args)
{
RecordEvent ("Enter");
RecordEvent ("Leave");
NoTailcall ();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Runtime.CompilerServices;

using NUnit.Framework;
using MonoTests.SystemWeb.Framework;
Expand All @@ -50,13 +51,17 @@ public sealed class ListViewPoker : ListView
public StateBag StateBag {
get { return base.ViewState; }
}


[MethodImplAttribute (MethodImplOptions.NoInlining)]
static void NoTailcall () { }

void RecordEvent (string suffix)
{
if (recorder == null)
return;

recorder.Record (suffix);
NoTailcall ();
}

public ListViewPoker ()
Expand Down Expand Up @@ -86,132 +91,151 @@ protected override void OnItemCanceling (ListViewCancelEventArgs e)
RecordEvent ("Enter");
base.OnItemCanceling (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemCommand (ListViewCommandEventArgs e)
{
RecordEvent ("Enter");
base.OnItemCommand (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemCreated (ListViewItemEventArgs e)
{
RecordEvent ("Enter");
base.OnItemCreated (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemDataBound (ListViewItemEventArgs e)
{
RecordEvent ("Enter");
base.OnItemDataBound (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemDeleted (ListViewDeletedEventArgs e)
{
RecordEvent ("Enter");
base.OnItemDeleted (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemDeleting (ListViewDeleteEventArgs e)
{
RecordEvent ("Enter");
base.OnItemDeleting (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemEditing (ListViewEditEventArgs e)
{
RecordEvent ("Enter");
base.OnItemEditing (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemInserted (ListViewInsertedEventArgs e)
{
RecordEvent ("Enter");
base.OnItemInserted (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemInserting (ListViewInsertEventArgs e)
{
RecordEvent ("Enter");
base.OnItemInserting (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemUpdated (ListViewUpdatedEventArgs e)
{
RecordEvent ("Enter");
base.OnItemUpdated (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnItemUpdating (ListViewUpdateEventArgs e)
{
RecordEvent ("Enter");
base.OnItemUpdating (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnLayoutCreated (EventArgs e)
{
RecordEvent ("Enter");
base.OnLayoutCreated (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnPagePropertiesChanged (EventArgs e)
{
RecordEvent ("Enter");
base.OnPagePropertiesChanged (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnPagePropertiesChanging (PagePropertiesChangingEventArgs e)
{
RecordEvent ("Enter");
base.OnPagePropertiesChanging (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnSelectedIndexChanged (EventArgs e)
{
RecordEvent ("Enter");
base.OnSelectedIndexChanged (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnSelectedIndexChanging (ListViewSelectEventArgs e)
{
RecordEvent ("Enter");
base.OnSelectedIndexChanging (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnSorted (EventArgs e)
{
RecordEvent ("Enter");
base.OnSorted (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnSorting (ListViewSortEventArgs e)
{
RecordEvent ("Enter");
base.OnSorting (e);
RecordEvent ("Leave");
NoTailcall ();
}

protected override void OnTotalRowCountAvailable (PageEventArgs e)
{
RecordEvent ("Enter");
base.OnTotalRowCountAvailable (e);
RecordEvent ("Leave");
NoTailcall ();
}

public void DoSetPageProperties (int startRowIndex, int maximumRows, bool databind)
Expand Down
4 changes: 4 additions & 0 deletions mcs/class/System.Web/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ thisdir = class/System.Web
SUBDIRS = Test
include ../../build/rules.make

# FIXME This tests for precise stack traces, which tailcall optimization breaks.
# The exact tailcall has not been determined.
TEST_RUNTIME_FLAGS += --optimize=-tailc

LIBRARY = System.Web.dll

RESOURCE_FILES_1= \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ internal static ObjectCreationDelegate GetObjectCreationCallback (Type t)
}

public static void RegisterObjectCreationCallback (ObjectCreationDelegate callback) {
int i = 1;
int i = 0;
StackTrace trace = new StackTrace (false);
while (i < trace.FrameCount) {
StackFrame frame = trace.GetFrame (i);
Expand Down
Loading