mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
explode Subroutines in compile.cpp rather than handling them in Compiler
This commit is contained in:
parent
14c960ac6a
commit
5ad1a14a73
@ -42,19 +42,15 @@ class Compiler {
|
||||
static const unsigned LongJumpOrCall = 1 << 3;
|
||||
|
||||
class State { };
|
||||
class Subroutine { };
|
||||
|
||||
virtual State* saveState() = 0;
|
||||
virtual void restoreState(State* state) = 0;
|
||||
|
||||
virtual Subroutine* startSubroutine() = 0;
|
||||
virtual void returnFromSubroutine(Subroutine* subroutine, ir::Value* address)
|
||||
= 0;
|
||||
virtual void linkSubroutine(Subroutine* subroutine) = 0;
|
||||
|
||||
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
|
||||
unsigned localFootprint, unsigned alignedFrameSize) = 0;
|
||||
|
||||
virtual void extendLogicalCode(unsigned more) = 0;
|
||||
|
||||
virtual void visitLogicalIp(unsigned logicalIp) = 0;
|
||||
virtual void startLogicalIp(unsigned logicalIp) = 0;
|
||||
|
||||
@ -76,7 +72,7 @@ class Compiler {
|
||||
virtual void push(ir::Type type, ir::Value* value) = 0;
|
||||
virtual void save(ir::Type type, ir::Value* value) = 0;
|
||||
virtual ir::Value* pop(ir::Type type) = 0;
|
||||
virtual void pushed() = 0;
|
||||
virtual void pushed(ir::Type type) = 0;
|
||||
virtual void popped(unsigned footprint) = 0;
|
||||
virtual unsigned topOfStack() = 0;
|
||||
virtual ir::Value* peek(unsigned footprint, unsigned index) = 0;
|
||||
|
@ -2141,27 +2141,9 @@ class MyCompiler: public Compiler {
|
||||
compiler::restoreState(&c, static_cast<ForkState*>(state));
|
||||
}
|
||||
|
||||
virtual Subroutine* startSubroutine() {
|
||||
return c.subroutine = new(c.zone) MySubroutine;
|
||||
}
|
||||
|
||||
virtual void returnFromSubroutine(Subroutine* subroutine, ir::Value* address)
|
||||
{
|
||||
appendSaveLocals(&c);
|
||||
appendJump(&c, lir::Jump, static_cast<Value*>(address), false, true);
|
||||
static_cast<MySubroutine*>(subroutine)->forkState = compiler::saveState(&c);
|
||||
}
|
||||
|
||||
virtual void linkSubroutine(Subroutine* subroutine) {
|
||||
Local* oldLocals = c.locals;
|
||||
restoreState(static_cast<MySubroutine*>(subroutine)->forkState);
|
||||
linkLocals(&c, oldLocals, c.locals);
|
||||
}
|
||||
|
||||
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
|
||||
unsigned localFootprint, unsigned alignedFrameSize)
|
||||
{
|
||||
c.logicalCodeLength = logicalCodeLength;
|
||||
c.parameterFootprint = parameterFootprint;
|
||||
c.localFootprint = localFootprint;
|
||||
c.alignedFrameSize = alignedFrameSize;
|
||||
@ -2180,23 +2162,23 @@ class MyCompiler: public Compiler {
|
||||
c.frameResources[base + c.arch->framePointerOffset()].reserved
|
||||
= UseFramePointer;
|
||||
|
||||
// leave room for logical instruction -1
|
||||
unsigned codeSize = sizeof(LogicalInstruction*) * (logicalCodeLength + 1);
|
||||
c.logicalCode = static_cast<LogicalInstruction**>
|
||||
(c.zone->allocate(codeSize));
|
||||
memset(c.logicalCode, 0, codeSize);
|
||||
c.logicalCode++;
|
||||
c.logicalCode.init(c.zone, logicalCodeLength);
|
||||
|
||||
c.logicalCode[-1] = new (c.zone) LogicalInstruction(-1, c.stack, c.locals);
|
||||
|
||||
c.locals = static_cast<Local*>
|
||||
(c.zone->allocate(sizeof(Local) * localFootprint));
|
||||
|
||||
memset(c.locals, 0, sizeof(Local) * localFootprint);
|
||||
}
|
||||
|
||||
c.logicalCode[-1] = new(c.zone) LogicalInstruction(-1, c.stack, c.locals);
|
||||
virtual void extendLogicalCode(unsigned more)
|
||||
{
|
||||
c.logicalCode.extend(c.zone, more);
|
||||
}
|
||||
|
||||
virtual void visitLogicalIp(unsigned logicalIp) {
|
||||
assert(&c, logicalIp < c.logicalCodeLength);
|
||||
assert(&c, logicalIp < c.logicalCode.count());
|
||||
|
||||
if (c.logicalCode[c.logicalIp]->lastEvent == 0) {
|
||||
appendDummy(&c);
|
||||
@ -2228,17 +2210,11 @@ class MyCompiler: public Compiler {
|
||||
populateJunctionReads(&c, link);
|
||||
}
|
||||
|
||||
if (c.subroutine) {
|
||||
c.subroutine->forkState
|
||||
= c.logicalCode[logicalIp]->subroutine->forkState;
|
||||
c.subroutine = 0;
|
||||
}
|
||||
|
||||
c.forkState = 0;
|
||||
}
|
||||
|
||||
virtual void startLogicalIp(unsigned logicalIp) {
|
||||
assert(&c, logicalIp < c.logicalCodeLength);
|
||||
assert(&c, logicalIp < c.logicalCode.count());
|
||||
assert(&c, c.logicalCode[logicalIp] == 0);
|
||||
|
||||
if (c.logicalCode[c.logicalIp]->lastEvent == 0) {
|
||||
@ -2253,30 +2229,7 @@ class MyCompiler: public Compiler {
|
||||
|
||||
c.logicalCode[logicalIp] = new(c.zone) LogicalInstruction(logicalIp, c.stack, c.locals);
|
||||
|
||||
bool startSubroutine = c.subroutine != 0;
|
||||
if (startSubroutine) {
|
||||
c.logicalCode[logicalIp]->subroutine = c.subroutine;
|
||||
c.subroutine = 0;
|
||||
}
|
||||
|
||||
c.logicalIp = logicalIp;
|
||||
|
||||
if (startSubroutine) {
|
||||
// assume all local variables are initialized on entry to a
|
||||
// subroutine, since other calls to the subroutine may
|
||||
// initialize them:
|
||||
unsigned sizeInBytes = sizeof(Local) * c.localFootprint;
|
||||
Local* newLocals = static_cast<Local*>(c.zone->allocate(sizeInBytes));
|
||||
memcpy(newLocals, c.locals, sizeInBytes);
|
||||
c.locals = newLocals;
|
||||
|
||||
for (unsigned li = 0; li < c.localFootprint; ++li) {
|
||||
Local* local = c.locals + li;
|
||||
if (local->value == 0) {
|
||||
initLocal(1, li, ir::Type(ir::Type::Invalid, TargetBytesPerWord));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual Promise* machineIp(unsigned logicalIp) {
|
||||
@ -2377,8 +2330,9 @@ class MyCompiler: public Compiler {
|
||||
return value;
|
||||
}
|
||||
|
||||
virtual void pushed() {
|
||||
Value* v = value(&c, ir::Type(ir::Type::Object, TargetBytesPerWord));
|
||||
virtual void pushed(ir::Type type)
|
||||
{
|
||||
Value* v = value(&c, type);
|
||||
appendFrameSite
|
||||
(&c, v, frameIndex
|
||||
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
|
||||
@ -2570,7 +2524,7 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual void initLocalsFromLogicalIp(unsigned logicalIp) {
|
||||
assert(&c, logicalIp < c.logicalCodeLength);
|
||||
assert(&c, logicalIp < c.logicalCode.count());
|
||||
|
||||
unsigned footprint = sizeof(Local) * c.localFootprint;
|
||||
Local* newLocals = static_cast<Local*>(c.zone->allocate(footprint));
|
||||
@ -2599,7 +2553,9 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual void saveLocals() {
|
||||
int oldIp UNUSED = c.logicalIp;
|
||||
appendSaveLocals(&c);
|
||||
assert(&c, oldIp == c.logicalIp);
|
||||
}
|
||||
|
||||
virtual void checkBounds(ir::Value* object,
|
||||
|
@ -28,7 +28,6 @@ Context::Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||
locals(0),
|
||||
saved(0),
|
||||
predecessor(0),
|
||||
logicalCode(0),
|
||||
regFile(arch->registerFile()),
|
||||
regAlloc(system, arch->registerFile()),
|
||||
registerResources
|
||||
@ -42,11 +41,9 @@ Context::Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||
firstEvent(0),
|
||||
lastEvent(0),
|
||||
forkState(0),
|
||||
subroutine(0),
|
||||
firstBlock(0),
|
||||
logicalIp(-1),
|
||||
constantCount(0),
|
||||
logicalCodeLength(0),
|
||||
parameterFootprint(0),
|
||||
localFootprint(0),
|
||||
machineCodeSize(0),
|
||||
|
@ -35,7 +35,6 @@ class FrameResource;
|
||||
class ConstantPoolNode;
|
||||
|
||||
class ForkState;
|
||||
class MySubroutine;
|
||||
class Block;
|
||||
|
||||
template<class T>
|
||||
@ -50,6 +49,48 @@ List<T>* reverseDestroy(List<T>* cell) {
|
||||
return previous;
|
||||
}
|
||||
|
||||
class LogicalCode {
|
||||
private:
|
||||
util::Slice<LogicalInstruction*> logicalCode;
|
||||
|
||||
public:
|
||||
LogicalCode() : logicalCode(0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
void init(vm::Zone* zone, size_t count)
|
||||
{
|
||||
// leave room for logical instruction -1
|
||||
size_t realCount = count + 1;
|
||||
|
||||
logicalCode
|
||||
= util::Slice<LogicalInstruction*>::allocAndSet(zone, realCount, 0);
|
||||
}
|
||||
|
||||
void extend(vm::Zone* zone, size_t more)
|
||||
{
|
||||
util::Slice<LogicalInstruction*> newCode
|
||||
= logicalCode.cloneAndSet(zone, logicalCode.count + more, 0);
|
||||
|
||||
for (size_t i = 0; i < logicalCode.count; i++) {
|
||||
assert((vm::System*)0, logicalCode[i] == newCode[i]);
|
||||
}
|
||||
|
||||
logicalCode = newCode;
|
||||
}
|
||||
|
||||
size_t count()
|
||||
{
|
||||
return logicalCode.count - 1;
|
||||
}
|
||||
|
||||
LogicalInstruction*& operator[](int index)
|
||||
{
|
||||
// leave room for logical instruction -1
|
||||
return logicalCode[index + 1];
|
||||
}
|
||||
};
|
||||
|
||||
class Context {
|
||||
public:
|
||||
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||
@ -64,7 +105,7 @@ class Context {
|
||||
Local* locals;
|
||||
List<Value*>* saved;
|
||||
Event* predecessor;
|
||||
LogicalInstruction** logicalCode;
|
||||
LogicalCode logicalCode;
|
||||
const RegisterFile* regFile;
|
||||
RegisterAllocator regAlloc;
|
||||
RegisterResource* registerResources;
|
||||
@ -76,11 +117,9 @@ class Context {
|
||||
Event* firstEvent;
|
||||
Event* lastEvent;
|
||||
ForkState* forkState;
|
||||
MySubroutine* subroutine;
|
||||
Block* firstBlock;
|
||||
int logicalIp;
|
||||
unsigned constantCount;
|
||||
unsigned logicalCodeLength;
|
||||
unsigned parameterFootprint;
|
||||
unsigned localFootprint;
|
||||
unsigned machineCodeSize;
|
||||
|
@ -15,14 +15,19 @@ namespace avian {
|
||||
namespace codegen {
|
||||
namespace compiler {
|
||||
|
||||
LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals):
|
||||
firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(stack),
|
||||
locals(locals), machineOffset(0), subroutine(0), index(index)
|
||||
LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals)
|
||||
: firstEvent(0),
|
||||
lastEvent(0),
|
||||
immediatePredecessor(0),
|
||||
stack(stack),
|
||||
locals(locals),
|
||||
machineOffset(0),
|
||||
/*subroutine(0), */ index(index)
|
||||
{ }
|
||||
|
||||
LogicalInstruction* LogicalInstruction::next(Context* c) {
|
||||
LogicalInstruction* i = this;
|
||||
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
|
||||
for (size_t n = i->index + 1; n < c->logicalCode.count(); ++n) {
|
||||
i = c->logicalCode[n];
|
||||
if (i) return i;
|
||||
}
|
||||
|
@ -57,17 +57,9 @@ class LogicalInstruction {
|
||||
Stack* stack;
|
||||
Local* locals;
|
||||
Promise* machineOffset;
|
||||
MySubroutine* subroutine;
|
||||
int index;
|
||||
};
|
||||
|
||||
class MySubroutine: public Compiler::Subroutine {
|
||||
public:
|
||||
MySubroutine(): forkState(0) { }
|
||||
|
||||
ForkState* forkState;
|
||||
};
|
||||
|
||||
class Block {
|
||||
public:
|
||||
Block(Event* head);
|
||||
|
960
src/compile.cpp
960
src/compile.cpp
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user