redo how progs strings are stored so multiple pools can exist

This commit is contained in:
Bill Currie 2002-07-05 20:02:10 +00:00
parent 5f1384828c
commit 8a402381e6
17 changed files with 304 additions and 83 deletions

View file

@ -2,4 +2,4 @@ AUTOMAKE_OPTIONS= foreign
EXTRA_DIST= class.h cmdlib.h cpp.h debug.h def.h expr.h function.h idstuff.h \
immediate.h linker.h method.h obj_file.h opcodes.h options.h \
qfcc.h reloc.h struct.h switch.h type.h
qfcc.h reloc.h strpool.h struct.h switch.h type.h

View file

@ -35,7 +35,6 @@
struct expr_s;
struct def_s *ReuseConstant (struct expr_s *expr, struct def_s *def);
int CopyString (const char *str);
int ReuseString (const char *str);
void clear_immediates (void);

View file

@ -3,7 +3,7 @@
object file support
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2002/6/16
@ -123,7 +123,7 @@ typedef struct qfo_s {
#define QFO_FLOAT(q, o) QFO_var (q, float, o)
#define QFO_INT(q, o) QFO_var (q, integer, o)
#define QFO_VECTOR(q, o) QFO_var (q, vector, o)
#define QFO_STRING(q, o) (pr.strings + QFO_var (q, string, o))
#define QFO_STRING(q, o) G_GETSTR (QFO_var (q, string, o))
#define QFO_FUNCTION(q, o) QFO_var (q, func, o)
#define QFO_POINTER(q, t,o) ((t *)((q)->data + o))
#define QFO_STRUCT(q, t,o) (*QFO_POINTER (q, t, o))

View file

@ -48,9 +48,7 @@ typedef struct pr_info_s {
struct type_s *types;
struct ex_label_s *labels;
char *strings;
int strofs;
int strings_size;
struct strpool_s *strings;
dstatement_t *statements;
int *statement_linenums;
@ -80,11 +78,12 @@ extern char destfile[];
extern struct scope_s *current_scope;
#define G_GETSTR(s) (pr.strings->strings + (s))
#define G_var(t, o) (pr.near_data->data[o].t##_var)
#define G_FLOAT(o) G_var (float, o)
#define G_INT(o) G_var (integer, o)
#define G_VECTOR(o) G_var (vector, o)
#define G_STRING(o) (pr.strings + G_var (string, o))
#define G_STRING(o) G_GETSTR (G_var (string, o))
#define G_FUNCTION(o) G_var (func, o)
#define G_POINTER(t,o) ((t *)(pr.near_data->data + o))
#define G_STRUCT(t,o) (*G_POINTER (t, o))

View file

@ -0,0 +1,46 @@
/*
strpool.h
unique strings support
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2002/7/5
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __strpool_h
#define __strpool_h
typedef struct strpool_s {
char *strings;
struct hashtab_s *str_tab;
int size, max_size;
} strpool_t;
strpool_t *strpool_new (void);
strpool_t *strpool_build (const char *strings, int size);
void strpool_delete (strpool_t *strpool);
int strpool_addstr (strpool_t *strpool, const char *str);
#endif//__strpool_h

View file

@ -40,7 +40,7 @@ bin_PROGRAMS= qfcc
qfcc_SOURCES= \
class.c cmdlib.c cpp.c debug.c def.c emit.c expr.c function.c idstuff.c \
immediate.c linker.c method.c obj_file.c opcodes.c options.c qc-lex.l \
qc-parse.y qfcc.c reloc.c struct.c switch.c type.c
qc-parse.y qfcc.c reloc.c strpool.c struct.c switch.c type.c
qfcc_LDADD= $(QFCC_LIBS)
qfcc_DEPENDENCIES= $(QFCC_DEPS)

View file

@ -3,7 +3,7 @@
QC function support code
Copyright (C) 2001 Bill Currie
Copyright (C) 2002 Bill Currie
Author: Bill Currie <bill@taniwha.org>
Date: 2002/5/7
@ -55,6 +55,7 @@ static const char rcsid[] =
#include "method.h"
#include "options.h"
#include "reloc.h"
#include "strpool.h"
#include "struct.h"
#include "type.h"
@ -330,7 +331,7 @@ class_message_response (class_t *class, expr_t *sel)
return 0;
}
selector = &G_STRUCT (pr_sel_t, sel->e.pointer.val);
sel_name = pr.strings + selector->sel_id;
sel_name = G_GETSTR (selector->sel_id);
while (c) {
if (c->methods) {
for (m = c->methods->head; m; m = m->next) {

View file

@ -37,6 +37,7 @@ static const char rcsid[] =
#include "qfcc.h"
#include "def.h"
#include "expr.h"
#include "strpool.h"
#include "struct.h"
#include "type.h"
@ -365,7 +366,7 @@ free_tempdefs (void)
*def = d->next;
if (d->users < 0)
printf ("%s:%d: warning: %s %3d %3d %d\n", pr.strings + d->file,
printf ("%s:%d: warning: %s %3d %3d %d\n", G_GETSTR (d->file),
d->line, pr_type_name[d->type->type], d->ofs, d->users,
d->managed);
size = type_size (d->type);
@ -394,7 +395,7 @@ reset_tempdefs (void)
}
for (d = temp_scope.next; d; d = d->next)
printf ("%s:%d: warning: %s %3d %3d %d\n", pr.strings + d->file, d->line,
printf ("%s:%d: warning: %s %3d %3d %d\n", G_GETSTR (d->file), d->line,
pr_type_name[d->type->type], d->ofs, d->users, d->managed);
temp_scope.next = 0;
}

View file

@ -55,6 +55,7 @@ static const char rcsid[] =
#include "immediate.h"
#include "method.h"
#include "options.h"
#include "strpool.h"
#include "struct.h"
#include "type.h"
#include "qc-parse.h"
@ -232,7 +233,7 @@ error (expr_t *e, const char *fmt, ...)
file = e->file;
line = e->line;
}
fprintf (stderr, "%s:%d: ", pr.strings + file, line);
fprintf (stderr, "%s:%d: ", G_GETSTR (file), line);
vfprintf (stderr, fmt, args);
fputs ("\n", stderr);
va_end (args);
@ -260,7 +261,7 @@ _warning (expr_t *e, const char *fmt, va_list args)
file = e->file;
line = e->line;
}
fprintf (stderr, "%s:%d: warning: ", pr.strings + file, line);
fprintf (stderr, "%s:%d: warning: ", G_GETSTR (file), line);
vfprintf (stderr, fmt, args);
fputs ("\n", stderr);
}
@ -294,7 +295,7 @@ notice (expr_t *e, const char *fmt, ...)
file = e->file;
line = e->line;
}
fprintf (stderr, "%s:%d: notice: ", pr.strings + file, line);
fprintf (stderr, "%s:%d: notice: ", G_GETSTR (file), line);
vfprintf (stderr, fmt, args);
fputs ("\n", stderr);
}

View file

@ -3,7 +3,7 @@
QC function support code
Copyright (C) 2001 Bill Currie
Copyright (C) 2002 Bill Currie
Author: Bill Currie <bill@taniwha.org>
Date: 2002/5/7

View file

@ -37,6 +37,7 @@ static const char rcsid[] =
#include "qfcc.h"
#include "expr.h"
#include "options.h"
#include "strpool.h"
#include "type.h"
#define MAX_SOUNDS 1024

View file

@ -38,6 +38,7 @@ static const char rcsid[] =
#include "def.h"
#include "expr.h"
#include "immediate.h"
#include "strpool.h"
#include "type.h"
static hashtab_t *string_imm_defs;
@ -49,7 +50,6 @@ static hashtab_t *func_imm_defs;
static hashtab_t *pointer_imm_defs;
static hashtab_t *quaternion_imm_defs;
static hashtab_t *integer_imm_defs;
static hashtab_t *strings_tab;
static const char *
string_imm_get_key (void *_def, void *unused)
@ -95,45 +95,10 @@ int_imm_get_key (void *_def, void *_str)
return va ("\001%s:%08X\001", str, G_INT (def->ofs));
}
static const char *
strings_get_key (void *_str, void *unsued)
{
return pr.strings + (int) _str;
}
int
CopyString (const char *str)
{
int old;
int len = strlen (str) + 1;
if (!strings_tab) {
strings_tab = Hash_NewTable (16381, strings_get_key, 0, 0);
}
if (pr.strofs + len >= pr.strings_size) {
pr.strings_size += (len + 16383) & ~16383;
pr.strings = realloc (pr.strings, pr.strings_size);
}
old = pr.strofs;
strcpy (pr.strings + pr.strofs, str);
pr.strofs += len;
Hash_Add (strings_tab, (void *)old);
return old;
}
int
ReuseString (const char *str)
{
int s;
if (!str || !*str)
return 0;
if (!strings_tab)
return CopyString (str);
s = (long) Hash_Find (strings_tab, str);
if (s)
return s;
return CopyString (str);
return strpool_addstr (pr.strings, str);
}
def_t *

View file

@ -3,7 +3,7 @@
qc object file linking
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2002/7/3
@ -48,6 +48,7 @@ static const char rcsid[] =
#include "immediate.h"
#include "obj_file.h"
#include "qfcc.h"
#include "strpool.h"
static hashtab_t *extern_defs;
static hashtab_t *defined_defs;
@ -57,7 +58,7 @@ defs_get_key (void *_def, void *unused)
{
qfo_def_t *def = (qfo_def_t *) _def;
return pr.strings + def->name;
return G_GETSTR (def->name);
}
void
@ -67,7 +68,7 @@ add_code (qfo_t *qfo)
pr.num_statements += qfo->code_size;
if (pr.num_statements >= pr.statements_size) {
pr.statements_size = (pr.num_statements + 16383) & ~16384;
pr.statements_size = (pr.num_statements + 16383) & ~16383;
pr.statements = realloc (pr.statements,
pr.statements_size * sizeof (dstatement_t));
}
@ -89,10 +90,10 @@ add_defs (qfo_t *qfo)
Hash_Add (extern_defs, def);
} else {
if (def->flags & QFOD_GLOBAL) {
if ((d = Hash_Find (defined_defs, pr.strings + def->name))) {
if ((d = Hash_Find (defined_defs, G_GETSTR (def->name)))) {
pr.source_file = def->file;
pr.source_line = def->line;
error (0, "%s redefined", pr.strings + def->name);
error (0, "%s redefined", G_GETSTR (def->name));
}
}
if (def->basic_type == ev_string && def->ofs
@ -104,14 +105,14 @@ add_defs (qfo_t *qfo)
if (def->ofs)
def->ofs += pr.near_data->size;
if (def->flags & QFOD_GLOBAL) {
while ((d = Hash_Find (extern_defs, pr.strings + def->name))) {
Hash_Del (extern_defs, pr.strings + d->name);
while ((d = Hash_Find (extern_defs, G_GETSTR (def->name)))) {
Hash_Del (extern_defs, G_GETSTR (d->name));
if (d->full_type != def->full_type) {
pr.source_file = def->file;
pr.source_line = def->line;
error (0, "type mismatch %s %s",
pr.strings + def->full_type,
pr.strings + d->full_type);
G_GETSTR (def->full_type),
G_GETSTR (d->full_type));
}
}
Hash_Add (defined_defs, def);
@ -146,7 +147,7 @@ linker_begin (void)
pr.statements_size = 16384;
pr.statements = calloc (pr.statements_size, sizeof (dstatement_t));
pr.statement_linenums = calloc (pr.statements_size, sizeof (int));
CopyString ("");
pr.strings = strpool_new ();
pr.num_functions = 1;
pr.near_data = new_defspace ();
pr.near_data->data = calloc (65536, sizeof (pr_type_t));
@ -177,6 +178,6 @@ linker_finish (void)
for (def = undef_defs; *def; def++) {
pr.source_file = (*def)->file;
pr.source_line = (*def)->line;
error (0, "undefined symbol %s", pr.strings + (*def)->name);
error (0, "undefined symbol %s", G_GETSTR ((*def)->name));
}
}

View file

@ -3,7 +3,7 @@
QC method support code
Copyright (C) 2001 Bill Currie
Copyright (C) 2002 Bill Currie
Author: Bill Currie <bill@taniwha.org>
Date: 2002/5/7
@ -54,6 +54,7 @@ static const char rcsid[] =
#include "immediate.h"
#include "method.h"
#include "reloc.h"
#include "strpool.h"
#include "struct.h"
#include "type.h"
@ -224,8 +225,8 @@ sel_def_get_hash (void *_sel_def, void *unused)
sel_def_t *sel_def = (sel_def_t*)_sel_def;
unsigned long hash;
hash = Hash_String (pr.strings + sel_def->sel_id)
^ Hash_String (pr.strings + sel_def->sel_types);
hash = Hash_String (G_GETSTR (sel_def->sel_id))
^ Hash_String (G_GETSTR (sel_def->sel_types));
return hash;
}
@ -236,10 +237,10 @@ sel_def_compare (void *_sd1, void *_sd2, void *unused)
sel_def_t *sd2 = (sel_def_t*)_sd2;
int cmp;
cmp = strcmp (pr.strings + sd1->sel_id, pr.strings + sd2->sel_id) == 0;
cmp = strcmp (G_GETSTR (sd1->sel_id), G_GETSTR (sd2->sel_id)) == 0;
if (cmp)
cmp = strcmp (pr.strings + sd1->sel_types,
pr.strings + sd2->sel_types) == 0;
cmp = strcmp (G_GETSTR (sd1->sel_types),
G_GETSTR (sd2->sel_types)) == 0;
return cmp;
}

View file

@ -3,7 +3,7 @@
qfcc object file support
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2002/6/21
@ -50,8 +50,9 @@ static const char rcsid[] =
#include "function.h"
#include "immediate.h"
#include "obj_file.h"
#include "reloc.h"
#include "qfcc.h"
#include "reloc.h"
#include "strpool.h"
#include "type.h"
static qfo_def_t *defs;
@ -227,7 +228,7 @@ write_obj_file (const char *filename)
file = Qopen (filename, "wbz9");
pr.strofs = (pr.strofs + 3) & ~3;
pr.strings->size = (pr.strings->size + 3) & ~3;
memset (&hdr, 0, sizeof (hdr));
@ -238,7 +239,7 @@ write_obj_file (const char *filename)
if (pr.far_data) {
hdr.far_data_size = LittleLong (pr.far_data->size);
}
hdr.strings_size = LittleLong (pr.strofs);
hdr.strings_size = LittleLong (pr.strings->size);
hdr.num_relocs = LittleLong (num_relocs);
hdr.num_defs = LittleLong (num_defs);
hdr.num_functions = LittleLong (num_functions);
@ -254,8 +255,8 @@ write_obj_file (const char *filename)
Qwrite (file, pr.far_data->data,
pr.far_data->size * sizeof (pr_type_t));
}
if (pr.strofs)
Qwrite (file, pr.strings, pr.strofs);
if (pr.strings->size)
Qwrite (file, pr.strings->strings, pr.strings->size);
if (num_relocs)
Qwrite (file, relocs, num_relocs * sizeof (qfo_reloc_t));
if (num_defs)
@ -395,3 +396,92 @@ read_obj_file (const char *filename)
return qfo;
}
defspace_t *
init_space (int size, pr_type_t *data)
{
defspace_t *space = new_defspace ();
space->max_size = space->size = size;
if (size && data) {
space->data = malloc (size * sizeof (pr_type_t));
memcpy (space->data, data, size * sizeof (pr_type_t));
}
return space;
}
int
qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
{
int i;
function_t *pf;
qfo_function_t *qf;
def_t *pd;
qfo_def_t *qd;
reloc_t *relocs;
relocs = calloc (qfo->num_relocs, sizeof (reloc_t));
for (i = 0; i < qfo->num_relocs; i++) {
if (i + 1 < qfo->num_relocs)
relocs[i].next = &relocs[i + 1];
relocs[i].ofs = qfo->relocs[i].ofs;
relocs[i].type = qfo->relocs[i].type;
}
pr->strings = strpool_build (qfo->strings, qfo->strings_size);
pr->num_statements = pr->statements_size = qfo->code_size;
pr->statements = malloc (pr->statements_size * sizeof (dstatement_t));
memcpy (pr->statements, qfo->code,
pr->statements_size * sizeof (dstatement_t));
pr->near_data = init_space (qfo->data_size, qfo->data);
pr->far_data = init_space (qfo->far_data_size, qfo->far_data);
pr->scope = new_scope (sc_global, pr->near_data, 0);
pr->scope->num_defs = qfo->num_defs;
pr->scope->head = calloc (pr->scope->num_defs, sizeof (def_t));
for (i = 0, pd = pr->scope->head, qd = qfo->defs;
i < pr->scope->num_defs; i++) {
*pr->scope->tail = pd;
pr->scope->tail = &pd->def_next;
pd->type = 0; //XXX
pd->name = qfo->strings + qd->name;
pd->ofs = qd->ofs;
if (qd->num_relocs) {
pd->refs = relocs + qd->relocs;
pd->refs[qd->num_relocs - 1].next = 0;
}
pd->initialized = (qd->flags & QFOD_INITIALIZED) != 0;
pd->constant = (qd->flags & QFOD_CONSTANT) != 0;
pd->absolute = (qd->flags & QFOD_ABSOLUTE) != 0;
pd->global = (qd->flags & QFOD_GLOBAL) != 0;
pd->external = (qd->flags & QFOD_EXTERNAL) != 0;
pd->file = qd->file;
pd->line = qd->line;
}
pr->num_functions = qfo->num_functions;
pr->func_head = calloc (pr->num_functions, sizeof (function_t));
pr->func_tail = &pr->func_head;
for (i = 0, pf = pr->func_head, qf = qfo->functions;
i < pr->num_functions; i++) {
*pr->func_tail = pf;
pr->func_tail = &pf->next;
pf->aux = 0;//XXX
pf->builtin = qf->builtin;
pf->code = qf->code;
pf->function_num = i + 1;
pf->s_file = qf->file;
pf->file_line = qf->line;
pf->scope = new_scope (sc_params, init_space (qf->locals_size, 0),
pr->scope);
if (qf->num_local_defs) {
pf->scope->head = pr->scope->head + qf->local_defs;
pf->scope->tail = &pf->scope->head[qf->num_local_defs - 1].def_next;
}
if (qf->num_relocs) {
pf->refs = relocs + qf->relocs;
pf->refs[qf->num_relocs - 1].next = 0;
}
}
return 0;
}

View file

@ -77,6 +77,7 @@ static const char rcsid[] =
#include "opcodes.h"
#include "options.h"
#include "reloc.h"
#include "strpool.h"
#include "struct.h"
#include "type.h"
@ -127,6 +128,7 @@ InitData (void)
if (pr.statements) {
free (pr.statements);
strpool_delete (pr.strings);
memset (&pr, 0, sizeof (pr));
}
chain_initial_types ();
@ -136,8 +138,7 @@ InitData (void)
pr.statements_size = 16384;
pr.statements = calloc (pr.statements_size, sizeof (dstatement_t));
pr.statement_linenums = calloc (pr.statements_size, sizeof (int));
pr.strofs = 0;
CopyString ("");
pr.strings = strpool_new ();
pr.num_functions = 1;
pr.near_data = new_defspace ();
@ -193,10 +194,10 @@ WriteData (int crc)
dd->ofs = def->ofs;
}
pr.strofs = (pr.strofs + 3) & ~3;
pr.strings->size = (pr.strings->size + 3) & ~3;
if (options.verbosity >= 0) {
printf ("%6i strofs\n", pr.strofs);
printf ("%6i strofs\n", pr.strings->size);
printf ("%6i statements\n", pr.num_statements);
printf ("%6i functions\n", pr.num_functions);
printf ("%6i global defs\n", numglobaldefs);
@ -210,8 +211,8 @@ WriteData (int crc)
SafeWrite (h, &progs, sizeof (progs));
progs.ofs_strings = ftell (h);
progs.numstrings = pr.strofs;
SafeWrite (h, pr.strings, pr.strofs);
progs.numstrings = pr.strings->size;
SafeWrite (h, pr.strings->strings, pr.strings->size);
progs.ofs_statements = ftell (h);
progs.numstatements = pr.num_statements;

115
tools/qfcc/source/strpool.c Normal file
View file

@ -0,0 +1,115 @@
/*
strpool.c
unique string support
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2002/7/5
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
static const char rcsid[] =
"$Id$";
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdlib.h>
#include "QF/hash.h"
#include "strpool.h"
static const char *
strpool_get_key (void *_str, void *_strpool)
{
int str = (long) _str;
strpool_t *strpool = (strpool_t *) _strpool;
return strpool->strings + str;
}
strpool_t *
strpool_new (void)
{
strpool_t *strpool = malloc (sizeof (strpool_t));
strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool);
strpool->size = 1;
strpool->max_size = 16384;
strpool->strings = malloc (strpool->max_size);
strpool->strings[0] = 0;
return strpool;
}
strpool_t *
strpool_build (const char *strings, int size)
{
int s;
strpool_t *strpool = malloc (sizeof (strpool_t));
strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool);
strpool->size = size;
strpool->max_size = (size + 16383) & ~16383;
strpool->strings = malloc (strpool->max_size);
memcpy (strpool->strings, strings, size);
for (s = 1; s < strpool->size; s += strlen (s) + 1) {
Hash_Add (strpool->str_tab, (void *) s);
}
}
void
strpool_delete (strpool_t *strpool)
{
Hash_DelTable (strpool->str_tab);
free (strpool->strings);
free (strpool);
}
int
strpool_addstr (strpool_t *strpool, const char *str)
{
int s;
int len;
if (!str || !*str)
return 0;
s = (long) Hash_Find (strpool->str_tab, str);
if (s)
return s;
len = strlen (str) + 1;
if (strpool->size + len > strpool->max_size) {
strpool->max_size += (len + 16383) & ~16383;
strpool->strings = realloc (strpool->strings, strpool->max_size);
}
s = strpool->size;
strpool->size += len;
strcpy (strpool->strings + s, str);
Hash_Add (strpool->str_tab, (void *) s);
return s;
}