diff: AGC: round 2.
Tyson Dowd
trd at cs.mu.OZ.AU
Fri Jul 3 16:56:05 AEST 1998
Here's a diff relative to my previous changes.
I've addressed the concerns raised in the review.
(there are a few indenting problems in mercury_deep_copy_body.h in
this diff, please ignore them I'll fix them before committing).
===================================================================
Estimated hours taken: 70
An initial implementation of the accurate garbage collector.
library/builtin.m:
library/mercury_builtin.m:
library/std_util.m:
runtime/mercury_tabling.h:
Deep copy terms using the address of the value instead of
just the value.
library/io.m:
Initialize the garbage rootset with the globals.
runtime/Mmakefile:
Add new files to the Mmakefile.
runtime/mercury_accurate_gc.h:
runtime/mercury_accurate_gc.c:
The new garbage collector.
runtime/mercury_agc_debug.c:
runtime/mercury_agc_debug.h:
Debugging utilities for the new garbage collector.
runtime/mercury_deep_copy.c:
runtime/mercury_deep_copy.h:
runtime/mercury_deep_copy_body.h:
Put the deep copy code in mercury_deep_copy_body.h, and #include
it with appropriate #defines in order to get a variant for
deep_copy(), and one for agc_deep_copy().
agc_deep_copy() forwards pointers as it copies.
Also, deep_copy (all variants) have been modified to take
a pointer to the data to be copied, because some variants
need to be able to modify it.
runtime/mercury_engine.c:
runtime/mercury_engine.h:
Add a second heap_zone which is the to-space of
the copying collector.
Add a debug_heap_zone, which is used as a scratch
heap for debugging.
runtime/mercury_goto.h:
runtime/mercury_label.c:
runtime/mercury_label.h:
Keep track of which labels are entry labels, and which ones
aren't. (This is a temporary change, until Zoltan commits
his dual label tables).
runtime/mercury_imp.h:
Include mercury_debug.h before most of the modules.
(mercury_engine.h adds a new MemoryZone only if we are
debugging accurate GC).
runtime/mercury_memory.c:
Setup the debug_memory_zone sizes.
Remove an unnecessary prototype.
runtime/mercury_memory_handlers.c:
Add code to get the program counter and the stack pointer
from the signal context.
Call MR_schedule_agc() from default_handler() if doing accurate gc.
runtime/mercury_memory_zones.c:
Setup the hardzone regardless of whether redzones are used.
Add some more debugging information.
runtime/mercury_regorder.h:
runtime/machdeps/alpha_regs.h:
runtime/machdeps/i386_regs.h:
Add definitions to make the real machine registers name/number
for MR_sp available.
runtime/mercury_trace_internal.c:
runtime/mercury_trace_util.c:
runtime/mercury_trace_util.h:
Add MR_trace_write_variable(), which writes terms given their
value and type_info.
runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
Change the size of the heap redzone when doing accurate GC.
Use a small heap when debugging agc.
runtime/mercury_debug.h:
runtime/mercury_conf_param.h:
Add new debugging macros and document them.
runtime/mercury_type_info.c:
Add const to the pointer arguments of MR_make_type_info.
===================================================================
diff -u runtime2/mercury_accurate_gc.c runtime/mercury_accurate_gc.c
--- runtime2/mercury_accurate_gc.c Tue Jun 30 14:10:40 1998
+++ runtime/mercury_accurate_gc.c Fri Jul 3 15:22:33 1998
@@ -8,16 +8,17 @@
** This module contains the accurate garbage collector.
*/
+#include "mercury_imp.h"
+
#ifdef NATIVE_GC
-#include "mercury_imp.h"
#include "mercury_trace_util.h"
#include "mercury_deep_copy.h"
#include "mercury_agc_debug.h"
- /*
- ** Function prototypes.
- */
+/*
+** Function prototypes.
+*/
static void garbage_collect(Code *saved_success, Word *stack_pointer, Word
*current_frame);
static void garbage_collect_roots(void);
@@ -26,38 +27,38 @@
static void copy_value(MR_Live_Lval locn, Word *type_info, bool copy_regs,
Word *stack_pointer, Word *current_frame);
- /*
- ** Global variables (only used in this module, however).
- */
+/*
+** Global variables (only used in this module, however).
+*/
static Code *saved_success = (Code *) NULL;
static Word *saved_success_location = (Word *) NULL;
static bool gc_scheduled = FALSE;
static bool gc_running = FALSE;
- /* The list of roots */
+/* The list of roots */
static MR_RootList root_list = NULL;
- /* The last root on the list */
+/* The last root on the list */
static MR_RootList last_root = NULL;
Define_extern_entry(mercury__garbage_collect_0_0);
- /*
- ** MR_schedule_agc:
- ** Schedule garbage collection.
- **
- ** We do this by replacing the succip that is saved in
- ** the current procedure's stack frame with the address
- ** of the garbage collector. When the current procedure
- ** returns, it will call the garbage collectior.
- **
- ** (We go to this trouble because then the stacks will
- ** be in a known state -- each stack frame is described
- ** by information associated with the continuation label
- ** that the code will return to).
- */
+/*
+** MR_schedule_agc:
+** Schedule garbage collection.
+**
+** We do this by replacing the succip that is saved in
+** the current procedure's stack frame with the address
+** of the garbage collector. When the current procedure
+** returns, it will call the garbage collectior.
+**
+** (We go to this trouble because then the stacks will
+** be in a known state -- each stack frame is described
+** by information associated with the continuation label
+** that the code will return to).
+*/
void
MR_schedule_agc(Code *pc_at_signal, Word *sp_at_signal)
{
@@ -70,18 +71,16 @@
int determinism, number;
if (gc_running) {
- /*
- ** This is bad news, but it can happen if
- ** you don't collect any garbage.
- ** We should try to avoid it by resizing
- ** the heaps so they don't become too full.
- **
- ** It might also be worthwhile eventually
- ** turning off the redzone in the destination
- ** heap (but only when the large problem of
- ** handling collections with little garbage
- ** has been solved).
- */
+ /*
+ ** This is bad news, but it can happen if you don't
+ ** collect any garbage. We should try to avoid it by
+ ** resizing the heaps so they don't become too full.
+ **
+ ** It might also be worthwhile eventually turning off
+ ** the redzone in the destination heap (but only when
+ ** the large problem of handling collections with little
+ ** garbage has been solved).
+ */
fprintf(stderr, "Garbage collection scheduled while "
"collector is already running\n");
@@ -97,13 +96,13 @@
fflush(NULL);
#endif
- /* Search for the entry label */
+ /* Search for the entry label */
label = lookup_label_addr(pc_at_signal);
while (label == NULL || label->e_layout == NULL) {
/*
- ** Linear search through the label table
- ** (should be replaced with a binary search through
- ** a different table).
+ ** Linear search through the label table (should be
+ ** replaced with a binary search through a different
+ ** table).
*/
pc_at_signal = (Code *) ((Word) pc_at_signal - 1);
label = lookup_label_addr(pc_at_signal);
@@ -135,10 +134,10 @@
fflush(NULL);
#endif
- /*
- ** If we have already scheduled a garbage collection,
- ** undo the last change, and do a new one.
- */
+ /*
+ ** If we have already scheduled a garbage collection, undo the
+ ** last change, and do a new one.
+ */
if (gc_scheduled) {
#ifdef MR_DEBUG_AGC_SCHEDULING
fprintf(stderr, "GC scheduled again. Replacing old scheduling,"
@@ -157,9 +156,9 @@
fatal_error("can only handle stackvars");
}
- /*
- ** Save the old succip and its location.
- */
+ /*
+ ** Save the old succip and its location.
+ */
saved_success_location = (Word *) sp_at_signal - number;
saved_success = (Code *) *saved_success_location;
@@ -171,10 +170,10 @@
(long) ENTRY(mercury__garbage_collect_0_0));
#endif
- /*
- ** Replace the old succip with the address
- ** of the garbage collector.
- */
+ /*
+ ** Replace the old succip with the address of the
+ ** garbage collector.
+ */
*saved_success_location = (Word) mercury__garbage_collect_0_0;
} else {
@@ -193,12 +192,12 @@
BEGIN_MODULE(native_gc)
BEGIN_CODE
- /*
- ** Our garbage collection entry label.
- **
- ** It saves the registers -- we use the saved registers
- ** for garbage collection and leave the real ones alone.
- */
+/*
+** Our garbage collection entry label.
+**
+** It saves the registers -- we use the saved registers
+** for garbage collection and leave the real ones alone.
+*/
Define_entry(mercury__garbage_collect_0_0);
/* record that the collector is running */
@@ -218,13 +217,13 @@
/*---------------------------------------------------------------------------*/
- /*
- ** garbage_collect:
- **
- ** The main garbage collection routine.
- **
- ** (We use 4 space tabs here because of the depth of indentation).
- */
+/*
+** garbage_collect:
+**
+** The main garbage collection routine.
+**
+** (We use 4 space tabs here because of the depth of indentation).
+*/
void
garbage_collect(Code *success_ip, Word *stack_pointer, Word *current_frame)
{
@@ -258,18 +257,18 @@
old_hp = MR_virtual_hp;
- /*
- ** The new heap pointer starts at the bottom of
- ** the new heap.
- */
+ /*
+ ** The new heap pointer starts at the bottom of
+ ** the new heap.
+ */
MR_virtual_hp = new_heap->min;
- /*
- ** Swap the two heaps (this just swaps them in
- ** the MR_ENGINE data structure -- we still have
- ** new_heap and old_heap that point to the
- ** new and old heaps).
- */
+ /*
+ ** Swap the two heaps (this just swaps them in
+ ** the MR_ENGINE data structure -- we still have
+ ** new_heap and old_heap that point to the
+ ** new and old heaps).
+ */
{
MemoryZone *tmp;
@@ -297,9 +296,9 @@
MR_agc_dump_roots(root_list);
#endif
- /*
- ** For each stack frame ...
- */
+ /*
+ ** For each stack frame ...
+ */
while (MR_DETISM_DET_STACK(entry_layout->MR_sle_detism)) {
#ifdef MR_DEBUG_AGC_COLLECTION
fprintf(stderr, "label: %s\n", label->e_name);
@@ -311,17 +310,17 @@
var_count = layout->MR_sll_var_count;
vars = &(layout->MR_sll_var_info);
- /*
- ** Get the type parameters from the stack frame.
- */
+ /*
+ ** Get the type parameters from the stack frame.
+ */
if (vars->MR_slvs_tvars != NULL) {
count = (int) (Integer) vars->MR_slvs_tvars[0];
type_params = checked_malloc((count + 1) * sizeof(Word));
- /*
- ** type_params should look like a typeinfo;
- ** type_params[0] is empty and will not be referred to
- */
+ /*
+ ** type_params should look like a typeinfo;
+ ** type_params[0] is empty and will not be referred to
+ */
for (i = 1; i <= count; i++) {
if (vars->MR_slvs_tvars[i] != 0) {
type_params[i] = get_live_lval(vars->MR_slvs_tvars[i],
@@ -335,9 +334,9 @@
type_params = NULL;
}
- /*
- ** Copy each live variable
- */
+ /*
+ ** Copy each live variable
+ */
for (i = 0; i < var_count; i++) {
MR_Stack_Layout_Var sl_var;
MR_Live_Type sl_type;
@@ -356,9 +355,9 @@
}
}
- /*
- ** Find the next stack frame.
- */
+ /*
+ ** Find the next stack frame.
+ */
{
MR_Live_Lval location;
MR_Lval_Type type;
@@ -370,7 +369,7 @@
if (type != MR_LVAL_TYPE_STACKVAR) {
fatal_error("can only handle stackvars");
}
- success_ip = (Code *) field(0, stack_pointer, -number);
+ success_ip = (Code *) based_detstackvar(stack_pointer, number);
stack_pointer = stack_pointer -
entry_layout->MR_sle_stack_slots;
}
@@ -381,9 +380,9 @@
entry_layout = layout->MR_sll_entry;
} /* end for each stack frame... */
- /*
- ** Copy any roots that are not on the stack.
- */
+ /*
+ ** Copy any roots that are not on the stack.
+ */
garbage_collect_roots();
#ifdef MR_DEBUG_AGC_COLLECTION
@@ -401,7 +400,7 @@
((char *) MR_virtual_hp - (char *) new_heap->min));
#endif
- /* Reset the redzone on the old heap */
+ /* Reset the redzone on the old heap */
reset_redzone(old_heap);
#ifdef MR_DEBUG_AGC_COLLECTION
@@ -410,16 +409,16 @@
}
- /*
- ** copy_value:
- ** Copies a value in a register or stack frame,
- ** replacing the original with the new copy.
- **
- ** The copying is done using agc_deep_copy, which is
- ** the accurate GC verison of deep_copy (it leaves
- ** forwarding pointers in the old copy of the data, if
- ** it is on the old heap).
- */
+/*
+** copy_value:
+** Copies a value in a register or stack frame,
+** replacing the original with the new copy.
+**
+** The copying is done using agc_deep_copy, which is
+** the accurate GC verison of deep_copy (it leaves
+** forwarding pointers in the old copy of the data, if
+** it is on the old heap).
+*/
void
copy_value(MR_Live_Lval locn, Word *type_info, bool copy_regs,
Word *stack_pointer, Word *current_frame)
@@ -441,10 +440,11 @@
break;
case MR_LVAL_TYPE_STACKVAR:
- stack_pointer[-locn_num] = agc_deep_copy(
- &stack_pointer[-locn_num], type_info,
- MR_ENGINE(heap_zone2->min),
- MR_ENGINE(heap_zone2->hardmax));
+ based_detstackvar(stack_pointer, locn_num) =
+ agc_deep_copy(&based_detstackvar(
+ stack_pointer,locn_num),
+ type_info, MR_ENGINE(heap_zone2->min),
+ MR_ENGINE(heap_zone2->hardmax));
break;
case MR_LVAL_TYPE_FRAMEVAR:
@@ -477,14 +477,14 @@
}
}
- /*
- ** get_live_lval:
- ** Retrieves the lval from the stack or registers and
- ** returns it. Succeeded is set to TRUE if the lval
- ** was a variable in a register or the stack, otherwise
- ** it is FALSE. If false, the data returned is meaningless
- ** and should not be used.
- */
+/*
+** get_live_lval:
+** Retrieves the lval from the stack or registers and
+** returns it. Succeeded is set to TRUE if the lval
+** was a variable in a register or the stack, otherwise
+** it is FALSE. If false, the data returned is meaningless
+** and should not be used.
+*/
Word
get_live_lval(MR_Live_Lval locn, Word *stack_pointer, Word *current_frame,
bool *succeeded)
@@ -540,14 +540,14 @@
return value;
}
- /*
- ** garbage_collect_roots:
- **
- ** Copies the extra roots. The roots are overwritten
- ** with the new data.
- */
+/*
+** garbage_collect_roots:
+**
+** Copies the extra roots. The roots are overwritten
+** with the new data.
+*/
void
-garbage_collect_roots()
+garbage_collect_roots(void)
{
MR_RootList current = root_list;
@@ -560,11 +560,11 @@
}
- /*
- ** MR_agc_add_root:
- **
- ** Adds a new root to the extra roots.
- */
+/*
+** MR_agc_add_root_internal:
+**
+** Adds a new root to the extra roots.
+*/
void
MR_agc_add_root(Word *root_addr, Word *type_info)
{
diff -u runtime2/mercury_accurate_gc.h runtime/mercury_accurate_gc.h
--- runtime2/mercury_accurate_gc.h Tue Jun 30 14:10:22 1998
+++ runtime/mercury_accurate_gc.h Fri Jul 3 14:52:26 1998
@@ -15,25 +15,25 @@
/*---------------------------------------------------------------------------*/
- /*
- ** MR_schedule_agc:
- ** Schedule a garbage collection as soon as possible. The
- ** PC (program counter) is used to find the procedure that
- ** is executing. The stack pointer is then used to replace
- ** the saved continuation pointer with the address of the
- ** garbage collector routine.
- */
+/*
+** MR_schedule_agc:
+** Schedule a garbage collection as soon as possible. The PC
+** (program counter) is used to find the procedure that is
+** executing. The stack pointer is then used to replace the saved
+** continuation pointer with the address of the garbage collector
+** routine.
+*/
extern void MR_schedule_agc(Code *pc_at_signal, Word *sp_at_signal);
- /*
- ** Roots apart from the stacks are stored in this data structure.
- **
- ** Essentially, this is a list of any pointers into the heap
- ** that are not stored on the heap or the det/nondet stacks.
- **
- ** Each node stores the address of the root, and its type.
- ** When a garbage collection occurs, the root will be modified.
- */
+/*
+** Roots apart from the stacks are stored in this data structure.
+**
+** Essentially, this is a list of any pointers into the heap that are
+** not stored on the heap or the det/nondet stacks.
+**
+** Each node stores the address of the root, and its type. When a
+** garbage collection occurs, the root will be modified.
+*/
struct MR_RootNode {
Word *root;
@@ -43,12 +43,12 @@
typedef struct MR_RootNode *MR_RootList;
- /*
- ** MR_agc_add_root:
- ** Adds the root whose address is supplied in root_addr
- ** with type described by type_info to the list of
- ** additional roots.
- */
+/*
+** MR_agc_add_root:
+** Adds the root whose address is supplied in root_addr with type
+** described by type_info to the list of additional roots.
+*/
+
extern void MR_agc_add_root(Word *root_addr, Word *type_info);
/*---------------------------------------------------------------------------*/
diff -u runtime2/mercury_agc_debug.c runtime/mercury_agc_debug.c
--- runtime2/mercury_agc_debug.c Tue Jun 30 15:38:37 1998
+++ runtime/mercury_agc_debug.c Fri Jul 3 15:19:44 1998
@@ -72,9 +72,9 @@
layout = (MR_Stack_Layout_Label *) label->e_layout;
entry_layout = layout->MR_sll_entry;
- /*
- ** For each stack frame...
- */
+ /*
+ ** For each stack frame...
+ */
while (MR_DETISM_DET_STACK(entry_layout->MR_sle_detism)) {
fprintf(stderr, " label: %s\n", label->e_name);
@@ -137,9 +137,9 @@
}
free(type_params);
- /*
- ** Move to the next stack frame.
- */
+ /*
+ ** Move to the next stack frame.
+ */
{
MR_Live_Lval location;
MR_Lval_Type type;
@@ -151,13 +151,15 @@
if (type != MR_LVAL_TYPE_STACKVAR) {
fatal_error("can only handle stackvars");
}
- success_ip = (Code *) field(0, stack_pointer, -number);
+
+ success_ip = (Code *)
+ based_detstackvar(stack_pointer, number);
stack_pointer = stack_pointer -
entry_layout->MR_sle_stack_slots;
label = lookup_label_addr(success_ip);
}
- top_frame = top_frame && FALSE;
+ top_frame = FALSE;
layout = (MR_Stack_Layout_Label *) label->e_layout;
entry_layout = layout->MR_sll_entry;
@@ -188,7 +190,7 @@
break;
case MR_LVAL_TYPE_STACKVAR:
- value = stack_pointer[-locn_num];
+ value = based_detstackvar(stack_pointer, locn_num);
have_value = TRUE;
fprintf(stderr, "stackvar%d", locn_num);
break;
diff -u runtime2/mercury_agc_debug.h runtime/mercury_agc_debug.h
--- runtime2/mercury_agc_debug.h Mon Jun 29 17:22:44 1998
+++ runtime/mercury_agc_debug.h Fri Jul 3 14:53:48 1998
@@ -14,23 +14,22 @@
/*---------------------------------------------------------------------------*/
- /*
- ** MR_agc_dump_stack_frames:
- ** Dump the stack, writing all information available about
- ** each stack frame.
- **
- ** label is the topmost label on the stack, heap_zone is
- ** the zone which the data is stored upon.
- */
+/*
+** MR_agc_dump_stack_frames:
+** Dump the stack, writing all information available about each
+** stack frame.
+**
+** label is the topmost label on the stack, heap_zone is the zone
+** which the data is stored upon.
+*/
extern void MR_agc_dump_stack_frames(Label *label, MemoryZone *heap_zone,
Word * stack_pointer, Word *current_frame);
- /*
- ** MR_agc_dump_roots:
- ** Dump the extra rootset, writing all information about
- ** each root.
- */
+/*
+** MR_agc_dump_roots:
+** Dump the extra rootset, writing all information about each root.
+*/
extern void MR_agc_dump_roots(MR_RootList roots);
/*---------------------------------------------------------------------------*/
diff -u runtime2/mercury_conf_param.h runtime/mercury_conf_param.h
--- runtime2/mercury_conf_param.h Wed Jun 24 12:25:43 1998
+++ runtime/mercury_conf_param.h Fri Jul 3 15:11:52 1998
@@ -124,6 +124,26 @@
** Include a "name" field in the nondet stack frames.
** (Since this affects binary compatibility,
** this is a "compilation model" option which affects the grade.)
+**
+** MR_DEBUG_AGC_SCHEDULING
+** Display debugging information while scheduling accurate garbage
+** collection.
+**
+** MR_DEBUG_AGC_COLLECTION
+** Display debugging information while collecting garbage using the
+** accurate garbage collector.
+**
+** MR_DEBUG_AGC_FORWARDING
+** Display debugging information when leaving or finding forwarding
+** pointers during accurate garbage collection.
+**
+** MR_DEBUG_AGC_PRINT_VARS
+** Display the values of live variables during accurate garbage
+** collection.
+**
+** MR_DEBUG_AGC
+** Turn on all debugging information for accurate garbage
+** collection. (Equivalent to all MR_DEBUG_AGC_* macros above).
*/
/*
diff -u runtime2/mercury_deep_copy.c runtime/mercury_deep_copy.c
--- runtime2/mercury_deep_copy.c Tue Jun 30 16:56:26 1998
+++ runtime/mercury_deep_copy.c Fri Jul 3 15:17:48 1998
@@ -9,7 +9,7 @@
**
** Deep copy is used for a number of different purposes. Each variant
** has the same basic control structure, but differs in how memory
-** is allocated, or forwarding pointers left behind, or
+** is allocated, or whether forwarding pointers are left behind.
*/
#include "mercury_imp.h"
@@ -29,6 +29,9 @@
#define in_range(X) (lower_limit == NULL || ((X) >= lower_limit && \
(X) <= upper_limit))
+#undef maybeconst
+#define maybeconst const
+
#undef copy
#define copy deep_copy
@@ -53,6 +56,9 @@
#undef in_range
#define in_range(X) ((X) >= lower_limit && (X) <= upper_limit)
+
+#undef maybeconst
+#define maybeconst
#undef copy
#define copy agc_deep_copy
diff -u runtime2/mercury_deep_copy.h runtime/mercury_deep_copy.h
--- runtime2/mercury_deep_copy.h Tue Jun 30 16:55:49 1998
+++ runtime/mercury_deep_copy.h Fri Jul 3 15:13:51 1998
@@ -65,8 +65,8 @@
** deep_copy to do both.
*/
-Word deep_copy(Word *data_ptr, Word *type_info, Word *lower_limit,
- Word *upper_limit);
+Word deep_copy(const Word *data_ptr, const Word *type_info,
+ const Word *lower_limit, const Word *upper_limit);
/*
** agc_deep_copy:
@@ -92,8 +92,8 @@
** Note: You cannot pass NULL as the lower_limit to agc_deep_copy
** (which is possible with normal deep_copy).
*/
-Word agc_deep_copy(Word *data_ptr, Word *type_info, Word *lower_limit,
- Word *upper_limit);
+Word agc_deep_copy(Word *data_ptr, const Word *type_info,
+ const Word *lower_limit, const Word *upper_limit);
/*
** MR_make_permanent:
diff -u runtime2/mercury_deep_copy_body.h runtime/mercury_deep_copy_body.h
--- runtime2/mercury_deep_copy_body.h Tue Jun 30 16:14:37 1998
+++ runtime/mercury_deep_copy_body.h Fri Jul 3 15:42:32 1998
@@ -16,14 +16,15 @@
/*
** Prototypes.
*/
-static Word copy_arg(Word *data_ptr, Word *type_info, Word
- *arg_type_info, Word *lower_limit, Word *upper_limit);
-static Word *copy_type_info(Word *type_info,
- Word *lower_limit, Word *upper_limit);
+static Word copy_arg(maybeconst Word *data_ptr, const Word *type_info,
+ const Word *arg_type_info, const Word *lower_limit,
+ const Word *upper_limit);
+static Word *copy_type_info(maybeconst Word *type_info,
+ const Word *lower_limit, const Word *upper_limit);
Word
-copy(Word *data_ptr, Word *type_info, Word *lower_limit,
- Word *upper_limit)
+copy(maybeconst Word *data_ptr, const Word *type_info,
+ const Word *lower_limit, const Word *upper_limit)
{
Word *base_type_info, *base_type_layout, *base_type_functors;
Word functors_indicator;
@@ -60,10 +61,10 @@
Word *argument_vector, *type_info_vector;
int arity, i;
- /*
- ** if the vector containing the secondary tags and the
- ** arguments is in range, copy it.
- */
+ /*
+ ** if the vector containing the secondary tags and the
+ ** arguments is in range, copy it.
+ */
if (in_range(data_value)) {
secondary_tag = *data_value;
argument_vector = data_value + 1;
@@ -71,13 +72,13 @@
arity = new_entry[TYPELAYOUT_SIMPLE_ARITY_OFFSET];
type_info_vector = new_entry + TYPELAYOUT_SIMPLE_ARGS_OFFSET;
- /* allocate space for new args, and secondary tag */
+ /* allocate space for new args, and secondary tag */
incr_saved_hp(new_data, arity + 1);
- /* copy secondary tag */
+ /* copy secondary tag */
field(0, new_data, 0) = secondary_tag;
- /* copy arguments */
+ /* copy arguments */
for (i = 0; i < arity; i++) {
field(0, new_data, i + 1) = copy_arg(
&argument_vector[i], type_info,
@@ -85,7 +86,7 @@
upper_limit);
}
- /* tag this pointer */
+ /* tag this pointer */
new_data = (Word) mkword(data_tag, new_data);
leave_forwarding_pointer(data_ptr, new_data);
} else {
@@ -100,21 +101,21 @@
Word *argument_vector, *type_info_vector;
argument_vector = data_value;
- /* If the argument vector is in range, copy the arguments */
+ /* If the argument vector is in range, copy the arguments */
if (in_range(argument_vector)) {
arity = entry_value[TYPELAYOUT_SIMPLE_ARITY_OFFSET];
type_info_vector = entry_value + TYPELAYOUT_SIMPLE_ARGS_OFFSET;
- /* allocate space for new args. */
+ /* allocate space for new args. */
incr_saved_hp(new_data, arity);
- /* copy arguments */
+ /* copy arguments */
for (i = 0; i < arity; i++) {
field(0, new_data, i) = copy_arg(&argument_vector[i],
type_info, (Word *) type_info_vector[i], lower_limit,
upper_limit);
}
- /* tag this pointer */
+ /* tag this pointer */
new_data = (Word) mkword(data_tag, new_data);
leave_forwarding_pointer(data_ptr, new_data);
} else {
@@ -132,8 +133,9 @@
case MR_DATAREP_EQUIV:
new_data = copy_arg(data_ptr, type_info,
- (Word *) MR_TYPELAYOUT_EQUIV_TYPE((Word *) entry_value),
- lower_limit, upper_limit);
+ (const Word *) MR_TYPELAYOUT_EQUIV_TYPE((Word *)
+ entry_value),
+ lower_limit, upper_limit);
break;
case MR_DATAREP_EQUIV_VAR:
@@ -149,10 +151,10 @@
case MR_DATAREP_FLOAT:
#ifdef BOXED_FLOAT
if (in_range(data_value)) {
- /*
- ** force a deep copy by converting to float
- ** and back
- */
+ /*
+ ** force a deep copy by converting to float
+ ** and back
+ */
new_data = float_to_word(word_to_float(data));
leave_forwarding_pointer(data_ptr, new_data);
} else {
@@ -178,36 +180,35 @@
break;
case MR_DATAREP_PRED: {
- /*
- ** predicate closures store the number of curried
- ** arguments as their first argument, the
- ** Code * as their second, and then the
- ** arguments
- **
- ** Their type-infos have a pointer to
- ** base_type_info for pred/0, arity, and then
- ** argument typeinfos.
- **/
+ /*
+ ** predicate closures store the number of curried arguments
+ ** as their first argument, the Code * as their second, and
+ ** then the arguments
+ **
+ ** Their type-infos have a pointer to base_type_info for
+ ** pred/0, arity, and then argument typeinfos.
+ **/
if (in_range(data_value)) {
int args, i;
Word *new_closure;
- /* get number of curried arguments */
+ /* get number of curried arguments */
args = data_value[0];
- /* create new closure */
+ /* create new closure */
incr_saved_hp(LVALUE_CAST(Word, new_closure), args + 2);
- /* copy number of arguments */
+ /* copy number of arguments */
new_closure[0] = args;
- /* copy pointer to code for closure */
+ /* copy pointer to code for closure */
new_closure[1] = data_value[1];
- /* copy arguments */
+ /* copy arguments */
for (i = 0; i < args; i++) {
new_closure[i + 2] = copy(&data_value[i + 2],
- (Word *) type_info[i + TYPEINFO_OFFSET_FOR_PRED_ARGS],
+ (const Word *)
+ type_info[i + TYPEINFO_OFFSET_FOR_PRED_ARGS],
lower_limit, upper_limit);
}
new_data = (Word) new_closure;
@@ -220,11 +221,11 @@
break;
case MR_DATAREP_UNIV:
- /* if the univ is stored in range, copy it */
+ /* if the univ is stored in range, copy it */
if (in_range(data_value)) {
Word *new_data_ptr;
- /* allocate space for a univ */
+ /* allocate space for a univ */
incr_saved_hp(new_data, 2);
new_data_ptr = (Word *) new_data;
new_data_ptr[UNIV_OFFSET_FOR_TYPEINFO] =
@@ -233,7 +234,7 @@
lower_limit, upper_limit);
new_data_ptr[UNIV_OFFSET_FOR_DATA] = copy(
&data_value[UNIV_OFFSET_FOR_DATA],
- (Word *) data_value[UNIV_OFFSET_FOR_TYPEINFO],
+ (const Word *) data_value[UNIV_OFFSET_FOR_TYPEINFO],
lower_limit, upper_limit);
leave_forwarding_pointer(data_ptr, new_data);
} else {
@@ -261,7 +262,7 @@
for (i = 0; i < array_size; i++) {
new_array->elements[i] = copy_arg(
&old_array->elements[i], type_info,
- (Word *) 1, lower_limit, upper_limit);
+ (const Word *) 1, lower_limit, upper_limit);
}
new_data = (Word) new_array;
leave_forwarding_pointer(data_ptr, new_data);
@@ -306,8 +307,9 @@
** which refer to arguments of the term_type_info.
*/
static Word
-copy_arg(Word *data_ptr, Word *term_type_info, Word *arg_pseudo_type_info,
- Word *lower_limit, Word *upper_limit)
+copy_arg(maybeconst Word *data_ptr, const Word *term_type_info,
+ const Word *arg_pseudo_type_info, const Word *lower_limit,
+ const Word *upper_limit)
{
MR_MemoryList allocated_memory_cells;
Word *new_type_info;
@@ -324,7 +326,8 @@
Word *
-copy_type_info(Word *type_info_ptr, Word *lower_limit, Word *upper_limit)
+copy_type_info(maybeconst Word *type_info_ptr, const Word *lower_limit,
+ const Word *upper_limit)
{
Word *type_info = (Word *) *type_info_ptr;
@@ -335,7 +338,8 @@
/* XXX this doesn't handle higher-order types properly */
- base_type_info = MR_TYPEINFO_GET_BASE_TYPEINFO(type_info);
+ base_type_info = MR_TYPEINFO_GET_BASE_TYPEINFO((Word *)
+ type_info);
arity = MR_BASE_TYPEINFO_GET_TYPE_ARITY(base_type_info);
incr_saved_hp(LVALUE_CAST(Word, new_type_info), arity + 1);
new_type_info[0] = type_info[0];
diff -u runtime2/mercury_label.h runtime/mercury_label.h
--- runtime2/mercury_label.h Wed Jun 24 12:26:15 1998
+++ runtime/mercury_label.h Fri Jul 3 15:44:55 1998
@@ -22,7 +22,7 @@
const char *e_name; /* name of the procedure */
Code *e_addr; /* address of the code */
Word *e_layout; /* layout info for the label */
- bool *e_entry; /* yes if this is an entry */
+ bool e_entry; /* yes if this is an entry */
} Label;
extern void do_init_entries(void);
diff -u runtime2/mercury_memory.h runtime/mercury_memory.h
--- runtime2/mercury_memory.h Wed Jun 24 12:25:47 1998
+++ runtime/mercury_memory.h Fri Jul 3 14:38:11 1998
@@ -105,5 +105,16 @@
extern size_t unit;
extern size_t page_size;
+/*
+** Users need to call MR_add_root() for any global variable which
+** contains pointers to the Mercury heap. This information is only
+** used for agc grades.
+*/
+#ifdef NATIVE_GC
+ #define MR_add_root(root_ptr, type_info) \
+ MR_agc_add_root((root_ptr), (type_info))
+#else
+ #define MR_add_root(root_ptr, type_info) /* nothing */
+#endif
#endif /* not MERCURY_MEMORY_H */
diff -u runtime2/mercury_trace_util.c runtime/mercury_trace_util.c
--- runtime2/mercury_trace_util.c Tue Jun 30 14:39:36 1998
+++ runtime/mercury_trace_util.c Fri Jul 3 14:57:17 1998
@@ -335,10 +335,10 @@
** them.
*/
- restore_transient_registers();
- r1 = type_info;
- r2 = value;
- save_transient_registers();
- call_engine(MR_library_trace_browser);
+ restore_transient_registers();
+ r1 = type_info;
+ r2 = value;
+ save_transient_registers();
+ call_engine(MR_library_trace_browser);
}
diff -u runtime2/mercury_trace_util.h runtime/mercury_trace_util.h
--- runtime2/mercury_trace_util.h Wed Jul 1 15:03:11 1998
+++ runtime/mercury_trace_util.h Fri Jul 3 14:57:42 1998
@@ -28,10 +28,10 @@
bool saved_regs_valid, Word *base_sp, Word *base_curfr,
Word *type_params, Word *type_info, Word *value);
- /*
- ** MR_trace_write_variable:
- ** Write a variable to stdout.
- */
+/*
+** MR_trace_write_variable:
+** Write a variable to stdout.
+*/
extern void MR_trace_write_variable(Word type_info, Word value);
#endif /* MERCURY_TRACE_UTIL_H */
diff -u runtime2/mercury_type_info.c runtime/mercury_type_info.c
--- runtime2/mercury_type_info.c Mon Jun 29 17:25:51 1998
+++ runtime/mercury_type_info.c Fri Jul 3 15:50:26 1998
@@ -452,7 +452,7 @@
*/
Word *
-MR_make_type_info(Word *term_type_info, Word *arg_pseudo_type_info,
+MR_make_type_info(const Word *term_type_info, const Word *arg_pseudo_type_info,
MR_MemoryList *allocated)
{
int i, arity, extra_args;
@@ -478,7 +478,7 @@
/* no arguments - optimise common case */
if (base_type_info == arg_pseudo_type_info) {
- return arg_pseudo_type_info;
+ return base_type_info;
}
if (MR_BASE_TYPEINFO_IS_HO(base_type_info)) {
@@ -533,7 +533,7 @@
}
}
if (type_info == NULL) {
- return arg_pseudo_type_info;
+ return (Word *) (Word) arg_pseudo_type_info;
} else {
return type_info;
}
diff -u runtime2/mercury_type_info.h runtime/mercury_type_info.h
--- runtime2/mercury_type_info.h Fri Jun 26 16:38:12 1998
+++ runtime/mercury_type_info.h Fri Jul 3 15:48:40 1998
@@ -662,7 +662,7 @@
*/
#define MR_TYPEINFO_GET_BASE_TYPEINFO(TypeInfo) \
- ((*TypeInfo) ? ((Word *) *TypeInfo) : TypeInfo)
+ ((*TypeInfo) ? (Word *) *TypeInfo : (Word *) (Word) TypeInfo)
#define MR_TYPEINFO_GET_HIGHER_ARITY(TypeInfo) \
((Integer) (Word *) (TypeInfo)[TYPEINFO_OFFSET_FOR_PRED_ARITY])
@@ -795,10 +795,8 @@
};
typedef struct MR_MemoryCellNode *MR_MemoryList;
-Word * MR_make_type_info(Word *term_type_info, Word *arg_pseudo_type_info,
- MR_MemoryList *allocated);
-Word * MR_make_type_info_tabled(Word *term_type_info,
- Word *arg_pseudo_type_info);
+Word * MR_make_type_info(const Word *term_type_info,
+ const Word *arg_pseudo_type_info, MR_MemoryList *allocated);
void MR_deallocate(MR_MemoryList allocated_memory_cells);
/*---------------------------------------------------------------------------*/
--
Tyson Dowd # There isn't any reason why Linux can't be
# implemented as an enterprise computing solution.
trd at cs.mu.oz.au # Find out what you've been missing while you've
http://www.cs.mu.oz.au/~trd # been rebooting Windows NT. -- InfoWorld, 1998.
More information about the developers
mailing list