move JumpEvent out of compiler.cpp

This commit is contained in:
Joshua Warner 2013-02-13 21:34:59 -07:00
parent 65b7cf047c
commit d00950458f
7 changed files with 297 additions and 266 deletions

View File

@ -961,6 +961,7 @@ ifeq ($(process),compile)
$(src)/codegen/compiler/read.cpp \
$(src)/codegen/compiler/event.cpp \
$(src)/codegen/compiler/promise.cpp \
$(src)/codegen/compiler/frame.cpp \
$(src)/codegen/registers.cpp \
$(src)/codegen/targets.cpp

View File

@ -22,8 +22,8 @@
#include "codegen/compiler/site.h"
#include "codegen/compiler/read.h"
#include "codegen/compiler/event.h"
#include "codegen/compiler/stack.h"
#include "codegen/compiler/promise.h"
#include "codegen/compiler/frame.h"
using namespace vm;
@ -67,11 +67,6 @@ apply(Context* c, lir::TernaryOperation op,
unsigned s2Size, Site* s2Low, Site* s2High,
unsigned s3Size, Site* s3Low, Site* s3High);
class Local {
public:
Value* value;
};
class ForkElement {
public:
Value* value;
@ -220,118 +215,6 @@ countSuccessors(Link* link)
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
clearSites(Context* c, Value* v)
{
@ -1021,44 +904,6 @@ apply(Context* c, lir::TernaryOperation op,
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
append(Context* c, Event* e);
@ -1366,12 +1211,6 @@ makeSnapshots(Context* c, Value* value, Snapshot* next)
return next;
}
Stack*
stack(Context* c, Value* value, Stack* next)
{
return new(c->zone) Stack(next ? next->index + 1 : 0, value, next);
}
Value*
maybeBuddy(Context* c, Value* v);
@ -1586,63 +1425,6 @@ register_(Context* c, int number)
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, &registerMask, &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 {
public:
BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset,
@ -2053,7 +1835,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
char buffer[256];
s->toString(c, buffer, 256);
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
@ -2068,7 +1850,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
char buffer[256];
s->toString(c, buffer, 256);
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);
@ -2101,7 +1883,7 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
if (DebugControl) {
char buffer[256]; s->toString(c, buffer, 256);
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);
@ -2142,7 +1924,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
if (DebugControl) {
char buffer[256]; sites[el.localIndex]->toString(c, buffer, 256);
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) {
char buffer[256]; sitesToString(c, sites[el.localIndex], buffer, 256);
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) {
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));
}
}
}

View File

@ -13,21 +13,16 @@
#include "codegen/compiler/context.h"
#include "codegen/compiler/event.h"
#include "codegen/compiler/stack.h"
#include "codegen/compiler/site.h"
#include "codegen/compiler/read.h"
#include "codegen/compiler/value.h"
#include "codegen/compiler/promise.h"
#include "codegen/compiler/frame.h"
namespace avian {
namespace codegen {
namespace compiler {
unsigned frameBase(Context* c);
unsigned totalFrameSize(Context* c);
int frameIndex(Context* c, int localIndex);
SiteMask generalRegisterMask(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, &registerMask, &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 codegen
} // namespace avian

View File

@ -143,6 +143,10 @@ void
appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first,
Value* second, Value* address);
void
appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false,
bool cleanLocals = false);
} // namespace compiler
} // namespace codegen
} // namespace avian

View 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

View 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

View File

@ -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