[m-rev.] for review: reducing string table size

Zoltan Somogyi zs at csse.unimelb.edu.au
Wed Sep 21 19:44:09 AEST 2011


For review by anyone.

Zoltan.

Reduce the size of the string tables in debuggable executables by encoding
variable names that a few standard templates, the most important of which
is STATE_VARIABLE_name_number.

The effect on the compiler is to reduce the string table size from about
3.1Mb to about 2.1Mb, which is about a 30% reduction.

compiler/stack_layout.m:
	Look for the names fitting the patterns in variable names, and encode
	them.

runtime/mercury_stack_layout.[ch]:
	Add a function for looking up variable names, decoding them if needed.

	Since goal paths cannot fit any of the patterns, access them without
	using that function.

mdbcomp/rtti_access.m:
	Use the new function to retrieve variable names.

runtime/mercury_grade.h:
	Increment the debugging compatibility version number, since debuggable
	executables in which some modules were produced by a compiler without
	this diff and some were produced by a compiler with this diff won't
	work together.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.164
diff -u -b -r1.164 stack_layout.m
--- compiler/stack_layout.m	16 Sep 2011 07:03:35 -0000	1.164
+++ compiler/stack_layout.m	21 Sep 2011 09:38:58 -0000
@@ -2423,7 +2423,7 @@
     % without losing their edge, (b) this algorithm is fast enough in most
     % cases, and when it isn't, even KMP is unlikely to be fast enough.
     %
-    % Turning this on optimization reduces the size of the generated .c and .o
+    % Turning on this optimization reduces the size of the generated .c and .o
     % files by about 12% and 11% respectively (measured on the files in the
     % library, mdbcomp and compiler directories in grade asm_fast.gc.debug),
     % but even without the type_spec pragmas, it increases sequential bootcheck
@@ -2560,10 +2560,146 @@
     lookup_string_in_table("", _, !StringTable),
     lookup_string_in_table("<too many variables>", _, !StringTable).
 
-lookup_string_in_table(String, Offset, !StringTable) :-
+lookup_string_in_table(String, StringCode, !StringTable) :-
+    % The encoding used here is decoded by MR_name_in_string_table
+    % in runtime/mercury_stack_layout.c. The code here and there
+    % must be kept in sync.
+    (
+        is_var_name_in_special_form(String, KindCode, MaybeBaseName, N),
+        N < int.unchecked_left_shift(1, 10),
+        (
+            MaybeBaseName = yes(BaseName),
+            lookup_raw_string_in_table(BaseName, MaybeOffset, !StringTable),
+            MaybeOffset = yes(Offset),
+            Offset < int.unchecked_left_shift(1, 16)
+        ;
+            MaybeBaseName = no,
+            Offset = 0
+        )
+    ->
+        % | ... offset ... | ... N ... | Kind | 1 |
+        % special form indication: 1 bit:   bit 0
+        % kind indication:         5 bits:  bits 1-5
+        % N:                       10 bits: bits 6-15
+        % Offset:                  16 bits: bits 16-31
+        StringCode = 1 \/
+            int.unchecked_left_shift(KindCode, 1) \/
+            int.unchecked_left_shift(N, 6) \/
+            int.unchecked_left_shift(Offset, 16)
+    ;
+        lookup_raw_string_in_table(String, MaybeOffset, !StringTable),
+        (
+            MaybeOffset = yes(Offset)
+        ;
+            MaybeOffset = no,
+            % Says that the name of the variable is "TOO_MANY_VARIABLES".
+            Offset = 1
+        ),
+        StringCode = int.unchecked_left_shift(Offset, 1)
+    ).
+
+:- pred is_var_name_in_special_form(string::in,
+    int::out, maybe(string)::out, int::out) is semidet.
+
+is_var_name_in_special_form(String, KindCode, MaybeBaseName, N) :-
+    % state_var.m constructs variable names that always contain
+    % the state var name, and usually but not always a numeric suffix.
+    % The numeric suffic may be zero or positive. We could represent
+    % the lack of a suffix using a negative number, but mixing unsigned
+    % and signed fields in a single word is tricky, especially since
+    % the size of the variable name descriptor word we generate (32 bits)
+    % may or may not be the same as the word size of the compiler.
+    % Instead, we simply add one to any actual suffix values, and use
+    % zero to represent the absence of a numeric suffix.
+
+    % polymorphism.m adds a numeric suffix but no type name
+    % to type_ctor_infos and type_infos.
+
+    % polymorphism.m adds a class id but no numeric suffix to
+    % base_typeclass_infos and typeclass_infos. Since the usual string table
+    % already does a good enough job for these, the code for handling them
+    % specially is commented out.
+
+    ( string.remove_prefix("STATE_VARIABLE_", String, NoPrefix) ->
+        KindCode = 0,
+        string.to_char_list(NoPrefix, NoPrefixChars),
+        ( find_number_suffix(NoPrefixChars, BaseNameChars, Num) ->
+            string.from_char_list(BaseNameChars, BaseName),
+            MaybeBaseName = yes(BaseName),
+            N = Num + 1
+        ;
+            MaybeBaseName = yes(NoPrefix),
+            N = 0
+        )
+    ; string.remove_prefix("TypeCtorInfo_", String, NoPrefix) ->
+        ( string.to_int(NoPrefix, Num) ->
+            KindCode = 1,
+            MaybeBaseName = no,
+            N = Num
+        ;
+            fail
+        )
+    ; string.remove_prefix("TypeInfo_", String, NoPrefix) ->
+        ( string.to_int(NoPrefix, Num) ->
+            KindCode = 2,
+            MaybeBaseName = no,
+            N = Num
+        ;
+            fail
+        )
+%   ; string.remove_prefix("BaseTypeClassInfo_for_", String, NoPrefix) ->
+%       KindCode = 3,
+%       MaybeBaseName = yes(NoPrefix),
+%       N = 0
+%   ; string.remove_prefix("TypeClassInfo_for_", String, NoPrefix) ->
+%       KindCode = 4,
+%       MaybeBaseName = yes(NoPrefix),
+%       N = 0
+    ; string.remove_prefix("PolyConst", String, NoPrefix) ->
+        ( string.to_int(NoPrefix, Num) ->
+            KindCode = 5,
+            MaybeBaseName = no,
+            N = Num
+        ;
+            fail
+        )
+    ;
+        fail
+    ).
+
+    % Given e.g. "Info_15" as input, we return "Info" as BeforeNum
+    % and 15 as Num.
+    %
+:- pred find_number_suffix(list(char)::in, list(char)::out, int::out)
+    is semidet.
+
+find_number_suffix(String, BeforeNum, Num) :-
+    list.reverse(String, RevString),
+    rev_find_number_suffix(RevString, 0, Num, 1, Scale, RevRest),
+    Scale > 1,
+    list.reverse(RevRest, BeforeNum).
+
+:- pred rev_find_number_suffix(list(char)::in, int::in, int::out,
+    int::in, int::out, list(char)::out) is semidet.
+
+rev_find_number_suffix([RevHead | RevTail], !Num, !Scale, RevRest) :-
+    ( char.digit_to_int(RevHead, Digit) ->
+        !:Num = !.Num + (!.Scale * Digit),
+        !:Scale = !.Scale * 10,
+        rev_find_number_suffix(RevTail, !Num, !Scale, RevRest)
+    ; RevHead = '_' ->
+        RevRest = RevTail
+    ;
+        fail
+    ).
+
+:- pred lookup_raw_string_in_table(string::in, maybe(int)::out,
+    string_table::in, string_table::out) is det.
+
+lookup_raw_string_in_table(String, MaybeOffset, !StringTable) :-
     !.StringTable = string_table(TableMap0, TableList0, TableOffset0),
     ( map.search(TableMap0, String, OldOffset) ->
-        Offset = OldOffset
+        MaybeOffset = yes(OldOffset)
     ;
         Length = string.count_utf8_code_units(String),
         TableOffset = TableOffset0 + Length + 1,
@@ -2579,13 +2715,12 @@
         % of other compiler structures.)
         TableOffset < (1 << ((4 * byte_bits) - 2))
     ->
-        Offset = TableOffset0,
+        MaybeOffset = yes(TableOffset0),
         map.det_insert(String, TableOffset0, TableMap0, TableMap),
         TableList = [String | TableList0],
         !:StringTable = string_table(TableMap, TableList, TableOffset)
     ;
-        % Says that the name of the variable is "TOO_MANY_VARIABLES".
-        Offset = 1
+        MaybeOffset = no
     ).
 
 %---------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
Index: mdbcomp/rtti_access.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/rtti_access.m,v
retrieving revision 1.20
diff -u -b -r1.20 rtti_access.m
--- mdbcomp/rtti_access.m	20 May 2011 04:16:53 -0000	1.20
+++ mdbcomp/rtti_access.m	6 Sep 2011 06:25:25 -0000
@@ -244,7 +244,7 @@
         ( special_pred_name_arity(SpecialIdPrime, _, PredName, _) ->
             SpecialId = SpecialIdPrime
         ;
-            error("get_proc_label_from_layout: bad special_pred_id")
+            unexpected($module, $pred, "bad special_pred_id")
         ),
         SymDefModule = string_to_sym_name(DefModule),
         SymTypeModule = string_to_sym_name(TypeModule),
@@ -325,6 +325,7 @@
     const MR_ProcLayout     *proc;
     int                     out_hlds_num;
     const char              *out_name;
+    int                     should_copy_out;
 
     proc = Layout;
 
@@ -333,11 +334,12 @@
     }
 
     out_hlds_num = proc->MR_sle_head_var_nums[OutArgNum - 1];
-    out_name = MR_hlds_var_name(proc, out_hlds_num);
+    out_name = MR_hlds_var_name(proc, out_hlds_num, &should_copy_out);
     if (out_name == NULL || MR_streq(out_name, """")) {
         /* out_hlds_num was not named by the user */
         SUCCESS_INDICATOR = MR_FALSE;
     } else {
+        char                    out_name_buf[MR_MAX_VARNAME_SIZE];
         int                     out_base_name_len;
         int                     out_numerical_suffix;
         int                     num_matches;
@@ -352,6 +354,11 @@
         const MR_LabelLayout    *call_label;
         MR_bool                 found;
 
+        if (should_copy_out) {
+            strncpy(out_name_buf, out_name, MR_MAX_VARNAME_SIZE);
+            out_name = (const char *) out_name_buf;
+        }
+
         start_of_num = MR_find_start_of_num_suffix(out_name);
         if (start_of_num < 0) {
             out_base_name_len = strlen(out_name);
@@ -368,7 +375,7 @@
             head_var_num++)
         {
             in_hlds_num = proc->MR_sle_head_var_nums[head_var_num];
-            in_name = MR_hlds_var_name(proc, in_hlds_num);
+            in_name = MR_hlds_var_name(proc, in_hlds_num, NULL);
             if (in_name == NULL || MR_streq(in_name, """")) {
                 continue;
             }
@@ -620,24 +627,27 @@
     Size = ModuleCommonLayout->MR_mlc_string_table_size;
 ").
 
-lookup_string_table(StringTable, StartOffset) = Str :-
+lookup_string_table(StringTable, NameCode) = Str :-
     StringTable = string_table(StringTableChars, Size),
-    (
-        0 =< StartOffset,
-        StartOffset < Size
-    ->
-        Str = lookup_string_table_2(StringTableChars, StartOffset)
-    ;
-        error("lookup_string_table: bounds violation")
-    ).
+    Str = lookup_string_table_2(StringTableChars, Size, NameCode).
 
-:- func lookup_string_table_2(string_table_chars, int) = string.
+:- func lookup_string_table_2(string_table_chars, int, int) = string.
 
 :- pragma foreign_proc("C",
-    lookup_string_table_2(StringTableChars::in, StartOffset::in) = (Str::out),
+    lookup_string_table_2(StringTableChars::in, StringTableSize::in,
+        NameCode::in) = (Str::out),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
-    MR_make_aligned_string(Str, StringTableChars + StartOffset);
+    MR_ConstString  str0;
+    int             should_copy;
+
+    str0 = MR_name_in_string_table(StringTableChars, StringTableSize,
+        NameCode, &should_copy);
+    if (should_copy) {
+        MR_make_aligned_string(Str, str0);
+    } else {
+        MR_make_aligned_string_copy(Str, str0);
+    }
 ").
 
 %-----------------------------------------------------------------------------%
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.85
diff -u -b -r1.85 mercury_grade.h
--- runtime/mercury_grade.h	5 Jul 2011 03:34:36 -0000	1.85
+++ runtime/mercury_grade.h	6 Sep 2011 06:30:10 -0000
@@ -59,13 +59,13 @@
 ** RTTI version number.
 **
 ** The MR_GRADE_EXEC_TRACE_VERSION_NO, MR_GRADE_DEEP_PROF_VERSION_NO and
-** MR_GRADE_LLC_PAR_VERSION_NO macros should be incremented when a change breaks
-** binary backwards compatibility only in debugging, deep profiling and
-** low-level C parallel grades respectively.
+** MR_GRADE_LLC_PAR_VERSION_NO macros should be incremented when a change
+** breaks binary backwards compatibility only in debugging, deep profiling
+** and low-level C parallel grades respectively.
 */
 
 #define MR_GRADE_PART_0 v18_
-#define MR_GRADE_EXEC_TRACE_VERSION_NO  9
+#define MR_GRADE_EXEC_TRACE_VERSION_NO  10
 #define MR_GRADE_DEEP_PROF_VERSION_NO   3
 #define MR_GRADE_LLC_PAR_VERSION_NO 1
 
Index: runtime/mercury_stack_layout.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.c,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_stack_layout.c
--- runtime/mercury_stack_layout.c	12 Sep 2007 06:21:16 -0000	1.3
+++ runtime/mercury_stack_layout.c	21 Sep 2011 09:40:12 -0000
@@ -18,12 +18,13 @@
 #include "mercury_stack_layout.h"
 
 MR_ConstString
-MR_hlds_var_name(const MR_ProcLayout *entry, int hlds_var_num)
+MR_hlds_var_name(const MR_ProcLayout *entry, int hlds_var_num,
+    int *should_copy)
 {
     const MR_ModuleCommonLayout *module_common;
     const char                  *string_table;
     MR_Integer                  string_table_size;
-    int                         offset;
+    int                         name_code;
 
     module_common = entry->MR_sle_module_common_layout;
     string_table = module_common->MR_mlc_string_table;
@@ -40,12 +41,120 @@
     }
 
     /* variable number 1 is stored at offset 0 */
-    offset = entry->MR_sle_used_var_names[hlds_var_num - 1];
+    name_code = entry->MR_sle_used_var_names[hlds_var_num - 1];
+    return MR_name_in_string_table(string_table, string_table_size,
+        name_code, should_copy);
+}
+
+MR_ConstString
+MR_name_in_string_table(const char *string_table, MR_Integer string_table_size,
+    MR_uint_least32_t name_code, int *should_copy)
+{
+    // The encoding decoded here is create by lookup_string_in_table
+    // in compiler/stack_layout.m. The code here and there must be kept
+    // in sync.
+
+    if ((name_code & 0x1) != 0) {
+        static  char    buf[MR_MAX_VARNAME_SIZE];
+        int             kind;
+        int             n;
+        int             offset;
+
+        name_code >>= 1;
+        kind = name_code & 0x1f;
+        name_code >>= 5;
+        n = name_code & 0x3ff;
+        offset = name_code >> 10;
+
+        switch (kind) {
+            case 0:
+                if (n == 0) {
+#ifdef  MR_HAVE_SNPRINTF
+                    snprintf(buf, MR_MAX_VARNAME_SIZE, "STATE_VARIABLE_%s",
+                        string_table + offset);
+#else
+                    sprintf(buf, "STATE_VARIABLE_%s",
+                        string_table + offset);
+#endif
+                } else {
+#ifdef  MR_HAVE_SNPRINTF
+                    snprintf(buf, MR_MAX_VARNAME_SIZE, "STATE_VARIABLE_%s_%d",
+                        string_table + offset, n - 1);
+#else
+                    sprintf(buf, "STATE_VARIABLE_%s_%d",
+                        string_table + offset, n - 1);
+#endif
+                }
+                break;
+
+            case 1:
+#ifdef  MR_HAVE_SNPRINTF
+                snprintf(buf, MR_MAX_VARNAME_SIZE, "TypeCtorInfo_%d", n);
+#else
+                sprintf(buf, "TypeCtorInfo_%d", n);
+#endif
+                break;
+
+            case 2:
+#ifdef  MR_HAVE_SNPRINTF
+                snprintf(buf, MR_MAX_VARNAME_SIZE, "TypeInfo_%d", n);
+#else
+                sprintf(buf, "TypeInfo_%d", n);
+#endif
+                break;
+
+            case 3:
+#ifdef  MR_HAVE_SNPRINTF
+                snprintf(buf, MR_MAX_VARNAME_SIZE, "BaseTypeClassInfo_for_%s",
+                    string_table + offset);
+#else
+                sprintf(buf, "BaseTypeClassInfo_for_%s",
+                    string_table + offset);
+#endif
+                break;
+
+            case 4:
+#ifdef  MR_HAVE_SNPRINTF
+                snprintf(buf, MR_MAX_VARNAME_SIZE, "TypeClassInfo_for_%s",
+                    string_table + offset);
+#else
+                sprintf(buf, "TypeClassInfo_for_%s",
+                    string_table + offset);
+#endif
+                break;
+
+            case 5:
+#ifdef  MR_HAVE_SNPRINTF
+                snprintf(buf, MR_MAX_VARNAME_SIZE, "PolyConst%d", n);
+#else
+                sprintf(buf, "PolyConst%d", n);
+#endif
+                break;
+
+            default:
+                MR_fatal_error("MR_hlds_var_name: unknown kind");
+                break;
+        }
+
+        if (should_copy != NULL) {
+            *should_copy = MR_TRUE;
+        }
+
+        return buf;
+    } else {
+        int offset;
+
+        offset = name_code >> 1;
     if (offset > string_table_size) {
         MR_fatal_error("MR_hlds_var_name: bounds error on string table");
     }
 
+        if (should_copy != NULL) {
+            *should_copy = MR_FALSE;
+        }
+
     return string_table + offset;
+    }
 }
 
 int
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.120
diff -u -b -r1.120 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	11 Oct 2010 00:49:27 -0000	1.120
+++ runtime/mercury_stack_layout.h	6 Sep 2011 14:35:48 -0000
@@ -518,7 +518,7 @@
     ((MR_PROC_LAYOUT_HAS_EXEC_TRACE((layout)->MR_sll_entry)) ?              \
         ((layout)->MR_sll_entry->MR_sle_module_layout                       \
             ->MR_ml_string_table                                            \
-        + (layout)->MR_sll_goal_path)                                       \
+        + ((layout)->MR_sll_goal_path >> 1))                                \
     : "")
 
 #define MR_SHORT_COUNT_BITS 10
@@ -1339,13 +1339,37 @@
     ((entry)->MR_sle_user.MR_user_arity -                                   \
         (((entry)->MR_sle_user.MR_user_pred_or_func == MR_FUNCTION) ? 1 : 0))
 
+#define MR_MAX_VARNAME_SIZE 160
+
 /*
 ** Return the name (if any) of the variable with the given HLDS variable number
 ** in the procedure indicated by the first argument.
+**
+** The name will actually be found by MR_name_in_string_table, so the
+** comments there about name size and should_copy apply here as well.
 */
 
 extern  MR_ConstString  MR_hlds_var_name(const MR_ProcLayout *entry,
-                            int hlds_var_num);
+                            int hlds_var_num, int *should_copy);
+
+/*
+** Return the name (if any) of the variable with the given name code
+** in the given string table.
+**
+** Sometimes, the returned name will point to static, const storage,
+** whose contents are valid until the end of the program's execution,
+** while at other times, it will point to a buffer whose contents
+** will be valid only until the next call to MR_name_in_string_table.
+**
+** Callers that want to know which is the case should pass a non-NULL
+** value for should_copy. The returned name will point to the buffer
+** if and only if *should_copy is true. The size of the buffer is
+** MR_MAX_VARNAME_SIZE bytes.
+*/
+
+extern  MR_ConstString  MR_name_in_string_table(const char *string_table,
+                            MR_Integer string_table_size,
+                            MR_uint_least32_t name_code, int *should_copy);
 
 /*
 ** Given a string, see whether its end consists a sequence of digits.
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.87
diff -u -b -r1.87 mercury_trace_vars.c
--- trace/mercury_trace_vars.c	6 Sep 2011 05:20:45 -0000	1.87
+++ trace/mercury_trace_vars.c	7 Sep 2011 07:37:15 -0000
@@ -655,7 +655,7 @@
         char            *num_addr;
 
         hlds_var_num = level_layout->MR_sll_var_nums[i];
-        name = MR_hlds_var_name(entry, hlds_var_num);
+        name = MR_hlds_var_name(entry, hlds_var_num, NULL);
 
 #ifdef  MR_DEBUG_LVAL_REP
         printf("i %d, hlds_var_num %d, name %s\n", i, hlds_var_num, name);
@@ -2139,8 +2139,8 @@
     switch (value->MR_value_kind) {
         case MR_VALUE_ATTRIBUTE:
             attr = &value->MR_value_attr;
-            attr_var_name =
-                MR_hlds_var_name(proc, attr->MR_attr_var_hlds_number);
+            attr_var_name = MR_hlds_var_name(proc,
+                attr->MR_attr_var_hlds_number, NULL);
 #ifdef  MR_HAVE_SNPRINTF
             if (attr_var_name != NULL && strcmp(attr_var_name, "") != 0) {
                 snprintf(MR_var_name_buf, MR_TRACE_VAR_NAME_BUF_SIZE,
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list