[m-rev.] for review: initialise mercury runtime on .NET fixes

Peter Ross pro at missioncriticalit.com
Fri Oct 24 00:30:34 AEST 2003


On Thu, Oct 16, 2003 at 12:04:34AM +1000, Fergus Henderson wrote:
> On 15-Oct-2003, Peter Ross <pro at missioncriticalit.com> wrote:
> > 
> > Ensure that the mercury runtime is always initialised on the .NET
> > backend, regardless of whether Mercury is used as a library or an
> > executable.
> 
> > +++ compiler/mlds_to_il.m	15 Oct 2003 13:07:37 -0000
> > @@ -2857,6 +2857,8 @@
> >  	{ Method = method(methodhead([public, static], cctor, 
> >  		signature(call_conv(no, default), void, []), []),
> >  		MethodDecls) },
> > + 	{ MaybeInitRuntimeInstrs = maybe_init_runtime_instrs },
> > + 	{ RuntimeInitInstrs = runtime_initialization_instrs },
> >  	test_rtti_initialization_field(DoneFieldRef, TestInstrs),
> >  	set_rtti_initialization_field(DoneFieldRef, SetInstrs),
> >  	{ CCtorCalls = list__filter_map(
> > @@ -2866,8 +2868,9 @@
> >  			C = call_class_constructor(
> >  				class_name(ImportName, wrapper_class_name))
> >  		), Imports) },
> > -	{ AllInstrs = list__condense([TestInstrs, AllocInstrs, SetInstrs,
> > -		CCtorCalls, InitInstrs, [ret]]) },
> > +	{ AllInstrs = list__condense([MaybeInitRuntimeInstrs,
> > +		TestInstrs, AllocInstrs, SetInstrs,
> > +		CCtorCalls, InitInstrs, RuntimeInitInstrs, [ret]]) },
> >  	{ MethodDecls = [instrs(AllInstrs)] }.
> >  
> >  :- pred test_rtti_initialization_field(fieldref, list(instr),
> 
> There should be some comments explaining what MaybeInitRuntimeInstrs
> and RuntimeInitInstrs are, and outlining the pattern of the IL that
> we will generate.
> 
> > @@ -2876,7 +2879,7 @@
> >  test_rtti_initialization_field(FieldRef, Instrs) -->
> >  	il_info_make_next_label(DoneLabel),
> >  	{ Instrs = [ldsfld(FieldRef), brfalse(label_target(DoneLabel)),
> > -		ret, label(DoneLabel)] }.
> > +		pop, ret, label(DoneLabel)] }.
> 
> The comment showing the pattern of instructions which includes these
> should be updated.
> 

Here is the interdiff with the review comments addressed.


diff -u compiler/mlds_to_il.m compiler/mlds_to_il.m
--- compiler/mlds_to_il.m
+++ compiler/mlds_to_il.m
@@ -2794,9 +2794,11 @@
 
 %-----------------------------------------------------------------------------
 %
-% Class constructors (.cctors) are used to fill in the RTTI information
-% needed for any types defined in the module.  The RTTI is stored in
-% static fields of the class.
+% Class constructors (.cctors) are used to initialise the runtime.
+% This currently consists of initialising the RTTI and calling
+% mercury.runtime.init_runtime.
+%
+% The RTTI is stored in static fields of the class.
 
 	% .cctors can be called at practically any time by the runtime
 	% system, but must be called before a static field is loaded
@@ -2805,27 +2807,44 @@
 	% fields, we could run into problems if we load a field from another
 	% class before we initialize it.  Often the RTTI in one module will
 	% refer to another, creating exactly this cross-referencing problem.
-	% To avoid problems, we initialize them in 3 passes.
+	% To avoid problems, we initialize them in 3 passes (passes 2 to 4
+	% below).
+	%
+	% Here is the structure of the .cctor that we generate.
+	%
+	% 1. We call mercury.runtime.responsible_for_initialising_runtime
+	%    to determine whether this is the first mercury .cctor called.
+	%
+	% 2. We allocate all the RTTI data structures but leave them blank.
+	%    When this is complete we set a flag to say we have completed this
+	%    pass.  After this pass is complete, it is safe for any other
+	%    module to reference our data structures.
 	%
-	% 1. We allocate all the RTTI data structures but leave them blank.
-	% When this is complete we set a flag to say we have completed this
-	% pass.  After this pass is complete, it is safe for any other module
-	% to reference our data structures.
+	% 3. We call all the .cctors for RTTI data structures that we
+	%    import.  We do this because we can't load fields from them until we
+	%    know they have been allocated.
 	%
-	% 2. We call all the .cctors for RTTI data structures that we
-	% import.  We do this because we can't load fields from them until we
-	% know they have been allocated.
+	% 4. We fill in the RTTI info in the already allocated structures.
 	%
-	% 3. We fill in the RTTI info in the already allocated structures.
+	% 5. If responsible_for_initialising_runtime returned true, then we
+	%    call the initialise runtime function now all the RTTI is
+	%    initialised.
 	%
-	% To ensure that pass 2 doesn't cause looping, the first thing done
+	% To ensure that pass 3 doesn't cause looping, the first thing done
 	% in all .cctors is a check to see if the flag is set.  If it is, we
 	% return immediately (we have already been called and our
-	% initialization is either complete or at pass 2).
+	% initialization is either complete or at pass 3).
 	%
+	% Here is a skeleton of the il that we will generate.
+	%
+	%	// Are we responsible for initialising the runtime.
+	%	call bool [mercury]mercury.runtime::
+	%			responsible_for_initialising_runtime()
+	%	
 	% 	// if (rtti_initialized) return;
 	% 	ldsfld rtti_initialized
 	%       brfalse done_label
+	%	pop	// pop the responsible_for_initialising_runtime bool
 	% 	ret
 	% 	done_label:
 	%
@@ -2844,6 +2863,8 @@
 	% 	// fill in fields of RTTI data structures
 	% 	<initialization instructions generated by field initializers>
 	%
+	%	// Maybe initialise the runtime
+	%	call void [mercury]mercury.runtime::init_runtime(bool)
 
 :- pred make_class_constructor_class_member(fieldref, mlds__imports,
 	list(instr), list(instr), class_member, il_info, il_info).
@@ -2854,7 +2875,7 @@
 	{ Method = method(methodhead([public, static], cctor,
 		signature(call_conv(no, default), void, []), []),
 		MethodDecls) },
- 	{ MaybeInitRuntimeInstrs = maybe_init_runtime_instrs },
+ 	{ ResponsibleInitRuntimeInstrs = responsible_for_init_runtime_instrs },
  	{ RuntimeInitInstrs = runtime_initialization_instrs },
 	test_rtti_initialization_field(DoneFieldRef, TestInstrs),
 	set_rtti_initialization_field(DoneFieldRef, SetInstrs),
@@ -2865,7 +2886,7 @@
 			C = call_class_constructor(
 				class_name(ImportName, wrapper_class_name))
 		), Imports) },
-	{ AllInstrs = list__condense([MaybeInitRuntimeInstrs,
+	{ AllInstrs = list__condense([ResponsibleInitRuntimeInstrs,
 		TestInstrs, AllocInstrs, SetInstrs,
 		CCtorCalls, InitInstrs, RuntimeInitInstrs, [ret]]) },
 	{ MethodDecls = [instrs(AllInstrs)] }.
@@ -4196,21 +4217,29 @@
 make_fieldref(ILType, ClassName, Id) =
 	fieldref(ILType, class_member_name(ClassName, id(Id))).
 
+:- func responsible_for_init_runtime_instrs = list(instr).
+responsible_for_init_runtime_instrs = [
+	call(get_static_methodref(runtime_init_module_name, 
+		responsible_for_init_runtime_name, simple_type(bool), []))
+	].
+
 :- func runtime_initialization_instrs = list(instr).
 runtime_initialization_instrs = [
-	call(get_static_methodref(runtime_init_module_name,
-			runtime_init_method_name, void, []))
+	call(get_static_methodref(runtime_init_module_name, 
+			runtime_init_method_name, void, [il_bool_type]))
 	].
 
 :- func runtime_init_module_name = ilds__class_name.
 runtime_init_module_name =
 	structured_name(assembly("mercury"),
-		["mercury", "private_builtin__cpp_code", wrapper_class_name],
-		[]).
+		["mercury", "runtime", "Init"], []).
 
 :- func runtime_init_method_name = ilds__member_name.
 runtime_init_method_name = id("init_runtime").
 
+:- func responsible_for_init_runtime_name = ilds__member_name.
+responsible_for_init_runtime_name = id("responsible_for_initialising_runtime").
+
 %-----------------------------------------------------------------------------%
 %
 runtime_init_method_name = id("init_runtime").
diff -u runtime/mercury_il.il runtime/mercury_il.il
--- runtime/mercury_il.il
+++ runtime/mercury_il.il
@@ -614,6 +614,8 @@
 
 .class public 'Init' {
 
+    .field private static bool will_initialise_runtime
+
     .method public static default void .cctor()
     {
     	ldc.i4.1
@@ -645,9 +647,6 @@
         call void ['mercury']mercury.io.mercury_code::init_state_2()
 	ret
     }
-
-
-    .field private static bool will_initialise_runtime
 }
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list