From 41420ce62b7299d0f35ac36a8a417dbaf44240d4 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Mon, 31 Mar 2003 21:38:32 +0000 Subject: [PATCH] GC fixes, added debug info to roots. --- js2/src/epimetheus.cpp | 4 +-- js2/src/js2array.cpp | 28 ++++++++--------- js2/src/js2boolean.cpp | 2 +- js2/src/js2date.cpp | 2 +- js2/src/js2eval.cpp | 10 +++--- js2/src/js2function.cpp | 2 +- js2/src/js2metadata.cpp | 69 ++++++++++++++++++++++++++++------------- js2/src/js2metadata.h | 52 +++++++++++++++++++++++++------ js2/src/js2regexp.cpp | 2 +- js2/src/js2string.cpp | 6 ++-- js2/src/js2value.h | 6 ++-- 11 files changed, 119 insertions(+), 64 deletions(-) diff --git a/js2/src/epimetheus.cpp b/js2/src/epimetheus.cpp index e00722d3ef2..890e506a5b1 100644 --- a/js2/src/epimetheus.cpp +++ b/js2/src/epimetheus.cpp @@ -320,7 +320,7 @@ js2val load(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint if (argc) { // Save off the current top frame and root it. Environment *curEnv = meta->env; - RootKeeper rk(&curEnv); + DEFINE_ROOTKEEPER(rk, curEnv); // Set the environment to global object and system frame so that the // load happens into the top frame. meta->env = new Environment(curEnv->getSystemFrame(), curEnv->getPackageFrame()); @@ -354,7 +354,7 @@ int main(int argc, char **argv) stdOut << "Welcome to Epimetheus.\n"; #endif - RootKeeper rk(&metadata); + DEFINE_ROOTKEEPER(rk, metadata); metadata = new MetaData::JS2Metadata(world); diff --git a/js2/src/js2array.cpp b/js2/src/js2array.cpp index 1c334abcb3e..90e6a0a6d10 100644 --- a/js2/src/js2array.cpp +++ b/js2/src/js2array.cpp @@ -83,7 +83,7 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength) } } Multiname *mn = new Multiname(meta->engine->length_StringAtom, meta->publicNamespace); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); LookupKind lookup(false, JS2VAL_NULL); defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, &lookup, true, result); } @@ -98,7 +98,7 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val * { js2val thatValue = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass)); ArrayInstance *arrInst = checked_cast(JS2VAL_TO_OBJECT(thatValue)); - RootKeeper rk(&arrInst); + DEFINE_ROOTKEEPER(rk, arrInst); if (argc > 0) { if (argc == 1) { if (JS2VAL_IS_NUMBER(argv[0])) { @@ -290,8 +290,8 @@ static js2val Array_reverse(JS2Metadata *meta, const js2val thisValue, js2val * // XXX Need to root the Strings somewhere, this'll do for now.. Multiname *mn1 = new Multiname(meta->publicNamespace); Multiname *mn2 = new Multiname(meta->publicNamespace); - RootKeeper rk1(&mn1); - RootKeeper rk2(&mn2); + DEFINE_ROOTKEEPER(rk1, mn1); + DEFINE_ROOTKEEPER(rk2, mn2); for (uint32 k = 0; k < halfway; k++) { bool deleteResult; @@ -345,8 +345,8 @@ static js2val Array_shift(JS2Metadata *meta, const js2val thisValue, js2val * /* // XXX Need to root the Strings somewhere, this'll do for now.. Multiname *mn1 = new Multiname(meta->publicNamespace); Multiname *mn2 = new Multiname(meta->publicNamespace); - RootKeeper rk1(&mn1); - RootKeeper rk2(&mn2); + DEFINE_ROOTKEEPER(rk1, mn1); + DEFINE_ROOTKEEPER(rk2, mn2); js2val result; bool deleteResult; @@ -425,8 +425,8 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg // XXX Need to root the Strings somewhere, this'll do for now.. Multiname *mn1 = new Multiname(meta->publicNamespace); Multiname *mn2 = new Multiname(meta->publicNamespace); - RootKeeper rk1(&mn1); - RootKeeper rk2(&mn2); + DEFINE_ROOTKEEPER(rk1, mn1); + DEFINE_ROOTKEEPER(rk2, mn2); uint32 n = 0; while (start < end) { mn1->name = meta->engine->numberToString(start); @@ -584,7 +584,7 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv JS2Class *c = meta->objectType(thisObj); // XXX Need to root the Strings somewhere, this'll do for now.. Multiname *mn1 = new Multiname(meta->publicNamespace); - RootKeeper rk1(&mn1); + DEFINE_ROOTKEEPER(rk1, mn1); for (i = 0; i < length; i++) { mn1->name = meta->engine->numberToString(i); c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &vec[i]); @@ -643,8 +643,8 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar // XXX Need to root the Strings somewhere, this'll do for now.. Multiname *mn1 = new Multiname(meta->publicNamespace); Multiname *mn2 = new Multiname(meta->publicNamespace); - RootKeeper rk1(&mn1); - RootKeeper rk2(&mn2); + DEFINE_ROOTKEEPER(rk1, mn1); + DEFINE_ROOTKEEPER(rk2, mn2); for (k = 0; k < deleteCount; k++) { mn1->name = meta->engine->numberToString(start + k); @@ -682,7 +682,7 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar bool deleteResult; mn1->name = meta->engine->numberToString(k + deleteCount - 1); mn2->name = meta->engine->numberToString(k + newItemCount - 1); - if (meta->hasOwnProperty(thisObj, meta->mn1->name)) { + if (meta->hasOwnProperty(thisObj, mn1->name)) { js2val rval; c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &rval); meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval); @@ -716,8 +716,8 @@ static js2val Array_unshift(JS2Metadata *meta, const js2val thisValue, js2val *a // XXX Need to root the Strings somewhere, this'll do for now.. Multiname *mn1 = new Multiname(meta->publicNamespace); Multiname *mn2 = new Multiname(meta->publicNamespace); - RootKeeper rk1(&mn1); - RootKeeper rk2(&mn2); + DEFINE_ROOTKEEPER(rk1, mn1); + DEFINE_ROOTKEEPER(rk2, mn2); for (k = length; k > 0; k--) { bool deleteResult; diff --git a/js2/src/js2boolean.cpp b/js2/src/js2boolean.cpp index 1ca6b15f359..66b05501c5e 100644 --- a/js2/src/js2boolean.cpp +++ b/js2/src/js2boolean.cpp @@ -59,7 +59,7 @@ namespace MetaData { { js2val thatValue = OBJECT_TO_JS2VAL(new BooleanInstance(meta, meta->booleanClass->prototype, meta->booleanClass)); BooleanInstance *boolInst = checked_cast(JS2VAL_TO_OBJECT(thatValue)); - RootKeeper rk(&boolInst); + DEFINE_ROOTKEEPER(rk, boolInst); if (argc > 0) boolInst->mValue = meta->toBoolean(argv[0]); diff --git a/js2/src/js2date.cpp b/js2/src/js2date.cpp index d9f4e92dc87..ef7dea2c49c 100644 --- a/js2/src/js2date.cpp +++ b/js2/src/js2date.cpp @@ -871,7 +871,7 @@ js2val Date_Constructor(JS2Metadata *meta, const js2val /* thisValue */, js2val { js2val thatValue = OBJECT_TO_JS2VAL(new DateInstance(meta, meta->dateClass->prototype, meta->dateClass)); DateInstance *thisInst = checked_cast(JS2VAL_TO_OBJECT(thatValue)); - RootKeeper rk(&thisInst); + DEFINE_ROOTKEEPER(rk, thisInst); /* Date called as constructor */ if (argc == 0) { diff --git a/js2/src/js2eval.cpp b/js2/src/js2eval.cpp index 176ec965475..03b7e7b74ff 100644 --- a/js2/src/js2eval.cpp +++ b/js2/src/js2eval.cpp @@ -267,7 +267,7 @@ namespace MetaData { CompilationData *oldData = startCompilationUnit(bCon, bCon->mSource, bCon->mSourceLocation); ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame); - RootKeeper rk(&runtimeFrame); + DEFINE_ROOTKEEPER(rk, runtimeFrame); runtimeFrame->instantiate(env); runtimeFrame->thisObject = thisValue; runtimeFrame->assignArguments(this, fnObj, argv, argc); @@ -591,7 +591,7 @@ namespace MetaData { // XXX could speed up by pushing knowledge of single namespace? LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); return defaultReadProperty(meta, base, limit, mn, &lookup, phase, rval); } @@ -600,7 +600,7 @@ namespace MetaData { // XXX could speed up by pushing knowledge of single namespace & lookup? LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); return defaultDeleteProperty(meta, base, limit, mn, &lookup, result); } @@ -609,7 +609,7 @@ namespace MetaData { // XXX could speed up by pushing knowledge of single namespace? LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); return defaultWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue); } @@ -666,7 +666,7 @@ namespace MetaData { || ( (JS2VAL_TO_OBJECT(base)->kind == PackageKind) && !checked_cast(JS2VAL_TO_OBJECT(base))->sealed)) ) { QualifiedName qName = multiname->selectPrimaryName(meta); Multiname *mn = new Multiname(qName); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); if ( (meta->findBaseInstanceMember(limit, mn, ReadAccess) == NULL) && (meta->findCommonMember(&base, mn, ReadAccess, true) == NULL) ) { meta->createDynamicProperty(JS2VAL_TO_OBJECT(base), &qName, newValue, ReadWriteAccess, false, true); diff --git a/js2/src/js2function.cpp b/js2/src/js2function.cpp index b23c4fc1731..c590e970045 100644 --- a/js2/src/js2function.cpp +++ b/js2/src/js2function.cpp @@ -77,7 +77,7 @@ namespace MetaData { ASSERT(parser.lexer.peek(true).hasKind(Token::end)); ASSERT(fnExpr); // otherwise, an exception would have been thrown out of here fnExpr->obj = NULL; - RootKeeper rk(&fnExpr->obj); + DEFINE_ROOTKEEPER(rk, fnExpr->obj); JS2Class *exprType; meta->ValidateExpression(&meta->cxt, meta->env, fnExpr); meta->SetupExprNode(meta->env, RunPhase, fnExpr, &exprType); diff --git a/js2/src/js2metadata.cpp b/js2/src/js2metadata.cpp index 668ad4bbec7..e71b8ec5120 100644 --- a/js2/src/js2metadata.cpp +++ b/js2/src/js2metadata.cpp @@ -88,10 +88,10 @@ namespace MetaData { FunctionInstance *JS2Metadata::validateStaticFunction(FunctionDefinition *fnDef, js2val compileThis, bool prototype, bool unchecked, Context *cxt, Environment *env) { ParameterFrame *compileFrame = new ParameterFrame(compileThis, prototype); - RootKeeper rk1(&compileFrame); + DEFINE_ROOTKEEPER(rk1, compileFrame); FunctionInstance *result = new FunctionInstance(this, functionClass->prototype, functionClass); - RootKeeper rk2(&result); + DEFINE_ROOTKEEPER(rk2, result); result->fWrap = new FunctionWrapper(unchecked, compileFrame, env); fnDef->fWrap = result->fWrap; @@ -140,7 +140,7 @@ namespace MetaData { void JS2Metadata::ValidateStmt(Context *cxt, Environment *env, Plurality pl, StmtNode *p) { CompoundAttribute *a = NULL; - RootKeeper rk(&a); + DEFINE_ROOTKEEPER(rk, a); Frame *curTopFrame = env->getTopFrame(); try { @@ -2858,7 +2858,7 @@ doUnary: if (s) { for (NamespaceListIterator nli = multiname->nsList->begin(), nlend = multiname->nsList->end(); (nli != nlend); nli++) { Multiname *mn = new Multiname(multiname->name, *nli); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); InstanceMember *m = findBaseInstanceMember(s, mn, access); if (mBase == NULL) mBase = m; @@ -3235,8 +3235,6 @@ static const uint8 urlCharType[256] = world(world), engine(new JS2Engine(world)), publicNamespace(new Namespace(engine->public_StringAtom)), - mn1(new Multiname(NULL, publicNamespace)), - mn2(new Multiname(NULL, publicNamespace)), bCon(new BytecodeContainer()), glob(new Package(new Namespace(&world.identifiers["internal"]))), env(new Environment(new MetaData::SystemFrame(), glob)), @@ -3245,9 +3243,6 @@ static const uint8 urlCharType[256] = { engine->meta = this; - JS2Object::addRoot(&mn1); - JS2Object::addRoot(&mn2); - cxt.openNamespaces.clear(); cxt.openNamespaces.push_back(publicNamespace); @@ -3713,7 +3708,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name) { Multiname *mn = new Multiname(name, publicNamespace); - RootKeeper rk(&mn); + DEFINE_ROOTKEEPER(rk, mn); js2val val = OBJECT_TO_JS2VAL(obj); return (findCommonMember(&val, mn, ReadWriteAccess, true) != NULL); } @@ -4224,14 +4219,14 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... void ParameterFrame::assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount) { Multiname *mn = new Multiname(NULL, meta->publicNamespace); - RootKeeper rk1(&mn); + DEFINE_ROOTKEEPER(rk1, mn); ASSERT(pluralFrame->kind == ParameterKind); ParameterFrame *plural = checked_cast(pluralFrame); ASSERT((plural->positionalCount == 0) || (plural->positional != NULL)); SimpleInstance *argsObj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);; - RootKeeper rk2(&argsObj); + DEFINE_ROOTKEEPER(rk2, argsObj); // Add the 'arguments' property String *name = &meta->world.identifiers["arguments"]; @@ -4326,17 +4321,28 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... ************************************************************************************/ Pond JS2Object::pond(POND_SIZE, NULL); +#ifdef DEBUG + std::list JS2Object::rootList; +#else std::list JS2Object::rootList; +#endif - // Add a pointer to a gc-allocated object to the root list + // Add a pointer to the (address of a) gc-allocated object to the root list // (Note - we hand out an iterator, so it's essential to // use something like std::list that doesn't mess with locations) +#ifdef DEBUG + JS2Object::RootIterator JS2Object::addRoot(RootKeeper *t) + { + return rootList.insert(rootList.end(), t); + } +#else JS2Object::RootIterator JS2Object::addRoot(void *t) { PondScum **p = (PondScum **)t; ASSERT(p); return rootList.insert(rootList.end(), p); } +#endif // Remove a root pointer void JS2Object::removeRoot(RootIterator ri) @@ -4348,26 +4354,44 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... uint32 JS2Object::gc() { pond.resetMarks(); - // Anything on the root list is a pointer to a JS2Object. - for (std::list::iterator i = rootList.begin(), end = rootList.end(); (i != end); i++) { + // Anything on the root list may also be a pointer to a JS2Object. + for (RootIterator i = rootList.begin(), end = rootList.end(); (i != end); i++) { +#ifdef DEBUG + RootKeeper *r = *i; + if (*(r->p)) { + PondScum *p = (*(r->p) - 1); + ASSERT(p->owner && (p->getSize() >= sizeof(PondScum)) && (p->owner->sanity == POND_SANITY)); + if (p->isJS2Object()) { + JS2Object *obj = (JS2Object *)(p + 1); + GCMARKOBJECT(obj) + } + else + mark(p); + } +#else if (**i) { PondScum *p = (**i) - 1; ASSERT(p->owner && (p->getSize() >= sizeof(PondScum)) && (p->owner->sanity == POND_SANITY)); - JS2Object *obj = (JS2Object *)(p + 1); - GCMARKOBJECT(obj) + if (p->isJS2Object()) { + JS2Object *obj = (JS2Object *)(p + 1); + GCMARKOBJECT(obj) + } + else + mark(p); } +#endif } return pond.moveUnmarkedToFreeList(); } // Allocate a chunk of size s - void *JS2Object::alloc(size_t s) + void *JS2Object::alloc(size_t s, bool isJS2Object) { s += sizeof(PondScum); // 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); + void *p = pond.allocFromPond(s, isJS2Object); ASSERT(((ptrdiff_t)p & 0xF) == 0); return p; } @@ -4429,7 +4453,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } // Allocate from this or the next Pond (make a new one if necessary) - void *Pond::allocFromPond(size_t sz) + void *Pond::allocFromPond(size_t sz, bool isJS2Object) { // See if there's room left... @@ -4459,15 +4483,16 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... // there isn't one; run the gc uint32 released = JS2Object::gc(); if (released > sz) - return JS2Object::alloc(sz - sizeof(PondScum)); + return JS2Object::alloc(sz - sizeof(PondScum), isJS2Object); nextPond = new Pond(sz, nextPond); } - return nextPond->allocFromPond(sz); + return nextPond->allocFromPond(sz, isJS2Object); } // there was room, so acquire it PondScum *p = (PondScum *)pondTop; p->owner = this; p->setSize(sz); + if (isJS2Object) p->setIsJS2Object(); pondTop += sz; pondSize -= sz; #ifdef DEBUG diff --git a/js2/src/js2metadata.h b/js2/src/js2metadata.h index d8deba20483..e4713d040b0 100644 --- a/js2/src/js2metadata.h +++ b/js2/src/js2metadata.h @@ -147,16 +147,22 @@ enum Hint { NoHint, NumberHint, StringHint }; class PondScum { public: + void resetMark() { size &= 0x7FFFFFFF; } void mark() { size |= 0x80000000; } bool isMarked() { return ((size & 0x80000000) != 0); } - uint32 getSize() { return size & 0x7FFFFFFF; } - void setSize(uint32 sz) { ASSERT((sz & 0x8000000) == 0); size = (sz & 0x7FFFFFFF); } + + void setIsJS2Object() { size |= 0x40000000; } + bool isJS2Object() { return ((size & 0x40000000) != 0); } + + uint32 getSize() { return size & 0x3FFFFFFF; } + void setSize(uint32 sz) { ASSERT((sz & 0xC000000) == 0); size = (sz & 0x3FFFFFFF); } Pond *owner; // for a piece of scum in use, this points to it's own Pond // otherwise it's a link to the next item on the free list private: uint32 size; // The high bit is used as the gc mark flag + // The next high bit is the flag that mark JS2Objects (1) or generic pointers }; // A pond is a place to get chunks of PondScum from and to return them to @@ -166,7 +172,7 @@ class Pond { public: Pond(size_t sz, Pond *nextPond); - void *allocFromPond(size_t sz); + void *allocFromPond(size_t sz, bool isJS2Object); uint32 returnToPond(PondScum *p); void resetMarks(); @@ -187,6 +193,8 @@ public: #define GCMARKOBJECT(n) if ((n) && !(n)->isMarked()) { (n)->markObject(); (n)->markChildren(); } #define GCMARKVALUE(v) JS2Object::markJS2Value(v) +class RootKeeper; + class JS2Object { // Every object is either undefined, null, a Boolean, // a number, a string, a namespace, a compound attribute, a class, a method closure, @@ -198,18 +206,23 @@ public: ObjectKind kind; static Pond pond; +#ifdef DEBUG + static std::list rootList; + typedef std::list::iterator RootIterator; + static RootIterator addRoot(RootKeeper *t); +#else static std::list rootList; typedef std::list::iterator RootIterator; - - static uint32 gc(); static RootIterator addRoot(void *t); // pass the address of any JS2Object pointer // Note: Not the address of a JS2VAL! +#endif + static uint32 gc(); static void removeRoot(RootIterator ri); - static void *alloc(size_t s); + static void *alloc(size_t s, bool isJS2Object = false); static void unalloc(void *p); - void *operator new(size_t s) { return alloc(s); } + void *operator new(size_t s) { return alloc(s, true); } void operator delete(void *p) { unalloc(p); } virtual void markChildren() { } // XXX !!!! XXXX these are supposed to not have vtables !!!! @@ -222,12 +235,33 @@ public: class RootKeeper { public: - RootKeeper(void *t) : ri(JS2Object::addRoot(t)) { } +#ifdef DEBUG + RootKeeper(void *p, int line, char *pfile) : p((PondScum **)p), line(line) + { + file = new char[strlen(pfile) + 1]; + strcpy(file, pfile); + ri = JS2Object::addRoot(this); + } +#else + RootKeeper(void *p) :{ ri = JS2Object::addRoot(p); } +#endif ~RootKeeper() { JS2Object::removeRoot(ri); } JS2Object::RootIterator ri; + +#ifdef DEBUG + PondScum **p; + int line; + char *file; +#endif }; +#ifdef DEBUG +#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__); +#else +#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj); +#endif + class Attribute : public JS2Object { public: enum AttributeKind { TrueAttr, FalseAttr, NamespaceAttr, CompoundAttr }; @@ -1248,8 +1282,6 @@ public: // The one and only 'public' namespace Namespace *publicNamespace; - Multiname *mn1, *mn2; // useful, gc-rooted multiname temps. - LocalMember *forbiddenMember; // just need one of these hanging around // The base classes: diff --git a/js2/src/js2regexp.cpp b/js2/src/js2regexp.cpp index 8dcf9d5ed4b..17ed15d89b0 100644 --- a/js2/src/js2regexp.cpp +++ b/js2/src/js2regexp.cpp @@ -183,7 +183,7 @@ namespace MetaData { // XXX Change constructors to take js2val pointer for the result (which would be an already // rooted pointer). RegExpInstance *thisInst = new RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass); - RootKeeper rk(&thisInst); + DEFINE_ROOTKEEPER(rk, thisInst); js2val thatValue = OBJECT_TO_JS2VAL(thisInst); REuint32 flags = 0; diff --git a/js2/src/js2string.cpp b/js2/src/js2string.cpp index c220143c723..cfe5f05c9a1 100644 --- a/js2/src/js2string.cpp +++ b/js2/src/js2string.cpp @@ -59,7 +59,7 @@ js2val String_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val { js2val thatValue = OBJECT_TO_JS2VAL(new StringInstance(meta, meta->stringClass->prototype, meta->stringClass)); StringInstance *strInst = checked_cast(JS2VAL_TO_OBJECT(thatValue)); - RootKeeper rk(&strInst); + DEFINE_ROOTKEEPER(rk, strInst); if (argc > 0) strInst->mValue = meta->engine->allocStringPtr(meta->toString(argv[0])); else @@ -169,7 +169,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar } else { ArrayInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass); - RootKeeper rk(&A); + DEFINE_ROOTKEEPER(rk, A); int32 index = 0; int32 lastIndex = 0; while (true) { @@ -405,7 +405,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass)); ArrayInstance *A = checked_cast(JS2VAL_TO_OBJECT(result)); - RootKeeper rk(&A); + DEFINE_ROOTKEEPER(rk, A); uint32 lim; js2val separatorV = (argc > 0) ? argv[0] : JS2VAL_UNDEFINED; diff --git a/js2/src/js2value.h b/js2/src/js2value.h index 128809fa778..7eea9d3eecd 100644 --- a/js2/src/js2value.h +++ b/js2/src/js2value.h @@ -35,8 +35,6 @@ #define js2value_h___ -#define JS2_BIT(n) ((uint32)1 << (n)) -#define JS2_BITMASK(n) (JS2_BIT(n) - 1) /* * Type tags stored in the low bits of a js2val. */ @@ -67,11 +65,11 @@ /* Type tag bitfield length and derived macros. */ #define JS2VAL_TAGBITS 4 -#define JS2VAL_TAGMASK JS2_BITMASK(JS2VAL_TAGBITS) +#define JS2VAL_TAGMASK JS_BITMASK(JS2VAL_TAGBITS) #define JS2VAL_TAG(v) ((v) & JS2VAL_TAGMASK) #define JS2VAL_SETTAG(v,t) ((v) | (t)) #define JS2VAL_CLRTAG(v) ((v) & ~(js2val)JS2VAL_TAGMASK) -#define JS2VAL_ALIGN JS2_BIT(JS2VAL_TAGBITS) +#define JS2VAL_ALIGN JS_BIT(JS2VAL_TAGBITS) #define JS2VAL_INT_POW2(n) ((js2val)1 << (n)) #define JS2VAL_INT_MAX (JS2VAL_INT_POW2(30) - 1)