Continue the work to move Values inside the v4 engine to the js stack
authorLars Knoll <lars.knoll@theqtcompany.com>
Wed, 25 Mar 2015 12:49:51 +0000 (13:49 +0100)
committerSimon Hausmann <simon.hausmann@theqtcompany.com>
Fri, 24 Apr 2015 15:21:20 +0000 (15:21 +0000)
Started with objectPrototype, the next commits will move more
of them over into the new data structure.

Change-Id: I1a048e95149ce69e4e42094db2dd738ce49b50b8
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
src/qml/jsruntime/qv4argumentsobject.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4functionobject.cpp
src/qml/jsruntime/qv4jsonobject.cpp
src/qml/jsruntime/qv4mathobject.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4regexpobject_p.h
src/qml/jsruntime/qv4runtime.cpp

index 20983bb..d7a8127 100644 (file)
@@ -41,7 +41,7 @@ DEFINE_OBJECT_VTABLE(ArgumentsObject);
 
 Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context)
     : Heap::Object(context->d()->strictMode ? context->d()->engine->strictArgumentsObjectClass : context->d()->engine->argumentsObjectClass,
-                   context->d()->engine->objectPrototype.objectValue())
+                   context->d()->engine->objectPrototype())
     , context(context->d())
     , fullyCreated(false)
 {
index b05b080..480949b 100644 (file)
@@ -228,6 +228,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
 
     exceptionValue = jsAlloca(1);
     globalObject = static_cast<Object *>(jsAlloca(1));
+    jsObjects = jsAlloca(NJSObjects);
 
 #ifdef V4_USE_VALGRIND
     VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, 2*JSStackLimit);
@@ -282,10 +283,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     id_buffer = newIdentifier(QStringLiteral("buffer"));
     id_lastIndex = newIdentifier(QStringLiteral("lastIndex"));
 
-    objectPrototype = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0);
+    jsObjects[ObjectProto] = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0);
 
     arrayClass = emptyClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
-    arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype.as<Object>());
+    arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype());
 
     InternalClass *argsClass = emptyClass->addMember(id_length, Attr_NotEnumerable);
     argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable);
@@ -296,15 +297,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     Q_ASSERT(globalObject->d()->vtable);
     initRootContext();
 
-    stringPrototype = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype.as<Object>());
-    numberPrototype = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype.as<Object>());
-    booleanPrototype = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype.as<Object>());
-    datePrototype = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype.as<Object>());
+    stringPrototype = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype());
+    numberPrototype = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype());
+    booleanPrototype = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype());
+    datePrototype = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype());
 
     uint index;
     InternalClass *functionProtoClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable, &index);
     Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
-    functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.as<Object>());
+    functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype());
     functionClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
     Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
     simpleScriptFunctionClass = functionClass->addMember(id_name, Attr_ReadOnly, &index);
@@ -320,7 +321,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
     Q_ASSERT(index == RegExpObject::Index_ArrayInput);
 
-    errorPrototype = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype.as<Object>());
+    errorPrototype = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype());
     evalErrorPrototype = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype.as<Object>());
     rangeErrorPrototype = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype.as<Object>());
     referenceErrorPrototype = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype.as<Object>());
@@ -328,8 +329,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     typeErrorPrototype = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype.as<Object>());
     uRIErrorPrototype = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype.as<Object>());
 
-    variantPrototype = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype.as<Object>());
-    Q_ASSERT(variantPrototype.as<Object>()->prototype() == objectPrototype.as<Object>()->d());
+    variantPrototype = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype());
+    Q_ASSERT(variantPrototype.as<Object>()->prototype() == objectPrototype()->d());
 
     Scope scope(this);
     sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.as<Object>()));
@@ -351,7 +352,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(global);
     uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(global);
 
-    static_cast<ObjectPrototype *>(objectPrototype.as<Object>())->init(this, objectCtor.as<Object>());
+    static_cast<ObjectPrototype *>(objectPrototype())->init(this, objectCtor.as<Object>());
     static_cast<StringPrototype *>(stringPrototype.as<Object>())->init(this, stringCtor.as<Object>());
     static_cast<NumberPrototype *>(numberPrototype.as<Object>())->init(this, numberCtor.as<Object>());
     static_cast<BooleanPrototype *>(booleanPrototype.as<Object>())->init(this, booleanCtor.as<Object>());
@@ -374,11 +375,11 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     // typed arrays
 
     arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(global);
-    arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype.as<Object>());
+    arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype());
     static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.as<Object>())->init(this, arrayBufferCtor.as<Object>());
 
     dataViewCtor = memoryManager->alloc<DataViewCtor>(global);
-    dataViewPrototype = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype.as<Object>());
+    dataViewPrototype = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype());
     static_cast<DataViewPrototype *>(dataViewPrototype.as<Object>())->init(this, dataViewCtor.as<Object>());
 
     for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
@@ -951,7 +952,6 @@ void ExecutionEngine::markObjects()
     for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
         typedArrayCtors[i].mark(this);
 
-    objectPrototype.mark(this);
     arrayPrototype.mark(this);
     stringPrototype.mark(this);
     numberPrototype.mark(this);
index a6a05c0..a71491a 100644 (file)
@@ -128,6 +128,12 @@ public:
     QQmlEngine *qmlEngine() const;
     QV8Engine *v8Engine;
 
+    enum JSObjects {
+        ObjectProto,
+        NJSObjects
+    };
+    Value *jsObjects;
+
     Value objectCtor;
     Value stringCtor;
     Value numberCtor;
@@ -148,7 +154,7 @@ public:
     enum { NTypedArrayTypes = 9 }; // avoid header dependency
     Value typedArrayCtors[NTypedArrayTypes];
 
-    Value objectPrototype;
+    Object *objectPrototype() { return reinterpret_cast<Object *>(jsObjects + ObjectProto); }
     Value arrayPrototype;
     Value stringPrototype;
     Value numberPrototype;
index 5a68cf6..2c8da4c 100644 (file)
@@ -152,7 +152,7 @@ void FunctionObject::init(String *n, bool createProto)
 
     ensureMemberIndex(s.engine, Heap::FunctionObject::Index_Prototype);
     if (createProto) {
-        ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype.as<Object>()));
+        ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype()));
         proto->ensureMemberIndex(s.engine, Heap::FunctionObject::Index_ProtoConstructor);
         proto->memberData()->data[Heap::FunctionObject::Index_ProtoConstructor] = this->asReturnedValue();
         memberData()->data[Heap::FunctionObject::Index_Prototype] = proto.asReturnedValue();
@@ -574,7 +574,7 @@ Heap::Object *SimpleScriptFunction::protoForConstructor()
     ScopedObject p(scope, protoProperty());
     if (p)
         return p->d();
-    return scope.engine->objectPrototype.as<Object>()->d();
+    return scope.engine->objectPrototype()->d();
 }
 
 
index e2b27c5..95d08d7 100644 (file)
@@ -852,7 +852,7 @@ QString Stringify::JA(ArrayObject *a)
 
 
 Heap::JsonObject::JsonObject(ExecutionEngine *e)
-    : Heap::Object(e->emptyClass, e->objectPrototype.objectValue())
+    : Heap::Object(e->emptyClass, e->objectPrototype())
 {
     Scope scope(e);
     ScopedObject o(scope, this);
index 4e51de9..c498160 100644 (file)
@@ -48,7 +48,7 @@ DEFINE_OBJECT_VTABLE(MathObject);
 static const double qt_PI = 2.0 * ::asin(1.0);
 
 Heap::MathObject::MathObject(ExecutionEngine *e)
-    : Heap::Object(e->emptyClass, e->objectPrototype.objectValue())
+    : Heap::Object(e->emptyClass, e->objectPrototype())
 {
     Scope scope(e);
     ScopedObject m(scope, this);
index 87c024b..3375b16 100644 (file)
@@ -47,11 +47,7 @@ namespace QV4 {
 namespace Heap {
 
 struct Object : Base {
-    Object(ExecutionEngine *engine)
-        : internalClass(engine->emptyClass),
-          prototype(static_cast<Object *>(engine->objectPrototype.m))
-    {
-    }
+    inline Object(ExecutionEngine *engine);
     Object(InternalClass *internal, QV4::Object *prototype);
 
     const Property *propertyAt(uint index) const { return reinterpret_cast<const Property *>(memberData->data + index); }
@@ -334,6 +330,12 @@ private:
 
 namespace Heap {
 
+inline Object::Object(ExecutionEngine *engine)
+    : internalClass(engine->emptyClass),
+      prototype(static_cast<Object *>(engine->objectPrototype()->m))
+{
+}
+
 struct BooleanObject : Object {
     BooleanObject(InternalClass *ic, QV4::Object *prototype)
         : Object(ic, prototype),
index af83282..29d2061 100644 (file)
@@ -146,7 +146,7 @@ struct RegExpPrototype: RegExpObject
 };
 
 inline Heap::RegExpPrototype::RegExpPrototype(ExecutionEngine *e)
-    : RegExpObject(e->emptyClass, e->objectPrototype.objectValue())
+    : RegExpObject(e->emptyClass, e->objectPrototype())
 {
 }
 
index bff9eaf..f2565e2 100644 (file)
@@ -1200,7 +1200,7 @@ ReturnedValue Runtime::objectLiteral(ExecutionEngine *engine, const QV4::Value *
 {
     Scope scope(engine);
     QV4::InternalClass *klass = engine->currentContext()->compilationUnit->runtimeClasses[classId];
-    ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype.as<Object>()));
+    ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype()));
 
     {
         bool needSparseArray = arrayGetterSetterCountAndFlags >> 30;