mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
bugfixes
This commit is contained in:
parent
e5bea7a455
commit
f71c77298c
@ -22,7 +22,7 @@ public class TestThreads implements Runnable {
|
|||||||
try {
|
try {
|
||||||
System.out.println("I'm running in a seperate thread!");
|
System.out.println("I'm running in a seperate thread!");
|
||||||
|
|
||||||
final int arrayCount = 64;
|
final int arrayCount = 8;
|
||||||
final int arraySize = 4;
|
final int arraySize = 4;
|
||||||
System.out.println("Allocating and discarding " + arrayCount +
|
System.out.println("Allocating and discarding " + arrayCount +
|
||||||
" arrays of " + arraySize + "MB each");
|
" arrays of " + arraySize + "MB each");
|
||||||
|
19
classpath/java/lang/ArrayIndexOutOfBoundsException.java
Normal file
19
classpath/java/lang/ArrayIndexOutOfBoundsException.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public class ArrayIndexOutOfBoundsException extends RuntimeException {
|
||||||
|
public ArrayIndexOutOfBoundsException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayIndexOutOfBoundsException(String message) {
|
||||||
|
this(message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayIndexOutOfBoundsException(Throwable cause) {
|
||||||
|
this(null, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayIndexOutOfBoundsException() {
|
||||||
|
this(null, null);
|
||||||
|
}
|
||||||
|
}
|
@ -19,9 +19,9 @@ public class Object {
|
|||||||
|
|
||||||
public native String toString();
|
public native String toString();
|
||||||
|
|
||||||
public native final void wait();
|
public final void wait() {
|
||||||
|
wait(0);
|
||||||
|
}
|
||||||
|
|
||||||
public native final void wait(long timeout);
|
public native final void wait(long timeout);
|
||||||
|
|
||||||
public native final void wait(long timeout, int nanos);
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,20 @@ public final class String {
|
|||||||
private int length;
|
private int length;
|
||||||
private int hash;
|
private int hash;
|
||||||
|
|
||||||
|
public String(char[] data, int offset, int length, boolean copy) {
|
||||||
|
if (copy) {
|
||||||
|
char[] c = new char[length];
|
||||||
|
System.arraycopy(data, offset, c, 0, length);
|
||||||
|
|
||||||
|
this.data = c;
|
||||||
|
this.length = length;
|
||||||
|
} else {
|
||||||
|
this.data = data;
|
||||||
|
this.offset = offset;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int length() {
|
public int length() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -14,8 +28,23 @@ public final class String {
|
|||||||
return valueOf((long) v);
|
return valueOf((long) v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public native void getChars(int offset, int length,
|
public void getChars(int srcOffset, int srcLength,
|
||||||
char[] dst, int dstLength);
|
char[] dst, int dstOffset)
|
||||||
|
{
|
||||||
|
if (srcOffset + srcLength > length) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data instanceof char[]) {
|
||||||
|
char[] src = (char[]) data;
|
||||||
|
System.arraycopy(src, offset + srcOffset, dst, dstOffset, srcLength);
|
||||||
|
} else {
|
||||||
|
byte[] src = (byte[]) data;
|
||||||
|
for (int i = 0; i < srcLength; ++i) {
|
||||||
|
dst[i + dstOffset] = (char) src[i + offset + srcOffset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String valueOf(long v) {
|
public static String valueOf(long v) {
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
@ -35,7 +64,7 @@ public final class String {
|
|||||||
array[--index] = '-';
|
array[--index] = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.Strings.wrap(array, index, Max - index);
|
return new String(array, index, Max - index, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public class StringBuilder {
|
|||||||
index -= c.value.length();
|
index -= c.value.length();
|
||||||
c.value.getChars(0, c.value.length(), array, index);
|
c.value.getChars(0, c.value.length(), array, index);
|
||||||
}
|
}
|
||||||
return vm.Strings.wrap(array, 0, array.length);
|
return new String(array, 0, array.length, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Cell {
|
private static class Cell {
|
||||||
|
@ -1,16 +1,34 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
#include "string.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
#undef JNIEXPORT
|
#undef JNIEXPORT
|
||||||
#define JNIEXPORT __attribute__ ((visibility("default")))
|
#define JNIEXPORT __attribute__ ((visibility("default")))
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_lang_System_00024Output_println(JNIEnv* e, jobject, jstring s)
|
Java_java_lang_System_00024Output_print(JNIEnv* e, jobject, jstring s)
|
||||||
{
|
{
|
||||||
jboolean isCopy;
|
jboolean isCopy;
|
||||||
const char* chars = e->GetStringUTFChars(s, &isCopy);
|
const char* chars = e->GetStringUTFChars(s, &isCopy);
|
||||||
if (chars) {
|
if (chars) {
|
||||||
printf("%s\n", chars);
|
printf("%s", chars);
|
||||||
}
|
}
|
||||||
e->ReleaseStringUTFChars(s, chars);
|
e->ReleaseStringUTFChars(s, chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jstring JNICALL
|
||||||
|
Java_java_lang_System_getProperty(JNIEnv* e, jstring key)
|
||||||
|
{
|
||||||
|
jstring value = 0;
|
||||||
|
|
||||||
|
jboolean isCopy;
|
||||||
|
const char* chars = e->GetStringUTFChars(key, &isCopy);
|
||||||
|
if (chars) {
|
||||||
|
if (strcmp(chars, "line.separator") == 0) {
|
||||||
|
value = e->NewStringUTF("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e->ReleaseStringUTFChars(key, chars);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
@ -8,14 +8,17 @@ public abstract class System {
|
|||||||
loadLibrary("natives");
|
loadLibrary("natives");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static native void arraycopy(Object src, int srcOffset, Object dst,
|
||||||
|
int dstOffset, int length);
|
||||||
|
|
||||||
public static native void loadLibrary(String name);
|
public static native void loadLibrary(String name);
|
||||||
|
|
||||||
public static native String getProperty(String name);
|
public static native String getProperty(String name);
|
||||||
|
|
||||||
public static class Output {
|
public static class Output {
|
||||||
public native void print(String s);
|
public synchronized native void print(String s);
|
||||||
|
|
||||||
public void println(String s) {
|
public synchronized void println(String s) {
|
||||||
print(s);
|
print(s);
|
||||||
print(getProperty("line.separator"));
|
print(getProperty("line.separator"));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
package vm;
|
|
||||||
|
|
||||||
public abstract class Strings {
|
|
||||||
public static native String wrap(char[] array, int offset, int length);
|
|
||||||
}
|
|
@ -5,6 +5,35 @@
|
|||||||
namespace vm {
|
namespace vm {
|
||||||
namespace builtin {
|
namespace builtin {
|
||||||
|
|
||||||
|
jstring
|
||||||
|
toString(Thread* t, jobject this_)
|
||||||
|
{
|
||||||
|
object s = makeString
|
||||||
|
(t, "%s@%p",
|
||||||
|
&byteArrayBody(t, className(t, objectClass(t, *this_)), 0),
|
||||||
|
*this_);
|
||||||
|
|
||||||
|
return pushReference(t, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wait(Thread* t, jobject this_, jlong milliseconds)
|
||||||
|
{
|
||||||
|
vm::wait(t, *this_, milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
notify(Thread* t, jobject this_)
|
||||||
|
{
|
||||||
|
vm::notify(t, *this_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
notifyAll(Thread* t, jobject this_)
|
||||||
|
{
|
||||||
|
vm::notifyAll(t, *this_);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
loadLibrary(Thread* t, jstring nameString)
|
loadLibrary(Thread* t, jstring nameString)
|
||||||
{
|
{
|
||||||
@ -30,15 +59,53 @@ loadLibrary(Thread* t, jstring nameString)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring
|
void
|
||||||
toString(Thread* t, jobject this_)
|
arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
|
||||||
|
jint length)
|
||||||
{
|
{
|
||||||
object s = makeString
|
if (LIKELY(src and dst)) {
|
||||||
(t, "%s@%p",
|
object s = *src;
|
||||||
&byteArrayBody(t, className(t, objectClass(t, *this_)), 0),
|
object d = *dst;
|
||||||
*this_);
|
|
||||||
|
|
||||||
return pushReference(t, s);
|
if (LIKELY(objectClass(t, s) == objectClass(t, d))) {
|
||||||
|
unsigned elementSize = classArrayElementSize(t, objectClass(t, s));
|
||||||
|
|
||||||
|
if (LIKELY(elementSize)) {
|
||||||
|
unsigned offset = 0;
|
||||||
|
|
||||||
|
if (objectClass(t, s)
|
||||||
|
== arrayBody(t, t->vm->types, Machine::ObjectArrayType))
|
||||||
|
{
|
||||||
|
if (LIKELY(objectArrayElementClass(t, s)
|
||||||
|
== objectArrayElementClass(t, d)))
|
||||||
|
{
|
||||||
|
offset = 1;
|
||||||
|
} else {
|
||||||
|
t->exception = makeArrayStoreException(t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t sl = cast<uint32_t>(s, offset * BytesPerWord);
|
||||||
|
int32_t dl = cast<uint32_t>(d, offset * BytesPerWord);
|
||||||
|
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
|
||||||
|
dstOffset >= 0 and dstOffset + length < dl))
|
||||||
|
{
|
||||||
|
uint8_t* sbody = &cast<uint8_t>(s, (offset * BytesPerWord) + 4);
|
||||||
|
uint8_t* dbody = &cast<uint8_t>(s, (offset * BytesPerWord) + 4);
|
||||||
|
memcpy(sbody + (srcOffset * elementSize),
|
||||||
|
dbody + (dstOffset * elementSize),
|
||||||
|
length * elementSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t->exception = makeNullPointerException(t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->exception = makeArrayStoreException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
jarray
|
jarray
|
||||||
@ -100,7 +167,6 @@ start(Thread* t, jobject this_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
populate(Thread* t, object map)
|
populate(Thread* t, object map)
|
||||||
{
|
{
|
||||||
@ -110,8 +176,16 @@ populate(Thread* t, object map)
|
|||||||
} builtins[] = {
|
} builtins[] = {
|
||||||
{ "Java_java_lang_Object_toString",
|
{ "Java_java_lang_Object_toString",
|
||||||
reinterpret_cast<void*>(toString) },
|
reinterpret_cast<void*>(toString) },
|
||||||
|
{ "Java_java_lang_Object_wait",
|
||||||
|
reinterpret_cast<void*>(wait) },
|
||||||
|
{ "Java_java_lang_Object_notify",
|
||||||
|
reinterpret_cast<void*>(notify) },
|
||||||
|
{ "Java_java_lang_Object_notifyAll",
|
||||||
|
reinterpret_cast<void*>(notifyAll) },
|
||||||
{ "Java_java_lang_System_loadLibrary",
|
{ "Java_java_lang_System_loadLibrary",
|
||||||
reinterpret_cast<void*>(loadLibrary) },
|
reinterpret_cast<void*>(loadLibrary) },
|
||||||
|
{ "Java_java_lang_System_arraycopy",
|
||||||
|
reinterpret_cast<void*>(arraycopy) },
|
||||||
{ "Java_java_lang_Throwable_trace",
|
{ "Java_java_lang_Throwable_trace",
|
||||||
reinterpret_cast<void*>(trace) },
|
reinterpret_cast<void*>(trace) },
|
||||||
{ "Java_java_lang_Thread_start",
|
{ "Java_java_lang_Thread_start",
|
||||||
|
@ -241,6 +241,7 @@ const unsigned ACC_PROTECTED = 1 << 2;
|
|||||||
const unsigned ACC_STATIC = 1 << 3;
|
const unsigned ACC_STATIC = 1 << 3;
|
||||||
const unsigned ACC_FINAL = 1 << 4;
|
const unsigned ACC_FINAL = 1 << 4;
|
||||||
const unsigned ACC_SUPER = 1 << 5;
|
const unsigned ACC_SUPER = 1 << 5;
|
||||||
|
const unsigned ACC_SYNCHRONIZED = ACC_SUPER;
|
||||||
const unsigned ACC_VOLATILE = 1 << 6;
|
const unsigned ACC_VOLATILE = 1 << 6;
|
||||||
const unsigned ACC_TRANSIENT = 1 << 7;
|
const unsigned ACC_TRANSIENT = 1 << 7;
|
||||||
const unsigned ACC_NATIVE = 1 << 8;
|
const unsigned ACC_NATIVE = 1 << 8;
|
||||||
|
@ -36,6 +36,14 @@ ReleaseStringUTFChars(Thread* t, jstring, const char* chars)
|
|||||||
t->vm->system->free(chars);
|
t->vm->system->free(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jstring
|
||||||
|
NewStringUTF(Thread* t, const char* chars)
|
||||||
|
{
|
||||||
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
|
return pushReference(t, makeString(t, "%s", chars));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
populate(JNIEnvVTable* table)
|
populate(JNIEnvVTable* table)
|
||||||
{
|
{
|
||||||
@ -44,6 +52,7 @@ populate(JNIEnvVTable* table)
|
|||||||
table->GetStringUTFLength = GetStringUTFLength;
|
table->GetStringUTFLength = GetStringUTFLength;
|
||||||
table->GetStringUTFChars = GetStringUTFChars;
|
table->GetStringUTFChars = GetStringUTFChars;
|
||||||
table->ReleaseStringUTFChars = ReleaseStringUTFChars;
|
table->ReleaseStringUTFChars = ReleaseStringUTFChars;
|
||||||
|
table->NewStringUTF = NewStringUTF;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace jni
|
} // namespace jni
|
||||||
|
107
src/machine.cpp
107
src/machine.cpp
@ -6,45 +6,6 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void
|
|
||||||
visitRoots(Thread* t, Heap::Visitor* v)
|
|
||||||
{
|
|
||||||
if (t->state != Thread::ZombieState) {
|
|
||||||
t->heapIndex = 0;
|
|
||||||
|
|
||||||
v->visit(&(t->javaThread));
|
|
||||||
v->visit(&(t->code));
|
|
||||||
v->visit(&(t->exception));
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < t->sp; ++i) {
|
|
||||||
if (t->stack[i * 2] == ObjectTag) {
|
|
||||||
v->visit(reinterpret_cast<object*>(t->stack + (i * 2) + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Thread::Protector* p = t->protector; p; p = p->next) {
|
|
||||||
v->visit(p->p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Thread* c = t->child; c; c = c->peer) {
|
|
||||||
visitRoots(c, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
postCollect(Thread* t)
|
|
||||||
{
|
|
||||||
if (t->large) {
|
|
||||||
t->vm->system->free(t->large);
|
|
||||||
t->large = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Thread* c = t->child; c; c = c->peer) {
|
|
||||||
postCollect(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
find(Thread* t, Thread* o)
|
find(Thread* t, Thread* o)
|
||||||
{
|
{
|
||||||
@ -140,6 +101,45 @@ killZombies(Thread* t, Thread* o)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
visitRoots(Thread* t, Heap::Visitor* v)
|
||||||
|
{
|
||||||
|
if (t->state != Thread::ZombieState) {
|
||||||
|
t->heapIndex = 0;
|
||||||
|
|
||||||
|
v->visit(&(t->javaThread));
|
||||||
|
v->visit(&(t->code));
|
||||||
|
v->visit(&(t->exception));
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < t->sp; ++i) {
|
||||||
|
if (t->stack[i * 2] == ObjectTag) {
|
||||||
|
v->visit(reinterpret_cast<object*>(t->stack + (i * 2) + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Thread::Protector* p = t->protector; p; p = p->next) {
|
||||||
|
v->visit(p->p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Thread* c = t->child; c; c = c->peer) {
|
||||||
|
visitRoots(c, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
postCollect(Thread* t)
|
||||||
|
{
|
||||||
|
if (t->large) {
|
||||||
|
t->vm->system->free(t->large);
|
||||||
|
t->large = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Thread* c = t->child; c; c = c->peer) {
|
||||||
|
postCollect(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
collect(Thread* t, Heap::CollectionType type)
|
collect(Thread* t, Heap::CollectionType type)
|
||||||
{
|
{
|
||||||
@ -174,13 +174,8 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (object* f = &(m->finalizers); *f; f = &finalizerNext(t, *f)) {
|
v->visit(&(m->finalizers));
|
||||||
v->visit(f);
|
v->visit(&(m->doomed));
|
||||||
}
|
|
||||||
|
|
||||||
for (object* f = &(m->doomed); *f; f = &finalizerNext(t, *f)) {
|
|
||||||
v->visit(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (object p = m->weakReferences; p;) {
|
for (object p = m->weakReferences; p;) {
|
||||||
object o = jreferenceTarget(t, p);
|
object o = jreferenceTarget(t, p);
|
||||||
@ -193,8 +188,8 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object last = p;
|
object last = p;
|
||||||
p = weakReferenceNext(t, p);
|
p = jreferenceNext(t, p);
|
||||||
weakReferenceNext(t, last) = 0;
|
jreferenceNext(t, last) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,13 +228,16 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
memcpy(dst, o, n * BytesPerWord);
|
memcpy(dst, o, n * BytesPerWord);
|
||||||
|
|
||||||
if (hashTaken(t, o)) {
|
if (hashTaken(t, o)) {
|
||||||
extendedWord(t, dst, base) = takeHash(t, o);
|
|
||||||
cast<uintptr_t>(dst, 0) &= PointerMask;
|
cast<uintptr_t>(dst, 0) &= PointerMask;
|
||||||
cast<uintptr_t>(dst, 0) |= ExtendedMark;
|
cast<uintptr_t>(dst, 0) |= ExtendedMark;
|
||||||
|
extendedWord(t, dst, base) = takeHash(t, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
||||||
weakReferenceNext(t, dst) = m->weakReferences;
|
fprintf(stderr, "weak reference to %p at %p\n",
|
||||||
|
jreferenceTarget(t, dst),
|
||||||
|
&jreferenceTarget(t, dst));
|
||||||
|
jreferenceNext(t, dst) = m->weakReferences;
|
||||||
m->weakReferences = dst;
|
m->weakReferences = dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +253,6 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
// fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n",
|
// fprintf(stderr, "p: %p; class: %p; mask: %p; mask length: %d\n",
|
||||||
// p, class_, objectMask, intArrayLength(t, objectMask));
|
// p, class_, objectMask, intArrayLength(t, objectMask));
|
||||||
|
|
||||||
unsigned vmFlags = classVmFlags(t, class_);
|
|
||||||
unsigned fixedSize = classFixedSize(t, class_);
|
unsigned fixedSize = classFixedSize(t, class_);
|
||||||
unsigned arrayElementSize = classArrayElementSize(t, class_);
|
unsigned arrayElementSize = classArrayElementSize(t, class_);
|
||||||
unsigned arrayLength
|
unsigned arrayLength
|
||||||
@ -275,9 +272,7 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
= divide(arrayElementSize, BytesPerWord);
|
= divide(arrayElementSize, BytesPerWord);
|
||||||
|
|
||||||
for (unsigned i = 0; i < fixedSizeInWords; ++i) {
|
for (unsigned i = 0; i < fixedSizeInWords; ++i) {
|
||||||
if ((i != 1 or (vmFlags & WeakReferenceFlag) == 0)
|
if (mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i))) {
|
||||||
and mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i)))
|
|
||||||
{
|
|
||||||
if (not w->visit(i)) {
|
if (not w->visit(i)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -322,7 +317,7 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
|
|
||||||
postCollect(m->rootThread);
|
postCollect(m->rootThread);
|
||||||
|
|
||||||
for (object f = m->doomed; f; f = tripleThird(t, f)) {
|
for (object f = m->doomed; f; f = finalizerNext(t, f)) {
|
||||||
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
|
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
|
||||||
(t, finalizerTarget(t, f));
|
(t, finalizerTarget(t, f));
|
||||||
}
|
}
|
||||||
@ -451,6 +446,8 @@ Thread::Thread(Machine* m, Allocator* allocator, object javaThread,
|
|||||||
|
|
||||||
object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType);
|
object intArrayClass = arrayBody(t, m->types, Machine::IntArrayType);
|
||||||
set(t, cast<object>(intArrayClass, 0), classClass);
|
set(t, cast<object>(intArrayClass, 0), classClass);
|
||||||
|
set(t, classSuper(t, intArrayClass),
|
||||||
|
arrayBody(t, m->types, Machine::JobjectType));
|
||||||
|
|
||||||
m->unsafe = false;
|
m->unsafe = false;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace vm {
|
|||||||
const bool Verbose = false;
|
const bool Verbose = false;
|
||||||
const bool Debug = false;
|
const bool Debug = false;
|
||||||
const bool DebugRun = true;
|
const bool DebugRun = true;
|
||||||
const bool DebugStack = false;
|
const bool DebugStack = true;
|
||||||
|
|
||||||
const uintptr_t HashTakenMark = 1;
|
const uintptr_t HashTakenMark = 1;
|
||||||
const uintptr_t ExtendedMark = 2;
|
const uintptr_t ExtendedMark = 2;
|
||||||
@ -1311,6 +1311,12 @@ makeIllegalStateException(Thread* t, object message)
|
|||||||
return makeIllegalStateException(t, message, trace, 0);
|
return makeIllegalStateException(t, message, trace, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
makeIllegalMonitorStateException(Thread* t)
|
||||||
|
{
|
||||||
|
return makeIllegalMonitorStateException(t, 0, makeTrace(t), 0);
|
||||||
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
makeArrayIndexOutOfBoundsException(Thread* t, object message)
|
makeArrayIndexOutOfBoundsException(Thread* t, object message)
|
||||||
{
|
{
|
||||||
@ -1320,11 +1326,17 @@ makeArrayIndexOutOfBoundsException(Thread* t, object message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
makeNegativeArrayStoreException(Thread* t, object message)
|
makeArrayStoreException(Thread* t)
|
||||||
|
{
|
||||||
|
return makeArrayStoreException(t, 0, makeTrace(t), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
makeNegativeArraySizeException(Thread* t, object message)
|
||||||
{
|
{
|
||||||
PROTECT(t, message);
|
PROTECT(t, message);
|
||||||
object trace = makeTrace(t);
|
object trace = makeTrace(t);
|
||||||
return makeNegativeArrayStoreException(t, message, trace, 0);
|
return makeNegativeArraySizeException(t, message, trace, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
@ -1535,7 +1547,7 @@ pokeLong(Thread* t, unsigned index, uint64_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pokeInt(t, index, value >> 32);
|
pokeInt(t, index, value >> 32);
|
||||||
pokeInt(t, index + 2, value & 0xFF);
|
pokeInt(t, index + 1, value & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object*
|
inline object*
|
||||||
@ -1807,6 +1819,56 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));
|
|||||||
System::Monitor*
|
System::Monitor*
|
||||||
objectMonitor(Thread* t, object o);
|
objectMonitor(Thread* t, object o);
|
||||||
|
|
||||||
|
inline void
|
||||||
|
acquire(Thread* t, object o)
|
||||||
|
{
|
||||||
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
if (not m->tryAcquire(t)) {
|
||||||
|
ENTER(t, Thread::IdleState);
|
||||||
|
m->acquire(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
release(Thread* t, object o)
|
||||||
|
{
|
||||||
|
objectMonitor(t, o)->release(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
wait(Thread* t, object o, int64_t milliseconds)
|
||||||
|
{
|
||||||
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
if (m->owner() == t) {
|
||||||
|
ENTER(t, Thread::IdleState);
|
||||||
|
m->wait(t, milliseconds);
|
||||||
|
} else {
|
||||||
|
t->exception = makeIllegalMonitorStateException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
notify(Thread* t, object o)
|
||||||
|
{
|
||||||
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
if (m->owner() == t) {
|
||||||
|
m->notify(t);
|
||||||
|
} else {
|
||||||
|
t->exception = makeIllegalMonitorStateException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
notifyAll(Thread* t, object o)
|
||||||
|
{
|
||||||
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
if (m->owner() == t) {
|
||||||
|
m->notifyAll(t);
|
||||||
|
} else {
|
||||||
|
t->exception = makeIllegalMonitorStateException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
exit(Thread* t);
|
exit(Thread* t);
|
||||||
|
|
||||||
|
@ -227,6 +227,10 @@ class System: public vm::System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void* owner() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
pthread_cond_destroy(&condition);
|
pthread_cond_destroy(&condition);
|
||||||
|
109
src/run.cpp
109
src/run.cpp
@ -42,11 +42,30 @@ pushFrame(Thread* t, object method)
|
|||||||
|
|
||||||
pokeInt(t, frame + FrameBaseOffset, base);
|
pokeInt(t, frame + FrameBaseOffset, base);
|
||||||
pokeObject(t, frame + FrameMethodOffset, method);
|
pokeObject(t, frame + FrameMethodOffset, method);
|
||||||
|
pokeInt(t, t->frame + FrameIpOffset, 0);
|
||||||
|
|
||||||
|
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
|
||||||
|
if (methodFlags(t, method) & ACC_STATIC) {
|
||||||
|
acquire(t, methodClass(t, method));
|
||||||
|
} else {
|
||||||
|
acquire(t, peekObject(t, base));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
popFrame(Thread* t)
|
popFrame(Thread* t)
|
||||||
{
|
{
|
||||||
|
object method = frameMethod(t, t->frame);
|
||||||
|
|
||||||
|
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
|
||||||
|
if (methodFlags(t, method) & ACC_STATIC) {
|
||||||
|
release(t, methodClass(t, method));
|
||||||
|
} else {
|
||||||
|
release(t, peekObject(t, frameBase(t, t->frame)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t->sp = frameBase(t, t->frame);
|
t->sp = frameBase(t, t->frame);
|
||||||
t->frame = frameNext(t, t->frame);
|
t->frame = frameNext(t, t->frame);
|
||||||
if (t->frame >= 0) {
|
if (t->frame >= 0) {
|
||||||
@ -1214,10 +1233,20 @@ resolveClass(Thread* t, object spec)
|
|||||||
|
|
||||||
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
|
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
|
||||||
} else {
|
} else {
|
||||||
|
class_ = hashMapFind
|
||||||
|
(t, t->vm->bootstrapClassMap, spec, byteArrayHash, byteArrayEqual);
|
||||||
|
|
||||||
|
if (class_ == 0) {
|
||||||
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
|
object message = makeString(t, "%s", &byteArrayBody(t, spec, 0));
|
||||||
t->exception = makeClassNotFoundException(t, message);
|
t->exception = makeClassNotFoundException(t, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (class_) {
|
||||||
|
hashMapInsert(t, t->vm->classMap, spec, class_, byteArrayHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return class_;
|
return class_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1452,6 +1481,12 @@ invokeNative(Thread* t, object method)
|
|||||||
enter(t, Thread::IdleState);
|
enter(t, Thread::IdleState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DebugRun) {
|
||||||
|
fprintf(stderr, "invoke native method %s.%s\n",
|
||||||
|
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||||
|
&byteArrayBody(t, methodName(t, method), 0));
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t result = t->vm->system->call
|
uint64_t result = t->vm->system->call
|
||||||
(function,
|
(function,
|
||||||
args,
|
args,
|
||||||
@ -1460,6 +1495,14 @@ invokeNative(Thread* t, object method)
|
|||||||
size,
|
size,
|
||||||
returnType);
|
returnType);
|
||||||
|
|
||||||
|
if (DebugRun) {
|
||||||
|
fprintf(stderr, "return from native method %s.%s\n",
|
||||||
|
&byteArrayBody
|
||||||
|
(t, className(t, methodClass(t, frameMethod(t, t->frame))), 0),
|
||||||
|
&byteArrayBody
|
||||||
|
(t, methodName(t, frameMethod(t, t->frame)), 0));
|
||||||
|
}
|
||||||
|
|
||||||
if (not builtin) {
|
if (not builtin) {
|
||||||
enter(t, oldState);
|
enter(t, oldState);
|
||||||
}
|
}
|
||||||
@ -1477,15 +1520,26 @@ invokeNative(Thread* t, object method)
|
|||||||
case ShortField:
|
case ShortField:
|
||||||
case FloatField:
|
case FloatField:
|
||||||
case IntField:
|
case IntField:
|
||||||
|
if (DebugRun) {
|
||||||
|
fprintf(stderr, "result: " LLD "\n", result);
|
||||||
|
}
|
||||||
pushInt(t, result);
|
pushInt(t, result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LongField:
|
case LongField:
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
|
if (DebugRun) {
|
||||||
|
fprintf(stderr, "result: " LLD "\n", result);
|
||||||
|
}
|
||||||
pushLong(t, result);
|
pushLong(t, result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
|
if (DebugRun) {
|
||||||
|
fprintf(stderr, "result: %p at %p\n", result == 0 ? 0 :
|
||||||
|
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)),
|
||||||
|
reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
|
||||||
|
}
|
||||||
pushObject(t, result == 0 ? 0 :
|
pushObject(t, result == 0 ? 0 :
|
||||||
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
|
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
|
||||||
break;
|
break;
|
||||||
@ -1622,28 +1676,19 @@ run(Thread* t)
|
|||||||
pushObject(t, array);
|
pushObject(t, array);
|
||||||
} else {
|
} else {
|
||||||
object message = makeString(t, "%d", count);
|
object message = makeString(t, "%d", count);
|
||||||
exception = makeNegativeArrayStoreException(t, message);
|
exception = makeNegativeArraySizeException(t, message);
|
||||||
goto throw_;
|
goto throw_;
|
||||||
}
|
}
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case areturn:
|
case areturn: {
|
||||||
case ireturn:
|
object result = popObject(t);
|
||||||
case lreturn: {
|
|
||||||
popFrame(t);
|
popFrame(t);
|
||||||
if (frame >= 0) {
|
if (frame >= 0) {
|
||||||
|
pushObject(t, result);
|
||||||
goto loop;
|
goto loop;
|
||||||
} else {
|
} else {
|
||||||
switch (instruction) {
|
return result;
|
||||||
case areturn:
|
|
||||||
return popObject(t);
|
|
||||||
|
|
||||||
case ireturn:
|
|
||||||
return makeInt(t, popInt(t));
|
|
||||||
|
|
||||||
case lreturn:
|
|
||||||
return makeLong(t, popLong(t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
@ -1655,14 +1700,14 @@ run(Thread* t)
|
|||||||
{
|
{
|
||||||
pushInt(t, objectArrayLength(t, array));
|
pushInt(t, objectArrayLength(t, array));
|
||||||
} else {
|
} else {
|
||||||
// for all other array types, the length follow the class pointer.
|
// for all other array types, the length follows the class pointer.
|
||||||
pushInt(t, cast<uint32_t>(array, BytesPerWord));
|
pushInt(t, cast<uint32_t>(array, BytesPerWord));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
goto throw_;
|
goto throw_;
|
||||||
}
|
}
|
||||||
} abort(t);
|
} goto loop;
|
||||||
|
|
||||||
case astore: {
|
case astore: {
|
||||||
setLocalObject(t, codeBody(t, code, ip++), popObject(t));
|
setLocalObject(t, codeBody(t, code, ip++), popObject(t));
|
||||||
@ -2168,7 +2213,7 @@ run(Thread* t)
|
|||||||
int32_t b = popInt(t);
|
int32_t b = popInt(t);
|
||||||
int32_t a = popInt(t);
|
int32_t a = popInt(t);
|
||||||
|
|
||||||
if (a < b) {
|
if (a <= b) {
|
||||||
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
||||||
}
|
}
|
||||||
} goto loop;
|
} goto loop;
|
||||||
@ -2405,6 +2450,17 @@ run(Thread* t)
|
|||||||
pushInt(t, a % b);
|
pushInt(t, a % b);
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
|
case ireturn: {
|
||||||
|
int32_t result = popInt(t);
|
||||||
|
popFrame(t);
|
||||||
|
if (frame >= 0) {
|
||||||
|
pushInt(t, result);
|
||||||
|
goto loop;
|
||||||
|
} else {
|
||||||
|
return makeInt(t, result);
|
||||||
|
}
|
||||||
|
} goto loop;
|
||||||
|
|
||||||
case ishl: {
|
case ishl: {
|
||||||
int32_t b = popInt(t);
|
int32_t b = popInt(t);
|
||||||
int32_t a = popInt(t);
|
int32_t a = popInt(t);
|
||||||
@ -2480,7 +2536,7 @@ run(Thread* t)
|
|||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case l2i: {
|
case l2i: {
|
||||||
pushLong(t, static_cast<int32_t>(popLong(t)));
|
pushInt(t, static_cast<int32_t>(popLong(t)));
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case ladd: {
|
case ladd: {
|
||||||
@ -2649,6 +2705,17 @@ run(Thread* t)
|
|||||||
pushLong(t, a % b);
|
pushLong(t, a % b);
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
|
case lreturn: {
|
||||||
|
int64_t result = popLong(t);
|
||||||
|
popFrame(t);
|
||||||
|
if (frame >= 0) {
|
||||||
|
pushLong(t, result);
|
||||||
|
goto loop;
|
||||||
|
} else {
|
||||||
|
return makeLong(t, result);
|
||||||
|
}
|
||||||
|
} goto loop;
|
||||||
|
|
||||||
case lshl: {
|
case lshl: {
|
||||||
int64_t b = popLong(t);
|
int64_t b = popLong(t);
|
||||||
int64_t a = popLong(t);
|
int64_t a = popLong(t);
|
||||||
@ -2707,7 +2774,7 @@ run(Thread* t)
|
|||||||
case monitorenter: {
|
case monitorenter: {
|
||||||
object o = popObject(t);
|
object o = popObject(t);
|
||||||
if (LIKELY(o)) {
|
if (LIKELY(o)) {
|
||||||
objectMonitor(t, o)->acquire(t);
|
acquire(t, o);
|
||||||
} else {
|
} else {
|
||||||
exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
goto throw_;
|
goto throw_;
|
||||||
@ -2717,7 +2784,7 @@ run(Thread* t)
|
|||||||
case monitorexit: {
|
case monitorexit: {
|
||||||
object o = popObject(t);
|
object o = popObject(t);
|
||||||
if (LIKELY(o)) {
|
if (LIKELY(o)) {
|
||||||
objectMonitor(t, o)->release(t);
|
release(t, o);
|
||||||
} else {
|
} else {
|
||||||
exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
goto throw_;
|
goto throw_;
|
||||||
@ -2790,7 +2857,7 @@ run(Thread* t)
|
|||||||
pushObject(t, array);
|
pushObject(t, array);
|
||||||
} else {
|
} else {
|
||||||
object message = makeString(t, "%d", count);
|
object message = makeString(t, "%d", count);
|
||||||
exception = makeNegativeArrayStoreException(t, message);
|
exception = makeNegativeArraySizeException(t, message);
|
||||||
goto throw_;
|
goto throw_;
|
||||||
}
|
}
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
@ -40,6 +40,7 @@ class System: public Allocator {
|
|||||||
virtual void wait(void* context, int64_t time) = 0;
|
virtual void wait(void* context, int64_t time) = 0;
|
||||||
virtual void notify(void* context) = 0;
|
virtual void notify(void* context) = 0;
|
||||||
virtual void notifyAll(void* context) = 0;
|
virtual void notifyAll(void* context) = 0;
|
||||||
|
virtual void* owner() = 0;
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1475,42 +1475,25 @@ writeInitialization(Output* out, Object* type)
|
|||||||
out->write(" object mask = 0;\n");
|
out->write(" object mask = 0;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeJavaName(type)) {
|
if (typeJavaName(type) and typeSuper(type)) {
|
||||||
if (typeObjectMask(type) != 1) {
|
|
||||||
out->write(" PROTECT(t, mask);\n");
|
|
||||||
}
|
|
||||||
out->write(" object name = ::makeByteArray(t, \"");
|
|
||||||
out->write(typeJavaName(type));
|
|
||||||
out->write("\");\n");
|
|
||||||
|
|
||||||
if (typeSuper(type)) {
|
|
||||||
out->write(" object super = arrayBody(t, t->vm->types, Machine::");
|
out->write(" object super = arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write(capitalize(typeName(typeSuper(type))));
|
out->write(capitalize(typeName(typeSuper(type))));
|
||||||
out->write("Type);\n");
|
out->write("Type);\n");
|
||||||
} else {
|
} else {
|
||||||
out->write(" object super = 0;\n");
|
out->write(" object super = 0;\n");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
out->write(" object name = 0;\n");
|
|
||||||
out->write(" object super = 0;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
out->write(" object class_ = makeClass");
|
out->write(" object class_ = makeClass");
|
||||||
out->write("(t, 0, 0, ");
|
out->write("(t, 0, 0, ");
|
||||||
out->write(typeFixedSize(type));
|
out->write(typeFixedSize(type));
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(typeArrayElementSize(type));
|
out->write(typeArrayElementSize(type));
|
||||||
out->write(", mask, name, super, 0, 0, 0, 0, 0, 0);\n");
|
out->write(", mask, 0, super, 0, 0, 0, 0, 0, 0);\n");
|
||||||
|
|
||||||
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write(capitalize(typeName(type)));
|
out->write(capitalize(typeName(type)));
|
||||||
out->write("Type), class_);\n");
|
out->write("Type), class_);\n");
|
||||||
|
|
||||||
if (typeJavaName(type)) {
|
|
||||||
out->write(" hashMapInsert(t, t->vm->bootstrapClassMap, ");
|
|
||||||
out->write("className(t, class_), class_, byteArrayHash);\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
out->write("}\n\n");
|
out->write("}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1549,10 +1532,38 @@ writeInitializations(Output* out, Object* declarations)
|
|||||||
|
|
||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
Object* o = car(p);
|
Object* o = car(p);
|
||||||
if (o->type == Object::Type and typeJavaName(o) == 0) {
|
if (o->type == Object::Type and equal(typeName(o), "intArray")) {
|
||||||
writeInitialization(out, o);
|
writeInitialization(out, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
|
Object* o = car(p);
|
||||||
|
if (o->type == Object::Type and not equal(typeName(o), "intArray")) {
|
||||||
|
writeInitialization(out, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
writeJavaInitialization(Output* out, Object* type)
|
||||||
|
{
|
||||||
|
out->write("{\n");
|
||||||
|
|
||||||
|
out->write(" object name = ::makeByteArray(t, \"");
|
||||||
|
out->write(typeJavaName(type));
|
||||||
|
out->write("\");\n");
|
||||||
|
|
||||||
|
out->write(" object class_ = arrayBody(t, t->vm->types, Machine::");
|
||||||
|
out->write(capitalize(typeName(type)));
|
||||||
|
out->write("Type);\n");
|
||||||
|
|
||||||
|
out->write(" set(t, className(t, class_), name);\n");
|
||||||
|
|
||||||
|
out->write(" hashMapInsert(t, t->vm->bootstrapClassMap, ");
|
||||||
|
out->write("name, class_, byteArrayHash);\n");
|
||||||
|
|
||||||
|
out->write("}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1561,7 +1572,7 @@ writeJavaInitializations(Output* out, Object* declarations)
|
|||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
Object* o = car(p);
|
Object* o = car(p);
|
||||||
if (o->type == Object::Type and typeJavaName(o)) {
|
if (o->type == Object::Type and typeJavaName(o)) {
|
||||||
writeInitialization(out, o);
|
writeJavaInitialization(out, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1570,7 +1581,8 @@ void
|
|||||||
usageAndExit(const char* command)
|
usageAndExit(const char* command)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s {enums,declarations,constructors,initializations}\n",
|
"usage: %s {enums,declarations,constructors,initializations,"
|
||||||
|
"java-initializations}\n",
|
||||||
command);
|
command);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
(type intArray
|
|
||||||
(array int32_t body))
|
|
||||||
|
|
||||||
(type class
|
(type class
|
||||||
(uint16_t flags)
|
(uint16_t flags)
|
||||||
(uint16_t vmFlags)
|
(uint16_t vmFlags)
|
||||||
@ -108,31 +105,6 @@
|
|||||||
(type array
|
(type array
|
||||||
(noassert array object body))
|
(noassert array object body))
|
||||||
|
|
||||||
(type objectArray
|
|
||||||
(object elementClass)
|
|
||||||
(array object body))
|
|
||||||
|
|
||||||
(type byteArray
|
|
||||||
(array int8_t body))
|
|
||||||
|
|
||||||
(type booleanArray
|
|
||||||
(array int8_t body))
|
|
||||||
|
|
||||||
(type shortArray
|
|
||||||
(array int16_t body))
|
|
||||||
|
|
||||||
(type charArray
|
|
||||||
(array uint16_t body))
|
|
||||||
|
|
||||||
(type longArray
|
|
||||||
(array int64_t body))
|
|
||||||
|
|
||||||
(type floatArray
|
|
||||||
(array uint32_t body))
|
|
||||||
|
|
||||||
(type doubleArray
|
|
||||||
(array uint64_t body))
|
|
||||||
|
|
||||||
|
|
||||||
(type jobject java/lang/Object)
|
(type jobject java/lang/Object)
|
||||||
|
|
||||||
@ -166,11 +138,17 @@
|
|||||||
(type illegalStateException java/lang/IllegalStateException
|
(type illegalStateException java/lang/IllegalStateException
|
||||||
(extends runtimeException))
|
(extends runtimeException))
|
||||||
|
|
||||||
|
(type illegalMonitorStateException java/lang/IllegalMonitorStateException
|
||||||
|
(extends runtimeException))
|
||||||
|
|
||||||
(type arrayIndexOutOfBoundsException
|
(type arrayIndexOutOfBoundsException
|
||||||
java/lang/ArrayIndexOutOfBoundsException
|
java/lang/ArrayIndexOutOfBoundsException
|
||||||
(extends runtimeException))
|
(extends runtimeException))
|
||||||
|
|
||||||
(type negativeArrayStoreException java/lang/NegativeArrayStoreException
|
(type arrayStoreException java/lang/arrayStoreException
|
||||||
|
(extends runtimeException))
|
||||||
|
|
||||||
|
(type negativeArraySizeException java/lang/NegativeArraySizeException
|
||||||
(extends runtimeException))
|
(extends runtimeException))
|
||||||
|
|
||||||
(type classCastException java/lang/ClassCastException
|
(type classCastException java/lang/ClassCastException
|
||||||
@ -228,8 +206,45 @@
|
|||||||
|
|
||||||
(type jreference java/lang/ref/Reference
|
(type jreference java/lang/ref/Reference
|
||||||
(extends jobject)
|
(extends jobject)
|
||||||
(object target))
|
(void* target)
|
||||||
|
(void* next))
|
||||||
|
|
||||||
(type weakReference java/lang/ref/WeakReference
|
(type weakReference java/lang/ref/WeakReference
|
||||||
(extends jreference)
|
(extends jreference))
|
||||||
(object next))
|
|
||||||
|
(type objectArray [
|
||||||
|
(extends jobject)
|
||||||
|
(object elementClass)
|
||||||
|
(array object body))
|
||||||
|
|
||||||
|
(type byteArray [B
|
||||||
|
(extends jobject)
|
||||||
|
(array int8_t body))
|
||||||
|
|
||||||
|
(type booleanArray [Z
|
||||||
|
(extends jobject)
|
||||||
|
(array int8_t body))
|
||||||
|
|
||||||
|
(type shortArray [S
|
||||||
|
(extends jobject)
|
||||||
|
(array int16_t body))
|
||||||
|
|
||||||
|
(type charArray [C
|
||||||
|
(extends jobject)
|
||||||
|
(array uint16_t body))
|
||||||
|
|
||||||
|
(type intArray [I
|
||||||
|
(extends jobject)
|
||||||
|
(array int32_t body))
|
||||||
|
|
||||||
|
(type longArray [J
|
||||||
|
(extends jobject)
|
||||||
|
(array int64_t body))
|
||||||
|
|
||||||
|
(type floatArray [F
|
||||||
|
(extends jobject)
|
||||||
|
(array uint32_t body))
|
||||||
|
|
||||||
|
(type doubleArray [D
|
||||||
|
(extends jobject)
|
||||||
|
(array uint64_t body))
|
||||||
|
Loading…
Reference in New Issue
Block a user