for review: add MR_virtual_hp, MR_virtual_sp, etc.
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed Apr 15 18:59:19 AEST 1998
Zoltan, can you please review this one?
Estimated hours taken: 2
runtime/mercury_regorder.h:
Add definitions for MR_virtual_sp, MR_virtual_hp, etc.
which access the underlying fake_reg slot rather than the
real machine register.
runtime/mercury_regs.h:
Add some more comments and move some code around, so as to
clearly delineate between the different abstraction layers.
runtime/mercury_heap.h:
Implement incr_saved_hp() and incr_saved_hp_atomic()
more efficiently, using MR_virtual_hp.
runtime/mercury_overflow.h:
Add saved_heap_overflow_check(), for use by incr_saved_hp().
cvs diff runtime/mercury_heap.h runtime/mercury_overflow.h runtime/mercury_regorder.h runtime/mercury_regs.h
Index: runtime/mercury_heap.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap.h,v
retrieving revision 1.4
diff -u -r1.4 mercury_heap.h
--- mercury_heap.h 1997/12/10 02:07:35 1.4
+++ mercury_heap.h 1998/04/15 08:56:30
@@ -224,18 +224,20 @@
** 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)
+#ifdef USE_CONSERVATIVE_GC
+ #define incr_saved_hp(A, B) incr_hp(A, B)
+ #define incr_saved_hp_atomic(A, B) incr_hp_atomic(A, B)
+#else
+ /* same as tag_incr_hp except we use MR_virtual_hp instead of MR_hp */
+ #define incr_saved_hp(dest, count) \
+ ( \
+ (dest) = (Word) mkword(0, (Word) MR_virtual_hp),\
+ debugincrhp(count, MR_virtual_hp), \
+ MR_virtual_hp += (count), \
+ saved_heap_overflow_check(), \
+ (void)0 \
+ )
+ #define incr_saved_hp_atomic(A, B) incr_saved_hp(A, B)
+#endif
#endif /* not MERCURY_HEAP_H */
Index: runtime/mercury_overflow.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_overflow.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_overflow.h
--- mercury_overflow.h 1998/03/16 12:23:35 1.3
+++ mercury_overflow.h 1998/04/15 08:54:58
@@ -14,6 +14,7 @@
#ifndef MR_CHECK_FOR_OVERFLOW
#define heap_overflow_check() ((void)0)
+#define saved_heap_overflow_check() ((void)0)
#define detstack_overflow_check() ((void)0)
#define detstack_underflow_check() ((void)0)
#define nondstack_overflow_check() ((void)0)
@@ -31,6 +32,17 @@
)), \
IF (MR_hp > heap_zone->max,( \
heap_zone->max = MR_hp \
+ )), \
+ (void)0 \
+ )
+
+#define saved_heap_overflow_check() \
+ ( \
+ IF (MR_virtual_hp >= heap_zone->top,( \
+ fatal_error("heap overflow") \
+ )), \
+ IF (MR_virtual_hp > heap_zone->max,( \
+ heap_zone->max = MR_virtual_hp \
)), \
(void)0 \
)
Index: runtime/mercury_regorder.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regorder.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_regorder.h
--- mercury_regorder.h 1998/04/08 11:34:01 1.3
+++ mercury_regorder.h 1998/04/15 08:45:51
@@ -22,6 +22,10 @@
#ifndef MERCURY_REGORDER_H
#define MERCURY_REGORDER_H
+/*
+** If you modify the r<N> to mr<N> mapping, make sure that you update
+** the definition of MR_VIRTUAL_REG_MAP_BODY below.
+*/
#define r1 count_usage(R_RN(1), mr2)
#define r2 count_usage(R_RN(2), mr3)
#define r3 count_usage(R_RN(3), mr4)
@@ -57,33 +61,49 @@
/*
** If you modify the following block, make sure that you update
-** the definitions of MR_NUM_SPECIAL_REG and MR_MAX_SPECIAL_REG_MR.
+** the definitions of MR_NUM_SPECIAL_REG, MR_MAX_SPECIAL_REG_MR,
+** and MR_virtual_*.
*/
-
-#define MR_succip LVALUE_CAST(Code *, count_usage(MR_SI_RN, mr1))
-#define succip MR_succip
-#define MR_hp LVALUE_CAST(Word *, count_usage(MR_HP_RN, mr5))
-#define hp MR_hp
-#define MR_sp LVALUE_CAST(Word *, count_usage(MR_SP_RN, mr0))
-#define sp MR_sp
-#define MR_curfr LVALUE_CAST(Word *, count_usage(MR_CF_RN, mr8))
-#define curfr MR_curfr
-#define MR_maxfr LVALUE_CAST(Word *, count_usage(MR_MF_RN, mr9))
-#define maxfr MR_maxfr
+#define MR_succip LVALUE_CAST(Code *, count_usage(MR_SI_RN, mr1))
+#define MR_hp LVALUE_CAST(Word *, count_usage(MR_HP_RN, mr5))
+#define MR_sp LVALUE_CAST(Word *, count_usage(MR_SP_RN, mr0))
+#define MR_curfr LVALUE_CAST(Word *, count_usage(MR_CF_RN, mr8))
+#define MR_maxfr LVALUE_CAST(Word *, count_usage(MR_MF_RN, mr9))
#define MR_sol_hp LVALUE_CAST(Word *, count_usage(MR_SOL_HP_RN, mr(37)))
#define MR_min_hp_rec LVALUE_CAST(Word *, count_usage(MR_MIN_HP_REC, mr(38)))
#define MR_min_sol_hp_rec LVALUE_CAST(Word *, \
count_usage(MR_MIN_HP_REC, mr39))
-
#define MR_trail_ptr count_usage(MR_TRAIL_PTR_RN, MR_trail_ptr_var)
#define MR_ticket_counter \
count_usage(MR_TICKET_COUNTER_RN, MR_ticket_counter_var)
+/* for backwards compatibility */
+#define succip MR_succip
+#define hp MR_hp
+#define sp MR_sp
+#define curfr MR_curfr
+#define maxfr MR_maxfr
+
/* the number of special, non rN registers */
#define MR_NUM_SPECIAL_REG 10
/* the maximum mrN number of special, non rN registers */
#define MR_MAX_SPECIAL_REG_MR 39
+
+/*
+** The MR_virtual_foo macros are like MR_foo except that
+** they access the underlying fake_reg slot rather than
+** the real machine register.
+*/
+
+#define MR_virtual_succip LVALUE_CAST(Code *, fake_reg[1])
+#define MR_virtual_hp LVALUE_CAST(Word *, fake_reg[5])
+#define MR_virtual_sp LVALUE_CAST(Word *, fake_reg[0])
+#define MR_virtual_curfr LVALUE_CAST(Word *, fake_reg[8])
+#define MR_virtual_maxfr LVALUE_CAST(Word *, fake_reg[9])
+#define MR_virtual_sol_hp LVALUE_CAST(Word *, fake_reg[37])
+#define MR_virtual_min_hp_rec LVALUE_CAST(Word *, fake_reg[38])
+#define MR_virtual_min_sol_hp_rec LVALUE_CAST(Word *, fake_reg[39])
#define VIRTUAL_REG_MAP_BODY { \
2, \
Index: runtime/mercury_regs.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regs.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_regs.h
--- mercury_regs.h 1998/02/04 03:55:27 1.5
+++ mercury_regs.h 1998/04/15 08:41:57
@@ -10,6 +10,7 @@
#include "mercury_conf.h"
#include "mercury_types.h"
+/*---------------------------------------------------------------------------*/
/*
** GNU C allows lvalue casts, so if we have gcc, use them.
** If we don't have gcc, then we can use *(type *)&lval,
@@ -28,33 +29,59 @@
#define LVALUE_COND(expr, x, y) (*((expr)?&(x):&(y)))
#endif
+/*---------------------------------------------------------------------------*/
/*
** The registers of the Mercury virtual machine are built up using
** three levels of abstraction.
**
-** The first level defines the first NUM_REAL_REGS register variables
-** mr0, mr1, etc. as the physical machine registers, and defines an
-** array fake_regs[n] of pseudo registers.
+** The bottom level is the hardware description layer.
+** This layer is defined seperately for each architecture, in machdeps/*.h.
+** The hardware description layer defines the first NUM_REAL_REGS register
+** variables mr0, mr1, etc. as the physical machine registers, and defines an
+** array fake_regs[n] of pseudo registers, with the remaining "registers"
+** mr<NUM_REAL_REGS>, ..., mr36 defined as corresponding slots in
+** this fake_reg array.
+** This level also provides the macros save_regs_to_mem(),
+** save_transient_regs_to_mem(), restore_regs_from_mem(),
+** and restore_transient_regs_from_mem().
+**
+** The next level is the hardware abstraction layer.
+** The hardware abstraction layer is at a similar level to the
+** hardware description layer, and includes that as a subset,
+** but in addition it provides a few more conveniences.
+** This layer defines macros mr(n) for n>36, and the macros
+** save_registers(), restore_registers(), save_transient_registers(),
+** and restore_transient_registers().
+** This layer is defined here in mercury_regs.h.
**
-** The next level defines macros mr0 through mr36 and also mr(n) for
-** n>36. The lower the number,
+** The hardware abstraction layer thus provides a very large number
+** of registers, which may be either real or fake. The lower the number,
** the greater the probability that the storage referred to will be
** a real machine register, and not a simulated one. The number of
** real machine registers is given by the macro NUM_REAL_REGS.
**
-** The final level maps the Mercury virtual machine registers
+** The final level is the Mercury abstract machine registers layer.
+** This layer maps the Mercury virtual machine registers
**
-** succip, hp, sp, curfr, maxfr and
+** MR_succip, MR_hp, MR_sp, MR_curfr, MR_maxfr and
** r1, ..., r32, r(33), ..., r(MAX_VIRTUAL_REG)
**
** to the set mr0..mr36, mr(37), mr(38), ..., mr(MAX_FAKE_REG-1)
+** which were provided by the hardware abstraction layer.
+** It also provides MR_virtual_r(), MR_virtual_succip, MR_virtual_hp, etc.,
+** which are similar to mr<N>, MR_succip, MR_hp, etc. except that they
+** always map to the underlying fake_reg rather than to the physical register.
**
** Since the set of most frequently used Mercury virtual machine
-** registers can be different for each program, we want to make
+** registers can be different for each program or grade, we want to make
** this mapping as easy to change as possible. This is why the
** map is in a minimal header file, mercury_regorder.h.
*/
+/*---------------------------------------------------------------------------*/
+/*
+** The hardware description layer
+*/
#if defined(USE_GCC_GLOBAL_REGISTERS)
#ifndef __GNUC__
#error "You must use gcc if you define USE_GCC_GLOBAL_REGISTERS."
@@ -79,24 +106,17 @@
#include "machdeps/no_regs.h"
#endif
+/*---------------------------------------------------------------------------*/
+/*
+** Extra stuff for the hardware abstraction layer
+*/
+
/* The machdeps header defines mr0 .. mr36; now define mr(n) for n > 36 */
#define mr(n) LVALUE_SEQ(MR_assert((n) >= MAX_REAL_REG + NUM_SPECIAL_REG && \
- (n) < MAX_FAKE_REG),\
+ (n) < MAX_FAKE_REG), \
fake_reg[n])
-#ifdef MEASURE_REGISTER_USAGE
- #define count_usage(num,reg) LVALUE_SEQ(num_uses[num]++, reg)
-#else
- #define count_usage(num,reg) (reg)
-#endif
-
-#include "mercury_regorder.h"
-
-/* mercury_regorder.h defines r1 .. r32; now define r(n) for n > 32 */
-
-#define r(n) mr((n) + NUM_SPECIAL_REG - 1)
-
/*
** the save_registers() macro copies the physical machine registers
** to their corresponding slots in the fake_reg array
@@ -122,15 +142,29 @@
#define save_transient_registers() save_transient_regs_to_mem(fake_reg)
#define restore_transient_registers() restore_transient_regs_from_mem(fake_reg)
+/*---------------------------------------------------------------------------*/
+/*
+** The Mercury abstract machine registers layer
+*/
+
+#ifdef MEASURE_REGISTER_USAGE
+ #define count_usage(num,reg) LVALUE_SEQ(num_uses[num]++, reg)
+#else
+ #define count_usage(num,reg) (reg)
+#endif
+
+#include "mercury_regorder.h"
+
+/* mercury_regorder.h defines r1 .. r32; now define r(n) for n > 32 */
+
+#define r(n) mr((n) + NUM_SPECIAL_REG - 1)
+
/* virtual_reg(n) accesses the underlying fake_reg for register n */
-#define virtual_reg(n) \
- LVALUE_COND((n) > MAX_REAL_REG, \
- r(n), \
- fake_reg[virtual_reg_map[(n) - 1]])
+#define virtual_reg(n) saved_reg(fake_reg, n)
/* saved_reg(save_area, n) is like virtual_reg, except in that */
-/* it accesses the given save area instead of the machine regs and fake_reg */
+/* it accesses the given save area instead of fake_reg */
#define saved_reg(save_area, n) \
LVALUE_COND((n) > MAX_REAL_REG, \
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list