make array bounds checking optional; add comments describing stack mapping algorithm

This commit is contained in:
Joel Dice 2008-01-08 10:10:24 -07:00
parent c8472c4d30
commit 551addc638

View File

@ -21,6 +21,8 @@ const bool DebugNatives = false;
const bool DebugTraces = false; const bool DebugTraces = false;
const bool DebugFrameMaps = false; const bool DebugFrameMaps = false;
const bool CheckArrayBounds = true;
class MyThread: public Thread { class MyThread: public Thread {
public: public:
class CallTrace { class CallTrace {
@ -1616,12 +1618,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case iaload: case iaload:
case laload: case laload:
case saload: { case saload: {
Operand* load = c->label();
Operand* throw_ = c->label();
Operand* index = frame->popInt4(); Operand* index = frame->popInt4();
Operand* array = frame->popObject(); Operand* array = frame->popObject();
if (CheckArrayBounds) {
Operand* load = c->label();
Operand* throw_ = c->label();
c->cmp4(c->constant(0), index); c->cmp4(c->constant(0), index);
c->jl(throw_); c->jl(throw_);
@ -1637,6 +1640,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
3, c->thread(), array, index); 3, c->thread(), array, index);
c->mark(load); c->mark(load);
}
switch (instruction) { switch (instruction) {
case aaload: case aaload:
@ -1688,12 +1692,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
value = frame->popInt(); value = frame->popInt();
} }
Operand* store = c->label();
Operand* throw_ = c->label();
Operand* index = frame->popInt4(); Operand* index = frame->popInt4();
Operand* array = frame->popObject(); Operand* array = frame->popObject();
if (CheckArrayBounds) {
Operand* store = c->label();
Operand* throw_ = c->label();
c->cmp4(c->constant(0), index); c->cmp4(c->constant(0), index);
c->jl(throw_); c->jl(throw_);
@ -1709,6 +1714,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
3, c->thread(), array, index); 3, c->thread(), array, index);
c->mark(store); c->mark(store);
}
switch (instruction) { switch (instruction) {
case aastore: { case aastore: {
@ -3471,6 +3477,14 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
int32_t ip = -1; int32_t ip = -1;
// invariant: for each stack position, roots contains a zero at that
// position if there exists some path to the current instruction
// such that there is definitely not an object pointer at that
// position. Otherwise, roots contains a one at that position,
// meaning either all known paths result in an object pointer at
// that position, or the contents of that position are as yet
// unknown.
while (ei < context->eventLog.length()) { while (ei < context->eventLog.length()) {
Event e = static_cast<Event>(context->eventLog.get(ei++)); Event e = static_cast<Event>(context->eventLog.get(ei++));
switch (e) { switch (e) {
@ -3610,8 +3624,11 @@ calculateFrameMaps(MyThread* t, Context* context)
uintptr_t roots[mapSize]; uintptr_t roots[mapSize];
memset(roots, 0, mapSize * BytesPerWord); memset(roots, 0, mapSize * BytesPerWord);
// first pass: calculate reachable roots at instructions with more // first pass: for each instruction with more than one predecessor,
// than one predecessor. // and for each stack position, determine if there exists a path to
// that instruction such that there is not an object pointer left at
// that stack position (i.e. it is uninitialized or contains
// primitive data).
calculateJunctions(t, context, roots, 0); calculateJunctions(t, context, roots, 0);
// second pass: update trace elements. // second pass: update trace elements.