From 78e450a0e289483afa7db09aa5e15e62df1540a6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 30 May 2013 10:55:41 +0200 Subject: [PATCH] Make debug annotations more robust against statement re-ordering 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 --- src/qml/qml/v4/moth/qv4isel_moth_p.h | 1 - src/qml/qml/v4/qv4codegen.cpp | 8 +++---- src/qml/qml/v4/qv4isel_masm.cpp | 7 ++---- src/qml/qml/v4/qv4isel_masm_p.h | 1 - src/qml/qml/v4/qv4jsir.cpp | 46 ++++++++++++++++-------------------- src/qml/qml/v4/qv4jsir_p.h | 22 ++++------------- 6 files changed, 31 insertions(+), 54 deletions(-) diff --git a/src/qml/qml/v4/moth/qv4isel_moth_p.h b/src/qml/qml/v4/moth/qv4isel_moth_p.h index dd3b73d..58f8eec 100644 --- a/src/qml/qml/v4/moth/qv4isel_moth_p.h +++ b/src/qml/qml/v4/moth/qv4isel_moth_p.h @@ -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); diff --git a/src/qml/qml/v4/qv4codegen.cpp b/src/qml/qml/v4/qv4codegen.cpp index c2b58e4..1b8473d 100644 --- a/src/qml/qml/v4/qv4codegen.cpp +++ b/src/qml/qml/v4/qv4codegen.cpp @@ -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(' '); diff --git a/src/qml/qml/v4/qv4isel_masm.cpp b/src/qml/qml/v4/qv4isel_masm.cpp index 28a5d51..f104b6e 100644 --- a/src/qml/qml/v4/qv4isel_masm.cpp +++ b/src/qml/qml/v4/qv4isel_masm.cpp @@ -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 diff --git a/src/qml/qml/v4/qv4isel_masm_p.h b/src/qml/qml/v4/qv4isel_masm_p.h index 120b4a5..9a55ede 100644 --- a/src/qml/qml/v4/qv4isel_masm_p.h +++ b/src/qml/qml/v4/qv4isel_masm_p.h @@ -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 diff --git a/src/qml/qml/v4/qv4jsir.cpp b/src/qml/qml/v4/qv4jsir.cpp index 33debee..9f62b94 100644 --- a/src/qml/qml/v4/qv4jsir.cpp +++ b/src/qml/qml/v4/qv4jsir.cpp @@ -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(); s->init(expr); - statements.append(s); + appendStatement(s); return s; } @@ -750,7 +743,7 @@ Stmt *BasicBlock::ENTER(Expr *expr) Enter *s = function->New(); s->init(expr); - statements.append(s); + appendStatement(s); return s; } @@ -761,7 +754,7 @@ Stmt *BasicBlock::LEAVE() Leave *s = function->New(); 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(); 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(); 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(); 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(); 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(); 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(); - 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) { diff --git a/src/qml/qml/v4/qv4jsir_p.h b/src/qml/qml/v4/qv4jsir_p.h index 0bb310b..5755f8e 100644 --- a/src/qml/qml/v4/qv4jsir_p.h +++ b/src/qml/qml/v4/qv4jsir_p.h @@ -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 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 -- 2.7.4