[m-dev.] for review: compressing RTTI using non-word creates (part 2)
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Apr 27 00:20:44 AEST 1999
On 26-Apr-1999, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
>
> +++ stack_layout.m 1999/04/26 05:23:13
...
> +% The field containing the number of live data items is encoded by the
> +% formula (#Long << 8 + #Short), where #Short is the number data items whose
> +% descriptions fit into an MR_Short_Lval and #Long is the number of data
> +% items whose descriptions do not.
What happens if #Short > 255?
I think you should detect that case and handle it appropriately.
> +stack_layout__construct_liveval_arrays(VarInfos, LengthRval,
> + TypeLocnVector, NameVector) -->
...
> + { stack_layout__byte_bits(ByteBits) },
> + { EncodedLength is IntArrayLength << ByteBits + ByteArrayLength },
Why `byte_bits'? Is there any reason why representing things as e.g.
"#Long << 10 + #Short" wouldn't work? If not, then the named constant
that names this hard-coded shift count should be named something other
than `byte_bits'.
(Also, it would probably be better to use a zero-arity function rather
than a unary predicate for named constants like this.)
> +:- pred stack_layout__make_tagged_byte(int::in, int::in, int::out) is semidet.
> +
> +stack_layout__make_tagged_byte(Tag, Value, TaggedValue) :-
> + stack_layout__byte_bits(ByteBits),
> + int__pow(2, ByteBits - 2, Limit),
> + Value < Limit,
> + TaggedValue is unchecked_left_shift(Value, 2) + Tag.
I suggest replacing the last two occurrences of the constant `2' by
a named constant, called say `short_locn_tag_bits' or something like that.
> +int
> +MR_get_register_number_short(MR_Short_Lval locn)
> +{
> + if ((locn & 03) == MR_SHORT_LVAL_TYPE_R) {
> + return locn >> 2;
Likewise here I would suggest writing that as
/* in header file */
#define MR_SHORT_LOCN_TAG_BITS 2
/* in C file */
if ((locn & ((1 << MR_LOCN_TAG_BITS) - 1)) == MR_SHORT_LVAL_TYPE_R) {
return LOCN >> MR_LOCN_TAG_BITS;
}
It would be even better to use a bit more abstraction, e.g.
something like
if (MR_SHORT_LOCN_TAG(locn) == MR_SHORT_LVAL_TYPE_R) {
return MR_SHORT_LVAL_R_REG(locn);
Here the MR_SHORT_LVAL_R_REG(n) is the one that you defined
in mercury_stack_layout.h, and MR_SHORT_LOCN_TAGS is a new macro
which would be defined in mercury_stack_layout.h.
Maybe MR_SHORT_LVAL_TAGS would be a better name than MR_SHORT_LOCN_TAGS,
I'm not sure.
> bool
> -MR_get_type_and_value_base(const MR_Stack_Layout_Var *var,
> +MR_get_type_and_value_base(const MR_Stack_Layout_Vars *vars, int i,
> Word *saved_regs, Word *base_sp, Word *base_curfr,
> Word *type_params, Word *type_info, Word *value)
> {
> bool succeeded;
> Word *pseudo_type_info;
> - int i;
>
> - if (!MR_LIVE_TYPE_IS_VAR(var->MR_slv_live_type)) {
> + if (!MR_LIVE_TYPE_IS_VAR(MR_var_pti(vars, i))) {
> return FALSE;
> }
>
> - pseudo_type_info = MR_LIVE_TYPE_GET_VAR_TYPE(var->MR_slv_live_type);
> + pseudo_type_info = MR_LIVE_TYPE_GET_VAR_TYPE(MR_var_pti(vars, i));
It would be better to write that as
pseudo_type_info = MR_LIVE_TYPE_GET_VAR_TYPE(MR_var_pti(vars, i));
if (!MR_LIVE_TYPE_IS_VAR(psuedo_type_info)) {
return FALSE;
}
> +++ mercury_stack_layout.h 1999/04/26 01:01:39
> +** (a) an integer with MR_LONG_LVAL_OFFSETBITS bits giving the index
> +** of the typeinfo inside a type class info (to be interpreted by
> +** private_builtin:type_info_from_typeclass_info), and (b) a MR_Long_Lval
> +** value giving the location of the pointer to the type class info.
> +** This MR_Long_Lval valud will *not* have an indirect tag.
s/valud/value/
> +#define MR_SHORT_LVAL_STACKVAR(n) \
> + ((MR_Short_Lval) (((n) << 2) + MR_SHORT_LVAL_TYPE_STACKVAR))
> +
> +#define MR_SHORT_LVAL_FRAMEVAR(n) \
> + ((MR_Short_Lval) (((n) << 2) + MR_SHORT_LVAL_TYPE_FRAMEVAR))
> +
> +#define MR_SHORT_LVAL_R_REG(n) \
> + ((MR_Short_Lval) (((n) << 2) + MR_SHORT_LVAL_TYPE_R))
The several occurrences of the number 2 should be replaced by a named
constant, e.g. MR_SHORT_LOCN_TAG_BITS.
> --- mercury_types.h 1998/12/15 00:22:29 1.14
> +++ mercury_types.h 1999/04/26 01:10:38
> @@ -26,10 +26,23 @@
> ** this is ensured by the autoconfiguration script.
> */
>
> -typedef unsigned WORD_TYPE Word;
> -typedef WORD_TYPE Integer;
> -typedef unsigned WORD_TYPE Unsigned;
> -typedef WORD_TYPE Bool;
> +#ifdef HAVE_STDINT
> +#include <stdint.h>
> +#else
> +typedef unsigned WORD_TYPE uintptr_t;
> +typedef WORD_TYPE intptr_t;
> +typedef unsigned INT32_TYPE uint_least32_t;
> +typedef INT32_TYPE int_least32_t;
> +typedef unsigned INT16_TYPE uint_least16_t;
> +typedef INT16_TYPE int_least16_t;
> +typedef unsigned char uint_least8_t;
> +typedef signed char int_least8_t;
> +#endif
The stuff inside the `#if' (i.e. the `#include' and the typedefs)
should be intended two spaces.
> --- mercury_trace.c 1999/02/23 08:06:54 1.8
> @@ -425,12 +431,19 @@
> return 0;
> }
>
> - for (i = 0; i < label->MR_sll_var_count; i++) {
> + for (i = 0; i < MR_all_desc_var_count(vars); i++) {
> if (streq(vars->MR_slvs_names[i], name)) {
> - return MR_lookup_live_lval_base(
> - vars->MR_slvs_pairs[i].MR_slv_locn, saved_regs,
> - MR_saved_sp(saved_regs),
> + if (i < MR_long_desc_var_count(vars)) {
> + return MR_lookup_long_lval_base(
> + MR_long_desc_var_locn(vars, i),
> + saved_regs, MR_saved_sp(saved_regs),
> + MR_saved_curfr(saved_regs), succeeded);
> + } else {
> + return MR_lookup_short_lval_base(
> + MR_short_desc_var_locn(vars, i),
> + saved_regs, MR_saved_sp(saved_regs),
> MR_saved_curfr(saved_regs), succeeded);
> + }
> }
> }
I think it would be better to avoid duplicating the common code here,
and write that as
Word locn; /* or whatever type is appropriate */
if (i < MR_long_desc_var_count(vars)) {
locn = MR_long_desc_var_locn(vars, i);
} else {
locn = MR_short_desc_var_locn(vars, i);
};
return MR_lookup_live_lval_base(locn, saved_regs,
MR_saved_sp(saved_regs),
MR_saved_curfr(saved_regs), succeeded);
> Index: trace/mercury_trace_external.c
> @@ -831,8 +831,7 @@
> ** due to the fake arity of the type private_builtin:typeinfo/1.
> */
> if ((strncmp(name, "TypeInfo", 8) == 0)
> - || (strncmp(name, "TypeClassInfo", 13) == 0)
> - ) {
> + || (strncmp(name, "TypeClassInfo", 13) == 0)) {
> continue;
> }
Neither the old code nor the new code conform to our coding standards
for indentation. The `{' should be on a line of its own, so it should
be
if ((...)
|| (...))
{
continue;
}
--
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.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list