From 4a060b2c14cec19ab5605eecbbfbab944cc48af1 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 31 Oct 2005 21:27:19 +0000 Subject: [PATCH] use --WORLD as root of all actions (GC just deletes --WORLD) git-archimport-id: chth@gmx.net--2004/mala-glibc--devel--0.2--patch-137 --- ChangeLog | 16 ++++++ NEWS | 2 + engine/action.c | 123 ++++++++++++++++++++++++++-------------------- engine/action.h | 7 ++- engine/actiondesc.c | 1 - engine/engine.c | 28 ++++++----- engine/engine.h | 4 +- engine/stringbucket.c | 21 +------- engine/stringbucket.h | 5 +- engine/strings.c | 63 +++++++++--------------- engine/strings.h | 3 ++ program/mala.c | 4 ++ tests/10stringlib.tests | 3 -- tests/test-mala_strings.c | 3 -- 14 files changed, 144 insertions(+), 139 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbdfe26..0224e59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,22 @@ # arch-tag: automatic-ChangeLog--chth@gmx.net--2004/mala-glibc--devel--0.2 # +2005-10-31 21:27:19 GMT Christian Thaeter patch-137 + + Summary: + use --WORLD as root of all actions (GC just deletes --WORLD) + Revision: + mala-glibc--devel--0.2--patch-137 + + + modified files: + ChangeLog NEWS engine/action.c engine/action.h + engine/actiondesc.c engine/engine.c engine/engine.h + engine/stringbucket.c engine/stringbucket.h engine/strings.c + engine/strings.h program/mala.c tests/10stringlib.tests + tests/test-mala_strings.c + + 2005-10-31 14:58:03 GMT Christian Thaeter patch-136 Summary: diff --git a/NEWS b/NEWS index 009de1e..3684883 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,7 @@ The second is the current state. Followed by any older releases. - mala-states to common strings mala_state_parser substitutes current state? - mala_predicates.c - SEGV handler (setjump after sideeffects, rollback in case of segv, garbage collect, retry) + - refactor "--WORLD" lookup - Language semantics - dynamic preprocessor substitutions ({ becomes --BEGIN, } becomes --END) like subst macros - voluntary typesystem with inheritance @@ -93,6 +94,7 @@ The second is the current state. Followed by any older releases. + --RESULT_--MACRO returnspec - --PRINTL prints blocks too - parsers for things generated by expansions + - --ONCE macro expands and --DELetes macro - strings - integer arithmetic - Documentation diff --git a/engine/action.c b/engine/action.c index 31b88b7..9d8fba1 100644 --- a/engine/action.c +++ b/engine/action.c @@ -22,6 +22,7 @@ #include "strings.h" #include "stringlist.h" #include "actiondesc.h" +#include "engine.h" #include "action.h" @@ -39,7 +40,7 @@ mala_action_new (MalaString name, if (!self) return NULL; - self->name = name; /* weak-reference, not refcounted */ + self->name = mala_string_copy (name); self->parser = parser; self->factory = factory; self->data = data; @@ -48,19 +49,22 @@ mala_action_new (MalaString name, LIST_INIT (&self->childs); self->parent = parent; + if (parent) - LIST_INSERT_HEAD (&self->childs, self, cldnode); + LIST_INSERT_HEAD (&parent->childs, self, cldnode); if (name->bucket->gc_trace > MALA_NOTRACE) - fprintf (stderr ,"GC: new action %p '%s' cnt = %ld\n", - self, name->str, (name->refcnt >> 2) - 1); + fprintf (stderr ,"GC: new action %p '%s' cnt %ld parent '%s'\n", + self, name->str, name->refcnt >> 2, parent?parent->name->str:NULL); return self; } MalaAction -mala_action_new_actioninit (MalaActionInit init, MalaStringBucket bucket) +mala_action_new_actioninit (MalaActionInit init, MalaEngine engine) { + MalaStringBucket bucket = &engine->words; + MalaAction parent; MalaAction self; MalaString name; void * data = NULL; @@ -79,9 +83,12 @@ mala_action_new_actioninit (MalaActionInit init, MalaStringBucket bucket) else data = init->data; - self = mala_action_new (name, data, - init->parser, factory, - mala_action_get_cstr (bucket, init->parent)); + if (!init->parent) + parent = mala_action_get_cstr (bucket, "--WORLD"); + else + parent = mala_action_get_cstr (bucket, init->parent); + + self = mala_action_new (name, data, init->parser, factory, parent); if (!self) goto ealloc_action; @@ -97,10 +104,18 @@ mala_action_new_actioninit (MalaActionInit init, MalaStringBucket bucket) } MalaAction -mala_action_get_cstr (MalaStringBucket bucket, const char * parent) +mala_action_get_cstr (MalaStringBucket bucket, const char * name) +{ + return name + ? mala_actiondesc_top (mala_string_user_get (mala_string_find (name, bucket))) + : NULL; +} + +MalaAction +mala_action_get_str (MalaString name) { - return parent - ? mala_actiondesc_top (mala_string_user_get (mala_string_find (parent, bucket))) + return name + ? mala_actiondesc_top (mala_string_user_get (name)) : NULL; } @@ -127,45 +142,6 @@ mala_action_execute (MalaAction self, MalaStringListNode_ref pptr, MalaEngine en -#if 0 /*TODO*/ - - -t_uchar * -mala_action_getname (MalaAction self) -{ - return self->name; -} - -int -mala_action_attach (MalaAction self, MalaAction parent) -{ - if (!llist_is_empty (&self->cldnode)) - return MALA_EACTIONUSED; - - llist_add_tail (&parent->childs, &self->cldnode); - return MALA_SUCCESS; -} - -void -mala_action_detach (MalaAction self) -{ - llist_unlink (&self->cldnode); -} - -MalaParserFunc -mala_action_getparser (MalaAction self) -{ - return self->parser; -} - -void * -mala_action_getdata (MalaAction self) -{ - return self->data; -} -#endif /*TODO*/ - - void mala_action_free (MalaAction self) { @@ -174,10 +150,11 @@ mala_action_free (MalaAction self) if (!self) return; + MALA_ASSERT(self->name); + if (self->name->bucket && self->name->bucket->gc_trace > MALA_NOTRACE) fprintf (stderr ,"GC: free action %p '%s'\n", self, self->name->str); - MALA_ASSERT(self->name); // detach from parent if (self->parent) { @@ -200,10 +177,11 @@ mala_action_free (MalaAction self) LIST_REMOVE(self, stknode); - /*ok, refcounting has some strange effects*/ - if (!self->name->bucket->destroying && self->desc->actions.lh_first) + if (!self->desc->actions.lh_first) mala_actiondesc_free (self->desc); + mala_string_free (self->name); + free (self); } @@ -211,6 +189,45 @@ mala_action_free (MalaAction self) +#if 0 /*TODO*/ + + +t_uchar * +mala_action_getname (MalaAction self) +{ + return self->name; +} + +int +mala_action_attach (MalaAction self, MalaAction parent) +{ + if (!llist_is_empty (&self->cldnode)) + return MALA_EACTIONUSED; + + llist_add_tail (&parent->childs, &self->cldnode); + return MALA_SUCCESS; +} + +void +mala_action_detach (MalaAction self) +{ + llist_unlink (&self->cldnode); +} + +MalaParserFunc +mala_action_getparser (MalaAction self) +{ + return self->parser; +} + +void * +mala_action_getdata (MalaAction self) +{ + return self->data; +} +#endif /*TODO*/ + + /* // Local Variables: // mode: C diff --git a/engine/action.h b/engine/action.h index 8f1fff4..af5bee9 100644 --- a/engine/action.h +++ b/engine/action.h @@ -52,7 +52,7 @@ struct mala_action_struct MalaAction -mala_action_new_actioninit (MalaActionInit init, MalaStringBucket bucket); +mala_action_new_actioninit (MalaActionInit init, MalaEngine engine); void mala_action_free (MalaAction self); @@ -72,7 +72,10 @@ mala_action_new (MalaString name, MalaAction parent); MalaAction -mala_action_get_cstr (MalaStringBucket bucket, const char*parent); +mala_action_get_cstr (MalaStringBucket bucket, const char* cstr); + +MalaAction +mala_action_get_str (MalaString str); int mala_action_execute (MalaAction self, MalaStringListNode_ref pptr, MalaEngine eng); diff --git a/engine/actiondesc.c b/engine/actiondesc.c index 86651a0..cc56f6e 100644 --- a/engine/actiondesc.c +++ b/engine/actiondesc.c @@ -51,7 +51,6 @@ mala_actiondesc_ensure (MalaString str) return self; } -#include void mala_actiondesc_free (MalaActionDesc self) { if (!self) diff --git a/engine/engine.c b/engine/engine.c index 1027faf..0803115 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -61,6 +61,8 @@ mala_engine_new () self->gc_trace = &self->words.gc_trace; + mala_engine_add_action_cstr (self, "--WORLD", NULL, NULL, NULL, NULL); + for (i = 0; i < MALA_STRING_MAX; ++i) { self->common_string[i] = mala_string_new (mala_common_strings[i], &self->words); @@ -142,7 +144,7 @@ mala_engine_ppexpand_define (MalaEngine self, const char * name, int argc, char mala_string_copy (self->common_string[MALA_STRING_PASS]), mala_substitute_parser, (MalaDataFactory)mala_string_factory, - NULL); + mala_action_get_cstr (&self->words, "--WORLD")); } if (mala_stringlist_is_tail (list, mala_stringlist_head (list))) @@ -156,7 +158,7 @@ mala_engine_ppexpand_define (MalaEngine self, const char * name, int argc, char return mala_engine_add_action_cstr (self, name, subst, mala_substitute_parser, (MalaDataFactory)mala_string_factory, - NULL); + mala_action_get_cstr (&self->words, "--WORLD")); } else { @@ -164,7 +166,7 @@ mala_engine_ppexpand_define (MalaEngine self, const char * name, int argc, char return mala_engine_add_action_cstr (self, name, list, mala_expand_parser, (MalaDataFactory) mala_stringlist_factory, - NULL); + mala_action_get_cstr (&self->words, "--WORLD")); } eunderrun: @@ -233,7 +235,8 @@ mala_engine_add_action (MalaEngine self, MalaString name, void * data, if (mala_engine_state_get (self) > MALA_EFAULT) return mala_engine_state_get (self); - action = mala_action_new (name, data, parser, factory, parent); + action = mala_action_new (name, data, parser, factory, + parent?parent:mala_action_get_cstr (&self->words, "--WORLD")); if (!action) goto ealloc_action; @@ -265,8 +268,6 @@ mala_engine_new_initfunc (int (*initfunc)(MalaEngine)) void mala_engine_free (MalaEngine self) { - int i; - if (!self) return; @@ -281,15 +282,15 @@ mala_engine_free (MalaEngine self) mala_stringlist_erase (&self->arguments); if (self->words.gc_trace > MALA_NOTRACE) - fprintf (stderr ,"GC: engine free, bucket\n"); + fprintf (stderr ,"GC: engine free world\n"); - mala_stringbucket_erase (&self->words); + /*TODO direct pointer top of the worlds*/ + mala_action_free (mala_action_get_cstr (&self->words, "--WORLD")); if (self->words.gc_trace > MALA_NOTRACE) - fprintf (stderr ,"GC: engine free, common\n"); + fprintf (stderr ,"GC: engine free, bucket\n"); - for (i = 0; i < MALA_STRING_MAX; ++i) - mala_string_free (self->common_string[i]); + mala_stringbucket_erase (&self->words); free (self); } @@ -304,7 +305,7 @@ mala_engine_actions_register (MalaEngine self, mala_actioninit * actioninit) while (actioninit->command) { - action = mala_action_new_actioninit (actioninit, &self->words); + action = mala_action_new_actioninit (actioninit, self); if (!action) goto ealloc; @@ -408,6 +409,9 @@ mala_engine_run (MalaEngine self) if (mala_engine_state_get (self) > MALA_EFAULT) return NULL; + if (self->words.gc_trace > MALA_NOTRACE) + fprintf (stderr ,"GC: engine run\n"); + while (self->state < MALA_EFAULT && (pptr = mala_stringlist_head (&self->program)) != (void *)&self->program) { diff --git a/engine/engine.h b/engine/engine.h index 8cdd07f..bbaceae 100644 --- a/engine/engine.h +++ b/engine/engine.h @@ -27,8 +27,10 @@ /* Build a table of common strings, this strings are - a) get never garbage collected + a) get never garbage collected (except at end) b) are fast accessible with their symbolic index + + TODO: MALA_EXPAND (WORLD, "--WORLD"), */ #define MALA_COMMON_STRINGS \ { \ diff --git a/engine/stringbucket.c b/engine/stringbucket.c index ca7dc20..6070283 100644 --- a/engine/stringbucket.c +++ b/engine/stringbucket.c @@ -32,33 +32,14 @@ void mala_stringbucket_init (MalaStringBucket bucket, bucket->bucket = NULL; bucket->cmpfn = cmpfn; bucket->freefn = freefn; - bucket->destroying = 0; bucket->gc_trace = MALA_NOTRACE; } - -static void -twalk_stringdata_destroy (const void *nodep, - const VISIT which, - const int depth) -{ - (void) depth; - (void) which; - mala_string_data_free (*(MalaString_ref)nodep); -} - - void mala_stringbucket_erase (MalaStringBucket bucket) { - bucket->destroying = 1; - - /* it makes the string destructor a bit easier when we destroy data on a single pass */ - twalk (bucket->bucket, twalk_stringdata_destroy); - - tdestroy (bucket->bucket, (void(*)(void*)) mala_string_free); + tdestroy (bucket->bucket, (void(*)(void*)) mala_string_free_forced); bucket->bucket = NULL; - bucket->destroying = 0; } diff --git a/engine/stringbucket.h b/engine/stringbucket.h index 2709eb2..9f2a02d 100644 --- a/engine/stringbucket.h +++ b/engine/stringbucket.h @@ -36,12 +36,11 @@ struct mala_stringbucket_struct void * bucket; mala_string_cmp_fn cmpfn; void (*freefn)(void*); - int destroying; mala_trace gc_trace; }; -#define MALA_STRINGBUCKET_STATIC(cmp_fn,free_fn) &(mala_stringbucket){NULL,cmp_fn,free_fn,0,MALA_NOTRACE} -#define MALA_STRINGBUCKET_AUTO(cmp_fn,free_fn) {NULL,cmp_fn,free_fn,0,MALA_NOTRACE} +#define MALA_STRINGBUCKET_STATIC(cmp_fn,free_fn) &(mala_stringbucket){NULL,cmp_fn,free_fn,MALA_NOTRACE} +#define MALA_STRINGBUCKET_AUTO(cmp_fn,free_fn) {NULL,cmp_fn,free_fn,MALA_NOTRACE} void diff --git a/engine/strings.c b/engine/strings.c index f58ff68..2d0d4c0 100644 --- a/engine/strings.c +++ b/engine/strings.c @@ -103,7 +103,6 @@ mala_string_new_cstr_attach (char* cstr, MalaStringBucket bucket) } self->bucket = bucket; - self->refcnt += 4; /*add a reference for the bucket itself*/ *loc = self; if (bucket->gc_trace > MALA_NOTRACE) @@ -117,7 +116,7 @@ mala_string_new_cstr_attach (char* cstr, MalaStringBucket bucket) self->refcnt += 4; if (bucket->gc_trace > MALA_NOTRACE) fprintf (stderr ,"GC: add string '%s' cnt = %ld\n", - self->str, (self->refcnt >> 2) - 1); + self->str, self->refcnt >> 2); } } else @@ -157,7 +156,6 @@ mala_string_new (const char* cstr, MalaStringBucket bucket) } self->bucket = bucket; - self->refcnt += 4; /*add a reference for the bucket itself*/ *loc = self; if (bucket->gc_trace > MALA_NOTRACE) fprintf (stderr ,"GC: new string '%s'\n", cstr); @@ -169,7 +167,7 @@ mala_string_new (const char* cstr, MalaStringBucket bucket) self->refcnt += 4; if (bucket->gc_trace > MALA_NOTRACE) fprintf (stderr ,"GC: add string '%s' cnt = %ld\n", - self->str, (self->refcnt >> 2) - 1); + self->str, self->refcnt >> 2); } } else @@ -218,7 +216,6 @@ mala_string_new_cat2 (const char* cstr1, const char* cstr2, MalaStringBucket buc goto ealloc_lookup; self->bucket = bucket; - self->refcnt += 4; /*add a reference for the bucket itself*/ *loc = self; if (bucket->gc_trace > MALA_NOTRACE) fprintf (stderr ,"GC: new string '%s'\n", cstr); @@ -231,7 +228,7 @@ mala_string_new_cat2 (const char* cstr1, const char* cstr2, MalaStringBucket buc free (cstr); if (bucket->gc_trace > MALA_NOTRACE) fprintf (stderr ,"GC: add string '%s' cnt = %ld\n", - self->str, (self->refcnt >> 2) - 1); + self->str, self->refcnt >> 2); } } else @@ -287,35 +284,25 @@ mala_string_free (MalaString self) if (!self) return; - MALA_ASSERT (self->refcnt < SIZE_MAX>>1); - - if (self->bucket && self->bucket->gc_trace > MALA_NOTRACE && self->refcnt >= 8) - fprintf (stderr ,"GC: unlink string '%s' cnt = %ld\n", - self->str, (self->refcnt >> 2) - 1); - if (self->refcnt >= 4) self->refcnt -= 4; + if (self->bucket && self->bucket->gc_trace > MALA_NOTRACE && self->refcnt >= 4) + fprintf (stderr ,"GC: unlink string '%s' cnt = %ld\n", + self->str, self->refcnt >> 2); + /* if this is the last used string */ if (self->refcnt < 4) { if (self->bucket && self->bucket->gc_trace > MALA_NOTRACE) - { - if (!self->bucket->destroying) - fprintf (stderr ,"GC: free string '%s'\n", self->str); - else - fprintf (stderr ,"GC: destroy string '%s'\n", self->str); - } + fprintf (stderr ,"GC: free string '%s'\n", self->str); if (self->user && self->bucket->freefn) - { - self->bucket->freefn (self->user); - } + self->bucket->freefn (self->user); + + if (self->bucket) + tdelete (self, &self->bucket->bucket, self->bucket->cmpfn); - if (self->bucket && !self->bucket->destroying) - { - tdelete (self, &self->bucket->bucket, self->bucket->cmpfn); - } if (!(self->refcnt & 0x2)) free ((void*) self->str); if (!(self->refcnt & 0x1)) @@ -323,23 +310,18 @@ mala_string_free (MalaString self) } } + void -mala_string_data_free (MalaString self) +mala_string_free_forced (MalaString self) { - if (!self) - return; - MALA_ASSERT(self); - MALA_ASSERT(self->str); - MALA_ASSERT(self->refcnt >= 4); - - if (self->user - && self->bucket - && self->bucket->freefn - && self->bucket->destroying) - { - self->bucket->freefn (self->user); - self->user = NULL; - } + if (self->bucket && self->bucket->gc_trace > MALA_NOTRACE) + fprintf (stderr ,"GC: free_forced string '%s' cnt = %ld\n", + self->str, self->refcnt >> 2); + + if (!(self->refcnt & 0x2)) + free ((void*) self->str); + if (!(self->refcnt & 0x1)) + free (self); } @@ -390,7 +372,6 @@ mala_string_new_prefix (const char* prefix, MalaString str) goto ealloc_lookup; self->bucket = bucket; - self->refcnt += 4; /*add a reference for the bucket itself*/ *loc = self; } else diff --git a/engine/strings.h b/engine/strings.h index 4d84a6c..37cdf98 100644 --- a/engine/strings.h +++ b/engine/strings.h @@ -85,6 +85,9 @@ mala_string_scan (const_MalaString str,const char* fmt,...); void mala_string_free (MalaString s); +void +mala_string_free_forced (MalaString s); + MalaString mala_string_factory (MalaString_ref dest, const char* src, MalaStringBucket bucket); diff --git a/program/mala.c b/program/mala.c index 0e3b017..c746214 100644 --- a/program/mala.c +++ b/program/mala.c @@ -38,6 +38,10 @@ main(int argc, char * argv[]) MalaEngine my_engine; my_engine = mala_engine_new (); + if (getenv ("MALA_GCTRACE")) + *my_engine->gc_trace = MALA_TRACE; + if (getenv ("MALA_TRACE")) + my_engine->engine_trace = MALA_TRACE; mala_module_std_init (my_engine); mala_engine_actions_register (my_engine, my_actions); mala_engine_ppexpand_define (my_engine, "--COMMANDLINE", argc - 1, argv + 1); diff --git a/tests/10stringlib.tests b/tests/10stringlib.tests index 4847d69..da0f7ce 100644 --- a/tests/10stringlib.tests +++ b/tests/10stringlib.tests @@ -22,9 +22,6 @@ TEST b = mala_string_new ("baz", test): .. OK TEST c = mala_string_new ("bar", test): .. OK TEST d = mala_string_new ("bar", NULL): .. OK TEST mala_stringbucket_erase (test): .. OK -TEST mala_string_free (a): .. OK -TEST mala_string_free (b): .. OK -TEST mala_string_free (c): .. OK TEST mala_string_free (d): .. OK TEST a = mala_string_new_print(NULL, "%d",1234): .. OK TEST mala_string_compare (a, onetwothreefour) == 0: .. OK diff --git a/tests/test-mala_strings.c b/tests/test-mala_strings.c index e0a6c89..3a7f237 100644 --- a/tests/test-mala_strings.c +++ b/tests/test-mala_strings.c @@ -43,9 +43,6 @@ basic_construction() TEST(c = mala_string_new ("bar", test)); TEST(d = mala_string_new ("bar", NULL)); TEST_VOID(mala_stringbucket_erase (test)); - TEST_VOID(mala_string_free (a)); - TEST_VOID(mala_string_free (b)); - TEST_VOID(mala_string_free (c)); TEST_VOID(mala_string_free (d)); } -- 2.11.4.GIT