mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-13 21:04:00 +00:00
Estimated hours taken: 6 Branches: main Reduce the size of the string tables in debuggable executables by encoding variable names that fit 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.
181 lines
4.7 KiB
C
181 lines
4.7 KiB
C
/*
|
|
** vim:sw=4 ts=4 expandtab
|
|
*/
|
|
/*
|
|
** Copyright (C) 2005-2007, 2011 The University of Melbourne.
|
|
** This file may only be copied under the terms of the GNU Library General
|
|
** Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
*/
|
|
|
|
/*
|
|
** This file implements utility functions operating on the data structures
|
|
** defined in the corresponding header file.
|
|
**
|
|
** Author: Zoltan Somogyi
|
|
*/
|
|
|
|
#include "mercury_imp.h"
|
|
#include "mercury_stack_layout.h"
|
|
|
|
MR_ConstString
|
|
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 name_code;
|
|
|
|
module_common = entry->MR_sle_module_common_layout;
|
|
string_table = module_common->MR_mlc_string_table;
|
|
string_table_size = module_common->MR_mlc_string_table_size;
|
|
|
|
if (hlds_var_num == 0) {
|
|
/* this value is not a variable */
|
|
return NULL;
|
|
}
|
|
|
|
if (hlds_var_num > entry->MR_sle_max_named_var_num) {
|
|
/* this value is a compiler-generated variable */
|
|
return NULL;
|
|
}
|
|
|
|
/* variable number 1 is stored at offset 0 */
|
|
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
|
|
MR_find_start_of_num_suffix(const char *str)
|
|
{
|
|
int len;
|
|
const char *s;
|
|
|
|
len = strlen(str);
|
|
s = str + len - 1;
|
|
while (s > str && MR_isdigit(*s)) {
|
|
s--;
|
|
}
|
|
|
|
if (s == str + len - 1) {
|
|
return -1;
|
|
} else {
|
|
/* *(s+1) is the first character of the numerical suffix */
|
|
return (s + 1) - str;
|
|
}
|
|
}
|