From 3148ff681f388eebdf2e473e5ec8c8e766138e92 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Fri, 4 Apr 2003 15:47:35 +0000 Subject: [PATCH] Disneyland bug fixes; gc bugs. git-svn-id: svn://10.0.0.236/trunk@140701 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/js2array.cpp | 1 + mozilla/js2/src/js2engine.cpp | 16 +++++++------- mozilla/js2/src/js2eval.cpp | 13 ++++++++++++ mozilla/js2/src/js2metadata.cpp | 37 ++++++++++++++++++++++++++------- mozilla/js2/src/js2metadata.h | 31 +++++++++++++++------------ 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/mozilla/js2/src/js2array.cpp b/mozilla/js2/src/js2array.cpp index 90e6a0a6d10..c752c6dd954 100644 --- a/mozilla/js2/src/js2array.cpp +++ b/mozilla/js2/src/js2array.cpp @@ -110,6 +110,7 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val * } else { meta->createDynamicProperty(arrInst, meta->engine->numberToString((int32)0), argv[0], ReadWriteAccess, false, true); + setLength(meta, arrInst, 1); } } else { diff --git a/mozilla/js2/src/js2engine.cpp b/mozilla/js2/src/js2engine.cpp index 0467949db8b..de63ec89a11 100644 --- a/mozilla/js2/src/js2engine.cpp +++ b/mozilla/js2/src/js2engine.cpp @@ -196,13 +196,13 @@ namespace MetaData { if (*float64Table[hash] == x) return float64Table[hash]; else { - float64 *p = (float64 *)JS2Object::alloc(sizeof(float64)); + float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), false); *p = x; return p; } } else { - float64 *p = (float64 *)JS2Object::alloc(sizeof(float64)); + float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), false); float64Table[hash] = p; *p = x; return p; @@ -216,13 +216,13 @@ namespace MetaData { String *JS2Engine::allocStringPtr(const String *s) { - String *p = (String *)(JS2Object::alloc(sizeof(String))); + String *p = (String *)(JS2Object::alloc(sizeof(String), false)); return new (p) String(*s); } String *JS2Engine::concatStrings(const String *s1, const String *s2) { - String *p = (String *)(JS2Object::alloc(sizeof(String))); + String *p = (String *)(JS2Object::alloc(sizeof(String), false)); String *result = new (p) String(*s1); result->append(*s2); return result; @@ -247,7 +247,7 @@ namespace MetaData { // Don't store as an int, even if possible, we need to retain 'longness' js2val JS2Engine::allocULong(uint64 x) { - uint64 *p = (uint64 *)(JS2Object::alloc(sizeof(uint64))); + uint64 *p = (uint64 *)(JS2Object::alloc(sizeof(uint64), false)); *p = x; return ULONG_TO_JS2VAL(p); @@ -256,7 +256,7 @@ namespace MetaData { // Don't store as an int, even if possible, we need to retain 'longness' js2val JS2Engine::allocLong(int64 x) { - int64 *p = (int64 *)(JS2Object::alloc(sizeof(int64))); + int64 *p = (int64 *)(JS2Object::alloc(sizeof(int64), false)); *p = x; return LONG_TO_JS2VAL(p); } @@ -264,7 +264,7 @@ namespace MetaData { // Don't store as an int, even if possible, we need to retain 'floatness' js2val JS2Engine::allocFloat(float32 x) { - float32 *p = (float32 *)(JS2Object::alloc(sizeof(float32))); + float32 *p = (float32 *)(JS2Object::alloc(sizeof(float32), false)); *p = x; return FLOAT_TO_JS2VAL(p); } @@ -417,7 +417,7 @@ namespace MetaData { for (int i = 0; i < 256; i++) float64Table[i] = NULL; - float64 *p = (float64 *)JS2Object::alloc(sizeof(float64)); + float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), false); *p = nan; nanValue = DOUBLE_TO_JS2VAL(p); posInfValue = DOUBLE_TO_JS2VAL(allocNumber(positiveInfinity)); diff --git a/mozilla/js2/src/js2eval.cpp b/mozilla/js2/src/js2eval.cpp index 03b7e7b74ff..850d48de697 100644 --- a/mozilla/js2/src/js2eval.cpp +++ b/mozilla/js2/src/js2eval.cpp @@ -589,6 +589,7 @@ namespace MetaData { bool defaultReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval) { // XXX could speed up by pushing knowledge of single namespace? + DEFINE_ROOTKEEPER(rk1, name); LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(rk, mn); @@ -597,6 +598,7 @@ namespace MetaData { bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result) { + DEFINE_ROOTKEEPER(rk1, name); // XXX could speed up by pushing knowledge of single namespace & lookup? LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); @@ -606,6 +608,7 @@ namespace MetaData { bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) { + DEFINE_ROOTKEEPER(rk1, name); // XXX could speed up by pushing knowledge of single namespace? LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); @@ -644,6 +647,16 @@ namespace MetaData { return result; } + bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) + { + DEFINE_ROOTKEEPER(rk1, name); + // XXX could speed up by pushing knowledge of single namespace? + LookupKind lookup(false, JS2VAL_NULL); + Multiname *mn = new Multiname(name, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk, mn); + return arrayWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue); + } + bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue) { InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess); diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index e71b8ec5120..79c572448e6 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -3359,6 +3359,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... /*** ECMA 3 Array Class ***/ MAKEBUILTINCLASS(arrayClass, objectClass, true, true, true, engine->allocStringPtr(&world.identifiers["Array"]), JS2VAL_NULL); arrayClass->write = arrayWriteProperty; + arrayClass->writePublic = arrayWritePublic; v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true); defineLocalMember(env, &world.identifiers["Array"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0); initArrayObject(this); @@ -3960,7 +3961,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... js2val JS2Class::implicitCoerce(JS2Metadata *meta, js2val newValue) { - if (JS2VAL_IS_NULL(newValue) || (meta->objectType(newValue) == this)) + if (JS2VAL_IS_NULL(newValue) || meta->objectType(newValue)->isAncestor(this) ) return newValue; meta->reportError(Exception::badValueError, "Illegal coercion", meta->engine->errorPos()); return JS2VAL_VOID; @@ -4046,6 +4047,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... void SimpleInstance::markChildren() { GCMARKOBJECT(type) + GCMARKVALUE(super); if (fWrap) { GCMARKOBJECT(fWrap->compileFrame); GCMARKOBJECT(fWrap->env); @@ -4191,6 +4193,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... void Package::markChildren() { NonWithFrame::markChildren(); + GCMARKVALUE(super); GCMARKOBJECT(internalNamespace) for (LocalBindingIterator bi = localBindings.begin(), bend = localBindings.end(); (bi != bend); bi++) { LocalBindingEntry *lbe = *bi; @@ -4242,11 +4245,12 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... ASSERT(plural->positional[i]->cloneContent->kind == Member::Variable); (checked_cast(plural->positional[i]->cloneContent))->value = argBase[i]; } - mn->name = meta->engine->numberToString(i); - meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->arrayClass, mn->name, true, argBase[i]); +// mn->name = meta->engine->numberToString(i); + meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->arrayClass, meta->engine->numberToString(i), true, argBase[i]); } setLength(meta, argsObj, i); - meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->arrayClass, &meta->world.identifiers["callee"], true, argBase[i]); +// mn->name = meta->engine->allocStringPtr(&meta->world.identifiers["callee"]); + meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->arrayClass, meta->engine->allocStringPtr("callee"), true, OBJECT_TO_JS2VAL(fnObj)); } @@ -4258,6 +4262,18 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } + /************************************************************************************ + * + * Variable + * + ************************************************************************************/ + + void Variable::mark() + { + GCMARKVALUE(value); + GCMARKOBJECT(type) + } + /************************************************************************************ * * BlockFrame @@ -4366,7 +4382,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... GCMARKOBJECT(obj) } else - mark(p); + mark(p + 1); } #else if (**i) { @@ -4377,7 +4393,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... GCMARKOBJECT(obj) } else - mark(p); + mark(p + 1); } #endif } @@ -4470,6 +4486,10 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... freeHeader = (PondScum *)(p->owner); p->owner = this; p->resetMark(); // might have lingering mark from previous gc + if (isJS2Object) + p->setIsJS2Object(); + else + p->clearIsJS2Object(); #ifdef DEBUG memset((p + 1), 0xB7, p->getSize() - sizeof(PondScum)); #endif @@ -4492,7 +4512,10 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... PondScum *p = (PondScum *)pondTop; p->owner = this; p->setSize(sz); - if (isJS2Object) p->setIsJS2Object(); + if (isJS2Object) + p->setIsJS2Object(); + else + p->clearIsJS2Object(); pondTop += sz; pondSize -= sz; #ifdef DEBUG diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index e4713d040b0..0409c14e481 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -79,6 +79,7 @@ bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multin bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result); bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result); bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result); +bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue); @@ -148,21 +149,23 @@ enum Hint { NoHint, NumberHint, StringHint }; class PondScum { public: - void resetMark() { size &= 0x7FFFFFFF; } - void mark() { size |= 0x80000000; } - bool isMarked() { return ((size & 0x80000000) != 0); } + void resetMark() { markFlag = 0; } + void mark() { markFlag = 1; } + bool isMarked() { return (markFlag != 0); } - void setIsJS2Object() { size |= 0x40000000; } - bool isJS2Object() { return ((size & 0x40000000) != 0); } + void setIsJS2Object() { js2Flag = 1; } + void clearIsJS2Object() { js2Flag = 0; } + bool isJS2Object() { return (js2Flag != 0); } - uint32 getSize() { return size & 0x3FFFFFFF; } - void setSize(uint32 sz) { ASSERT((sz & 0xC000000) == 0); size = (sz & 0x3FFFFFFF); } + uint32 getSize() { return size; } + void setSize(uint32 sz) { ASSERT(sz < JS_BIT(30)); size = sz; } 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 + unsigned int markFlag:1; + unsigned int js2Flag:1; + unsigned int size:30; }; // A pond is a place to get chunks of PondScum from and to return them to @@ -219,7 +222,7 @@ public: static uint32 gc(); static void removeRoot(RootIterator ri); - static void *alloc(size_t s, bool isJS2Object = false); + static void *alloc(size_t s, bool isJS2Object); static void unalloc(void *p); void *operator new(size_t s) { return alloc(s, true); } @@ -242,10 +245,11 @@ public: strcpy(file, pfile); ri = JS2Object::addRoot(this); } + ~RootKeeper() { JS2Object::removeRoot(ri); delete file; } #else RootKeeper(void *p) :{ ri = JS2Object::addRoot(p); } -#endif ~RootKeeper() { JS2Object::removeRoot(ri); } +#endif JS2Object::RootIterator ri; @@ -380,6 +384,7 @@ public: // variable instantations in a parameter frame. virtual LocalMember *clone() { if (forbidden) return this; ASSERT(false); return NULL; } + virtual void mark() { } bool forbidden; }; @@ -400,7 +405,7 @@ public: // XXX union this with the type field later? VariableBinding *vb; // The variable definition node, to resolve future types - virtual void mark() { GCMARKVALUE(value); } + virtual void mark(); }; class DynamicVariable : public LocalMember { @@ -816,7 +821,7 @@ public: // are added. class ArrayInstance : public SimpleInstance { public: - ArrayInstance(JS2Metadata *meta, js2val parent, JS2Class *type) : SimpleInstance(meta, parent, type) { setLength(meta, this, 0); } + ArrayInstance(JS2Metadata *meta, js2val parent, JS2Class *type) : SimpleInstance(meta, parent, type) { } virtual ~ArrayInstance() { } };