diff options
author | Erik Verbruggen <[email protected]> | 2014-01-28 13:25:55 +0100 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-02-07 10:44:53 +0100 |
commit | 0b806c3adda7172673ee76a9d6f4320cf986bbf8 (patch) | |
tree | 76b9cc67ba2fd4a37efcee0a5f1fc166125f0dda /src/qml/compiler/qv4isel_util_p.h | |
parent | 412f22f15ac13d678d018763aafad134ee02e872 (diff) |
V4: stack slot allocator for the interpreter.
Use the life-time intervals to track which temps go out of scope, in
order to re-use the stack-slots they occupied. This reduces the memory
consumption on the JavaScript stack and allows for deeper call stacks.
For the ECMA tests, this reduces the number of slots needed for the
main/entry function from more than 650 to about 10 (depending on the
test).
Change-Id: Iff4044f5ff7f25e1f88ff1a04f4e80dd99a67590
Reviewed-by: Lars Knoll <[email protected]>
Diffstat (limited to 'src/qml/compiler/qv4isel_util_p.h')
-rw-r--r-- | src/qml/compiler/qv4isel_util_p.h | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/qml/compiler/qv4isel_util_p.h b/src/qml/compiler/qv4isel_util_p.h index 1d7a99941e..637746dce1 100644 --- a/src/qml/compiler/qv4isel_util_p.h +++ b/src/qml/compiler/qv4isel_util_p.h @@ -97,38 +97,52 @@ inline QV4::Primitive convertToValue(V4IR::Const *c) class ConvertTemps: protected V4IR::StmtVisitor, protected V4IR::ExprVisitor { - int _nextFreeStackSlot; - QHash<V4IR::Temp, int> _stackSlotForTemp; - void renumber(V4IR::Temp *t) { if (t->kind != V4IR::Temp::VirtualRegister) return; - int stackSlot = _stackSlotForTemp.value(*t, -1); + int stackSlot = _stackSlotForTemp.value(t->index, -1); if (stackSlot == -1) { - stackSlot = _nextFreeStackSlot++; - _stackSlotForTemp[*t] = stackSlot; + stackSlot = allocateFreeSlot(); + _stackSlotForTemp[t->index] = stackSlot; } t->kind = V4IR::Temp::StackSlot; t->index = stackSlot; } +protected: + int _nextUnusedStackSlot; + QHash<int, int> _stackSlotForTemp; + V4IR::BasicBlock *_currentBasicBlock; + virtual int allocateFreeSlot() + { + return _nextUnusedStackSlot++; + } + + virtual void process(V4IR::Stmt *s) + { + s->accept(this); + } + public: ConvertTemps() - : _nextFreeStackSlot(0) + : _nextUnusedStackSlot(0) + , _currentBasicBlock(0) {} void toStackSlots(V4IR::Function *function) { _stackSlotForTemp.reserve(function->tempCount); - foreach (V4IR::BasicBlock *bb, function->basicBlocks) + foreach (V4IR::BasicBlock *bb, function->basicBlocks) { + _currentBasicBlock = bb; foreach (V4IR::Stmt *s, bb->statements) - s->accept(this); + process(s); + } - function->tempCount = _nextFreeStackSlot; + function->tempCount = _nextUnusedStackSlot; } protected: |