cvs diff: Bug fix for SPARCs non-gc grades.

Tyson Richard DOWD trd at students.cs.mu.oz.au
Thu Feb 6 10:24:21 AEDT 1997


Hi folks.

Fergus, could you please review this.
Any comments from others are of course appreciated.

===================================================================

Estimated hours taken: 1.5

Bug fix for failed tests in non-gc grades on SPARCs.

Sliding register windows on the SPARC meant that registers were
being clobbered by C function calls. This bug was foreshadowed
by Tom, but I hadn't fixed it yet.

NB: This problem needs to be documented in out C coding standard, and
possibly the user documentation somewhere.

library/std_util.m:
	- Change arg, expand and functor to save_transient_registers()
	  and restore_transient_registers before calling mercury_expand.
	- Change mercury_expand to use incr_saved_hp and
	  incr_saved_hp_atomic.

runtime/deep_copy.c:
runtime/heap.h:
	- Move the definitions of incr_saved_hp and incr_saved_hp_atomic
	  from deep_copy.c to heap.h, so they are more generally
	  accessible.


Index: library/std_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/std_util.m,v
retrieving revision 1.64
diff -u -r1.64 std_util.m
--- std_util.m	1997/02/04 06:35:05	1.64
+++ std_util.m	1997/02/05 22:48:10
@@ -964,7 +964,7 @@
 			/* is it a no_tag type? */
 		else if (((Word *) entry_value)[0]) {
 			Word new_arg_vector; 
-			incr_hp(new_arg_vector, 1);
+			incr_saved_hp(new_arg_vector, 1);
 			field(0, new_arg_vector, 0) = data_word;
 			mercury_expand_simple(new_arg_vector, 
 				(Word *) entry_value, type_info, info);
@@ -1130,7 +1130,7 @@
 		/* XXX should escape characters correctly */
 
 		if (info->need_functor) {
-			incr_hp_atomic(LVALUE_CAST(Word, info->functor), 
+			incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor), 
 				(strlen((String) data_value) + 2 + 
 					sizeof(Word)) / sizeof(Word));
 			sprintf(info->functor, ""%c%s%c"", '""', 
@@ -1147,7 +1147,7 @@
 			Float f;
 			f = word_to_float(data_value);
 			sprintf(buf, ""%#.15g"", f);
-			incr_hp_atomic(LVALUE_CAST(Word, info->functor), 
+			incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor), 
 				(strlen(buf) + sizeof(Word)) / sizeof(Word));
 			strcpy(info->functor, buf);
 		}
@@ -1161,7 +1161,7 @@
 			char buf[500];
 
 			sprintf(buf, ""%ld"", (long) data_value);
-			incr_hp_atomic(LVALUE_CAST(Word, info->functor), 
+			incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor), 
 				(strlen(buf) + sizeof(Word)) / sizeof(Word));
 			strcpy(info->functor, buf);
 		}
@@ -1175,7 +1175,7 @@
 		/* XXX should escape characters correctly */
 
 		if (info->need_functor) {
-			incr_hp_atomic(LVALUE_CAST(Word, info->functor), 
+			incr_saved_hp_atomic(LVALUE_CAST(Word, info->functor), 
 				(3 + sizeof(Word)) / sizeof(Word));
 			sprintf(info->functor, ""\'%c\'"", (char) data_value);
 		}
@@ -1267,7 +1267,7 @@
 
 	arity = ((Word *) base_type_info)[0];
 
-	incr_hp(LVALUE_CAST(Word, type_info), arity + 1);
+	incr_saved_hp(LVALUE_CAST(Word, type_info), arity + 1);
 
 	for (i = 0; i <= arity; i++) {
 		if (arg_pseudo_type_info[i] < TYPELAYOUT_MAX_VARINT) {
@@ -1295,8 +1295,12 @@
 	info.need_functor = TRUE;
 	info.need_args = FALSE;
 
+	save_transient_registers();
+
 	mercury_expand((Word *) TypeInfo_for_T, Type, &info);
 
+	restore_transient_registers();
+
 		/* Copy functor onto the heap */
 	make_aligned_string(LVALUE_CAST(String, Functor), info.functor);
 
@@ -1312,8 +1316,12 @@
 	info.need_functor = FALSE;
 	info.need_args = TRUE;
 
+	save_transient_registers();
+
 	mercury_expand((Word *) TypeInfo_for_T, Type, &info);
 
+	restore_transient_registers();
+
 		/* Check range */
 	SUCCESS_INDICATOR = (ArgumentIndex > 0 && ArgumentIndex <= info.arity);
 	if (SUCCESS_INDICATOR) {
@@ -1339,6 +1347,7 @@
 
 	free(info.type_info_vector);
 
+
 }").
 
 det_arg(Type, ArgumentIndex, Argument) :-
@@ -1360,7 +1369,11 @@
 	info.need_functor = TRUE;
 	info.need_args = TRUE;
 
+	save_transient_registers();
+
 	mercury_expand((Word *) TypeInfo_for_T, Type, &info);
+	
+	restore_transient_registers();
 
 		/* Get functor */
 	make_aligned_string(LVALUE_CAST(String, Functor), info.functor);
Index: runtime/deep_copy.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/deep_copy.c,v
retrieving revision 1.3
diff -u -r1.3 deep_copy.c
--- deep_copy.c	1997/02/04 01:25:02	1.3
+++ deep_copy.c	1997/02/05 06:19:50
@@ -8,22 +8,11 @@
  * This module defines the deep copy function.
  */
 
+#include "imp.h"
 #include "deep_copy.h"
 #include "type_info.h"
 
 #define in_range(X)	((X) >= lower_limit && (X) <= upper_limit)
-
-#define incr_saved_hp(A,B)	do { 					\
-					restore_transient_registers();	\
-					incr_hp((A), (B));		\
-					save_transient_registers();	\
-				} while (0)
-
-#define incr_saved_hp_atomic(A,B) do { 					\
-					restore_transient_registers();	\
-					incr_hp_atomic((A), (B));	\
-					save_transient_registers();	\
-				} while (0)
 
 /*
 ** Prototypes.
Index: runtime/heap.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/heap.h,v
retrieving revision 1.5
diff -u -r1.5 heap.h
--- heap.h	1996/12/19 08:03:23	1.5
+++ heap.h	1997/02/05 06:24:13
@@ -155,3 +155,24 @@
 				heap_overflow_check(),		\
 				/* return */ (Word) (hp - 2)	\
 			)
+
+/*
+** Indended for use in handwritten C code where the Mercury registers
+** may have been clobbered due to C function calls (eg, on the SPARC due
+** to sliding register windows).
+** Remember to save_transient_registers() before calls to such code, and
+** restore_transient_registers() after.
+*/
+
+#define incr_saved_hp(A,B)	do { 					\
+					restore_transient_registers();	\
+					incr_hp((A), (B));		\
+					save_transient_registers();	\
+				} while (0)
+
+#define incr_saved_hp_atomic(A,B) do { 					\
+					restore_transient_registers();	\
+					incr_hp_atomic((A), (B));	\
+					save_transient_registers();	\
+				} while (0)
+




More information about the developers mailing list