[m-rev.] for review: improperly initialised rtti structures in java
Julien Fischer
juliensf at csse.unimelb.edu.au
Fri Jun 26 10:43:03 AEST 2009
On Thu, 25 Jun 2009, Peter Wang wrote:
> Branches: main
>
> The Java backend was sometimes generating code like this to initialise RTTI
> data structures:
>
> foo_type_info.init(...,
> /* cast */ new TypeInfo_Struct(bar_type_ctor_info), ...);
> bar_type_ctor_info.init(...);
>
> where `bar_type_ctor_info' is actually a type_info.
>
> The problem is that the fields of the non-initialised `bar_type_ctor_info'
> would be copied into the new TypeInfo_Struct object. The "cast" is of course
> also unnecessary as the bar is already a TypeInfo_Struct.
>
> This patch attempts to fix the problem in two ways:
>
> 1. Don't allocate a new TypeInfo_Struct object to emulate the "cast" unless the
> value is actually a TypeCtorInfo_Struct, avoiding the problem of copying
> uninitialised fields. Currently this is implemented by a runtime check because
> the MLDS `cast' operation doesn't record the original type of the value being
> cast.
(You presumably saw the the XXX regrading that MLDS cast op?)
> 2. Instead of relying on mlds_to_rtti.m to return a list of RTTI data
> structures where sub-structures appear before the structures that reference
> them, explicitly perform a topological sort. This should be more robust.
>
>
> Unrelated change: use pre-allocated PseudoTypeInfo instances for common
> variable numbers (1 through 5).
>
>
> compiler/rtti_to_mlds.m:
> Add a function to order a list of RTTI definitions as above.
>
> Use cons instead of list.append in some places now that we can.
>
> compiler/mlds_to_java.m:
> Call the function to order RTTI definitions before outputing
> the initialisations.
>
> Call TypeInfo_Struct.maybe_new instead of allocating new
> TypeInfo_Structs.
>
> Generate code that uses pre-allocated PseudoTypeInfo instances.
>
> java/runtime/TypeInfo_Struct.java:
> Add a `maybe_new' method for "casting" TypeCtorInfo_Structs to
> TypeInfos or returning the argument unchanged.
>
> Delete a copy constructor; now unused.
>
> Add some assertions.
>
> java/runtime/PseudoTypeInfo.java:
> Add static instances of PseudoTypeInfo.
>
> tests/hard_coded/Mmakefile:
> tests/hard_coded/java_rtti_bug.exp:
> tests/hard_coded/java_rtti_bug.m:
> Add test case.
>
> diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
> index 0c7a995..bd22bc6 100644
> --- a/compiler/mlds_to_java.m
> +++ b/compiler/mlds_to_java.m
> @@ -98,6 +98,7 @@
> :- import_module ml_backend.ml_code_util. % for ml_gen_local_var_decl_flags.
> :- import_module ml_backend.ml_type_gen. % for ml_gen_type_name
> :- import_module ml_backend.ml_util.
> +:- import_module ml_backend.rtti_to_mlds.
> :- import_module parse_tree.builtin_lib_types.
> :- import_module parse_tree.file_names. % for mercury_std_library_name.
> :- import_module parse_tree.java_names.
> @@ -1752,15 +1753,27 @@ output_rtti_assignments(Indent, ModuleInfo,
> ModuleName, Defns, !IO) :-
> Defns = []
> ;
> Defns = [_ | _],
> + OrderedDefns = order_mlds_rtti_defns(Defns),
> indent_line(Indent, !IO),
> io.write_string("static {\n", !IO),
> list.foldl(
> - output_rtti_defn_assignments(Indent + 1, ModuleInfo, ModuleName),
> - Defns, !IO),
> + output_rtti_defns_assignments(Indent + 1, ModuleInfo, ModuleName),
> + OrderedDefns, !IO),
> indent_line(Indent, !IO),
> io.write_string("}\n", !IO)
> ).
>
> +:- pred output_rtti_defns_assignments(indent::in, module_info::in,
> + mlds_module_name::in, list(mlds_defn)::in, io::di, io::uo) is det.
> +
> +output_rtti_defns_assignments(Indent, ModuleInfo, ModuleName, Defns, !IO) :-
> + % Separate cliques.
> + indent_line(Indent, !IO),
> + io.write_string("//\n", !IO),
> + list.foldl(
> + output_rtti_defn_assignments(Indent, ModuleInfo, ModuleName),
> + Defns, !IO).
> +
> :- pred output_rtti_defn_assignments(indent::in, module_info::in,
> mlds_module_name::in, mlds_defn::in, io::di, io::uo) is det.
>
> @@ -3414,19 +3427,27 @@ output_unop(ModuleInfo, Unop, Expr, ModuleName, !IO) :-
> % Similarly for conversions from TypeCtorInfo to TypeInfo.
> (
> Type = mlds_pseudo_type_info_type,
> - Expr = ml_const(mlconst_int(_))
> + Expr = ml_const(mlconst_int(N))
> ->
> maybe_output_comment("cast", !IO),
> - io.write_string("new jmercury.runtime.PseudoTypeInfo(", !IO),
> - output_rval(ModuleInfo, Expr, ModuleName, !IO),
> - io.write_string(")", !IO)
> + ( have_preallocated_pseudo_type_var(N) ->
> + io.write_string("jmercury.runtime.PseudoTypeInfo.K", !IO),
> + io.write_int(N, !IO)
> + ;
> + io.write_string("new jmercury.runtime.PseudoTypeInfo(", !IO),
> + output_rval(ModuleInfo, Expr, ModuleName, !IO),
> + io.write_string(")", !IO)
> + )
> ;
> ( Type = mercury_type(_, ctor_cat_system(cat_system_type_info), _)
> ; Type = mlds_type_info_type
> )
> ->
> + % XXX we really should be able to tell if we are casting a
> + % TypeCtorInfo or a TypeInfo
That's probably going to be rather difficult as the compiler doesn't
keep track of where type_ctor_infos are acting as type_infos properly,
i.e. the common case optimization described at the beginning of
compiler/polymorphism.m. (This is already involved in several open
bugs). This is one the the next major rewrite of polymorphism.m is
going to have do properly.
> maybe_output_comment("cast", !IO),
> - io.write_string("new jmercury.runtime.TypeInfo_Struct(", !IO),
> + io.write_string("jmercury.runtime.TypeInfo_Struct.maybe_new(",
> + !IO),
> output_rval(ModuleInfo, Expr, ModuleName, !IO),
> io.write_string(")", !IO)
That looks okay.
Julien.
--------------------------------------------------------------------------
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