Replace usage of stdout for debug output by qDebug
authorErik Verbruggen <erik.verbruggen@digia.com>
Tue, 16 Dec 2014 12:44:14 +0000 (13:44 +0100)
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>
Fri, 19 Dec 2014 11:37:15 +0000 (12:37 +0100)
This way even paranoid Androids can be show interesting stuff.

Task-number: QTBUG-43109
Change-Id: Ib0ef9e8f6c6fc66e9ea9bfcaf2cd9e33d7469070
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/compiler/qv4isel_moth.cpp
src/qml/compiler/qv4isel_p.cpp
src/qml/compiler/qv4ssa.cpp
src/qml/compiler/qv4ssa_p.h
src/qml/debugger/qv4debugservice.cpp
src/qml/jit/qv4isel_masm.cpp
src/qml/jit/qv4regalloc.cpp
src/qml/jsruntime/qv4runtime.cpp
src/qml/jsruntime/qv4vme_moth.cpp
src/qml/qml/qqmlengine.cpp
src/qml/qml/qqmlengine_p.h

index 3997737..8f411bf 100644 (file)
@@ -188,15 +188,9 @@ public:
 
     void forFunction(IR::Function *function)
     {
-        IR::Optimizer::showMeTheCode(function);
+        IR::Optimizer::showMeTheCode(function, "Before stack slot allocation");
         _function = function;
         toStackSlots(function);
-
-//        QTextStream os(stdout, QIODevice::WriteOnly);
-//        os << "Frame layout:" << endl;
-//        foreach (int t, _stackSlotForTemp.keys()) {
-//            os << "\t" << t << " -> " << _stackSlotForTemp[t] << endl;
-//        }
     }
 
 protected:
@@ -364,7 +358,7 @@ void InstructionSelection::run(int functionIndex)
             opt.convertOutOfSSA();
             ConvertTemps().toStackSlots(_function);
         }
-        opt.showMeTheCode(_function);
+        opt.showMeTheCode(_function, "After stack slot allocation");
     } else {
         ConvertTemps().toStackSlots(_function);
     }
index e419084..167ea83 100644 (file)
@@ -31,6 +31,8 @@
 **
 ****************************************************************************/
 
+#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
 #include "qv4jsir_p.h"
 #include "qv4isel_p.h"
 #include "qv4isel_util_p.h"
 
 #include <QString>
 
-namespace {
-Q_GLOBAL_STATIC_WITH_ARGS(QTextStream, qout, (stderr, QIODevice::WriteOnly));
-#define qout *qout()
-} // anonymous namespace
-
 using namespace QV4;
 using namespace QV4::IR;
 
@@ -218,8 +215,12 @@ void IRDecoder::visitMove(IR::Move *s)
 
     // For anything else...:
     Q_UNIMPLEMENTED();
+    QBuffer buf;
+    buf.open(QIODevice::WriteOnly);
+    QTextStream qout(&buf);
     IRPrinter(&qout).print(s);
     qout << endl;
+    qDebug("%s", buf.data().constData());
     Q_ASSERT(!"TODO");
 }
 
@@ -398,7 +399,10 @@ void IRDecoder::callBuiltin(IR::Call *call, Expr *result)
     }
 
     Q_UNIMPLEMENTED();
+    QBuffer buf;
+    buf.open(QIODevice::WriteOnly);
+    QTextStream qout(&buf);
     IRPrinter(&qout).print(call); qout << endl;
-    Q_ASSERT(!"TODO!");
+    qDebug("%s", buf.data().constData());
     Q_UNREACHABLE();
 }
index d2222a0..77cfab8 100644 (file)
@@ -40,6 +40,7 @@
 #include "qv4isel_util_p.h"
 #include "qv4util_p.h"
 
+#include <QtCore/QBuffer>
 #include <QtCore/QCoreApplication>
 #include <QtCore/QStringList>
 #include <QtCore/QSet>
@@ -51,9 +52,6 @@
 #include <cassert>
 #include <algorithm>
 
-#undef SHOW_SSA
-#undef DEBUG_MOVEMAPPING
-
 QT_USE_NAMESPACE
 
 using namespace QV4;
@@ -61,21 +59,25 @@ using namespace IR;
 
 namespace {
 
+enum { DebugMoveMapping = 0 };
+
 #ifdef QT_NO_DEBUG
 enum { DoVerification = 0 };
 #else
 enum { DoVerification = 1 };
 #endif
 
-Q_GLOBAL_STATIC_WITH_ARGS(QTextStream, qout, (stderr, QIODevice::WriteOnly));
-#define qout *qout()
-
-void showMeTheCode(IR::Function *function)
+static void showMeTheCode(IR::Function *function, const char *marker)
 {
     static bool showCode = !qgetenv("QV4_SHOW_IR").isNull();
     if (showCode) {
-        IRPrinter(&qout).print(function);
-        qout << endl;
+        qDebug() << marker;
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream stream(&buf);
+        IRPrinter(&stream).print(function);
+        stream << endl;
+        qDebug("%s", buf.data().constData());
     }
 }
 
@@ -402,11 +404,6 @@ class DominatorTree
             todo = worklist.back();
             worklist.pop_back();
         }
-
-#if defined(SHOW_SSA)
-        for (int i = 0; i < nodes.size(); ++i)
-            qDebug("\tL%d: dfnum = %d, parent = %d", i, dfnum[i], parent[i]);
-#endif // SHOW_SSA
     }
 
     BasicBlockIndex ancestorWithLowestSemi(BasicBlockIndex v, std::vector<BasicBlockIndex> &worklist) {
@@ -592,6 +589,9 @@ public:
         }
 
         if (DebugDominatorFrontiers) {
+            QBuffer buf;
+            buf.open(QIODevice::WriteOnly);
+            QTextStream qout(&buf);
             qout << "Dominator Frontiers:" << endl;
             foreach (BasicBlock *n, function->basicBlocks()) {
                 if (n->isRemoved())
@@ -606,6 +606,7 @@ public:
                 }
                 qout << "}" << endl;
             }
+            qDebug("%s", buf.data().constData());
         }
 
         if (DebugDominatorFrontiers && DebugCodeCanUseLotsOfCpu) {
@@ -624,7 +625,7 @@ public:
                         }
                     }
                     if (!hasDominatedSucc) {
-                        qout << fBlock << " in DF[" << n->index() << "] has no dominated predecessors" << endl;
+                        qDebug("%d in DF[%d] has no dominated predecessors", fBlock->index(), n->index());
                     }
                     Q_ASSERT(hasDominatedSucc);
                 }
@@ -646,6 +647,9 @@ public:
     void dumpImmediateDominators() const
     {
         if (DebugImmediateDominators) {
+            QBuffer buf;
+            buf.open(QIODevice::WriteOnly);
+            QTextStream qout(&buf);
             qout << "Immediate dominators:" << endl;
             foreach (BasicBlock *to, function->basicBlocks()) {
                 if (to->isRemoved())
@@ -659,6 +663,7 @@ public:
                     qout << "(none)";
                 qout << " -> " << to->index() << endl;
             }
+            qDebug("%s", buf.data().constData());
         }
     }
 
@@ -953,10 +958,6 @@ public:
         for (int i = 0, ei = A_orig.size(); i != ei; ++i)
             A_orig[i].reserve(8);
 
-#if defined(SHOW_SSA)
-        qout << "Variables collected:" << endl;
-#endif // SHOW_SSA
-
         foreach (BasicBlock *bb, function->basicBlocks()) {
             if (bb->isRemoved())
                 continue;
@@ -966,17 +967,6 @@ public:
             foreach (Stmt *s, bb->statements())
                 s->accept(this);
         }
-
-#if defined(SHOW_SSA)
-        qout << "Non-locals:" << endl;
-        foreach (const Temp &nonLocal, nonLocals) {
-            qout << "\t";
-            nonLocal.dump(qout);
-            qout << endl;
-        }
-
-        qout << "end collected variables." << endl;
-#endif // SHOW_SSA
     }
 
     const std::vector<Temp> &allTemps() const
@@ -1038,12 +1028,6 @@ protected:
             addTemp(t);
 
             if (isCollectable(t)) {
-#if defined(SHOW_SSA)
-                qout << '\t';
-                t->dump(qout);
-                qout << " -> L" << currentBB->index << endl;
-#endif // SHOW_SSA
-
                 _defsites[t->index].insert(currentBB);
                 addDefInCurrentBlock(t);
 
@@ -1274,6 +1258,9 @@ public:
 
     void dump() const
     {
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream qout(&buf);
         qout << "Defines and uses:" << endl;
         foreach (const DefUse &du, _defUses) {
             if (!du.isValid())
@@ -1294,16 +1281,11 @@ public:
                 qout << ' ' << t.index;
             qout << endl;
         }
+        qDebug("%s", buf.data().constData());
     }
 };
 
 void insertPhiNode(const Temp &a, BasicBlock *y, IR::Function *f) {
-#if defined(SHOW_SSA)
-    qout << "-> inserted phi node for variable ";
-    a.dump(qout);
-    qout << " in block " << y->index << endl;
-#endif
-
     Phi *phiNode = f->NewStmt<Phi>();
     phiNode->d = new Stmt::Data;
     phiNode->targetTemp = f->New<Temp>();
@@ -1643,15 +1625,6 @@ protected:
 // see [Appel]. For the changes needed for semi-pruned SSA form, and for its advantages, see [Briggs].
 void convertToSSA(IR::Function *function, const DominatorTree &df, DefUses &defUses)
 {
-#if defined(SHOW_SSA)
-    qout << "Converting function ";
-    if (function->name)
-        qout << *function->name;
-    else
-        qout << "<no name>";
-    qout << " to SSA..." << endl;
-#endif // SHOW_SSA
-
     // Collect all applicable variables:
     VariableCollector variables(function);
 
@@ -2248,23 +2221,32 @@ public:
                 continue;
 
             if (DebugTypeInference) {
+                QBuffer buf;
+                buf.open(QIODevice::WriteOnly);
+                QTextStream qout(&buf);
                 qout<<"Typing stmt ";
                 IRPrinter(&qout).print(s);
-                qout<<endl;
+                qDebug("%s", buf.data().constData());
             }
 
             if (!run(s)) {
                 *_worklist += s;
                 if (DebugTypeInference) {
+                    QBuffer buf;
+                    buf.open(QIODevice::WriteOnly);
+                    QTextStream qout(&buf);
                     qout<<"Pushing back stmt: ";
                     IRPrinter(&qout).print(s);
-                    qout<<endl;
+                    qDebug("%s", buf.data().constData());
                 }
             } else {
                 if (DebugTypeInference) {
+                    QBuffer buf;
+                    buf.open(QIODevice::WriteOnly);
+                    QTextStream qout(&buf);
                     qout<<"Finished: ";
                     IRPrinter(&qout).print(s);
-                    qout<<endl;
+                    qDebug("%s", buf.data().constData());
                 }
             }
         }
@@ -2306,9 +2288,9 @@ private:
     void setType(Expr *e, DiscoveredType ty) {
         if (Temp *t = e->asTemp()) {
             if (DebugTypeInference)
-                qout << "Setting type for temp " << t->index
-                     << " to " << typeName(Type(ty.type)) << " (" << ty.type << ")"
-                     << endl;
+                qDebug() << "Setting type for temp" << t->index
+                         << " to " << typeName(Type(ty.type)) << "(" << ty.type << ")"
+                         << endl;
 
             DiscoveredType &it = _tempTypes[t->index];
             if (it != ty) {
@@ -2316,9 +2298,12 @@ private:
 
                 if (DebugTypeInference) {
                     foreach (Stmt *s, _defUses.uses(*t)) {
+                        QBuffer buf;
+                        buf.open(QIODevice::WriteOnly);
+                        QTextStream qout(&buf);
                         qout << "Pushing back dependent stmt: ";
                         IRPrinter(&qout).print(s);
-                        qout<<endl;
+                        qDebug("%s", buf.data().constData());
                     }
                 }
 
@@ -2704,15 +2689,6 @@ class TypePropagation: public StmtVisitor, public ExprVisitor {
         if (requestedType != UnknownType) {
             if (e->type != requestedType) {
                 if (requestedType & NumberType || requestedType == BoolType) {
-#ifdef SHOW_SSA
-                    QTextStream os(stdout, QIODevice::WriteOnly);
-                    os << "adding conversion from " << typeName(e->type)
-                       << " to " << typeName(requestedType) << " for expression ";
-                    e->dump(os);
-                    os << " in statement ";
-                    _currStmt->dump(os);
-                    os << endl;
-#endif
                     if (insertConversion)
                         addConversion(e, requestedType);
                     return true;
@@ -3409,15 +3385,9 @@ public:
 
     QHash<BasicBlock *, BasicBlock *> go()
     {
-        showMeTheCode(function);
+        showMeTheCode(function, "Before block scheduling");
         schedule(function->basicBlock(0));
 
-#if defined(SHOW_SSA)
-        qDebug() << "Block sequence:";
-        foreach (BasicBlock *bb, sequence)
-            qDebug("\tL%d", bb->index());
-#endif // SHOW_SSA
-
         Q_ASSERT(function->liveBasicBlocksCount() == sequence.size());
         function->setScheduledBlocks(sequence);
         function->renumberBasicBlocks();
@@ -3431,8 +3401,8 @@ void checkCriticalEdges(QVector<BasicBlock *> basicBlocks) {
         if (bb && bb->out.size() > 1) {
             foreach (BasicBlock *bb2, bb->out) {
                 if (bb2 && bb2->in.size() > 1) {
-                    qout << "found critical edge between block "
-                         << bb->index() << " and block " << bb2->index();
+                    qDebug() << "found critical edge between block"
+                             << bb->index() << "and block" << bb2->index();
                     Q_ASSERT(false);
                 }
             }
@@ -3443,7 +3413,7 @@ void checkCriticalEdges(QVector<BasicBlock *> basicBlocks) {
 
 void cleanupBasicBlocks(IR::Function *function)
 {
-    showMeTheCode(function);
+    showMeTheCode(function, "Before basic block cleanup");
 
     // Algorithm: this is the iterative version of a depth-first search for all blocks that are
     // reachable through outgoing edges, starting with the start block and all exception handler
@@ -3496,7 +3466,7 @@ void cleanupBasicBlocks(IR::Function *function)
         function->removeBasicBlock(bb);
     }
 
-    showMeTheCode(function);
+    showMeTheCode(function, "After basic block cleanup");
 }
 
 inline Const *isConstPhi(Phi *phi)
@@ -3829,8 +3799,14 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
     if (!showCode)
         return;
 
+    QBuffer buf;
+    buf.open(QIODevice::WriteOnly);
+    QTextStream qout(&buf);
+
     struct Util {
-        static void genLoop(LoopDetection::LoopInfo *loop)
+        QTextStream &qout;
+        Util(QTextStream &qout): qout(qout) {}
+        void genLoop(LoopDetection::LoopInfo *loop)
         {
             qout << "  subgraph \"cluster" << quint64(loop) << "\" {\n";
             qout << "    L" << loop->loopHeader->index() << ";\n";
@@ -3849,7 +3825,7 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
 
     foreach (LoopDetection::LoopInfo *l, loops) {
         if (l->parentLoop == 0)
-            Util::genLoop(l);
+            Util(qout).genLoop(l);
     }
 
     foreach (BasicBlock *bb, f->basicBlocks()) {
@@ -3867,7 +3843,8 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
             qout << "  L" << idx << " -> L" << out->index() << "\n";
     }
 
-    qout << "}\n" << flush;
+    qout << "}\n";
+    qDebug("%s", buf.data().constData());
 }
 
 } // anonymous namespace
@@ -4301,6 +4278,10 @@ public:
 
     void dump() const
     {
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream qout(&buf);
+
         qout << "Life ranges:" << endl;
         qout << "Intervals:" << endl;
         foreach (const LifeTimeInterval *range, _sortedIntervals->intervals()) {
@@ -4321,6 +4302,7 @@ public:
             }
             qout << endl;
         }
+        qDebug("%s", buf.data().constData());
     }
 
 private:
@@ -5068,12 +5050,7 @@ Optimizer::Optimizer(IR::Function *function)
 
 void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool peelLoops)
 {
-#if defined(SHOW_SSA)
-    qout << "##### NOW IN FUNCTION " << (function->name ? qPrintable(*function->name) : "anonymous!")
-         << " with " << function->basicBlocks.size() << " basic blocks." << endl << flush;
-#endif
-
-//    showMeTheCode(function);
+    showMeTheCode(function, "Before running the optimizer");
 
     cleanupBasicBlocks(function);
 
@@ -5087,7 +5064,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
 //        qout << "SSA for " << (function->name ? qPrintable(*function->name) : "<anonymous>") << endl;
 
         ConvertArgLocals(function).toTemps();
-        showMeTheCode(function);
+        showMeTheCode(function, "After converting arguments to locals");
 
         // Calculate the dominator tree:
         DominatorTree df(function);
@@ -5099,7 +5076,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
 
             LoopDetection loopDetection(df);
             loopDetection.run(function);
-            showMeTheCode(function);
+            showMeTheCode(function, "After loop detection");
 //            cfg2dot(function, loopDetection.allLoops());
 
             if (peelLoops) {
@@ -5107,7 +5084,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
                 LoopPeeling(df).run(innerLoops);
 
 //                cfg2dot(function, loopDetection.allLoops());
-                showMeTheCode(function);
+                showMeTheCode(function, "After loop peeling");
                 if (!innerLoops.isEmpty())
                     verifyImmediateDominators(df, function);
             }
@@ -5130,14 +5107,14 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
 
 //        qout << "Cleaning up phi nodes..." << endl;
         cleanupPhis(defUses);
-        showMeTheCode(function);
+        showMeTheCode(function, "After cleaning up phi-nodes");
 
         StatementWorklist worklist(function);
 
         if (doTypeInference) {
 //            qout << "Running type inference..." << endl;
             TypeInference(qmlEngine, defUses).run(worklist);
-            showMeTheCode(function);
+            showMeTheCode(function, "After type inference");
 
 //            qout << "Doing reverse inference..." << endl;
             ReverseInference(defUses).run(function);
@@ -5154,7 +5131,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
 //            qout << "Running SSA optimization..." << endl;
             worklist.reset();
             optimizeSSA(worklist, defUses, df);
-            showMeTheCode(function);
+            showMeTheCode(function, "After optimization");
 
             verifyImmediateDominators(df, function);
             verifyCFG(function);
@@ -5180,7 +5157,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
 //        qout << "Doing block scheduling..." << endl;
 //        df.dumpImmediateDominators();
         startEndLoops = BlockScheduler(function, df).go();
-        showMeTheCode(function);
+        showMeTheCode(function, "After basic block scheduling");
 //        cfg2dot(function);
 
 #ifndef QT_NO_DEBUG
@@ -5217,16 +5194,19 @@ void Optimizer::convertOutOfSSA() {
             }
         }
 
-    #if defined(DEBUG_MOVEMAPPING)
-        QTextStream os(stdout, QIODevice::WriteOnly);
-        os << "Move mapping for function ";
-        if (function->name)
-            os << *function->name;
-        else
-            os << (void *) function;
-        os << " on basic-block L" << bb->index << ":" << endl;
-        moves.dump();
-    #endif // DEBUG_MOVEMAPPING
+        if (DebugMoveMapping) {
+            QBuffer buf;
+            buf.open(QIODevice::WriteOnly);
+            QTextStream os(&buf);
+            os << "Move mapping for function ";
+            if (function->name)
+                os << *function->name;
+            else
+                os << (void *) function;
+            os << " on basic-block L" << bb->index() << ":" << endl;
+            moves.dump();
+            qDebug("%s", buf.data().constData());
+        }
 
         moves.order();
 
@@ -5282,22 +5262,12 @@ QSet<Jump *> Optimizer::calculateOptionalJumps()
         reachableWithoutJump.insert(bb);
     }
 
-#if 0
-    QTextStream out(stdout, QIODevice::WriteOnly);
-    out << "Jumps to ignore:" << endl;
-    foreach (Jump *j, removed) {
-        out << "\t" << j->id << ": ";
-        j->dump(out, Stmt::MIR);
-        out << endl;
-    }
-#endif
-
     return optional;
 }
 
-void Optimizer::showMeTheCode(IR::Function *function)
+void Optimizer::showMeTheCode(IR::Function *function, const char *marker)
 {
-    ::showMeTheCode(function);
+    ::showMeTheCode(function, marker);
 }
 
 static inline bool overlappingStorage(const Temp &t1, const Temp &t2)
@@ -5339,14 +5309,17 @@ void MoveMapping::add(Expr *from, Temp *to) {
     if (Temp *t = from->asTemp()) {
         if (overlappingStorage(*t, *to)) {
             // assignments like fp1 = fp1 or var{&1} = double{&1} can safely be skipped.
-#if defined(DEBUG_MOVEMAPPING)
-            QTextStream os(stderr, QIODevice::WriteOnly);
-            os << "Skipping ";
-            to->dump(os);
-            os << " <- ";
-            from->dump(os);
-            os << endl;
-#endif // DEBUG_MOVEMAPPING
+            if (DebugMoveMapping) {
+                QBuffer buf;
+                buf.open(QIODevice::WriteOnly);
+                QTextStream os(&buf);
+                IRPrinter printer(&os);
+                os << "Skipping ";
+                printer.print(to);
+                os << " <- ";
+                printer.print(from);
+                qDebug("%s", buf.data().constData());
+            }
             return;
         }
     }
@@ -5397,20 +5370,24 @@ QList<IR::Move *> MoveMapping::insertMoves(BasicBlock *bb, IR::Function *functio
 
 void MoveMapping::dump() const
 {
-#if defined(DEBUG_MOVEMAPPING)
-    QTextStream os(stdout, QIODevice::WriteOnly);
-    os << "Move mapping has " << _moves.size() << " moves..." << endl;
-    foreach (const Move &m, _moves) {
-        os << "\t";
-        m.to->dump(os);
-        if (m.needsSwap)
-            os << " <-> ";
-        else
-            os << " <-- ";
-        m.from->dump(os);
-        os << endl;
+    if (DebugMoveMapping) {
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream os(&buf);
+        IRPrinter printer(&os);
+        os << "Move mapping has " << _moves.size() << " moves..." << endl;
+        foreach (const Move &m, _moves) {
+            os << "\t";
+            printer.print(m.to);
+            if (m.needsSwap)
+                os << " <-> ";
+            else
+                os << " <-- ";
+            printer.print(m.from);
+            os << endl;
+        }
+        qDebug("%s", buf.data().constData());
     }
-#endif // DEBUG_MOVEMAPPING
 }
 
 MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed,
@@ -5421,19 +5398,24 @@ MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QLis
         if (!output.contains(dependency)) {
             if (delayed.contains(dependency)) {
                 // We have a cycle! Break it by swapping instead of assigning.
-#if defined(DEBUG_MOVEMAPPING)
-                delayed+=m;
-                QTextStream out(stderr, QIODevice::WriteOnly);
-                out<<"we have a cycle! temps:" << endl;
-                foreach (const Move &m, delayed) {
-                    out<<"\t";
-                    m.to->dump(out);
-                    out<<" <- ";
-                    m.from->dump(out);
-                    out<<endl;
+                if (DebugMoveMapping) {
+                    delayed += m;
+                    QBuffer buf;
+                    buf.open(QIODevice::WriteOnly);
+                    QTextStream out(&buf);
+                    IRPrinter printer(&out);
+                    out<<"we have a cycle! temps:" << endl;
+                    foreach (const Move &m, delayed) {
+                        out<<"\t";
+                        printer.print(m.to);
+                        out<<" <- ";
+                        printer.print(m.from);
+                        out<<endl;
+                    }
+                    qDebug("%s", buf.data().constData());
+                    delayed.removeOne(m);
                 }
-                delayed.removeOne(m);
-#endif // DEBUG_MOVEMAPPING
+
                 return NeedsSwap;
             } else {
                 delayed.append(m);
index 21a5b03..93bf62a 100644 (file)
@@ -219,7 +219,7 @@ public:
 
     QSet<IR::Jump *> calculateOptionalJumps();
 
-    static void showMeTheCode(Function *function);
+    static void showMeTheCode(Function *function, const char *marker);
 
 private:
     Function *function;
index 30d9557..90f86cc 100644 (file)
@@ -62,8 +62,8 @@ const char *V4_LINENUMBER = "linenumber";
 #ifdef NO_PROTOCOL_TRACING
 #  define TRACE_PROTOCOL(x)
 #else
+#include <QtCore/QDebug>
 #  define TRACE_PROTOCOL(x) x
-static QTextStream debug(stderr, QIODevice::WriteOnly);
 #endif
 
 QT_BEGIN_NAMESPACE
@@ -378,7 +378,7 @@ public:
         QByteArray responseData = doc.toJson(QJsonDocument::Indented);
 #endif
 
-        TRACE_PROTOCOL(debug << "sending response for: " << responseData << endl);
+        TRACE_PROTOCOL(qDebug() << "sending response for:" << responseData << endl);
 
         q_func()->sendMessage(packMessage("v8message", responseData));
     }
@@ -523,7 +523,7 @@ public:
 
     void handle(const QJsonObject &request, QQmlDebugService *s, QV4DebugServicePrivate *p)
     {
-        TRACE_PROTOCOL(debug << "handling command " << command() << "..." << endl);
+        TRACE_PROTOCOL(qDebug() << "handling command" << command() << "...");
 
         req = request;
         seq = req.value(QStringLiteral("seq"));
@@ -1137,13 +1137,13 @@ void QV4DebugService::messageReceived(const QByteArray &message)
     QByteArray header;
     ms >> header;
 
-    TRACE_PROTOCOL(debug << "received message with header " << header << endl);
+    TRACE_PROTOCOL(qDebug() << "received message with header" << header);
 
     if (header == "V8DEBUG") {
         QByteArray type;
         QByteArray payload;
         ms >> type >> payload;
-        TRACE_PROTOCOL(debug << "... type: "<<type << endl);
+        TRACE_PROTOCOL(qDebug() << "... type:" << type);
 
         if (type == V4_CONNECT) {
             sendMessage(d->packMessage(type));
@@ -1164,7 +1164,7 @@ void QV4DebugService::messageReceived(const QByteArray &message)
         } else if (type == "v8request") {
             handleV8Request(payload);
         } else if (type == V4_DISCONNECT) {
-            TRACE_PROTOCOL(debug << "... payload:"<<payload << endl);
+            TRACE_PROTOCOL(qDebug() << "... payload:" << payload);
             handleV8Request(payload);
         } else {
             sendSomethingToSomebody(type, 0);
@@ -1249,7 +1249,7 @@ void QV4DebugService::handleV8Request(const QByteArray &payload)
 {
     Q_D(QV4DebugService);
 
-    TRACE_PROTOCOL(debug << "v8request, payload: " << payload << endl);
+    TRACE_PROTOCOL(qDebug() << "v8request, payload:" << payload);
 
     QJsonDocument request = QJsonDocument::fromJson(payload);
     QJsonObject o = request.object();
index f905e9c..e7771f5 100644 (file)
@@ -115,8 +115,8 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput, const Q
             continue;
         processedOutput = processedOutput.insert(idx, QByteArrayLiteral("                          ; call ") + it.value());
     }
-    fprintf(stderr, "%s\n", processedOutput.constData());
-    fflush(stderr);
+
+    qDebug("%s", processedOutput.constData());
 }
 
 JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
@@ -225,7 +225,7 @@ void InstructionSelection::run(int functionIndex)
             // No register allocator available for this platform, or env. var was set, so:
             opt.convertOutOfSSA();
         ConvertTemps().toStackSlots(_function);
-        IR::Optimizer::showMeTheCode(_function);
+        IR::Optimizer::showMeTheCode(_function, "After stack slot allocation");
         calculateRegistersToSave(Assembler::getRegisterInfo()); // FIXME: this saves all registers. We can probably do with a subset: those that are not used by the register allocator.
     }
     QSet<IR::Jump *> removableJumps = opt.calculateOptionalJumps();
index e695224..16792d8 100644 (file)
@@ -31,6 +31,8 @@
 **
 ****************************************************************************/
 
+#include <QtCore/QBuffer>
+#include <QtCore/QDebug>
 #include "qv4regalloc_p.h"
 #include <private/qv4value_inl_p.h>
 
@@ -223,7 +225,9 @@ public:
         if (!DebugRegAlloc)
             return;
 
-        QTextStream qout(stdout, QIODevice::WriteOnly);
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream qout(&buf);
         IRPrinterWithPositions printer(&qout, _lifeTimeIntervals);
 
         qout << "RegAllocInfo:" << endl << "Defs/uses:" << endl;
@@ -264,6 +268,7 @@ public:
             }
             qout << endl;
         }
+        qDebug("%s", buf.data().constData());
     }
 
 protected: // IRDecoder
@@ -823,8 +828,11 @@ public:
     void run() {
         renumber();
         if (DebugRegAlloc) {
-            QTextStream qout(stdout, QIODevice::WriteOnly);
+            QBuffer buf;
+            buf.open(QIODevice::WriteOnly);
+            QTextStream qout(&buf);
             IRPrinterWithPositions(&qout, _intervals).print(_function);
+            qDebug("%s", buf.data().constData());
         }
         resolve();
     }
@@ -876,7 +884,9 @@ private:
             _liveAtEnd[bb] = _intervalForTemp.values();
 
             if (DebugRegAlloc) {
-                QTextStream os(stdout, QIODevice::WriteOnly);
+                QBuffer buf;
+                buf.open(QIODevice::WriteOnly);
+                QTextStream os(&buf);
                 os << "Intervals live at the start of L" << bb->index() << ":" << endl;
                 if (_liveAtStart[bb].isEmpty())
                     os << "\t(none)" << endl;
@@ -893,6 +903,7 @@ private:
                     i->dump(os);
                     os << endl;
                 }
+                qDebug("%s", buf.data().constData());
             }
 
             bb->setStatements(newStatements);
@@ -967,11 +978,13 @@ private:
     {
         if (DebugRegAlloc) {
             qDebug() << "Resolving edge" << predecessor->index() << "->" << successor->index();
-            QTextStream qout(stdout, QIODevice::WriteOnly);
+            QBuffer buf;
+            buf.open(QIODevice::WriteOnly);
+            QTextStream qout(&buf);
             IRPrinterWithPositions printer(&qout, _intervals);
             printer.print(predecessor);
             printer.print(successor);
-            qout.flush();
+            qDebug("%s", buf.data().constData());
         }
 
         MoveMapping mapping;
@@ -1088,11 +1101,13 @@ private:
 
         if (DebugRegAlloc) {
             qDebug() << ".. done, result:";
-            QTextStream qout(stdout, QIODevice::WriteOnly);
+            QBuffer buf;
+            buf.open(QIODevice::WriteOnly);
+            QTextStream qout(&buf);
             IRPrinterWithPositions printer(&qout, _intervals);
             printer.print(predecessor);
             printer.print(successor);
-            qout.flush();
+            qDebug("%s", buf.data().constData());
         }
     }
 
@@ -1260,7 +1275,9 @@ void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
     _info->collect(function, _lifeTimeIntervals);
 
     if (DebugRegAlloc) {
-        QTextStream qout(stdout, QIODevice::WriteOnly);
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream qout(&buf);
         qout << "Ranges:" << endl;
         QVector<LifeTimeInterval *> intervals = _unhandled;
         std::reverse(intervals.begin(), intervals.end());
@@ -1268,13 +1285,13 @@ void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
             r->dump(qout);
             qout << endl;
         }
+        qDebug("%s", buf.data().constData());
         _info->dump();
-    }
 
-    if (DebugRegAlloc) {
         qDebug() << "*** Before register allocation:";
-        QTextStream qout(stdout, QIODevice::WriteOnly);
+        buf.setData(QByteArray());
         IRPrinterWithPositions(&qout, _lifeTimeIntervals).print(function);
+        qDebug("%s", buf.data().constData());
     }
     prepareRanges();
 
@@ -1293,8 +1310,11 @@ void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
 
     static bool showCode = !qgetenv("QV4_SHOW_IR").isNull();
     if (showCode) {
-        QTextStream qout(stdout, QIODevice::WriteOnly);
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream qout(&buf);
         IRPrinterWithRegisters(&qout, _lifeTimeIntervals, _registerInformation).print(function);
+        qDebug("%s", buf.data().constData());
     }
 }
 
@@ -1675,10 +1695,12 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current)
 
     // spill interval that currently block reg
     if (DebugRegAlloc) {
-        QTextStream out(stderr, QIODevice::WriteOnly);
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream out(&buf);
         out << "*** spilling intervals that block reg " <<reg<< " for interval ";
         current.dump(out);
-        out << endl;
+        qDebug("%s", buf.data().constData());
     }
     current.setReg(reg);
     _lastAssignedRegister[current.temp().index] = reg;
@@ -1701,8 +1723,7 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current)
         int ni = nextIntersection(current, *fixedRegRange);
         if (ni != -1) {
             if (DebugRegAlloc) {
-                QTextStream out(stderr, QIODevice::WriteOnly);
-                out << "***-- current range intersects with a fixed reg use at " << ni << ", so splitting it." << endl;
+                qDebug("***-- current range intersects with a fixed reg use at %d, so splitting it.", ni);
             }
             // current does overlap with a fixed interval, so split current before that intersection.
             split(current, ni, true);
@@ -1767,8 +1788,14 @@ void RegisterAllocator::split(LifeTimeInterval &current, int beforePosition,
     Q_ASSERT(!current.isFixedInterval());
 
     if (DebugRegAlloc) {
-        QTextStream out(stderr, QIODevice::WriteOnly);
-        out << "***** split request for range ";current.dump(out);out<<" before position "<<beforePosition<<" and skipOptionalRegisterUses = "<<skipOptionalRegisterUses<<endl;
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream out(&buf);
+        out << "***** split request for range ";
+        current.dump(out);
+        out << " before position " << beforePosition
+            << " and skipOptionalRegisterUses = " << skipOptionalRegisterUses << endl;
+        qDebug("%s", buf.data().constData());
     }
 
     assignSpillSlot(current.temp(), current.start(), current.end());
@@ -1796,10 +1823,17 @@ void RegisterAllocator::split(LifeTimeInterval &current, int beforePosition,
 
     LifeTimeInterval newInterval = current.split(lastUse, nextUse);
     if (DebugRegAlloc) {
-        QTextStream out(stderr, QIODevice::WriteOnly);
-        out << "***** last use = "<<lastUse<<", nextUse = " << nextUse<<endl;
-        out << "***** new interval: "; newInterval.dump(out); out << endl;
-        out << "***** preceding interval: "; current.dump(out); out << endl;
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream out(&buf);
+        out << "***** last use = " << lastUse << ", nextUse = " << nextUse << endl;
+        out << "***** new interval: ";
+        newInterval.dump(out);
+        out << endl;
+        out << "***** preceding interval: ";
+        current.dump(out);
+        out << endl;
+        qDebug("%s", buf.data().constData());
     }
     if (newInterval.isValid()) {
         if (current.reg() != LifeTimeInterval::InvalidRegister)
@@ -1848,7 +1882,9 @@ void RegisterAllocator::assignSpillSlot(const Temp &t, int startPos, int endPos)
 
 void RegisterAllocator::dump(IR::Function *function) const
 {
-    QTextStream qout(stdout, QIODevice::WriteOnly);
+    QBuffer buf;
+    buf.open(QIODevice::WriteOnly);
+    QTextStream qout(&buf);
     IRPrinterWithPositions printer(&qout, _lifeTimeIntervals);
 
     qout << "Ranges:" << endl;
@@ -1865,6 +1901,7 @@ void RegisterAllocator::dump(IR::Function *function) const
             qout << "\t%" << i << " -> " << _assignedSpillSlots[i] << endl;
 
     printer.print(function);
+    qDebug("%s", buf.data().constData());
 }
 
 // References:
index b5fbf89..a4340a3 100644 (file)
 
 #include "../../3rdparty/double-conversion/double-conversion.h"
 
+#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
+#  include <QtCore/QBuffer>
+#  include <QtCore/QDebug>
+#endif // QV4_COUNT_RUNTIME_FUNCTIONS
+
 QT_BEGIN_NAMESPACE
 
 namespace QV4 {
@@ -144,7 +149,9 @@ struct RuntimeCounters::Data {
     };
 
     void dump() const {
-        QTextStream outs(stderr, QIODevice::WriteOnly);
+        QBuffer buf;
+        buf.open(QIODevice::WriteOnly);
+        QTextStream outs(&buf);
         QList<Line> lines;
         foreach (const char *func, counters.keys()) {
             const Counters &fCount = counters[func];
@@ -159,7 +166,7 @@ struct RuntimeCounters::Data {
                 lines.append(line);
             }
         }
-        qSort(lines.begin(), lines.end(), Line::less);
+        std::sort(lines.begin(), lines.end(), Line::less);
         outs << lines.size() << " counters:" << endl;
         foreach (const Line &line, lines)
             outs << qSetFieldWidth(10) << line.count << qSetFieldWidth(0)
@@ -167,6 +174,7 @@ struct RuntimeCounters::Data {
                  << " | " << pretty(line.tag1)
                  << " | " << pretty(line.tag2)
                  << endl;
+        qDebug("%s", buf.data().constData());
     }
 };
 
index 1e1c17f..8372aaa 100644 (file)
 
 #include "qv4alloca_p.h"
 
+#undef DO_TRACE_INSTR // define to enable instruction tracing
+
 #ifdef DO_TRACE_INSTR
-#  define TRACE_INSTR(I) fprintf(stderr, "executing a %s\n", #I);
-#  define TRACE(n, str, ...) { char buf[4096]; snprintf(buf, 4096, str, __VA_ARGS__); fprintf(stderr, "    %s : %s\n", #n, buf); }
+#  define TRACE_INSTR(I) qDebug("executing a %s\n", #I);
+#  define TRACE(n, str, ...) { char buf[4096]; snprintf(buf, 4096, str, __VA_ARGS__); qDebug("    %s : %s", #n, buf); }
 #else
 #  define TRACE_INSTR(I)
 #  define TRACE(n, str, ...)
@@ -79,59 +81,23 @@ using namespace QV4::Moth;
 
 #endif
 
-#ifdef WITH_STATS
-namespace {
-struct VMStats {
-    quint64 paramIsValue;
-    quint64 paramIsArg;
-    quint64 paramIsLocal;
-    quint64 paramIsTemp;
-    quint64 paramIsScopedLocal;
-
-    VMStats()
-        : paramIsValue(0)
-        , paramIsArg(0)
-        , paramIsLocal(0)
-        , paramIsTemp(0)
-        , paramIsScopedLocal(0)
-    {}
-
-    ~VMStats()
-    { show(); }
-
-    void show() {
-        fprintf(stderr, "VM stats:\n");
-        fprintf(stderr, "         value: %lu\n", paramIsValue);
-        fprintf(stderr, "           arg: %lu\n", paramIsArg);
-        fprintf(stderr, "         local: %lu\n", paramIsLocal);
-        fprintf(stderr, "          temp: %lu\n", paramIsTemp);
-        fprintf(stderr, "  scoped local: %lu\n", paramIsScopedLocal);
-    }
-};
-static VMStats vmStats;
-#define VMSTATS(what) ++vmStats.what
-}
-#else // !WITH_STATS
-#define VMSTATS(what) {}
-#endif // WITH_STATS
-
 #ifdef DO_TRACE_INSTR
 Param traceParam(const Param &param)
 {
     if (param.isConstant()) {
-        fprintf(stderr, "    constant\n");
+        qDebug("    constant\n");
     } else if (param.isArgument()) {
-        fprintf(stderr, "    argument %d@%d\n", param.index, param.scope);
+        qDebug("    argument %d@%d\n", param.index, param.scope);
     } else if (param.isLocal()) {
-        fprintf(stderr, "    local %d\n", param.index);
+        qDebug("    local %d\n", param.index);
     } else if (param.isTemp()) {
-        fprintf(stderr, "    temp %d\n", param.index);
+        qDebug("    temp %d\n", param.index);
     } else if (param.isScopedLocal()) {
-        fprintf(stderr, "    temp %d@%d\n", param.index, param.scope);
+        qDebug("    temp %d@%d\n", param.index, param.scope);
     } else {
         Q_ASSERT(!"INVALID");
     }
-    return Param
+    return param;
 }
 # define VALUE(param) (*VALUEPTR(param))
 # define VALUEPTR(param) (scopes[traceParam(param).scope] + param.index)
@@ -256,7 +222,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
     MOTH_END_INSTR(LoadName)
 
     MOTH_BEGIN_INSTR(GetGlobalLookup)
-        TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
         QV4::Lookup *l = context->d()->lookups + instr.index;
         STOREVALUE(instr.result, l->globalGetter(l, engine));
     MOTH_END_INSTR(GetGlobalLookup)
@@ -364,7 +329,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
     MOTH_END_INSTR(CallProperty)
 
     MOTH_BEGIN_INSTR(CallPropertyLookup)
-        TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
         Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
         QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
         callData->tag = QV4::Value::Integer_Type;
@@ -383,7 +347,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
     MOTH_END_INSTR(CallElement)
 
     MOTH_BEGIN_INSTR(CallActivationProperty)
-        TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
         Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
         QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
         callData->tag = QV4::Value::Integer_Type;
@@ -393,7 +356,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
     MOTH_END_INSTR(CallActivationProperty)
 
     MOTH_BEGIN_INSTR(CallGlobalLookup)
-        TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
         Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
         QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
         callData->tag = QV4::Value::Integer_Type;
@@ -519,7 +481,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
     MOTH_END_INSTR(ConstructPropertyLookup)
 
     MOTH_BEGIN_INSTR(CreateActivationProperty)
-        TRACE(inline, "property name = %s, args = %d, argc = %d", runtimeStrings[instr.name]->toQString().toUtf8().constData(), instr.args, instr.argc);
         Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
         QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
         callData->tag = QV4::Value::Integer_Type;
@@ -529,7 +490,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
     MOTH_END_INSTR(CreateActivationProperty)
 
     MOTH_BEGIN_INSTR(ConstructGlobalLookup)
-        TRACE(inline, "property name = %s, args = %d, argc = %d", runtimeStrings[instr.name]->toQString().toUtf8().constData(), instr.args, instr.argc);
         Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
         QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
         callData->tag = QV4::Value::Integer_Type;
index debf740..22cf73c 100644 (file)
@@ -553,7 +553,7 @@ the same object as is returned from the Qt.include() call.
 
 QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
 : propertyCapture(0), rootContext(0), isDebugging(false),
-  profiler(0), outputWarningsToStdErr(true),
+  profiler(0), outputWarningsToMsgLog(true),
   cleanup(0), erroredBindings(0), inProgressCreations(0),
   workerScriptEngine(0),
   activeObjectCreator(0),
@@ -1180,7 +1180,7 @@ void QQmlEngine::setBaseUrl(const QUrl &url)
 bool QQmlEngine::outputWarningsToStandardError() const
 {
     Q_D(const QQmlEngine);
-    return d->outputWarningsToStdErr;
+    return d->outputWarningsToMsgLog;
 }
 
 /*!
@@ -1196,7 +1196,7 @@ bool QQmlEngine::outputWarningsToStandardError() const
 void QQmlEngine::setOutputWarningsToStandardError(bool enabled)
 {
     Q_D(QQmlEngine);
-    d->outputWarningsToStdErr = enabled;
+    d->outputWarningsToMsgLog = enabled;
 }
 
 /*!
@@ -1789,7 +1789,7 @@ void QQmlEnginePrivate::warning(const QQmlError &error)
 {
     Q_Q(QQmlEngine);
     q->warnings(QList<QQmlError>() << error);
-    if (outputWarningsToStdErr)
+    if (outputWarningsToMsgLog)
         dumpwarning(error);
 }
 
@@ -1797,7 +1797,7 @@ void QQmlEnginePrivate::warning(const QList<QQmlError> &errors)
 {
     Q_Q(QQmlEngine);
     q->warnings(errors);
-    if (outputWarningsToStdErr)
+    if (outputWarningsToMsgLog)
         dumpwarning(errors);
 }
 
index 3df249a..a1935b8 100644 (file)
@@ -141,7 +141,7 @@ public:
     QQmlProfiler *profiler;
     void enableProfiler();
 
-    bool outputWarningsToStdErr;
+    bool outputWarningsToMsgLog;
 
     // Registered cleanup handlers
     QQmlCleanup *cleanup;