add SingleRead::successor; fix build errors

The SingleRead::successor field is used (when non-null) to further
constrain the SiteMask in SingleRead::intersect based on reads of
successor values (as in the cases of moves and condensed-addressing
combine and translate instructions).
This commit is contained in:
Joel Dice 2009-04-06 18:34:12 -06:00
parent fea92ed995
commit 35d1c6e068
7 changed files with 209 additions and 86 deletions

View File

@ -44,13 +44,19 @@ class BootImage {
uintptr_t codeBase;
unsigned defaultThunk;
unsigned defaultTailThunk;
unsigned defaultVirtualThunk;
unsigned tailHelperThunk;
unsigned nativeThunk;
unsigned nativeTailThunk;
unsigned aioobThunk;
unsigned thunkTable;
unsigned thunkSize;
unsigned compileMethodCall;
unsigned compileVirtualMethodCall;
unsigned tailCallCall;
unsigned invokeNativeCall;
unsigned throwArrayIndexOutOfBoundsCall;

View File

@ -76,6 +76,9 @@ class MyThread: public Thread {
ip(0),
base(0),
stack(0),
tailAddress(0),
virtualCallClass(0),
virtualCallIndex(0),
trace(0),
reference(0),
arch(parent ? parent->arch : makeArchitecture(m->system))
@ -86,6 +89,9 @@ class MyThread: public Thread {
void* ip;
void* base;
void* stack;
void* tailAddress;
void* virtualCallClass;
uintptr_t virtualCallIndex;
CallTrace* trace;
Reference* reference;
Assembler::Architecture* arch;
@ -441,8 +447,8 @@ class Context;
class TraceElement: public TraceHandler {
public:
const unsigned VirtualCall = 1 << 0;
const unsigned TailCall = 1 << 1;
static const unsigned VirtualCall = 1 << 0;
static const unsigned TailCall = 1 << 1;
TraceElement(Context* context, object target,
unsigned flags, TraceElement* next):
@ -477,7 +483,7 @@ class TraceElement: public TraceHandler {
class TraceElementPromise: public Promise {
public:
TraceElementPromise(TraceElement* trace): trace(trace) { }
TraceElementPromise(System* s, TraceElement* trace): s(s), trace(trace) { }
virtual int64_t value() {
assert(s, resolved());
@ -1352,12 +1358,24 @@ objectPools(MyThread* t);
uintptr_t
defaultThunk(MyThread* t);
uintptr_t
defaultTailThunk(MyThread* t);
uintptr_t
nativeThunk(MyThread* t);
uintptr_t
nativeTailThunk(MyThread* t);
uintptr_t
tailHelperThunk(MyThread* t);
uintptr_t
aioobThunk(MyThread* t);
uintptr_t
virtualThunk(MyThread* t, unsigned index);
uintptr_t
methodAddress(Thread* t, object method)
{
@ -1378,6 +1396,10 @@ tryInitClass(MyThread* t, object class_)
FixedAllocator*
codeAllocator(MyThread* t);
void
compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
object method);
int64_t
findInterfaceMethodFromInstance(MyThread* t, object method, object instance)
{
@ -1916,6 +1938,8 @@ Compiler::Operand*
compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
bool useThunk, unsigned rSize, Promise* addressPromise)
{
Compiler* c = frame->c;
if (tailCall and methodParameterFootprint(t, target)
> methodParameterFootprint(t, frame->context->method))
{
@ -1930,7 +1954,6 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
(c->constant(nativeTailThunk(t)),
Compiler::TailCall,
frame->trace(target, TraceElement::TailCall),
trace,
rSize,
methodParameterFootprint(t, target));
} else {
@ -1956,11 +1979,11 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
return result;
} else {
return c->stackCall
(address,
flags | Compiler::Aligned,
frame->trace(target, 0),
rSize,
methodParameterFootprint(t, target));
(c->constant(defaultThunk(t)),
flags | Compiler::Aligned,
frame->trace(target, 0),
rSize,
methodParameterFootprint(t, target));
}
} else {
Compiler::Operand* address =
@ -1969,10 +1992,10 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
: c->constant(methodAddress(t, target)));
return c->stackCall
(c->promiseConstant(p),
(address,
flags,
tailCall ? 0 : frame->trace
((methodFlags(t, target) & ACC_NATIVE) ? target, 0),
((methodFlags(t, target) & ACC_NATIVE) ? target : 0, 0),
rSize,
methodParameterFootprint(t, target));
}
@ -1982,8 +2005,6 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
void
compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall)
{
Compiler* c = frame->c;
unsigned rSize = resultSize(t, methodReturnCode(t, target));
Compiler::Operand* result = 0;
@ -2043,7 +2064,7 @@ handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function)
0,
frame->trace(0, 0),
0,
2, c->thread(), lock);
2, c->register_(t->arch->thread()), lock);
}
}
@ -2229,7 +2250,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
0,
1, c->thread());
1, c->register_(t->arch->thread()));
}
// fprintf(stderr, "ip: %d map: %ld\n", ip, *(frame->map));
@ -2329,7 +2350,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
0,
4, c->thread(), array,
4, c->register_(t->arch->thread()), array,
c->add(4, c->constant(ArrayBody),
c->shl(4, c->constant(log(BytesPerWord)), index)),
value);
@ -2397,7 +2418,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
BytesPerWord,
3, c->thread(), frame->append(class_), length));
3, c->register_(t->arch->thread()), frame->append(class_), length));
} break;
case areturn: {
@ -2439,7 +2460,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Compiler::NoReturn,
frame->trace(0, 0),
0,
2, c->thread(), target);
2, c->register_(t->arch->thread()), target);
} return;
case bipush:
@ -2460,7 +2481,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
0,
3, c->thread(), frame->append(class_), instance);
3, c->register_(t->arch->thread()), frame->append(class_), instance);
} break;
case d2f: {
@ -2741,7 +2762,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
0,
2, c->thread(), frame->append(fieldClass(t, field)));
2, c->register_(t->arch->thread()),
frame->append(fieldClass(t, field)));
}
table = frame->append(classStaticTable(t, fieldClass(t, field)));
@ -2766,7 +2788,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
c->call
(c->constant(getThunk(t, acquireMonitorForObjectThunk)),
0, frame->trace(0, 0), 0, 2, c->thread(), fieldOperand);
0, frame->trace(0, 0), 0, 2, c->register_(t->arch->thread()),
fieldOperand);
}
switch (fieldCode(t, field)) {
@ -2820,7 +2843,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
{
c->call
(c->constant(getThunk(t, releaseMonitorForObjectThunk)),
0, frame->trace(0, 0), 0, 2, c->thread(), fieldOperand);
0, frame->trace(0, 0), 0, 2, c->register_(t->arch->thread()),
fieldOperand);
} else {
c->loadBarrier();
}
@ -3094,7 +3118,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
(c->call
(c->constant(getThunk(t, instanceOf64Thunk)),
0, 0, 4,
3, c->thread(), frame->append(class_), frame->popObject()));
3, c->register_(t->arch->thread()), frame->append(class_),
frame->popObject()));
} break;
case invokeinterface: {
@ -3119,7 +3144,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
BytesPerWord,
3, c->thread(), frame->append(target),
3, c->register_(t->arch->thread()), frame->append(target),
c->peek(1, instance)),
0,
frame->trace(0, 0),
@ -3583,14 +3608,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Compiler::Operand* target = frame->popObject();
c->call
(c->constant(getThunk(t, acquireMonitorForObjectThunk)),
0, frame->trace(0, 0), 0, 2, c->thread(), target);
0, frame->trace(0, 0), 0, 2, c->register_(t->arch->thread()), target);
} break;
case monitorexit: {
Compiler::Operand* target = frame->popObject();
c->call
(c->constant(getThunk(t, releaseMonitorForObjectThunk)),
0, frame->trace(0, 0), 0, 2, c->thread(), target);
0, frame->trace(0, 0), 0, 2, c->register_(t->arch->thread()), target);
} break;
case multianewarray: {
@ -3612,8 +3637,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
BytesPerWord,
4, c->thread(), frame->append(class_), c->constant(dimensions),
c->constant(offset));
4, c->register_(t->arch->thread()), frame->append(class_),
c->constant(dimensions), c->constant(offset));
frame->pop(dimensions);
frame->pushObject(result);
@ -3632,7 +3657,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
BytesPerWord,
2, c->thread(), frame->append(class_)));
2, c->register_(t->arch->thread()), frame->append(class_)));
} else {
frame->pushObject
(c->call
@ -3640,7 +3665,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
BytesPerWord,
2, c->thread(), frame->append(class_)));
2, c->register_(t->arch->thread()), frame->append(class_)));
}
} break;
@ -3655,7 +3680,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
BytesPerWord,
3, c->thread(), c->constant(type), length));
3, c->register_(t->arch->thread()), c->constant(type), length));
} break;
case nop: break;
@ -3688,7 +3713,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
0,
2, c->thread(), frame->append(fieldClass(t, field)));
2, c->register_(t->arch->thread()),
frame->append(fieldClass(t, field)));
}
staticTable = classStaticTable(t, fieldClass(t, field));
@ -3742,7 +3768,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
c->call
(c->constant(getThunk(t, acquireMonitorForObjectThunk)),
0, frame->trace(0, 0), 0, 2, c->thread(), fieldOperand);
0, frame->trace(0, 0), 0, 2, c->register_(t->arch->thread()),
fieldOperand);
} else {
c->storeStoreBarrier();
}
@ -3779,12 +3806,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0,
frame->trace(0, 0),
0,
4, c->thread(), table, c->constant(fieldOffset(t, field)), value);
4, c->register_(t->arch->thread()), table,
c->constant(fieldOffset(t, field)), value);
} else {
c->call
(c->constant(getThunk(t, setThunk)),
0, 0, 0,
4, c->thread(), table, c->constant(fieldOffset(t, field)), value);
4, c->register_(t->arch->thread()), table,
c->constant(fieldOffset(t, field)), value);
}
break;
@ -3798,7 +3827,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
{
c->call
(c->constant(getThunk(t, releaseMonitorForObjectThunk)),
0, frame->trace(0, 0), 0, 2, c->thread(), fieldOperand);
0, frame->trace(0, 0), 0, 2, c->register_(t->arch->thread()),
fieldOperand);
} else {
c->storeLoadBarrier();
}
@ -4562,12 +4592,8 @@ updateCall(MyThread* t, UnaryOperation op, bool assertAlignment,
t->arch->updateCall(op, assertAlignment, returnAddress, target);
}
void
compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
object method);
void*
compileMethod2(MyThread* t, uintptr_t ip)
compileMethod2(MyThread* t, void* ip)
{
object node = findCallNode(t, ip);
PROTECT(t, node);
@ -4583,12 +4609,12 @@ compileMethod2(MyThread* t, uintptr_t ip)
return 0;
} else {
void* address = reinterpret_cast<void*>(methodAddress(t, target));
uintptr_t updateIp = ip;
if (callNode(t, node) & TraceElement::TailCall) {
uint8_t* updateIp = static_cast<uint8_t*>(ip);
if (callNodeFlags(t, node) & TraceElement::TailCall) {
updateIp -= t->arch->constantCallSize();
}
updateCall(t, Call, true, reinterpret_cast<void*>(updateIp), address);
updateCall(t, Call, true, updateIp, address);
return address;
}
@ -4597,7 +4623,7 @@ compileMethod2(MyThread* t, uintptr_t ip)
uint64_t
compileMethod(MyThread* t)
{
uintptr_t ip;
void* ip;
if (t->tailAddress) {
ip = t->tailAddress;
t->tailAddress = 0;
@ -4629,7 +4655,7 @@ compileVirtualMethod2(MyThread* t, object class_, unsigned index)
return 0;
} else {
void* address = reinterpret_cast<void*>(methodAddress(t, target));
if (address != nativeThunk(t, method)) {
if (address != reinterpret_cast<void*>(nativeThunk(t))) {
classVtable(t, class_, methodOffset(t, target)) = address;
}
return address;
@ -4639,7 +4665,7 @@ compileVirtualMethod2(MyThread* t, object class_, unsigned index)
uint64_t
compileVirtualMethod(MyThread* t)
{
object class_ = t->virtualCallClass;
object class_ = static_cast<object>(t->virtualCallClass);
t->virtualCallClass = 0;
unsigned index = t->virtualCallIndex;
@ -4655,7 +4681,7 @@ compileVirtualMethod(MyThread* t)
}
void*
tailCall2(MyThread* t, uintptr_t ip)
tailCall2(MyThread* t, void* ip)
{
object node = findCallNode(t, ip);
PROTECT(t, node);
@ -4678,7 +4704,9 @@ tailCall2(MyThread* t, uintptr_t ip)
void* stack = t->stack;
t->arch->nextFrame(&stack, &base);
if (t->arch->matchCall(t->arch->frameIp(stack), tailHelperThunk(t))) {
if (t->arch->matchCall(t->arch->frameIp(stack),
reinterpret_cast<void*>(tailHelperThunk(t))))
{
void* nextBase = base;
void* nextStack = stack;
t->arch->nextFrame(&nextStack, &nextBase);
@ -4896,7 +4924,7 @@ uint64_t
invokeNative(MyThread* t)
{
if (t->trace->nativeMethod == 0) {
uintptr_t ip;
void* ip;
if (t->tailAddress) {
ip = t->tailAddress;
t->tailAddress = 0;
@ -5276,7 +5304,11 @@ class MyProcessor: public Processor {
s(s),
allocator(allocator),
defaultThunk(0),
defaultTailThunk(0),
defaultVirtualThunk(0),
tailHelperThunk(0),
nativeThunk(0),
nativeTailThunk(0),
aioobThunk(0),
callTable(0),
callTableSize(0),
@ -5346,7 +5378,8 @@ class MyProcessor: public Processor {
initVtable(Thread* t, object c)
{
for (unsigned i = 0; i < classLength(t, c); ++i) {
classVtable(t, c, i) = virtualThunk(static_cast<MyThread*>(t), i);
classVtable(t, c, i) = reinterpret_cast<void*>
(virtualThunk(static_cast<MyThread*>(t), i));
}
}
@ -5650,7 +5683,7 @@ class MyProcessor: public Processor {
table[index++] = callNodeAddress(t, p)
- reinterpret_cast<uintptr_t>(code);
table[index++] = w->map()->find(callNodeTarget(t, p))
| (static_cast<unsigned>(callNodeFlags(t, node)) << BootShift);
| (static_cast<unsigned>(callNodeFlags(t, p)) << BootShift);
}
}
@ -5658,7 +5691,8 @@ class MyProcessor: public Processor {
}
virtual void boot(Thread* t, BootImage* image) {
codeAllocator.base = s->tryAllocateExecutable(ExecutableAreaSizeInBytes);
codeAllocator.base = static_cast<uint8_t*>
(s->tryAllocateExecutable(ExecutableAreaSizeInBytes));
codeAllocator.capacity = ExecutableAreaSizeInBytes;
if (image) {
@ -5681,7 +5715,11 @@ class MyProcessor: public Processor {
System* s;
Allocator* allocator;
uint8_t* defaultThunk;
uint8_t* defaultTailThunk;
uint8_t* defaultVirtualThunk;
uint8_t* tailHelperThunk;
uint8_t* nativeThunk;
uint8_t* nativeTailThunk;
uint8_t* aioobThunk;
uint8_t* thunkTable;
unsigned thunkSize;
@ -5965,11 +6003,23 @@ fixupThunks(MyThread* t, BootImage* image, uint8_t* code)
MyProcessor* p = processor(t);
p->defaultThunk = code + image->defaultThunk;
p->defaultTailThunk = code + image->defaultTailThunk;
updateCall(t, LongCall, false, code + image->compileMethodCall,
voidPointer(::compileMethod));
p->defaultVirtualThunk = code + image->defaultVirtualThunk;
updateCall(t, LongCall, false, code + image->compileVirtualMethodCall,
voidPointer(::compileVirtualMethod));
p->tailHelperThunk = code + image->tailHelperThunk;
updateCall(t, LongCall, false, code + image->tailCallCall,
voidPointer(::tailCall));
p->nativeThunk = code + image->nativeThunk;
p->nativeTailThunk = code + image->nativeTailThunk;
updateCall(t, LongCall, false, code + image->invokeNativeCall,
voidPointer(invokeNative));
@ -6263,7 +6313,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
if (image) {
image->tailHelperThunk = p->tailHelperThunk - imageBase;
image->tailHelperCall = static_cast<uint8_t*>(call) - imageBase;
image->tailCallCall = static_cast<uint8_t*>(call) - imageBase;
}
}
@ -6344,12 +6394,36 @@ defaultThunk(MyThread* t)
return reinterpret_cast<uintptr_t>(processor(t)->defaultThunk);
}
uintptr_t
defaultTailThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->defaultTailThunk);
}
uintptr_t
defaultVirtualThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->defaultVirtualThunk);
}
uintptr_t
tailHelperThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->tailHelperThunk);
}
uintptr_t
nativeThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->nativeThunk);
}
uintptr_t
nativeTailThunk(MyThread* t)
{
return reinterpret_cast<uintptr_t>(processor(t)->nativeTailThunk);
}
uintptr_t
aioobThunk(MyThread* t)
{
@ -6359,18 +6433,22 @@ aioobThunk(MyThread* t)
uintptr_t
compileVirtualThunk(MyThread* t, unsigned index)
{
Context context;
Context context(t);
Assembler* a = context.assembler;
Assembler::Constant indexConstant(index);
ResolvedPromise indexPromise(index);
Assembler::Constant indexConstant(&indexPromise);
Assembler::Register indexRegister(t->arch->returnHigh());
a->apply(Move, BytesPerWord, ConstantOperand, &indexConstant,
BytesPerWord, ConstantOperand, &indexRegister);
Assembler::Constant thunk(defaultVirtualThunk(t));
ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t));
Assembler::Constant thunk(&defaultVirtualThunkPromise);
a->apply(Jump, BytesPerWord, ConstantOperand, &thunk);
uint8_t* start = codeAllocator(t)->allocate(a->length());
uint8_t* start = static_cast<uint8_t*>
(codeAllocator(t)->allocate(a->length()));
a->writeTo(start);
}

View File

@ -286,6 +286,13 @@ intersect(const SiteMask& a, const SiteMask& b)
intersectFrameIndexes(a.frameIndex, b.frameIndex));
}
bool
valid(const SiteMask& a)
{
return a.typeMask
and ((a.typeMask & ~(1 << RegisterOperand)) or a.registerMask);
}
class Value: public Compiler::Operand {
public:
Value(Site* site, Site* target):
@ -1879,12 +1886,25 @@ release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED)
class SingleRead: public Read {
public:
SingleRead(const SiteMask& mask):
next_(0), mask(mask)
SingleRead(const SiteMask& mask, Value* successor):
next_(0), mask(mask), successor(successor)
{ }
virtual bool intersect(SiteMask* mask) {
*mask = ::intersect(*mask, this->mask);
SiteMask result = ::intersect(*mask, this->mask);
if (successor) {
Read* r = live(successor);
if (r) {
SiteMask intersection = result;
bool valid = r->intersect(&intersection);
if (valid and ::valid(intersection)) {
result = intersection;
}
}
}
*mask = result;
return true;
}
@ -1904,15 +1924,16 @@ class SingleRead: public Read {
Read* next_;
SiteMask mask;
Value* successor;
};
Read*
read(Context* c, const SiteMask& mask)
read(Context* c, const SiteMask& mask, Value* successor = 0)
{
assert(c, (mask.typeMask != 1 << MemoryOperand) or mask.frameIndex >= 0);
return new (c->zone->allocate(sizeof(SingleRead)))
SingleRead(mask);
SingleRead(mask, successor);
}
Read*
@ -2681,15 +2702,19 @@ class MoveEvent: public Event {
{
assert(c, srcSelectSize <= srcSize);
addRead(c, this, src, read(c, srcLowMask));
if (srcSelectSize > BytesPerWord) {
maybeSplit(c, src);
addRead(c, this, src->high, read(c, srcHighMask));
}
bool noop = srcSelectSize >= dstSize;
if (dstSize > BytesPerWord) {
grow(c, dst);
}
addRead(c, this, src, read(c, srcLowMask, noop ? dst : 0));
if (srcSelectSize > BytesPerWord) {
maybeSplit(c, src);
addRead(c, this, src->high, read
(c, srcHighMask,
noop and dstSize > BytesPerWord ? dst->high : 0));
}
}
virtual const char* name() {
@ -2966,14 +2991,17 @@ class CombineEvent: public Event {
addRead(c, this, first->high, read(c, firstHighMask));
}
addRead(c, this, second, read(c, secondLowMask));
if (secondSize > BytesPerWord) {
addRead(c, this, second->high, read(c, secondHighMask));
}
if (resultSize > BytesPerWord) {
grow(c, result);
}
bool condensed = c->arch->condensedAddressing();
addRead(c, this, second, read(c, secondLowMask, condensed ? result : 0));
if (secondSize > BytesPerWord) {
addRead(c, this, second->high, read
(c, secondHighMask, condensed ? result->high : 0));
}
}
virtual const char* name() {
@ -3367,10 +3395,13 @@ class TranslateEvent: public Event {
Event(c), type(type), size(size), value(value), result(result),
resultLowMask(resultLowMask), resultHighMask(resultHighMask)
{
addRead(c, this, value, read(c, valueLowMask));
bool condensed = c->arch->condensedAddressing();
addRead(c, this, value, read(c, valueLowMask, condensed ? result : 0));
if (size > BytesPerWord) {
addRead(c, this, value->high, read(c, valueHighMask));
grow(c, result);
addRead(c, this, value->high, read
(c, valueHighMask, condensed ? result->high : 0));
}
}

View File

@ -60,8 +60,7 @@ class Compiler {
Operand* index = 0,
unsigned scale = 1) = 0;
virtual Operand* thread() = 0;
virtual Operand* stack() = 0;
virtual Operand* register_(int number) = 0;
virtual void freezeRegister(int number, Operand* value) = 0;
virtual void thawRegister(int number) = 0;

View File

@ -571,7 +571,7 @@ class MySystem: public System {
}
virtual void freeExecutable(const void* p, unsigned sizeInBytes) {
munmap(p, sizeInBytes);
munmap(const_cast<void*>(p), sizeInBytes);
}
virtual bool success(Status s) {
@ -766,11 +766,6 @@ class MySystem: public System {
registerHandler(0, VisitSignalIndex);
system = 0;
if (executableArea) {
int r UNUSED = munmap(executableArea, ExecutableAreaSizeInBytes);
assert(this, r == 0);
}
::free(this);
}

View File

@ -1713,6 +1713,13 @@ class MyArchitecture: public Assembler::Architecture {
return index + 3;
}
virtual bool matchCall(void* returnAddress, void* target) {
uint32_t* instruction = static_cast<uint32_t*>(returnAddress) - 1;
return *instruction == bl(static_cast<uint8_t*>(target)
- reinterpret_cast<uint8_t*>(instruction));
}
virtual void updateCall(UnaryOperation op UNUSED,
bool assertAlignment UNUSED, void* returnAddress,
void* newTarget)

View File

@ -2057,9 +2057,16 @@ class MyArchitecture: public Assembler::Architecture {
}
}
virtual void updateCall(UnaryOperation op UNUSED,
bool assertAlignment UNUSED, void* returnAddress,
void* newTarget)
virtual bool matchCall(void* returnAddress, void* target) {
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
int32_t actualOffset; memcpy(&actualOffset, instruction + 1, 4);
void* actualTarget = static_cast<uint8_t*>(returnAddress) + actualOffset;
return *instruction == 0xE8 and actualTarget == target;
}
virtual void updateCall(UnaryOperation op, bool assertAlignment UNUSED,
void* returnAddress, void* newTarget)
{
if (BytesPerWord == 4 or op == Call or op == Jump) {
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;