mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
move JumpEvent out of compiler.cpp
This commit is contained in:
parent
65b7cf047c
commit
d00950458f
1
makefile
1
makefile
@ -961,6 +961,7 @@ ifeq ($(process),compile)
|
|||||||
$(src)/codegen/compiler/read.cpp \
|
$(src)/codegen/compiler/read.cpp \
|
||||||
$(src)/codegen/compiler/event.cpp \
|
$(src)/codegen/compiler/event.cpp \
|
||||||
$(src)/codegen/compiler/promise.cpp \
|
$(src)/codegen/compiler/promise.cpp \
|
||||||
|
$(src)/codegen/compiler/frame.cpp \
|
||||||
$(src)/codegen/registers.cpp \
|
$(src)/codegen/registers.cpp \
|
||||||
$(src)/codegen/targets.cpp
|
$(src)/codegen/targets.cpp
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
#include "codegen/compiler/site.h"
|
#include "codegen/compiler/site.h"
|
||||||
#include "codegen/compiler/read.h"
|
#include "codegen/compiler/read.h"
|
||||||
#include "codegen/compiler/event.h"
|
#include "codegen/compiler/event.h"
|
||||||
#include "codegen/compiler/stack.h"
|
|
||||||
#include "codegen/compiler/promise.h"
|
#include "codegen/compiler/promise.h"
|
||||||
|
#include "codegen/compiler/frame.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -67,11 +67,6 @@ apply(Context* c, lir::TernaryOperation op,
|
|||||||
unsigned s2Size, Site* s2Low, Site* s2High,
|
unsigned s2Size, Site* s2Low, Site* s2High,
|
||||||
unsigned s3Size, Site* s3Low, Site* s3High);
|
unsigned s3Size, Site* s3Low, Site* s3High);
|
||||||
|
|
||||||
class Local {
|
|
||||||
public:
|
|
||||||
Value* value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ForkElement {
|
class ForkElement {
|
||||||
public:
|
public:
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -220,118 +215,6 @@ countSuccessors(Link* link)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
|
||||||
totalFrameSize(Context* c)
|
|
||||||
{
|
|
||||||
return c->alignedFrameSize
|
|
||||||
+ c->arch->frameHeaderSize()
|
|
||||||
+ c->arch->argumentFootprint(c->parameterFootprint);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
frameIndex(Context* c, int localIndex)
|
|
||||||
{
|
|
||||||
assert(c, localIndex >= 0);
|
|
||||||
|
|
||||||
int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1;
|
|
||||||
|
|
||||||
if (localIndex < static_cast<int>(c->parameterFootprint)) {
|
|
||||||
index += c->arch->frameHeaderSize();
|
|
||||||
} else {
|
|
||||||
index -= c->arch->frameFooterSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(c, index >= 0);
|
|
||||||
assert(c, static_cast<unsigned>(index) < totalFrameSize(c));
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
frameIndexToOffset(Context* c, unsigned frameIndex)
|
|
||||||
{
|
|
||||||
assert(c, frameIndex < totalFrameSize(c));
|
|
||||||
|
|
||||||
return (frameIndex + c->arch->frameFooterSize()) * TargetBytesPerWord;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
offsetToFrameIndex(Context* c, unsigned offset)
|
|
||||||
{
|
|
||||||
assert(c, static_cast<int>
|
|
||||||
((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0);
|
|
||||||
assert(c, ((offset / TargetBytesPerWord) - c->arch->frameFooterSize())
|
|
||||||
< totalFrameSize(c));
|
|
||||||
|
|
||||||
return (offset / TargetBytesPerWord) - c->arch->frameFooterSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
frameBase(Context* c)
|
|
||||||
{
|
|
||||||
return c->alignedFrameSize
|
|
||||||
- c->arch->frameReturnAddressSize()
|
|
||||||
- c->arch->frameFooterSize()
|
|
||||||
+ c->arch->frameHeaderSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
class FrameIterator {
|
|
||||||
public:
|
|
||||||
class Element {
|
|
||||||
public:
|
|
||||||
Element(Value* value, unsigned localIndex):
|
|
||||||
value(value), localIndex(localIndex)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Value* const value;
|
|
||||||
const unsigned localIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
FrameIterator(Context* c, Stack* stack, Local* locals,
|
|
||||||
bool includeEmpty = false):
|
|
||||||
stack(stack), locals(locals), localIndex(c->localFootprint - 1),
|
|
||||||
includeEmpty(includeEmpty)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool hasMore() {
|
|
||||||
if (not includeEmpty) {
|
|
||||||
while (stack and stack->value == 0) stack = stack->next;
|
|
||||||
|
|
||||||
while (localIndex >= 0 and locals[localIndex].value == 0) -- localIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stack != 0 or localIndex >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element next(Context* c) {
|
|
||||||
Value* v;
|
|
||||||
unsigned li;
|
|
||||||
if (stack) {
|
|
||||||
Stack* s = stack;
|
|
||||||
v = s->value;
|
|
||||||
li = s->index + c->localFootprint;
|
|
||||||
stack = stack->next;
|
|
||||||
} else {
|
|
||||||
Local* l = locals + localIndex;
|
|
||||||
v = l->value;
|
|
||||||
li = localIndex;
|
|
||||||
-- localIndex;
|
|
||||||
}
|
|
||||||
return Element(v, li);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack* stack;
|
|
||||||
Local* locals;
|
|
||||||
int localIndex;
|
|
||||||
bool includeEmpty;
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
frameIndex(Context* c, FrameIterator::Element* element)
|
|
||||||
{
|
|
||||||
return frameIndex(c, element->localIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
clearSites(Context* c, Value* v)
|
clearSites(Context* c, Value* v)
|
||||||
{
|
{
|
||||||
@ -1021,44 +904,6 @@ apply(Context* c, lir::TernaryOperation op,
|
|||||||
OperandInfo(s3Size, s3Type, &s3Union));
|
OperandInfo(s3Size, s3Type, &s3Union));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
clean(Context* c, Value* v, unsigned popIndex)
|
|
||||||
{
|
|
||||||
for (SiteIterator it(c, v); it.hasMore();) {
|
|
||||||
Site* s = it.next();
|
|
||||||
if (not (s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))
|
|
||||||
and offsetToFrameIndex
|
|
||||||
(c, static_cast<MemorySite*>(s)->offset)
|
|
||||||
>= popIndex))
|
|
||||||
{
|
|
||||||
if (false and
|
|
||||||
s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)))
|
|
||||||
{
|
|
||||||
char buffer[256]; s->toString(c, buffer, 256);
|
|
||||||
fprintf(stderr, "remove %s from %p at %d pop offset 0x%x\n",
|
|
||||||
buffer, v, offsetToFrameIndex
|
|
||||||
(c, static_cast<MemorySite*>(s)->offset),
|
|
||||||
frameIndexToOffset(c, popIndex));
|
|
||||||
}
|
|
||||||
it.remove(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads,
|
|
||||||
unsigned popIndex)
|
|
||||||
{
|
|
||||||
for (FrameIterator it(c, stack, locals); it.hasMore();) {
|
|
||||||
FrameIterator::Element e = it.next(c);
|
|
||||||
clean(c, e.value, popIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
|
||||||
popRead(c, e, r->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
append(Context* c, Event* e);
|
append(Context* c, Event* e);
|
||||||
|
|
||||||
@ -1366,12 +1211,6 @@ makeSnapshots(Context* c, Value* value, Snapshot* next)
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack*
|
|
||||||
stack(Context* c, Value* value, Stack* next)
|
|
||||||
{
|
|
||||||
return new(c->zone) Stack(next ? next->index + 1 : 0, value, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
maybeBuddy(Context* c, Value* v);
|
maybeBuddy(Context* c, Value* v);
|
||||||
|
|
||||||
@ -1586,63 +1425,6 @@ register_(Context* c, int number)
|
|||||||
return value(c, type, s, s);
|
return value(c, type, s, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
class JumpEvent: public Event {
|
|
||||||
public:
|
|
||||||
JumpEvent(Context* c, lir::UnaryOperation type, Value* address, bool exit,
|
|
||||||
bool cleanLocals):
|
|
||||||
Event(c), type(type), address(address), exit(exit),
|
|
||||||
cleanLocals(cleanLocals)
|
|
||||||
{
|
|
||||||
bool thunk;
|
|
||||||
uint8_t typeMask;
|
|
||||||
uint64_t registerMask;
|
|
||||||
c->arch->plan(type, TargetBytesPerWord, &typeMask, ®isterMask, &thunk);
|
|
||||||
|
|
||||||
assert(c, not thunk);
|
|
||||||
|
|
||||||
this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* name() {
|
|
||||||
return "JumpEvent";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
if (not this->isUnreachable()) {
|
|
||||||
apply(c, type, TargetBytesPerWord, address->source, address->source);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
|
||||||
popRead(c, this, r->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cleanLocals) {
|
|
||||||
for (FrameIterator it(c, 0, c->locals); it.hasMore();) {
|
|
||||||
FrameIterator::Element e = it.next(c);
|
|
||||||
clean(c, e.value, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isBranch() { return true; }
|
|
||||||
|
|
||||||
virtual bool allExits() {
|
|
||||||
return exit or this->isUnreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
lir::UnaryOperation type;
|
|
||||||
Value* address;
|
|
||||||
bool exit;
|
|
||||||
bool cleanLocals;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false,
|
|
||||||
bool cleanLocals = false)
|
|
||||||
{
|
|
||||||
append(c, new(c->zone) JumpEvent(c, type, address, exit, cleanLocals));
|
|
||||||
}
|
|
||||||
|
|
||||||
class BoundsCheckEvent: public Event {
|
class BoundsCheckEvent: public Event {
|
||||||
public:
|
public:
|
||||||
BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset,
|
BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset,
|
||||||
@ -2053,7 +1835,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
|
|||||||
char buffer[256];
|
char buffer[256];
|
||||||
s->toString(c, buffer, 256);
|
s->toString(c, buffer, 256);
|
||||||
fprintf(stderr, "resolve original %s for %p local %d frame %d\n",
|
fprintf(stderr, "resolve original %s for %p local %d frame %d\n",
|
||||||
buffer, v, el.localIndex, frameIndex(c, &el));
|
buffer, v, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
Site* target = pickSiteOrMove
|
Site* target = pickSiteOrMove
|
||||||
@ -2068,7 +1850,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
|
|||||||
char buffer[256];
|
char buffer[256];
|
||||||
s->toString(c, buffer, 256);
|
s->toString(c, buffer, 256);
|
||||||
fprintf(stderr, "freeze original %s for %p local %d frame %d\n",
|
fprintf(stderr, "freeze original %s for %p local %d frame %d\n",
|
||||||
buffer, v, el.localIndex, frameIndex(c, &el));
|
buffer, v, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value dummy(0, 0, lir::ValueGeneral);
|
Value dummy(0, 0, lir::ValueGeneral);
|
||||||
@ -2101,7 +1883,7 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
|
|||||||
if (DebugControl) {
|
if (DebugControl) {
|
||||||
char buffer[256]; s->toString(c, buffer, 256);
|
char buffer[256]; s->toString(c, buffer, 256);
|
||||||
fprintf(stderr, "resolve source %s from %p local %d frame %d\n",
|
fprintf(stderr, "resolve source %s from %p local %d frame %d\n",
|
||||||
buffer, v, el.localIndex, frameIndex(c, &el));
|
buffer, v, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
freeze(c, frozen, s, v);
|
freeze(c, frozen, s, v);
|
||||||
@ -2142,7 +1924,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
|
|||||||
if (DebugControl) {
|
if (DebugControl) {
|
||||||
char buffer[256]; sites[el.localIndex]->toString(c, buffer, 256);
|
char buffer[256]; sites[el.localIndex]->toString(c, buffer, 256);
|
||||||
fprintf(stderr, "resolve target %s for %p local %d frame %d\n",
|
fprintf(stderr, "resolve target %s for %p local %d frame %d\n",
|
||||||
buffer, el.value, el.localIndex, frameIndex(c, &el));
|
buffer, el.value, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2258,11 +2040,11 @@ setSites(Context* c, Event* e, Site** sites)
|
|||||||
} else if (DebugControl) {
|
} else if (DebugControl) {
|
||||||
char buffer[256]; sitesToString(c, sites[el.localIndex], buffer, 256);
|
char buffer[256]; sitesToString(c, sites[el.localIndex], buffer, 256);
|
||||||
fprintf(stderr, "skip sites %s for %p local %d frame %d\n",
|
fprintf(stderr, "skip sites %s for %p local %d frame %d\n",
|
||||||
buffer, el.value, el.localIndex, frameIndex(c, &el));
|
buffer, el.value, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
} else if (DebugControl) {
|
} else if (DebugControl) {
|
||||||
fprintf(stderr, "no sites for %p local %d frame %d\n",
|
fprintf(stderr, "no sites for %p local %d frame %d\n",
|
||||||
el.value, el.localIndex, frameIndex(c, &el));
|
el.value, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,21 +13,16 @@
|
|||||||
|
|
||||||
#include "codegen/compiler/context.h"
|
#include "codegen/compiler/context.h"
|
||||||
#include "codegen/compiler/event.h"
|
#include "codegen/compiler/event.h"
|
||||||
#include "codegen/compiler/stack.h"
|
|
||||||
#include "codegen/compiler/site.h"
|
#include "codegen/compiler/site.h"
|
||||||
#include "codegen/compiler/read.h"
|
#include "codegen/compiler/read.h"
|
||||||
#include "codegen/compiler/value.h"
|
#include "codegen/compiler/value.h"
|
||||||
#include "codegen/compiler/promise.h"
|
#include "codegen/compiler/promise.h"
|
||||||
|
#include "codegen/compiler/frame.h"
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
namespace compiler {
|
namespace compiler {
|
||||||
|
|
||||||
|
|
||||||
unsigned frameBase(Context* c);
|
|
||||||
unsigned totalFrameSize(Context* c);
|
|
||||||
int frameIndex(Context* c, int localIndex);
|
|
||||||
|
|
||||||
SiteMask generalRegisterMask(Context* c);
|
SiteMask generalRegisterMask(Context* c);
|
||||||
SiteMask generalRegisterOrConstantMask(Context* c);
|
SiteMask generalRegisterOrConstantMask(Context* c);
|
||||||
|
|
||||||
@ -1409,6 +1404,96 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clean(Context* c, Value* v, unsigned popIndex) {
|
||||||
|
for (SiteIterator it(c, v); it.hasMore();) {
|
||||||
|
Site* s = it.next();
|
||||||
|
if (not (s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))
|
||||||
|
and offsetToFrameIndex
|
||||||
|
(c, static_cast<MemorySite*>(s)->offset)
|
||||||
|
>= popIndex))
|
||||||
|
{
|
||||||
|
if (false and
|
||||||
|
s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)))
|
||||||
|
{
|
||||||
|
char buffer[256]; s->toString(c, buffer, 256);
|
||||||
|
fprintf(stderr, "remove %s from %p at %d pop offset 0x%x\n",
|
||||||
|
buffer, v, offsetToFrameIndex
|
||||||
|
(c, static_cast<MemorySite*>(s)->offset),
|
||||||
|
frameIndexToOffset(c, popIndex));
|
||||||
|
}
|
||||||
|
it.remove(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads,
|
||||||
|
unsigned popIndex)
|
||||||
|
{
|
||||||
|
for (FrameIterator it(c, stack, locals); it.hasMore();) {
|
||||||
|
FrameIterator::Element e = it.next(c);
|
||||||
|
clean(c, e.value, popIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
|
popRead(c, e, r->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JumpEvent: public Event {
|
||||||
|
public:
|
||||||
|
JumpEvent(Context* c, lir::UnaryOperation type, Value* address, bool exit,
|
||||||
|
bool cleanLocals):
|
||||||
|
Event(c), type(type), address(address), exit(exit),
|
||||||
|
cleanLocals(cleanLocals)
|
||||||
|
{
|
||||||
|
bool thunk;
|
||||||
|
uint8_t typeMask;
|
||||||
|
uint64_t registerMask;
|
||||||
|
c->arch->plan(type, vm::TargetBytesPerWord, &typeMask, ®isterMask, &thunk);
|
||||||
|
|
||||||
|
assert(c, not thunk);
|
||||||
|
|
||||||
|
this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* name() {
|
||||||
|
return "JumpEvent";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(Context* c) {
|
||||||
|
if (not this->isUnreachable()) {
|
||||||
|
apply(c, type, vm::TargetBytesPerWord, address->source, address->source);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
|
popRead(c, this, r->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleanLocals) {
|
||||||
|
for (FrameIterator it(c, 0, c->locals); it.hasMore();) {
|
||||||
|
FrameIterator::Element e = it.next(c);
|
||||||
|
clean(c, e.value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isBranch() { return true; }
|
||||||
|
|
||||||
|
virtual bool allExits() {
|
||||||
|
return exit or this->isUnreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
lir::UnaryOperation type;
|
||||||
|
Value* address;
|
||||||
|
bool exit;
|
||||||
|
bool cleanLocals;
|
||||||
|
};
|
||||||
|
|
||||||
|
void appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit, bool cleanLocals) {
|
||||||
|
append(c, new(c->zone) JumpEvent(c, type, address, exit, cleanLocals));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
@ -143,6 +143,10 @@ void
|
|||||||
appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first,
|
appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first,
|
||||||
Value* second, Value* address);
|
Value* second, Value* address);
|
||||||
|
|
||||||
|
void
|
||||||
|
appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false,
|
||||||
|
bool cleanLocals = false);
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
119
src/codegen/compiler/frame.cpp
Normal file
119
src/codegen/compiler/frame.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
#include "codegen/compiler/context.h"
|
||||||
|
#include "codegen/compiler/frame.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
unsigned totalFrameSize(Context* c) {
|
||||||
|
return c->alignedFrameSize
|
||||||
|
+ c->arch->frameHeaderSize()
|
||||||
|
+ c->arch->argumentFootprint(c->parameterFootprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
int frameIndex(Context* c, int localIndex) {
|
||||||
|
assert(c, localIndex >= 0);
|
||||||
|
|
||||||
|
int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1;
|
||||||
|
|
||||||
|
if (localIndex < static_cast<int>(c->parameterFootprint)) {
|
||||||
|
index += c->arch->frameHeaderSize();
|
||||||
|
} else {
|
||||||
|
index -= c->arch->frameFooterSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(c, index >= 0);
|
||||||
|
assert(c, static_cast<unsigned>(index) < totalFrameSize(c));
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned frameIndexToOffset(Context* c, unsigned frameIndex) {
|
||||||
|
assert(c, frameIndex < totalFrameSize(c));
|
||||||
|
|
||||||
|
return (frameIndex + c->arch->frameFooterSize()) * vm::TargetBytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned offsetToFrameIndex(Context* c, unsigned offset) {
|
||||||
|
assert(c, static_cast<int>
|
||||||
|
((offset / vm::TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0);
|
||||||
|
assert(c, ((offset / vm::TargetBytesPerWord) - c->arch->frameFooterSize())
|
||||||
|
< totalFrameSize(c));
|
||||||
|
|
||||||
|
return (offset / vm::TargetBytesPerWord) - c->arch->frameFooterSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned frameBase(Context* c) {
|
||||||
|
return c->alignedFrameSize
|
||||||
|
- c->arch->frameReturnAddressSize()
|
||||||
|
- c->arch->frameFooterSize()
|
||||||
|
+ c->arch->frameHeaderSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameIterator::Element::Element(Value* value, unsigned localIndex):
|
||||||
|
value(value), localIndex(localIndex)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
int FrameIterator::Element::frameIndex(Context* c) {
|
||||||
|
return compiler::frameIndex(c, this->localIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameIterator::FrameIterator(Context* c, Stack* stack, Local* locals,
|
||||||
|
bool includeEmpty):
|
||||||
|
stack(stack), locals(locals), localIndex(c->localFootprint - 1),
|
||||||
|
includeEmpty(includeEmpty)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool FrameIterator::hasMore() {
|
||||||
|
if (not includeEmpty) {
|
||||||
|
while (stack and stack->value == 0) {
|
||||||
|
stack = stack->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (localIndex >= 0 and locals[localIndex].value == 0) {
|
||||||
|
-- localIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack != 0 or localIndex >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameIterator::Element FrameIterator::next(Context* c) {
|
||||||
|
Value* v;
|
||||||
|
unsigned li;
|
||||||
|
if (stack) {
|
||||||
|
Stack* s = stack;
|
||||||
|
v = s->value;
|
||||||
|
li = s->index + c->localFootprint;
|
||||||
|
stack = stack->next;
|
||||||
|
} else {
|
||||||
|
Local* l = locals + localIndex;
|
||||||
|
v = l->value;
|
||||||
|
li = localIndex;
|
||||||
|
-- localIndex;
|
||||||
|
}
|
||||||
|
return Element(v, li);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stack* stack(Context* c, Value* value, Stack* next) {
|
||||||
|
return new(c->zone) Stack(next ? next->index + 1 : 0, value, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
75
src/codegen/compiler/frame.h
Normal file
75
src/codegen/compiler/frame.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_COMPILER_FRAME_H
|
||||||
|
#define AVIAN_CODEGEN_COMPILER_FRAME_H
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
unsigned totalFrameSize(Context* c);
|
||||||
|
|
||||||
|
int frameIndex(Context* c, int localIndex);
|
||||||
|
|
||||||
|
unsigned frameIndexToOffset(Context* c, unsigned frameIndex);
|
||||||
|
|
||||||
|
unsigned offsetToFrameIndex(Context* c, unsigned offset);
|
||||||
|
|
||||||
|
unsigned frameBase(Context* c);
|
||||||
|
|
||||||
|
class FrameIterator {
|
||||||
|
public:
|
||||||
|
class Element {
|
||||||
|
public:
|
||||||
|
Element(Value* value, unsigned localIndex);
|
||||||
|
|
||||||
|
int frameIndex(Context* c);
|
||||||
|
|
||||||
|
Value* const value;
|
||||||
|
const unsigned localIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
FrameIterator(Context* c, Stack* stack, Local* locals,
|
||||||
|
bool includeEmpty = false);
|
||||||
|
|
||||||
|
bool hasMore();
|
||||||
|
|
||||||
|
Element next(Context* c);
|
||||||
|
|
||||||
|
Stack* stack;
|
||||||
|
Local* locals;
|
||||||
|
int localIndex;
|
||||||
|
bool includeEmpty;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Local {
|
||||||
|
public:
|
||||||
|
Value* value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Stack {
|
||||||
|
public:
|
||||||
|
Stack(unsigned index, Value* value, Stack* next):
|
||||||
|
index(index), value(value), next(next)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
unsigned index;
|
||||||
|
Value* value;
|
||||||
|
Stack* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
Stack* stack(Context* c, Value* value, Stack* next);
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_COMPILER_FRAME_H
|
@ -1,35 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2012, Avian Contributors
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
|
||||||
for any purpose with or without fee is hereby granted, provided
|
|
||||||
that the above copyright notice and this permission notice appear
|
|
||||||
in all copies.
|
|
||||||
|
|
||||||
There is NO WARRANTY for this software. See license.txt for
|
|
||||||
details. */
|
|
||||||
|
|
||||||
#ifndef AVIAN_CODEGEN_COMPILER_STACK_H
|
|
||||||
#define AVIAN_CODEGEN_COMPILER_STACK_H
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace compiler {
|
|
||||||
|
|
||||||
class Value;
|
|
||||||
|
|
||||||
class Stack {
|
|
||||||
public:
|
|
||||||
Stack(unsigned index, Value* value, Stack* next):
|
|
||||||
index(index), value(value), next(next)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
unsigned index;
|
|
||||||
Value* value;
|
|
||||||
Stack* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_COMPILER_STACK_H
|
|
Loading…
Reference in New Issue
Block a user