mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 12:52:46 +00:00
various memory saving tricks. seems to have not broken anything
This commit is contained in:
parent
4e467ac8df
commit
001571e25a
12 changed files with 140 additions and 103 deletions
|
@ -36,12 +36,12 @@
|
|||
|
||||
typedef struct function_s {
|
||||
struct function_s *next;
|
||||
dfunction_t *dfunc;
|
||||
pr_auxfunction_t *aux; // debug info;
|
||||
int builtin; // if non 0, call an internal function
|
||||
int code; // first statement
|
||||
int function_num;
|
||||
const char *file; // source file with definition
|
||||
string_t s_file; // source file with definition
|
||||
string_t s_name;
|
||||
int file_line;
|
||||
struct def_s *def;
|
||||
struct scope_s *scope;
|
||||
|
@ -67,10 +67,11 @@ param_t *_reverse_params (param_t *params, param_t *next);
|
|||
param_t *reverse_params (param_t *params);
|
||||
struct type_s *parse_params (struct type_s *type, param_t *params);
|
||||
void build_scope (function_t *f, struct def_s *func, param_t *params);
|
||||
function_t *new_function (void);
|
||||
function_t *new_function (const char *name);
|
||||
function_t *build_builtin_function (struct def_s *def, struct expr_s *bi_val);
|
||||
void build_function (function_t *f);
|
||||
void finish_function (function_t *f);
|
||||
void emit_function (function_t *f, struct expr_s *e);
|
||||
int function_parms (function_t *f, byte *parm_size);
|
||||
|
||||
#endif//__function_h
|
||||
|
|
|
@ -92,6 +92,8 @@ extern string_t s_file; // filename for function definition
|
|||
|
||||
const char *strip_path (const char *filename);
|
||||
|
||||
const char *save_string (const char *str);
|
||||
|
||||
#define ALLOC(s, t, n, v) \
|
||||
do { \
|
||||
if (!free_##n) { \
|
||||
|
|
|
@ -475,7 +475,7 @@ class_finish_module (void)
|
|||
|
||||
exec_class_def = get_def (&type_obj_exec_class, "__obj_exec_class",
|
||||
pr.scope, 1);
|
||||
exec_class_func = new_function ();
|
||||
exec_class_func = new_function ("__obj_exec_class");
|
||||
exec_class_func->builtin = 0;
|
||||
exec_class_func->def = exec_class_def;
|
||||
exec_class_func->refs = new_reloc (exec_class_def->ofs, rel_def_func);
|
||||
|
@ -483,7 +483,7 @@ class_finish_module (void)
|
|||
finish_function (exec_class_func);
|
||||
|
||||
init_def = get_def (&type_function, ".ctor", pr.scope, 1);
|
||||
init_func = new_function ();
|
||||
init_func = new_function (".ctor");
|
||||
init_func->def = init_def;
|
||||
init_func->refs = new_reloc (init_def->ofs, rel_def_func);
|
||||
init_func->code = pr.num_statements;
|
||||
|
|
|
@ -134,9 +134,10 @@ static void
|
|||
vector_component (def_t *vec, int comp, scope_t *scope)
|
||||
{
|
||||
def_t *d;
|
||||
const char *name;
|
||||
|
||||
d = new_def (&type_float, va (vector_component_names[comp], vec->name),
|
||||
scope);
|
||||
name = save_string (va (vector_component_names[comp], vec->name));
|
||||
d = new_def (&type_float, name, scope);
|
||||
d->used = 1;
|
||||
d->parent = vec;
|
||||
d->ofs = vec->ofs + comp;
|
||||
|
@ -147,9 +148,10 @@ static void
|
|||
vector_field_component (def_t *vec, int comp, scope_t *scope)
|
||||
{
|
||||
def_t *d;
|
||||
const char *name;
|
||||
|
||||
d = new_def (&type_floatfield, va (vector_component_names[comp], vec->name),
|
||||
scope);
|
||||
name = save_string (va (vector_component_names[comp], vec->name));
|
||||
d = new_def (&type_floatfield, name, scope);
|
||||
d->used = 1; // always `used'
|
||||
d->parent = vec;
|
||||
d->ofs = vec->ofs + comp;
|
||||
|
@ -217,7 +219,7 @@ new_def (type_t *type, const char *name, scope_t *scope)
|
|||
|
||||
def->return_addr = __builtin_return_address (0);
|
||||
|
||||
def->name = name ? strdup (name) : 0;
|
||||
def->name = name;
|
||||
def->type = type;
|
||||
|
||||
def->scope = scope;
|
||||
|
|
|
@ -669,21 +669,20 @@ print_expr (expr_t *e)
|
|||
static expr_t *
|
||||
do_op_string (int op, expr_t *e1, expr_t *e2)
|
||||
{
|
||||
int len;
|
||||
char *buf;
|
||||
const char *s1, *s2;
|
||||
static dstring_t *temp_str;
|
||||
|
||||
s1 = e1->e.string_val ? e1->e.string_val : "";
|
||||
s2 = e2->e.string_val ? e2->e.string_val : "";
|
||||
|
||||
switch (op) {
|
||||
case '+':
|
||||
len = strlen (s1) + strlen (s2) + 1;
|
||||
buf = malloc (len);
|
||||
SYS_CHECKMEM (buf);
|
||||
strcpy (buf, s1);
|
||||
strcat (buf, s2);
|
||||
e1->e.string_val = buf;
|
||||
if (!temp_str)
|
||||
temp_str = dstring_newstr ();
|
||||
dstring_clearstr (temp_str);
|
||||
dstring_appendstr (temp_str, s1);
|
||||
dstring_appendstr (temp_str, s2);
|
||||
e1->e.string_val = save_string (temp_str->str);
|
||||
break;
|
||||
case LT:
|
||||
e1->type = ex_integer;
|
||||
|
|
|
@ -54,11 +54,15 @@ static const char rcsid[] =
|
|||
#include "reloc.h"
|
||||
#include "type.h"
|
||||
|
||||
static param_t *free_params;
|
||||
static function_t *free_functions;
|
||||
|
||||
param_t *
|
||||
new_param (const char *selector, type_t *type, const char *name)
|
||||
{
|
||||
param_t *param = malloc (sizeof (param_t));
|
||||
param_t *param;
|
||||
|
||||
ALLOC (4096, param_t, params, param);
|
||||
param->next = 0;
|
||||
param->selector = selector;
|
||||
param->type = type;
|
||||
|
@ -165,14 +169,17 @@ build_scope (function_t *f, def_t *func, param_t *params)
|
|||
}
|
||||
|
||||
function_t *
|
||||
new_function (void)
|
||||
new_function (const char *name)
|
||||
{
|
||||
function_t *f;
|
||||
|
||||
f = calloc (1, sizeof (function_t));
|
||||
ALLOC (1024, function_t, functions, f);
|
||||
|
||||
*pr.func_tail = f;
|
||||
pr.func_tail = &f->next;
|
||||
f->function_num = pr.num_functions++;
|
||||
f->s_name = ReuseString (name);
|
||||
f->s_file = s_file;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -191,7 +198,7 @@ build_builtin_function (def_t *def, expr_t *bi_val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
f = new_function ();
|
||||
f = new_function (def->name);
|
||||
|
||||
f->builtin = bi_val->type == ex_integer ? bi_val->e.integer_val
|
||||
: (int)bi_val->e.float_val;
|
||||
|
@ -213,28 +220,6 @@ build_function (function_t *f)
|
|||
void
|
||||
finish_function (function_t *f)
|
||||
{
|
||||
dfunction_t *df;
|
||||
int i, count;
|
||||
|
||||
df = calloc (1, sizeof (dfunction_t));
|
||||
f->dfunc = df;
|
||||
|
||||
if (f->builtin)
|
||||
df->first_statement = -f->builtin;
|
||||
else
|
||||
df->first_statement = f->code;
|
||||
|
||||
df->s_name = ReuseString (f->def->name);
|
||||
df->s_file = s_file;
|
||||
df->numparms = f->def->type->num_parms;
|
||||
if (f->scope)
|
||||
df->locals = f->scope->space->size;
|
||||
df->parm_start = 0;
|
||||
if ((count = df->numparms) < 0)
|
||||
count = -count - 1;
|
||||
for (i = 0; i < count; i++)
|
||||
df->parm_size[i] = type_size (f->def->type->parm_types[i]);
|
||||
|
||||
if (f->aux) {
|
||||
def_t *def;
|
||||
f->aux->function = f->function_num;
|
||||
|
@ -275,3 +260,18 @@ emit_function (function_t *f, expr_t *e)
|
|||
|
||||
//puts ("");
|
||||
}
|
||||
|
||||
int
|
||||
function_parms (function_t *f, byte *parm_size)
|
||||
{
|
||||
int count, i;
|
||||
|
||||
if (f->def->type->num_parms >= 0)
|
||||
count = f->def->type->num_parms;
|
||||
else
|
||||
count = -f->def->type->num_parms - 1;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
parm_size[i] = type_size (f->def->type->parm_types[i]);
|
||||
return f->def->type->num_parms;
|
||||
}
|
||||
|
|
|
@ -166,8 +166,8 @@ setup_data (void)
|
|||
for (d = pr.scope->head; d; d = d->def_next)
|
||||
write_def (d, def++, &reloc);
|
||||
for (f = pr.func_head; f; f = f->next) {
|
||||
func->name = LittleLong (f->dfunc->s_name);
|
||||
func->file = LittleLong (f->dfunc->s_file);
|
||||
func->name = LittleLong (f->s_name);
|
||||
func->file = LittleLong (f->s_file);
|
||||
func->line = LittleLong (f->def->line);
|
||||
func->builtin = LittleLong (f->builtin);
|
||||
func->code = LittleLong (f->code);
|
||||
|
@ -182,8 +182,7 @@ setup_data (void)
|
|||
func->num_local_defs = LittleLong (f->scope->num_defs);
|
||||
if (f->aux)
|
||||
func->line_info = LittleLong (f->aux->line_info);
|
||||
func->num_parms = LittleLong (f->dfunc->numparms);
|
||||
memcpy (func->parm_size, f->dfunc->parm_size, MAX_PARMS);
|
||||
func->num_parms = LittleLong (function_parms (f, func->parm_size));
|
||||
func->relocs = LittleLong (reloc - relocs);
|
||||
write_relocs (f->refs, &reloc);
|
||||
|
||||
|
|
|
@ -43,8 +43,10 @@ static const char rcsid[] =
|
|||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <QF/dstring.h>
|
||||
#include <QF/hash.h>
|
||||
#include <QF/sys.h>
|
||||
|
||||
#include "qfcc.h"
|
||||
#include "expr.h"
|
||||
#include "class.h"
|
||||
|
@ -62,7 +64,7 @@ int do_grab (char *token);
|
|||
|
||||
void add_frame_macro (char *token);
|
||||
|
||||
char *make_string (char *token);
|
||||
const char *make_string (char *token);
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
extern int element_flag;
|
||||
|
@ -136,18 +138,18 @@ m ([\-+]?)
|
|||
}
|
||||
|
||||
'(\\[^xX0-7\r\n]|[^'\r\n]|\\[xX][0-9A-Fa-f]+|\\[0-7]+)*' {
|
||||
char *str = make_string (yytext);
|
||||
const char *str = make_string (yytext);
|
||||
|
||||
if (str[1])
|
||||
warning (0, "multibyte char constant");
|
||||
yylval.integer_val = *str;
|
||||
free (str);
|
||||
return INT_VAL;
|
||||
}
|
||||
|
||||
^#{s}+{DIGIT}+{s}+\"(\.|[^"\n])*\".*$ {
|
||||
char *p;
|
||||
char *s;
|
||||
const char *str;
|
||||
int line;
|
||||
|
||||
p = yytext + 1;
|
||||
|
@ -157,12 +159,11 @@ m ([\-+]?)
|
|||
p++;
|
||||
if (!*p)
|
||||
error (0, "Unexpected end of file");
|
||||
s = make_string (p); // grab the filename
|
||||
str = make_string (p); // grab the filename
|
||||
while (*p && *p != '\n') // ignore flags
|
||||
p++;
|
||||
pr_source_line = line - 1;
|
||||
s_file = ReuseString (strip_path (s));
|
||||
free (s);
|
||||
s_file = ReuseString (strip_path (str));
|
||||
}
|
||||
|
||||
[+\-*/&|^%]= {
|
||||
|
@ -335,7 +336,7 @@ type_or_name (char *token)
|
|||
yylval.type = type;
|
||||
return TYPE;
|
||||
}
|
||||
yylval.string_val = strdup (token);
|
||||
yylval.string_val = save_string (token);
|
||||
return NAME;
|
||||
}
|
||||
|
||||
|
@ -369,7 +370,6 @@ static void
|
|||
frame_free (void *_f, void *unused)
|
||||
{
|
||||
frame_t *f = (frame_t *)_f;
|
||||
free ((char*)f->name);
|
||||
f->next = free_frames;
|
||||
free_frames = f;
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ add_frame_macro (char *token)
|
|||
frame_t *frame;
|
||||
ALLOC (1024, frame_t, frames, frame);
|
||||
|
||||
frame->name = strdup (token);
|
||||
frame->name = save_string (token);
|
||||
frame->num = frame_number++;
|
||||
Hash_Add (frame_tab, frame);
|
||||
}
|
||||
|
@ -425,18 +425,22 @@ clear_frame_macros (void)
|
|||
Hash_FlushTable (frame_tab);
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
make_string (char *token)
|
||||
{
|
||||
char *str, *s;
|
||||
char s[2];
|
||||
int c;
|
||||
int i;
|
||||
int mask;
|
||||
int boldnext;
|
||||
int quote;
|
||||
static dstring_t *str;
|
||||
|
||||
s = str = malloc (strlen (token) + 1);
|
||||
SYS_CHECKMEM (str);
|
||||
if (!str)
|
||||
str = dstring_newstr ();
|
||||
dstring_clearstr (str);
|
||||
|
||||
s[1] = 0;
|
||||
|
||||
mask = 0x00;
|
||||
boldnext = 0;
|
||||
|
@ -574,17 +578,17 @@ make_string (char *token)
|
|||
break;
|
||||
}
|
||||
} else if (c == quote) {
|
||||
*s++ = 0;
|
||||
break;;
|
||||
}
|
||||
if (boldnext)
|
||||
c = c ^ 0x80;
|
||||
boldnext = 0;
|
||||
c = c ^ mask;
|
||||
*s++ = c;
|
||||
s[0] = c;
|
||||
dstring_appendstr (str, s);
|
||||
} while (1);
|
||||
|
||||
return str;
|
||||
return save_string (str->str);
|
||||
}
|
||||
|
||||
static void *(*const yy_flex_realloc_hack)(void *,yy_size_t) = yy_flex_realloc;
|
||||
|
|
|
@ -96,7 +96,7 @@ void free_local_inits (hashtab_t *def_list);
|
|||
expr_t *expr;
|
||||
int integer_val;
|
||||
float float_val;
|
||||
char *string_val;
|
||||
const char *string_val;
|
||||
float vector_val[3];
|
||||
float quaternion_val[4];
|
||||
struct function_s *function;
|
||||
|
@ -479,7 +479,7 @@ opt_comma
|
|||
begin_function
|
||||
: /*empty*/
|
||||
{
|
||||
$$ = current_func = new_function ();
|
||||
$$ = current_func = new_function (current_def->name);
|
||||
$$->def = current_def;
|
||||
$$->refs = new_reloc ($$->def->ofs, rel_def_func);
|
||||
$$->code = pr.num_statements;
|
||||
|
@ -1204,29 +1204,29 @@ keywordselector
|
|||
|
||||
selector
|
||||
: NAME
|
||||
| TYPE { $$ = strdup (yytext); }
|
||||
| TYPE { $$ = save_string (yytext); }
|
||||
| reserved_word
|
||||
;
|
||||
|
||||
reserved_word
|
||||
: LOCAL { $$ = strdup (yytext); }
|
||||
| RETURN { $$ = strdup (yytext); }
|
||||
| WHILE { $$ = strdup (yytext); }
|
||||
| DO { $$ = strdup (yytext); }
|
||||
| IF { $$ = strdup (yytext); }
|
||||
| ELSE { $$ = strdup (yytext); }
|
||||
| FOR { $$ = strdup (yytext); }
|
||||
| BREAK { $$ = strdup (yytext); }
|
||||
| CONTINUE { $$ = strdup (yytext); }
|
||||
| SWITCH { $$ = strdup (yytext); }
|
||||
| CASE { $$ = strdup (yytext); }
|
||||
| DEFAULT { $$ = strdup (yytext); }
|
||||
| NIL { $$ = strdup (yytext); }
|
||||
| STRUCT { $$ = strdup (yytext); }
|
||||
| UNION { $$ = strdup (yytext); }
|
||||
| ENUM { $$ = strdup (yytext); }
|
||||
| TYPEDEF { $$ = strdup (yytext); }
|
||||
| SUPER { $$ = strdup (yytext); }
|
||||
: LOCAL { $$ = save_string (yytext); }
|
||||
| RETURN { $$ = save_string (yytext); }
|
||||
| WHILE { $$ = save_string (yytext); }
|
||||
| DO { $$ = save_string (yytext); }
|
||||
| IF { $$ = save_string (yytext); }
|
||||
| ELSE { $$ = save_string (yytext); }
|
||||
| FOR { $$ = save_string (yytext); }
|
||||
| BREAK { $$ = save_string (yytext); }
|
||||
| CONTINUE { $$ = save_string (yytext); }
|
||||
| SWITCH { $$ = save_string (yytext); }
|
||||
| CASE { $$ = save_string (yytext); }
|
||||
| DEFAULT { $$ = save_string (yytext); }
|
||||
| NIL { $$ = save_string (yytext); }
|
||||
| STRUCT { $$ = save_string (yytext); }
|
||||
| UNION { $$ = save_string (yytext); }
|
||||
| ENUM { $$ = save_string (yytext); }
|
||||
| TYPEDEF { $$ = save_string (yytext); }
|
||||
| SUPER { $$ = save_string (yytext); }
|
||||
;
|
||||
|
||||
keyworddecl
|
||||
|
|
|
@ -98,6 +98,27 @@ const char *big_function = 0;
|
|||
ddef_t *fields;
|
||||
int numfielddefs;
|
||||
|
||||
hashtab_t *saved_strings;
|
||||
|
||||
static const char *
|
||||
ss_get_key (void *s, void *unused)
|
||||
{
|
||||
return (const char *)s;
|
||||
}
|
||||
|
||||
const char *
|
||||
save_string (const char *str)
|
||||
{
|
||||
char *s;
|
||||
if (!saved_strings)
|
||||
saved_strings = Hash_NewTable (16381, ss_get_key, 0, 0);
|
||||
s = Hash_Find (saved_strings, str);
|
||||
if (s)
|
||||
return s;
|
||||
s = strdup (str);
|
||||
Hash_Add (saved_strings, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
InitData (void)
|
||||
|
@ -134,8 +155,8 @@ WriteData (int crc)
|
|||
FILE *h;
|
||||
int i;
|
||||
|
||||
globals = calloc (pr.scope->num_defs, sizeof (ddef_t));
|
||||
fields = calloc (pr.scope->num_defs, sizeof (ddef_t));
|
||||
globals = calloc (pr.scope->num_defs + 1, sizeof (ddef_t));
|
||||
fields = calloc (pr.scope->num_defs + 1, sizeof (ddef_t));
|
||||
|
||||
for (def = pr.scope->head; def; def = def->def_next) {
|
||||
if (!def->global || !def->name)
|
||||
|
@ -192,20 +213,17 @@ WriteData (int crc)
|
|||
SafeWrite (h, pr.statements, pr.num_statements * sizeof (dstatement_t));
|
||||
|
||||
{
|
||||
function_t *f;
|
||||
dfunction_t *df;
|
||||
|
||||
progs.ofs_functions = ftell (h);
|
||||
progs.numfunctions = pr.num_functions;
|
||||
pr.functions = malloc (pr.num_functions * sizeof (dfunction_t));
|
||||
for (i = 1, f = pr.func_head; f; i++, f = f->next) {
|
||||
pr.functions[i].first_statement =
|
||||
LittleLong (f->dfunc->first_statement);
|
||||
pr.functions[i].parm_start = LittleLong (f->dfunc->parm_start);
|
||||
pr.functions[i].s_name = LittleLong (f->dfunc->s_name);
|
||||
pr.functions[i].s_file = LittleLong (f->dfunc->s_file);
|
||||
pr.functions[i].numparms = LittleLong (f->dfunc->numparms);
|
||||
pr.functions[i].locals = LittleLong (f->dfunc->locals);
|
||||
memcpy (pr.functions[i].parm_size, f->dfunc->parm_size, MAX_PARMS);
|
||||
for (i = 0, df = pr.functions + 1; i < pr.num_functions; i++, df++) {
|
||||
df->first_statement = LittleLong (df->first_statement);
|
||||
df->parm_start = LittleLong (df->parm_start);
|
||||
df->s_name = LittleLong (df->s_name);
|
||||
df->s_file = LittleLong (df->s_file);
|
||||
df->numparms = LittleLong (df->numparms);
|
||||
df->locals = LittleLong (df->locals);
|
||||
}
|
||||
SafeWrite (h, pr.functions, pr.num_functions * sizeof (dfunction_t));
|
||||
}
|
||||
|
@ -320,6 +338,7 @@ finish_compilation (void)
|
|||
def_t *def;
|
||||
expr_t e;
|
||||
ex_label_t *l;
|
||||
dfunction_t *df;
|
||||
|
||||
class_finish_module ();
|
||||
// check to make sure all functions prototyped have code
|
||||
|
@ -351,14 +370,25 @@ finish_compilation (void)
|
|||
relocate_refs (def->refs, def->ofs);
|
||||
}
|
||||
|
||||
for (f = pr.func_head; f; f = f->next) {
|
||||
if (f->builtin || !f->code)
|
||||
pr.functions = calloc (pr.num_functions + 1, sizeof (dfunction_t));
|
||||
for (df = pr.functions + 1, f = pr.func_head; f; df++, f = f->next) {
|
||||
df->s_name = f->s_name;
|
||||
df->s_file = f->s_file;
|
||||
df->numparms = function_parms (f, df->parm_size);
|
||||
if (f->scope)
|
||||
df->locals = f->scope->space->size;
|
||||
if (f->builtin) {
|
||||
df->first_statement = -f->builtin;
|
||||
continue;
|
||||
}
|
||||
if (!f->code)
|
||||
continue;
|
||||
df->first_statement = f->code;
|
||||
if (f->scope->space->size > num_localdefs) {
|
||||
num_localdefs = f->scope->space->size;
|
||||
big_function = f->def->name;
|
||||
}
|
||||
f->dfunc->parm_start = pr.near_data->size;
|
||||
df->parm_start = pr.near_data->size;
|
||||
for (def = f->scope->head; def; def = def->def_next) {
|
||||
if (def->absolute)
|
||||
continue;
|
||||
|
|
|
@ -116,7 +116,7 @@ new_reloc (int ofs, reloc_type type)
|
|||
{
|
||||
reloc_t *ref;
|
||||
|
||||
ALLOC (1024, reloc_t, refs, ref);
|
||||
ALLOC (16384, reloc_t, refs, ref);
|
||||
ref->ofs = ofs;
|
||||
ref->type = type;
|
||||
return ref;
|
||||
|
|
|
@ -146,7 +146,7 @@ new_struct (const char *name)
|
|||
strct->type->class = (struct class_s *)strct;
|
||||
strct->is_union = 0;
|
||||
if (name) {
|
||||
strct->type->name = strdup (name);
|
||||
strct->type->name = save_string (name);
|
||||
Hash_Add (structs, strct);
|
||||
}
|
||||
return strct->type;
|
||||
|
|
Loading…
Reference in a new issue