Use QDeclarativePool to allocate the V4 instructions.
authorRoberto Raggi <roberto.raggi@nokia.com>
Wed, 20 Jul 2011 10:51:12 +0000 (12:51 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 30 Aug 2011 11:18:28 +0000 (13:18 +0200)
Change-Id: Ib4a9748bf81392a901c8ae94a8746f2e52f7284e
Reviewed-on: http://codereview.qt.nokia.com/3759
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>

src/declarative/qml/v4/qdeclarativev4compiler.cpp
src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
src/declarative/qml/v4/qdeclarativev4ir.cpp
src/declarative/qml/v4/qdeclarativev4ir_p.h
src/declarative/qml/v4/qdeclarativev4irbuilder.cpp

index 332ce03..4890722 100644 (file)
@@ -91,11 +91,12 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
         if (IR::Stmt *terminator = block->terminator()) {
             if (IR::CJump *cj = terminator->asCJump()) {
                 if (cj->iffalse != next) {
-                    block->i(new (_function->module->pool) IR::Jump(cj->iffalse));
+                    IR::Jump *jump = _function->module->pool->New<IR::Jump>();
+                    jump->init(cj->iffalse);
+                    block->statements.append(jump);
                 }
             } else if (IR::Jump *j = terminator->asJump()) {
                 if (j->target == next) {
-                    delete block->statements.at(block->statements.size() - 1);
                     block->statements.resize(block->statements.size() - 1);
                 }
             }
@@ -269,7 +270,7 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
         instr.load_id(currentReg, e->index);
         gen(instr);
 
-        _subscribeName << QLatin1String("$$$ID_") + e->id;
+        _subscribeName << QLatin1String("$$$ID_") + *e->id;
 
         if (blockNeedsSubscription(_subscribeName)) {
             Instr sub;
@@ -292,7 +293,7 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
     } break;
 
     case IR::Name::AttachType: {
-        _subscribeName << e->id;
+        _subscribeName << *e->id;
 
         Instr attached;
         attached.common.type = Instr::LoadAttached;
@@ -305,7 +306,7 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
     } break;
 
     case IR::Name::Property: {
-        _subscribeName << e->id;
+        _subscribeName << *e->id;
 
         QMetaProperty prop = e->meta->property(e->index);
         int fastFetchIndex = QDeclarativeFastProperties::instance()->accessorIndexForProperty(e->meta, e->index);
@@ -989,7 +990,7 @@ void QDeclarativeV4CompilerPrivate::resetInstanceState()
     registeredStrings = committed.registeredStrings;
     bytecode.clear();
     patches.clear();
-    pool.reset(); // reset the memory pool without disposing the allocated memory
+    pool.clear();
     currentReg = 0;
 }
 
index e2c85f4..b64aff9 100644 (file)
@@ -137,7 +137,7 @@ public:
             : block(block), offset(index) {}
     };
     QVector<Patch> patches;
-    QDeclarativeJS::MemoryPool pool;
+    QDeclarativePool pool;
 
     // Committed binding data
     struct {
index bc2cc62..9555b9e 100644 (file)
@@ -186,29 +186,30 @@ QString String::escape(const QStringRef &s)
     return r;
 }
 
-Name::Name(Name *base, Type type, QString &id, Symbol symbol, quint32 line, quint32 column)
-: Expr(type)
-  , base(base)
-  , id(id)
-  , symbol(symbol)
-  , ptr(0)
-  , index(-1)
-  , storage(MemberStorage)
-  , builtin(NoBuiltinSymbol)
-  , line(line)
-  , column(column)
-{
-    if (id.length() == 8 && id == QLatin1String("Math.sin")) {
+void Name::init(Name *base, Type type, const QString *id, Symbol symbol, quint32 line, quint32 column)
+{
+    this->type = type;
+    this->base = base;
+    this->id = id;
+    this->symbol = symbol;
+    this->ptr = 0;
+    this->index = -1;
+    this->storage = MemberStorage;
+    this->builtin = NoBuiltinSymbol;
+    this->line = line;
+    this->column = column;
+
+    if (id->length() == 8 && *id == QLatin1String("Math.sin")) {
         builtin = MathSinBultinFunction;
-    } else if (id.length() == 8 && id == QLatin1String("Math.cos")) {
+    } else if (id->length() == 8 && *id == QLatin1String("Math.cos")) {
         builtin = MathCosBultinFunction;
-    } else if (id.length() == 10 && id == QLatin1String("Math.round")) {
+    } else if (id->length() == 10 && *id == QLatin1String("Math.round")) {
         builtin = MathRoundBultinFunction;
-    } else if (id.length() == 10 && id == QLatin1String("Math.floor)")) {
+    } else if (id->length() == 10 && *id == QLatin1String("Math.floor)")) {
         builtin = MathFloorBultinFunction;
-    } else if (id.length() == 7 && id == QLatin1String("Math.PI")) {
+    } else if (id->length() == 7 && *id == QLatin1String("Math.PI")) {
         builtin = MathPIBuiltinConstant;
-        type = RealType;
+        this->type = RealType;
     }
 }
 
@@ -219,7 +220,7 @@ void Name::dump(QTextStream &out)
         out << '.';
     }
 
-    out << id;
+    out << *id;
 }
 
 void Temp::dump(QTextStream &out)
@@ -419,7 +420,9 @@ void Function::dump(QTextStream &out)
 
 Temp *BasicBlock::TEMP(Type type, int index) 
 { 
-    return function->e(new (function->module->pool) Temp(type, index));
+    Temp *e = function->module->pool->New<Temp>();
+    e->init(type, index);
+    return e;
 }
 
 Temp *BasicBlock::TEMP(Type type) 
@@ -434,12 +437,16 @@ Expr *BasicBlock::CONST(double value)
 
 Expr *BasicBlock::CONST(Type type, double value) 
 { 
-    return function->e(new (function->module->pool) Const(type, value));
+    Const *e = function->module->pool->New<Const>();
+    e->init(type, value);
+    return e;
 }
 
 Expr *BasicBlock::STRING(const QStringRef &value)
-{ 
-    return function->e(new (function->module->pool) String(value));
+{
+    String *e = function->module->pool->New<String>();
+    e->init(value);
+    return e;
 }
 
 Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
@@ -449,9 +456,11 @@ Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
 
 Name *BasicBlock::NAME(Name *base, const QString &id, quint32 line, quint32 column)
 { 
-    return function->e(new (function->module->pool) Name(base, InvalidType,
-                                                          function->module->newIdentifier(id),
-                                                          Name::Unbound, line, column));
+    Name *e = function->module->pool->New<Name>();
+    e->init(base, InvalidType,
+            function->module->newString(id),
+            Name::Unbound, line, column);
+    return e;
 }
 
 Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage,
@@ -465,52 +474,56 @@ Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta,
 Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage,
                          quint32 line, quint32 column)
 {
-    Name *name = new (function->module->pool) Name(base, type,
-                                                    function->module->newIdentifier(id),
-                                                    Name::Property, line, column);
+    Name *name = function->module->pool->New<Name>();
+    name->init(base, type, function->module->newString(id),
+               Name::Property, line, column);
     name->meta = meta;
     name->index = index;
     name->storage = storage;
-    return function->e(name);
+    return name;
 }
 
 Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index,
                          quint32 line, quint32 column)
 {
-    Name *name = new (function->module->pool) Name(base, type,
-                                                    function->module->newIdentifier(id),
-                                                    Name::Property, line, column);
+    Name *name = function->module->pool->New<Name>();
+    name->init(base, type, function->module->newString(id),
+               Name::Property, line, column);
     name->meta = meta;
     name->index = index;
-    return function->e(name);
+    return name;
 }
 
 Name *BasicBlock::ID_OBJECT(const QString &id, const QDeclarativeParser::Object *object, quint32 line, quint32 column)
 {
-    Name *name = new (function->module->pool) Name(/*base = */ 0, IR::ObjectType,
-                                                    function->module->newIdentifier(id),
-                                                    Name::IdObject, line, column);
+    Name *name = function->module->pool->New<Name>();
+    name->init(/*base = */ 0, IR::ObjectType,
+               function->module->newString(id),
+               Name::IdObject, line, column);
     name->idObject = object;
     name->index = object->idIndex;
     name->storage = Name::IdStorage;
-    return function->e(name);
+    return name;
 }
 
 Name *BasicBlock::ATTACH_TYPE(const QString &id, const QDeclarativeType *attachType, Name::Storage storage,
                               quint32 line, quint32 column)
 { 
-    Name *name = new (function->module->pool) Name(/*base = */ 0, IR::AttachType,
-                                                    function->module->newIdentifier(id),
-                                                    Name::AttachType, line, column);
+    Name *name = function->module->pool->New<Name>();
+    name->init(/*base = */ 0, IR::AttachType,
+               function->module->newString(id),
+               Name::AttachType, line, column);
     name->declarativeType = attachType;
     name->storage = storage;
-    return function->e(name);
+    return name;
 }
 
 
 Expr *BasicBlock::UNOP(AluOp op, Expr *expr) 
 { 
-    return function->e(new (function->module->pool) Unop(op, expr));
+    Unop *e = function->module->pool->New<Unop>();
+    e->init(op, expr);
+    return e;
 }
 
 Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
@@ -553,45 +566,65 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
         }
     }
 
-    return function->e(new (function->module->pool) Binop(op, left, right));
+    Binop *e = function->module->pool->New<Binop>();
+    e->init(op, left, right);
+    return e;
 }
 
 Expr *BasicBlock::CALL(Expr *base, ExprList *args)
 { 
-    return function->e(new (function->module->pool) Call(base, args));
+    Call *e = function->module->pool->New<Call>();
+    e->init(base, args);
+    return e;
 }
 
 Stmt *BasicBlock::EXP(Expr *expr) 
 { 
-    return i(new (function->module->pool) Exp(expr));
+    Exp *s = function->module->pool->New<Exp>();
+    s->init(expr);
+    statements.append(s);
+    return s;
 }
 
 Stmt *BasicBlock::MOVE(Expr *target, Expr *source, bool isMoveForReturn) 
 { 
-    return i(new (function->module->pool) Move(target, source, isMoveForReturn));
+    Move *s = function->module->pool->New<Move>();
+    s->init(target, source, isMoveForReturn);
+    statements.append(s);
+    return s;
 }
 
 Stmt *BasicBlock::JUMP(BasicBlock *target) 
 {
     if (isTerminated())
         return 0;
-    else
-        return i(new (function->module->pool) Jump(target));
+
+    Jump *s = function->module->pool->New<Jump>();
+    s->init(target);
+    statements.append(s);
+    return s;
 }
 
 Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) 
 {
     if (isTerminated())
         return 0;
-    return i(new (function->module->pool) CJump(cond, iftrue, iffalse));
+
+    CJump *s = function->module->pool->New<CJump>();
+    s->init(cond, iftrue, iffalse);
+    statements.append(s);
+    return s;
 }
 
 Stmt *BasicBlock::RET(Expr *expr, Type type, quint32 line, quint32 column)
 {
     if (isTerminated())
         return 0;
-    else
-        return i(new (function->module->pool) Ret(expr, type, line, column));
+
+    Ret *s = function->module->pool->New<Ret>();
+    s->init(expr, type, line, column);
+    statements.append(s);
+    return s;
 }
 
 void BasicBlock::dump(QTextStream &out)
@@ -604,7 +637,7 @@ void BasicBlock::dump(QTextStream &out)
     }
 }
 
-Module::Module(MemoryPool *pool)
+Module::Module(QDeclarativePool *pool)
     : pool(pool)
 {
 }
@@ -612,14 +645,11 @@ Module::Module(MemoryPool *pool)
 Module::~Module()
 {
     qDeleteAll(functions);
-    qDeleteAll(strings);
 }
 
-QString &Module::newIdentifier(const QString &text)
+QString *Module::newString(const QString &text)
 {
-    QString *s = new QString(text);
-    strings.append(s);
-    return *s;
+    return pool->NewString(text);
 }
 
 Function *Module::newFunction(const QString &name)
index a27b8d8..0c93fbb 100644 (file)
@@ -60,8 +60,8 @@
 #include <private/qdeclarativeengine_p.h>
 #include <private/qdeclarativev4compiler_p.h>
 
-#include <qdeclarativejsmemorypool_p.h>
-#include <QtCore/qvarlengtharray.h>.h>
+#include <qdeclarativepool_p.h>
+#include <QtCore/qvarlengtharray.h>
 
 // #define DEBUG_IR_STRUCTURE
 
@@ -176,10 +176,10 @@ struct StmtVisitor {
     virtual void visitRet(Ret *) {}
 };
 
-struct Expr: Managed {
+struct Expr: QDeclarativePool::POD {
     Type type;
 
-    Expr(Type type): type(type) {}
+    Expr(): type(InvalidType) {}
     virtual ~Expr() {}
     virtual void accept(ExprVisitor *) = 0;
     virtual Const *asConst() { return 0; }
@@ -192,17 +192,25 @@ struct Expr: Managed {
     virtual void dump(QTextStream &out) = 0;
 };
 
-struct ExprList: Managed {
+struct ExprList: QDeclarativePool::POD {
     Expr *expr;
     ExprList *next;
 
-    ExprList(Expr *expr, ExprList *next = 0)
-        : expr(expr), next(next) {}
+    void init(Expr *expr, ExprList *next = 0)
+    {
+        this->expr = expr;
+        this->next = next;
+    }
 };
 
 struct Const: Expr {
     double value;
-    Const(Type type, double value): Expr(type), value(value) {}
+
+    void init(Type type, double value)
+    {
+        this->type = type;
+        this->value = value;
+    }
 
     virtual void accept(ExprVisitor *v) { v->visitConst(this); }
     virtual Const *asConst() { return this; }
@@ -212,7 +220,12 @@ struct Const: Expr {
 
 struct String: Expr {
     QStringRef value;
-    String(const QStringRef &value): Expr(StringType), value(value) {}
+
+    void init(const QStringRef &value)
+    {
+        this->type = StringType;
+        this->value = value;
+    }
 
     virtual void accept(ExprVisitor *v) { v->visitString(this); }
     virtual String *asString() { return this; }
@@ -249,7 +262,7 @@ struct Name: Expr {
     };
 
     Name *base;
-    QString &id;
+    const QString *id;
     Symbol symbol;
     union {
         void *ptr;
@@ -263,7 +276,7 @@ struct Name: Expr {
     quint32 line;
     quint32 column;
 
-    Name(Name *base, Type type, QString &id, Symbol symbol, quint32 line, quint32 column);
+    void init(Name *base, Type type, const QString *id, Symbol symbol, quint32 line, quint32 column);
 
     inline bool is(Symbol s) const { return s == symbol; }
     inline bool isNot(Symbol s) const { return s != symbol; }
@@ -276,7 +289,12 @@ struct Name: Expr {
 
 struct Temp: Expr {
     int index;
-    Temp(Type type, int index): Expr(type), index(index) {}
+
+    void init(Type type, int index)
+    {
+        this->type = type;
+        this->index = index;
+    }
 
     virtual void accept(ExprVisitor *v) { v->visitTemp(this); }
     virtual Temp *asTemp() { return this; }
@@ -288,8 +306,12 @@ struct Unop: Expr {
     AluOp op;
     Expr *expr;
 
-    Unop(AluOp op, Expr *expr)
-        : Expr(typeForOp(op, expr)), op(op), expr(expr) {}
+    void init(AluOp op, Expr *expr)
+    {
+        this->typeForOp(op, expr);
+        this->op = op;
+        this->expr = expr;
+    }
 
     virtual void accept(ExprVisitor *v) { v->visitUnop(this); }
     virtual Unop *asUnop() { return this; }
@@ -304,8 +326,14 @@ struct Binop: Expr {
     AluOp op;
     Expr *left;
     Expr *right;
-    Binop(AluOp op, Expr *left, Expr *right)
-        : Expr(typeForOp(op, left, right)), op(op), left(left), right(right) {}
+
+    void init(AluOp op, Expr *left, Expr *right)
+    {
+        this->type = typeForOp(op, left, right);
+        this->op = op;
+        this->left = left;
+        this->right = right;
+    }
 
     virtual void accept(ExprVisitor *v) { v->visitBinop(this); }
     virtual Binop *asBinop() { return this; }
@@ -320,8 +348,12 @@ struct Call: Expr {
     Expr *base;
     ExprList *args;
 
-    Call(Expr *base, ExprList *args)
-        : Expr(typeForFunction(base)), base(base), args(args) {}
+    void init(Expr *base, ExprList *args)
+    {
+        this->type = typeForFunction(base);
+        this->base = base;
+        this->args = args;
+    }
 
     Expr *onlyArgument() const {
         if (args && ! args->next)
@@ -338,7 +370,7 @@ private:
     static Type typeForFunction(Expr *base);
 };
 
-struct Stmt: Managed {
+struct Stmt: QDeclarativePool::POD {
     enum Mode {
         HIR,
         MIR
@@ -358,7 +390,11 @@ struct Stmt: Managed {
 
 struct Exp: Stmt {
     Expr *expr;
-    Exp(Expr *expr): expr(expr) {}
+
+    void init(Expr *expr)
+    {
+        this->expr = expr;
+    }
 
     virtual void accept(StmtVisitor *v) { v->visitExp(this); }
     virtual Exp *asExp() { return this; }
@@ -370,7 +406,13 @@ struct Move: Stmt {
     Expr *target;
     Expr *source;
     bool isMoveForReturn;
-    Move(Expr *target, Expr *source, bool isMoveForReturn): target(target), source(source), isMoveForReturn(isMoveForReturn) {}
+
+    void init(Expr *target, Expr *source, bool isMoveForReturn)
+    {
+        this->target = target;
+        this->source = source;
+        this->isMoveForReturn = isMoveForReturn;
+    }
 
     virtual void accept(StmtVisitor *v) { v->visitMove(this); }
     virtual Move *asMove() { return this; }
@@ -380,7 +422,11 @@ struct Move: Stmt {
 
 struct Jump: Stmt {
     BasicBlock *target;
-    Jump(BasicBlock *target): target(target) {}
+
+    void init(BasicBlock *target)
+    {
+        this->target = target;
+    }
 
     virtual Stmt *asTerminator() { return this; }
 
@@ -394,8 +440,13 @@ struct CJump: Stmt {
     Expr *cond;
     BasicBlock *iftrue;
     BasicBlock *iffalse;
-    CJump(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
-        : cond(cond), iftrue(iftrue), iffalse(iffalse) {}
+
+    void init(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
+    {
+        this->cond = cond;
+        this->iftrue = iftrue;
+        this->iffalse = iffalse;
+    }
 
     virtual Stmt *asTerminator() { return this; }
 
@@ -410,7 +461,14 @@ struct Ret: Stmt {
     Type type;
     quint32 line;
     quint32 column;
-    Ret(Expr *expr, Type type, quint32 line, quint32 column): expr(expr), type(type), line(line), column(column) {}
+
+    void init(Expr *expr, Type type, quint32 line, quint32 column)
+    {
+        this->expr = expr;
+        this->type = type;
+        this->line = line;
+        this->column = column;
+    }
 
     virtual Stmt *asTerminator() { return this; }
 
@@ -426,8 +484,7 @@ struct Function {
     int tempCount;
     QVarLengthArray<BasicBlock *, 8> basicBlocks;
 
-    template <typename BB> inline BB i(BB i) { basicBlocks.append(i); return i; }
-    template <typename E> inline E e(E e) { return e; }
+    inline BasicBlock *i(BasicBlock *block) { basicBlocks.append(block); return block; }
 
     Function(Module *module, const QString &name): module(module), name(name), tempCount(0) {}
     ~Function();
@@ -494,14 +551,13 @@ struct BasicBlock {
 };
 
 struct Module {
-    MemoryPool *pool;
+    QDeclarativePool *pool;
     QVarLengthArray<Function *, 4> functions;
-    QVarLengthArray<QString *, 8> strings;
 
-    Module(MemoryPool *pool);
+    Module(QDeclarativePool *pool);
     ~Module();
 
-    QString &newIdentifier(const QString &text);
+    QString *newString(const QString &text);
     Function *newFunction(const QString &name = QString());
 
     virtual void dump(QTextStream &out);
index fa67f57..915bf5f 100644 (file)
@@ -606,7 +606,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
 
                     if (!found && qmlVerboseCompiler())
                         qWarning() << "*** unresolved enum:" 
-                                   << (baseName->id + QLatin1String(".") + ast->name.toString());
+                                   << (*baseName->id + QLatin1String(".") + ast->name.toString());
                 } else if(const QMetaObject *attachedMeta = baseName->declarativeType->attachedPropertiesType()) {
                     QDeclarativePropertyCache *cache = m_engine->cache(attachedMeta);
                     QDeclarativePropertyCache::Data *data = cache->property(name);
@@ -617,7 +617,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
                     if(!data->isFinal()) {
                         if (qmlVerboseCompiler())
                             qWarning() << "*** non-final attached property:"
-                                       << (baseName->id + QLatin1String(".") + ast->name.toString());
+                                       << (*baseName->id + QLatin1String(".") + ast->name.toString());
                         return false; // We don't know enough about this property
                     }
 
@@ -663,7 +663,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
                     if(!data->isFinal()) {
                         if (qmlVerboseCompiler())
                             qWarning() << "*** non-final property access:"
-                                << (baseName->id + QLatin1String(".") + ast->name.toString());
+                                << (*baseName->id + QLatin1String(".") + ast->name.toString());
                         return false; // We don't know enough about this property
                     }
 
@@ -707,7 +707,8 @@ bool QDeclarativeV4IRBuilder::visit(AST::CallExpression *ast)
         IR::ExprList *args = 0, **argsInserter = &args;
         for (AST::ArgumentList *it = ast->arguments; it; it = it->next) {
             IR::Expr *arg = expression(it->expression);
-            *argsInserter = new (_module->pool) IR::ExprList(arg);
+            *argsInserter = _module->pool->New<IR::ExprList>();
+            (*argsInserter)->init(arg);
             argsInserter = &(*argsInserter)->next;
         }