mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
ensure that only one value holds a given frame site at at time
This commit is contained in:
parent
61c708d7b2
commit
d409f89d5d
@ -75,7 +75,6 @@ enum OperandType {
|
||||
const unsigned OperandTypeCount = MemoryOperand + 1;
|
||||
|
||||
const int NoRegister = -1;
|
||||
const int AnyRegister = -2;
|
||||
|
||||
class Promise {
|
||||
public:
|
||||
|
@ -342,7 +342,7 @@ alignedFrameSize(MyThread* t, object method)
|
||||
- methodParameterFootprint(t, method)
|
||||
+ codeMaxStack(t, methodCode(t, method))
|
||||
+ MaxNativeCallFootprint
|
||||
- t->arch->argumentRegisterCount());
|
||||
- min(MaxNativeCallFootprint, t->arch->argumentRegisterCount()));
|
||||
}
|
||||
|
||||
unsigned
|
||||
|
145
src/compiler.cpp
145
src/compiler.cpp
@ -28,6 +28,7 @@ class Value;
|
||||
class Stack;
|
||||
class Site;
|
||||
class RegisterSite;
|
||||
class MemorySite;
|
||||
class Event;
|
||||
class PushEvent;
|
||||
class Read;
|
||||
@ -158,7 +159,7 @@ class Register {
|
||||
public:
|
||||
Register(int number):
|
||||
value(0), site(0), number(number), size(0), refCount(0),
|
||||
freezeCount(0), reserved(false), pushed(false)
|
||||
freezeCount(0), reserved(false)
|
||||
{ }
|
||||
|
||||
Value* value;
|
||||
@ -168,7 +169,14 @@ class Register {
|
||||
unsigned refCount;
|
||||
unsigned freezeCount;
|
||||
bool reserved;
|
||||
bool pushed;
|
||||
};
|
||||
|
||||
class FrameResource {
|
||||
public:
|
||||
Value* value;
|
||||
MemorySite* site;
|
||||
unsigned size;
|
||||
unsigned freezeCount;
|
||||
};
|
||||
|
||||
class ConstantPoolNode {
|
||||
@ -256,6 +264,7 @@ class Context {
|
||||
registers
|
||||
(static_cast<Register**>
|
||||
(zone->allocate(sizeof(Register*) * arch->registerCount()))),
|
||||
frameResources(0),
|
||||
firstConstant(0),
|
||||
lastConstant(0),
|
||||
machineCode(0),
|
||||
@ -293,6 +302,7 @@ class Context {
|
||||
Event* predecessor;
|
||||
LogicalInstruction** logicalCode;
|
||||
Register** registers;
|
||||
FrameResource* frameResources;
|
||||
ConstantPoolNode* firstConstant;
|
||||
ConstantPoolNode* lastConstant;
|
||||
uint8_t* machineCode;
|
||||
@ -508,27 +518,52 @@ class Event {
|
||||
};
|
||||
|
||||
int
|
||||
localOffset(Context* c, int v)
|
||||
localOffset(Context* c, int frameIndex)
|
||||
{
|
||||
int parameterFootprint = c->parameterFootprint;
|
||||
int frameSize = c->alignedFrameSize;
|
||||
|
||||
int offset = ((v < parameterFootprint) ?
|
||||
int offset = ((frameIndex < parameterFootprint) ?
|
||||
(frameSize
|
||||
+ parameterFootprint
|
||||
+ (c->arch->frameFooterSize() * 2)
|
||||
+ c->arch->frameHeaderSize()
|
||||
- v - 1) :
|
||||
- frameIndex - 1) :
|
||||
(frameSize
|
||||
+ parameterFootprint
|
||||
+ c->arch->frameFooterSize()
|
||||
- v - 1)) * BytesPerWord;
|
||||
- frameIndex - 1)) * BytesPerWord;
|
||||
|
||||
assert(c, offset >= 0);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
int
|
||||
localOffsetToFrameIndex(Context* c, int offset)
|
||||
{
|
||||
int parameterFootprint = c->parameterFootprint;
|
||||
int frameSize = c->alignedFrameSize;
|
||||
|
||||
int normalizedOffset = offset / BytesPerWord;
|
||||
|
||||
int frameIndex = ((normalizedOffset > frameSize) ?
|
||||
(frameSize
|
||||
+ parameterFootprint
|
||||
+ (c->arch->frameFooterSize() * 2)
|
||||
+ c->arch->frameHeaderSize()
|
||||
- normalizedOffset - 1) :
|
||||
(frameSize
|
||||
+ parameterFootprint
|
||||
+ c->arch->frameFooterSize()
|
||||
- normalizedOffset - 1));
|
||||
|
||||
assert(c, frameIndex >= 0);
|
||||
assert(c, localOffset(c, frameIndex) == offset);
|
||||
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
bool
|
||||
findSite(Context*, Value* v, Site* site)
|
||||
{
|
||||
@ -872,6 +907,14 @@ decrement(Context* c UNUSED, Register* r)
|
||||
-- r->refCount;
|
||||
}
|
||||
|
||||
void
|
||||
acquireFrameIndex(Context* c, int index, Stack* stack, Local* locals,
|
||||
unsigned newSize, Value* newValue, MemorySite* newSite,
|
||||
bool recurse = true);
|
||||
|
||||
void
|
||||
releaseFrameIndex(Context* c, int index, bool recurse = true);
|
||||
|
||||
class MemorySite: public Site {
|
||||
public:
|
||||
MemorySite(int base, int offset, int index, unsigned scale):
|
||||
@ -918,14 +961,28 @@ class MemorySite: public Site {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void acquire(Context* c, Stack*, Local*, unsigned, Value*) {
|
||||
virtual void acquire(Context* c, Stack* stack, Local* locals, unsigned size,
|
||||
Value* v)
|
||||
{
|
||||
base = increment(c, value.base);
|
||||
if (value.index != NoRegister) {
|
||||
index = increment(c, value.index);
|
||||
}
|
||||
|
||||
if (value.base == c->arch->stack()) {
|
||||
assert(c, value.index == NoRegister);
|
||||
acquireFrameIndex
|
||||
(c, localOffsetToFrameIndex(c, value.offset), stack, locals, size, v,
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void release(Context* c) {
|
||||
if (value.base == c->arch->stack()) {
|
||||
assert(c, value.index == NoRegister);
|
||||
releaseFrameIndex(c, localOffsetToFrameIndex(c, value.offset));
|
||||
}
|
||||
|
||||
decrement(c, base);
|
||||
if (index) {
|
||||
decrement(c, index);
|
||||
@ -1014,6 +1071,7 @@ allocateSite(Context* c, uint8_t typeMask, uint64_t registerMask,
|
||||
} else if (frameIndex >= 0) {
|
||||
return frameSite(c, frameIndex);
|
||||
} else {
|
||||
fprintf(stderr, "type mask %02x reg mask %016lx frame index %d\n", typeMask, registerMask, frameIndex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1066,6 +1124,7 @@ Read*
|
||||
read(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
|
||||
int frameIndex)
|
||||
{
|
||||
assert(c, (typeMask != 1 << MemoryOperand) or frameIndex >= 0);
|
||||
return new (c->zone->allocate(sizeof(SingleRead)))
|
||||
SingleRead(size, typeMask, registerMask, frameIndex);
|
||||
}
|
||||
@ -1535,6 +1594,70 @@ validate(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
||||
return r;
|
||||
}
|
||||
|
||||
bool
|
||||
trySteal(Context* c, FrameResource* r, Stack*, Local*)
|
||||
{
|
||||
Value* v = r->value;
|
||||
assert(c, v->reads);
|
||||
|
||||
if (v->sites->next == 0) {
|
||||
return false; // todo
|
||||
}
|
||||
|
||||
removeSite(c, v, r->site);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
acquireFrameIndex(Context* c, int index, Stack* stack, Local* locals,
|
||||
unsigned newSize, Value* newValue, MemorySite* newSite,
|
||||
bool recurse)
|
||||
{
|
||||
assert(c, index >= 0);
|
||||
assert(c, index < static_cast<int>
|
||||
(c->alignedFrameSize + c->parameterFootprint));
|
||||
|
||||
FrameResource* r = c->frameResources + index;
|
||||
|
||||
if (recurse and newSize > BytesPerWord) {
|
||||
acquireFrameIndex
|
||||
(c, index + 1, stack, locals, newSize, newValue, newSite, false);
|
||||
}
|
||||
|
||||
Value* oldValue = r->value;
|
||||
if (oldValue
|
||||
and oldValue != newValue
|
||||
and findSite(c, oldValue, r->site))
|
||||
{
|
||||
if (not trySteal(c, r, stack, locals)) {
|
||||
abort(c);
|
||||
}
|
||||
}
|
||||
|
||||
r->size = newSize;
|
||||
r->value = newValue;
|
||||
r->site = 0;
|
||||
}
|
||||
|
||||
void
|
||||
releaseFrameIndex(Context* c, int index, bool recurse)
|
||||
{
|
||||
assert(c, index >= 0);
|
||||
assert(c, index < static_cast<int>
|
||||
(c->alignedFrameSize + c->parameterFootprint));
|
||||
|
||||
FrameResource* r = c->frameResources + index;
|
||||
|
||||
if (recurse and r->size > BytesPerWord) {
|
||||
releaseFrameIndex(c, index + 1, false);
|
||||
}
|
||||
|
||||
r->size = 0;
|
||||
r->value = 0;
|
||||
r->site = 0;
|
||||
}
|
||||
|
||||
void
|
||||
apply(Context* c, UnaryOperation op,
|
||||
unsigned s1Size, Site* s1)
|
||||
@ -3018,6 +3141,14 @@ class MyCompiler: public Compiler {
|
||||
c.localFootprint = localFootprint;
|
||||
c.alignedFrameSize = alignedFrameSize;
|
||||
|
||||
unsigned frameResourceSize = sizeof(FrameResource)
|
||||
* (alignedFrameSize + parameterFootprint);
|
||||
|
||||
c.frameResources = static_cast<FrameResource*>
|
||||
(c.zone->allocate(frameResourceSize));
|
||||
|
||||
memset(c.frameResources, 0, frameResourceSize);
|
||||
|
||||
c.logicalCode = static_cast<LogicalInstruction**>
|
||||
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
|
||||
memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength);
|
||||
|
Loading…
Reference in New Issue
Block a user