[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