[m-rev.] for review: add agc tracing code to exception.m
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed Jun 5 01:18:04 AEST 2002
Estimated hours taken: 4
Branches: main
library/exception.m:
For accurate garbage collection, add code to trace the local
variables in the hand-coded C builtin_catch_*() functions.
Workspace: /home/ceres/fjh/mercury
Index: library/exception.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.60
diff -u -d -r1.60 exception.m
--- library/exception.m 28 Mar 2002 03:44:40 -0000 1.60
+++ library/exception.m 3 Jun 2002 05:14:01 -0000
@@ -777,6 +777,10 @@
MR_Univ exception;
} ML_ExceptionHandler;
+/*
+** XXX This is currently not thread-safe!
+** The ML_exception_handler variable should be thread-local.
+*/
ML_ExceptionHandler *ML_exception_handler;
void MR_CALL
@@ -795,15 +799,93 @@
}
}
+#ifdef MR_NATIVE_GC
+
+/*
+** The following code is needed to trace the local variables
+** in the builtin_catch_* functions for accurate GC.
+*/
+
+struct mercury__exception__builtin_catch_locals {
+ /* fixed fields, from struct MR_StackChain */
+ struct MR_StackChain *prev;
+ void (*trace)(void *this_frame);
+ /* locals for this function */
+ MR_Mercury_Type_Info type_info;
+ MR_Pred handler_pred;
+};
+
+static void
+mercury__exception__builtin_catch_gc_trace(void *frame)
+{
+ struct mercury__exception__builtin_catch_locals *agc_locals = frame;
+ /*
+ ** Construct a type_info for the type `pred(univ, T)',
+ ** which is the type of the handler_pred.
+ */
+ MR_VAR_ARITY_TYPEINFO_STRUCT(s, 2) type_info_for_handler_pred;
+ type_info_for_handler_pred.MR_ti_type_ctor_info =
+ &mercury__builtin__builtin__type_ctor_info_pred_0;
+ type_info_for_handler_pred.MR_ti_var_arity_arity = 2;
+ type_info_for_handler_pred.MR_ti_var_arity_arg_typeinfos[0] =
+ (MR_TypeInfo)
+ &mercury__std_util__std_util__type_ctor_info_univ_0;
+ type_info_for_handler_pred.MR_ti_var_arity_arg_typeinfos[1] =
+ (MR_TypeInfo) agc_locals->type_info;
+ /*
+ ** Call gc_trace/1 to trace the two local variables in this frame.
+ */
+ mercury__private_builtin__gc_trace_1_p_0(
+ (MR_Word)
+ &mercury__type_desc__type_desc__type_ctor_info_type_desc_0,
+ (MR_Word) &agc_locals->type_info);
+ mercury__private_builtin__gc_trace_1_p_0(
+ (MR_Word) &type_info_for_handler_pred,
+ (MR_Word) &agc_locals->handler_pred);
+}
+
+ #define MR_DECLARE_AGC_HANDLER \
+ struct mercury__exception__builtin_catch_locals agc_locals;
+
+ #define MR_INSTALL_AGC_HANDLER(TYPE_INFO, HANDLER_PRED) \
+ do { \
+ agc_locals.prev = mercury__private_builtin__stack_chain; \
+ agc_locals.trace = mercury__exception__builtin_catch_gc_trace; \
+ agc_locals.type_info = (TYPE_INFO); \
+ agc_locals.handler_pred = (HANDLER_PRED); \
+ mercury__private_builtin__stack_chain = &agc_locals; \
+ } while(0);
+
+ #define MR_UNINSTALL_AGC_HANDLER() \
+ do { \
+ mercury__private_builtin__stack_chain = ((struct MR_StackChain *) \
+ mercury__private_builtin__stack_chain)->prev; \
+ } while (0)
+
+ #define MR_AGC_LOCAL(NAME) (agc_locals.NAME)
+
+#else /* !MR_NATIVE_GC */
+
+ /* If accurate GC is not enabled, we define all of these as NOPs. */
+ #define MR_DECLARE_AGC_HANDLER
+ #define MR_INSTALL_AGC_HANDLER(type_info, handler_pred)
+ #define MR_UNINSTALL_AGC_HANDLER()
+ #define MR_AGC_LOCAL(name) (name)
+
+#endif /* !MR_NATIVE_GC */
+
void MR_CALL
mercury__exception__builtin_catch_model_det(MR_Mercury_Type_Info type_info,
MR_Pred pred, MR_Pred handler_pred, MR_Box *output)
{
ML_ExceptionHandler this_handler;
-
+ MR_DECLARE_AGC_HANDLER
+
this_handler.prev = ML_exception_handler;
ML_exception_handler = &this_handler;
+ MR_INSTALL_AGC_HANDLER(type_info, handler_pred);
+
#ifdef MR_DEBUG_JMPBUFS
fprintf(stderr, ""detcatch setjmp %p\\n"", this_handler.handler);
#endif
@@ -811,6 +893,7 @@
if (setjmp(this_handler.handler) == 0) {
ML_call_goal_det_handcoded(type_info, pred, output);
ML_exception_handler = this_handler.prev;
+ MR_UNINSTALL_AGC_HANDLER();
} else {
#ifdef MR_DEBUG_JMPBUFS
fprintf(stderr, ""detcatch caught jmp %p\\n"",
@@ -818,7 +901,9 @@
#endif
ML_exception_handler = this_handler.prev;
- ML_call_handler_det_handcoded(type_info, handler_pred,
+ MR_UNINSTALL_AGC_HANDLER();
+ ML_call_handler_det_handcoded(
+ MR_AGC_LOCAL(type_info), MR_AGC_LOCAL(handler_pred),
this_handler.exception, output);
}
}
@@ -828,10 +913,13 @@
MR_Pred pred, MR_Pred handler_pred, MR_Box *output)
{
ML_ExceptionHandler this_handler;
+ MR_DECLARE_AGC_HANDLER
this_handler.prev = ML_exception_handler;
ML_exception_handler = &this_handler;
+ MR_INSTALL_AGC_HANDLER(type_info, handler_pred);
+
#ifdef MR_DEBUG_JMPBUFS
fprintf(stderr, ""semicatch setjmp %p\\n"", this_handler.handler);
#endif
@@ -840,6 +928,7 @@
MR_bool result = ML_call_goal_semi_handcoded(type_info, pred,
output);
ML_exception_handler = this_handler.prev;
+ MR_UNINSTALL_AGC_HANDLER();
return result;
} else {
#ifdef MR_DEBUG_JMPBUFS
@@ -848,7 +937,9 @@
#endif
ML_exception_handler = this_handler.prev;
- ML_call_handler_det_handcoded(type_info, handler_pred,
+ MR_UNINSTALL_AGC_HANDLER();
+ ML_call_handler_det_handcoded(
+ MR_AGC_LOCAL(type_info), MR_AGC_LOCAL(handler_pred),
this_handler.exception, output);
return MR_TRUE;
}
@@ -862,6 +953,7 @@
MR_NestedCont cont)
{
ML_ExceptionHandler this_handler;
+ MR_DECLARE_AGC_HANDLER
auto void MR_CALL success_cont(void);
void MR_CALL success_cont(void) {
@@ -886,6 +978,8 @@
this_handler.prev = ML_exception_handler;
ML_exception_handler = &this_handler;
+ MR_INSTALL_AGC_HANDLER(type_info, handler_pred);
+
#ifdef MR_DEBUG_JMPBUFS
fprintf(stderr, ""noncatch setjmp %p\\n"", this_handler.handler);
#endif
@@ -894,6 +988,7 @@
ML_call_goal_non_handcoded(type_info, pred, output,
success_cont);
ML_exception_handler = this_handler.prev;
+ MR_UNINSTALL_AGC_HANDLER();
} else {
#ifdef MR_DEBUG_JMPBUFS
fprintf(stderr, ""noncatch caught jmp %p\\n"",
@@ -901,7 +996,9 @@
#endif
ML_exception_handler = this_handler.prev;
- ML_call_handler_det_handcoded(type_info, handler_pred,
+ MR_UNINSTALL_AGC_HANDLER();
+ ML_call_handler_det_handcoded(
+ MR_AGC_LOCAL(type_info), MR_AGC_LOCAL(handler_pred),
this_handler.exception, output);
(*cont)();
}
@@ -942,6 +1039,7 @@
MR_Pred pred, MR_Pred handler_pred, MR_Box *output,
MR_Cont cont, void *cont_env)
{
+ MR_DECLARE_AGC_HANDLER
struct ML_catch_env locals;
locals.cont = cont;
locals.cont_env = cont_env;
@@ -949,6 +1047,8 @@
locals.this_handler.prev = ML_exception_handler;
ML_exception_handler = &locals.this_handler;
+ MR_INSTALL_AGC_HANDLER(type_info, handler_pred);
+
#ifdef MR_DEBUG_JMPBUFS
fprintf(stderr, ""noncatch setjmp %p\\n"", locals.this_handler.handler);
#endif
@@ -963,6 +1063,7 @@
** handler
*/
ML_exception_handler = locals.this_handler.prev;
+ MR_UNINSTALL_AGC_HANDLER();
return;
} else {
/*
@@ -979,7 +1080,9 @@
ML_exception_handler = locals.this_handler.prev;
- ML_call_handler_det_handcoded(type_info, handler_pred,
+ MR_UNINSTALL_AGC_HANDLER();
+ ML_call_handler_det_handcoded(
+ MR_AGC_LOCAL(type_info), MR_AGC_LOCAL(handler_pred),
locals.this_handler.exception, output);
cont(cont_env);
}
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list