[m-dev.] for review: Accurate garbage collection.
Tyson Dowd
trd at cs.mu.OZ.AU
Thu Jul 2 15:19:59 AEST 1998
On 01-Jul-1998, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 01-Jul-1998, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
>
> > 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.
>
> There are probably other calls to deep_copy() somewhere in extras/*.
>
> I think it would be better to leave the interface to deep_copy()
> as is, if necessary by making deep_copy() a forwarding macro that
> calls the function that actually does the work.
That's fine for the moment. It will all need to be re-visited when
non-destructive sharing is added.
> > Index: library/io.m
> ...
> > +#ifdef NATIVE_GC
> > + MR_agc_add_root(&ML_io_stream_names, (Word *) StreamNamesType);
> > + MR_agc_add_root(&ML_io_user_globals, (Word *) UserGlobalsType);
> > +#endif
>
> In general, users will need to call MR_agc_add_root() for any
> global variable which contains pointers to the Mercury heap.
> So I think it would be better to have a macro
>
> #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
>
> defined somewhere in the runtime, e.g. runtime/mercury_memory.h.
> That way the #ifdef doesn't need to be in so many places.
Good idea.
> > + top_frame = top_frame && FALSE;
>
> What are you trying to do here? Should that be `top_frame = FALSE;'?
>
Ummm... ... yes (how embarrasing).
It was obviously written before I had a coffee! That's the standard
excuse for being logic-impaired, isn't it?
> > Index: runtime/mercury_deep_copy_body.h
>
> Can you give a diff of that against the old mercury_deep_copy.c?
Of course.
--- mercury_deep_copy.c Thu Jul 2 15:07:47 1998
+++ mercury_deep_copy_body.h Tue Jun 30 16:14:37 1998
@@ -5,44 +5,34 @@
*/
/*
-** This module defines the deep_copy() function.
+** The internals of deep copy.
+**
+** Functions such as "copy", "copy_arg", "copy_type_info", "in_range",
+** etc can be #defined to whatever functions are needed for a particular
+** copying application.
*/
-#include "mercury_imp.h"
-#include "mercury_deep_copy.h"
-#include "mercury_type_info.h"
-#include "mercury_memory.h"
-
-#define in_range(X) ((X) >= lower_limit && (X) <= upper_limit)
/*
** Prototypes.
*/
-static Word deep_copy_arg(Word data, Word *type_info, Word *arg_type_info,
- Word *lower_limit, Word *upper_limit);
-static Word * deep_copy_type_info(Word *type_info,
- Word *lower_limit, Word *upper_limit);
+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);
-MR_DECLARE_STRUCT(mercury_data___base_type_info_pred_0);
-MR_DECLARE_STRUCT(mercury_data___base_type_info_func_0);
-
-/*
-** deep_copy(): see mercury_deep_copy.h for documentation.
-**
-** Due to the depth of the control here, we'll use 4 space indentation.
-**
-** NOTE : changes to this function will probably also have to be reflected
-** in the function std_util::ML_expand() and mercury_table_any.c
-*/
Word
-deep_copy(Word data, Word *type_info, Word *lower_limit, Word *upper_limit)
+copy(Word *data_ptr, Word *type_info, Word *lower_limit,
+ Word *upper_limit)
{
Word *base_type_info, *base_type_layout, *base_type_functors;
Word functors_indicator;
Word layout_entry, *entry_value, *data_value;
enum MR_DataRepresentation data_rep;
int data_tag;
- Word new_data;
+ Word new_data, data;
+
+ data = *data_ptr;
data_tag = tag(data);
data_value = (Word *) body(data, data_tag);
@@ -89,16 +79,18 @@
/* copy arguments */
for (i = 0; i < arity; i++) {
- field(0, new_data, i + 1) = deep_copy_arg(
- argument_vector[i], type_info,
+ field(0, new_data, i + 1) = copy_arg(
+ &argument_vector[i], type_info,
(Word *) type_info_vector[i], lower_limit,
upper_limit);
}
/* tag this pointer */
new_data = (Word) mkword(data_tag, new_data);
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
break;
}
@@ -118,32 +110,34 @@
/* copy arguments */
for (i = 0; i < arity; i++) {
- field(0, new_data, i) = deep_copy_arg(argument_vector[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 */
new_data = (Word) mkword(data_tag, new_data);
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
break;
}
case MR_DATAREP_NOTAG:
- new_data = deep_copy_arg(data, type_info,
+ new_data = copy_arg(data_ptr, type_info,
(Word *) *MR_TYPELAYOUT_NO_TAG_VECTOR_ARGS(entry_value),
lower_limit, upper_limit);
break;
case MR_DATAREP_EQUIV:
- new_data = deep_copy_arg(data, type_info,
+ new_data = copy_arg(data_ptr, type_info,
(Word *) MR_TYPELAYOUT_EQUIV_TYPE((Word *) entry_value),
lower_limit, upper_limit);
break;
case MR_DATAREP_EQUIV_VAR:
- new_data = deep_copy(data, (Word *) type_info[(Word) entry_value],
+ new_data = copy(data_ptr, (Word *) type_info[(Word) entry_value],
lower_limit, upper_limit);
break;
@@ -160,8 +154,10 @@
** and back
*/
new_data = float_to_word(word_to_float(data));
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
#else
new_data = data;
@@ -174,8 +170,10 @@
(strlen((String) data_value) + sizeof(Word))
/ sizeof(Word));
strcpy((String) new_data, (String) data_value);
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
break;
@@ -208,13 +206,15 @@
/* copy arguments */
for (i = 0; i < args; i++) {
- new_closure[i + 2] = deep_copy(data_value[i + 2],
+ new_closure[i + 2] = copy(&data_value[i + 2],
(Word *) type_info[i + TYPEINFO_OFFSET_FOR_PRED_ARGS],
lower_limit, upper_limit);
}
- new_data = (Word) new_closure;
+ new_data = (Word) new_closure;
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
}
break;
@@ -228,20 +228,22 @@
incr_saved_hp(new_data, 2);
new_data_ptr = (Word *) new_data;
new_data_ptr[UNIV_OFFSET_FOR_TYPEINFO] =
- (Word) deep_copy_type_info( (Word *)
- data_value[UNIV_OFFSET_FOR_TYPEINFO],
- lower_limit, upper_limit);
- new_data_ptr[UNIV_OFFSET_FOR_DATA] = deep_copy(
- data_value[UNIV_OFFSET_FOR_DATA],
- (Word *) data_value[UNIV_OFFSET_FOR_TYPEINFO],
- lower_limit, upper_limit);
+ (Word) copy_type_info(
+ &data_value[UNIV_OFFSET_FOR_TYPEINFO],
+ 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],
+ lower_limit, upper_limit);
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
break;
case MR_DATAREP_VOID:
- fatal_error("Cannot deep copy a void type");
+ fatal_error("Cannot copy a void type");
break;
case MR_DATAREP_ARRAY: {
@@ -257,26 +259,28 @@
new_array = MR_make_array(array_size);
new_array->size = array_size;
for (i = 0; i < array_size; i++) {
- new_array->elements[i] = deep_copy_arg(
- old_array->elements[i], type_info,
+ new_array->elements[i] = copy_arg(
+ &old_array->elements[i], type_info,
(Word *) 1, lower_limit, upper_limit);
}
new_data = (Word) new_array;
+ leave_forwarding_pointer(data_ptr, new_data);
} else {
new_data = data;
+ found_forwarding_pointer(data);
}
break;
}
case MR_DATAREP_TYPEINFO:
- new_data = (Word) deep_copy_type_info(data_value,
+ new_data = (Word) copy_type_info(data_ptr,
lower_limit, upper_limit);
break;
case MR_DATAREP_C_POINTER:
if (in_range(data_value)) {
/*
- ** This error occurs if we try to deep_copy() a
+ ** This error occurs if we try to copy() a
** `c_pointer' type that points to memory allocated
** on the Mercury heap.
*/
@@ -293,16 +297,16 @@
}
return new_data;
-} /* end deep_copy() */
+}
/*
-** deep_copy_arg is like deep_copy() except that it takes a
+** copy_arg is like copy() except that it takes a
** pseudo_type_info (namely arg_pseudo_type_info) rather than
** a type_info. The pseudo_type_info may contain type variables,
** which refer to arguments of the term_type_info.
*/
static Word
-deep_copy_arg(Word data, Word *term_type_info, Word *arg_pseudo_type_info,
+copy_arg(Word *data_ptr, Word *term_type_info, Word *arg_pseudo_type_info,
Word *lower_limit, Word *upper_limit)
{
MR_MemoryList allocated_memory_cells;
@@ -312,7 +316,7 @@
allocated_memory_cells = NULL;
new_type_info = MR_make_type_info(term_type_info, arg_pseudo_type_info,
&allocated_memory_cells);
- new_data = deep_copy(data, new_type_info, lower_limit, upper_limit);
+ new_data = copy(data_ptr, new_type_info, lower_limit, upper_limit);
MR_deallocate(allocated_memory_cells);
return new_data;
@@ -320,8 +324,10 @@
Word *
-deep_copy_type_info(Word *type_info, Word *lower_limit, Word *upper_limit)
+copy_type_info(Word *type_info_ptr, Word *lower_limit, Word *upper_limit)
{
+ Word *type_info = (Word *) *type_info_ptr;
+
if (in_range(type_info)) {
Word *base_type_info;
Word *new_type_info;
@@ -334,58 +340,17 @@
incr_saved_hp(LVALUE_CAST(Word, new_type_info), arity + 1);
new_type_info[0] = type_info[0];
for (i = 1; i < arity + 1; i++) {
- new_type_info[i] = (Word) deep_copy_type_info(
+ new_type_info[i] = (Word) copy_type_info(
(Word *) type_info[i],
lower_limit, upper_limit);
}
+ leave_forwarding_pointer(type_info_ptr, (Word) new_type_info);
return new_type_info;
} else {
+ found_forwarding_pointer(type_info);
return type_info;
}
}
-#define SWAP(val1, val2, type) \
- do { \
- type swap_tmp; \
- swap_tmp = (val1); \
- (val1) = (val2); \
- (val2) = swap_tmp; \
- } while (0)
-
-#ifndef CONSERVATIVE_GC
-/*
-** MR_make_long_lived(): see mercury_deep_copy.h for documentation.
-*/
-Word
-MR_make_long_lived(Word term, Word *type_info, Word *lower_limit)
-{
- Word result;
-
- restore_transient_registers(); /* Because we play with MR_hp */
-
- if (lower_limit < MR_heap_zone->bottom ||
- lower_limit > MR_heap_zone->top) {
- lower_limit = MR_heap_zone->bottom;
- }
-
- /* temporarily swap the heap with the global heap */
- SWAP(MR_heap_zone, MR_global_heap_zone, MemoryZone *);
- SWAP(MR_hp, MR_global_hp, Word *);
-
- /* copy values from the heap to the global heap */
- save_transient_registers();
- result = deep_copy(term, type_info, lower_limit,
- MR_global_heap_zone->top);
- restore_transient_registers();
-
- /* swap the heap and global heap back again */
- SWAP(MR_heap_zone, MR_global_heap_zone, MemoryZone *);
- SWAP(MR_hp, MR_global_hp, Word *);
-
- save_transient_registers(); /* Because we played with MR_hp */
-
- return result;
-}
-#endif /* not CONSERVATIVE_GC */
--
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