From 2faa1faa84c7f0949b26bb7a7a2c115f9e4ea83e Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Thu, 20 Feb 2003 19:16:39 +0000 Subject: [PATCH] Experimental new gc scheme. --- js2/src/js2engine.cpp | 10 +++++--- js2/src/js2metadata.cpp | 55 ++++++++++++++++++++++------------------- js2/src/js2metadata.h | 9 ++++--- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/js2/src/js2engine.cpp b/js2/src/js2engine.cpp index b361195fd129..52e6f98c04f5 100644 --- a/js2/src/js2engine.cpp +++ b/js2/src/js2engine.cpp @@ -891,7 +891,7 @@ namespace MetaData { return buildNameList(); } - // XXX need help from spec. Here we iterate ove dynamic properties only + // XXX need help from spec. Here we iterate over dynamic properties only // unless the object is a Class, in which case we iterate the static // members. bool ForIteratorObject::buildNameList() @@ -931,7 +931,7 @@ namespace MetaData { } // - // Set the iterator to the first property in that list that is not + // Set the iterator to the next property in that list that is not // shadowed by a property higher up the prototype chain. If we get // to the end of the list, bump down to the next object on the chain. // @@ -945,7 +945,11 @@ namespace MetaData { else { if (originalObj != obj) { while (it != length) - if (engine->meta->lookupDynamicProperty(originalObj, nameList[it]) != obj) it++; + if (engine->meta->lookupDynamicProperty(originalObj, nameList[it]) != obj) + // shadowed by a property higher in the chain, so skip to next + it++; + else + break; } if (it == length) { if (obj->kind == PrototypeInstanceKind) { diff --git a/js2/src/js2metadata.cpp b/js2/src/js2metadata.cpp index 6ada3e19fc08..61f075c9a06e 100644 --- a/js2/src/js2metadata.cpp +++ b/js2/src/js2metadata.cpp @@ -2977,7 +2977,7 @@ doUnary: #define MAKEBUILTINCLASS(c, super, dynamic, allowNull, final, name, defaultVal) c = new JS2Class(super, NULL, new Namespace(engine->private_StringAtom), dynamic, allowNull, final, name); c->complete = true; c->defaultValue = defaultVal; - JS2Metadata::JS2Metadata(World &world) : + JS2Metadata::JS2Metadata(World &world) : JS2Object(MetaDataKind), world(world), engine(new JS2Engine(world)), publicNamespace(new Namespace(engine->public_StringAtom)), @@ -3963,7 +3963,7 @@ deleteClassProperty: // gc-mark all contained JS2Objects and their children // and then invoke mark on all other structures that contain JS2Objects - void JS2Metadata::mark() + void JS2Metadata::markChildren() { // XXX - maybe have a separate pool to allocate chunks // that are meant to be never collected? @@ -4781,7 +4781,7 @@ deleteClassProperty: void *JS2Object::alloc(size_t s) { s += sizeof(PondScum); - // make sure that the thing is 16-byte aligned + // make sure that the thing is a multiple of 16 bytes if (s & 0xF) s += 16 - (s & 0xF); ASSERT(s <= 0x7FFFFFFF); void *p = pond.allocFromPond(s); @@ -4848,34 +4848,37 @@ deleteClassProperty: // Allocate from this or the next Pond (make a new one if necessary) void *Pond::allocFromPond(size_t sz) { - // Try scannning the free list... - PondScum *p = freeHeader; - PondScum *pre = NULL; - while (p) { - ASSERT(p->getSize() > 0); - if (p->getSize() >= sz) { - if (pre) - pre->owner = p->owner; - else - freeHeader = (PondScum *)(p->owner); - p->owner = this; - p->resetMark(); // might have lingering mark from previous gc -#ifdef DEBUG - memset((p + 1), 0xB7, p->getSize() - sizeof(PondScum)); -#endif - return (p + 1); - } - pre = p; - p = (PondScum *)(p->owner); - } - // See if there's room left... if (sz > pondSize) { - if (nextPond == NULL) + // If not, try the free list... + PondScum *p = freeHeader; + PondScum *pre = NULL; + while (p) { + ASSERT(p->getSize() > 0); + if (p->getSize() >= sz) { + if (pre) + pre->owner = p->owner; + else + freeHeader = (PondScum *)(p->owner); + p->owner = this; + p->resetMark(); // might have lingering mark from previous gc +#ifdef DEBUG + memset((p + 1), 0xB7, p->getSize() - sizeof(PondScum)); +#endif + return (p + 1); + } + pre = p; + p = (PondScum *)(p->owner); + } + // ok, then try the next Pond + if (nextPond == NULL) { + // there isn't one, so make it nextPond = new Pond(sz, nextPond); + } return nextPond->allocFromPond(sz); } - p = (PondScum *)pondTop; + // there was room, so acquire it + PondScum *p = (PondScum *)pondTop; p->owner = this; p->setSize(sz); pondTop += sz; diff --git a/js2/src/js2metadata.h b/js2/src/js2metadata.h index 1fb5a5390d54..010622b192d1 100644 --- a/js2/src/js2metadata.h +++ b/js2/src/js2metadata.h @@ -106,7 +106,8 @@ enum ObjectKind { AlienInstanceKind, ForIteratorKind, - EnvironmentKind // Not an available JS2 runtime kind + EnvironmentKind, // Not an available JS2 runtime kind + MetaDataKind }; enum Plurality { Singular, Plural }; @@ -128,7 +129,7 @@ private: }; // A pond is a place to get chunks of PondScum from and to return them to -#define POND_SIZE (8000) +#define POND_SIZE (16000) #define POND_SANITY (0xFADE2BAD) class Pond { public: @@ -1024,7 +1025,7 @@ public: BytecodeContainer *execution_bCon; }; -class JS2Metadata { +class JS2Metadata : public JS2Object { public: JS2Metadata(World &world); @@ -1178,7 +1179,7 @@ public: TargetList targetList; // stack of potential break/continue targets - void mark(); + virtual void markChildren(); bool showTrees; // debug only, causes parse tree dump