[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