[m-rev.] Retry added in ssdb
Peter Wang
novalazy at gmail.com
Fri Nov 9 11:34:22 AEDT 2007
On 2007-11-08, Olivier Annet <oan at missioncriticalit.com> wrote:
> Hi,
>
> could someone review my code before commiting please.
>
> Olivier.
>
> ===================================================================
>
>
> Estimated hours taken: 24
> Branches: main
>
> Modification of the source-to-source debugger to manage the retry command.
Implement the retry command in the source-to-source debugger.
>
> compiler/ssdebug.m:
> Create an output variable and modify each call to the handle_event
> function at exit and fail port to support the retry command. Create
> the switch at exit and fail port in the source-to-source code.
Make the transformed code switch on the variable at exit and fail ports,
retrying the procedure call as the user wishes.
>
> ssdb/ssdb.m:
> Somme modifications have been added to support the retry at exit and
> fail port.
Some
> A new type ssdb_retry has been added. It is used to set the output
> variable Retry used for the switch in the source-to-source code at
> exit and fail port.
>
> Index: compiler/ssdebug.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/ssdebug.m,v
> retrieving revision 1.9
> diff -u -r1.9 ssdebug.m
> --- compiler/ssdebug.m 1 Nov 2007 06:23:22 -0000 1.9
> +++ compiler/ssdebug.m 8 Nov 2007 02:15:02 -0000
> @@ -266,35 +256,41 @@
> - %
> - % Generate the call to handle_event_exit(ProcId, VarList).
> - %
> - make_handle_event("exit", [ProcIdVar, ExitArgListVar],
> - HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
> + % Create DoRetry output variable
Full stop.
> + make_retry_var("", RetryVar, !Varset, !Vartypes),
See later.
>
> + % Generate the call to handle_event_exit(ProcId, VarList, DoRetry).
> + make_handle_event("exit", [ProcIdVar, ExitArgListVar, RetryVar],
> + HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
>
> - %
> + % Generate the recursive call in the case of a retry
> + make_recursive_call(!.PredInfo, !.ModuleInfo, PredId, ProcId, HeadVars,
> + HeadGoal),
Rename HeadGoal.
> +
> % Organize the order of the generated code.
> % XXX Need optimization in list append.
> goal_to_conj_list(BodyGoal1, BodyGoalList),
> - ConjGoals = ProcIdGoals ++ CallArgListGoals ++
> - [HandleEventCallGoal] ++ BodyGoalList ++ ExitArgListGoals ++
> - [HandleEventExitGoal | RenamingGoals],
> -
> % Set the determinism.
> Determinism = detism_det,
> goal_info_init(GoalInfo0),
> goal_info_set_determinism(Determinism, GoalInfo0, GoalInfo),
> -
> +
> + conj_list_to_goal(RenamingGoals, GoalInfo, RenamingGoal),
> + % Create the switch on Retry at exit port.
> + make_switch_call(RetryVar, HeadGoal, RenamingGoal, GoalInfo,
> + SwitchGoal),
> +
> + ConjGoals = ProcIdGoals ++ CallArgListGoals ++
> + [HandleEventCallGoal | BodyGoalList] ++ ExitArgListGoals ++
> + [HandleEventExitGoal, SwitchGoal],
> +
> conj_list_to_goal(ConjGoals, GoalInfo, GoalWithoutPurity),
>
> % Add the purity scope.
> @@ -364,46 +348,61 @@
> + % Create DoRetryA output variable
> + make_retry_var("A", RetryAVar, !Varset, !Vartypes),
>
> - %
> - % Generate the call to handle_event_exit(ProcId, VarList).
> - %
> - make_handle_event("exit", [ProcIdVar, ExitArgListVar],
> + % Generate the call to handle_event_exit(ProcId, VarList, DoRetryA).
> + make_handle_event("exit", [ProcIdVar, ExitArgListVar, RetryAVar],
> HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
>
> + % Generate the recursive call in the case of a retry
> + make_recursive_call(!.PredInfo, !.ModuleInfo, PredId, ProcId, HeadVars,
> + HeadGoal),
>
> - %
> % Generate the list of arguments at the fail port.
> - %
> make_arg_list(0, InitInstMap, [], Renaming, FailArgListVar,
> FailArgListGoals, !ModuleInfo, !ProcInfo, !PredInfo, !Varset,
> !Vartypes, BoundVarDescsAtCall, _BoundVarDescsAtFail),
>
> - %
> - % Generate the call to handle_event_fail(ProcId, VarList).
> - %
> - make_handle_event("fail", [ProcIdVar, FailArgListVar],
> + % Create DoRetryA output variable
> + make_retry_var("B", RetryBVar, !Varset, !Vartypes),
> +
> + % Generate the call to handle_event_fail(ProcId, VarList, DoRetryB).
> + make_handle_event("fail", [ProcIdVar, FailArgListVar, RetryBVar],
> HandleEventFailGoal, !ModuleInfo, !Varset, !Vartypes),
>
> make_fail_call(FailGoal, !.ModuleInfo),
>
> - %
> % Organize the order of the generated code.
> % XXX Need optimization in list append.
>
> % Get a flattened goal to avoid nested conjuction.
> goal_to_conj_list(BodyGoal1, BodyGoalList),
> GoalsCond = BodyGoalList,
> - GoalsThen = ExitArgListGoals ++ [HandleEventExitGoal| RenamingGoals],
> - GoalsElse = FailArgListGoals ++ [HandleEventFailGoal, FailGoal],
> +
> + % Create the switch on DoRetryA at exit port.
> + Determinism = detism_det,
> + goal_info_init(GoalInfo1),
> + goal_info_set_determinism(Determinism, GoalInfo1, GoalInfo),
> + conj_list_to_goal(RenamingGoals, GoalInfo, RenamingGoal),
> + make_switch_call(RetryAVar, HeadGoal, RenamingGoal, GoalInfo,
> + SwitchExitPortGoal),
> +
> + % Create the switch on DoRetryB at fail port.
> + make_switch_call(RetryBVar, HeadGoal, FailGoal, GoalInfo,
> + SwitchFailPortGoal),
> +
> + GoalsThen = ExitArgListGoals ++
> + [HandleEventExitGoal, SwitchExitPortGoal],
> + GoalsElse = FailArgListGoals ++
> + [HandleEventFailGoal, SwitchFailPortGoal],
>
> goal_info_init(GoalInfo0),
> goal_list_determinism(GoalsCond, Detism),
> @@ -426,10 +425,6 @@
> GoalWithoutPurity = hlds_goal(conj(plain_conj, ConjGoal),
> GoalInfoCond),
>
> - Determinism = detism_det,
> - goal_info_init(GoalInfo1),
> - goal_info_set_determinism(Determinism, GoalInfo1, GoalInfo),
> -
> % Add the purity scope.
> Purity = goal_info_get_purity(BodyGoalInfo0),
> wrap_with_purity_scope(Purity, GoalInfo, GoalWithoutPurity, Goal),
> @@ -497,43 +480,38 @@
> +
> + % Create DoRetryA output variable
> + make_retry_var("A", RetryAVar, !Varset, !Vartypes),
>
> - %
> - % Generate the call to handle_event_exit(ProcId, VarList).
> - %
> - make_handle_event("exit", [ProcIdVar, ExitArgListVar],
> + % Generate the call to handle_event_exit(ProcId, VarList, DoRetryA).
> + make_handle_event("exit", [ProcIdVar, ExitArgListVar, RetryAVar],
> HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
>
> - %
> % Generate the call to handle_event_redo(ProcId, VarList).
> - %
> make_handle_event("redo", [ProcIdVar, ExitArgListVar],
> HandleEventRedoGoal, !ModuleInfo, !Varset, !Vartypes),
>
> - %
> % Generate the list of argument at the fail port.
> - %
> make_arg_list(0, InitInstMap, [], Renaming, FailArgListVar,
> FailArgListGoals, !ModuleInfo, !ProcInfo, !PredInfo, !Varset,
> !Vartypes, BoundVarDescsAtCall, _BoundVarDescsAtFail),
>
> - %
> - % Generate the call to handle_event_fail(ProcId, VarList).
> - %
> - make_handle_event("fail", [ProcIdVar, FailArgListVar],
> + % Create DoRetryB output variable
> + make_retry_var("B", RetryBVar, !Varset, !Vartypes),
> +
> + % Generate the call to handle_event_fail(ProcId, VarList, DoRetryB).
> + make_handle_event("fail", [ProcIdVar, FailArgListVar, RetryBVar],
> HandleEventFailGoal, !ModuleInfo, !Varset, !Vartypes),
>
> make_fail_call(FailGoal, !.ModuleInfo),
>
> @@ -541,29 +519,45 @@
> goal_to_conj_list(BodyGoal1, BodyGoalList1),
> CallVarGoal0 = CallArgListGoals ++
> [HandleEventCallGoal | BodyGoalList1] ++ ExitArgListGoals,
> - goal_info_init(GoalInfo),
> - conj_list_to_goal(CallVarGoal0, GoalInfo, CallVarGoal1),
> + goal_info_init(GoalInfo0),
> + conj_list_to_goal(CallVarGoal0, GoalInfo0, CallVarGoal1),
> goal_to_conj_list(CallVarGoal1, CallVarGoal),
>
> + % Generate the recursive call in the case of a retry
> + make_recursive_call(!.PredInfo, !.ModuleInfo, PredId, ProcId, HeadVars,
> + HeadGoal),
> +
> + % Create the switch on DoRetryA at exit port.
> + Determinism = detism_det,
> + goal_info_set_determinism(Determinism, GoalInfo0, GoalInfo),
> + conj_list_to_goal(RenamingGoals, GoalInfo, RenamingGoal),
> + make_switch_call(RetryAVar, HeadGoal, RenamingGoal, GoalInfo,
> + SwitchExitPortGoal),
> +
> + % Create the switch on DoRetryB at fail port.
> + make_switch_call(RetryBVar, HeadGoal, FailGoal, GoalInfo,
> + SwitchFailPortGoal),
> +
> ConjGoal11 = hlds_goal(conj(plain_conj,
> - [HandleEventExitGoal| RenamingGoals]), GoalInfo),
> + [HandleEventExitGoal, SwitchExitPortGoal]), GoalInfo0),
> ConjGoal120 = hlds_goal(conj(plain_conj,
> - [HandleEventRedoGoal, FailGoal]), GoalInfo),
> + [HandleEventRedoGoal, FailGoal]), GoalInfo0),
> goal_add_feature(feature_preserve_backtrack_into, ConjGoal120,
> ConjGoal12),
> - DisjGoal1 = hlds_goal(disj([ConjGoal11, ConjGoal12]), GoalInfo),
> + DisjGoal1 = hlds_goal(disj([ConjGoal11, ConjGoal12]), GoalInfo0),
>
> ConjGoal21 = hlds_goal(conj(plain_conj,
> - CallVarGoal ++ [DisjGoal1]), GoalInfo),
> + CallVarGoal ++ [DisjGoal1]), GoalInfo0),
> ConjGoal220 = hlds_goal(conj(plain_conj,
> - FailArgListGoals ++ [HandleEventFailGoal, FailGoal]), GoalInfo),
> + FailArgListGoals ++ [HandleEventFailGoal, SwitchFailPortGoal]),
> + GoalInfo0),
> goal_add_feature(feature_preserve_backtrack_into, ConjGoal220,
> ConjGoal22),
> DisjGoal2 = hlds_goal(disj([ConjGoal21, ConjGoal22]),
> - GoalInfo),
> + GoalInfo0),
>
> GoalWithoutPurity = hlds_goal(conj(plain_conj,
> - ProcIdGoals ++ [DisjGoal2]), GoalInfo),
> + ProcIdGoals ++ [DisjGoal2]), GoalInfo0),
>
> % Add the purity scope.
> Purity = goal_info_get_purity(BodyGoalInfo0),
> @@ -572,9 +566,64 @@
> commit_goal_changes(Goal, PredId, ProcId, !.PredInfo, !ProcInfo,
> !ModuleInfo, !.Varset, !.Vartypes)
> ).
> -
>
> +
> + %
> + % Create the output variable DoRetry.
> %
> +:- pred make_retry_var(string::in, prog_var::out,
> + prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
> +
> +make_retry_var(String, RetryVar, !VarSet, !VarTypes) :-
> + SSDBModule = mercury_ssdb_builtin_module,
> + TypeCtor = type_ctor(qualified(SSDBModule, "ssdb_retry"), 0),
> + construct_type(TypeCtor, [], RetryType),
> + Name = "DoRetry" ++ String,
Pass the full variable name to this predicate.
> + svvarset.new_named_var(Name, RetryVar, !VarSet),
> + svmap.det_insert(RetryVar, RetryType, !VarTypes).
> +
> +
> + %
> + % Create the goal for recursive call in the case of a retry.
> + %
> +:- pred make_recursive_call(pred_info::in, module_info::in, pred_id::in,
> + proc_id::in, list(prog_var)::in, hlds_goal::out) is det.
> +
> +make_recursive_call(PredInfo, ModuleInfo, PredId, ProcId, HeadVars,
> + Goal) :-
Indent.
> + PredName = pred_info_name(PredInfo),
> + ModuleName = pred_info_module(PredInfo),
> + SymName = qualified(ModuleName, PredName),
> + BuiltIn = builtin_state(ModuleInfo, PredId, PredId, ProcId),
> + GoalExpr = plain_call(PredId, ProcId, HeadVars, BuiltIn, no,
> + SymName),
> + goal_info_init(GoalInfoHG),
> + Goal = hlds_goal(GoalExpr, GoalInfoHG).
> +
> +
> + %
> + % make_switch_call(SwitchVar, SwitchCase1, SwitchCase2, GoalInfo, Goal).
> + %
> + % Create the switch Goal.
> + %
> +:- pred make_switch_call(prog_var::in, hlds_goal::in, hlds_goal::in,
> + hlds_goal_info::in, hlds_goal::out) is det.
Rename this predicate and improve the comment.
> +
> +make_switch_call(SwitchVar, DoRetryGoal, DoNotRetryGoal, GoalInfo,
> + SwitchGoal) :-
Indent.
> Index: ssdb/ssdb.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/ssdb/ssdb.m,v
> retrieving revision 1.9
> diff -u -r1.9 ssdb.m
> --- ssdb/ssdb.m 1 Nov 2007 06:23:22 -0000 1.9
> +++ ssdb/ssdb.m 8 Nov 2007 02:15:02 -0000
> @@ -35,6 +35,13 @@
> ; ssdb_fail
> .
>
> +
> +:- type ssdb_retry
> + ---> do_retry
> + ; do_not_retry
> + .
> +
> +
> %
> % The list of all variables in use in a procedure.
> %
> @@ -68,12 +75,14 @@
> %
> % This routine is called at each exit event that occurs.
> %
> -:- impure pred handle_event_exit(ssdb_proc_id::in, list_var_value::in) is det.
> +:- impure pred handle_event_exit(ssdb_proc_id::in, list_var_value::in,
> + ssdb_retry::out) is det.
>
> %
> % This routine is called at each fail event that occurs.
> %
> -:- impure pred handle_event_fail(ssdb_proc_id::in, list_var_value::in) is det.
> +:- impure pred handle_event_fail(ssdb_proc_id::in, list_var_value::in,
> + ssdb_retry::out) is det.
>
> %
> % This routine is called at each redo event that occurs.
> @@ -136,7 +146,14 @@
> ---> wn_step
> ; wn_next
> ; wn_continue
> - ; wn_finish(int).
> + ; wn_finish(int)
> + ; wn_retry(int).
> +
> +:- inst what_next_no_retry
> + ---> wn_step
> + ; wn_next
> + ; wn_continue
> + ; wn_finish(ground).
>
>
> %
> @@ -147,7 +164,7 @@
> ---> ns_step
> ; ns_next(int)
> ; ns_continue
> - ; ns_final_port(int).
> + ; ns_final_port(int, ssdb_retry).
Explain what the arguments are.
> @@ -260,11 +278,17 @@
> print_event_info(Event, EventNum, ProcId, PrintDepth, CSN, !IO),
>
> semipure get_shadow_stack(ShadowStack),
> - impure prompt(Event, ShadowStack, 0, WhatNext, !IO),
> + (
> + AutoRetry = do_retry
> + ->
> + WhatNext = wn_retry(CSN)
> + ;
> + impure prompt(Event, ShadowStack, 0, WhatNext, !IO)
> + ),
Use a switch.
> @@ -295,7 +320,7 @@
>
> CSN = StackFrame ^ se_initial_state ^ ssdb_csn,
>
> - set_stop(Event, CSN, State0, ProcId, Stop),
> + set_stop(Event, CSN, State0, ProcId, Stop, AutoRetry),
> (
> Stop = yes,
> some [!IO]
> @@ -305,11 +330,17 @@
> print_event_info(Event, EventNum, ProcId, PrintDepth, CSN, !IO),
>
> semipure get_shadow_stack(ShadowStack),
> - impure prompt(Event, ShadowStack, 0, WhatNext, !IO),
> + (
> + AutoRetry = do_retry
> + ->
> + WhatNext = wn_retry(CSN)
> + ;
> + impure prompt(Event, ShadowStack, 0, WhatNext, !IO)
> + ),
Switch.
> @@ -490,17 +557,19 @@
> % Set Stop, if Stop equals yes, we will call the prompt.
> %
> :- pred set_stop(ssdb_event_type::in, int::in, debugger_state::in,
> - ssdb_proc_id::in, bool::out) is det.
> + ssdb_proc_id::in, bool::out, ssdb_retry::out) is det.
>
> -set_stop(Event, CSN, State, ProcId, ShouldStopAtEvent) :-
> +set_stop(Event, CSN, State, ProcId, ShouldStopAtEvent, AutoRetry) :-
This predicate should be renamed.
> @@ -527,6 +597,58 @@
> ).
>
>
> + %
> + % set_next_stop(CSN, WhatNext, ShadowStack, NextStop, Retry).
> + %
> + % Set the NextStop and the Retry variable according to the WhatNext value.
> + % In the case where the WathNext is set for a retry, it modify the
> + % debugger_state at his old value which it had at the call point.
> + %
> +:- impure pred set_next_stop(int::in, what_next::in, stack(stack_elem)::in,
> + next_stop::out, ssdb_retry::out) is det.
> +
Try to name that better.
> +set_next_stop(CSN, WhatNext, ShadowStack, NextStop, Retry) :-
> + (
> + WhatNext = wn_step,
> + NextStop = ns_step,
> + Retry = do_not_retry
> + ;
> + WhatNext = wn_next,
> + NextStop = ns_next(CSN),
> + Retry = do_not_retry
> + ;
> + WhatNext = wn_continue,
> + NextStop = ns_continue,
> + Retry = do_not_retry
> + ;
> + WhatNext = wn_finish(EndCSN),
> + NextStop = ns_final_port(EndCSN, do_not_retry),
> + Retry = do_not_retry
> + ;
> + WhatNext = wn_retry(RetryCSN),
> + (
> + RetryCSN = CSN
> + ->
> + NextStop = ns_step,
> + Retry = do_retry,
> + % Set the debugger state for the retry
> + stack.top_det(ShadowStack, FrameStack),
> + SetCSN0 = FrameStack ^ se_initial_state ^ ssdb_csn,
> + SetEventNum0 = FrameStack ^ se_initial_state ^ ssdb_event_number,
> + SetCSN = SetCSN0 - 1,
> + SetEventNum = SetEventNum0 - 1,
> + impure set_csn(SetCSN),
> + impure set_event_num(SetEventNum)
You don't need those extra variables.
> @@ -697,6 +804,18 @@
> impure prompt(Event, ShadowStack, Depth, WhatNext, !IO)
> )
>
> + ; Words = ["r"] ->
> + (
> + ( Event = ssdb_exit
> + ; Event = ssdb_fail
> + ) ->
> + stack.top_det(ShadowStack, FrameStack),
> + CSN = FrameStack ^ se_initial_state ^ ssdb_csn,
> + WhatNext = wn_retry(CSN)
> + ;
> + io.write_string("Impossible at call or redo port\n", !IO),
> + impure prompt(Event, ShadowStack, Depth, WhatNext, !IO)
> + )
Switch.
Peter
--------------------------------------------------------------------------
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