mirror of
https://github.com/corda/corda.git
synced 2024-12-28 16:58:55 +00:00
snapshot
This commit is contained in:
parent
95c4bff51b
commit
29f9bb84ca
@ -1,7 +1,9 @@
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int a = 2 + 2;
|
||||
while (true) {
|
||||
byte[] array = new byte[4 * 1024];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
128
src/heap.cpp
128
src/heap.cpp
@ -19,6 +19,12 @@ System* system(Context*);
|
||||
void NO_RETURN abort(Context*);
|
||||
void assert(Context*, bool);
|
||||
|
||||
void
|
||||
indent(unsigned i)
|
||||
{
|
||||
for (; i > 0; --i) fprintf(stderr, " ");
|
||||
}
|
||||
|
||||
class Segment {
|
||||
public:
|
||||
class Map {
|
||||
@ -385,6 +391,8 @@ class Context {
|
||||
Segment::Map heapMap;
|
||||
|
||||
CollectionMode mode;
|
||||
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
inline System*
|
||||
@ -448,21 +456,34 @@ initNextGen2(Context* c)
|
||||
c->gen2.map = 0;
|
||||
}
|
||||
|
||||
inline object&
|
||||
follow(object o)
|
||||
inline bool
|
||||
wasCollected(Context* c, object o)
|
||||
{
|
||||
return o and
|
||||
(not c->nextGen1.contains(o)) and
|
||||
(not c->nextGen2.contains(o)) and
|
||||
(c->nextGen1.contains(cast<object>(o, 0)) or
|
||||
c->nextGen2.contains(cast<object>(o, 0)));
|
||||
}
|
||||
|
||||
inline object
|
||||
follow(Context* c, object o)
|
||||
{
|
||||
assert(c, wasCollected(c, o));
|
||||
return cast<object>(o, 0);
|
||||
}
|
||||
|
||||
inline object&
|
||||
parent(object o)
|
||||
parent(Context* c, object o)
|
||||
{
|
||||
assert(c, wasCollected(c, o));
|
||||
return cast<object>(o, BytesPerWord);
|
||||
}
|
||||
|
||||
inline uintptr_t*
|
||||
bitset(object o)
|
||||
bitset(Context* c, object o)
|
||||
{
|
||||
assert(c, wasCollected(c, o));
|
||||
return &cast<uintptr_t>(o, BytesPerWord * 2);
|
||||
}
|
||||
|
||||
@ -524,25 +545,21 @@ copy(Context* c, object o)
|
||||
{
|
||||
object r = copy2(c, o);
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "copy %p to %p\n", o, r);
|
||||
|
||||
// leave a pointer to the copy in the original
|
||||
follow(o) = r;
|
||||
cast<object>(o, 0) = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline bool
|
||||
wasCollected(Context* c, object o)
|
||||
{
|
||||
return o and (c->nextGen1.contains(follow(o)) or
|
||||
c->nextGen2.contains(follow(o)));
|
||||
}
|
||||
|
||||
object
|
||||
update3(Context* c, object *p, bool* needsVisit)
|
||||
{
|
||||
if (wasCollected(c, *p)) {
|
||||
*needsVisit = false;
|
||||
return follow(*p);
|
||||
return follow(c, *p);
|
||||
} else {
|
||||
*needsVisit = true;
|
||||
return copy(c, *p);
|
||||
@ -708,13 +725,19 @@ collect(Context* c, void** p)
|
||||
object original = *p;
|
||||
object parent = 0;
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "update %p at %p\n", *p, p);
|
||||
|
||||
bool needsVisit;
|
||||
*p = update(c, p, &needsVisit);
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " result: %p (visit? %d)\n", *p, needsVisit);
|
||||
|
||||
if (not needsVisit) return;
|
||||
|
||||
visit: {
|
||||
object copy = follow(original);
|
||||
object copy = follow(c, original);
|
||||
|
||||
class Walker : public Heap::Walker {
|
||||
public:
|
||||
@ -723,16 +746,27 @@ collect(Context* c, void** p)
|
||||
copy(copy),
|
||||
bitset(bitset),
|
||||
first(0),
|
||||
second(0),
|
||||
last(0),
|
||||
visits(0),
|
||||
total(0)
|
||||
{ }
|
||||
|
||||
virtual bool visit(unsigned offset) {
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " update %p at %p - offset %d from %p\n",
|
||||
cast<object>(copy, offset * BytesPerWord),
|
||||
&cast<object>(copy, offset * BytesPerWord),
|
||||
offset,
|
||||
copy);
|
||||
|
||||
bool needsVisit;
|
||||
object childCopy = update
|
||||
(c, &cast<object>(copy, offset * BytesPerWord), &needsVisit);
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " result: %p (visit? %d)\n", childCopy, needsVisit);
|
||||
|
||||
++ total;
|
||||
|
||||
if (total == 3) {
|
||||
@ -744,18 +778,27 @@ collect(Context* c, void** p)
|
||||
|
||||
if (visits == 1) {
|
||||
first = offset;
|
||||
} else if (visits == 2) {
|
||||
second = offset;
|
||||
}
|
||||
|
||||
if (total >= 3) {
|
||||
bitsetClear(bitset, last, offset);
|
||||
last = offset;
|
||||
|
||||
bitsetSet(bitset, offset, true);
|
||||
}
|
||||
} else {
|
||||
cast<object>(copy, offset * BytesPerWord) = childCopy;
|
||||
}
|
||||
|
||||
if (total >= 3 and (second or needsVisit)) {
|
||||
bitsetClear(bitset, last, offset);
|
||||
last = offset;
|
||||
|
||||
if (second) {
|
||||
bitsetSet(bitset, second, true);
|
||||
second = 0;
|
||||
}
|
||||
|
||||
if (needsVisit) {
|
||||
bitsetSet(bitset, offset, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -763,31 +806,37 @@ collect(Context* c, void** p)
|
||||
object copy;
|
||||
uintptr_t* bitset;
|
||||
unsigned first;
|
||||
unsigned second;
|
||||
unsigned last;
|
||||
unsigned visits;
|
||||
unsigned total;
|
||||
} walker(c, copy, bitset(original));
|
||||
} walker(c, copy, bitset(c, original));
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "walk %p\n", copy);
|
||||
|
||||
c->client->walk(copy, &walker);
|
||||
|
||||
if (walker.visits) {
|
||||
// descend
|
||||
++ c->depth;
|
||||
if (walker.visits > 1) {
|
||||
::parent(original) = parent;
|
||||
::parent(c, original) = parent;
|
||||
parent = original;
|
||||
}
|
||||
|
||||
original = cast<object>(copy, walker.first * BytesPerWord);
|
||||
cast<object>(copy, walker.first * BytesPerWord) = follow(original);
|
||||
cast<object>(copy, walker.first * BytesPerWord) = follow(c, original);
|
||||
goto visit;
|
||||
} else {
|
||||
// ascend
|
||||
-- c->depth;
|
||||
original = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (original) {
|
||||
object copy = follow(original);
|
||||
object copy = follow(c, original);
|
||||
|
||||
class Walker : public Heap::Walker {
|
||||
public:
|
||||
@ -820,18 +869,30 @@ collect(Context* c, void** p)
|
||||
uintptr_t* bitset;
|
||||
unsigned next;
|
||||
unsigned total;
|
||||
} walker(c, bitset(original));
|
||||
} walker(c, bitset(c, original));
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, "scan %p\n", copy);
|
||||
|
||||
c->client->walk(copy, &walker);
|
||||
|
||||
assert(c, walker.total > 1);
|
||||
|
||||
if (walker.total == 3 and bitsetHasMore(bitset(original))) {
|
||||
if (walker.total == 3 and bitsetHasMore(bitset(c, original))) {
|
||||
parent = original;
|
||||
} else {
|
||||
parent = ::parent(original);
|
||||
parent = ::parent(c, original);
|
||||
}
|
||||
|
||||
indent(c->depth);
|
||||
fprintf(stderr, " next is %p at %p - offset %d from %p\n",
|
||||
cast<object>(copy, walker.next * BytesPerWord),
|
||||
&cast<object>(copy, walker.next * BytesPerWord),
|
||||
walker.next,
|
||||
copy);
|
||||
|
||||
original = cast<object>(copy, walker.next * BytesPerWord);
|
||||
cast<object>(copy, walker.next * BytesPerWord) = follow(original);
|
||||
cast<object>(copy, walker.next * BytesPerWord) = follow(c, original);
|
||||
goto visit;
|
||||
} else {
|
||||
return;
|
||||
@ -1019,6 +1080,7 @@ makeHeap(System* system)
|
||||
}
|
||||
|
||||
c.client = client;
|
||||
c.depth = 0;
|
||||
|
||||
::collect(&c);
|
||||
}
|
||||
@ -1038,8 +1100,14 @@ makeHeap(System* system)
|
||||
|
||||
virtual void* follow(void* p) {
|
||||
if (wasCollected(&c, p)) {
|
||||
return ::follow(p);
|
||||
indent(c.depth);
|
||||
fprintf(stderr, "follow: %p: %p\n", p, ::follow(&c, p));
|
||||
|
||||
return ::follow(&c, p);
|
||||
} else {
|
||||
//indent(c.depth);
|
||||
//fprintf(stderr, "follow: %p: %p\n", p, p);
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
@ -928,11 +928,15 @@ parse(Input* in)
|
||||
}
|
||||
|
||||
void
|
||||
writeAccessorName(Output* out, Object* member, bool respectHide = false)
|
||||
writeAccessorName(Output* out, Object* member, bool respectHide = false,
|
||||
bool unsafe = false)
|
||||
{
|
||||
const char* owner = typeShortName(memberOwner(member));
|
||||
out->write(owner);
|
||||
out->write(capitalize(memberName(member)));
|
||||
if (unsafe) {
|
||||
out->write("Unsafe");
|
||||
}
|
||||
if (respectHide and memberHide(member)) {
|
||||
out->write("0");
|
||||
}
|
||||
@ -988,7 +992,8 @@ writeSubtypeAssertions(Output* out, Object* o)
|
||||
{
|
||||
for (Object* p = typeSubtypes(o); p; p = cdr(p)) {
|
||||
Object* st = car(p);
|
||||
out->write(" or objectClass(o) == arrayBody(t, t->vm->types, Machine::");
|
||||
out->write(" or objectClass(o) == arrayBodyUnsafe");
|
||||
out->write("(t, t->vm->types, Machine::");
|
||||
out->write(capitalize(typeName(st)));
|
||||
out->write("Type)");
|
||||
writeSubtypeAssertions(out, st);
|
||||
@ -1009,7 +1014,7 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
out->write("&");
|
||||
}
|
||||
out->write("\n");
|
||||
writeAccessorName(out, member, true);
|
||||
writeAccessorName(out, member, true, unsafe);
|
||||
if (memberOwner(member)->type == Object::Pod) {
|
||||
out->write("(");
|
||||
out->write(capitalize(::typeName(memberOwner(member))));
|
||||
@ -1027,8 +1032,9 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
if (unsafe) {
|
||||
out->write(" assert(t, true);");
|
||||
} else {
|
||||
out->write(" assert(t, objectClass(o) == 0 or ");
|
||||
out->write("objectClass(o) == arrayBody(t, t->vm->types, Machine::");
|
||||
out->write(" assert(t, t->vm->unsafe or objectClass(o) == 0 or ");
|
||||
out->write("objectClass(o) == arrayBodyUnsafe");
|
||||
out->write("(t, t->vm->types, Machine::");
|
||||
out->write(capitalize(::typeName(memberOwner(member))));
|
||||
out->write("Type)");
|
||||
writeSubtypeAssertions(out, memberOwner(member));
|
||||
@ -1155,13 +1161,19 @@ writeAccessors(Output* out, Object* declarations)
|
||||
switch (m->type) {
|
||||
case Object::Scalar: {
|
||||
if (it.padding()) offset = cons(Number::make(it.padding()), offset);
|
||||
writeAccessor(out, m, offset, memberNoAssert(m));
|
||||
writeAccessor(out, m, offset);
|
||||
if (memberNoAssert(m)) {
|
||||
writeAccessor(out, m, offset, true);
|
||||
}
|
||||
offset = cons(Number::make(it.size()), offset);
|
||||
} break;
|
||||
|
||||
case Object::Array: {
|
||||
if (it.padding()) offset = cons(Number::make(it.padding()), offset);
|
||||
writeAccessor(out, m, offset, memberNoAssert(m));
|
||||
writeAccessor(out, m, offset);
|
||||
if (memberNoAssert(m)) {
|
||||
writeAccessor(out, m, offset, true);
|
||||
}
|
||||
offset = cons(m, offset);
|
||||
} break;
|
||||
|
||||
@ -1373,7 +1385,7 @@ typeFixedSize(Object* type)
|
||||
default: UNREACHABLE;
|
||||
}
|
||||
}
|
||||
return length / 4;
|
||||
return length;
|
||||
}
|
||||
|
||||
unsigned
|
||||
@ -1385,7 +1397,7 @@ typeArrayElementSize(Object* type)
|
||||
case Object::Scalar: break;
|
||||
|
||||
case Object::Array: {
|
||||
return memberElementSize(m) / 4;
|
||||
return memberElementSize(m);
|
||||
} break;
|
||||
|
||||
default: UNREACHABLE;
|
||||
@ -1397,9 +1409,10 @@ typeArrayElementSize(Object* type)
|
||||
uint32_t
|
||||
typeObjectMask(Object* type)
|
||||
{
|
||||
assert(typeFixedSize(type) + typeArrayElementSize(type) < 32);
|
||||
assert(typeFixedSize(type) + typeArrayElementSize(type)
|
||||
< 32 * sizeof(void*));
|
||||
|
||||
uint32_t mask = 0;
|
||||
uint32_t mask = 1;
|
||||
|
||||
for (MemberIterator it(type); it.hasMore();) {
|
||||
Object* m = it.next();
|
||||
@ -1442,7 +1455,7 @@ writeInitialization(Output* out, Object* type)
|
||||
|
||||
out->write("{\n");
|
||||
|
||||
if (typeObjectMask(type)) {
|
||||
if (typeObjectMask(type) != 1) {
|
||||
out->write(" object mask = makeIntArray(t, 1);\n");
|
||||
|
||||
out->write(" intArrayBody(t, mask, 0) = ");
|
||||
@ -1507,9 +1520,6 @@ writeInitializations(Output* out, Object* declarations)
|
||||
writeInitialization(out, o);
|
||||
}
|
||||
}
|
||||
|
||||
out->write("set(t, objectClass(t->vm->types), ");
|
||||
out->write("arrayBody(t, t->vm->types, Machine::ArrayType));\n");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,3 +1,6 @@
|
||||
(type intArray
|
||||
(array int32_t body))
|
||||
|
||||
(type class
|
||||
(uint16_t flags)
|
||||
(uint16_t fixedSize)
|
||||
@ -181,9 +184,6 @@
|
||||
(type charArray
|
||||
(array uint16_t body))
|
||||
|
||||
(type intArray
|
||||
(array int32_t body))
|
||||
|
||||
(type longArray
|
||||
(array int64_t body))
|
||||
|
||||
|
145
src/vm.cpp
145
src/vm.cpp
@ -23,7 +23,7 @@ class Thread;
|
||||
void assert(Thread*, bool);
|
||||
object resolveClass(Thread*, object);
|
||||
object allocate(Thread*, unsigned);
|
||||
object& arrayBody(Thread*, object, unsigned);
|
||||
object& arrayBodyUnsafe(Thread*, object, unsigned);
|
||||
void set(Thread*, object&, object);
|
||||
|
||||
object&
|
||||
@ -62,6 +62,7 @@ class Machine {
|
||||
System::Monitor* classLock;
|
||||
object classMap;
|
||||
object types;
|
||||
bool unsafe;
|
||||
};
|
||||
|
||||
class Thread {
|
||||
@ -171,7 +172,8 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
||||
heapLock(0),
|
||||
classLock(0),
|
||||
classMap(0),
|
||||
types(0)
|
||||
types(0),
|
||||
unsafe(false)
|
||||
{
|
||||
if (not system->success(system->make(&stateLock)) or
|
||||
not system->success(system->make(&heapLock)) or
|
||||
@ -197,12 +199,24 @@ Thread::Thread(Machine* m):
|
||||
{
|
||||
if (m->rootThread == 0) {
|
||||
m->rootThread = this;
|
||||
m->unsafe = true;
|
||||
|
||||
Thread* t = this;
|
||||
|
||||
#include "type-initializations.cpp"
|
||||
|
||||
object arrayClass = arrayBody(t, t->vm->types, Machine::ArrayType);
|
||||
set(t, objectClass(t->vm->types), arrayClass);
|
||||
|
||||
object classClass = arrayBody(t, m->types, Machine::ClassType);
|
||||
set(t, objectClass(classClass), classClass);
|
||||
|
||||
object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType);
|
||||
set(t, objectClass(intArrayClass), classClass);
|
||||
|
||||
m->classMap = makeHashMap(this, 0, 0);
|
||||
|
||||
m->unsafe = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,10 +265,12 @@ collect(Machine* m, Heap::CollectionType type)
|
||||
p = m->heap->follow(p);
|
||||
object class_ = m->heap->follow(objectClass(p));
|
||||
|
||||
unsigned n = classFixedSize(t, class_);
|
||||
unsigned n = divide(classFixedSize(t, class_), BytesPerWord);
|
||||
|
||||
if (classArrayElementSize(t, class_)) {
|
||||
n += classArrayElementSize(t, class_)
|
||||
* cast<uint32_t>(p, (classFixedSize(t, class_) - 1) * BytesPerWord);
|
||||
n += divide(classArrayElementSize(t, class_)
|
||||
* cast<uint32_t>(p, classFixedSize(t, class_) - 4),
|
||||
BytesPerWord);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@ -264,28 +280,63 @@ collect(Machine* m, Heap::CollectionType type)
|
||||
|
||||
p = m->heap->follow(p);
|
||||
object class_ = m->heap->follow(objectClass(p));
|
||||
unsigned fixedSize = classFixedSize(t, class_);
|
||||
unsigned arrayLength = cast<uint32_t>(p, (fixedSize - 1) * BytesPerWord);
|
||||
unsigned arrayElementSize = classArrayElementSize(t, class_);
|
||||
|
||||
object objectMask = m->heap->follow(classObjectMask(t, class_));
|
||||
int mask[intArrayLength(t, objectMask)];
|
||||
memcpy(mask, &intArrayBody(t, objectMask, 0),
|
||||
intArrayLength(t, objectMask) * 4);
|
||||
|
||||
for (unsigned i = 0; i < fixedSize; ++i) {
|
||||
if (mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i))) {
|
||||
if (not w->visit(i)) return;
|
||||
}
|
||||
}
|
||||
if (objectMask) {
|
||||
fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n",
|
||||
p, class_, objectMask, intArrayLength(t, objectMask));
|
||||
|
||||
for (unsigned i = 0; i < arrayLength; ++i) {
|
||||
for (unsigned j = 0; j < arrayElementSize; ++j) {
|
||||
unsigned k = fixedSize + j;
|
||||
if (mask[wordOf(k)] & (static_cast<uintptr_t>(1) << bitOf(k))) {
|
||||
if (not w->visit(fixedSize + (i * arrayElementSize) + j)) return;
|
||||
unsigned fixedSize = classFixedSize(t, class_);
|
||||
unsigned arrayElementSize = classArrayElementSize(t, class_);
|
||||
unsigned arrayLength
|
||||
= (arrayElementSize ? cast<uint32_t>(p, fixedSize - 4) : 0);
|
||||
|
||||
int mask[intArrayLength(t, objectMask)];
|
||||
memcpy(mask, &intArrayBody(t, objectMask, 0),
|
||||
intArrayLength(t, objectMask) * 4);
|
||||
|
||||
// fprintf
|
||||
// (stderr,
|
||||
// "fixed size: %d; array length: %d; element size: %d; mask: %x\n",
|
||||
// fixedSize, arrayLength, arrayElementSize, mask[0]);
|
||||
|
||||
unsigned fixedSizeInWords = divide(fixedSize, BytesPerWord);
|
||||
unsigned arrayElementSizeInWords
|
||||
= divide(arrayElementSize, BytesPerWord);
|
||||
|
||||
for (unsigned i = 0; i < fixedSizeInWords; ++i) {
|
||||
if (mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i))) {
|
||||
if (not w->visit(i)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool arrayObjectElements = false;
|
||||
for (unsigned j = 0; j < arrayElementSizeInWords; ++j) {
|
||||
unsigned k = fixedSizeInWords + j;
|
||||
if (mask[wordOf(k)] & (static_cast<uintptr_t>(1) << bitOf(k))) {
|
||||
arrayObjectElements = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arrayObjectElements) {
|
||||
for (unsigned i = 0; i < arrayLength; ++i) {
|
||||
for (unsigned j = 0; j < arrayElementSizeInWords; ++j) {
|
||||
unsigned k = fixedSizeInWords + j;
|
||||
if (mask[wordOf(k)] & (static_cast<uintptr_t>(1) << bitOf(k))) {
|
||||
if (not w->visit
|
||||
(fixedSizeInWords + (i * arrayElementSizeInWords) + j))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
w->visit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,7 +346,9 @@ collect(Machine* m, Heap::CollectionType type)
|
||||
|
||||
fprintf(stderr, "collection time!\n");
|
||||
|
||||
m->unsafe = true;
|
||||
m->heap->collect(type, &it);
|
||||
m->unsafe = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1187,15 +1240,13 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
PROTECT(t, class_);
|
||||
PROTECT(t, pool);
|
||||
|
||||
unsigned memberOffset = BytesPerWord;
|
||||
if (classSuper(t, class_)) {
|
||||
memberOffset = classFixedSize(t, classSuper(t, class_)) * BytesPerWord;
|
||||
}
|
||||
|
||||
unsigned count = s.read2();
|
||||
if (count) {
|
||||
fprintf(stderr, "%d fields\n", count);
|
||||
|
||||
unsigned memberOffset = BytesPerWord;
|
||||
if (classSuper(t, class_)) {
|
||||
memberOffset= classFixedSize(t, classSuper(t, class_)) * BytesPerWord;
|
||||
}
|
||||
|
||||
unsigned staticOffset = 0;
|
||||
|
||||
object fieldTable = makeArray(t, count);
|
||||
@ -1243,6 +1294,32 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
set(t, classStaticTable(t, class_), staticTable);
|
||||
}
|
||||
}
|
||||
|
||||
classFixedSize(t, class_) = divide(memberOffset, BytesPerWord);
|
||||
|
||||
object mask = makeIntArray
|
||||
(t, divide(classFixedSize(t, class_), BitsPerWord));
|
||||
|
||||
memset(&intArrayBody(t, mask, 0), 0, intArrayLength(t, mask) * 4);
|
||||
|
||||
bool sawReferenceField = false;
|
||||
for (object c = class_; c; c = classSuper(t, c)) {
|
||||
object fieldTable = classFieldTable(t, c);
|
||||
if (fieldTable) {
|
||||
for (int i = arrayLength(t, fieldTable) - 1; i >= 0; --i) {
|
||||
object field = arrayBody(t, fieldTable, i);
|
||||
if (isReferenceField(t, field)) {
|
||||
unsigned index = fieldOffset(t, field) / BytesPerWord;
|
||||
intArrayBody(t, mask, (index / 32)) |= 1 << (index % 32);
|
||||
sawReferenceField = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sawReferenceField) {
|
||||
set(t, classObjectMask(t, class_), mask);
|
||||
}
|
||||
}
|
||||
|
||||
object
|
||||
@ -1612,6 +1689,8 @@ run(Thread* t)
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
|
||||
loop:
|
||||
//fprintf(stderr, "ip: %d; instruction: 0x%x\n", ip, codeBody(t, code, ip));
|
||||
|
||||
switch (codeBody(t, code, ip++)) {
|
||||
case aaload: {
|
||||
object index = pop(t);
|
||||
@ -2036,7 +2115,7 @@ run(Thread* t)
|
||||
uint8_t offset1 = codeBody(t, code, ip++);
|
||||
uint8_t offset2 = codeBody(t, code, ip++);
|
||||
|
||||
ip = (ip - 1) + ((offset1 << 8) | offset2);
|
||||
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
||||
} goto loop;
|
||||
|
||||
case goto_w: {
|
||||
@ -2045,8 +2124,8 @@ run(Thread* t)
|
||||
uint8_t offset3 = codeBody(t, code, ip++);
|
||||
uint8_t offset4 = codeBody(t, code, ip++);
|
||||
|
||||
ip = (ip - 1)
|
||||
+ ((offset1 << 24) | (offset2 << 16) | (offset3 << 8) | offset4);
|
||||
ip = (ip - 5) + static_cast<int16_t>
|
||||
(((offset1 << 24) | (offset2 << 16) | (offset3 << 8) | offset4));
|
||||
} goto loop;
|
||||
|
||||
case i2b: {
|
||||
@ -3044,6 +3123,8 @@ run(Thread* t)
|
||||
void
|
||||
run(Thread* t, const char* className, int argc, const char** argv)
|
||||
{
|
||||
enter(t, Thread::ActiveState);
|
||||
|
||||
object class_ = resolveClass(t, makeByteArray(t, "%s", className));
|
||||
if (LIKELY(t->exception == 0)) {
|
||||
PROTECT(t, class_);
|
||||
|
Loading…
Reference in New Issue
Block a user