From Didier Gautheron: Bug #2042: Move constants initialisation at compile time.

svn path=/trunk/; revision=23659
This commit is contained in:
Bill Meier 2007-11-28 22:44:37 +00:00
parent 6d4dda3327
commit b436aeaf5f
5 changed files with 140 additions and 11 deletions

View File

@ -32,7 +32,9 @@
/* Passed back to user */
struct _dfilter_t {
GPtrArray *insns;
GPtrArray *consts;
int num_registers;
int max_registers;
GList **registers;
gboolean *attempted_load;
int *interesting_fields;
@ -44,10 +46,13 @@ typedef struct {
stnode_t *st_root;
gboolean syntax_error;
GPtrArray *insns;
GPtrArray *consts;
GHashTable *loaded_fields;
GHashTable *interesting_fields;
int next_insn_id;
int next_const_id;
int next_register;
int first_constant; /* first register used as a constant */
} dfwork_t;
/* Constructor/Destructor prototypes for Lemon Parser */

View File

@ -137,13 +137,28 @@ free_insns(GPtrArray *insns)
void
dfilter_free(dfilter_t *df)
{
int i;
if (!df)
return;
if (df->insns) {
free_insns(df->insns);
}
if (df->consts) {
free_insns(df->consts);
}
if (df->interesting_fields) {
g_free(df->interesting_fields);
}
/* clear registers */
for (i = 0; i < df->max_registers; i++) {
if (df->registers[i]) {
g_list_free(df->registers[i]);
}
}
g_free(df->registers);
g_free(df->attempted_load);
@ -161,10 +176,12 @@ dfwork_new(void)
dfw->st_root = NULL;
dfw->syntax_error = FALSE;
dfw->insns = NULL;
dfw->consts = NULL;
dfw->loaded_fields = NULL;
dfw->interesting_fields = NULL;
dfw->next_insn_id = 0;
dfw->next_register = 0;
dfw->first_constant = -1;
return dfw;
}
@ -187,11 +204,14 @@ dfwork_free(dfwork_t *dfw)
if (dfw->insns) {
free_insns(dfw->insns);
}
if (dfw->consts) {
free_insns(dfw->consts);
}
g_free(dfw);
}
gboolean
dfilter_compile(const gchar *text, dfilter_t **dfp)
{
@ -279,14 +299,20 @@ dfilter_compile(const gchar *text, dfilter_t **dfp)
/* Tuck away the bytecode in the dfilter_t */
dfilter = dfilter_new();
dfilter->insns = dfw->insns;
dfilter->consts = dfw->consts;
dfw->insns = NULL;
dfw->consts = NULL;
dfilter->interesting_fields = dfw_interesting_fields(dfw,
&dfilter->num_interesting_fields);
/* Initialize run-time space */
dfilter->num_registers = dfw->next_register;
dfilter->registers = g_new0(GList*, dfilter->num_registers);
dfilter->attempted_load = g_new0(gboolean, dfilter->num_registers);
dfilter->num_registers = dfw->first_constant;
dfilter->max_registers = dfw->next_register;
dfilter->registers = g_new0(GList*, dfilter->max_registers);
dfilter->attempted_load = g_new0(gboolean, dfilter->max_registers);
/* Initialize constants */
dfvm_init_const(dfilter);
/* And give it to the user. */
*dfp = dfilter;

View File

@ -36,6 +36,7 @@ dfvm_insn_new(dfvm_opcode_t op)
insn->arg1 = NULL;
insn->arg2 = NULL;
insn->arg3 = NULL;
insn->arg4 = NULL;
return insn;
}
@ -68,6 +69,9 @@ dfvm_insn_free(dfvm_insn_t *insn)
if (insn->arg3) {
dfvm_value_free(insn->arg3);
}
if (insn->arg4) {
dfvm_value_free(insn->arg4);
}
g_free(insn);
}
@ -439,11 +443,6 @@ dfvm_apply(dfilter_t *df, proto_tree *tree)
&df->registers[arg2->value.numeric]);
break;
case PUT_FVALUE:
accum = put_fvalue(df,
arg1->value.fvalue, arg2->value.numeric);
break;
case MK_RANGE:
arg3 = insn->arg3;
mk_range(df,
@ -518,6 +517,12 @@ dfvm_apply(dfilter_t *df, proto_tree *tree)
}
break;
case PUT_FVALUE:
#if 0
accum = put_fvalue(df,
arg1->value.fvalue, arg2->value.numeric);
break;
#endif
default:
g_assert_not_reached();
@ -528,3 +533,50 @@ dfvm_apply(dfilter_t *df, proto_tree *tree)
g_assert_not_reached();
return FALSE; /* to appease the compiler */
}
void
dfvm_init_const(dfilter_t *df)
{
int id, length;
dfvm_insn_t *insn;
dfvm_value_t *arg1;
dfvm_value_t *arg2;
length = df->consts->len;
for (id = 0; id < length; id++) {
insn = g_ptr_array_index(df->consts, id);
arg1 = insn->arg1;
arg2 = insn->arg2;
switch (insn->op) {
case PUT_FVALUE:
put_fvalue(df,
arg1->value.fvalue, arg2->value.numeric);
break;
case CHECK_EXISTS:
case READ_TREE:
case CALL_FUNCTION:
case MK_RANGE:
case ANY_EQ:
case ANY_NE:
case ANY_GT:
case ANY_GE:
case ANY_LT:
case ANY_LE:
case ANY_BITWISE_AND:
case ANY_CONTAINS:
case ANY_MATCHES:
case NOT:
case RETURN:
case IF_TRUE_GOTO:
case IF_FALSE_GOTO:
default:
g_assert_not_reached();
break;
}
}
return;
}

View File

@ -102,5 +102,7 @@ dfvm_dump(FILE *f, GPtrArray *insns);
gboolean
dfvm_apply(dfilter_t *df, proto_tree *tree);
void
dfvm_init_const(dfilter_t *df);
#endif

View File

@ -47,6 +47,14 @@ dfw_append_insn(dfwork_t *dfw, dfvm_insn_t *insn)
g_ptr_array_add(dfw->insns, insn);
}
static void
dfw_append_const(dfwork_t *dfw, dfvm_insn_t *insn)
{
insn->id = dfw->next_const_id;
dfw->next_const_id++;
g_ptr_array_add(dfw->consts, insn);
}
/* returns register number */
static int
dfw_append_read_tree(dfwork_t *dfw, header_field_info *hfinfo)
@ -116,11 +124,11 @@ dfw_append_put_fvalue(dfwork_t *dfw, fvalue_t *fv)
val1 = dfvm_value_new(FVALUE);
val1->value.fvalue = fv;
val2 = dfvm_value_new(REGISTER);
reg = dfw->next_register++;
reg = dfw->first_constant--;
val2->value.numeric = reg;
insn->arg1 = val1;
insn->arg2 = val2;
dfw_append_insn(dfw, insn);
dfw_append_const(dfw, insn);
return reg;
}
@ -444,6 +452,7 @@ dfw_gencode(dfwork_t *dfw)
dfvm_value_t *arg1;
dfw->insns = g_ptr_array_new();
dfw->consts = g_ptr_array_new();
dfw->loaded_fields = g_hash_table_new(g_direct_hash, g_direct_equal);
dfw->interesting_fields = g_hash_table_new(g_direct_hash, g_direct_equal);
gencode(dfw, dfw->st_root);
@ -485,6 +494,41 @@ dfw_gencode(dfwork_t *dfw)
}
}
/* move constants after registers*/
if (dfw->first_constant == -1) {
/* NONE */
dfw->first_constant = 0;
return;
}
id = -dfw->first_constant -1;
dfw->first_constant = dfw->next_register;
dfw->next_register += id;
length = dfw->consts->len;
for (id = 0; id < length; id++) {
insn = g_ptr_array_index(dfw->consts, id);
if (insn->arg2 && insn->arg2->type == REGISTER && (int)insn->arg2->value.numeric < 0 )
insn->arg2->value.numeric = dfw->first_constant - insn->arg2->value.numeric -1;
}
length = dfw->insns->len;
for (id = 0; id < length; id++) {
insn = g_ptr_array_index(dfw->insns, id);
if (insn->arg1 && insn->arg1->type == REGISTER && (int)insn->arg1->value.numeric < 0 )
insn->arg1->value.numeric = dfw->first_constant - insn->arg1->value.numeric -1;
if (insn->arg2 && insn->arg2->type == REGISTER && (int)insn->arg2->value.numeric < 0 )
insn->arg2->value.numeric = dfw->first_constant - insn->arg2->value.numeric -1;
if (insn->arg3 && insn->arg3->type == REGISTER && (int)insn->arg3->value.numeric < 0 )
insn->arg3->value.numeric = dfw->first_constant - insn->arg3->value.numeric -1;
if (insn->arg4 && insn->arg4->type == REGISTER && (int)insn->arg4->value.numeric < 0 )
insn->arg4->value.numeric = dfw->first_constant - insn->arg4->value.numeric -1;
}
}