[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