Make debug annotations more robust against statement re-ordering
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 30 May 2013 08:55:41 +0000 (10:55 +0200)
committerLars Knoll <lars.knoll@digia.com>
Fri, 31 May 2013 21:00:51 +0000 (23:00 +0200)
As suggested by Erik, instead of storing debug annotations as separate
statements in the IR, annotate the Stmt itself instead.

Change-Id: I690ae602fba500a39909eb3ef71b50f39b98ec86
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/moth/qv4isel_moth_p.h
src/qml/qml/v4/qv4codegen.cpp
src/qml/qml/v4/qv4isel_masm.cpp
src/qml/qml/v4/qv4isel_masm_p.h
src/qml/qml/v4/qv4jsir.cpp
src/qml/qml/v4/qv4jsir_p.h

index dd3b73d..58f8eec 100644 (file)
@@ -26,7 +26,6 @@ protected:
     virtual void visitCJump(V4IR::CJump *);
     virtual void visitRet(V4IR::Ret *);
     virtual void visitTry(V4IR::Try *);
-    virtual void visitDebugAnnotation(V4IR::DebugAnnotation *) {}
 
     virtual void callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result);
     virtual void callBuiltinTypeofMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result);
index c2b58e4..1b8473d 100644 (file)
@@ -116,7 +116,6 @@ struct ComputeUseDef: V4IR::StmtVisitor, V4IR::ExprVisitor
         if (! _stmt->d->defs.contains(t->exceptionVar->index))
             _stmt->d->defs.append(t->exceptionVar->index);
     }
-    virtual void visitDebugAnnotation(V4IR::DebugAnnotation *) {}
 
     virtual void visitTemp(V4IR::Temp *e) {
         if (e->index < 0 || e->scope != 0)
@@ -372,7 +371,6 @@ protected:
     virtual void visitCJump(V4IR::CJump *s) { s->cond->accept(this); }
     virtual void visitRet(V4IR::Ret *s) { s->expr->accept(this); }
     virtual void visitTry(V4IR::Try *) {}
-    virtual void visitDebugAnnotation(V4IR::DebugAnnotation *) {}
 
     virtual void visitCall(V4IR::Call *e) {
         e->base->accept(this);
@@ -552,7 +550,6 @@ protected:
     virtual void visitCJump(V4IR::CJump *s) { s->cond->accept(this); }
     virtual void visitRet(V4IR::Ret *s) { s->expr->accept(this); }
     virtual void visitTry(V4IR::Try *t) { visitTemp(t->exceptionVar); }
-    virtual void visitDebugAnnotation(V4IR::DebugAnnotation *) {}
 
     virtual void visitTemp(V4IR::Temp *e) {
         if (e->scope) // scoped local
@@ -1343,7 +1340,7 @@ void Codegen::accept(Node *node)
 
 void Codegen::statement(Statement *ast)
 {
-    _block->DEBUGANNOTATION(ast->firstSourceLocation());
+    _block->nextLocation = ast->firstSourceLocation();
     accept(ast);
 }
 
@@ -2520,6 +2517,9 @@ void Codegen::linearize(V4IR::Function *function)
             s->dump(out, V4IR::Stmt::MIR);
             out.flush();
 
+            if (s->location.isValid())
+                qout << "    // line: " << s->location.startLine << " column: " << s->location.startColumn << endl;
+
 #ifndef QV4_NO_LIVENESS
             for (int i = 60 - str.size(); i >= 0; --i)
                 str.append(' ');
index 28a5d51..f104b6e 100644 (file)
@@ -607,6 +607,8 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
         }
 
         foreach (V4IR::Stmt *s, block->statements) {
+            if (s->location.isValid())
+                _as->recordLineNumber(s->location.startLine);
             s->accept(this);
         }
     }
@@ -799,11 +801,6 @@ void InstructionSelection::visitTry(V4IR::Try *t)
     _as->jump(Assembler::ReturnValueRegister);
 }
 
-void InstructionSelection::visitDebugAnnotation(V4IR::DebugAnnotation *annotation)
-{
-    _as->recordLineNumber(annotation->location.startLine);
-}
-
 void InstructionSelection::callBuiltinFinishTry()
 {
     // This assumes that we're in code that was called by tryWrapper, so we return to try wrapper
index 120b4a5..9a55ede 100644 (file)
@@ -847,7 +847,6 @@ protected:
     virtual void visitCJump(V4IR::CJump *);
     virtual void visitRet(V4IR::Ret *);
     virtual void visitTry(V4IR::Try *);
-    virtual void visitDebugAnnotation(V4IR::DebugAnnotation *);
 
 private:
     #define isel_stringIfyx(s) #s
index 33debee..9f62b94 100644 (file)
@@ -221,8 +221,6 @@ struct RemoveSharedExpressions: V4IR::StmtVisitor, V4IR::ExprVisitor
         // nothing to do for Try statements
     }
 
-    virtual void visitDebugAnnotation(DebugAnnotation *) {}
-
     // expressions
     virtual void visitConst(Const *) {}
     virtual void visitString(String *) {}
@@ -545,11 +543,6 @@ void Try::dump(QTextStream &out, Stmt::Mode mode)
     out << " with the name " << exceptionVarName << " and go to L" << catchBlock->index << ';';
 }
 
-void DebugAnnotation::dump(QTextStream &out, Mode mode)
-{
-    out << "// line: " << location.startLine << " ; column: " << location.startColumn;
-}
-
 Function *Module::newFunction(const QString &name, Function *outer)
 {
     Function *f = new Function(this, outer, name);
@@ -739,7 +732,7 @@ Stmt *BasicBlock::EXP(Expr *expr)
 
     Exp *s = function->New<Exp>();
     s->init(expr);
-    statements.append(s);
+    appendStatement(s);
     return s;
 }
 
@@ -750,7 +743,7 @@ Stmt *BasicBlock::ENTER(Expr *expr)
 
     Enter *s = function->New<Enter>();
     s->init(expr);
-    statements.append(s);
+    appendStatement(s);
     return s;
 }
 
@@ -761,7 +754,7 @@ Stmt *BasicBlock::LEAVE()
 
     Leave *s = function->New<Leave>();
     s->init();
-    statements.append(s);
+    appendStatement(s);
     return s;
 }
 
@@ -772,7 +765,7 @@ Stmt *BasicBlock::MOVE(Expr *target, Expr *source, AluOp op)
 
     Move *s = function->New<Move>();
     s->init(target, source, op);
-    statements.append(s);
+    appendStatement(s);
     return s;
 }
 
@@ -783,7 +776,7 @@ Stmt *BasicBlock::JUMP(BasicBlock *target)
 
     Jump *s = function->New<Jump>();
     s->init(target);
-    statements.append(s);
+    appendStatement(s);
 
     assert(! out.contains(target));
     out.append(target);
@@ -806,7 +799,7 @@ Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
 
     CJump *s = function->New<CJump>();
     s->init(cond, iftrue, iffalse);
-    statements.append(s);
+    appendStatement(s);
 
     assert(! out.contains(iftrue));
     out.append(iftrue);
@@ -830,7 +823,7 @@ Stmt *BasicBlock::RET(Temp *expr)
 
     Ret *s = function->New<Ret>();
     s->init(expr);
-    statements.append(s);
+    appendStatement(s);
     return s;
 }
 
@@ -841,7 +834,7 @@ Stmt *BasicBlock::TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QStrin
 
     Try *t = function->New<Try>();
     t->init(tryBlock, catchBlock, exceptionVarName, exceptionVar);
-    statements.append(t);
+    appendStatement(t);
 
     assert(! out.contains(tryBlock));
     out.append(tryBlock);
@@ -858,26 +851,29 @@ Stmt *BasicBlock::TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QStrin
     return t;
 }
 
-Stmt *BasicBlock::DEBUGANNOTATION(const AST::SourceLocation &location)
-{
-    if (isTerminated())
-        return 0;
-
-    DebugAnnotation *t = function->New<DebugAnnotation>();
-    t->init(location);
-    statements.append(t);
-}
-
 void BasicBlock::dump(QTextStream &out, Stmt::Mode mode)
 {
     out << 'L' << index << ':' << endl;
     foreach (Stmt *s, statements) {
         out << '\t';
         s->dump(out, mode);
+
+        if (s->location.isValid())
+            out << " // line: " << s->location.startLine << " ; column: " << s->location.startColumn;
+
         out << endl;
     }
 }
 
+void BasicBlock::appendStatement(Stmt *statement)
+{
+    if (nextLocation.isValid()) {
+        statement->location = nextLocation;
+        nextLocation = AST::SourceLocation();
+    }
+    statements.append(statement);
+}
+
 CloneExpr::CloneExpr(BasicBlock *block)
     : block(block), cloned(0)
 {
index 0bb310b..5755f8e 100644 (file)
@@ -119,7 +119,6 @@ struct Jump;
 struct CJump;
 struct Ret;
 struct Try;
-struct DebugAnnotation;
 
 enum AluOp {
     OpInvalid = 0,
@@ -200,7 +199,6 @@ struct StmtVisitor {
     virtual void visitCJump(CJump *) = 0;
     virtual void visitRet(Ret *) = 0;
     virtual void visitTry(Try *) = 0;
-    virtual void visitDebugAnnotation(DebugAnnotation *) = 0;
 };
 
 struct Expr {
@@ -481,6 +479,7 @@ struct Stmt {
     };
 
     Data *d;
+    AST::SourceLocation location;
 
     Stmt(): d(0) {}
     virtual ~Stmt() { Q_UNREACHABLE(); }
@@ -495,7 +494,6 @@ struct Stmt {
     virtual CJump *asCJump() { return 0; }
     virtual Ret *asRet() { return 0; }
     virtual Try *asTry() { return 0; }
-    virtual DebugAnnotation *asDebugAnnotation() { return 0; }
     virtual void dump(QTextStream &out, Mode mode = HIR) = 0;
 
     void destroyData() {
@@ -633,20 +631,6 @@ struct Try: Stmt {
     virtual void dump(QTextStream &out, Mode mode);
 };
 
-struct DebugAnnotation: Stmt {
-    AST::SourceLocation location;
-
-    void init(const AST::SourceLocation &location)
-    {
-        this->location = location;
-    }
-
-    virtual void accept(StmtVisitor *v) { v->visitDebugAnnotation(this); }
-    virtual DebugAnnotation *asDebugAnnotation() { return this; }
-
-    virtual void dump(QTextStream &out, Mode mode);
-};
-
 struct Q_QML_EXPORT Module {
     MemoryPool pool;
     QVector<Function *> functions;
@@ -732,6 +716,7 @@ struct BasicBlock {
     QBitArray liveOut;
     int index;
     int offset;
+    AST::SourceLocation nextLocation;
 
     BasicBlock(Function *function): function(function), index(-1), offset(-1) {}
     ~BasicBlock() {}
@@ -786,9 +771,10 @@ struct BasicBlock {
     Stmt *CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse);
     Stmt *RET(Temp *expr);
     Stmt *TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName, Temp *exceptionVar);
-    Stmt *DEBUGANNOTATION(const AST::SourceLocation &location);
 
     void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR);
+
+    void appendStatement(Stmt *statement);
 };
 
 class CloneExpr: protected V4IR::ExprVisitor