aboutsummaryrefslogtreecommitdiffstats
path: root/moth
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2012-12-11 10:03:40 +0100
committerLars Knoll <lars.knoll@digia.com>2012-12-11 23:16:32 +0100
commit5e39d56c0974faa28c5060a12064e1ad7f611ea0 (patch)
treea2f900ab936799f002e769e9a48d191af773d3d8 /moth
parentbcdddfda8ca81752b249540b0abaefb46eb5f766 (diff)
Remove IR::Function from the runtime.
This fixes potential leaks of IR::Functions, lowers the memory usage of the functions that the VM needs (because the IR fields are not present in the VM::Function), and makes both managed by the module respectively the ExecutionEngine. Change-Id: I6748ad98b062f994eae9dd14f1919aec5aa7c0b0 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'moth')
-rw-r--r--moth/qv4instr_moth_p.h2
-rw-r--r--moth/qv4isel_moth.cpp65
-rw-r--r--moth/qv4isel_moth_p.h11
3 files changed, 43 insertions, 35 deletions
diff --git a/moth/qv4instr_moth_p.h b/moth/qv4instr_moth_p.h
index 67d11370ac..65a6a0303e 100644
--- a/moth/qv4instr_moth_p.h
+++ b/moth/qv4instr_moth_p.h
@@ -86,7 +86,7 @@ union Instr
};
struct instr_loadClosure {
MOTH_INSTR_HEADER
- IR::Function *value;
+ VM::Function *value;
int targetTempIndex;
};
struct instr_loadName {
diff --git a/moth/qv4isel_moth.cpp b/moth/qv4isel_moth.cpp
index 10a5c1106d..328fdce38c 100644
--- a/moth/qv4isel_moth.cpp
+++ b/moth/qv4isel_moth.cpp
@@ -181,27 +181,28 @@ private:
} // anonymous namespace
-InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine)
- : _engine(engine)
+InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module)
+ : EvalInstructionSelection(engine, module)
+ , _function(0)
+ , _block(0)
+ , _code(0)
+ , _ccode(0)
{
- // FIXME: make the size dynamic. This requires changing the patching.
- _code = new uchar[getpagesize() * 4000];
- _ccode = _code;
}
InstructionSelection::~InstructionSelection()
{
}
-void InstructionSelection::operator()(IR::Function *function)
+VM::Function *InstructionSelection::run(IR::Function *function)
{
qSwap(_function, function);
+ // FIXME: make the size dynamic. This requires changing the patching.
+ _code = new uchar[getpagesize() * 4000];
+ _ccode = _code;
CompressTemps().run(_function);
- _function->code = VME::exec;
- _function->codeData = _code;
-
int locals = frameSize();
assert(locals >= 0);
@@ -210,10 +211,7 @@ void InstructionSelection::operator()(IR::Function *function)
addInstruction(push);
foreach (_block, _function->basicBlocks) {
- ptrdiff_t blockOffset = _ccode - _code;
_addrs.insert(_block, _ccode - _code);
- if (_engine->debugger)
- _engine->debugger->addaddBasicBlockOffset(_function, _block, blockOffset);
foreach (IR::Stmt *s, _block->statements)
s->accept(this);
@@ -234,6 +232,17 @@ void InstructionSelection::operator()(IR::Function *function)
}
qSwap(_function, function);
+ _patches.clear();
+ _addrs.clear();
+
+ VM::Function *vmFunc = vmFunction(function);
+ vmFunc->code = VME::exec;
+ vmFunc->codeData = _code;
+
+ _block = 0;
+ _code = 0;
+ _ccode = 0;
+ return vmFunc;
}
void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempIndex)
@@ -246,7 +255,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempInd
const int scratchIndex = scratchTempIndex();
Instruction::LoadName load;
- load.name = _engine->newString(*baseName->id);
+ load.name = engine()->newString(*baseName->id);
load.targetTempIndex = scratchIndex;
addInstruction(load);
@@ -272,7 +281,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempInd
if (IR::Member *m = c->args->expr->asMember()) {
Instruction::CallBuiltinDeleteMember call;
call.base = m->base->asTemp()->index;
- call.member = _engine->newString(*m->name);
+ call.member = engine()->newString(*m->name);
call.targetTempIndex = targetTempIndex;
addInstruction(call);
} else if (IR::Subscript *ss = c->args->expr->asSubscript()) {
@@ -283,7 +292,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempInd
addInstruction(call);
} else if (IR::Name *n = c->args->expr->asName()) {
Instruction::CallBuiltinDeleteName call;
- call.name = _engine->newString(*n->id);
+ call.name = engine()->newString(*n->id);
call.targetTempIndex = targetTempIndex;
addInstruction(call);
} else {
@@ -363,7 +372,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempInd
for (IR::ExprList *it = c->args->next; it; it = it->next) {
Instruction::CallBuiltinDeclareVar call;
call.isDeletable = isDeletable;
- call.varName = _engine->newString(*it->expr->asName()->id);
+ call.varName = engine()->newString(*it->expr->asName()->id);
}
} break;
@@ -393,7 +402,7 @@ void InstructionSelection::callProperty(IR::Call *c, int targetTempIndex)
// call the property on the loaded base
Instruction::CallProperty call;
call.baseTemp = m->base->asTemp()->index;
- call.name = _engine->newString(*m->name);
+ call.name = engine()->newString(*m->name);
prepareCallArgs(c->args, call.argc, call.args);
call.targetTempIndex = targetTempIndex;
addInstruction(call);
@@ -403,7 +412,7 @@ void InstructionSelection::construct(IR::New *ctor, int targetTempIndex)
{
if (IR::Name *baseName = ctor->base->asName()) {
Instruction::CreateActivationProperty create;
- create.name = _engine->newString(*baseName->id);
+ create.name = engine()->newString(*baseName->id);
prepareCallArgs(ctor->args, create.argc, create.args);
create.targetTempIndex = targetTempIndex;
addInstruction(create);
@@ -413,7 +422,7 @@ void InstructionSelection::construct(IR::New *ctor, int targetTempIndex)
Instruction::CreateProperty create;
create.base = base->index;
- create.name = _engine->newString(*member->name);
+ create.name = engine()->newString(*member->name);
prepareCallArgs(ctor->args, create.argc, create.args);
create.targetTempIndex = targetTempIndex;
addInstruction(create);
@@ -578,7 +587,7 @@ void InstructionSelection::visitMove(IR::Move *s)
addInstruction(load);
} else {
Instruction::LoadName load;
- load.name = _engine->newString(*n->id);
+ load.name = engine()->newString(*n->id);
load.targetTempIndex = targetTempIndex;
addInstruction(load);
}
@@ -607,12 +616,14 @@ void InstructionSelection::visitMove(IR::Move *s)
}
} else if (IR::String *str = s->source->asString()) {
Instruction::LoadValue load;
- load.value = VM::Value::fromString(_engine->newString(*str->value));
+ load.value = VM::Value::fromString(engine()->newString(*str->value));
load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else if (IR::Closure *clos = s->source->asClosure()) {
+ VM::Function *vmFunc = vmFunction(clos->value);
+ assert(vmFunc);
Instruction::LoadClosure load;
- load.value = clos->value;
+ load.value = vmFunc;
load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else if (IR::New *ctor = s->source->asNew()) {
@@ -621,7 +632,7 @@ void InstructionSelection::visitMove(IR::Move *s)
if (IR::Temp *base = m->base->asTemp()) {
Instruction::LoadProperty load;
load.baseTemp = base->index;
- load.name = _engine->newString(*m->name);
+ load.name = engine()->newString(*m->name);
load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else {
@@ -699,14 +710,14 @@ void InstructionSelection::visitMove(IR::Move *s)
if (op) {
Instruction::InplaceNameOp ieo;
ieo.alu = op;
- ieo.targetName = _engine->newString(*n->id);
+ ieo.targetName = engine()->newString(*n->id);
ieo.sourceIsTemp = toValueOrTemp(s->source, ieo.source);
addInstruction(ieo);
return;
} else if (s->op == IR::OpInvalid) {
Instruction::StoreName store;
store.sourceIsTemp = toValueOrTemp(s->source, store.source);
- store.name = _engine->newString(*n->id);
+ store.name = engine()->newString(*n->id);
addInstruction(store);
return;
}
@@ -770,14 +781,14 @@ void InstructionSelection::visitMove(IR::Move *s)
Instruction::InplaceMemberOp imo;
imo.alu = op;
imo.targetBase = m->base->asTemp()->index;
- imo.targetMember = _engine->newString(*m->name);
+ imo.targetMember = engine()->newString(*m->name);
imo.sourceIsTemp = toValueOrTemp(s->source, imo.source);
addInstruction(imo);
return;
} else if (s->op == IR::OpInvalid) {
Instruction::StoreProperty store;
store.baseTemp = m->base->asTemp()->index;
- store.name = _engine->newString(*m->name);
+ store.name = engine()->newString(*m->name);
store.sourceIsTemp = toValueOrTemp(s->source, store.source);
addInstruction(store);
return;
diff --git a/moth/qv4isel_moth_p.h b/moth/qv4isel_moth_p.h
index 6fe5259dfb..e7c85174c3 100644
--- a/moth/qv4isel_moth_p.h
+++ b/moth/qv4isel_moth_p.h
@@ -12,12 +12,10 @@ namespace Moth {
class InstructionSelection : public IR::StmtVisitor, public EvalInstructionSelection
{
public:
- InstructionSelection(VM::ExecutionEngine *engine);
+ InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module);
~InstructionSelection();
- virtual void run(IR::Function *function)
- { this->operator()(function); }
- virtual void operator()(IR::Function *function);
+ virtual VM::Function *run(IR::Function *function);
protected:
virtual void visitExp(IR::Exp *);
@@ -52,7 +50,6 @@ private:
inline ptrdiff_t addInstruction(const InstrData<Instr> &data);
ptrdiff_t addInstructionHelper(Instr::Type type, Instr &instr);
- VM::ExecutionEngine *_engine;
IR::Function *_function;
IR::BasicBlock *_block;
@@ -67,8 +64,8 @@ class ISelFactory: public EvalISelFactory
{
public:
virtual ~ISelFactory() {}
- virtual EvalInstructionSelection *create(VM::ExecutionEngine *engine)
- { return new InstructionSelection(engine); }
+ virtual EvalInstructionSelection *create(VM::ExecutionEngine *engine, IR::Module *module)
+ { return new InstructionSelection(engine, module); }
};
template<int InstrT>