Faster marking of objects in the GC
authorLars Knoll <lars.knoll@digia.com>
Fri, 25 Jan 2013 11:43:44 +0000 (12:43 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 25 Jan 2013 12:02:36 +0000 (13:02 +0100)
Change-Id: I4ccbf7fc50758fc176bfdb2f0382a7ec1f18d6ba
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4argumentsobject.cpp
qv4argumentsobject.h
qv4array.cpp
qv4array.h
qv4functionobject.cpp
qv4functionobject.h
qv4managed.h
qv4mm.cpp
qv4mm.h
qv4object.cpp
qv4object.h

index b803644..320b3e0 100644 (file)
@@ -116,14 +116,14 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
     return result;
 }
 
-void ArgumentsObject::getCollectables(QVector<Object *> &objects)
+void ArgumentsObject::markObjects()
 {
     for (int i = 0; i < mappedArguments.size(); ++i) {
         Object *o = mappedArguments.at(i).asObject();
         if (o)
-            objects.append(o);
+            o->mark();
     }
-    Object::getCollectables(objects);
+    Object::markObjects();
 }
 
 
index 398f5de..c3f5de7 100644 (file)
@@ -77,7 +77,7 @@ struct ArgumentsObject: Object {
 
     bool defineOwnProperty(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc);
 
-    virtual void getCollectables(QVector<Object *> &objects);
+    virtual void markObjects();
 };
 
 }
index 8cf745e..70bbd9d 100644 (file)
@@ -628,18 +628,19 @@ bool Array::setLength(uint newLen) {
     return ok;
 }
 
-void Array::getCollectables(QVector<Object *> &objects) const {
+void Array::markObjects() const
+{
     uint i = sparse ? 0 : offset;
     for (; i < (uint)values.size(); ++i) {
         const PropertyDescriptor &pd = values.at(i);
         if (pd.isData()) {
             if (Object *o = pd.value.asObject())
-                objects.append(o);
+                o->mark();
          } else if (pd.isAccessor()) {
             if (pd.get)
-                objects.append(pd.get);
+                pd.get->mark();
             if (pd.set)
-                objects.append(pd.set);
+                pd.set->mark();
         }
     }
 }
index ead2f34..19aa99b 100644 (file)
@@ -543,7 +543,7 @@ public:
         }
     }
 
-    void getCollectables(QVector<Object *> &objects) const;
+    void markObjects() const;
 
     void push_front(Value v) {
         if (!sparse) {
index 7985491..b580f84 100644 (file)
@@ -402,13 +402,13 @@ bool BoundFunction::hasInstance(ExecutionContext *ctx, const Value &value)
     return target->hasInstance(ctx, value);
 }
 
-void BoundFunction::getCollectables(QVector<Object *> &objects)
+void BoundFunction::markObjects()
 {
-    FunctionObject::getCollectables(objects);
-    objects.append(target);
+    target->mark();
     if (Object *o = boundThis.asObject())
-        objects.append(o);
+        o->mark();
     for (int i = 0; i < boundArgs.size(); ++i)
         if (Object *o = boundArgs.at(i).asObject())
-            objects.append(o);
+            o->mark();
+    FunctionObject::markObjects();
 }
index 95e06e1..f913744 100644 (file)
@@ -210,7 +210,7 @@ struct BoundFunction: FunctionObject {
     virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
     virtual Value construct(ExecutionContext *context, Value *args, int argc);
     virtual bool hasInstance(ExecutionContext *ctx, const Value &value);
-    virtual void getCollectables(QVector<Object *> &objects);
+    virtual void markObjects();
 };
 
 } // namespace VM
index 51aa68a..855200d 100644 (file)
@@ -71,8 +71,15 @@ public:
     void *operator new(size_t size, MemoryManager *mm);
     void operator delete(void *ptr);
 
+    inline void mark() {
+        if (markBit)
+            return;
+        markBit = 1;
+        markObjects();
+    }
+
 protected:
-    virtual void getCollectables(QVector<Object *> &objects) = 0;
+    virtual void markObjects() = 0;
 
     union {
         Managed *nextFree;
index 895026d..e4f1fbe 100644 (file)
--- a/qv4mm.cpp
+++ b/qv4mm.cpp
@@ -165,29 +165,15 @@ void MemoryManager::scribble(Managed *obj, int c, int size) const
         ::memset((void *)(obj + 1), c, size - sizeof(Managed));
 }
 
-std::size_t MemoryManager::mark(const QVector<Object *> &objects)
+void MemoryManager::mark(const QVector<Object *> &objects)
 {
-    std::size_t marks = 0;
-
-    QVector<Object *> kids;
-    kids.reserve(32);
-
     foreach (Object *o, objects) {
         if (!o)
             continue;
-
-        Managed *obj = o;
-        assert(obj->inUse);
-        if (obj->markBit == 0) {
-            obj->markBit = 1;
-            ++marks;
-            static_cast<Managed *>(o)->getCollectables(kids);
-            marks += mark(kids);
-            kids.resize(0);
-        }
+        o->mark();
     }
 
-    return marks;
+    return;
 }
 
 std::size_t MemoryManager::sweep()
diff --git a/qv4mm.h b/qv4mm.h
index 5790ba4..0dd3e61 100644 (file)
--- a/qv4mm.h
+++ b/qv4mm.h
@@ -111,7 +111,7 @@ protected:
 
 private:
     void collectRoots(QVector<VM::Object *> &roots) const;
-    static std::size_t mark(const QVector<Object *> &objects);
+    static void mark(const QVector<Object *> &objects);
     std::size_t sweep();
     std::size_t sweep(char *chunkStart, std::size_t chunkSize, size_t size);
 
index 108ad48..5f8a693 100644 (file)
@@ -168,10 +168,10 @@ void Object::defineReadonlyProperty(String *name, Value value)
     pd->value = value;
 }
 
-void Object::getCollectables(QVector<Object *> &objects)
+void Object::markObjects()
 {
     if (prototype)
-        objects.append(prototype);
+        prototype->mark();
 
     if (members) {
         for (PropertyTable::iterator it = members->begin(), eit = members->end(); it < eit; ++it) {
@@ -180,16 +180,16 @@ void Object::getCollectables(QVector<Object *> &objects)
             PropertyDescriptor &pd = (*it)->descriptor;
             if (pd.isData()) {
                 if (Object *o = pd.value.asObject())
-                    objects.append(o);
+                    o->mark();
             } else if (pd.isAccessor()) {
                 if (pd.get)
-                    objects.append(pd.get);
+                    pd.get->mark();
                 if (pd.set)
-                    objects.append(pd.set);
+                    pd.set->mark();
             }
         }
     }
-    array.getCollectables(objects);
+    array.markObjects();
 }
 
 // Section 8.12.1
@@ -660,10 +660,10 @@ void ArrayObject::init(ExecutionContext *context)
 
 
 
-void ForEachIteratorObject::getCollectables(QVector<Object *> &objects)
+void ForEachIteratorObject::markObjects()
 {
-    Object::getCollectables(objects);
+    Object::markObjects();
     if (it.object)
-        objects.append(it.object);
+        it.object->mark();
 }
 
index ddf0d05..df7cf1c 100644 (file)
@@ -164,7 +164,7 @@ struct Object: Managed {
     void defineReadonlyProperty(String *name, Value value);
 
 protected:
-    virtual void getCollectables(QVector<Object *> &objects);
+    virtual void markObjects();
 
     friend struct ObjectIterator;
 };
@@ -178,7 +178,7 @@ struct ForEachIteratorObject: Object {
     Value nextPropertyName() { return it.nextPropertyNameAsString(); }
 
 protected:
-    virtual void getCollectables(QVector<Object *> &objects);
+    virtual void markObjects();
 };
 
 struct BooleanObject: Object {