[m-rev.] diff: mutables for java grade

Peter Wang novalazy at gmail.com
Mon Apr 27 15:10:42 AEST 2009


2009/4/27 Julien Fischer <juliensf at csse.unimelb.edu.au>:
>
> Please also update the documentation in compiler/prog_mutable.m that
> describes the implementation of mutables to cover the Java backend.

Committed this followup.


Branches: main

compiler/make_hlds_passes.m:
        Don't generate lock objects for a constant mutables in Java grade
        as they won't be used.

compiler/prog_mutable.m:
        Document mutable transformation for Java.

diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
index 69d0112..fd5a4a0 100644
--- a/compiler/make_hlds_passes.m
+++ b/compiler/make_hlds_passes.m
@@ -1594,6 +1594,7 @@ add_pass_3_finalise(ItemFinalise, Status,
!ModuleInfo, !QualInfo, !Specs) :-
 add_pass_3_mutable(ItemMutable, Status, !ModuleInfo, !QualInfo, !Specs) :-
     ItemMutable = item_mutable_info(MercuryMutableName, Type, _InitTerm, _Inst,
         MutAttrs, _MutVarset, Context, _SeqNum),
+    IsConstant = mutable_var_constant(MutAttrs),

     % The transformation here is documented in the comments at the
     % beginning of prog_mutable.m.
@@ -1617,7 +1618,6 @@ add_pass_3_mutable(ItemMutable, Status,
!ModuleInfo, !QualInfo, !Specs) :-
             % global variable used to implement the mutable.  If the mutable is
             % not constant then add a mutex to synchronize access to it as
             % well.
-            IsConstant = mutable_var_constant(MutAttrs),
             IsThreadLocal = mutable_var_thread_local(MutAttrs),
             add_c_mutable_defn_and_decl(TargetMutableName, Type, IsConstant,
                 IsThreadLocal, Context, !ModuleInfo, !QualInfo, !Specs),
@@ -1635,7 +1635,7 @@ add_pass_3_mutable(ItemMutable, Status,
!ModuleInfo, !QualInfo, !Specs) :-

             % Add foreign_code item that defines the global variable used to
             % implement the mutable.
-            add_java_mutable_defn(TargetMutableName, Type,
+            add_java_mutable_defn(TargetMutableName, Type, IsConstant,
                 Context, !ModuleInfo, !QualInfo, !Specs),

             % Add all the predicates related to mutables.
@@ -2273,33 +2273,42 @@ add_c_mutable_initialisation(IsConstant,
IsThreadLocal, TargetMutableName,
     % Add foreign_code item that defines the global variable used to hold the
     % mutable.
     %
-:- pred add_java_mutable_defn(string::in, mer_type::in, prog_context::in,
-    module_info::in, module_info::out, qual_info::in, qual_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
+:- pred add_java_mutable_defn(string::in, mer_type::in, bool::in,
+    prog_context::in, module_info::in, module_info::out,
+    qual_info::in, qual_info::out, list(error_spec)::in, list(error_spec)::out)
+    is det.

-add_java_mutable_defn(TargetMutableName, Type,
+add_java_mutable_defn(TargetMutableName, Type, IsConstant,
         Context, !ModuleInfo, !QualInfo, !Specs) :-
     get_java_mutable_global_foreign_defn(!.ModuleInfo, Type,
-        TargetMutableName, Context, ForeignDefn),
+        TargetMutableName, IsConstant, Context, ForeignDefn),
     ItemStatus0 = item_status(status_local, may_be_unqualified),
     add_item_decl_pass_2(ForeignDefn, ItemStatus0, _, !ModuleInfo, !Specs).

 :- pred get_java_mutable_global_foreign_defn(module_info::in, mer_type::in,
-    string::in, prog_context::in, item::out) is det.
+    string::in, bool::in, prog_context::in, item::out) is det.

 get_java_mutable_global_foreign_defn(ModuleInfo, Type, TargetMutableName,
-        Context, DefnItem) :-
+        IsConstant, Context, DefnItem) :-
     module_info_get_globals(ModuleInfo, Globals),
     globals.lookup_bool_option(Globals, mutable_always_boxed, AlwaysBoxed),
     TypeName = global_foreign_type_name(AlwaysBoxed, lang_java, ModuleInfo,
         Type),
     MutableMutexVarName = mutable_mutex_var_name(TargetMutableName),

+    % Constant mutables do not require mutexes as their values are never
+    % updated.
+    (
+        IsConstant = yes,
+        LockDefn = []
+    ;
+        IsConstant = no,
+        LockDefn = ["static final java.lang.Object ", MutableMutexVarName,
+            " = new Object();\n"]
+    ),
+
     DefnBody = string.append_list([
-        "static ", TypeName, " ", TargetMutableName, ";\n",
-        "static final java.lang.Object ", MutableMutexVarName,
-        " = new Object();\n"
-    ]),
+        "static ", TypeName, " ", TargetMutableName, ";\n" | LockDefn]),
     DefnPragma = pragma_foreign_code(lang_java, DefnBody),
     DefnItemPragma = item_pragma_info(compiler(mutable_decl), DefnPragma,
         Context, -1),
diff --git a/compiler/prog_mutable.m b/compiler/prog_mutable.m
index 434279f..6495775 100644
--- a/compiler/prog_mutable.m
+++ b/compiler/prog_mutable.m
@@ -213,6 +213,85 @@
 %
 %-----------------------------------------------------------------------------%
 %
+% JAVA BACKEND
+%
+% For non-constant mutables the transformation is as follows:
+%
+%   :- mutable(<varname>, <vartype>, <initvalue>, <varinst>, [attributes]).
+%
+% ===>
+%
+%   :- pragma foreign_code("Java", "
+%       static <JavaType> mutable_<varname>;
+%       static final java.lang.Object mutable_<varname>_lock = new Object();
+%   ").
+%
+%   :- initialise initialise_mutable_<varname>/0.
+%
+%   :- impure pred initialise_mutable_<varname> is det.
+%
+%   initialise_mutable_<varname> :-
+%       impure set_<varname>(<initval>).
+%
+% Operations on mutables are defined in terms of the following two predicates.
+%
+%   :- impure pred set_<varname>(<vartype>::in(<varinst>)) is det.
+%   :- pragma foreign_proc("Java",
+%       set_<varname>(X::in(<varinst>)),
+%       [will_not_call_mercury, thread_safe],
+%   "
+%       synchronized (mutable_<varname>_lock) {
+%           mutable_<varname> = X;
+%       }
+%   ").
+%
+%   :- semipure pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%   :- pragma foreign_proc("C",
+%       get_varname(X::out(<varinst>)),
+%       [promise_semipure, will_not_call_mercury, thread_safe],
+%   "
+%       synchronized (mutable_<varname>_lock) {
+%           X = mutable_<varname>;
+%       }
+%   ").
+%
+% For constant mutables the transformation is:
+%
+%   :- mutable(<varname>, <vartype>, <initvalue>, <varinst>, [constant]).
+%
+% ===>
+%
+%   :- pragma foreign_code("Java", "<JavaType> mutable_<varname>;").
+%
+%   :- pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%   :- pragma foreign_proc("Java",
+%       get_<varname>(X::out(<varinst>)),
+%       [will_not_call_mercury, promise_pure, thread_safe],
+%   "
+%       X = mutable_<varname>;
+%   ").
+%
+% In order to initialise constant mutables we generate the following:
+%
+%   :- impure pred secret_initialization_only_set_<varname>(
+%       <vartype>::in(<varinst>)) is det.
+%
+%   :- pragma foreign_proc("Java",
+%       secret_initialization_only_set_<varname>(X::in(<varinst>)),
+%       [will_not_call_mercury],
+%   "
+%       mutable_<varname> = X;
+%   ").
+%
+%   :- initialise initialise_mutable_<varname>/0.
+%
+%   :- impure pred initialise_mutable_<varname> is det.
+%
+%   initialise_mutable_<varname> :-
+%       impure secret_initialization_only_set_<varname>(<initval>).
+%
+%-----------------------------------------------------------------------------%
+%
 % ERLANG BACKEND
 %
 % Every Erlang "process" has an associated process dictionary, which we can use
--------------------------------------------------------------------------
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