[m-rev.] diff: C# optimisations

Peter Wang novalazy at gmail.com
Wed Oct 13 13:43:35 AEDT 2010


On 2010-10-12, Peter Wang <novalazy at gmail.com> wrote:
> 
> runtime/mercury_dotnet.cs.in:
>         Keep an instance of a TypeInfo_Struct created from a
>         TypeCtorInfo_Struct, so it can be reused if the same
>         TypeCtorInfo_Struct needs to be "cast" to TypeInfo_Struct again.

Branches: main

compiler/mlds_to_cs.m:
        Implement module finalisation by registering predicates with the
        `System.AppDomain.CurrentDomain.ProcessExit' event.

library/builtin.m:
runtime/mercury_dotnet.cs.in:
        Fix problems with deep copying TypeCtorInfo_Struct instances, which
        due to a recent change could have a pointer to a TypeInfo_Struct
        which points to itself.

        Mark the offending field with the [NonSerialized] attribute and make
        the `deep_copy' implementation ignore fields with the attribute.

tests/hard_coded/loop_inv_test.m:
tests/hard_coded/loop_inv_test1.m:
        Make these tests work in C#.

diff --git a/compiler/mlds_to_cs.m b/compiler/mlds_to_cs.m
index 6247347..029dc53 100644
--- a/compiler/mlds_to_cs.m
+++ b/compiler/mlds_to_cs.m
@@ -123,7 +123,7 @@ interface_is_special("MercuryType").
 output_csharp_src_file(ModuleInfo, Indent, MLDS, !IO) :-
     % Run further transformations on the MLDS.
     MLDS = mlds(ModuleName, AllForeignCode, Imports, GlobalData, Defns0,
-        InitPreds, _FinalPreds, ExportedEnums),
+        InitPreds, FinalPreds, ExportedEnums),
     ml_global_data_get_all_global_defns(GlobalData,
         ScalarCellGroupMap, VectorCellGroupMap, GlobalDefns),
     Defns = GlobalDefns ++ Defns0,
@@ -172,9 +172,6 @@ output_csharp_src_file(ModuleInfo, Indent, MLDS, !IO) :-
     io.write_string("\n// ExportedEnums\n", !IO),
     output_exported_enums(Info, Indent + 1, ExportedEnums, !IO),
 
-    % io.write_string("\n// FinalPreds\n", !IO),
-    % output_finals(Indent + 1, FinalPreds, !IO),
-
     io.write_string("\n// EnvVarNames\n", !IO),
     output_env_vars(Indent + 1, NonRttiDefns, !IO),
 
@@ -185,7 +182,8 @@ output_csharp_src_file(ModuleInfo, Indent, MLDS, !IO) :-
         "MR_init_vector_common_data"
         | InitPreds
     ],
-    output_static_constructor(ModuleName, Indent + 1, StaticCtorCalls, !IO),
+    output_static_constructor(ModuleName, Indent + 1, StaticCtorCalls,
+        FinalPreds, !IO),
 
     output_src_end(Indent, ModuleName, !IO).
 
@@ -473,10 +471,10 @@ output_src_start(Globals, Info, Indent, MercuryModuleName, _Imports,
     % methods that we generated earlier.
     %
 :- pred output_static_constructor(mercury_module_name::in, indent::in,
-    list(string)::in, io::di, io::uo) is det.
+    list(string)::in, list(string)::in, io::di, io::uo) is det.
 
 output_static_constructor(MercuryModuleName, Indent, StaticConstructors,
-        !IO) :-
+        FinalPreds, !IO) :-
     indent_line(Indent, !IO),
     io.write_string("static ", !IO),
     mangle_sym_name_for_csharp(MercuryModuleName, module_qual, "__",
@@ -489,6 +487,14 @@ output_static_constructor(MercuryModuleName, Indent, StaticConstructors,
         io.write_string("();\n", !IO)
     ),
     list.foldl(WriteCall, StaticConstructors, !IO),
+    WriteFinal = (pred(FinalPred::in, !.IO::di, !:IO::uo) is det :-
+        indent_line(Indent + 1, !IO),
+        list.foldl(io.write_string, [
+            "System.AppDomain.CurrentDomain.ProcessExit += ",
+            "(sender, ev) => ", FinalPred, "();\n"
+        ], !IO)
+    ),
+    list.foldl(WriteFinal, FinalPreds, !IO),
     indent_line(Indent, !IO),
     io.write_string("}\n", !IO).
 
diff --git a/library/builtin.m b/library/builtin.m
index f8923ed..05a3c15 100644
--- a/library/builtin.m
+++ b/library/builtin.m
@@ -763,8 +763,10 @@ public static void deep_copy_fields(System.Reflection.FieldInfo[] fields,
     // XXX We don't handle init-only fields, but I can't think of a way.
     foreach (System.Reflection.FieldInfo f in fields)
     {
+        if (!f.IsNotSerialized) {
         f.SetValue(dest, deep_copy(f.GetValue(src)));
     }
+    }
 }
 ").
 
diff --git a/runtime/mercury_dotnet.cs.in b/runtime/mercury_dotnet.cs.in
index fad20c1..b5b20a4 100644
--- a/runtime/mercury_dotnet.cs.in
+++ b/runtime/mercury_dotnet.cs.in
@@ -139,6 +139,9 @@ public class TypeCtorInfo_Struct : PseudoTypeInfo {
     public int              type_ctor_num_functors;
     public short            type_ctor_flags;
     public int[]            type_functor_number_map;
+
+    // This attribute is also to to prevent cyclic copying in deep_copy.
+    [System.NonSerialized]
     private TypeInfo_Struct cached_type_info;
 
     public TypeCtorInfo_Struct() {
diff --git a/tests/hard_coded/loop_inv_test.m b/tests/hard_coded/loop_inv_test.m
index 8e071c4..e50ae99 100644
--- a/tests/hard_coded/loop_inv_test.m
+++ b/tests/hard_coded/loop_inv_test.m
@@ -82,7 +82,7 @@ loop2(N, Inv, Acc0, Acc) :-
     [will_not_call_mercury, promise_pure],
 "
     /* Test that p/1 only gets called once. */
-    if (p_num_calls++) {
+    if (p_num_calls++ > 0) {
         mercury.runtime.Errors.fatal_error(""p/1 called more than once"");
     }
 
@@ -130,7 +130,7 @@ loop2(N, Inv, Acc0, Acc) :-
     [will_not_call_mercury, promise_pure],
 "
     /* Test that q/1 only gets called once. */
-    if (q_num_calls++) {
+    if (q_num_calls++ > 0) {
         mercury.runtime.Errors.fatal_error(""q/1 called more than once"");
     }
 
diff --git a/tests/hard_coded/loop_inv_test1.m b/tests/hard_coded/loop_inv_test1.m
index 7677fdd..ce31787 100644
--- a/tests/hard_coded/loop_inv_test1.m
+++ b/tests/hard_coded/loop_inv_test1.m
@@ -81,7 +81,7 @@ loop2(N, Acc0, Acc) :-
     [will_not_call_mercury, promise_pure],
 "
     /* Test that p/1 only gets called once. */
-    if (p_num_calls++) {
+    if (p_num_calls++ > 0) {
         mercury.runtime.Errors.fatal_error(""p/1 called more than once"");
     }
 
@@ -129,7 +129,7 @@ loop2(N, Acc0, Acc) :-
     [will_not_call_mercury, promise_pure],
 "
     /* Test that q/1 only gets called once. */
-    if (q_num_calls++) {
+    if (q_num_calls++ > 0) {
         mercury.runtime.Errors.fatal_error(""q/1 called more than once"");
     }
 

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list