[m-rev.] diff: restore java mutables

Peter Wang novalazy at gmail.com
Mon Aug 24 13:35:00 AEST 2009


Branches: main

The recent changes to support warnings about non-contiguous clauses broke
mutable support in Java.  The problem was that we generated both a foreign
procedure called "get_<var>" and a clause called "get_<var>", due to sharing
code with the C backends.

compiler/make_hlds_passes.m:
        Rename the foreign procs generated for Java to "unsafe_get_<var>" and
        "unsafe_set_<var>", to align the Java backend with the C backends.

compiler/prog_mutable.m:
        Update the description of the mutables transformation for Java.

diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
index 7d91c0e..849055f 100644
--- a/compiler/make_hlds_passes.m
+++ b/compiler/make_hlds_passes.m
@@ -515,13 +515,18 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
         (
             CompilationTarget = target_c,
             WantPreInitDecl = yes,
-            WantUnsafeAccessAndLockDecls = yes
+            WantLockDecls = yes,
+            WantUnsafeAccessDecls = yes
         ;
-            ( CompilationTarget = target_erlang
-            ; CompilationTarget = target_java
-            ),
+            CompilationTarget = target_java,
+            WantPreInitDecl = no,
+            WantLockDecls = no,
+            WantUnsafeAccessDecls = yes
+        ;
+            CompilationTarget = target_erlang,
             WantPreInitDecl = no,
-            WantUnsafeAccessAndLockDecls = no
+            WantLockDecls = no,
+            WantUnsafeAccessDecls = no
         ;
             ( CompilationTarget = target_il
             ; CompilationTarget = target_asm
@@ -529,7 +534,8 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
             ),
             % Not supported yet.
             WantPreInitDecl = yes,
-            WantUnsafeAccessAndLockDecls = yes
+            WantLockDecls = yes,
+            WantUnsafeAccessDecls = yes
         ),
 
         % Create the mutable initialisation predicate.
@@ -555,13 +561,18 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
 
             % Create the primitive access and locking predicates.
             (
-                WantUnsafeAccessAndLockDecls = yes,
+                WantLockDecls = yes,
                 LockPredDeclItem = lock_pred_decl(ModuleName, Name, Context),
                 UnlockPredDecl = unlock_pred_decl(ModuleName, Name, Context),
                 add_item_decl_pass_1(LockPredDeclItem, _, Status, _,
                     !ModuleInfo, !Specs),
                 add_item_decl_pass_1(UnlockPredDecl, _, Status, _,
-                    !ModuleInfo, !Specs),
+                    !ModuleInfo, !Specs)
+            ;
+                WantLockDecls = no
+            ),
+            (
+                WantUnsafeAccessDecls = yes,
                 UnsafeGetPredDeclItem = unsafe_get_pred_decl(ModuleName, Name,
                     Type, Inst, Context),
                 UnsafeSetPredDeclItem = unsafe_set_pred_decl(ModuleName, Name,
@@ -571,7 +582,7 @@ add_pass_1_mutable(Item, Status, !ModuleInfo, !Specs) :-
                 add_item_decl_pass_1(UnsafeSetPredDeclItem, _, Status, _,
                     !ModuleInfo, !Specs)
             ;
-                WantUnsafeAccessAndLockDecls = no
+                WantUnsafeAccessDecls = no
             ),
 
             % Create the standard, non-pure access predicates. These are
@@ -840,7 +851,7 @@ add_pass_2_mutable(ItemMutable, Status, !ModuleInfo, !Specs) :-
         globals.get_target(Globals, CompilationTarget),
 
         % XXX We don't currently support the foreign_name attribute
-        % for languages other than C and Erlang.
+        % for all languages.
         (
             (
                 CompilationTarget = target_c,
@@ -2121,53 +2132,49 @@ add_c_mutable_primitive_preds(TargetMutableName, ModuleName, MutableName,
 add_c_java_mutable_user_access_preds(ModuleName, MutableName, MutAttrs,
         ForLang, Context, !Status, !ModuleInfo, !QualInfo, !Specs) :-
     varset.new_named_var(varset.init, "X", X, ProgVarSet0),
+
     LockPredName   = mutable_lock_pred_sym_name(ModuleName, MutableName),
     UnlockPredName = mutable_unlock_pred_sym_name(ModuleName, MutableName),
-    SetPredName = mutable_set_pred_sym_name(ModuleName, MutableName),
+    CallLock   = call_expr(LockPredName, [], purity_impure) - Context,
+    CallUnlock = call_expr(UnlockPredName, [], purity_impure) - Context,
+
+    GetterPredName = mutable_unsafe_get_pred_sym_name(ModuleName, MutableName),
+    SetterPredName = mutable_unsafe_set_pred_sym_name(ModuleName, MutableName),
+    CallGetter = call_expr(GetterPredName, [variable(X, Context)],
+        purity_semipure) - Context,
+    CallSetter = call_expr(SetterPredName, [variable(X, context_init)],
+        purity_impure) - Context,
+
     GetPredName = mutable_get_pred_sym_name(ModuleName, MutableName),
+    SetPredName = mutable_set_pred_sym_name(ModuleName, MutableName),
 
     (
         ForLang = for_c,
-        CallLock   = call_expr(LockPredName, [], purity_impure) - Context,
-        CallUnlock = call_expr(UnlockPredName, [], purity_impure) - Context,
-        GetterPredName = mutable_unsafe_get_pred_sym_name(ModuleName,
-            MutableName),
-        SetterPredName = mutable_unsafe_set_pred_sym_name(ModuleName,
-            MutableName)
+        GetBody = goal_list_to_conj(Context, [CallLock, CallGetter,
+            CallUnlock]),
+        StdSetBody = goal_list_to_conj(Context, [CallLock, CallSetter,
+            CallUnlock])
     ;
         ForLang = for_java,
-        CallLock   = true_expr - Context,
-        CallUnlock = true_expr - Context,
-        GetterPredName = mutable_get_pred_sym_name(ModuleName, MutableName),
-        SetterPredName = mutable_set_pred_sym_name(ModuleName, MutableName)
+        % There are no separate lock predicates for Java; the synchronisation
+        % is performed within the "unsafe" predicates.
+        GetBody = CallGetter,
+        StdSetBody = CallSetter
     ),
 
     % Construct the semipure get predicate.
-    CallGetter = call_expr(GetterPredName, [variable(X, Context)],
-        purity_semipure) - Context,
-
-    GetBody = goal_list_to_conj(Context, [CallLock, CallGetter, CallUnlock]),
     StdGetBody = promise_purity_expr(purity_semipure, GetBody) - Context,
-
-    StdGetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet0,
-        pf_predicate, GetPredName, [variable(X, context_init)], StdGetBody,
-        Context, -1
-    ),
-    StdSetItem = item_clause(StdSetItemClause),
+    StdGetItemClause = item_clause_info(compiler(mutable_decl),
+        ProgVarSet0, pf_predicate, GetPredName,
+        [variable(X, context_init)], StdGetBody, Context, -1),
+    StdGetItem = item_clause(StdGetItemClause),
     add_item_pass_3(StdGetItem, !Status, !ModuleInfo, !QualInfo, !Specs),
 
     % Construct the impure set predicate.
-    CallSetter = call_expr(SetterPredName, [variable(X, context_init)],
-        purity_impure) - Context,
-
-    StdSetBody = goal_list_to_conj(Context,
-        [CallLock, CallSetter, CallUnlock]),
-
-    StdSetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet0,
-        pf_predicate, SetPredName, [variable(X, context_init)], StdSetBody,
-        Context, -1
-    ),
-    StdGetItem = item_clause(StdGetItemClause),
+    StdSetItemClause = item_clause_info(compiler(mutable_decl),
+        ProgVarSet0, pf_predicate, SetPredName,
+        [variable(X, context_init)], StdSetBody, Context, -1),
+    StdSetItem = item_clause(StdSetItemClause),
     add_item_pass_3(StdSetItem, !Status, !ModuleInfo, !QualInfo, !Specs),
 
     IOStateInterface = mutable_var_attach_to_io_state(MutAttrs),
@@ -2177,7 +2184,6 @@ add_c_java_mutable_user_access_preds(ModuleName, MutableName, MutAttrs,
 
         % Construct the pure get predicate.
         IOGetBody = promise_purity_expr(purity_pure, GetBody) - Context,
-
         Ctxt = context_init,
         IOGetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet,
             pf_predicate, GetPredName,
@@ -2192,9 +2198,7 @@ add_c_java_mutable_user_access_preds(ModuleName, MutableName, MutAttrs,
         % We just use the body of impure version and attach a promise_pure
         % pragma to the predicate. (The purity pragma was added during
         % stage 2.)
-
         IOSetBody = StdSetBody,
-
         IOSetItemClause = item_clause_info(compiler(mutable_decl), ProgVarSet,
             pf_predicate, SetPredName,
             [variable(X, Ctxt), variable(IO, Ctxt), variable(IO, Ctxt)],
@@ -2399,7 +2403,7 @@ add_java_mutable_primitive_preds(TargetMutableName, ModuleName, MutableName,
         "\tsynchronized (" ++ MutableMutexVarName ++ ") {\n" ++
         "\t\tX = " ++ TargetMutableName ++ ";\n\t}\n",
     GetForeignProc = pragma_foreign_proc(GetAttrs,
-        mutable_get_pred_sym_name(ModuleName, MutableName),
+        mutable_unsafe_get_pred_sym_name(ModuleName, MutableName),
         pf_predicate,
         [pragma_var(X, "X", out_mode(Inst), BoxPolicy)],
         ProgVarSet,
@@ -2430,7 +2434,7 @@ add_java_mutable_primitive_preds(TargetMutableName, ModuleName, MutableName,
     SetCode = "\tsynchronized (" ++ MutableMutexVarName ++ ") {\n" ++
         "\t\t" ++ TargetMutableName ++ "= X;\n\t}\n",
     SetForeignProc = pragma_foreign_proc(SetAttrs,
-        mutable_set_pred_sym_name(ModuleName, MutableName),
+        mutable_unsafe_set_pred_sym_name(ModuleName, MutableName),
         pf_predicate,
         [pragma_var(X, "X", in_mode(Inst), BoxPolicy)],
         ProgVarSet,
diff --git a/compiler/prog_mutable.m b/compiler/prog_mutable.m
index 939cac9..9c96f5a 100644
--- a/compiler/prog_mutable.m
+++ b/compiler/prog_mutable.m
@@ -234,10 +234,14 @@
 %       impure set_<varname>(<initval>).
 %
 % Operations on mutables are defined in terms of the following two predicates.
+% They are actually "safe": we synchronize the access and assignment statements
+% within the predicates (by the Java specification, only actually necessary for
+% doubles and longs).  They are named so to minimise the differences with the C
+% backends.
 %
-%   :- impure pred set_<varname>(<vartype>::in(<varinst>)) is det.
+%   :- impure pred unsafe_set_<varname>(<vartype>::in(<varinst>)) is det.
 %   :- pragma foreign_proc("Java",
-%       set_<varname>(X::in(<varinst>)),
+%       unsafe_set_<varname>(X::in(<varinst>)),
 %       [will_not_call_mercury, thread_safe],
 %   "
 %       synchronized (mutable_<varname>_lock) {
@@ -245,9 +249,9 @@
 %       }
 %   ").
 %
-%   :- semipure pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%   :- semipure pred unsafe_get_<varname>(<vartype>::out(<varinst>)) is det.
 %   :- pragma foreign_proc("Java",
-%       get_varname(X::out(<varinst>)),
+%       unsafe_get_varname(X::out(<varinst>)),
 %       [promise_semipure, will_not_call_mercury, thread_safe],
 %   "
 %       synchronized (mutable_<varname>_lock) {
@@ -255,6 +259,19 @@
 %       }
 %   ").
 %
+% The above prediates are called by these predicates, again to minimise
+% differences with the C backends:
+%
+%   :- impure pred set_<varname>(<vartype>::in(<varinst>)) is det.
+%
+%   set_<varname>(X) :-
+%       impure unsafe_set_<varname>(X).
+%
+%   :- semipure pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%
+%   get_<varname>(X) :-
+%       semipure unsafe_get_<varname>(X).
+%
 % For constant mutables the transformation is:
 %
 %   :- mutable(<varname>, <vartype>, <initvalue>, <varinst>, [constant]).

--------------------------------------------------------------------------
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