mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +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 unsigned OperandTypeCount = MemoryOperand + 1;
|
||||||
|
|
||||||
const int NoRegister = -1;
|
const int NoRegister = -1;
|
||||||
const int AnyRegister = -2;
|
|
||||||
|
|
||||||
class Promise {
|
class Promise {
|
||||||
public:
|
public:
|
||||||
|
@ -342,7 +342,7 @@ alignedFrameSize(MyThread* t, object method)
|
|||||||
- methodParameterFootprint(t, method)
|
- methodParameterFootprint(t, method)
|
||||||
+ codeMaxStack(t, methodCode(t, method))
|
+ codeMaxStack(t, methodCode(t, method))
|
||||||
+ MaxNativeCallFootprint
|
+ MaxNativeCallFootprint
|
||||||
- t->arch->argumentRegisterCount());
|
- min(MaxNativeCallFootprint, t->arch->argumentRegisterCount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
|
145
src/compiler.cpp
145
src/compiler.cpp
@ -28,6 +28,7 @@ class Value;
|
|||||||
class Stack;
|
class Stack;
|
||||||
class Site;
|
class Site;
|
||||||
class RegisterSite;
|
class RegisterSite;
|
||||||
|
class MemorySite;
|
||||||
class Event;
|
class Event;
|
||||||
class PushEvent;
|
class PushEvent;
|
||||||
class Read;
|
class Read;
|
||||||
@ -158,7 +159,7 @@ class Register {
|
|||||||
public:
|
public:
|
||||||
Register(int number):
|
Register(int number):
|
||||||
value(0), site(0), number(number), size(0), refCount(0),
|
value(0), site(0), number(number), size(0), refCount(0),
|
||||||
freezeCount(0), reserved(false), pushed(false)
|
freezeCount(0), reserved(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -168,7 +169,14 @@ class Register {
|
|||||||
unsigned refCount;
|
unsigned refCount;
|
||||||
unsigned freezeCount;
|
unsigned freezeCount;
|
||||||
bool reserved;
|
bool reserved;
|
||||||
bool pushed;
|
};
|
||||||
|
|
||||||
|
class FrameResource {
|
||||||
|
public:
|
||||||
|
Value* value;
|
||||||
|
MemorySite* site;
|
||||||
|
unsigned size;
|
||||||
|
unsigned freezeCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConstantPoolNode {
|
class ConstantPoolNode {
|
||||||
@ -256,6 +264,7 @@ class Context {
|
|||||||
registers
|
registers
|
||||||
(static_cast<Register**>
|
(static_cast<Register**>
|
||||||
(zone->allocate(sizeof(Register*) * arch->registerCount()))),
|
(zone->allocate(sizeof(Register*) * arch->registerCount()))),
|
||||||
|
frameResources(0),
|
||||||
firstConstant(0),
|
firstConstant(0),
|
||||||
lastConstant(0),
|
lastConstant(0),
|
||||||
machineCode(0),
|
machineCode(0),
|
||||||
@ -293,6 +302,7 @@ class Context {
|
|||||||
Event* predecessor;
|
Event* predecessor;
|
||||||
LogicalInstruction** logicalCode;
|
LogicalInstruction** logicalCode;
|
||||||
Register** registers;
|
Register** registers;
|
||||||
|
FrameResource* frameResources;
|
||||||
ConstantPoolNode* firstConstant;
|
ConstantPoolNode* firstConstant;
|
||||||
ConstantPoolNode* lastConstant;
|
ConstantPoolNode* lastConstant;
|
||||||
uint8_t* machineCode;
|
uint8_t* machineCode;
|
||||||
@ -508,27 +518,52 @@ class Event {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
localOffset(Context* c, int v)
|
localOffset(Context* c, int frameIndex)
|
||||||
{
|
{
|
||||||
int parameterFootprint = c->parameterFootprint;
|
int parameterFootprint = c->parameterFootprint;
|
||||||
int frameSize = c->alignedFrameSize;
|
int frameSize = c->alignedFrameSize;
|
||||||
|
|
||||||
int offset = ((v < parameterFootprint) ?
|
int offset = ((frameIndex < parameterFootprint) ?
|
||||||
(frameSize
|
(frameSize
|
||||||
+ parameterFootprint
|
+ parameterFootprint
|
||||||
+ (c->arch->frameFooterSize() * 2)
|
+ (c->arch->frameFooterSize() * 2)
|
||||||
+ c->arch->frameHeaderSize()
|
+ c->arch->frameHeaderSize()
|
||||||
- v - 1) :
|
- frameIndex - 1) :
|
||||||
(frameSize
|
(frameSize
|
||||||
+ parameterFootprint
|
+ parameterFootprint
|
||||||
+ c->arch->frameFooterSize()
|
+ c->arch->frameFooterSize()
|
||||||
- v - 1)) * BytesPerWord;
|
- frameIndex - 1)) * BytesPerWord;
|
||||||
|
|
||||||
assert(c, offset >= 0);
|
assert(c, offset >= 0);
|
||||||
|
|
||||||
return offset;
|
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
|
bool
|
||||||
findSite(Context*, Value* v, Site* site)
|
findSite(Context*, Value* v, Site* site)
|
||||||
{
|
{
|
||||||
@ -872,6 +907,14 @@ decrement(Context* c UNUSED, Register* r)
|
|||||||
-- r->refCount;
|
-- 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 {
|
class MemorySite: public Site {
|
||||||
public:
|
public:
|
||||||
MemorySite(int base, int offset, int index, unsigned scale):
|
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);
|
base = increment(c, value.base);
|
||||||
if (value.index != NoRegister) {
|
if (value.index != NoRegister) {
|
||||||
index = increment(c, value.index);
|
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) {
|
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);
|
decrement(c, base);
|
||||||
if (index) {
|
if (index) {
|
||||||
decrement(c, index);
|
decrement(c, index);
|
||||||
@ -1014,6 +1071,7 @@ allocateSite(Context* c, uint8_t typeMask, uint64_t registerMask,
|
|||||||
} else if (frameIndex >= 0) {
|
} else if (frameIndex >= 0) {
|
||||||
return frameSite(c, frameIndex);
|
return frameSite(c, frameIndex);
|
||||||
} else {
|
} else {
|
||||||
|
fprintf(stderr, "type mask %02x reg mask %016lx frame index %d\n", typeMask, registerMask, frameIndex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1066,6 +1124,7 @@ Read*
|
|||||||
read(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
|
read(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
|
||||||
int frameIndex)
|
int frameIndex)
|
||||||
{
|
{
|
||||||
|
assert(c, (typeMask != 1 << MemoryOperand) or frameIndex >= 0);
|
||||||
return new (c->zone->allocate(sizeof(SingleRead)))
|
return new (c->zone->allocate(sizeof(SingleRead)))
|
||||||
SingleRead(size, typeMask, registerMask, frameIndex);
|
SingleRead(size, typeMask, registerMask, frameIndex);
|
||||||
}
|
}
|
||||||
@ -1535,6 +1594,70 @@ validate(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
|||||||
return r;
|
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
|
void
|
||||||
apply(Context* c, UnaryOperation op,
|
apply(Context* c, UnaryOperation op,
|
||||||
unsigned s1Size, Site* s1)
|
unsigned s1Size, Site* s1)
|
||||||
@ -3018,6 +3141,14 @@ class MyCompiler: public Compiler {
|
|||||||
c.localFootprint = localFootprint;
|
c.localFootprint = localFootprint;
|
||||||
c.alignedFrameSize = alignedFrameSize;
|
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.logicalCode = static_cast<LogicalInstruction**>
|
||||||
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
|
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
|
||||||
memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength);
|
memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength);
|
||||||
|
Loading…
Reference in New Issue
Block a user