reformat changes since master

This commit is contained in:
Joshua Warner 2014-07-11 09:47:57 -06:00
parent cbad6931af
commit 7642b94308
39 changed files with 5007 additions and 4371 deletions

View File

@ -58,21 +58,23 @@ Java_java_net_Socket_closeInput(JNIEnv* e, jclass, SOCKET sock) {
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments) { /* SOCKET s, object buffer_obj, int start_pos, int count */ Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments) { /* SOCKET s, object buffer_obj, int start_pos, int count */
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0])); SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(t, reinterpret_cast<vm::object>(arguments[2])); vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3])); t, reinterpret_cast<vm::object>(arguments[2]));
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4])); int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4]));
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]); char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
avian::classpath::sockets::send((JNIEnv*)t, s, buffer, count); avian::classpath::sockets::send((JNIEnv*)t, s, buffer, count);
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments) { /* SOCKET s, object buffer_obj, int start_pos, int count */ Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments) { /* SOCKET s, object buffer_obj, int start_pos, int count */
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0])); SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(t, reinterpret_cast<vm::object>(arguments[2])); vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3])); t, reinterpret_cast<vm::object>(arguments[2]));
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4])); int32_t& count = *(reinterpret_cast<int32_t*>(&arguments[4]));
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]); char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
return avian::classpath::sockets::recv((JNIEnv*)t, s, buffer, count); return avian::classpath::sockets::recv((JNIEnv*)t, s, buffer, count);
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL

View File

@ -160,4 +160,4 @@ class DelayedPromise: public ListenPromise {
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian
#endif // AVIAN_CODEGEN_PROMISE_H #endif // AVIAN_CODEGEN_PROMISE_H

View File

@ -70,4 +70,4 @@ public:
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian
#endif // AVIAN_CODEGEN_REGISTERS_H #endif // AVIAN_CODEGEN_REGISTERS_H

View File

@ -75,7 +75,7 @@ class Heap : public avian::util::Allocator {
virtual void pad(void* p) = 0; virtual void pad(void* p) = 0;
virtual void* follow(void* p) = 0; virtual void* follow(void* p) = 0;
template<class T> template <class T>
T* follow(T* p) T* follow(T* p)
{ {
return static_cast<T*>(follow((void*)p)); return static_cast<T*>(follow((void*)p));

View File

@ -44,8 +44,9 @@ inline void expect(T t, bool v) {
#ifdef NDEBUG #ifdef NDEBUG
#define assertT(t, v) #define assertT(t, v)
#else #else
template<class T> template <class T>
inline void assertT(T t, bool v) { inline void assertT(T t, bool v)
{
expect(t, v); expect(t, v);
} }
#endif #endif

View File

@ -46,4 +46,4 @@ public:
} // namespace avian } // namespace avian
} // namespace util } // namespace util
#endif // AVIAN_UTIL_ARG_PARSER_H #endif // AVIAN_UTIL_ARG_PARSER_H

View File

@ -37,8 +37,8 @@ inline uint32_t hash(Slice<const uint8_t> data)
inline uint32_t hash(Slice<const int8_t> data) inline uint32_t hash(Slice<const int8_t> data)
{ {
return hash( return hash(Slice<const uint8_t>(
Slice<const uint8_t>(reinterpret_cast<const uint8_t*>(data.begin()), data.count)); reinterpret_cast<const uint8_t*>(data.begin()), data.count));
} }
inline uint32_t hash(Slice<const uint16_t> data) inline uint32_t hash(Slice<const uint16_t> data)

View File

@ -21,7 +21,6 @@ namespace util {
template <class T> template <class T>
struct NonConst; struct NonConst;
template <class T> template <class T>
struct NonConst<const T> { struct NonConst<const T> {
typedef T Type; typedef T Type;
@ -42,7 +41,8 @@ class Slice {
{ {
} }
inline Slice(const Slice<typename NonConst<T>::Type>& copy) : items(copy.items), count(copy.count) inline Slice(const Slice<typename NonConst<T>::Type>& copy)
: items(copy.items), count(copy.count)
{ {
} }

View File

@ -30,12 +30,9 @@ getTrace(Thread* t, unsigned skipCount)
virtual bool visit(Processor::StackWalker* walker) { virtual bool visit(Processor::StackWalker* walker) {
if (skipCount == 0) { if (skipCount == 0) {
GcMethod* method = walker->method(); GcMethod* method = walker->method();
if (isAssignableFrom if (isAssignableFrom(t, type(t, GcThrowable::Type), method->class_())
(t, type(t, GcThrowable::Type), method->class_())
and vm::strcmp(reinterpret_cast<const int8_t*>("<init>"), and vm::strcmp(reinterpret_cast<const int8_t*>("<init>"),
method->name()->body().begin()) method->name()->body().begin()) == 0) {
== 0)
{
return true; return true;
} else { } else {
trace = makeTrace(t, walker); trace = makeTrace(t, walker);
@ -59,14 +56,11 @@ getTrace(Thread* t, unsigned skipCount)
return v.trace; return v.trace;
} }
bool bool compatibleArrayTypes(Thread* t UNUSED, GcClass* a, GcClass* b)
compatibleArrayTypes(Thread* t UNUSED, GcClass* a, GcClass* b)
{ {
return a->arrayElementSize() return a->arrayElementSize() and b->arrayElementSize()
and b->arrayElementSize() and (a == b or (not((a->vmFlags() & PrimitiveFlag)
and (a == b or (b->vmFlags() & PrimitiveFlag))));
or (not ((a->vmFlags() & PrimitiveFlag)
or (b->vmFlags() & PrimitiveFlag))));
} }
void void
@ -239,8 +233,11 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
runOnLoadIfFound(t, lib); runOnLoadIfFound(t, lib);
} }
} else if (throw_) { } else if (throw_) {
throwNew(t, GcUnsatisfiedLinkError::Type, throwNew(t,
"library not found in %s: %s", path, name); GcUnsatisfiedLinkError::Type,
"library not found in %s: %s",
path,
name);
} }
return lib; return lib;
@ -268,17 +265,20 @@ clone(Thread* t, object o)
} else { } else {
GcByteArray* classNameSlash = objectClass(t, o)->name(); GcByteArray* classNameSlash = objectClass(t, o)->name();
THREAD_RUNTIME_ARRAY(t, char, classNameDot, classNameSlash->length()); THREAD_RUNTIME_ARRAY(t, char, classNameDot, classNameSlash->length());
replace('/', '.', RUNTIME_ARRAY_BODY(classNameDot), replace('/',
'.',
RUNTIME_ARRAY_BODY(classNameDot),
reinterpret_cast<char*>(classNameSlash->body().begin())); reinterpret_cast<char*>(classNameSlash->body().begin()));
throwNew(t, GcCloneNotSupportedException::Type, "%s", throwNew(t,
GcCloneNotSupportedException::Type,
"%s",
RUNTIME_ARRAY_BODY(classNameDot)); RUNTIME_ARRAY_BODY(classNameDot));
} }
return clone; return clone;
} }
GcStackTraceElement* GcStackTraceElement* makeStackTraceElement(Thread* t, GcTraceElement* e)
makeStackTraceElement(Thread* t, GcTraceElement* e)
{ {
PROTECT(t, e); PROTECT(t, e);
@ -289,7 +289,9 @@ makeStackTraceElement(Thread* t, GcTraceElement* e)
PROTECT(t, class_name); PROTECT(t, class_name);
THREAD_RUNTIME_ARRAY(t, char, s, class_name->length()); THREAD_RUNTIME_ARRAY(t, char, s, class_name->length());
replace('/', '.', RUNTIME_ARRAY_BODY(s), replace('/',
'.',
RUNTIME_ARRAY_BODY(s),
reinterpret_cast<char*>(class_name->body().begin())); reinterpret_cast<char*>(class_name->body().begin()));
GcString* class_name_string = makeString(t, "%s", RUNTIME_ARRAY_BODY(s)); GcString* class_name_string = makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
PROTECT(t, class_name_string); PROTECT(t, class_name_string);
@ -297,22 +299,21 @@ makeStackTraceElement(Thread* t, GcTraceElement* e)
GcByteArray* method_name = method->name(); GcByteArray* method_name = method->name();
PROTECT(t, method_name); PROTECT(t, method_name);
GcString* method_name_string = t->m->classpath->makeString GcString* method_name_string = t->m->classpath->makeString(
(t, method_name, 0, method_name->length() - 1); t, method_name, 0, method_name->length() - 1);
PROTECT(t, method_name_string); PROTECT(t, method_name_string);
unsigned line = t->m->processor->lineNumber unsigned line = t->m->processor->lineNumber(t, method, e->ip());
(t, method, e->ip());
GcByteArray* file = method->class_()->sourceFile(); GcByteArray* file = method->class_()->sourceFile();
GcString* file_string = file ? t->m->classpath->makeString GcString* file_string
(t, file, 0, file->length() - 1) : 0; = file ? t->m->classpath->makeString(t, file, 0, file->length() - 1) : 0;
return makeStackTraceElement(t, class_name_string, method_name_string, file_string, line); return makeStackTraceElement(
t, class_name_string, method_name_string, file_string, line);
} }
GcObject* GcObject* translateInvokeResult(Thread* t, unsigned returnCode, object o)
translateInvokeResult(Thread* t, unsigned returnCode, object o)
{ {
switch (returnCode) { switch (returnCode) {
case ByteField: case ByteField:
@ -344,9 +345,10 @@ translateInvokeResult(Thread* t, unsigned returnCode, object o)
} }
} }
GcClass* GcClass* resolveClassBySpec(Thread* t,
resolveClassBySpec(Thread* t, GcClassLoader* loader, const char* spec, GcClassLoader* loader,
unsigned specLength) const char* spec,
unsigned specLength)
{ {
switch (*spec) { switch (*spec) {
case 'L': { case 'L': {
@ -368,15 +370,19 @@ resolveClassBySpec(Thread* t, GcClassLoader* loader, const char* spec,
} }
} }
GcJclass* GcJclass* resolveJType(Thread* t,
resolveJType(Thread* t, GcClassLoader* loader, const char* spec, unsigned specLength) GcClassLoader* loader,
const char* spec,
unsigned specLength)
{ {
return getJClass(t, resolveClassBySpec(t, loader, spec, specLength)); return getJClass(t, resolveClassBySpec(t, loader, spec, specLength));
} }
GcPair* GcPair* resolveParameterTypes(Thread* t,
resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec, GcClassLoader* loader,
unsigned* parameterCount, unsigned* returnTypeSpec) GcByteArray* spec,
unsigned* parameterCount,
unsigned* returnTypeSpec)
{ {
PROTECT(t, loader); PROTECT(t, loader);
PROTECT(t, spec); PROTECT(t, spec);
@ -391,12 +397,15 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
case 'L': { case 'L': {
unsigned start = offset; unsigned start = offset;
++ offset; ++ offset;
while (spec->body()[offset] != ';') ++ offset; while (spec->body()[offset] != ';')
++offset;
++ offset; ++ offset;
GcClass* type = resolveClassBySpec GcClass* type
(t, loader, reinterpret_cast<char*>(&spec->body()[start]), = resolveClassBySpec(t,
offset - start); loader,
reinterpret_cast<char*>(&spec->body()[start]),
offset - start);
list = makePair(t, type, list); list = makePair(t, type, list);
@ -405,11 +414,13 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
case '[': { case '[': {
unsigned start = offset; unsigned start = offset;
while (spec->body()[offset] == '[') ++ offset; while (spec->body()[offset] == '[')
++offset;
switch (spec->body()[offset]) { switch (spec->body()[offset]) {
case 'L': case 'L':
++ offset; ++ offset;
while (spec->body()[offset] != ';') ++ offset; while (spec->body()[offset] != ';')
++offset;
++ offset; ++ offset;
break; break;
@ -418,17 +429,18 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
break; break;
} }
GcClass* type = resolveClassBySpec GcClass* type
(t, loader, reinterpret_cast<char*>(&spec->body()[start]), = resolveClassBySpec(t,
offset - start); loader,
reinterpret_cast<char*>(&spec->body()[start]),
offset - start);
list = makePair(t, type, list); list = makePair(t, type, list);
++ count; ++ count;
} break; } break;
default: default:
list = makePair list = makePair(t, primitiveClass(t, spec->body()[offset]), list);
(t, primitiveClass(t, spec->body()[offset]), list);
++ offset; ++ offset;
++ count; ++ count;
break; break;
@ -440,17 +452,18 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
return list; return list;
} }
object object resolveParameterJTypes(Thread* t,
resolveParameterJTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec, GcClassLoader* loader,
unsigned* parameterCount, unsigned* returnTypeSpec) GcByteArray* spec,
unsigned* parameterCount,
unsigned* returnTypeSpec)
{ {
GcPair* list = resolveParameterTypes GcPair* list
(t, loader, spec, parameterCount, returnTypeSpec); = resolveParameterTypes(t, loader, spec, parameterCount, returnTypeSpec);
PROTECT(t, list); PROTECT(t, list);
object array = makeObjectArray object array = makeObjectArray(t, type(t, GcJclass::Type), *parameterCount);
(t, type(t, GcJclass::Type), *parameterCount);
PROTECT(t, array); PROTECT(t, array);
for (int i = *parameterCount - 1; i >= 0; --i) { for (int i = *parameterCount - 1; i >= 0; --i) {
@ -462,8 +475,9 @@ resolveParameterJTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
return array; return array;
} }
object object resolveExceptionJTypes(Thread* t,
resolveExceptionJTypes(Thread* t, GcClassLoader* loader, GcMethodAddendum* addendum) GcClassLoader* loader,
GcMethodAddendum* addendum)
{ {
if (addendum == 0 or addendum->exceptionTable() == 0) { if (addendum == 0 or addendum->exceptionTable() == 0) {
return makeObjectArray(t, type(t, GcJclass::Type), 0); return makeObjectArray(t, type(t, GcJclass::Type), 0);
@ -472,16 +486,15 @@ resolveExceptionJTypes(Thread* t, GcClassLoader* loader, GcMethodAddendum* adden
PROTECT(t, loader); PROTECT(t, loader);
PROTECT(t, addendum); PROTECT(t, addendum);
GcShortArray* exceptionTable = cast<GcShortArray>(t, addendum->exceptionTable()); GcShortArray* exceptionTable
= cast<GcShortArray>(t, addendum->exceptionTable());
PROTECT(t, exceptionTable); PROTECT(t, exceptionTable);
object array = makeObjectArray object array
(t, type(t, GcJclass::Type), = makeObjectArray(t, type(t, GcJclass::Type), exceptionTable->length());
exceptionTable->length());
PROTECT(t, array); PROTECT(t, array);
for (unsigned i = 0; i < exceptionTable->length(); ++i) for (unsigned i = 0; i < exceptionTable->length(); ++i) {
{
uint16_t index = exceptionTable->body()[i] - 1; uint16_t index = exceptionTable->body()[i] - 1;
object o = singletonObject(t, addendum->pool()->as<GcSingleton>(t), index); object o = singletonObject(t, addendum->pool()->as<GcSingleton>(t), index);
@ -489,7 +502,8 @@ resolveExceptionJTypes(Thread* t, GcClassLoader* loader, GcMethodAddendum* adden
if (objectClass(t, o) == type(t, GcReference::Type)) { if (objectClass(t, o) == type(t, GcReference::Type)) {
o = resolveClass(t, loader, cast<GcReference>(t, o)->name()); o = resolveClass(t, loader, cast<GcReference>(t, o)->name());
addendum->pool()->setBodyElement(t, index, reinterpret_cast<uintptr_t>(o)); addendum->pool()->setBodyElement(
t, index, reinterpret_cast<uintptr_t>(o));
} }
o = getJClass(t, cast<GcClass>(t, o)); o = getJClass(t, cast<GcClass>(t, o));
@ -500,8 +514,7 @@ resolveExceptionJTypes(Thread* t, GcClassLoader* loader, GcMethodAddendum* adden
return array; return array;
} }
object object invoke(Thread* t, GcMethod* method, object instance, object args)
invoke(Thread* t, GcMethod* method, object instance, object args)
{ {
PROTECT(t, method); PROTECT(t, method);
PROTECT(t, instance); PROTECT(t, instance);
@ -512,30 +525,45 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
} }
if ((args == 0 ? 0 : objectArrayLength(t, args)) if ((args == 0 ? 0 : objectArrayLength(t, args))
!= method->parameterCount()) != method->parameterCount()) {
{
throwNew(t, GcIllegalArgumentException::Type); throwNew(t, GcIllegalArgumentException::Type);
} }
if (method->parameterCount()) { if (method->parameterCount()) {
unsigned specLength = method->spec()->length(); unsigned specLength = method->spec()->length();
THREAD_RUNTIME_ARRAY(t, char, spec, specLength); THREAD_RUNTIME_ARRAY(t, char, spec, specLength);
memcpy(RUNTIME_ARRAY_BODY(spec), memcpy(
method->spec()->body().begin(), specLength); RUNTIME_ARRAY_BODY(spec), method->spec()->body().begin(), specLength);
unsigned i = 0; unsigned i = 0;
for (MethodSpecIterator it(t, RUNTIME_ARRAY_BODY(spec)); it.hasNext();) { for (MethodSpecIterator it(t, RUNTIME_ARRAY_BODY(spec)); it.hasNext();) {
GcClass* type; GcClass* type;
bool objectType = false; bool objectType = false;
const char* p = it.next(); const char* p = it.next();
switch (*p) { switch (*p) {
case 'Z': type = vm::type(t, GcBoolean::Type); break; case 'Z':
case 'B': type = vm::type(t, GcByte::Type); break; type = vm::type(t, GcBoolean::Type);
case 'S': type = vm::type(t, GcShort::Type); break; break;
case 'C': type = vm::type(t, GcChar::Type); break; case 'B':
case 'I': type = vm::type(t, GcInt::Type); break; type = vm::type(t, GcByte::Type);
case 'F': type = vm::type(t, GcFloat::Type); break; break;
case 'J': type = vm::type(t, GcLong::Type); break; case 'S':
case 'D': type = vm::type(t, GcDouble::Type); break; type = vm::type(t, GcShort::Type);
break;
case 'C':
type = vm::type(t, GcChar::Type);
break;
case 'I':
type = vm::type(t, GcInt::Type);
break;
case 'F':
type = vm::type(t, GcFloat::Type);
break;
case 'J':
type = vm::type(t, GcLong::Type);
break;
case 'D':
type = vm::type(t, GcDouble::Type);
break;
case 'L': case 'L':
case '[': { case '[': {
@ -550,9 +578,8 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
THREAD_RUNTIME_ARRAY(t, char, name, nameLength); THREAD_RUNTIME_ARRAY(t, char, name, nameLength);
memcpy(RUNTIME_ARRAY_BODY(name), p, nameLength - 1); memcpy(RUNTIME_ARRAY_BODY(name), p, nameLength - 1);
RUNTIME_ARRAY_BODY(name)[nameLength - 1] = 0; RUNTIME_ARRAY_BODY(name)[nameLength - 1] = 0;
type = resolveClass type = resolveClass(
(t, method->class_()->loader(), t, method->class_()->loader(), RUNTIME_ARRAY_BODY(name));
RUNTIME_ARRAY_BODY(name));
} break; } break;
default: default:
@ -576,10 +603,11 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
THREAD_RESOURCE0(t, { THREAD_RESOURCE0(t, {
if (t->exception) { if (t->exception) {
t->exception = makeThrowable t->exception = makeThrowable(
(t, GcInvocationTargetException::Type, 0, 0, t->exception); t, GcInvocationTargetException::Type, 0, 0, t->exception);
t->exception->as<GcInvocationTargetException>(t)->setTarget(t, t->exception->cause()); t->exception->as<GcInvocationTargetException>(t)
->setTarget(t, t->exception->cause());
} }
}); });
@ -595,9 +623,12 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
// only safe to call during bootstrap when there's only one thread // only safe to call during bootstrap when there's only one thread
// running: // running:
void void intercept(Thread* t,
intercept(Thread* t, GcClass* c, const char* name, const char* spec, GcClass* c,
void* function, bool updateRuntimeData) const char* name,
const char* spec,
void* function,
bool updateRuntimeData)
{ {
GcMethod* m = findMethodOrNull(t, c, name, spec); GcMethod* m = findMethodOrNull(t, c, name, spec);
if (m) { if (m) {
@ -638,14 +669,11 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
{ {
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
for (GcFinder* p = roots(t)->virtualFileFinders(); for (GcFinder* p = roots(t)->virtualFileFinders(); p; p = p->next()) {
p; p = p->next())
{
if (p->name()->length() == nameLength if (p->name()->length() == nameLength
and strncmp(reinterpret_cast<const char*> and strncmp(reinterpret_cast<const char*>(p->name()->body().begin()),
(p->name()->body().begin()), name,
name, nameLength)) nameLength)) {
{
return static_cast<Finder*>(p->finder()); return static_cast<Finder*>(p->finder());
} }
} }
@ -653,8 +681,8 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
GcByteArray* n = makeByteArray(t, nameLength + 1); GcByteArray* n = makeByteArray(t, nameLength + 1);
memcpy(n->body().begin(), name, nameLength); memcpy(n->body().begin(), name, nameLength);
void* p = t->m->libraries->resolve void* p = t->m->libraries->resolve(
(reinterpret_cast<const char*>(n->body().begin())); reinterpret_cast<const char*>(n->body().begin()));
if (p) { if (p) {
uint8_t* (*function)(unsigned*); uint8_t* (*function)(unsigned*);
@ -664,8 +692,7 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
uint8_t* data = function(&size); uint8_t* data = function(&size);
if (data) { if (data) {
Finder* f = makeFinder(t->m->system, t->m->heap, data, size); Finder* f = makeFinder(t->m->system, t->m->heap, data, size);
GcFinder* finder = makeFinder GcFinder* finder = makeFinder(t, f, n, roots(t)->virtualFileFinders());
(t, f, n, roots(t)->virtualFileFinders());
roots(t)->setVirtualFileFinders(t, finder); roots(t)->setVirtualFileFinders(t, finder);
@ -676,8 +703,7 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
return 0; return 0;
} }
object object getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
{ {
GcClassAddendum* addendum = c->addendum(); GcClassAddendum* addendum = c->addendum();
if (addendum) { if (addendum) {
@ -687,12 +713,11 @@ getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
unsigned count = 0; unsigned count = 0;
for (unsigned i = 0; i < table->length(); ++i) { for (unsigned i = 0; i < table->length(); ++i) {
GcInnerClassReference* reference = cast<GcInnerClassReference>(t, table->body()[i]); GcInnerClassReference* reference
= cast<GcInnerClassReference>(t, table->body()[i]);
GcByteArray* outer = reference->outer(); GcByteArray* outer = reference->outer();
if (outer and byteArrayEqual(t, outer, c->name()) if (outer and byteArrayEqual(t, outer, c->name())
and ((not publicOnly) and ((not publicOnly) or (reference->flags() & ACC_PUBLIC))) {
or (reference->flags() & ACC_PUBLIC)))
{
++ count; ++ count;
} }
} }
@ -701,18 +726,13 @@ getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
PROTECT(t, result); PROTECT(t, result);
for (unsigned i = 0; i < table->length(); ++i) { for (unsigned i = 0; i < table->length(); ++i) {
GcInnerClassReference* reference = cast<GcInnerClassReference>(t, table->body()[i]); GcInnerClassReference* reference
= cast<GcInnerClassReference>(t, table->body()[i]);
GcByteArray* outer = reference->outer(); GcByteArray* outer = reference->outer();
if (outer and byteArrayEqual(t, outer, c->name()) if (outer and byteArrayEqual(t, outer, c->name())
and ((not publicOnly) and ((not publicOnly) or (reference->flags() & ACC_PUBLIC))) {
or (reference->flags() & ACC_PUBLIC))) object inner
{ = getJClass(t, resolveClass(t, c->loader(), reference->inner()));
object inner = getJClass(
t,
resolveClass(
t,
c->loader(),
reference->inner()));
-- count; -- count;
reinterpret_cast<GcArray*>(result)->setBodyElement(t, count, inner); reinterpret_cast<GcArray*>(result)->setBodyElement(t, count, inner);
@ -726,24 +746,19 @@ getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
return makeObjectArray(t, type(t, GcJclass::Type), 0); return makeObjectArray(t, type(t, GcJclass::Type), 0);
} }
GcJclass* GcJclass* getDeclaringClass(Thread* t, GcClass* c)
getDeclaringClass(Thread* t, GcClass* c)
{ {
GcClassAddendum* addendum = c->addendum(); GcClassAddendum* addendum = c->addendum();
if (addendum) { if (addendum) {
GcArray* table = cast<GcArray>(t, addendum->innerClassTable()); GcArray* table = cast<GcArray>(t, addendum->innerClassTable());
if (table) { if (table) {
for (unsigned i = 0; i < table->length(); ++i) { for (unsigned i = 0; i < table->length(); ++i) {
GcInnerClassReference* reference = cast<GcInnerClassReference>(t, table->body()[i]); GcInnerClassReference* reference
if (reference->outer() and strcmp = cast<GcInnerClassReference>(t, table->body()[i]);
(reference->inner()->body().begin(), if (reference->outer()
c->name()->body().begin()) == 0) and strcmp(reference->inner()->body().begin(),
{ c->name()->body().begin()) == 0) {
return getJClass( return getJClass(t, resolveClass(t, c->loader(), reference->outer()));
t,
resolveClass(t,
c->loader(),
reference->outer()));
} }
} }
} }
@ -752,19 +767,17 @@ getDeclaringClass(Thread* t, GcClass* c)
return 0; return 0;
} }
unsigned unsigned classModifiers(Thread* t, GcClass* c)
classModifiers(Thread* t, GcClass* c)
{ {
GcClassAddendum* addendum = c->addendum(); GcClassAddendum* addendum = c->addendum();
if (addendum) { if (addendum) {
GcArray* table = cast<GcArray>(t, addendum->innerClassTable()); GcArray* table = cast<GcArray>(t, addendum->innerClassTable());
if (table) { if (table) {
for (unsigned i = 0; i < table->length(); ++i) { for (unsigned i = 0; i < table->length(); ++i) {
GcInnerClassReference* reference = cast<GcInnerClassReference>(t, table->body()[i]); GcInnerClassReference* reference
if (0 == strcmp = cast<GcInnerClassReference>(t, table->body()[i]);
(c->name()->body().begin(), if (0 == strcmp(c->name()->body().begin(),
reference->inner()->body().begin())) reference->inner()->body().begin())) {
{
return reference->flags(); return reference->flags();
} }
} }

View File

@ -16,7 +16,8 @@ namespace vm {
class Machine; class Machine;
class Thread; class Thread;
class GcObject;; class GcObject;
;
typedef GcObject* object; typedef GcObject* object;

File diff suppressed because it is too large Load Diff

View File

@ -18,16 +18,14 @@
namespace vm { namespace vm {
inline int16_t inline int16_t codeReadInt16(Thread* t UNUSED, GcCode* code, unsigned& ip)
codeReadInt16(Thread* t UNUSED, GcCode* code, unsigned& ip)
{ {
uint8_t v1 = code->body()[ip++]; uint8_t v1 = code->body()[ip++];
uint8_t v2 = code->body()[ip++]; uint8_t v2 = code->body()[ip++];
return ((v1 << 8) | v2); return ((v1 << 8) | v2);
} }
inline int32_t inline int32_t codeReadInt32(Thread* t UNUSED, GcCode* code, unsigned& ip)
codeReadInt32(Thread* t UNUSED, GcCode* code, unsigned& ip)
{ {
uint8_t v1 = code->body()[ip++]; uint8_t v1 = code->body()[ip++];
uint8_t v2 = code->body()[ip++]; uint8_t v2 = code->body()[ip++];
@ -36,8 +34,7 @@ codeReadInt32(Thread* t UNUSED, GcCode* code, unsigned& ip)
return ((v1 << 24) | (v2 << 16) | (v3 << 8) | v4); return ((v1 << 24) | (v2 << 16) | (v3 << 8) | v4);
} }
inline bool inline bool isSuperclass(Thread* t UNUSED, GcClass* class_, GcClass* base)
isSuperclass(Thread* t UNUSED, GcClass* class_, GcClass* base)
{ {
for (GcClass* oc = base->super(); oc; oc = oc->super()) { for (GcClass* oc = base->super(); oc; oc = oc->super()) {
if (oc == class_) { if (oc == class_) {
@ -47,20 +44,17 @@ isSuperclass(Thread* t UNUSED, GcClass* class_, GcClass* base)
return false; return false;
} }
inline bool inline bool isSpecialMethod(Thread* t, GcMethod* method, GcClass* class_)
isSpecialMethod(Thread* t, GcMethod* method, GcClass* class_)
{ {
return (class_->flags() & ACC_SUPER) return (class_->flags() & ACC_SUPER)
and strcmp(reinterpret_cast<const int8_t*>("<init>"), and strcmp(reinterpret_cast<const int8_t*>("<init>"),
method->name()->body().begin()) != 0 method->name()->body().begin()) != 0
and isSuperclass(t, method->class_(), class_); and isSuperclass(t, method->class_(), class_);
} }
void void resolveNative(Thread* t, GcMethod* method);
resolveNative(Thread* t, GcMethod* method);
int int findLineNumber(Thread* t, GcMethod* method, unsigned ip);
findLineNumber(Thread* t, GcMethod* method, unsigned ip);
} // namespace vm } // namespace vm

View File

@ -74,46 +74,43 @@ class Processor {
virtual void dispose() = 0; virtual void dispose() = 0;
}; };
virtual Thread* virtual Thread* makeThread(Machine* m, GcThread* javaThread, Thread* parent)
makeThread(Machine* m, GcThread* javaThread, Thread* parent) = 0; = 0;
virtual GcMethod* virtual GcMethod* makeMethod(Thread* t,
makeMethod(Thread* t, uint8_t vmFlags,
uint8_t vmFlags, uint8_t returnCode,
uint8_t returnCode, uint8_t parameterCount,
uint8_t parameterCount, uint8_t parameterFootprint,
uint8_t parameterFootprint, uint16_t flags,
uint16_t flags, uint16_t offset,
uint16_t offset, GcByteArray* name,
GcByteArray* name, GcByteArray* spec,
GcByteArray* spec, GcMethodAddendum* addendum,
GcMethodAddendum* addendum, GcClass* class_,
GcClass* class_, GcCode* code) = 0;
GcCode* code) = 0;
virtual GcClass* virtual GcClass* makeClass(Thread* t,
makeClass(Thread* t, uint16_t flags,
uint16_t flags, uint16_t vmFlags,
uint16_t vmFlags, uint16_t fixedSize,
uint16_t fixedSize, uint8_t arrayElementSize,
uint8_t arrayElementSize, uint8_t arrayDimensions,
uint8_t arrayDimensions, GcClass* arrayElementClass,
GcClass* arrayElementClass, GcIntArray* objectMask,
GcIntArray* objectMask, GcByteArray* name,
GcByteArray* name, GcByteArray* sourceFile,
GcByteArray* sourceFile, GcClass* super,
GcClass* super, object interfaceTable,
object interfaceTable, object virtualTable,
object virtualTable, object fieldTable,
object fieldTable, object methodTable,
object methodTable, GcClassAddendum* addendum,
GcClassAddendum* addendum, GcSingleton* staticTable,
GcSingleton* staticTable, GcClassLoader* loader,
GcClassLoader* loader, unsigned vtableLength) = 0;
unsigned vtableLength) = 0;
virtual void virtual void initVtable(Thread* t, GcClass* c) = 0;
initVtable(Thread* t, GcClass* c) = 0;
virtual void virtual void
visitObjects(Thread* t, Heap::Visitor* v) = 0; visitObjects(Thread* t, Heap::Visitor* v) = 0;
@ -121,8 +118,7 @@ class Processor {
virtual void virtual void
walkStack(Thread* t, StackVisitor* v) = 0; walkStack(Thread* t, StackVisitor* v) = 0;
virtual int virtual int lineNumber(Thread* t, GcMethod* method, int ip) = 0;
lineNumber(Thread* t, GcMethod* method, int ip) = 0;
virtual object* virtual object*
makeLocalReference(Thread* t, object o) = 0; makeLocalReference(Thread* t, object o) = 0;
@ -136,21 +132,29 @@ class Processor {
virtual void virtual void
popLocalFrame(Thread* t) = 0; popLocalFrame(Thread* t) = 0;
virtual object virtual object invokeArray(Thread* t,
invokeArray(Thread* t, GcMethod* method, object this_, object arguments) = 0; GcMethod* method,
object this_,
object arguments) = 0;
virtual object virtual object invokeArray(Thread* t,
invokeArray(Thread* t, GcMethod* method, object this_, const jvalue* arguments) GcMethod* method,
= 0; object this_,
const jvalue* arguments) = 0;
virtual object virtual object invokeList(Thread* t,
invokeList(Thread* t, GcMethod* method, object this_, bool indirectObjects, GcMethod* method,
va_list arguments) = 0; object this_,
bool indirectObjects,
va_list arguments) = 0;
virtual object virtual object invokeList(Thread* t,
invokeList(Thread* t, GcClassLoader* loader, const char* className, GcClassLoader* loader,
const char* methodName, const char* methodSpec, const char* className,
object this_, va_list arguments) = 0; const char* methodName,
const char* methodSpec,
object this_,
va_list arguments) = 0;
virtual void virtual void
dispose(Thread* t) = 0; dispose(Thread* t) = 0;
@ -167,10 +171,13 @@ class Processor {
virtual void virtual void
addCompilationHandler(CompilationHandler* handler) = 0; addCompilationHandler(CompilationHandler* handler) = 0;
virtual void virtual void compileMethod(Thread* t,
compileMethod(Thread* t, Zone* zone, GcTriple** constants, GcTriple** calls, Zone* zone,
avian::codegen::DelayedPromise** addresses, GcMethod* method, GcTriple** constants,
OffsetResolver* resolver) = 0; GcTriple** calls,
avian::codegen::DelayedPromise** addresses,
GcMethod* method,
OffsetResolver* resolver) = 0;
virtual void virtual void
visitRoots(Thread* t, HeapWalker* w) = 0; visitRoots(Thread* t, HeapWalker* w) = 0;
@ -190,19 +197,19 @@ class Processor {
virtual void virtual void
dynamicWind(Thread* t, object before, object thunk, object after) = 0; dynamicWind(Thread* t, object before, object thunk, object after) = 0;
virtual void virtual void feedResultToContinuation(Thread* t,
feedResultToContinuation(Thread* t, GcContinuation* continuation, object result) = 0; GcContinuation* continuation,
object result) = 0;
virtual void virtual void feedExceptionToContinuation(Thread* t,
feedExceptionToContinuation(Thread* t, GcContinuation* continuation, GcContinuation* continuation,
GcThrowable* exception) = 0; GcThrowable* exception) = 0;
virtual void virtual void
walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start) walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start)
= 0; = 0;
object object invoke(Thread* t, GcMethod* method, object this_, ...)
invoke(Thread* t, GcMethod* method, object this_, ...)
{ {
va_list a; va_list a;
va_start(a, this_); va_start(a, this_);
@ -214,9 +221,13 @@ class Processor {
return r; return r;
} }
object object invoke(Thread* t,
invoke(Thread* t, GcClassLoader* loader, const char* className, GcClassLoader* loader,
const char* methodName, const char* methodSpec, object this_, ...) const char* className,
const char* methodName,
const char* methodSpec,
object this_,
...)
{ {
va_list a; va_list a;
va_start(a, this_); va_start(a, this_);

View File

@ -16,32 +16,39 @@
namespace vm { namespace vm {
GcTriple* GcTriple* hashMapFindNode(Thread* t,
hashMapFindNode(Thread* t, GcHashMap* map, object key, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)); uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object));
inline object inline object hashMapFind(Thread* t,
hashMapFind(Thread* t, GcHashMap* map, object key, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)) uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object))
{ {
GcTriple* n = hashMapFindNode(t, map, key, hash, equal); GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
return (n ? n->second() : 0); return (n ? n->second() : 0);
} }
void void hashMapResize(Thread* t,
hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object), GcHashMap* map,
unsigned size); uint32_t (*hash)(Thread*, object),
unsigned size);
void void hashMapInsert(Thread* t,
hashMapInsert(Thread* t, GcHashMap* map, object key, object value, GcHashMap* map,
uint32_t (*hash)(Thread*, object)); object key,
object value,
uint32_t (*hash)(Thread*, object));
inline bool inline bool hashMapInsertOrReplace(Thread* t,
hashMapInsertOrReplace(Thread* t, GcHashMap* map, object key, object value, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)) object value,
uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object))
{ {
GcTriple* n = hashMapFindNode(t, map, key, hash, equal); GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
if (n == 0) { if (n == 0) {
@ -53,10 +60,12 @@ hashMapInsertOrReplace(Thread* t, GcHashMap* map, object key, object value,
} }
} }
inline bool inline bool hashMapInsertMaybe(Thread* t,
hashMapInsertMaybe(Thread* t, GcHashMap* map, object key, object value, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)) object value,
uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object))
{ {
GcTriple* n = hashMapFindNode(t, map, key, hash, equal); GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
if (n == 0) { if (n == 0) {
@ -67,43 +76,49 @@ hashMapInsertMaybe(Thread* t, GcHashMap* map, object key, object value,
} }
} }
object object hashMapRemove(Thread* t,
hashMapRemove(Thread* t, GcHashMap* map, object key, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)); uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object));
object object hashMapIterator(Thread* t, GcHashMap* map);
hashMapIterator(Thread* t, GcHashMap* map);
object object
hashMapIteratorNext(Thread* t, object it); hashMapIteratorNext(Thread* t, object it);
void void listAppend(Thread* t, GcList* list, object value);
listAppend(Thread* t, GcList* list, object value);
GcVector* GcVector* vectorAppend(Thread* t, GcVector* vector, object value);
vectorAppend(Thread* t, GcVector* vector, object value);
object object
growArray(Thread* t, object array); growArray(Thread* t, object array);
object object treeQuery(Thread* t,
treeQuery(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)); intptr_t key,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
GcTreeNode* GcTreeNode* treeInsert(Thread* t,
treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value, Zone* zone,
GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)); intptr_t key,
object value,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
void void treeUpdate(Thread* t,
treeUpdate(Thread* t, GcTreeNode* tree, intptr_t key, object value, GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)); intptr_t key,
object value,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
class HashMapIterator: public Thread::Protector { class HashMapIterator: public Thread::Protector {
public: public:
HashMapIterator(Thread* t, GcHashMap* map): HashMapIterator(Thread* t, GcHashMap* map)
Protector(t), map(map), node(0), index(0) : Protector(t), map(map), node(0), index(0)
{ {
find(); find();
} }
@ -126,7 +141,8 @@ class HashMapIterator: public Thread::Protector {
return node != 0; return node != 0;
} }
GcTriple* next() { GcTriple* next()
{
if (node) { if (node) {
GcTriple* n = node; GcTriple* n = node;
if (node->third()) { if (node->third()) {

View File

@ -19,9 +19,11 @@ using namespace vm;
namespace { namespace {
int64_t int64_t search(Thread* t,
search(Thread* t, GcClassLoader* loader, GcString* name, GcClassLoader* loader,
GcClass* (*op)(Thread*, GcClassLoader*, GcByteArray*), bool replaceDots) GcString* name,
GcClass* (*op)(Thread*, GcClassLoader*, GcByteArray*),
bool replaceDots)
{ {
if (LIKELY(name)) { if (LIKELY(name)) {
PROTECT(t, loader); PROTECT(t, loader);
@ -41,15 +43,15 @@ search(Thread* t, GcClassLoader* loader, GcString* name,
} }
} }
GcClass* GcClass* resolveSystemClassThrow(Thread* t,
resolveSystemClassThrow(Thread* t, GcClassLoader* loader, GcByteArray* spec) GcClassLoader* loader,
GcByteArray* spec)
{ {
return resolveSystemClass return resolveSystemClass(
(t, loader, spec, true, GcClassNotFoundException::Type); t, loader, spec, true, GcClassNotFoundException::Type);
} }
GcField* GcField* fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
{ {
GcClass* super = c->super(); GcClass* super = c->super();
if (super) { if (super) {
@ -63,9 +65,7 @@ fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
if (table) { if (table) {
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
GcField* field = cast<GcField>(t, objectArrayBody(t, table, i)); GcField* field = cast<GcField>(t, objectArrayBody(t, table, i));
if ((field->flags() & ACC_STATIC) == 0 if ((field->flags() & ACC_STATIC) == 0 and field->offset() == offset) {
and field->offset() == offset)
{
return field; return field;
} }
} }
@ -74,8 +74,7 @@ fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
return 0; return 0;
} }
GcField* GcField* fieldForOffset(Thread* t, GcSingleton* o, unsigned offset)
fieldForOffset(Thread* t, GcSingleton* o, unsigned offset)
{ {
GcClass* c = objectClass(t, o); GcClass* c = objectClass(t, o);
if (c->vmFlags() & SingletonFlag) { if (c->vmFlags() & SingletonFlag) {
@ -84,9 +83,7 @@ fieldForOffset(Thread* t, GcSingleton* o, unsigned offset)
if (table) { if (table) {
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
GcField* field = cast<GcField>(t, objectArrayBody(t, table, i)); GcField* field = cast<GcField>(t, objectArrayBody(t, table, i));
if ((field->flags() & ACC_STATIC) if ((field->flags() & ACC_STATIC) and field->offset() == offset) {
and field->offset() == offset)
{
return field; return field;
} }
} }
@ -131,18 +128,21 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_resolveVMClass Avian_avian_Classes_resolveVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0])); GcClassLoader* loader
GcByteArray* spec = cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1])); = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
GcByteArray* spec
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(resolveClass(t, loader, spec, true, GcClassNotFoundException::Type)); resolveClass(t, loader, spec, true, GcClassNotFoundException::Type));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_defineVMClass Avian_avian_Classes_defineVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0])); GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
GcByteArray* b = cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1])); GcByteArray* b = cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
int offset = arguments[2]; int offset = arguments[2];
int length = arguments[3]; int length = arguments[3];
@ -162,7 +162,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findLoadedVMClass Avian_avian_SystemClassLoader_findLoadedVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0])); GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1])); GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
return search(t, loader, name, findLoadedClass, true); return search(t, loader, name, findLoadedClass, true);
@ -172,15 +173,16 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_vmClass Avian_avian_SystemClassLoader_vmClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass()); cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findVMClass Avian_avian_SystemClassLoader_findVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0])); GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1])); GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
return search(t, loader, name, resolveSystemClassThrow, true); return search(t, loader, name, resolveSystemClassThrow, true);
@ -190,15 +192,17 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_resourceURLPrefix Avian_avian_SystemClassLoader_resourceURLPrefix
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0])); GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1])); GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
if (LIKELY(name)) { if (LIKELY(name)) {
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1); THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n)); stringChars(t, name, RUNTIME_ARRAY_BODY(n));
const char* name = static_cast<Finder*> const char* name
(loader->as<GcSystemClassLoader>(t)->finder())->urlPrefix(RUNTIME_ARRAY_BODY(n)); = static_cast<Finder*>(loader->as<GcSystemClassLoader>(t)->finder())
->urlPrefix(RUNTIME_ARRAY_BODY(n));
return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0; return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0;
} else { } else {
@ -210,18 +214,21 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_00024ResourceEnumeration_nextResourceURLPrefix Avian_avian_SystemClassLoader_00024ResourceEnumeration_nextResourceURLPrefix
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[1])); GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[1]));
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[2])); GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[2]));
GcLongArray* finderElementPtrPtr = cast<GcLongArray>(t, reinterpret_cast<object>(arguments[3])); GcLongArray* finderElementPtrPtr
= cast<GcLongArray>(t, reinterpret_cast<object>(arguments[3]));
if (LIKELY(name) && LIKELY(finderElementPtrPtr)) { if (LIKELY(name) && LIKELY(finderElementPtrPtr)) {
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1); THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n)); stringChars(t, name, RUNTIME_ARRAY_BODY(n));
void *&finderElementPtr = reinterpret_cast<void *&>(finderElementPtrPtr->body()[0]); void*& finderElementPtr
const char* name = static_cast<Finder*> = reinterpret_cast<void*&>(finderElementPtrPtr->body()[0]);
(loader->as<GcSystemClassLoader>(t)->finder())->nextUrlPrefix(RUNTIME_ARRAY_BODY(n), const char* name
finderElementPtr); = static_cast<Finder*>(loader->as<GcSystemClassLoader>(t)->finder())
->nextUrlPrefix(RUNTIME_ARRAY_BODY(n), finderElementPtr);
return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0; return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0;
} else { } else {
@ -233,8 +240,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_getClass Avian_avian_SystemClassLoader_getClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(getJClass(t, cast<GcClass>(t, reinterpret_cast<object>(arguments[0])))); getJClass(t, cast<GcClass>(t, reinterpret_cast<object>(arguments[0]))));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -254,14 +261,14 @@ Avian_avian_SystemClassLoader_getPackageSource
GcByteArray* key = makeByteArray(t, RUNTIME_ARRAY_BODY(chars)); GcByteArray* key = makeByteArray(t, RUNTIME_ARRAY_BODY(chars));
GcByteArray* array = cast<GcByteArray>(t, hashMapFind GcByteArray* array = cast<GcByteArray>(
(t, roots(t)->packageMap(), key, byteArrayHash, byteArrayEqual)); t,
hashMapFind(
t, roots(t)->packageMap(), key, byteArrayHash, byteArrayEqual));
if (array) { if (array) {
return reinterpret_cast<uintptr_t>(makeLocalReference( return reinterpret_cast<uintptr_t>(makeLocalReference(
t, t, t->m->classpath->makeString(t, array, 0, array->length())));
t->m->classpath->makeString(
t, array, 0, array->length())));
} else { } else {
return 0; return 0;
} }
@ -285,7 +292,9 @@ Avian_avian_Machine_dumpHeap
} }
fclose(out); fclose(out);
} else { } else {
throwNew(t, GcRuntimeException::Type, "file not found: %s", throwNew(t,
GcRuntimeException::Type,
"file not found: %s",
RUNTIME_ARRAY_BODY(n)); RUNTIME_ARRAY_BODY(n));
} }
} }
@ -392,7 +401,8 @@ Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI_3BII
{ {
int64_t peer; memcpy(&peer, arguments, 8); int64_t peer; memcpy(&peer, arguments, 8);
int32_t position = arguments[2]; int32_t position = arguments[2];
GcByteArray* buffer = cast<GcByteArray>(t, reinterpret_cast<object>(arguments[3])); GcByteArray* buffer
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[3]));
int32_t offset = arguments[4]; int32_t offset = arguments[4];
int32_t length = arguments[5]; int32_t length = arguments[5];
@ -405,8 +415,7 @@ Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI_3BII
if (length <= 0) { if (length <= 0) {
return -1; return -1;
} else { } else {
memcpy(&buffer->body()[offset], region->start() + position, memcpy(&buffer->body()[offset], region->start() + position, length);
length);
return length; return length;
} }
} }
@ -445,9 +454,10 @@ extern "C" AVIAN_EXPORT void JNICALL
Avian_avian_Continuations_00024Continuation_handleResult Avian_avian_Continuations_00024Continuation_handleResult
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
t->m->processor->feedResultToContinuation t->m->processor->feedResultToContinuation(
(t, cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])), t,
reinterpret_cast<object>(arguments[1])); cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
reinterpret_cast<object>(arguments[1]));
abort(t); abort(t);
} }
@ -456,9 +466,10 @@ extern "C" AVIAN_EXPORT void JNICALL
Avian_avian_Continuations_00024Continuation_handleException Avian_avian_Continuations_00024Continuation_handleException
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
t->m->processor->feedExceptionToContinuation t->m->processor->feedExceptionToContinuation(
(t, cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])), t,
cast<GcThrowable>(t, reinterpret_cast<object>(arguments[1]))); cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
cast<GcThrowable>(t, reinterpret_cast<object>(arguments[1])));
abort(t); abort(t);
} }
@ -467,16 +478,20 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Singleton_getObject Avian_avian_Singleton_getObject
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(singletonObject(
(singletonObject(t, cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])), arguments[1])); t,
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
arguments[1]));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Singleton_getInt Avian_avian_Singleton_getInt
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return singletonValue return singletonValue(
(t, cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])), arguments[1]); t,
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
arguments[1]);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -484,8 +499,12 @@ Avian_avian_Singleton_getLong
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
int64_t v; int64_t v;
memcpy(&v, &singletonValue memcpy(&v,
(t, cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])), arguments[1]), 8); &singletonValue(
t,
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
arguments[1]),
8);
return v; return v;
} }
@ -710,19 +729,16 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_arrayIndexScale Avian_sun_misc_Unsafe_arrayIndexScale
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcClass* c = cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))->vmClass(); GcClass* c
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))->vmClass();
if (c == type(t, GcBooleanArray::Type) if (c == type(t, GcBooleanArray::Type) || c == type(t, GcByteArray::Type))
|| c == type(t, GcByteArray::Type))
return 1; return 1;
else if (c == type(t, GcShortArray::Type) else if (c == type(t, GcShortArray::Type) || c == type(t, GcCharArray::Type))
|| c == type(t, GcCharArray::Type))
return 2; return 2;
else if (c == type(t, GcIntArray::Type) else if (c == type(t, GcIntArray::Type) || c == type(t, GcFloatArray::Type))
|| c == type(t, GcFloatArray::Type))
return 4; return 4;
else if (c == type(t, GcLongArray::Type) else if (c == type(t, GcLongArray::Type) || c == type(t, GcDoubleArray::Type))
|| c == type(t, GcDoubleArray::Type))
return 8; return 8;
else else
return BytesPerWord; return BytesPerWord;
@ -733,13 +749,15 @@ Avian_java_nio_FixedArrayByteBuffer_allocateFixed
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
int capacity = arguments[0]; int capacity = arguments[0];
GcLongArray* address = cast<GcLongArray>(t, reinterpret_cast<object>(arguments[1])); GcLongArray* address
= cast<GcLongArray>(t, reinterpret_cast<object>(arguments[1]));
PROTECT(t, address); PROTECT(t, address);
GcArray* array = reinterpret_cast<GcArray*>(allocate3 GcArray* array = reinterpret_cast<GcArray*>(allocate3(
(t, t->m->heap, Machine::FixedAllocation, ArrayBody + capacity, false)); t, t->m->heap, Machine::FixedAllocation, ArrayBody + capacity, false));
setObjectClass(t, reinterpret_cast<object>(array), type(t, GcByteArray::Type)); setObjectClass(
t, reinterpret_cast<object>(array), type(t, GcByteArray::Type));
array->length() = capacity; array->length() = capacity;
address->body()[0] = reinterpret_cast<intptr_t>(array) + ArrayBody; address->body()[0] = reinterpret_cast<intptr_t>(array) + ArrayBody;
@ -964,11 +982,11 @@ Avian_sun_misc_Unsafe_park
monitorAcquire(t, cast<GcMonitor>(t, interruptLock(t, t->javaThread))); monitorAcquire(t, cast<GcMonitor>(t, interruptLock(t, t->javaThread)));
bool interrupted = false; bool interrupted = false;
while (time >= 0 while (time >= 0
and (not (t->javaThread->unparked() and (not(t->javaThread->unparked() or t->javaThread->interrupted()
or t->javaThread->interrupted() or (interrupted = monitorWait(
or (interrupted = monitorWait t,
(t, cast<GcMonitor>(t, interruptLock(t, t->javaThread)), time))))) cast<GcMonitor>(t, interruptLock(t, t->javaThread)),
{ time))))) {
int64_t now = t->m->system->now(); int64_t now = t->m->system->now();
time -= now - then; time -= now - then;
then = now; then = now;

File diff suppressed because it is too large Load Diff

View File

@ -26,20 +26,20 @@ class MyClasspath : public Classpath {
allocator(allocator) allocator(allocator)
{ } { }
virtual GcJclass* virtual GcJclass* makeJclass(Thread* t, GcClass* class_)
makeJclass(Thread* t, GcClass* class_)
{ {
return vm::makeJclass(t, class_); return vm::makeJclass(t, class_);
} }
virtual GcString* virtual GcString* makeString(Thread* t,
makeString(Thread* t, object array, int32_t offset, int32_t length) object array,
int32_t offset,
int32_t length)
{ {
return vm::makeString(t, array, offset, length, 0); return vm::makeString(t, array, offset, length, 0);
} }
virtual GcThread* virtual GcThread* makeThread(Thread* t, Thread* parent)
makeThread(Thread* t, Thread* parent)
{ {
GcThreadGroup* group; GcThreadGroup* group;
if (parent) { if (parent) {
@ -51,38 +51,48 @@ class MyClasspath : public Classpath {
const unsigned NewState = 0; const unsigned NewState = 0;
const unsigned NormalPriority = 5; const unsigned NormalPriority = 5;
return vm::makeThread return vm::makeThread(t,
(t, 0, 0, 0, 0, 0, NewState, NormalPriority, 0, 0, 0, 0,
roots(t)->appLoader(), 0, 0, group, 0); 0,
0,
0,
0,
NewState,
NormalPriority,
0,
0,
0,
roots(t)->appLoader(),
0,
0,
group,
0);
} }
virtual object virtual object makeJMethod(Thread* t, GcMethod* vmMethod)
makeJMethod(Thread* t, GcMethod* vmMethod)
{ {
PROTECT(t, vmMethod); PROTECT(t, vmMethod);
GcJmethod* jmethod = makeJmethod(t, vmMethod, false); GcJmethod* jmethod = makeJmethod(t, vmMethod, false);
return vmMethod->name()->body()[0] == '<' return vmMethod->name()->body()[0] == '<'
? (object)makeJconstructor(t, jmethod) : (object)jmethod; ? (object)makeJconstructor(t, jmethod)
: (object)jmethod;
} }
virtual GcMethod* virtual GcMethod* getVMMethod(Thread* t, object jmethod)
getVMMethod(Thread* t, object jmethod)
{ {
return objectClass(t, jmethod) == type(t, GcJmethod::Type) return objectClass(t, jmethod) == type(t, GcJmethod::Type)
? cast<GcJmethod>(t, jmethod)->vmMethod() ? cast<GcJmethod>(t, jmethod)->vmMethod()
: cast<GcJconstructor>(t, jmethod)->method()->vmMethod(); : cast<GcJconstructor>(t, jmethod)->method()->vmMethod();
} }
virtual object virtual object makeJField(Thread* t, GcField* vmField)
makeJField(Thread* t, GcField* vmField)
{ {
return makeJfield(t, vmField, false); return makeJfield(t, vmField, false);
} }
virtual GcField* virtual GcField* getVMField(Thread* t UNUSED, GcJfield* jfield)
getVMField(Thread* t UNUSED, GcJfield* jfield)
{ {
return jfield->vmField(); return jfield->vmField();
} }
@ -96,15 +106,16 @@ class MyClasspath : public Classpath {
virtual void virtual void
runThread(Thread* t) runThread(Thread* t)
{ {
GcMethod* method = resolveMethod GcMethod* method = resolveMethod(t,
(t, roots(t)->bootLoader(), "java/lang/Thread", "run", roots(t)->bootLoader(),
"(Ljava/lang/Thread;)V"); "java/lang/Thread",
"run",
"(Ljava/lang/Thread;)V");
t->m->processor->invoke(t, method, 0, t->javaThread); t->m->processor->invoke(t, method, 0, t->javaThread);
} }
virtual void virtual void resolveNative(Thread* t, GcMethod* method)
resolveNative(Thread* t, GcMethod* method)
{ {
vm::resolveNative(t, method); vm::resolveNative(t, method);
} }
@ -141,8 +152,8 @@ class MyClasspath : public Classpath {
virtual object virtual object
makeDirectByteBuffer(Thread* t, void* p, jlong capacity) makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
{ {
GcClass* c = resolveClass GcClass* c
(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer"); = resolveClass(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer");
PROTECT(t, c); PROTECT(t, c);
object instance = makeNew(t, c); object instance = makeNew(t, c);
@ -164,8 +175,7 @@ class MyClasspath : public Classpath {
GcField* field = resolveField(t, objectClass(t, b), "address", "J"); GcField* field = resolveField(t, objectClass(t, b), "address", "J");
return reinterpret_cast<void*> return reinterpret_cast<void*>(fieldAtOffset<int64_t>(b, field->offset()));
(fieldAtOffset<int64_t>(b, field->offset()));
} }
virtual int64_t virtual int64_t
@ -173,8 +183,7 @@ class MyClasspath : public Classpath {
{ {
PROTECT(t, b); PROTECT(t, b);
GcField* field = resolveField GcField* field = resolveField(t, objectClass(t, b), "capacity", "I");
(t, objectClass(t, b), "capacity", "I");
return fieldAtOffset<int32_t>(b, field->offset()); return fieldAtOffset<int32_t>(b, field->offset());
} }
@ -194,14 +203,12 @@ class MyClasspath : public Classpath {
(strcmp("loadLibrary", (strcmp("loadLibrary",
reinterpret_cast<char*>(calleeMethodName->body().begin())) reinterpret_cast<char*>(calleeMethodName->body().begin()))
and strcmp("load", and strcmp("load",
reinterpret_cast<char*>( reinterpret_cast<char*>(calleeMethodName->body().begin())))
calleeMethodName->body().begin()))) or (strcmp("java/lang/System",
or (strcmp( reinterpret_cast<char*>(calleeClassName->body().begin()))
"java/lang/System", and strcmp(
reinterpret_cast<char*>(calleeClassName->body().begin())) "java/lang/Runtime",
and strcmp("java/lang/Runtime", reinterpret_cast<char*>(calleeClassName->body().begin()))));
reinterpret_cast<char*>(
calleeClassName->body().begin()))));
} }
virtual GcClassLoader* libraryClassLoader(Thread* t, GcMethod* caller) virtual GcClassLoader* libraryClassLoader(Thread* t, GcMethod* caller)
@ -227,9 +234,11 @@ class MyClasspath : public Classpath {
Allocator* allocator; Allocator* allocator;
}; };
void void enumerateThreads(Thread* t,
enumerateThreads(Thread* t, Thread* x, GcArray* array, unsigned* index, Thread* x,
unsigned limit) GcArray* array,
unsigned* index,
unsigned limit)
{ {
if (*index < limit) { if (*index < limit) {
array->setBodyElement(t, *index, x->javaThread); array->setBodyElement(t, *index, x->javaThread);
@ -263,10 +272,8 @@ Avian_java_lang_Object_toString
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
unsigned hash = objectHash(t, this_); unsigned hash = objectHash(t, this_);
GcString* s = makeString GcString* s = makeString(
(t, "%s@0x%x", t, "%s@0x%x", objectClass(t, this_)->name()->body().begin(), hash);
objectClass(t, this_)->name()->body().begin(),
hash);
return reinterpret_cast<int64_t>(s); return reinterpret_cast<int64_t>(s);
} }
@ -457,8 +464,8 @@ Avian_java_lang_reflect_Method_invoke
THREAD_RESOURCE0(t, { THREAD_RESOURCE0(t, {
if (t->exception) { if (t->exception) {
GcThrowable* exception = t->exception; GcThrowable* exception = t->exception;
t->exception = makeThrowable t->exception = makeThrowable(
(t, GcInvocationTargetException::Type, 0, 0, exception); t, GcInvocationTargetException::Type, 0, 0, exception);
} }
}); });
@ -492,11 +499,12 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Array_makeObjectArray Avian_java_lang_reflect_Array_makeObjectArray
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
GcJclass* elementType = cast<GcJclass>(t, reinterpret_cast<object>(arguments[0])); GcJclass* elementType
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]));
int length = arguments[1]; int length = arguments[1];
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(makeObjectArray(t, elementType->vmClass(), length)); makeObjectArray(t, elementType->vmClass(), length));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -580,8 +588,7 @@ Avian_java_lang_System_identityHashCode
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_ClassLoader_getCaller(Thread* t, object, uintptr_t*) Avian_java_lang_ClassLoader_getCaller(Thread* t, object, uintptr_t*)
{ {
return reinterpret_cast<int64_t>( return reinterpret_cast<int64_t>(getJClass(t, getCaller(t, 2)->class_()));
getJClass(t, getCaller(t, 2)->class_()));
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
@ -591,7 +598,9 @@ extern "C" AVIAN_EXPORT void JNICALL
Thread::LibraryLoadStack stack( Thread::LibraryLoadStack stack(
t, t,
cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))->vmClass()->loader()); cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))
->vmClass()
->loader());
bool mapName = arguments[2]; bool mapName = arguments[2];
@ -643,7 +652,8 @@ Avian_java_lang_Throwable_resolveTrace
PROTECT(t, array); PROTECT(t, array);
for (unsigned i = 0; i < length; ++i) { for (unsigned i = 0; i < length; ++i) {
GcStackTraceElement* ste = makeStackTraceElement(t, cast<GcTraceElement>(t, objectArrayBody(t, trace, i))); GcStackTraceElement* ste = makeStackTraceElement(
t, cast<GcTraceElement>(t, objectArrayBody(t, trace, i)));
reinterpret_cast<GcArray*>(array)->setBodyElement(t, i, ste); reinterpret_cast<GcArray*>(array)->setBodyElement(t, i, ste);
} }
@ -661,8 +671,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_doStart Avian_java_lang_Thread_doStart
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(startThread(t, cast<GcThread>(t, reinterpret_cast<object>(*arguments)))); startThread(t, cast<GcThread>(t, reinterpret_cast<object>(*arguments))));
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
@ -713,7 +723,8 @@ Avian_java_lang_Thread_enumerate
ACQUIRE_RAW(t, t->m->stateLock); ACQUIRE_RAW(t, t->m->stateLock);
unsigned count = min(t->m->liveCount, objectArrayLength(t, reinterpret_cast<object>(array))); unsigned count = min(t->m->liveCount,
objectArrayLength(t, reinterpret_cast<object>(array)));
unsigned index = 0; unsigned index = 0;
local::enumerateThreads(t, t->m->rootThread, array, &index, count); local::enumerateThreads(t, t->m->rootThread, array, &index, count);
return count; return count;
@ -730,14 +741,18 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Atomic_getOffset Avian_avian_Atomic_getOffset
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return cast<GcJfield>(t, reinterpret_cast<object>(arguments[0]))->vmField()->offset(); return cast<GcJfield>(t, reinterpret_cast<object>(arguments[0]))
->vmField()
->offset();
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_objectFieldOffset Avian_sun_misc_Unsafe_objectFieldOffset
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return cast<GcJfield>(t, reinterpret_cast<object>(arguments[1]))->vmField()->offset(); return cast<GcJfield>(t, reinterpret_cast<object>(arguments[1]))
->vmField()
->offset();
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -793,8 +808,8 @@ Avian_avian_Classes_makeMethod
->methodTable())->body()[arguments[1]]); ->methodTable())->body()[arguments[1]]);
PROTECT(t, method); PROTECT(t, method);
GcClass* c = resolveClass GcClass* c
(t, roots(t)->bootLoader(), "java/lang/reflect/Method"); = resolveClass(t, roots(t)->bootLoader(), "java/lang/reflect/Method");
PROTECT(t, c); PROTECT(t, c);
object instance = makeNew(t, c); object instance = makeNew(t, c);
@ -807,13 +822,13 @@ Avian_avian_Classes_makeMethod
if (method->name()->body()[0] == '<') { if (method->name()->body()[0] == '<') {
object oldInstance = instance; object oldInstance = instance;
c = resolveClass c = resolveClass(
(t, roots(t)->bootLoader(), "java/lang/reflect/Constructor"); t, roots(t)->bootLoader(), "java/lang/reflect/Constructor");
object instance = makeNew(t, c); object instance = makeNew(t, c);
GcMethod* constructor = resolveMethod GcMethod* constructor
(t, c, "<init>", "(Ljava/lang/Method;)V"); = resolveMethod(t, c, "<init>", "(Ljava/lang/Method;)V");
t->m->processor->invoke(t, constructor, instance, oldInstance); t->m->processor->invoke(t, constructor, instance, oldInstance);
} }

File diff suppressed because it is too large Load Diff

View File

@ -586,7 +586,8 @@ acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask)
if (s->type(c) == lir::RegisterOperand) { if (s->type(c) == lir::RegisterOperand) {
return c->availableGeneralRegisterCount > ResolveRegisterReserveCount; return c->availableGeneralRegisterCount > ResolveRegisterReserveCount;
} else { } else {
assertT(c, s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))); assertT(c,
s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)));
return isHome(read->value, offsetToFrameIndex return isHome(read->value, offsetToFrameIndex
(c, static_cast<MemorySite*>(s)->offset)); (c, static_cast<MemorySite*>(s)->offset));
@ -1138,9 +1139,11 @@ pop(Context* c, unsigned footprint)
high = low->next; high = low->next;
} }
assertT(c, (TargetBytesPerWord == 8 assertT(
and low->value->nextWord == low->value and high->value == 0) c,
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value)); (TargetBytesPerWord == 8 and low->value->nextWord == low->value
and high->value == 0)
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value));
#endif // not NDEBUG #endif // not NDEBUG
popWord(c); popWord(c);
@ -2379,10 +2382,11 @@ class MyCompiler: public Compiler {
high = s->next; high = s->next;
} }
assertT(&c, (TargetBytesPerWord == 8 assertT(
and low->value->nextWord == low->value and high->value == 0) &c,
or (TargetBytesPerWord == 4 (TargetBytesPerWord == 8 and low->value->nextWord == low->value
and low->value->nextWord == high->value)); and high->value == 0)
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value));
#endif // not NDEBUG #endif // not NDEBUG
if (bigEndian) { if (bigEndian) {
@ -2649,8 +2653,8 @@ class MyCompiler: public Compiler {
ir::Value* addr) ir::Value* addr)
{ {
assertT(&c, assertT(&c,
(isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))or( (isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))
isFloatBranch(op) and isFloatValue(a) and isFloatValue(b))); or (isFloatBranch(op) and isFloatValue(a) and isFloatValue(b)));
assertT(&c, a->type == b->type); assertT(&c, a->type == b->type);
assertT(&c, addr->type == ir::Type::iptr()); assertT(&c, addr->type == ir::Type::iptr());
@ -2678,8 +2682,8 @@ class MyCompiler: public Compiler {
ir::Value* b) ir::Value* b)
{ {
assertT(&c, assertT(&c,
(isGeneralBinaryOp(op) and isGeneralValue(a) and isGeneralValue(b)) (isGeneralBinaryOp(op) and isGeneralValue(a) and isGeneralValue(b))
or(isFloatBinaryOp(op) and isFloatValue(a) and isFloatValue(b))); or (isFloatBinaryOp(op) and isFloatValue(a) and isFloatValue(b)));
Value* result = value(&c, type); Value* result = value(&c, type);
@ -2695,8 +2699,8 @@ class MyCompiler: public Compiler {
ir::Value* a) ir::Value* a)
{ {
assertT(&c, assertT(&c,
(isGeneralUnaryOp(op) and isGeneralValue(a))or(isFloatUnaryOp(op) (isGeneralUnaryOp(op) and isGeneralValue(a))
and isFloatValue(a))); or (isFloatUnaryOp(op) and isFloatValue(a)));
Value* result = value(&c, a->type); Value* result = value(&c, a->type);
appendTranslate( appendTranslate(
&c, op, static_cast<Value*>(a), result); &c, op, static_cast<Value*>(a), result);

View File

@ -400,8 +400,8 @@ class CallEvent: public Event {
&& (v == 0 || (i >= 1 && arguments[i - 1] == 0))) && (v == 0 || (i >= 1 && arguments[i - 1] == 0)))
|| (c->targetInfo.pointerSize == 4 && v->nextWord != v)) { || (c->targetInfo.pointerSize == 4 && v->nextWord != v)) {
assertT(c, assertT(c,
c->targetInfo.pointerSize == 8 c->targetInfo.pointerSize == 8
or v->nextWord == arguments[i - 1]); or v->nextWord == arguments[i - 1]);
arguments[i] = arguments[i - 1]; arguments[i] = arguments[i - 1];
--i; --i;
@ -512,10 +512,14 @@ class CallEvent: public Event {
op = lir::Jump; op = lir::Jump;
} }
assertT(c, returnAddressSurrogate == 0 assertT(
or returnAddressSurrogate->source->type(c) == lir::RegisterOperand); c,
assertT(c, framePointerSurrogate == 0 returnAddressSurrogate == 0
or framePointerSurrogate->source->type(c) == lir::RegisterOperand); or returnAddressSurrogate->source->type(c) == lir::RegisterOperand);
assertT(
c,
framePointerSurrogate == 0
or framePointerSurrogate->source->type(c) == lir::RegisterOperand);
int ras; int ras;
if (returnAddressSurrogate) { if (returnAddressSurrogate) {
@ -1004,7 +1008,9 @@ class CombineEvent: public Event {
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
assertT(c, firstValue->source->type(c) == firstValue->nextWord->source->type(c)); assertT(
c,
firstValue->source->type(c) == firstValue->nextWord->source->type(c));
// if (secondValue->source->type(c) != secondValue->nextWord->source->type(c)) { // if (secondValue->source->type(c) != secondValue->nextWord->source->type(c)) {
// fprintf(stderr, "%p %p %d : %p %p %d\n", // fprintf(stderr, "%p %p %d : %p %p %d\n",
@ -1013,7 +1019,9 @@ class CombineEvent: public Event {
// secondValue->nextWord->source->type(c)); // secondValue->nextWord->source->type(c));
// } // }
assertT(c, secondValue->source->type(c) == secondValue->nextWord->source->type(c)); assertT(
c,
secondValue->source->type(c) == secondValue->nextWord->source->type(c));
freezeSource(c, firstValue->type.size(c->targetInfo), firstValue); freezeSource(c, firstValue->type.size(c->targetInfo), firstValue);
@ -1197,7 +1205,9 @@ class TranslateEvent: public Event {
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
assertT(c, firstValue->source->type(c) == firstValue->nextWord->source->type(c)); assertT(
c,
firstValue->source->type(c) == firstValue->nextWord->source->type(c));
OperandMask bMask; OperandMask bMask;
@ -1266,11 +1276,11 @@ void appendTranslate(Context* c,
Value* resultValue) Value* resultValue)
{ {
assertT(c, assertT(c,
firstValue->type.size(c->targetInfo) firstValue->type.size(c->targetInfo)
== firstValue->type.size(c->targetInfo)); == firstValue->type.size(c->targetInfo));
assertT(c, assertT(c,
resultValue->type.size(c->targetInfo) resultValue->type.size(c->targetInfo)
== resultValue->type.size(c->targetInfo)); == resultValue->type.size(c->targetInfo));
bool thunk; bool thunk;
OperandMask first; OperandMask first;

View File

@ -50,11 +50,11 @@ unsigned frameIndexToOffset(Context* c, unsigned frameIndex) {
unsigned offsetToFrameIndex(Context* c, unsigned offset) { unsigned offsetToFrameIndex(Context* c, unsigned offset) {
assertT(c, assertT(c,
static_cast<int>((offset / c->targetInfo.pointerSize) static_cast<int>((offset / c->targetInfo.pointerSize)
- c->arch->frameFooterSize()) >= 0); - c->arch->frameFooterSize()) >= 0);
assertT(c, assertT(c,
((offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize()) ((offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize())
< totalFrameSize(c)); < totalFrameSize(c));
return (offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize(); return (offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize();
} }

View File

@ -181,7 +181,8 @@ Read* StubRead::next(Context*) {
SingleRead* read(Context* c, const SiteMask& mask, Value* successor) { SingleRead* read(Context* c, const SiteMask& mask, Value* successor) {
assertT(c, (mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0); assertT(c,
(mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0);
return new(c->zone) SingleRead(mask, successor); return new(c->zone) SingleRead(mask, successor);
} }

View File

@ -223,4 +223,4 @@ void release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNU
} // namespace compiler } // namespace compiler
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -378,8 +378,9 @@ unsigned RegisterSite::registerMask(Context* c UNUSED) {
Site* registerSite(Context* c, int number) { Site* registerSite(Context* c, int number) {
assertT(c, number >= 0); assertT(c, number >= 0);
assertT(c, (1 << number) & (c->regFile->generalRegisters.mask assertT(c,
| c->regFile->floatRegisters.mask)); (1 << number) & (c->regFile->generalRegisters.mask
| c->regFile->floatRegisters.mask));
return new(c->zone) RegisterSite(1 << number, number); return new(c->zone) RegisterSite(1 << number, number);
} }
@ -488,8 +489,7 @@ void MemorySite::acquire(Context* c, Value* v) {
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
assertT(c, index == lir::NoRegister); assertT(c, index == lir::NoRegister);
assertT assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
compiler::acquire compiler::acquire
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this); (c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
@ -501,8 +501,7 @@ void MemorySite::acquire(Context* c, Value* v) {
void MemorySite::release(Context* c, Value* v) { void MemorySite::release(Context* c, Value* v) {
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
assertT(c, index == lir::NoRegister); assertT(c, index == lir::NoRegister);
assertT assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
compiler::release compiler::release
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this); (c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
@ -552,12 +551,12 @@ void MemorySite::asAssemblerOperand(Context* c UNUSED, Site* high UNUSED,
{ {
// todo: endianness? // todo: endianness?
assertT(c, assertT(c,
high == this high == this
or (static_cast<MemorySite*>(high)->base == base or (static_cast<MemorySite*>(high)->base == base
and static_cast<MemorySite*>(high)->offset and static_cast<MemorySite*>(high)->offset
== static_cast<int>(offset + c->targetInfo.pointerSize) == static_cast<int>(offset + c->targetInfo.pointerSize)
and static_cast<MemorySite*>(high)->index == index and static_cast<MemorySite*>(high)->index == index
and static_cast<MemorySite*>(high)->scale == scale)); and static_cast<MemorySite*>(high)->scale == scale));
assertT(c, acquired); assertT(c, acquired);

View File

@ -884,11 +884,11 @@ void moveAR(Context* con, unsigned srcSize, lir::Address* src,
void compareRR(Context* con, unsigned aSize, lir::Register* a, void compareRR(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize UNUSED, lir::Register* b) unsigned bSize UNUSED, lir::Register* b)
{ {
assertT(con, !(isFpr(a) ^ isFpr(b))); // regs must be of the same type assertT(con, !(isFpr(a) ^ isFpr(b))); // regs must be of the same type
if (!isFpr(a)) { // GPR compare if (!isFpr(a)) { // GPR compare
assertT(con, aSize == 4 && bSize == 4); assertT(con, aSize == 4 && bSize == 4);
/**///assertT(con, b->low != a->low); /**/ // assertT(con, b->low != a->low);
emit(con, cmp(b->low, a->low)); emit(con, cmp(b->low, a->low));
} else { // FPR compare } else { // FPR compare
assertT(con, aSize == bSize); assertT(con, aSize == bSize);

View File

@ -143,11 +143,13 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
} }
if (UseFramePointer and not mostRecent) { if (UseFramePointer and not mostRecent) {
assertT(c, static_cast<void***>(*stack)[-1] + 1 assertT(c,
== static_cast<void**>(*stack) + offset); static_cast<void***>(*stack)[-1] + 1
== static_cast<void**>(*stack) + offset);
assertT(c, static_cast<void***>(*stack)[-1][1] assertT(c,
== static_cast<void**>(*stack)[offset]); static_cast<void***>(*stack)[-1][1]
== static_cast<void**>(*stack)[offset]);
} }
*ip = static_cast<void**>(*stack)[offset]; *ip = static_cast<void**>(*stack)[offset];
@ -341,11 +343,15 @@ class MyArchitecture: public Architecture {
if (TargetBytesPerWord == 4 or op == lir::Call or op == lir::Jump) { if (TargetBytesPerWord == 4 or op == lir::Call or op == lir::Jump) {
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5; uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
assertT(&c, ((op == lir::Call or op == lir::LongCall) and *instruction == 0xE8) assertT(
or ((op == lir::Jump or op == lir::LongJump) and *instruction == 0xE9)); &c,
((op == lir::Call or op == lir::LongCall) and *instruction == 0xE8)
or ((op == lir::Jump or op == lir::LongJump)
and *instruction == 0xE9));
assertT(&c, (not assertTAlignment) assertT(&c,
or reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0); (not assertTAlignment)
or reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
intptr_t v = static_cast<uint8_t*>(newTarget) intptr_t v = static_cast<uint8_t*>(newTarget)
- static_cast<uint8_t*>(returnAddress); - static_cast<uint8_t*>(returnAddress);
@ -360,11 +366,13 @@ class MyArchitecture: public Architecture {
assertT(&c, instruction[0] == 0x49 and instruction[1] == 0xBA); assertT(&c, instruction[0] == 0x49 and instruction[1] == 0xBA);
assertT(&c, instruction[10] == 0x41 and instruction[11] == 0xFF); assertT(&c, instruction[10] == 0x41 and instruction[11] == 0xFF);
assertT(&c, (op == lir::LongCall and instruction[12] == 0xD2) assertT(&c,
or (op == lir::LongJump and instruction[12] == 0xE2)); (op == lir::LongCall and instruction[12] == 0xD2)
or (op == lir::LongJump and instruction[12] == 0xE2));
assertT(&c, (not assertTAlignment) assertT(&c,
or reinterpret_cast<uintptr_t>(instruction + 2) % 8 == 0); (not assertTAlignment)
or reinterpret_cast<uintptr_t>(instruction + 2) % 8 == 0);
memcpy(instruction + 2, &newTarget, 8); memcpy(instruction + 2, &newTarget, 8);
} }

View File

@ -708,7 +708,6 @@ void andRR(Context* c, unsigned aSize, lir::Register* a,
{ {
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
if (vm::TargetBytesPerWord == 4 and aSize == 8) { if (vm::TargetBytesPerWord == 4 and aSize == 8) {
lir::Register ah(a->high); lir::Register ah(a->high);
lir::Register bh(b->high); lir::Register bh(b->high);
@ -877,7 +876,6 @@ void multiplyRR(Context* c, unsigned aSize, lir::Register* a,
{ {
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
if (vm::TargetBytesPerWord == 4 and aSize == 8) { if (vm::TargetBytesPerWord == 4 and aSize == 8) {
assertT(c, b->high == rdx); assertT(c, b->high == rdx);
assertT(c, b->low != rax); assertT(c, b->low != rax);

File diff suppressed because it is too large Load Diff

View File

@ -284,7 +284,8 @@ class JarIndex {
while (p < end) { while (p < end) {
if (signature(p) == EntrySignature) { if (signature(p) == EntrySignature) {
index = index->add(Entry(hash(Slice<const uint8_t>(fileName(p), fileNameLength(p))), p)); index = index->add(Entry(
hash(Slice<const uint8_t>(fileName(p), fileNameLength(p))), p));
p = endOfEntry(p); p = endOfEntry(p);
} else { } else {

View File

@ -34,14 +34,13 @@ const unsigned FrameFootprint = 4;
class Thread: public vm::Thread { class Thread: public vm::Thread {
public: public:
Thread(Machine* m, GcThread* javaThread, vm::Thread* parent)
Thread(Machine* m, GcThread* javaThread, vm::Thread* parent): : vm::Thread(m, javaThread, parent),
vm::Thread(m, javaThread, parent), ip(0),
ip(0), sp(0),
sp(0), frame(-1),
frame(-1), code(0),
code(0), stackPointers(0)
stackPointers(0)
{ } { }
unsigned ip; unsigned ip;
@ -249,8 +248,7 @@ frameNext(Thread* t, int frame)
return peekInt(t, frame + FrameNextOffset); return peekInt(t, frame + FrameNextOffset);
} }
inline GcMethod* inline GcMethod* frameMethod(Thread* t, int frame)
frameMethod(Thread* t, int frame)
{ {
return cast<GcMethod>(t, peekObject(t, frame + FrameMethodOffset)); return cast<GcMethod>(t, peekObject(t, frame + FrameMethodOffset));
} }
@ -303,8 +301,7 @@ setLocalLong(Thread* t, unsigned index, uint64_t value)
pokeLong(t, frameBase(t, t->frame) + index, value); pokeLong(t, frameBase(t, t->frame) + index, value);
} }
void void pushFrame(Thread* t, GcMethod* method)
pushFrame(Thread* t, GcMethod* method)
{ {
PROTECT(t, method); PROTECT(t, method);
@ -386,7 +383,8 @@ class MyStackWalker: public Processor::StackWalker {
} }
} }
virtual GcMethod* method() { virtual GcMethod* method()
{
return frameMethod(t, frame); return frameMethod(t, frame);
} }
@ -406,16 +404,11 @@ class MyStackWalker: public Processor::StackWalker {
int frame; int frame;
}; };
inline void inline void checkStack(Thread* t, GcMethod* method)
checkStack(Thread* t, GcMethod* method)
{ {
if (UNLIKELY(t->sp if (UNLIKELY(t->sp + method->parameterFootprint()
+ method->parameterFootprint() + method->code()->maxLocals() + FrameFootprint
+ method->code()->maxLocals() + method->code()->maxStack() > stackSizeInWords(t) / 2)) {
+ FrameFootprint
+ method->code()->maxStack()
> stackSizeInWords(t) / 2))
{
throwNew(t, GcStackOverflowError::Type); throwNew(t, GcStackOverflowError::Type);
} }
} }
@ -488,13 +481,15 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect)
} }
} }
void void marshalArguments(Thread* t,
marshalArguments(Thread* t, uintptr_t* args, uint8_t* types, unsigned sp, uintptr_t* args,
GcMethod* method, bool fastCallingConvention) uint8_t* types,
unsigned sp,
GcMethod* method,
bool fastCallingConvention)
{ {
MethodSpecIterator it MethodSpecIterator it(
(t, reinterpret_cast<const char*> t, reinterpret_cast<const char*>(method->spec()->body().begin()));
(method->spec()->body().begin()));
unsigned argOffset = 0; unsigned argOffset = 0;
unsigned typeOffset = 0; unsigned typeOffset = 0;
@ -538,8 +533,7 @@ marshalArguments(Thread* t, uintptr_t* args, uint8_t* types, unsigned sp,
} }
} }
unsigned unsigned invokeNativeSlow(Thread* t, GcMethod* method, void* function)
invokeNativeSlow(Thread* t, GcMethod* method, void* function)
{ {
PROTECT(t, method); PROTECT(t, method);
@ -587,7 +581,8 @@ invokeNativeSlow(Thread* t, GcMethod* method, void* function)
uint64_t result; uint64_t result;
if (DebugRun) { if (DebugRun) {
fprintf(stderr, "invoke native method %s.%s\n", fprintf(stderr,
"invoke native method %s.%s\n",
method->class_()->name()->body().begin(), method->class_()->name()->body().begin(),
method->name()->body().begin()); method->name()->body().begin());
} }
@ -607,7 +602,8 @@ invokeNativeSlow(Thread* t, GcMethod* method, void* function)
} }
if (DebugRun) { if (DebugRun) {
fprintf(stderr, "return from native method %s.%s\n", fprintf(stderr,
"return from native method %s.%s\n",
frameMethod(t, t->frame)->class_()->name()->body().begin(), frameMethod(t, t->frame)->class_()->name()->body().begin(),
frameMethod(t, t->frame)->name()->body().begin()); frameMethod(t, t->frame)->name()->body().begin());
} }
@ -625,8 +621,7 @@ invokeNativeSlow(Thread* t, GcMethod* method, void* function)
return returnCode; return returnCode;
} }
unsigned unsigned invokeNative(Thread* t, GcMethod* method)
invokeNative(Thread* t, GcMethod* method)
{ {
PROTECT(t, method); PROTECT(t, method);
@ -651,8 +646,8 @@ invokeNative(Thread* t, GcMethod* method)
marshalArguments marshalArguments
(t, RUNTIME_ARRAY_BODY(args) + argOffset, 0, sp, method, true); (t, RUNTIME_ARRAY_BODY(args) + argOffset, 0, sp, method, true);
result = reinterpret_cast<FastNativeFunction> result = reinterpret_cast<FastNativeFunction>(native->function())(
(native->function())(t, method, RUNTIME_ARRAY_BODY(args)); t, method, RUNTIME_ARRAY_BODY(args));
} }
pushResult(t, method->returnCode(), result, false); pushResult(t, method->returnCode(), result, false);
@ -683,12 +678,12 @@ isNaN(float v)
return fpclassify(v) == FP_NAN; return fpclassify(v) == FP_NAN;
} }
uint64_t uint64_t findExceptionHandler(Thread* t, GcMethod* method, unsigned ip)
findExceptionHandler(Thread* t, GcMethod* method, unsigned ip)
{ {
PROTECT(t, method); PROTECT(t, method);
GcExceptionHandlerTable* eht = cast<GcExceptionHandlerTable>(t, method->code()->exceptionHandlerTable()); GcExceptionHandlerTable* eht = cast<GcExceptionHandlerTable>(
t, method->code()->exceptionHandlerTable());
if (eht) { if (eht) {
for (unsigned i = 0; i < eht->length(); ++i) { for (unsigned i = 0; i < eht->length(); ++i) {
@ -732,8 +727,7 @@ findExceptionHandler(Thread* t, int frame)
return findExceptionHandler(t, frameMethod(t, frame), frameIp(t, frame)); return findExceptionHandler(t, frameMethod(t, frame), frameIp(t, frame));
} }
void void pushField(Thread* t, object target, GcField* field)
pushField(Thread* t, object target, GcField* field)
{ {
switch (field->code()) { switch (field->code()) {
case ByteField: case ByteField:
@ -791,10 +785,11 @@ interpret3(Thread* t, const int base)
} }
loop: loop:
instruction = code->body()[ip++]; instruction = code->body()[ip++];
if (DebugRun) { if (DebugRun) {
fprintf(stderr, "ip: %d; instruction: 0x%x in %s.%s ", fprintf(stderr,
"ip: %d; instruction: 0x%x in %s.%s ",
ip - 1, ip - 1,
instruction, instruction,
frameMethod(t, frame)->class_()->name()->body().begin(), frameMethod(t, frame)->class_()->name()->body().begin(),
@ -824,9 +819,11 @@ interpret3(Thread* t, const int base)
{ {
pushObject(t, objectArrayBody(t, array, index)); pushObject(t, objectArrayBody(t, array, index));
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, objectArrayLength(t, array)); "%d not in [0,%d)",
index,
objectArrayLength(t, array));
goto throw_; goto throw_;
} }
} else { } else {
@ -846,9 +843,11 @@ interpret3(Thread* t, const int base)
{ {
setField(t, array, ArrayBody + (index * BytesPerWord), value); setField(t, array, ArrayBody + (index * BytesPerWord), value);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, objectArrayLength(t, array)); "%d not in [0,%d)",
index,
objectArrayLength(t, array));
goto throw_; goto throw_;
} }
} else { } else {
@ -891,8 +890,8 @@ interpret3(Thread* t, const int base)
pushObject(t, makeObjectArray(t, class_, count)); pushObject(t, makeObjectArray(t, class_, count));
} else { } else {
exception = makeThrowable exception
(t, GcNegativeArraySizeException::Type, "%d", count); = makeThrowable(t, GcNegativeArraySizeException::Type, "%d", count);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -952,28 +951,28 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
if (objectClass(t, array) == type(t, GcBooleanArray::Type)) { if (objectClass(t, array) == type(t, GcBooleanArray::Type)) {
GcBooleanArray* a = cast<GcBooleanArray>(t, array); GcBooleanArray* a = cast<GcBooleanArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0
static_cast<uintptr_t>(index) and static_cast<uintptr_t>(index) < a->length())) {
< a->length()))
{
pushInt(t, a->body()[index]); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
GcByteArray* a = cast<GcByteArray>(t, array); GcByteArray* a = cast<GcByteArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0
static_cast<uintptr_t>(index) and static_cast<uintptr_t>(index) < a->length())) {
< a->length()))
{
pushInt(t, a->body()[index]); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} }
@ -991,27 +990,28 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
if (objectClass(t, array) == type(t, GcBooleanArray::Type)) { if (objectClass(t, array) == type(t, GcBooleanArray::Type)) {
GcBooleanArray* a = cast<GcBooleanArray>(t, array); GcBooleanArray* a = cast<GcBooleanArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0
static_cast<uintptr_t>(index) and static_cast<uintptr_t>(index) < a->length())) {
< a->length()))
{
a->body()[index] = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
GcByteArray* a = cast<GcByteArray>(t, array); GcByteArray* a = cast<GcByteArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0
static_cast<uintptr_t>(index) < a->length())) and static_cast<uintptr_t>(index) < a->length())) {
{
a->body()[index] = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, GcArrayIndexOutOfBoundsException::Type,
"%d not in [0,%d)", index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} }
@ -1031,14 +1031,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcCharArray* a = cast<GcCharArray>(t, array); GcCharArray* a = cast<GcCharArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
pushInt(t, a->body()[index]); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1054,14 +1054,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcCharArray* a = cast<GcCharArray>(t, array); GcCharArray* a = cast<GcCharArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
a->body()[index] = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1078,10 +1078,12 @@ interpret3(Thread* t, const int base)
if (UNLIKELY(exception)) goto throw_; if (UNLIKELY(exception)) goto throw_;
if (not instanceOf(t, class_, peekObject(t, sp - 1))) { if (not instanceOf(t, class_, peekObject(t, sp - 1))) {
exception = makeThrowable exception = makeThrowable(
(t, GcClassCastException::Type, "%s as %s", t,
objectClass(t, peekObject(t, sp - 1))->name()->body().begin(), GcClassCastException::Type,
class_->name()->body().begin()); "%s as %s",
objectClass(t, peekObject(t, sp - 1))->name()->body().begin(),
class_->name()->body().begin());
goto throw_; goto throw_;
} }
} }
@ -1128,14 +1130,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcDoubleArray* a = cast<GcDoubleArray>(t, array); GcDoubleArray* a = cast<GcDoubleArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
pushLong(t, a->body()[index]); pushLong(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1151,14 +1153,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcDoubleArray* a = cast<GcDoubleArray>(t, array); GcDoubleArray* a = cast<GcDoubleArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
memcpy(&a->body()[index], &value, sizeof(uint64_t)); memcpy(&a->body()[index], &value, sizeof(uint64_t));
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1347,14 +1349,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcFloatArray* a = cast<GcFloatArray>(t, array); GcFloatArray* a = cast<GcFloatArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
pushInt(t, a->body()[index]); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1370,14 +1372,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcFloatArray* a = cast<GcFloatArray>(t, array); GcFloatArray* a = cast<GcFloatArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
memcpy(&a->body()[index], &value, sizeof(uint32_t)); memcpy(&a->body()[index], &value, sizeof(uint32_t));
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1548,14 +1550,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcIntArray* a = cast<GcIntArray>(t, array); GcIntArray* a = cast<GcIntArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
pushInt(t, a->body()[index]); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1578,14 +1580,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcIntArray* a = cast<GcIntArray>(t, array); GcIntArray* a = cast<GcIntArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
a->body()[index] = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -1855,8 +1857,8 @@ interpret3(Thread* t, const int base)
unsigned parameterFootprint = m->parameterFootprint(); unsigned parameterFootprint = m->parameterFootprint();
if (LIKELY(peekObject(t, sp - parameterFootprint))) { if (LIKELY(peekObject(t, sp - parameterFootprint))) {
method = findInterfaceMethod method = findInterfaceMethod(
(t, m, objectClass(t, peekObject(t, sp - parameterFootprint))); t, m, objectClass(t, peekObject(t, sp - parameterFootprint)));
goto invoke; goto invoke;
} else { } else {
exception = makeThrowable(t, GcNullPointerException::Type); exception = makeThrowable(t, GcNullPointerException::Type);
@ -2051,14 +2053,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcLongArray* a = cast<GcLongArray>(t, array); GcLongArray* a = cast<GcLongArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
pushLong(t, a->body()[index]); pushLong(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2081,14 +2083,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcLongArray* a = cast<GcLongArray>(t, array); GcLongArray* a = cast<GcLongArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
a->body()[index] = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2127,12 +2129,13 @@ interpret3(Thread* t, const int base)
if (singletonIsObject(t, pool, index - 1)) { if (singletonIsObject(t, pool, index - 1)) {
object v = singletonObject(t, pool, index - 1); object v = singletonObject(t, pool, index - 1);
if (objectClass(t, v) == type(t, GcReference::Type)) { if (objectClass(t, v) == type(t, GcReference::Type)) {
GcClass* class_ = resolveClassInPool GcClass* class_
(t, frameMethod(t, frame), index - 1); = resolveClassInPool(t, frameMethod(t, frame), index - 1);
pushObject(t, reinterpret_cast<object>(getJClass(t, class_))); pushObject(t, reinterpret_cast<object>(getJClass(t, class_)));
} else if (objectClass(t, v) == type(t, GcClass::Type)) { } else if (objectClass(t, v) == type(t, GcClass::Type)) {
pushObject(t, reinterpret_cast<object>(getJClass(t, cast<GcClass>(t, v)))); pushObject(t,
reinterpret_cast<object>(getJClass(t, cast<GcClass>(t, v))));
} else { } else {
pushObject(t, v); pushObject(t, v);
} }
@ -2353,9 +2356,10 @@ interpret3(Thread* t, const int base)
for (int i = dimensions - 1; i >= 0; --i) { for (int i = dimensions - 1; i >= 0; --i) {
RUNTIME_ARRAY_BODY(counts)[i] = popInt(t); RUNTIME_ARRAY_BODY(counts)[i] = popInt(t);
if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) { if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) {
exception = makeThrowable exception = makeThrowable(t,
(t, GcNegativeArraySizeException::Type, "%d", GcNegativeArraySizeException::Type,
RUNTIME_ARRAY_BODY(counts)[i]); "%d",
RUNTIME_ARRAY_BODY(counts)[i]);
goto throw_; goto throw_;
} }
} }
@ -2426,8 +2430,8 @@ interpret3(Thread* t, const int base)
pushObject(t, array); pushObject(t, array);
} else { } else {
exception = makeThrowable exception
(t, GcNegativeArraySizeException::Type, "%d", count); = makeThrowable(t, GcNegativeArraySizeException::Type, "%d", count);
goto throw_; goto throw_;
} }
} goto loop; } goto loop;
@ -2574,8 +2578,7 @@ interpret3(Thread* t, const int base)
case return_: { case return_: {
GcMethod* method = frameMethod(t, frame); GcMethod* method = frameMethod(t, frame);
if ((method->flags() & ConstructorFlag) if ((method->flags() & ConstructorFlag)
and (method->class_()->vmFlags() & HasFinalMemberFlag)) and (method->class_()->vmFlags() & HasFinalMemberFlag)) {
{
storeStoreMemoryBarrier(); storeStoreMemoryBarrier();
} }
@ -2593,14 +2596,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcShortArray* a = cast<GcShortArray>(t, array); GcShortArray* a = cast<GcShortArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
pushInt(t, a->body()[index]); pushInt(t, a->body()[index]);
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2616,14 +2619,14 @@ interpret3(Thread* t, const int base)
if (LIKELY(array)) { if (LIKELY(array)) {
GcShortArray* a = cast<GcShortArray>(t, array); GcShortArray* a = cast<GcShortArray>(t, array);
if (LIKELY(index >= 0 and if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
static_cast<uintptr_t>(index) < a->length()))
{
a->body()[index] = value; a->body()[index] = value;
} else { } else {
exception = makeThrowable exception = makeThrowable(t,
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)", GcArrayIndexOutOfBoundsException::Type,
index, a->length()); "%d not in [0,%d)",
index,
a->length());
goto throw_; goto throw_;
} }
} else { } else {
@ -2683,8 +2686,7 @@ interpret3(Thread* t, const int base)
GcClass* class_ = objectClass(t, peekObject(t, sp - parameterFootprint)); GcClass* class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
assertT(t, class_->vmFlags() & BootstrapFlag); assertT(t, class_->vmFlags() & BootstrapFlag);
resolveClass(t, frameMethod(t, frame)->class_()->loader(), resolveClass(t, frameMethod(t, frame)->class_()->loader(), class_->name());
class_->name());
ip -= 3; ip -= 3;
} goto loop; } goto loop;
@ -2693,7 +2695,7 @@ interpret3(Thread* t, const int base)
} }
wide: wide:
switch (code->body()[ip++]) { switch (code->body()[ip++]) {
case aload: { case aload: {
pushObject(t, localObject(t, codeReadInt16(t, code, ip))); pushObject(t, localObject(t, codeReadInt16(t, code, ip)));
} goto loop; } goto loop;
@ -2737,8 +2739,8 @@ interpret3(Thread* t, const int base)
goto loop; goto loop;
invoke: { invoke: {
if (method->flags() & ACC_NATIVE) { if (method->flags() & ACC_NATIVE) {
invokeNative(t, method); invokeNative(t, method);
} else { } else {
checkStack(t, method); checkStack(t, method);
pushFrame(t, method); pushFrame(t, method);
@ -2896,8 +2898,7 @@ pushArguments(Thread* t, object this_, const char* spec, object a)
} }
} }
object object invoke(Thread* t, GcMethod* method)
invoke(Thread* t, GcMethod* method)
{ {
PROTECT(t, method); PROTECT(t, method);
@ -2982,8 +2983,9 @@ class MyProcessor: public Processor {
signals.setCrashDumpDirectory(crashDumpDirectory); signals.setCrashDumpDirectory(crashDumpDirectory);
} }
virtual vm::Thread* virtual vm::Thread* makeThread(Machine* m,
makeThread(Machine* m, GcThread* javaThread, vm::Thread* parent) GcThread* javaThread,
vm::Thread* parent)
{ {
Thread* t = new (m->heap->allocate(sizeof(Thread) + m->stackSizeInBytes)) Thread* t = new (m->heap->allocate(sizeof(Thread) + m->stackSizeInBytes))
Thread(m, javaThread, parent); Thread(m, javaThread, parent);
@ -2991,19 +2993,18 @@ class MyProcessor: public Processor {
return t; return t;
} }
virtual GcMethod* virtual GcMethod* makeMethod(vm::Thread* t,
makeMethod(vm::Thread* t, uint8_t vmFlags,
uint8_t vmFlags, uint8_t returnCode,
uint8_t returnCode, uint8_t parameterCount,
uint8_t parameterCount, uint8_t parameterFootprint,
uint8_t parameterFootprint, uint16_t flags,
uint16_t flags, uint16_t offset,
uint16_t offset, GcByteArray* name,
GcByteArray* name, GcByteArray* spec,
GcByteArray* spec, GcMethodAddendum* addendum,
GcMethodAddendum* addendum, GcClass* class_,
GcClass* class_, GcCode* code)
GcCode* code)
{ {
return vm::makeMethod(t, return vm::makeMethod(t,
vmFlags, vmFlags,
@ -3021,26 +3022,25 @@ class MyProcessor: public Processor {
code); code);
} }
virtual GcClass* virtual GcClass* makeClass(vm::Thread* t,
makeClass(vm::Thread* t, uint16_t flags,
uint16_t flags, uint16_t vmFlags,
uint16_t vmFlags, uint16_t fixedSize,
uint16_t fixedSize, uint8_t arrayElementSize,
uint8_t arrayElementSize, uint8_t arrayDimensions,
uint8_t arrayDimensions, GcClass* arrayElementClass,
GcClass* arrayElementClass, GcIntArray* objectMask,
GcIntArray* objectMask, GcByteArray* name,
GcByteArray* name, GcByteArray* sourceFile,
GcByteArray* sourceFile, GcClass* super,
GcClass* super, object interfaceTable,
object interfaceTable, object virtualTable,
object virtualTable, object fieldTable,
object fieldTable, object methodTable,
object methodTable, GcClassAddendum* addendum,
GcClassAddendum* addendum, GcSingleton* staticTable,
GcSingleton* staticTable, GcClassLoader* loader,
GcClassLoader* loader, unsigned vtableLength UNUSED)
unsigned vtableLength UNUSED)
{ {
return vm::makeClass(t, return vm::makeClass(t,
flags, flags,
@ -3065,8 +3065,7 @@ class MyProcessor: public Processor {
0); 0);
} }
virtual void virtual void initVtable(vm::Thread*, GcClass*)
initVtable(vm::Thread*, GcClass*)
{ {
// ignore // ignore
} }
@ -3098,8 +3097,7 @@ class MyProcessor: public Processor {
walker.walk(v); walker.walk(v);
} }
virtual int virtual int lineNumber(vm::Thread* t, GcMethod* method, int ip)
lineNumber(vm::Thread* t, GcMethod* method, int ip)
{ {
return findLineNumber(static_cast<Thread*>(t), method, ip); return findLineNumber(static_cast<Thread*>(t), method, ip);
} }
@ -3147,86 +3145,92 @@ class MyProcessor: public Processor {
t->m->heap->free(f, sizeof(List<unsigned>)); t->m->heap->free(f, sizeof(List<unsigned>));
} }
virtual object virtual object invokeArray(vm::Thread* vmt,
invokeArray(vm::Thread* vmt, GcMethod* method, object this_, object arguments) GcMethod* method,
object this_,
object arguments)
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
assertT(t, t->state == Thread::ActiveState assertT(
or t->state == Thread::ExclusiveState); t,
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0)); assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + method->parameterFootprint() + 1 if (UNLIKELY(t->sp + method->parameterFootprint() + 1 > stackSizeInWords(t)
> stackSizeInWords(t) / 2)) / 2)) {
{
throwNew(t, GcStackOverflowError::Type); throwNew(t, GcStackOverflowError::Type);
} }
const char* spec = reinterpret_cast<char*> const char* spec = reinterpret_cast<char*>(method->spec()->body().begin());
(method->spec()->body().begin());
pushArguments(t, this_, spec, arguments); pushArguments(t, this_, spec, arguments);
return local::invoke(t, method); return local::invoke(t, method);
} }
virtual object virtual object invokeArray(vm::Thread* vmt,
invokeArray(vm::Thread* vmt, GcMethod* method, object this_, GcMethod* method,
const jvalue* arguments) object this_,
const jvalue* arguments)
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
assertT(t, t->state == Thread::ActiveState assertT(
or t->state == Thread::ExclusiveState); t,
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0)); assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + method->parameterFootprint() + 1 if (UNLIKELY(t->sp + method->parameterFootprint() + 1 > stackSizeInWords(t)
> stackSizeInWords(t) / 2)) / 2)) {
{
throwNew(t, GcStackOverflowError::Type); throwNew(t, GcStackOverflowError::Type);
} }
const char* spec = reinterpret_cast<char*> const char* spec = reinterpret_cast<char*>(method->spec()->body().begin());
(method->spec()->body().begin());
pushArguments(t, this_, spec, arguments); pushArguments(t, this_, spec, arguments);
return local::invoke(t, method); return local::invoke(t, method);
} }
virtual object virtual object invokeList(vm::Thread* vmt,
invokeList(vm::Thread* vmt, GcMethod* method, object this_, GcMethod* method,
bool indirectObjects, va_list arguments) object this_,
bool indirectObjects,
va_list arguments)
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
assertT(t, t->state == Thread::ActiveState assertT(
or t->state == Thread::ExclusiveState); t,
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0)); assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + method->parameterFootprint() + 1 if (UNLIKELY(t->sp + method->parameterFootprint() + 1 > stackSizeInWords(t)
> stackSizeInWords(t) / 2)) / 2)) {
{
throwNew(t, GcStackOverflowError::Type); throwNew(t, GcStackOverflowError::Type);
} }
const char* spec = reinterpret_cast<char*> const char* spec = reinterpret_cast<char*>(method->spec()->body().begin());
(method->spec()->body().begin());
pushArguments(t, this_, spec, indirectObjects, arguments); pushArguments(t, this_, spec, indirectObjects, arguments);
return local::invoke(t, method); return local::invoke(t, method);
} }
virtual object virtual object invokeList(vm::Thread* vmt,
invokeList(vm::Thread* vmt, GcClassLoader* loader, const char* className, GcClassLoader* loader,
const char* methodName, const char* methodSpec, object this_, const char* className,
va_list arguments) const char* methodName,
const char* methodSpec,
object this_,
va_list arguments)
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
assertT(t, t->state == Thread::ActiveState assertT(
or t->state == Thread::ExclusiveState); t,
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false) if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false)
> stackSizeInWords(t) / 2)) > stackSizeInWords(t) / 2))
@ -3236,8 +3240,8 @@ class MyProcessor: public Processor {
pushArguments(t, this_, methodSpec, false, arguments); pushArguments(t, this_, methodSpec, false, arguments);
GcMethod* method = resolveMethod GcMethod* method
(t, loader, className, methodName, methodSpec); = resolveMethod(t, loader, className, methodName, methodSpec);
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0)); assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
@ -3258,8 +3262,13 @@ class MyProcessor: public Processor {
abort(s); abort(s);
} }
virtual void compileMethod(vm::Thread*, Zone*, GcTriple**, GcTriple**, virtual void compileMethod(vm::Thread*,
avian::codegen::DelayedPromise**, GcMethod*, OffsetResolver*) Zone*,
GcTriple**,
GcTriple**,
avian::codegen::DelayedPromise**,
GcMethod*,
OffsetResolver*)
{ {
abort(s); abort(s);
} }
@ -3288,11 +3297,15 @@ class MyProcessor: public Processor {
abort(s); abort(s);
} }
virtual void feedResultToContinuation(vm::Thread*, GcContinuation*, object){ virtual void feedResultToContinuation(vm::Thread*, GcContinuation*, object)
{
abort(s); abort(s);
} }
virtual void feedExceptionToContinuation(vm::Thread*, GcContinuation*, GcThrowable*) { virtual void feedExceptionToContinuation(vm::Thread*,
GcContinuation*,
GcThrowable*)
{
abort(s); abort(s);
} }

View File

@ -150,8 +150,8 @@ GetStringChars(Thread* t, jstring s, jboolean* isCopy)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
jchar* chars = static_cast<jchar*> jchar* chars = static_cast<jchar*>(
(t->m->heap->allocate(((*s)->length(t) + 1) * sizeof(jchar))); t->m->heap->allocate(((*s)->length(t) + 1) * sizeof(jchar)));
stringChars(t, *s, chars); stringChars(t, *s, chars);
if (isCopy) *isCopy = true; if (isCopy) *isCopy = true;
@ -266,9 +266,7 @@ newString(Thread* t, uintptr_t* arguments)
} }
return reinterpret_cast<uint64_t>( return reinterpret_cast<uint64_t>(
makeLocalReference(t, makeLocalReference(t, t->m->classpath->makeString(t, a, 0, size)));
t->m->classpath->makeString(
t, a, 0, size)));
} }
jstring JNICALL jstring JNICALL
@ -325,14 +323,14 @@ defineClass(Thread* t, uintptr_t* arguments)
return reinterpret_cast<uint64_t>(makeLocalReference( return reinterpret_cast<uint64_t>(makeLocalReference(
t, t,
getJClass(t, getJClass(
cast<GcClass>( t,
t, cast<GcClass>(t,
defineClass(t, defineClass(t,
loader ? cast<GcClassLoader>(t, *loader) loader ? cast<GcClassLoader>(t, *loader)
: roots(t)->bootLoader(), : roots(t)->bootLoader(),
buffer, buffer,
length))))); length)))));
} }
jclass JNICALL jclass JNICALL
@ -456,8 +454,8 @@ getObjectClass(Thread* t, uintptr_t* arguments)
{ {
jobject o = reinterpret_cast<jobject>(arguments[0]); jobject o = reinterpret_cast<jobject>(arguments[0]);
return reinterpret_cast<uint64_t>(makeLocalReference( return reinterpret_cast<uint64_t>(
t, getJClass(t, objectClass(t, *o)))); makeLocalReference(t, getJClass(t, objectClass(t, *o))));
} }
jclass JNICALL jclass JNICALL
@ -525,8 +523,7 @@ IsAssignableFrom(Thread* t, jclass b, jclass a)
return run(t, isAssignableFrom, arguments); return run(t, isAssignableFrom, arguments);
} }
GcMethod* GcMethod* findMethod(Thread* t, jclass c, const char* name, const char* spec)
findMethod(Thread* t, jclass c, const char* name, const char* spec)
{ {
GcByteArray* n = makeByteArray(t, "%s", name); GcByteArray* n = makeByteArray(t, "%s", name);
PROTECT(t, n); PROTECT(t, n);
@ -535,8 +532,7 @@ findMethod(Thread* t, jclass c, const char* name, const char* spec)
return vm::findMethod(t, (*c)->vmClass(), n, s); return vm::findMethod(t, (*c)->vmClass(), n, s);
} }
jint jint methodID(Thread* t, GcMethod* method)
methodID(Thread* t, GcMethod* method)
{ {
int id = method->nativeID(); int id = method->nativeID();
@ -548,8 +544,7 @@ methodID(Thread* t, GcMethod* method)
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
if (method->nativeID() == 0) { if (method->nativeID() == 0) {
GcVector* v = vectorAppend( GcVector* v = vectorAppend(t, roots(t)->jNIMethodTable(), method);
t, roots(t)->jNIMethodTable(), method);
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
roots(t)->setJNIMethodTable(t, v); roots(t)->setJNIMethodTable(t, v);
@ -610,12 +605,12 @@ GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec)
return run(t, getStaticMethodID, arguments); return run(t, getStaticMethodID, arguments);
} }
GcMethod* GcMethod* getMethod(Thread* t, jmethodID m)
getMethod(Thread* t, jmethodID m)
{ {
assertT(t, m); assertT(t, m);
GcMethod* method = cast<GcMethod>(t, roots(t)->jNIMethodTable()->body()[m - 1]); GcMethod* method
= cast<GcMethod>(t, roots(t)->jNIMethodTable()->body()[m - 1]);
assertT(t, (method->flags() & ACC_STATIC) == 0); assertT(t, (method->flags() & ACC_STATIC) == 0);
@ -675,12 +670,10 @@ newObjectA(Thread* t, uintptr_t* arguments)
return reinterpret_cast<uint64_t>(makeLocalReference(t, o)); return reinterpret_cast<uint64_t>(makeLocalReference(t, o));
} }
jobject JNICALL jobject JNICALL NewObjectA(Thread* t, jclass c, jmethodID m, const jvalue* a)
NewObjectA(Thread* t, jclass c, jmethodID m, const jvalue* a)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[]
m, = {reinterpret_cast<uintptr_t>(c), m, reinterpret_cast<uintptr_t>(a)};
reinterpret_cast<uintptr_t>(a) };
return reinterpret_cast<jobject>(run(t, newObjectA, arguments)); return reinterpret_cast<jobject>(run(t, newObjectA, arguments));
} }
@ -749,8 +742,9 @@ callIntMethodV(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[1]; jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]); va_list* a = reinterpret_cast<va_list*>(arguments[2]);
return cast<GcInt> return cast<GcInt>(
(t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))->value(); t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))
->value();
} }
jboolean JNICALL jboolean JNICALL
@ -783,8 +777,8 @@ callIntMethodA(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[1]; jmethodID m = arguments[1];
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[2]); const jvalue* a = reinterpret_cast<const jvalue*>(arguments[2]);
return cast<GcInt> return cast<GcInt>(t, t->m->processor->invokeArray(t, getMethod(t, m), *o, a))
(t, t->m->processor->invokeArray(t, getMethod(t, m), *o, a))->value(); ->value();
} }
jboolean JNICALL jboolean JNICALL
@ -936,8 +930,9 @@ callLongMethodV(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[1]; jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]); va_list* a = reinterpret_cast<va_list*>(arguments[2]);
return cast<GcLong> return cast<GcLong>(
(t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))->value(); t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))
->value();
} }
jlong JNICALL jlong JNICALL
@ -970,8 +965,9 @@ callLongMethodA(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[1]; jmethodID m = arguments[1];
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[2]); const jvalue* a = reinterpret_cast<const jvalue*>(arguments[2]);
return cast<GcLong> return cast<GcLong>(t,
(t, t->m->processor->invokeArray(t, getMethod(t, m), *o, a))->value(); t->m->processor->invokeArray(t, getMethod(t, m), *o, a))
->value();
} }
jlong JNICALL jlong JNICALL
@ -1105,12 +1101,12 @@ CallVoidMethodA(Thread* t, jobject o, jmethodID m, const jvalue* a)
run(t, callVoidMethodA, arguments); run(t, callVoidMethodA, arguments);
} }
GcMethod* GcMethod* getStaticMethod(Thread* t, jmethodID m)
getStaticMethod(Thread* t, jmethodID m)
{ {
assertT(t, m); assertT(t, m);
GcMethod* method = cast<GcMethod>(t, roots(t)->jNIMethodTable()->body()[m - 1]); GcMethod* method
= cast<GcMethod>(t, roots(t)->jNIMethodTable()->body()[m - 1]);
assertT(t, method->flags() & ACC_STATIC); assertT(t, method->flags() & ACC_STATIC);
@ -1174,8 +1170,9 @@ callStaticIntMethodV(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[0]; jmethodID m = arguments[0];
va_list* a = reinterpret_cast<va_list*>(arguments[1]); va_list* a = reinterpret_cast<va_list*>(arguments[1]);
return cast<GcInt> return cast<GcInt>(t,
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a))->value(); t->m->processor->invokeList(
t, getStaticMethod(t, m), 0, true, *a))->value();
} }
jboolean JNICALL jboolean JNICALL
@ -1205,8 +1202,9 @@ callStaticIntMethodA(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[0]; jmethodID m = arguments[0];
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[1]); const jvalue* a = reinterpret_cast<const jvalue*>(arguments[1]);
return cast<GcInt> return cast<GcInt>(
(t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))->value(); t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))
->value();
} }
jboolean JNICALL jboolean JNICALL
@ -1339,8 +1337,9 @@ callStaticLongMethodV(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[0]; jmethodID m = arguments[0];
va_list* a = reinterpret_cast<va_list*>(arguments[1]); va_list* a = reinterpret_cast<va_list*>(arguments[1]);
return cast<GcLong> return cast<GcLong>(t,
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a))->value(); t->m->processor->invokeList(
t, getStaticMethod(t, m), 0, true, *a))->value();
} }
jlong JNICALL jlong JNICALL
@ -1370,8 +1369,9 @@ callStaticLongMethodA(Thread* t, uintptr_t* arguments)
jmethodID m = arguments[0]; jmethodID m = arguments[0];
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[1]); const jvalue* a = reinterpret_cast<const jvalue*>(arguments[1]);
return cast<GcLong> return cast<GcLong>(
(t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))->value(); t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))
->value();
} }
jlong JNICALL jlong JNICALL
@ -1489,8 +1489,7 @@ CallStaticVoidMethodA(Thread* t, jclass, jmethodID m, const jvalue* a)
run(t, callStaticVoidMethodA, arguments); run(t, callStaticVoidMethodA, arguments);
} }
jint jint fieldID(Thread* t, GcField* field)
fieldID(Thread* t, GcField* field)
{ {
int id = field->nativeID(); int id = field->nativeID();
@ -1502,8 +1501,7 @@ fieldID(Thread* t, GcField* field)
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
if (field->nativeID() == 0) { if (field->nativeID() == 0) {
GcVector* v = vectorAppend( GcVector* v = vectorAppend(t, roots(t)->jNIFieldTable(), field);
t, roots(t)->jNIFieldTable(), field);
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
roots(t)->setJNIFieldTable(t, v); roots(t)->setJNIFieldTable(t, v);
@ -1546,8 +1544,7 @@ GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec)
return run(t, getFieldID, arguments); return run(t, getFieldID, arguments);
} }
GcField* GcField* getField(Thread* t, jfieldID f)
getField(Thread* t, jfieldID f)
{ {
assertT(t, f); assertT(t, f);
@ -1567,8 +1564,8 @@ getObjectField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return reinterpret_cast<uintptr_t> return reinterpret_cast<uintptr_t>(
(makeLocalReference(t, fieldAtOffset<object>(*o, field->offset()))); makeLocalReference(t, fieldAtOffset<object>(*o, field->offset())));
} }
jobject JNICALL jobject JNICALL
@ -1975,8 +1972,7 @@ SetDoubleField(Thread* t, jobject o, jfieldID field, jdouble v)
run(t, setDoubleField, arguments); run(t, setDoubleField, arguments);
} }
GcField* GcField* getStaticField(Thread* t, jfieldID f)
getStaticField(Thread* t, jfieldID f)
{ {
assertT(t, f); assertT(t, f);
@ -1999,14 +1995,11 @@ getStaticObjectField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return reinterpret_cast<uintptr_t> return reinterpret_cast<uintptr_t>(makeLocalReference(
(makeLocalReference t, fieldAtOffset<object>(c->vmClass()->staticTable(), field->offset())));
(t, fieldAtOffset<object>
(c->vmClass()->staticTable(), field->offset())));
} }
jobject JNICALL jobject JNICALL GetStaticObjectField(Thread* t, jclass c, jfieldID field)
GetStaticObjectField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2026,12 +2019,10 @@ getStaticBooleanField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return fieldAtOffset<jboolean> return fieldAtOffset<jboolean>(c->vmClass()->staticTable(), field->offset());
(c->vmClass()->staticTable(), field->offset());
} }
jboolean JNICALL jboolean JNICALL GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2051,12 +2042,10 @@ getStaticByteField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return fieldAtOffset<jbyte> return fieldAtOffset<jbyte>(c->vmClass()->staticTable(), field->offset());
(c->vmClass()->staticTable(), field->offset());
} }
jbyte JNICALL jbyte JNICALL GetStaticByteField(Thread* t, jclass c, jfieldID field)
GetStaticByteField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2076,12 +2065,10 @@ getStaticCharField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return fieldAtOffset<jchar> return fieldAtOffset<jchar>(c->vmClass()->staticTable(), field->offset());
(c->vmClass()->staticTable(), field->offset());
} }
jchar JNICALL jchar JNICALL GetStaticCharField(Thread* t, jclass c, jfieldID field)
GetStaticCharField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2101,12 +2088,10 @@ getStaticShortField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return fieldAtOffset<jshort> return fieldAtOffset<jshort>(c->vmClass()->staticTable(), field->offset());
(c->vmClass()->staticTable(), field->offset());
} }
jshort JNICALL jshort JNICALL GetStaticShortField(Thread* t, jclass c, jfieldID field)
GetStaticShortField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2126,12 +2111,10 @@ getStaticIntField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return fieldAtOffset<jint> return fieldAtOffset<jint>(c->vmClass()->staticTable(), field->offset());
(c->vmClass()->staticTable(), field->offset());
} }
jint JNICALL jint JNICALL GetStaticIntField(Thread* t, jclass c, jfieldID field)
GetStaticIntField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2151,12 +2134,10 @@ getStaticLongField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return fieldAtOffset<jlong> return fieldAtOffset<jlong>(c->vmClass()->staticTable(), field->offset());
(c->vmClass()->staticTable(), field->offset());
} }
jlong JNICALL jlong JNICALL GetStaticLongField(Thread* t, jclass c, jfieldID field)
GetStaticLongField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2176,13 +2157,11 @@ getStaticFloatField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return floatToBits return floatToBits(
(fieldAtOffset<jfloat> fieldAtOffset<jfloat>(c->vmClass()->staticTable(), field->offset()));
(c->vmClass()->staticTable(), field->offset()));
} }
jfloat JNICALL jfloat JNICALL GetStaticFloatField(Thread* t, jclass c, jfieldID field)
GetStaticFloatField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2202,13 +2181,11 @@ getStaticDoubleField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_READ(t, field); ACQUIRE_FIELD_FOR_READ(t, field);
return doubleToBits return doubleToBits(
(fieldAtOffset<jdouble> fieldAtOffset<jdouble>(c->vmClass()->staticTable(), field->offset()));
(c->vmClass()->staticTable(), field->offset()));
} }
jdouble JNICALL jdouble JNICALL GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field }; field };
@ -2229,14 +2206,13 @@ setStaticObjectField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
setField(t, c->vmClass()->staticTable(), field->offset(), setField(t, c->vmClass()->staticTable(), field->offset(), (v ? *v : 0));
(v ? *v : 0));
return 1; return 1;
} }
void JNICALL void JNICALL
SetStaticObjectField(Thread* t, jclass c, jfieldID field, jobject v) SetStaticObjectField(Thread* t, jclass c, jfieldID field, jobject v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2258,14 +2234,13 @@ setStaticBooleanField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jboolean> fieldAtOffset<jboolean>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL
SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v) SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2287,14 +2262,12 @@ setStaticByteField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jbyte> fieldAtOffset<jbyte>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2316,14 +2289,12 @@ setStaticCharField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jchar> fieldAtOffset<jchar>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2345,14 +2316,12 @@ setStaticShortField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jshort> fieldAtOffset<jshort>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2374,14 +2343,12 @@ setStaticIntField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jint> fieldAtOffset<jint>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2403,14 +2370,12 @@ setStaticLongField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jlong> fieldAtOffset<jlong>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
{ {
uintptr_t arguments[2 + (sizeof(jlong) / BytesPerWord)]; uintptr_t arguments[2 + (sizeof(jlong) / BytesPerWord)];
arguments[0] = reinterpret_cast<uintptr_t>(c); arguments[0] = reinterpret_cast<uintptr_t>(c);
@ -2433,14 +2398,12 @@ setStaticFloatField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jfloat> fieldAtOffset<jfloat>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
@ -2462,14 +2425,13 @@ setStaticDoubleField(Thread* t, uintptr_t* arguments)
PROTECT(t, field); PROTECT(t, field);
ACQUIRE_FIELD_FOR_WRITE(t, field); ACQUIRE_FIELD_FOR_WRITE(t, field);
fieldAtOffset<jdouble> fieldAtOffset<jdouble>(c->vmClass()->staticTable(), field->offset()) = v;
(c->vmClass()->staticTable(), field->offset()) = v;
return 1; return 1;
} }
void JNICALL void JNICALL
SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v) SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v)
{ {
uintptr_t arguments[2 + (sizeof(jdouble) / BytesPerWord)]; uintptr_t arguments[2 + (sizeof(jdouble) / BytesPerWord)];
arguments[0] = reinterpret_cast<uintptr_t>(c); arguments[0] = reinterpret_cast<uintptr_t>(c);
@ -2596,7 +2558,8 @@ GetObjectArrayElement(Thread* t, jobjectArray array, jsize index)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return makeLocalReference(t, objectArrayBody(t, reinterpret_cast<object>(*array), index)); return makeLocalReference(
t, objectArrayBody(t, reinterpret_cast<object>(*array), index));
} }
void JNICALL void JNICALL
@ -2605,7 +2568,10 @@ SetObjectArrayElement(Thread* t, jobjectArray array, jsize index,
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
setField(t, reinterpret_cast<object>(*array), ArrayBody + (index * BytesPerWord), (value ? *value : 0)); setField(t,
reinterpret_cast<object>(*array),
ArrayBody + (index * BytesPerWord),
(value ? *value : 0));
} }
uint64_t uint64_t
@ -3003,8 +2969,7 @@ GetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
if (length) { if (length) {
memcpy(dst, &(*array)->body()[offset], memcpy(dst, &(*array)->body()[offset], length * sizeof(jboolean));
length * sizeof(jboolean));
} }
} }
@ -3092,8 +3057,7 @@ SetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
if (length) { if (length) {
memcpy(&(*array)->body()[offset], src, memcpy(&(*array)->body()[offset], src, length * sizeof(jboolean));
length * sizeof(jboolean));
} }
} }
@ -3291,15 +3255,16 @@ registerNatives(Thread* t, uintptr_t* arguments)
const char* sig = methods[i].signature; const char* sig = methods[i].signature;
if (*sig == '!') ++ sig; if (*sig == '!') ++ sig;
GcMethod* method = findMethodOrNull GcMethod* method
(t, (*c)->vmClass(), methods[i].name, sig); = findMethodOrNull(t, (*c)->vmClass(), methods[i].name, sig);
if (method == 0 or (method->flags() & ACC_NATIVE) == 0) { if (method == 0 or (method->flags() & ACC_NATIVE) == 0) {
// The JNI spec says we must throw a NoSuchMethodError in this // The JNI spec says we must throw a NoSuchMethodError in this
// case, but that would prevent using a code shrinker like // case, but that would prevent using a code shrinker like
// ProGuard effectively. Instead, we just ignore it. // ProGuard effectively. Instead, we just ignore it.
// fprintf(stderr, "not found: %s.%s%s\n", &byteArrayBody(t, className(t, (*c)->vmClass()), 0), methods[i].name, sig); // fprintf(stderr, "not found: %s.%s%s\n", &byteArrayBody(t,
// className(t, (*c)->vmClass()), 0), methods[i].name, sig);
// abort(t); // abort(t);
} else { } else {
registerNative(t, method, methods[i].function); registerNative(t, method, methods[i].function);
@ -3578,9 +3543,11 @@ boot(Thread* t, uintptr_t*)
GcString* host = makeString(t, "0.0.0.0"); GcString* host = makeString(t, "0.0.0.0");
PROTECT(t, host); PROTECT(t, host);
GcMethod* method = resolveMethod GcMethod* method = resolveMethod(t,
(t, roots(t)->bootLoader(), "avian/Traces", "startTraceListener", roots(t)->bootLoader(),
"(Ljava/lang/String;I)V"); "avian/Traces",
"startTraceListener",
"(Ljava/lang/String;I)V");
t->m->processor->invoke(t, method, 0, host, atoi(port)); t->m->processor->invoke(t, method, 0, host, atoi(port));
} }

File diff suppressed because it is too large Load Diff

View File

@ -66,8 +66,7 @@ mangle(int8_t c, char* dst)
} }
} }
unsigned unsigned jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
{ {
unsigned size = 0; unsigned size = 0;
@ -87,9 +86,9 @@ jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
size += 2; size += 2;
GcByteArray* methodSpec = method->spec(); GcByteArray* methodSpec = method->spec();
for (unsigned i = 1; i < methodSpec->length() - 1 for (unsigned i = 1;
and methodSpec->body()[i] != ')'; ++i) i < methodSpec->length() - 1 and methodSpec->body()[i] != ')';
{ ++i) {
size += mangledSize(methodSpec->body()[i]); size += mangledSize(methodSpec->body()[i]);
} }
} }
@ -97,9 +96,12 @@ jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
return size; return size;
} }
void void makeJNIName(Thread* t UNUSED,
makeJNIName(Thread* t UNUSED, const char* prefix, unsigned prefixLength, char* name, const char* prefix,
GcMethod* method, bool decorate) unsigned prefixLength,
char* name,
GcMethod* method,
bool decorate)
{ {
memcpy(name, prefix, prefixLength); memcpy(name, prefix, prefixLength);
name += prefixLength; name += prefixLength;
@ -121,9 +123,9 @@ makeJNIName(Thread* t UNUSED, const char* prefix, unsigned prefixLength, char* n
*(name++) = '_'; *(name++) = '_';
GcByteArray* methodSpec = method->spec(); GcByteArray* methodSpec = method->spec();
for (unsigned i = 1; i < methodSpec->length() - 1 for (unsigned i = 1;
and methodSpec->body()[i] != ')'; ++i) i < methodSpec->length() - 1 and methodSpec->body()[i] != ')';
{ ++i) {
name += mangle(methodSpec->body()[i], name); name += mangle(methodSpec->body()[i], name);
} }
} }
@ -149,9 +151,11 @@ resolveNativeMethod(Thread* t, const char* undecorated, const char* decorated)
return 0; return 0;
} }
void* void* resolveNativeMethod(Thread* t,
resolveNativeMethod(Thread* t, GcMethod* method, const char* prefix, GcMethod* method,
unsigned prefixLength, int footprint UNUSED) const char* prefix,
unsigned prefixLength,
int footprint UNUSED)
{ {
unsigned undecoratedSize = prefixLength + jniNameLength(t, method, false); unsigned undecoratedSize = prefixLength + jniNameLength(t, method, false);
// extra 6 is for code below: // extra 6 is for code below:
@ -205,8 +209,7 @@ resolveNativeMethod(Thread* t, GcMethod* method, const char* prefix,
return 0; return 0;
} }
GcNative* GcNative* resolveNativeMethod(Thread* t, GcMethod* method)
resolveNativeMethod(Thread* t, GcMethod* method)
{ {
void* p = resolveNativeMethod(t, method, "Avian_", 6, 3); void* p = resolveNativeMethod(t, method, "Avian_", 6, 3);
if (p) { if (p) {
@ -225,8 +228,7 @@ resolveNativeMethod(Thread* t, GcMethod* method)
namespace vm { namespace vm {
void void resolveNative(Thread* t, GcMethod* method)
resolveNative(Thread* t, GcMethod* method)
{ {
PROTECT(t, method); PROTECT(t, method);
@ -237,7 +239,9 @@ resolveNative(Thread* t, GcMethod* method)
if (getMethodRuntimeData(t, method)->native() == 0) { if (getMethodRuntimeData(t, method)->native() == 0) {
GcNative* native = resolveNativeMethod(t, method); GcNative* native = resolveNativeMethod(t, method);
if (UNLIKELY(native == 0)) { if (UNLIKELY(native == 0)) {
throwNew(t, GcUnsatisfiedLinkError::Type, "%s.%s%s", throwNew(t,
GcUnsatisfiedLinkError::Type,
"%s.%s%s",
method->class_()->name()->body().begin(), method->class_()->name()->body().begin(),
method->name()->body().begin(), method->name()->body().begin(),
method->spec()->body().begin()); method->spec()->body().begin());
@ -255,8 +259,7 @@ resolveNative(Thread* t, GcMethod* method)
} }
} }
int int findLineNumber(Thread* t UNUSED, GcMethod* method, unsigned ip)
findLineNumber(Thread* t UNUSED, GcMethod* method, unsigned ip)
{ {
if (method->flags() & ACC_NATIVE) { if (method->flags() & ACC_NATIVE) {
return NativeLine; return NativeLine;
@ -276,8 +279,7 @@ findLineNumber(Thread* t UNUSED, GcMethod* method, unsigned ip)
if (ip >= lineNumberIp(ln) if (ip >= lineNumberIp(ln)
and (middle + 1 == lnt->length() and (middle + 1 == lnt->length()
or ip < lineNumberIp(lnt->body()[middle + 1]))) or ip < lineNumberIp(lnt->body()[middle + 1]))) {
{
return lineNumberLine(ln); return lineNumberLine(ln);
} else if (ip < lineNumberIp(ln)) { } else if (ip < lineNumberIp(ln)) {
top = middle; top = middle;

View File

@ -175,23 +175,29 @@ endsWith(const char* suffix, const char* s, unsigned length)
and memcmp(suffix, s + (length - suffixLength), suffixLength) == 0; and memcmp(suffix, s + (length - suffixLength), suffixLength) == 0;
} }
GcVector* GcVector* getNonStaticFields(Thread* t,
getNonStaticFields(Thread* t, GcHashMap* typeMaps, GcClass* c, GcVector* fields, GcHashMap* typeMaps,
unsigned* count, GcByteArray** array) GcClass* c,
GcVector* fields,
unsigned* count,
GcByteArray** array)
{ {
PROTECT(t, typeMaps); PROTECT(t, typeMaps);
PROTECT(t, c); PROTECT(t, c);
PROTECT(t, fields); PROTECT(t, fields);
*array = cast<GcByteArray>(t, hashMapFind(t, typeMaps, reinterpret_cast<object>(c), objectHash, objectEqual)); *array = cast<GcByteArray>(
t,
hashMapFind(
t, typeMaps, reinterpret_cast<object>(c), objectHash, objectEqual));
if (*array) { if (*array) {
*count += reinterpret_cast<TypeMap*>((*array)->body().begin()) *count += reinterpret_cast<TypeMap*>((*array)->body().begin())
->fixedFieldCount; ->fixedFieldCount;
} else { } else {
if (c->super()) { if (c->super()) {
fields = getNonStaticFields fields
(t, typeMaps, c->super(), fields, count, array); = getNonStaticFields(t, typeMaps, c->super(), fields, count, array);
} }
if (GcArray* ftable = cast<GcArray>(t, c->fieldTable())) { if (GcArray* ftable = cast<GcArray>(t, c->fieldTable())) {
@ -210,8 +216,11 @@ getNonStaticFields(Thread* t, GcHashMap* typeMaps, GcClass* c, GcVector* fields,
return vectorAppend(t, fields, 0); return vectorAppend(t, fields, 0);
} }
GcVector* GcVector* allFields(Thread* t,
allFields(Thread* t, GcHashMap* typeMaps, GcClass* c, unsigned* count, GcByteArray** array) GcHashMap* typeMaps,
GcClass* c,
unsigned* count,
GcByteArray** array)
{ {
PROTECT(t, typeMaps); PROTECT(t, typeMaps);
PROTECT(t, c); PROTECT(t, c);
@ -219,18 +228,21 @@ allFields(Thread* t, GcHashMap* typeMaps, GcClass* c, unsigned* count, GcByteArr
GcVector* fields = makeVector(t, 0, 0); GcVector* fields = makeVector(t, 0, 0);
PROTECT(t, fields); PROTECT(t, fields);
*array = cast<GcByteArray>(t, hashMapFind(t, typeMaps, reinterpret_cast<object>(c), objectHash, objectEqual)); *array = cast<GcByteArray>(
t,
hashMapFind(
t, typeMaps, reinterpret_cast<object>(c), objectHash, objectEqual));
bool includeMembers; bool includeMembers;
if (*array) { if (*array) {
includeMembers = false; includeMembers = false;
*count += reinterpret_cast<TypeMap*>((*array)->body().begin()) *count += reinterpret_cast<TypeMap*>((*array)->body().begin())
->fixedFieldCount; ->fixedFieldCount;
} else { } else {
includeMembers = true; includeMembers = true;
if (c->super()) { if (c->super()) {
fields = getNonStaticFields fields
(t, typeMaps, c->super(), fields, count, array); = getNonStaticFields(t, typeMaps, c->super(), fields, count, array);
} }
} }
@ -249,41 +261,54 @@ allFields(Thread* t, GcHashMap* typeMaps, GcClass* c, unsigned* count, GcByteArr
return fields; return fields;
} }
TypeMap* TypeMap* classTypeMap(Thread* t, GcHashMap* typeMaps, object p)
classTypeMap(Thread* t, GcHashMap* typeMaps, object p)
{ {
return reinterpret_cast<TypeMap*> return reinterpret_cast<TypeMap*>(
(cast<GcByteArray> cast<GcByteArray>(t, hashMapFind(t, typeMaps, p, objectHash, objectEqual))
(t, hashMapFind(t, typeMaps, p, objectHash, objectEqual))->body().begin()); ->body()
.begin());
} }
TypeMap* TypeMap* typeMap(Thread* t, GcHashMap* typeMaps, object p)
typeMap(Thread* t, GcHashMap* typeMaps, object p)
{ {
return reinterpret_cast<TypeMap*> return reinterpret_cast<TypeMap*>(
(cast<GcByteArray> cast<GcByteArray>(
(t, objectClass(t, p) == type(t, GcSingleton::Type) t,
? hashMapFind(t, typeMaps, p, objectHash, objectEqual) objectClass(t, p) == type(t, GcSingleton::Type)
: hashMapFind(t, typeMaps, reinterpret_cast<object>(objectClass(t, p)), objectHash, objectEqual))->body().begin()); ? hashMapFind(t, typeMaps, p, objectHash, objectEqual)
: hashMapFind(t,
typeMaps,
reinterpret_cast<object>(objectClass(t, p)),
objectHash,
objectEqual))
->body()
.begin());
} }
unsigned unsigned targetFieldOffset(Thread* t, GcHashMap* typeMaps, GcField* field)
targetFieldOffset(Thread* t, GcHashMap* typeMaps, GcField* field)
{ {
// if (strcmp(reinterpret_cast<const char*> // if (strcmp(reinterpret_cast<const char*>
// (&byteArrayBody(t, className(t, field->class_()), 0)), // (&byteArrayBody(t, className(t, field->class_()), 0)),
// "java/lang/Throwable") == 0) trap(); // "java/lang/Throwable") == 0) trap();
return ((field->flags() & ACC_STATIC) return ((field->flags() & ACC_STATIC)
? typeMap(t, typeMaps, reinterpret_cast<object>(field->class_()->staticTable())) ? typeMap(
: classTypeMap(t, typeMaps, reinterpret_cast<object>(field->class_()))) t,
->targetFixedOffsets()[field->offset()]; typeMaps,
reinterpret_cast<object>(field->class_()->staticTable()))
: classTypeMap(
t, typeMaps, reinterpret_cast<object>(field->class_())))
->targetFixedOffsets()[field->offset()];
} }
GcTriple* GcTriple* makeCodeImage(Thread* t,
makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, Zone* zone,
const char* className, const char* methodName, BootImage* image,
const char* methodSpec, GcHashMap* typeMaps) uint8_t* code,
const char* className,
const char* methodName,
const char* methodSpec,
GcHashMap* typeMaps)
{ {
PROTECT(t, typeMaps); PROTECT(t, typeMaps);
@ -302,17 +327,20 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
class MyOffsetResolver: public OffsetResolver { class MyOffsetResolver: public OffsetResolver {
public: public:
MyOffsetResolver(GcHashMap** typeMaps): typeMaps(typeMaps) { } MyOffsetResolver(GcHashMap** typeMaps) : typeMaps(typeMaps)
{
}
virtual unsigned fieldOffset(Thread* t, GcField* field) { virtual unsigned fieldOffset(Thread* t, GcField* field)
{
return targetFieldOffset(t, *typeMaps, field); return targetFieldOffset(t, *typeMaps, field);
} }
GcHashMap** typeMaps; GcHashMap** typeMaps;
} resolver(&typeMaps); } resolver(&typeMaps);
Finder* finder = static_cast<Finder*> Finder* finder = static_cast<Finder*>(
(roots(t)->bootLoader()->as<GcSystemClassLoader>(t)->finder()); roots(t)->bootLoader()->as<GcSystemClassLoader>(t)->finder());
for (Finder::Iterator it(finder); it.hasMore();) { for (Finder::Iterator it(finder); it.hasMore();) {
unsigned nameSize = 0; unsigned nameSize = 0;
@ -322,9 +350,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
and (className == 0 or strncmp(name, className, nameSize - 6) == 0)) and (className == 0 or strncmp(name, className, nameSize - 6) == 0))
{ {
// fprintf(stderr, "pass 1 %.*s\n", nameSize - 6, name); // fprintf(stderr, "pass 1 %.*s\n", nameSize - 6, name);
GcClass* c = resolveSystemClass GcClass* c
(t, roots(t)->bootLoader(), = resolveSystemClass(t,
makeByteArray(t, "%.*s", nameSize - 6, name), true); roots(t)->bootLoader(),
makeByteArray(t, "%.*s", nameSize - 6, name),
true);
PROTECT(t, c); PROTECT(t, c);
@ -400,11 +430,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
} }
} }
GcByteArray* array = makeByteArray GcByteArray* array
(t, TypeMap::sizeInBytes(count + 2, count + 2)); = makeByteArray(t, TypeMap::sizeInBytes(count + 2, count + 2));
TypeMap* map = new (array->body().begin()) TypeMap TypeMap* map = new (array->body().begin())
(count + 2, count + 2, count + 2, TypeMap::PoolKind); TypeMap(count + 2, count + 2, count + 2, TypeMap::PoolKind);
for (unsigned i = 0; i < count + 2; ++i) { for (unsigned i = 0; i < count + 2; ++i) {
expect(t, i < map->buildFixedSizeInWords); expect(t, i < map->buildFixedSizeInWords);
@ -417,14 +447,21 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
TargetBytesPerWord); TargetBytesPerWord);
} }
hashMapInsert hashMapInsert(
(t, typeMaps, reinterpret_cast<object>(hashMapFind t,
(t, roots(t)->poolMap(), reinterpret_cast<object>(c), objectHash, objectEqual)), reinterpret_cast<object>(array), typeMaps,
objectHash); reinterpret_cast<object>(hashMapFind(t,
roots(t)->poolMap(),
reinterpret_cast<object>(c),
objectHash,
objectEqual)),
reinterpret_cast<object>(array),
objectHash);
} }
} }
{ GcByteArray* array = 0; {
GcByteArray* array = 0;
PROTECT(t, array); PROTECT(t, array);
unsigned count = 0; unsigned count = 0;
@ -442,8 +479,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildMemberOffset = 0; buildMemberOffset = 0;
targetMemberOffset = 0; targetMemberOffset = 0;
TypeMap* map = reinterpret_cast<TypeMap*> TypeMap* map = reinterpret_cast<TypeMap*>(array->body().begin());
(array->body().begin());
for (unsigned j = 0; j < map->fixedFieldCount; ++j) { for (unsigned j = 0; j < map->fixedFieldCount; ++j) {
Field* f = map->fixedFields() + j; Field* f = map->fixedFields() + j;
@ -548,14 +584,20 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
} }
} }
if (hashMapFind(t, typeMaps, reinterpret_cast<object>(c), objectHash, objectEqual) == 0) { if (hashMapFind(t,
GcByteArray* array = makeByteArray typeMaps,
(t, TypeMap::sizeInBytes reinterpret_cast<object>(c),
(ceilingDivide(c->fixedSize(), BytesPerWord), memberIndex)); objectHash,
objectEqual) == 0) {
GcByteArray* array = makeByteArray(
t,
TypeMap::sizeInBytes(ceilingDivide(c->fixedSize(), BytesPerWord),
memberIndex));
TypeMap* map = new (array->body().begin()) TypeMap TypeMap* map = new (array->body().begin())
(ceilingDivide(c->fixedSize(), BytesPerWord), TypeMap(ceilingDivide(c->fixedSize(), BytesPerWord),
ceilingDivide(targetMemberOffset, TargetBytesPerWord), memberIndex); ceilingDivide(targetMemberOffset, TargetBytesPerWord),
memberIndex);
for (unsigned i = 0; i < memberIndex; ++i) { for (unsigned i = 0; i < memberIndex; ++i) {
Field* f = RUNTIME_ARRAY_BODY(memberFields) + i; Field* f = RUNTIME_ARRAY_BODY(memberFields) + i;
@ -568,18 +610,24 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
map->fixedFields()[i] = *f; map->fixedFields()[i] = *f;
} }
hashMapInsert(t, typeMaps, reinterpret_cast<object>(c), reinterpret_cast<object>(array), objectHash); hashMapInsert(t,
typeMaps,
reinterpret_cast<object>(c),
reinterpret_cast<object>(array),
objectHash);
} }
if (c->staticTable()) { if (c->staticTable()) {
GcByteArray* array = makeByteArray GcByteArray* array = makeByteArray(
(t, TypeMap::sizeInBytes t,
(singletonCount(t, c->staticTable()) + 2, staticIndex)); TypeMap::sizeInBytes(singletonCount(t, c->staticTable()) + 2,
staticIndex));
TypeMap* map = new (array->body().begin()) TypeMap TypeMap* map = new (array->body().begin())
(singletonCount(t, c->staticTable()) + 2, TypeMap(singletonCount(t, c->staticTable()) + 2,
ceilingDivide(targetStaticOffset, TargetBytesPerWord), staticIndex, ceilingDivide(targetStaticOffset, TargetBytesPerWord),
TypeMap::SingletonKind); staticIndex,
TypeMap::SingletonKind);
for (unsigned i = 0; i < staticIndex; ++i) { for (unsigned i = 0; i < staticIndex; ++i) {
Field* f = RUNTIME_ARRAY_BODY(staticFields) + i; Field* f = RUNTIME_ARRAY_BODY(staticFields) + i;
@ -592,8 +640,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
map->fixedFields()[i] = *f; map->fixedFields()[i] = *f;
} }
hashMapInsert hashMapInsert(t,
(t, typeMaps, reinterpret_cast<object>(c->staticTable()), reinterpret_cast<object>(array), objectHash); typeMaps,
reinterpret_cast<object>(c->staticTable()),
reinterpret_cast<object>(array),
objectHash);
} }
} }
} }
@ -610,56 +661,64 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
GcClass* c = 0; GcClass* c = 0;
PROTECT(t, c); PROTECT(t, c);
c = resolveSystemClass c = resolveSystemClass(t,
(t, roots(t)->bootLoader(), roots(t)->bootLoader(),
makeByteArray(t, "%.*s", nameSize - 6, name), true); makeByteArray(t, "%.*s", nameSize - 6, name),
true);
if (GcArray* mtable = cast<GcArray>(t, c->methodTable())) { if (GcArray* mtable = cast<GcArray>(t, c->methodTable())) {
PROTECT(t, mtable); PROTECT(t, mtable);
for (unsigned i = 0; i < mtable->length(); ++i) { for (unsigned i = 0; i < mtable->length(); ++i) {
GcMethod* method = cast<GcMethod>(t, mtable->body()[i]); GcMethod* method = cast<GcMethod>(t, mtable->body()[i]);
if (((methodName == 0 if (((methodName == 0
or ::strcmp or ::strcmp(
(reinterpret_cast<char*> reinterpret_cast<char*>(method->name()->body().begin()),
(method->name()->body().begin()), methodName) == 0) methodName) == 0)
and (methodSpec == 0 and (methodSpec == 0
or ::strcmp or ::strcmp(reinterpret_cast<char*>(
(reinterpret_cast<char*> method->spec()->body().begin()),
(method->spec()->body().begin()), methodSpec) methodSpec) == 0))) {
== 0))) if (method->code() or (method->flags() & ACC_NATIVE)) {
{
if (method->code()
or (method->flags() & ACC_NATIVE))
{
PROTECT(t, method); PROTECT(t, method);
t->m->processor->compileMethod t->m->processor->compileMethod(
(t, zone, reinterpret_cast<GcTriple**>(&constants), reinterpret_cast<GcTriple**>(&calls), &addresses, method, &resolver); t,
zone,
reinterpret_cast<GcTriple**>(&constants),
reinterpret_cast<GcTriple**>(&calls),
&addresses,
method,
&resolver);
if (method->code()) { if (method->code()) {
methods = makePair(t, reinterpret_cast<object>(method), reinterpret_cast<object>(methods)); methods = makePair(t,
reinterpret_cast<object>(method),
reinterpret_cast<object>(methods));
} }
} }
GcMethodAddendum* addendum = method->addendum(); GcMethodAddendum* addendum = method->addendum();
if (addendum and addendum->exceptionTable()) { if (addendum and addendum->exceptionTable()) {
PROTECT(t, addendum); PROTECT(t, addendum);
GcShortArray* exceptionTable = cast<GcShortArray>(t, addendum->exceptionTable()); GcShortArray* exceptionTable
= cast<GcShortArray>(t, addendum->exceptionTable());
PROTECT(t, exceptionTable); PROTECT(t, exceptionTable);
// resolve exception types now to avoid trying to update // resolve exception types now to avoid trying to update
// immutable references at runtime // immutable references at runtime
for (unsigned i = 0; i < exceptionTable->length(); ++i) for (unsigned i = 0; i < exceptionTable->length(); ++i) {
{
uint16_t index = exceptionTable->body()[i] - 1; uint16_t index = exceptionTable->body()[i] - 1;
object o = singletonObject(t, addendum->pool(), index); object o = singletonObject(t, addendum->pool(), index);
if (objectClass(t, o) == type(t, GcReference::Type)) { if (objectClass(t, o) == type(t, GcReference::Type)) {
o = reinterpret_cast<object>(resolveClass o = reinterpret_cast<object>(
(t, roots(t)->bootLoader(), cast<GcReference>(t, o)->name())); resolveClass(t,
roots(t)->bootLoader(),
cast<GcReference>(t, o)->name()));
addendum->pool()->setBodyElement(t, index, reinterpret_cast<uintptr_t>(o)); addendum->pool()->setBodyElement(
t, index, reinterpret_cast<uintptr_t>(o));
} }
} }
} }
@ -679,7 +738,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
} }
static_cast<ListenPromise*>(cast<GcPointer>(t, calls->second())->value()) static_cast<ListenPromise*>(cast<GcPointer>(t, calls->second())->value())
->listener->resolve(address, 0); ->listener->resolve(address, 0);
} }
for (; addresses; addresses = addresses->next) { for (; addresses; addresses = addresses->next) {
@ -692,7 +751,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
for (; methods; methods = cast<GcPair>(t, methods->second())) { for (; methods; methods = cast<GcPair>(t, methods->second())) {
cast<GcMethod>(t, methods->first())->code()->compiled() cast<GcMethod>(t, methods->first())->code()->compiled()
-= reinterpret_cast<uintptr_t>(code); -= reinterpret_cast<uintptr_t>(code);
} }
t->m->processor->normalizeVirtualThunks(t); t->m->processor->normalizeVirtualThunks(t);
@ -700,19 +759,19 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
return constants; return constants;
} }
void void visitRoots(Thread* t, BootImage* image, HeapWalker* w, GcTriple* constants)
visitRoots(Thread* t, BootImage* image, HeapWalker* w, GcTriple* constants)
{ {
Machine* m = t->m; Machine* m = t->m;
for (HashMapIterator it(t, cast<GcHashMap>(t, roots(t)->bootLoader()->map())); for (HashMapIterator it(t, cast<GcHashMap>(t, roots(t)->bootLoader()->map()));
it.hasMore();) it.hasMore();) {
{
w->visitRoot(it.next()->second()); w->visitRoot(it.next()->second());
} }
image->bootLoader = w->visitRoot(reinterpret_cast<object>(roots(t)->bootLoader())); image->bootLoader
image->appLoader = w->visitRoot(reinterpret_cast<object>(roots(t)->appLoader())); = w->visitRoot(reinterpret_cast<object>(roots(t)->bootLoader()));
image->appLoader
= w->visitRoot(reinterpret_cast<object>(roots(t)->appLoader()));
image->types = w->visitRoot(reinterpret_cast<object>(m->types)); image->types = w->visitRoot(reinterpret_cast<object>(m->types));
m->processor->visitRoots(t, w); m->processor->visitRoots(t, w);
@ -722,8 +781,7 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, GcTriple* constants)
} }
} }
unsigned unsigned targetOffset(Thread* t, GcHashMap* typeMaps, object p, unsigned offset)
targetOffset(Thread* t, GcHashMap* typeMaps, object p, unsigned offset)
{ {
TypeMap* map = typeMap(t, typeMaps, p); TypeMap* map = typeMap(t, typeMaps, p);
@ -739,8 +797,7 @@ targetOffset(Thread* t, GcHashMap* typeMaps, object p, unsigned offset)
} }
} }
unsigned unsigned targetSize(Thread* t, GcHashMap* typeMaps, object p)
targetSize(Thread* t, GcHashMap* typeMaps, object p)
{ {
TypeMap* map = typeMap(t, typeMaps, p); TypeMap* map = typeMap(t, typeMaps, p);
@ -784,14 +841,14 @@ objectMaskCount(TypeMap* map)
return count; return count;
} }
unsigned unsigned targetSize(Thread* t,
targetSize(Thread* t, GcHashMap* typeMaps, object referer, unsigned refererOffset, GcHashMap* typeMaps,
object p) object referer,
unsigned refererOffset,
object p)
{ {
if (referer if (referer and objectClass(t, referer) == type(t, GcClass::Type)
and objectClass(t, referer) == type(t, GcClass::Type) and (refererOffset * BytesPerWord) == ClassObjectMask) {
and (refererOffset * BytesPerWord) == ClassObjectMask)
{
return (TargetBytesPerWord * 2) return (TargetBytesPerWord * 2)
+ pad + pad
(ceilingDivide (ceilingDivide
@ -911,8 +968,7 @@ nonObjectsEqual(TypeMap* map, uint8_t* src, uint8_t* dst)
return true; return true;
} }
void void copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
{ {
TypeMap* map = typeMap(t, typeMaps, p); TypeMap* map = typeMap(t, typeMaps, p);
@ -937,23 +993,22 @@ copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
if (objectClass(t, p) == type(t, GcClass::Type)) { if (objectClass(t, p) == type(t, GcClass::Type)) {
uint16_t fixedSize; uint16_t fixedSize;
uint8_t arrayElementSize; uint8_t arrayElementSize;
GcByteArray* array = cast<GcByteArray>(t, hashMapFind(t, typeMaps, p, objectHash, objectEqual)); GcByteArray* array = cast<GcByteArray>(
t, hashMapFind(t, typeMaps, p, objectHash, objectEqual));
PROTECT(t, array); PROTECT(t, array);
GcClass* c = cast<GcClass>(t, p); GcClass* c = cast<GcClass>(t, p);
PROTECT(t, c); PROTECT(t, c);
if (array) { if (array) {
TypeMap* classMap = reinterpret_cast<TypeMap*> TypeMap* classMap = reinterpret_cast<TypeMap*>(array->body().begin());
(array->body().begin());
fixedSize = targetV2 fixedSize = targetV2
(classMap->targetFixedSizeInWords * TargetBytesPerWord); (classMap->targetFixedSizeInWords * TargetBytesPerWord);
arrayElementSize = classMap->targetArrayElementSizeInBytes; arrayElementSize = classMap->targetArrayElementSizeInBytes;
} else if (c->fixedSize() == BytesPerWord * 2 } else if (c->fixedSize() == BytesPerWord * 2
and c->arrayElementSize() == BytesPerWord) and c->arrayElementSize() == BytesPerWord) {
{
fixedSize = targetV2(TargetBytesPerWord * 2); fixedSize = targetV2(TargetBytesPerWord * 2);
arrayElementSize = TargetBytesPerWord; arrayElementSize = TargetBytesPerWord;
@ -975,7 +1030,8 @@ copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
switch (map->kind) { switch (map->kind) {
case TypeMap::NormalKind: case TypeMap::NormalKind:
if (objectClass(t, p) == type(t, GcField::Type)) { if (objectClass(t, p) == type(t, GcField::Type)) {
uint16_t offset = targetV2(targetFieldOffset(t, typeMaps, cast<GcField>(t, p))); uint16_t offset
= targetV2(targetFieldOffset(t, typeMaps, cast<GcField>(t, p)));
memcpy(dst + TargetFieldOffset, &offset, 2); memcpy(dst + TargetFieldOffset, &offset, 2);
} }
break; break;
@ -1068,14 +1124,15 @@ copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
} }
} }
void void copy(Thread* t,
copy(Thread* t, GcHashMap* typeMaps, object referer, unsigned refererOffset, GcHashMap* typeMaps,
object p, uint8_t* dst) object referer,
unsigned refererOffset,
object p,
uint8_t* dst)
{ {
if (referer if (referer and objectClass(t, referer) == type(t, GcClass::Type)
and objectClass(t, referer) == type(t, GcClass::Type) and (refererOffset * BytesPerWord) == ClassObjectMask) {
and (refererOffset * BytesPerWord) == ClassObjectMask)
{
TypeMap* map = classTypeMap(t, typeMaps, referer); TypeMap* map = classTypeMap(t, typeMaps, referer);
memset(dst, 0, TargetBytesPerWord); memset(dst, 0, TargetBytesPerWord);
@ -1115,17 +1172,30 @@ copy(Thread* t, GcHashMap* typeMaps, object referer, unsigned refererOffset,
} }
} }
HeapWalker* HeapWalker* makeHeapImage(Thread* t,
makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap, BootImage* image,
target_uintptr_t* map, unsigned capacity, GcTriple* constants, target_uintptr_t* heap,
GcHashMap* typeMaps) target_uintptr_t* map,
unsigned capacity,
GcTriple* constants,
GcHashMap* typeMaps)
{ {
class Visitor: public HeapVisitor { class Visitor: public HeapVisitor {
public: public:
Visitor(Thread* t, GcHashMap* typeMaps, target_uintptr_t* heap, Visitor(Thread* t,
target_uintptr_t* map, unsigned capacity): GcHashMap* typeMaps,
t(t), typeMaps(typeMaps), currentObject(0), currentNumber(0), target_uintptr_t* heap,
currentOffset(0), heap(heap), map(map), position(0), capacity(capacity) target_uintptr_t* map,
unsigned capacity)
: t(t),
typeMaps(typeMaps),
currentObject(0),
currentNumber(0),
currentOffset(0),
heap(heap),
map(map),
position(0),
capacity(capacity)
{ } { }
void visit(unsigned number) { void visit(unsigned number) {
@ -1164,8 +1234,7 @@ makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap,
if ((currentObject if ((currentObject
and objectClass(t, currentObject) == type(t, GcClass::Type) and objectClass(t, currentObject) == type(t, GcClass::Type)
and (currentOffset * BytesPerWord) == ClassStaticTable) and (currentOffset * BytesPerWord) == ClassStaticTable)
or instanceOf(t, type(t, GcSystemClassLoader::Type), p)) or instanceOf(t, type(t, GcSystemClassLoader::Type), p)) {
{
// Static tables and system classloaders must be allocated // Static tables and system classloaders must be allocated
// as fixed objects in the heap image so that they can be // as fixed objects in the heap image so that they can be
// marked as dirty and visited during GC. Otherwise, // marked as dirty and visited during GC. Otherwise,
@ -1256,17 +1325,17 @@ makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap,
return w; return w;
} }
void void updateConstants(Thread* t, GcTriple* constants, HeapMap* heapTable)
updateConstants(Thread* t, GcTriple* constants, HeapMap* heapTable)
{ {
for (; constants; constants = cast<GcTriple>(t, constants->third())) { for (; constants; constants = cast<GcTriple>(t, constants->third())) {
unsigned target = heapTable->find(constants->first()); unsigned target = heapTable->find(constants->first());
expect(t, target > 0); expect(t, target > 0);
for (Promise::Listener* pl = static_cast<ListenPromise*> for (Promise::Listener* pl
(cast<GcPointer>(t, constants->second())->value())->listener; = static_cast<ListenPromise*>(
pl; pl = pl->next) cast<GcPointer>(t, constants->second())->value())->listener;
{ pl;
pl = pl->next) {
pl->resolve((target - 1) * TargetBytesPerWord, 0); pl->resolve((target - 1) * TargetBytesPerWord, 0);
} }
} }
@ -1287,7 +1356,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
const char* codeimageStart, const char* codeimageEnd, const char* codeimageStart, const char* codeimageEnd,
bool useLZMA) bool useLZMA)
{ {
GcThrowable* throwable = cast<GcThrowable>(t, make(t, type(t, GcOutOfMemoryError::Type))); GcThrowable* throwable
= cast<GcThrowable>(t, make(t, type(t, GcOutOfMemoryError::Type)));
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
roots(t)->setOutOfMemoryError(t, throwable); roots(t)->setOutOfMemoryError(t, throwable);
@ -1460,15 +1530,19 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
targetArrayElementSize = 0; targetArrayElementSize = 0;
} }
GcByteArray* array = makeByteArray GcByteArray* array = makeByteArray(
(t, TypeMap::sizeInBytes t,
(ceilingDivide(buildOffset, BytesPerWord), fixedFieldCount)); TypeMap::sizeInBytes(ceilingDivide(buildOffset, BytesPerWord),
fixedFieldCount));
TypeMap* map = new (array->body().begin()) TypeMap TypeMap* map = new (array->body().begin())
(ceilingDivide(buildOffset, BytesPerWord), TypeMap(ceilingDivide(buildOffset, BytesPerWord),
ceilingDivide(targetOffset, TargetBytesPerWord), ceilingDivide(targetOffset, TargetBytesPerWord),
fixedFieldCount, TypeMap::NormalKind, buildArrayElementSize, fixedFieldCount,
targetArrayElementSize, arrayElementType); TypeMap::NormalKind,
buildArrayElementSize,
targetArrayElementSize,
arrayElementType);
for (unsigned j = 0; j < fixedFieldCount; ++j) { for (unsigned j = 0; j < fixedFieldCount; ++j) {
Field* f = RUNTIME_ARRAY_BODY(fields) + j; Field* f = RUNTIME_ARRAY_BODY(fields) + j;
@ -1481,9 +1555,12 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
map->fixedFields()[j] = *f; map->fixedFields()[j] = *f;
} }
hashMapInsert hashMapInsert(
(t, typeMaps, reinterpret_cast<object>(vm::type(t, static_cast<Gc::Type>(i))), reinterpret_cast<object>(array), t,
objectHash); typeMaps,
reinterpret_cast<object>(vm::type(t, static_cast<Gc::Type>(i))),
reinterpret_cast<object>(array),
objectHash);
} }
constants = makeCodeImage constants = makeCodeImage
@ -1501,46 +1578,48 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
// name all primitive classes so we don't try to update immutable // name all primitive classes so we don't try to update immutable
// references at runtime: // references at runtime:
{ GcByteArray* name = makeByteArray(t, "void"); {
// sequence point, for gc (don't recombine statements) GcByteArray* name = makeByteArray(t, "void");
// sequence point, for gc (don't recombine statements)
type(t, GcJvoid::Type)->setName(t, name); type(t, GcJvoid::Type)->setName(t, name);
name = makeByteArray(t, "boolean"); name = makeByteArray(t, "boolean");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJboolean::Type)->setName(t, name); type(t, GcJboolean::Type)->setName(t, name);
name = makeByteArray(t, "byte"); name = makeByteArray(t, "byte");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJbyte::Type)->setName(t, name); type(t, GcJbyte::Type)->setName(t, name);
name = makeByteArray(t, "short"); name = makeByteArray(t, "short");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJshort::Type)->setName(t, name); type(t, GcJshort::Type)->setName(t, name);
name = makeByteArray(t, "char"); name = makeByteArray(t, "char");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJchar::Type)->setName(t, name); type(t, GcJchar::Type)->setName(t, name);
name = makeByteArray(t, "int"); name = makeByteArray(t, "int");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJint::Type)->setName(t, name); type(t, GcJint::Type)->setName(t, name);
name = makeByteArray(t, "float"); name = makeByteArray(t, "float");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJfloat::Type)->setName(t, name); type(t, GcJfloat::Type)->setName(t, name);
name = makeByteArray(t, "long"); name = makeByteArray(t, "long");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJlong::Type)->setName(t, name); type(t, GcJlong::Type)->setName(t, name);
name = makeByteArray(t, "double"); name = makeByteArray(t, "double");
// sequence point, for gc (don't recombine statements) // sequence point, for gc (don't recombine statements)
type(t, GcJdouble::Type)->setName(t, name); type(t, GcJdouble::Type)->setName(t, name);
} }
// resolve primitive array classes in case they are needed at // resolve primitive array classes in case they are needed at
// runtime: // runtime:
{ GcByteArray* name = makeByteArray(t, "[B"); {
GcByteArray* name = makeByteArray(t, "[B");
resolveSystemClass(t, roots(t)->bootLoader(), name, true); resolveSystemClass(t, roots(t)->bootLoader(), name, true);
name = makeByteArray(t, "[Z"); name = makeByteArray(t, "[Z");
@ -1578,35 +1657,33 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
updateConstants(t, constants, heapWalker->map()); updateConstants(t, constants, heapWalker->map());
image->bootClassCount = cast<GcHashMap> image->bootClassCount
(t, roots(t)->bootLoader()->map())->size(); = cast<GcHashMap>(t, roots(t)->bootLoader()->map())->size();
unsigned* bootClassTable = static_cast<unsigned*> unsigned* bootClassTable = static_cast<unsigned*>
(t->m->heap->allocate(image->bootClassCount * sizeof(unsigned))); (t->m->heap->allocate(image->bootClassCount * sizeof(unsigned)));
{ unsigned i = 0; { unsigned i = 0;
for (HashMapIterator it for (HashMapIterator it(t,
(t, cast<GcHashMap>(t, roots(t)->bootLoader()->map())); cast<GcHashMap>(t, roots(t)->bootLoader()->map()));
it.hasMore();) it.hasMore();) {
{ bootClassTable[i++]
bootClassTable[i++] = targetVW = targetVW(heapWalker->map()->find(it.next()->second()));
(heapWalker->map()->find(it.next()->second()));
} }
} }
image->appClassCount = cast<GcHashMap> image->appClassCount
(t, roots(t)->appLoader()->map())->size(); = cast<GcHashMap>(t, roots(t)->appLoader()->map())->size();
unsigned* appClassTable = static_cast<unsigned*> unsigned* appClassTable = static_cast<unsigned*>
(t->m->heap->allocate(image->appClassCount * sizeof(unsigned))); (t->m->heap->allocate(image->appClassCount * sizeof(unsigned)));
{ unsigned i = 0; { unsigned i = 0;
for (HashMapIterator it for (
(t, cast<GcHashMap>(t, roots(t)->appLoader()->map())); HashMapIterator it(t, cast<GcHashMap>(t, roots(t)->appLoader()->map()));
it.hasMore();) it.hasMore();) {
{ appClassTable[i++]
appClassTable[i++] = targetVW = targetVW(heapWalker->map()->find(it.next()->second()));
(heapWalker->map()->find(it.next()->second()));
} }
} }
@ -1616,9 +1693,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
{ unsigned i = 0; { unsigned i = 0;
for (HashMapIterator it(t, roots(t)->stringMap()); it.hasMore();) { for (HashMapIterator it(t, roots(t)->stringMap()); it.hasMore();) {
stringTable[i++] = targetVW stringTable[i++]
(heapWalker->map()->find = targetVW(heapWalker->map()->find(reinterpret_cast<object>(
(reinterpret_cast<object>(cast<GcJreference>(t, it.next()->first())->target()))); cast<GcJreference>(t, it.next()->first())->target())));
} }
} }

View File

@ -135,7 +135,8 @@ class FileOutput : public Output {
} }
} }
virtual void write(const std::string& s) { virtual void write(const std::string& s)
{
fputs(s.c_str(), stream); fputs(s.c_str(), stream);
} }

View File

@ -77,16 +77,18 @@ class Field {
{ {
} }
std::string dump() const { std::string dump() const
{
std::ostringstream ss; std::ostringstream ss;
ss << "field " << name << ":" << typeName << ":" << javaSpec << ", size=" << elementSize << ", offset=" << offset; ss << "field " << name << ":" << typeName << ":" << javaSpec
if(noassert) { << ", size=" << elementSize << ", offset=" << offset;
if (noassert) {
ss << " noassert"; ss << " noassert";
} }
if(nogc) { if (nogc) {
ss << " nogc"; ss << " nogc";
} }
if(polyfill) { if (polyfill) {
ss << " polyfill"; ss << " polyfill";
} }
return ss.str(); return ss.str();
@ -103,14 +105,18 @@ class Method {
{ {
} }
bool operator == (const Method& o) const { bool operator==(const Method& o) const
{
return javaName == o.javaName && javaSpec == o.javaSpec; return javaName == o.javaName && javaSpec == o.javaSpec;
} }
bool operator < (const Method& o) const { bool operator<(const Method& o) const
return javaName < o.javaName || (javaName == o.javaName && javaSpec < o.javaSpec); {
return javaName < o.javaName
|| (javaName == o.javaName && javaSpec < o.javaSpec);
} }
std::string dump() const { std::string dump() const
{
return "method " + javaName + javaSpec; return "method " + javaName + javaSpec;
} }
}; };
@ -134,33 +140,44 @@ class Class {
int fixedSize; int fixedSize;
Class(const std::string& name) : name(name), super(0), arrayField(0), overridesMethods(false), fixedSize(-1) Class(const std::string& name)
: name(name),
super(0),
arrayField(0),
overridesMethods(false),
fixedSize(-1)
{ {
} }
std::string dump() const { std::string dump() const
{
std::ostringstream ss; std::ostringstream ss;
ss << "class " << name; ss << "class " << name;
if(javaName.size() > 0) { if (javaName.size() > 0) {
ss << "(" << javaName << ")"; ss << "(" << javaName << ")";
} }
if(super) { if (super) {
ss << " : " << super->name << "(" << super->javaName << ")"; ss << " : " << super->name << "(" << super->javaName << ")";
} }
ss << " {\n"; ss << " {\n";
for(std::vector<Field*>::const_iterator it = fields.begin(); it != fields.end(); it++) { for (std::vector<Field*>::const_iterator it = fields.begin();
it != fields.end();
it++) {
ss << " " << (*it)->dump() << "\n"; ss << " " << (*it)->dump() << "\n";
} }
for(std::set<Method>::const_iterator it = methods.begin(); it != methods.end(); ++it) { for (std::set<Method>::const_iterator it = methods.begin();
it != methods.end();
++it) {
ss << " " << it->dump() << "\n"; ss << " " << it->dump() << "\n";
} }
ss << "}"; ss << "}";
return ss.str(); return ss.str();
} }
void dumpToStdout() const AVIAN_EXPORT { void dumpToStdout() const AVIAN_EXPORT
{
printf("%s\n", dump().c_str()); printf("%s\n", dump().c_str());
} }
}; };
@ -172,10 +189,11 @@ class Module {
std::map<std::string, Class*> classes; std::map<std::string, Class*> classes;
void add(Class* cl) { void add(Class* cl)
{
assert(classes.find(cl->name) == classes.end()); assert(classes.find(cl->name) == classes.end());
classes[cl->name] = cl; classes[cl->name] = cl;
if(cl->javaName != "") { if (cl->javaName != "") {
assert(javaClasses.find(cl->javaName) == javaClasses.end()); assert(javaClasses.find(cl->javaName) == javaClasses.end());
javaClasses[cl->javaName] = cl; javaClasses[cl->javaName] = cl;
} }
@ -191,19 +209,17 @@ namespace {
namespace local { namespace local {
#ifndef POINTER_SIZE #ifndef POINTER_SIZE
# define POINTER_SIZE sizeof(void*) #define POINTER_SIZE sizeof(void*)
#endif #endif
const unsigned BytesPerWord = POINTER_SIZE; const unsigned BytesPerWord = POINTER_SIZE;
inline bool inline bool equal(const char* a, const char* b)
equal(const char* a, const char* b)
{ {
return strcmp(a, b) == 0; return strcmp(a, b) == 0;
} }
inline bool inline bool endsWith(const std::string& b, const std::string& a)
endsWith(const std::string& b, const std::string& a)
{ {
if (b.size() > a.size()) { if (b.size() > a.size()) {
return false; return false;
@ -211,18 +227,20 @@ endsWith(const std::string& b, const std::string& a)
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
} }
std::string enumName(Module& module, Field& f) { std::string enumName(Module& module, Field& f)
{
std::string& type = f.typeName; std::string& type = f.typeName;
if (type == "void*") { if (type == "void*") {
return "word"; return "word";
} else if(type == "maybe_object") { } else if (type == "maybe_object") {
return "uintptr_t"; return "uintptr_t";
} else if(f.javaSpec.size() != 0 && (f.javaSpec[0] == 'L' || f.javaSpec[0] == '[')) { } else if (f.javaSpec.size() != 0
&& (f.javaSpec[0] == 'L' || f.javaSpec[0] == '[')) {
return "object"; return "object";
} }
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName); std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
assert(f.typeName.size() > 0); assert(f.typeName.size() > 0);
if(it != module.classes.end()) { if (it != module.classes.end()) {
return "object"; return "object";
} else { } else {
return f.typeName; return f.typeName;
@ -288,10 +306,9 @@ class Singleton : public Object {
} }
}; };
std::string std::string capitalize(const std::string& s)
capitalize(const std::string& s)
{ {
if(s[0] >= 'a' && s[0] <= 'z') { if (s[0] >= 'a' && s[0] <= 'z') {
return (char)(s[0] + 'A' - 'a') + s.substr(1, s.size() - 1); return (char)(s[0] + 'A' - 'a') + s.substr(1, s.size() - 1);
} }
return s; return s;
@ -358,20 +375,15 @@ read(Input* in, Object* eos, int level)
} }
} }
bool bool namesPointer(const std::string& s)
namesPointer(const std::string& s)
{ {
return s == "Collector" return s == "Collector" or s == "Disposer" or endsWith("*", s);
or s == "Disposer"
or endsWith("*", s);
} }
unsigned unsigned sizeOf(Module& module, const std::string& type)
sizeOf(Module& module, const std::string& type)
{ {
if (type == "object" if (type == "object" or type == "intptr_t" or type == "uintptr_t"
or type == "intptr_t" or type == "uintptr_t" or type == "maybe_object") or type == "maybe_object") {
{
return BytesPerWord; return BytesPerWord;
} else if (type == "unsigned" or type == "int") { } else if (type == "unsigned" or type == "int") {
return sizeof(int); return sizeof(int);
@ -393,7 +405,7 @@ sizeOf(Module& module, const std::string& type)
return BytesPerWord; return BytesPerWord;
} else { } else {
std::map<std::string, Class*>::iterator it = module.classes.find(type); std::map<std::string, Class*>::iterator it = module.classes.find(type);
if(it != module.classes.end()) { if (it != module.classes.end()) {
return BytesPerWord; return BytesPerWord;
} else { } else {
fprintf(stderr, "unexpected type: %s\n", type.c_str()); fprintf(stderr, "unexpected type: %s\n", type.c_str());
@ -408,9 +420,14 @@ struct FieldSpec {
bool require; bool require;
Field* field; Field* field;
FieldSpec(){} FieldSpec()
{
}
FieldSpec(bool isArray, Field* field) :isArray(isArray), require(false), field(field) {} FieldSpec(bool isArray, Field* field)
: isArray(isArray), require(false), field(field)
{
}
}; };
class ClassParser { class ClassParser {
@ -422,9 +439,10 @@ class ClassParser {
{ {
} }
void add(FieldSpec f) { void add(FieldSpec f)
if(f.field->polyfill) { {
if(fields.find(f.field->name) == fields.end()) { if (f.field->polyfill) {
if (fields.find(f.field->name) == fields.end()) {
fields[f.field->name] = f.field; fields[f.field->name] = f.field;
cl->fields.push_back(f.field); cl->fields.push_back(f.field);
} else { } else {
@ -432,11 +450,13 @@ class ClassParser {
} }
return; return;
} }
if(f.aliasName.size() > 0) { if (f.aliasName.size() > 0) {
if(fields.find(f.aliasName) == fields.end()) { if (fields.find(f.aliasName) == fields.end()) {
if(fields.find(f.field->name) != fields.end()) { if (fields.find(f.field->name) != fields.end()) {
// printf("alias %s.%s -> %s.%s\n", cl->name.c_str(), f.field->name.c_str(), cl->name.c_str(), f.aliasName.c_str()); // printf("alias %s.%s -> %s.%s\n", cl->name.c_str(),
std::map<std::string, Field*>::iterator it = fields.find(f.field->name); // f.field->name.c_str(), cl->name.c_str(), f.aliasName.c_str());
std::map<std::string, Field*>::iterator it
= fields.find(f.field->name);
assert(it != fields.end()); assert(it != fields.end());
Field* renamed = it->second; Field* renamed = it->second;
fields.erase(it); fields.erase(it);
@ -444,20 +464,24 @@ class ClassParser {
renamed->name = f.aliasName; renamed->name = f.aliasName;
// TODO: this currently works around how avian uses an object (either a char[] or byte[]) for String.data // TODO: this currently works around how avian uses an object (either
// a char[] or byte[]) for String.data
renamed->typeName = f.field->typeName; renamed->typeName = f.field->typeName;
renamed->javaSpec = f.field->javaSpec; renamed->javaSpec = f.field->javaSpec;
} else { } else {
// printf("ignoring absent alias %s.%s -> %s.%s\n", cl->name.c_str(), f.field->name.c_str(), cl->name.c_str(), f. aliasName.c_str()); // printf("ignoring absent alias %s.%s -> %s.%s\n", cl->name.c_str(),
// f.field->name.c_str(), cl->name.c_str(), f. aliasName.c_str());
} }
} else { } else {
// printf("ignoring already defined alias %s.%s -> %s.%s\n", cl->name.c_str(), f.field->name.c_str(), cl->name.c_str(), f. aliasName.c_str()); // printf("ignoring already defined alias %s.%s -> %s.%s\n",
// cl->name.c_str(), f.field->name.c_str(), cl->name.c_str(), f.
// aliasName.c_str());
} }
} else { } else {
if(fields.find(f.field->name) == fields.end()) { if (fields.find(f.field->name) == fields.end()) {
// printf("add %s.%s\n", cl->name.c_str(), f.field->name.c_str()); // printf("add %s.%s\n", cl->name.c_str(), f.field->name.c_str());
fields[f.field->name] = f.field; fields[f.field->name] = f.field;
if(f.isArray) { if (f.isArray) {
add(FieldSpec(false, new Field(cl, "uintptr_t", "", "length"))); add(FieldSpec(false, new Field(cl, "uintptr_t", "", "length")));
assert(!cl->arrayField); assert(!cl->arrayField);
cl->arrayField = f.field; cl->arrayField = f.field;
@ -465,7 +489,8 @@ class ClassParser {
cl->fields.push_back(f.field); cl->fields.push_back(f.field);
} }
} else { } else {
// printf("required check %s.%s\n", cl->name.c_str(), f.field->name.c_str()); // printf("required check %s.%s\n", cl->name.c_str(),
// f.field->name.c_str());
assert(f.aliasName.size() > 0 || f.require); assert(f.aliasName.size() > 0 || f.require);
fields[f.field->name]->nogc |= f.field->nogc; fields[f.field->name]->nogc |= f.field->nogc;
fields[f.field->name]->noassert |= f.field->noassert; fields[f.field->name]->noassert |= f.field->noassert;
@ -473,12 +498,15 @@ class ClassParser {
} }
} }
void setSuper(Class* super) { void setSuper(Class* super)
{
assert(!cl->super); assert(!cl->super);
cl->super = super; cl->super = super;
assert(!super->arrayField); assert(!super->arrayField);
assert(fields.size() == 0); assert(fields.size() == 0);
for(std::vector<Field*>::iterator it = super->fields.begin(); it != super->fields.end(); it++) { for (std::vector<Field*>::iterator it = super->fields.begin();
it != super->fields.end();
it++) {
add(FieldSpec(false, *it)); add(FieldSpec(false, *it));
} }
} }
@ -495,12 +523,11 @@ FieldSpec parseArray(Module&, ClassParser& clparser, Object* p)
return FieldSpec(true, new Field(clparser.cl, typeName, "", name)); return FieldSpec(true, new Field(clparser.cl, typeName, "", name));
} }
FieldSpec parseVerbatimField(Module&, ClassParser& clparser, Object* p) { FieldSpec parseVerbatimField(Module&, ClassParser& clparser, Object* p)
{
const char* spec = string(car(p)); const char* spec = string(car(p));
const char* name = string(car(cdr(p))); const char* name = string(car(cdr(p)));
return FieldSpec( return FieldSpec(false, new Field(clparser.cl, spec, "", name));
false,
new Field(clparser.cl, spec, "", name));
} }
FieldSpec parseField(Module& module, ClassParser& clparser, Object* p) FieldSpec parseField(Module& module, ClassParser& clparser, Object* p)
@ -535,8 +562,7 @@ FieldSpec parseField(Module& module, ClassParser& clparser, Object* p)
return f; return f;
} }
void void parseSubdeclaration(Module& module, ClassParser& clparser, Object* p)
parseSubdeclaration(Module& module, ClassParser& clparser, Object* p)
{ {
const char* front = string(car(p)); const char* front = string(car(p));
if (equal(front, "extends")) { if (equal(front, "extends")) {
@ -592,8 +618,7 @@ fieldType(const char* spec)
} }
} }
void void parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
{ {
uint32_t magic = s->read4(); uint32_t magic = s->read4();
assert(magic == 0xCAFEBABE); assert(magic == 0xCAFEBABE);
@ -659,8 +684,8 @@ parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
s->skip(interfaceCount * 2); s->skip(interfaceCount * 2);
// for (unsigned i = 0; i < interfaceCount; ++i) { // for (unsigned i = 0; i < interfaceCount; ++i) {
// const char* name = reinterpret_cast<const char*> // const char* name = reinterpret_cast<const char*>
// (pool[pool[s->read2() - 1] - 1]); // (pool[pool[s->read2() - 1] - 1]);
// } // }
unsigned fieldCount = s->read2(); unsigned fieldCount = s->read2();
for (unsigned i = 0; i < fieldCount; ++i) { for (unsigned i = 0; i < fieldCount; ++i) {
@ -684,12 +709,14 @@ parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
const char* spec = reinterpret_cast<const char*>(pool[specIndex - 1]); const char* spec = reinterpret_cast<const char*>(pool[specIndex - 1]);
const char* memberType = fieldType(spec); const char* memberType = fieldType(spec);
clparser.add(FieldSpec(false, new Field(clparser.cl, memberType, spec, name))); clparser.add(
FieldSpec(false, new Field(clparser.cl, memberType, spec, name)));
} }
} }
if (clparser.cl->super) { if (clparser.cl->super) {
clparser.cl->methods.insert(clparser.cl->super->methods.begin(), clparser.cl->super->methods.end()); clparser.cl->methods.insert(clparser.cl->super->methods.begin(),
clparser.cl->super->methods.end());
} }
unsigned methodCount = s->read2(); unsigned methodCount = s->read2();
@ -782,8 +809,9 @@ void parse(Finder* finder, Input* in, Module& module)
} }
} }
void layoutClass(Module& module, Class* cl) { void layoutClass(Module& module, Class* cl)
if(cl->fixedSize >= 0) { {
if (cl->fixedSize >= 0) {
return; return;
} }
@ -794,12 +822,14 @@ void layoutClass(Module& module, Class* cl) {
alignment = BytesPerWord; alignment = BytesPerWord;
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); it++) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it; Field& f = **it;
f.elementSize = sizeOf(module, f.typeName); f.elementSize = sizeOf(module, f.typeName);
if(!f.polyfill) { // polyfills contribute no size if (!f.polyfill) { // polyfills contribute no size
alignment = f.elementSize; alignment = f.elementSize;
offset = (offset + alignment - 1) & ~(alignment - 1); offset = (offset + alignment - 1) & ~(alignment - 1);
f.offset = offset; f.offset = offset;
@ -809,7 +839,7 @@ void layoutClass(Module& module, Class* cl) {
offset += size; offset += size;
} }
} }
if(cl->arrayField) { if (cl->arrayField) {
Field& f = *cl->arrayField; Field& f = *cl->arrayField;
f.elementSize = sizeOf(module, f.typeName); f.elementSize = sizeOf(module, f.typeName);
@ -824,65 +854,68 @@ void layoutClass(Module& module, Class* cl) {
void layoutClasses(Module& module) void layoutClasses(Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
layoutClass(module, cl); layoutClass(module, cl);
} }
} }
void void writeOffset(Output* out, size_t offset)
writeOffset(Output* out, size_t offset)
{ {
out->write(offset); out->write(offset);
} }
void void writeOffset(Output* out, Class* cl)
writeOffset(Output* out, Class* cl)
{ {
out->write(cl->fixedSize); out->write(cl->fixedSize);
if(cl->arrayField) { if (cl->arrayField) {
out->write(" + pad(length * "); out->write(" + pad(length * ");
out->write(cl->arrayField->elementSize); out->write(cl->arrayField->elementSize);
out->write(")"); out->write(")");
} }
} }
std::string cppClassName(Class* cl) { std::string cppClassName(Class* cl)
if(cl->name == "jobject") { {
if (cl->name == "jobject") {
return "object"; return "object";
} else { } else {
return "Gc" + capitalize(cl->name) + "*"; return "Gc" + capitalize(cl->name) + "*";
} }
} }
std::string cppFieldType(Module& module, Field& f) { std::string cppFieldType(Module& module, Field& f)
if(f.javaSpec.size() != 0) { {
if(f.javaSpec[0] == 'L') { if (f.javaSpec.size() != 0) {
if (f.javaSpec[0] == 'L') {
std::string className = f.javaSpec.substr(1, f.javaSpec.size() - 2); std::string className = f.javaSpec.substr(1, f.javaSpec.size() - 2);
std::map<std::string, Class*>::iterator it = module.javaClasses.find(className); std::map<std::string, Class*>::iterator it
if(it != module.javaClasses.end()) { = module.javaClasses.find(className);
if (it != module.javaClasses.end()) {
return cppClassName(it->second); return cppClassName(it->second);
} }
} else if(f.javaSpec[0] == '[') { } else if (f.javaSpec[0] == '[') {
std::map<std::string, Class*>::iterator it = module.javaClasses.find(f.javaSpec); std::map<std::string, Class*>::iterator it
if(it != module.javaClasses.end()) { = module.javaClasses.find(f.javaSpec);
if (it != module.javaClasses.end()) {
return cppClassName(it->second); return cppClassName(it->second);
} }
} }
} }
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName); std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
assert(f.typeName.size() > 0); assert(f.typeName.size() > 0);
if(it != module.classes.end()) { if (it != module.classes.end()) {
return cppClassName(it->second); return cppClassName(it->second);
} else if(f.typeName == "maybe_object") { } else if (f.typeName == "maybe_object") {
return "uintptr_t"; return "uintptr_t";
} else { } else {
return f.typeName; return f.typeName;
} }
} }
void void writeAccessor(Output* out, Class* cl, Field& field)
writeAccessor(Output* out, Class* cl, Field& field)
{ {
std::string typeName = field.typeName; std::string typeName = field.typeName;
@ -899,28 +932,32 @@ writeAccessor(Output* out, Class* cl, Field& field)
out->write(" 1\n\n"); out->write(" 1\n\n");
} }
void void writeAccessors(Output* out, Module& module)
writeAccessors(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); ++it) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it; Field& f = **it;
if(!f.polyfill) { if (!f.polyfill) {
writeAccessor(out, cl, f); writeAccessor(out, cl, f);
} }
} }
if(cl->arrayField) { if (cl->arrayField) {
writeAccessor(out, cl, *cl->arrayField); writeAccessor(out, cl, *cl->arrayField);
} }
} }
} }
void void writeSizes(Output* out, Module& module)
writeSizes(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
out->write("const unsigned FixedSizeOf"); out->write("const unsigned FixedSizeOf");
@ -939,8 +976,7 @@ writeSizes(Output* out, Module& module)
} }
} }
std::string std::string obfuscate(const std::string& s)
obfuscate(const std::string& s)
{ {
if (s == "default" || s == "template" || s == "class" || s == "register" if (s == "default" || s == "template" || s == "class" || s == "register"
|| s == "this") { || s == "this") {
@ -950,12 +986,13 @@ obfuscate(const std::string& s)
} }
} }
void void writeConstructorParameters(Output* out, Module& module, Class* cl)
writeConstructorParameters(Output* out, Module& module, Class* cl)
{ {
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); ++it) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it; Field& f = **it;
if(!f.polyfill) { if (!f.polyfill) {
out->write(", "); out->write(", ");
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
out->write(" "); out->write(" ");
@ -964,24 +1001,26 @@ writeConstructorParameters(Output* out, Module& module, Class* cl)
} }
} }
void void writeConstructorArguments(Output* out, Class* cl)
writeConstructorArguments(Output* out, Class* cl)
{ {
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); ++it) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it; Field& f = **it;
if(!f.polyfill) { if (!f.polyfill) {
out->write(", "); out->write(", ");
out->write(obfuscate(f.name)); out->write(obfuscate(f.name));
} }
} }
} }
void void writeConstructorInitializations(Output* out, Class* cl)
writeConstructorInitializations(Output* out, Class* cl)
{ {
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); ++it) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it; Field& f = **it;
if(!f.polyfill) { if (!f.polyfill) {
out->write(" o->set"); out->write(" o->set");
out->write(capitalize(f.name)); out->write(capitalize(f.name));
out->write("(t, "); out->write("(t, ");
@ -991,10 +1030,11 @@ writeConstructorInitializations(Output* out, Class* cl)
} }
} }
void writeClassDeclarations(Output* out, Module& module) void writeClassDeclarations(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); it++) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
it++) {
Class* cl = it->second; Class* cl = it->second;
out->write("class Gc"); out->write("class Gc");
@ -1004,26 +1044,31 @@ void writeClassDeclarations(Output* out, Module& module)
out->write("\n"); out->write("\n");
} }
bool isFieldGcVisible(Module& module, Field& f) { bool isFieldGcVisible(Module& module, Field& f)
{
return enumName(module, f) == "object" && !f.nogc; return enumName(module, f) == "object" && !f.nogc;
} }
bool isFieldGcMarkable(Module& module, Field& f) { bool isFieldGcMarkable(Module& module, Field& f)
return (f.typeName == "maybe_object" || enumName(module, f) == "object") && !f.nogc; {
return (f.typeName == "maybe_object" || enumName(module, f) == "object")
&& !f.nogc;
} }
void writeClassAccessors(Output* out, Module& module, Class* cl) void writeClassAccessors(Output* out, Module& module, Class* cl)
{ {
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); ++it) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it; Field& f = **it;
if(!f.polyfill) { if (!f.polyfill) {
out->write(" void set"); out->write(" void set");
out->write(capitalize(f.name)); out->write(capitalize(f.name));
out->write("(Thread* t UNUSED, "); out->write("(Thread* t UNUSED, ");
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
out->write(" value) { "); out->write(" value) { ");
if(isFieldGcMarkable(module, f)) { if (isFieldGcMarkable(module, f)) {
out->write("setField(t, this , "); out->write("setField(t, this , ");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
out->write(capitalize(f.name)); out->write(capitalize(f.name));
@ -1052,17 +1097,17 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
out->write(" "); out->write(" ");
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
if(!f.polyfill && !isFieldGcMarkable(module, f)) { if (!f.polyfill && !isFieldGcMarkable(module, f)) {
out->write("&"); out->write("&");
} }
out->write(" "); out->write(" ");
out->write(obfuscate(f.name)); out->write(obfuscate(f.name));
if(f.threadParam || f.polyfill) { if (f.threadParam || f.polyfill) {
out->write("(Thread*"); out->write("(Thread*");
} else { } else {
out->write("("); out->write("(");
} }
if(f.polyfill) { if (f.polyfill) {
out->write("); // polyfill, assumed to be implemented elsewhere\n"); out->write("); // polyfill, assumed to be implemented elsewhere\n");
} else { } else {
out->write(") { return field_at<"); out->write(") { return field_at<");
@ -1073,22 +1118,22 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
out->write("); }\n"); out->write("); }\n");
} }
} }
if(cl->arrayField) { if (cl->arrayField) {
Field& f = *cl->arrayField; Field& f = *cl->arrayField;
out->write(" avian::util::Slice<"); out->write(" avian::util::Slice<");
if(isFieldGcVisible(module, f)) { if (isFieldGcVisible(module, f)) {
out->write("const "); out->write("const ");
} }
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
out->write("> "); out->write("> ");
out->write(obfuscate(f.name)); out->write(obfuscate(f.name));
out->write("() { return avian::util::Slice<"); out->write("() { return avian::util::Slice<");
if(isFieldGcVisible(module, f)) { if (isFieldGcVisible(module, f)) {
out->write("const "); out->write("const ");
} }
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
out->write("> (&field_at<"); out->write("> (&field_at<");
if(isFieldGcVisible(module, f)) { if (isFieldGcVisible(module, f)) {
out->write("const "); out->write("const ");
} }
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
@ -1104,7 +1149,7 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
out->write("Element(Thread* t UNUSED, size_t index, "); out->write("Element(Thread* t UNUSED, size_t index, ");
out->write(cppFieldType(module, f)); out->write(cppFieldType(module, f));
out->write(" value) { "); out->write(" value) { ");
if(isFieldGcMarkable(module, f)) { if (isFieldGcMarkable(module, f)) {
out->write("setField(t, this , "); out->write("setField(t, this , ");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
out->write(capitalize(f.name)); out->write(capitalize(f.name));
@ -1127,7 +1172,9 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
void writeClasses(Output* out, Module& module) void writeClasses(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); it++) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
it++) {
Class* cl = it->second; Class* cl = it->second;
out->write("class Gc"); out->write("class Gc");
@ -1147,10 +1194,11 @@ void writeClasses(Output* out, Module& module)
} }
} }
void void writeInitializerDeclarations(Output* out, Module& module)
writeInitializerDeclarations(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
out->write("void init"); out->write("void init");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
@ -1164,10 +1212,11 @@ writeInitializerDeclarations(Output* out, Module& module)
} }
} }
void void writeConstructorDeclarations(Output* out, Module& module)
writeConstructorDeclarations(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
out->write("Gc"); out->write("Gc");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
@ -1181,10 +1230,11 @@ writeConstructorDeclarations(Output* out, Module& module)
} }
} }
void void writeInitializers(Output* out, Module& module)
writeInitializers(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
out->write("void init"); out->write("void init");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
@ -1197,7 +1247,9 @@ writeInitializers(Output* out, Module& module)
out->write(")\n{\n"); out->write(")\n{\n");
out->write(" setObjectClass(t, reinterpret_cast<object>(o), "); out->write(" setObjectClass(t, reinterpret_cast<object>(o), ");
out->write("reinterpret_cast<GcClass*>(reinterpret_cast<GcArray*>(t->m->types)->body()[Gc::"); out->write(
"reinterpret_cast<GcClass*>(reinterpret_cast<GcArray*>(t->m->types)->"
"body()[Gc::");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
out->write("Type]));\n"); out->write("Type]));\n");
@ -1207,10 +1259,11 @@ writeInitializers(Output* out, Module& module)
} }
} }
void void writeConstructors(Output* out, Module& module)
writeConstructors(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
out->write("Gc"); out->write("Gc");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
@ -1223,11 +1276,11 @@ writeConstructors(Output* out, Module& module)
out->write(")\n{\n"); out->write(")\n{\n");
bool hasObjectMask = cl->name == "singleton"; bool hasObjectMask = cl->name == "singleton";
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); it++) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it; Field& f = **it;
if (enumName(module, f) == "object" if (enumName(module, f) == "object" and not f.nogc) {
and not f.nogc)
{
out->write(" PROTECT(t, "); out->write(" PROTECT(t, ");
out->write(obfuscate(f.name)); out->write(obfuscate(f.name));
out->write(");\n"); out->write(");\n");
@ -1235,7 +1288,7 @@ writeConstructors(Output* out, Module& module)
hasObjectMask = true; hasObjectMask = true;
} }
} }
if(cl->arrayField) { if (cl->arrayField) {
Field& f = *cl->arrayField; Field& f = *cl->arrayField;
if (f.typeName == "object" and not f.nogc) { if (f.typeName == "object" and not f.nogc) {
hasObjectMask = true; hasObjectMask = true;
@ -1265,11 +1318,12 @@ writeConstructors(Output* out, Module& module)
} }
} }
void void writeEnums(Output* out, Module& module)
writeEnums(Output* out, Module& module)
{ {
bool wrote = false; bool wrote = false;
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
if (wrote) { if (wrote) {
out->write(",\n"); out->write(",\n");
@ -1295,26 +1349,27 @@ set(uint32_t* mask, unsigned index)
} }
} }
uint32_t uint32_t typeObjectMask(Module& module, Class* cl)
typeObjectMask(Module& module, Class* cl)
{ {
assert(cl->fixedSize + (cl->arrayField ? cl->arrayField->elementSize : 0) assert(cl->fixedSize + (cl->arrayField ? cl->arrayField->elementSize : 0)
< 32 * BytesPerWord); < 32 * BytesPerWord);
uint32_t mask = 1; uint32_t mask = 1;
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); it++) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it; Field& f = **it;
unsigned offset = f.offset / BytesPerWord; unsigned offset = f.offset / BytesPerWord;
if(isFieldGcVisible(module, f)) { if (isFieldGcVisible(module, f)) {
set(&mask, offset); set(&mask, offset);
} }
} }
if(cl->arrayField) { if (cl->arrayField) {
Field& f = *cl->arrayField; Field& f = *cl->arrayField;
unsigned offset = f.offset / BytesPerWord; unsigned offset = f.offset / BytesPerWord;
if(isFieldGcVisible(module, f)) { if (isFieldGcVisible(module, f)) {
set(&mask, offset); set(&mask, offset);
} }
} }
@ -1322,14 +1377,16 @@ typeObjectMask(Module& module, Class* cl)
return mask; return mask;
} }
void void writeInitialization(Output* out,
writeInitialization(Output* out, Module& module, std::set<Class*>& alreadyInited, Class* cl) Module& module,
std::set<Class*>& alreadyInited,
Class* cl)
{ {
if(alreadyInited.find(cl) != alreadyInited.end()) { if (alreadyInited.find(cl) != alreadyInited.end()) {
return; return;
} }
alreadyInited.insert(cl); alreadyInited.insert(cl);
if(cl->super && cl->name != "intArray" && cl->name != "class") { if (cl->super && cl->name != "intArray" && cl->name != "class") {
writeInitialization(out, module, alreadyInited, cl->super); writeInitialization(out, module, alreadyInited, cl->super);
} }
out->write("bootClass(t, Gc::"); out->write("bootClass(t, Gc::");
@ -1362,24 +1419,24 @@ writeInitialization(Output* out, Module& module, std::set<Class*>& alreadyInited
out->write(");\n"); out->write(");\n");
} }
void void writeInitializations(Output* out, Module& module)
writeInitializations(Output* out, Module& module)
{ {
std::set<Class*> alreadyInited; std::set<Class*> alreadyInited;
writeInitialization(out, module, alreadyInited, module.classes["intArray"]); writeInitialization(out, module, alreadyInited, module.classes["intArray"]);
writeInitialization(out, module, alreadyInited, module.classes["class"]); writeInitialization(out, module, alreadyInited, module.classes["class"]);
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
if(cl->name != "intArray" && cl->name != "class") { if (cl->name != "intArray" && cl->name != "class") {
writeInitialization(out, module, alreadyInited, cl); writeInitialization(out, module, alreadyInited, cl);
} }
} }
} }
void void writeJavaInitialization(Output* out, Class* cl)
writeJavaInitialization(Output* out, Class* cl)
{ {
out->write("bootJavaClass(t, Gc::"); out->write("bootJavaClass(t, Gc::");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
@ -1405,10 +1462,11 @@ writeJavaInitialization(Output* out, Class* cl)
out->write(", bootMethod);\n"); out->write(", bootMethod);\n");
} }
void void writeJavaInitializations(Output* out, Module& module)
writeJavaInitializations(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
if (cl->javaName.size()) { if (cl->javaName.size()) {
writeJavaInitialization(out, cl); writeJavaInitialization(out, cl);
@ -1416,22 +1474,14 @@ writeJavaInitializations(Output* out, Module& module)
} }
} }
void void writeNameInitialization(Output* out, Class* cl)
writeNameInitialization(Output* out, Class* cl)
{ {
out->write("nameClass(t, Gc::"); out->write("nameClass(t, Gc::");
out->write(capitalize(cl->name)); out->write(capitalize(cl->name));
out->write("Type, \""); out->write("Type, \"");
if (cl->name == "jbyte" if (cl->name == "jbyte" or cl->name == "jboolean" or cl->name == "jshort"
or cl->name == "jboolean" or cl->name == "jchar" or cl->name == "jint" or cl->name == "jlong"
or cl->name == "jshort" or cl->name == "jfloat" or cl->name == "jdouble" or cl->name == "jvoid") {
or cl->name == "jchar"
or cl->name == "jint"
or cl->name == "jlong"
or cl->name == "jfloat"
or cl->name == "jdouble"
or cl->name == "jvoid")
{
out->write(cl->name.substr(1, cl->name.size() - 1)); out->write(cl->name.substr(1, cl->name.size() - 1));
} else { } else {
out->write("vm::"); out->write("vm::");
@ -1440,10 +1490,11 @@ writeNameInitialization(Output* out, Class* cl)
out->write("\");\n"); out->write("\");\n");
} }
void void writeNameInitializations(Output* out, Module& module)
writeNameInitializations(Output* out, Module& module)
{ {
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
if (!cl->javaName.size()) { if (!cl->javaName.size()) {
writeNameInitialization(out, cl); writeNameInitialization(out, cl);
@ -1451,15 +1502,16 @@ writeNameInitializations(Output* out, Module& module)
} }
} }
void void writeMap(Output* out, Module& module, Class* cl)
writeMap(Output* out, Module& module, Class* cl)
{ {
std::ostringstream ss; std::ostringstream ss;
uintptr_t ownerId = 0; uintptr_t ownerId = 0;
for(std::vector<Field*>::iterator it = cl->fields.begin(); it != cl->fields.end(); it++) { for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it; Field& f = **it;
if(ownerId && ownerId != f.ownerId) { if (ownerId && ownerId != f.ownerId) {
ss << "Type_pad, "; ss << "Type_pad, ";
} }
ownerId = f.ownerId; ownerId = f.ownerId;
@ -1473,9 +1525,9 @@ writeMap(Output* out, Module& module, Class* cl)
ss << ", "; ss << ", ";
} }
if(cl->arrayField) { if (cl->arrayField) {
Field& f = *cl->arrayField; Field& f = *cl->arrayField;
if(ownerId && ownerId != f.ownerId) { if (ownerId && ownerId != f.ownerId) {
ss << "Type_pad, "; ss << "Type_pad, ";
} }
ss << "Type_array, "; ss << "Type_array, ";
@ -1489,14 +1541,15 @@ writeMap(Output* out, Module& module, Class* cl)
out->write(ss.str()); out->write(ss.str());
} }
void void writeMaps(Output* out, Module& module)
writeMaps(Output* out, Module& module)
{ {
out->write("Type types[]["); out->write("Type types[][");
out->write(module.classes.size()); out->write(module.classes.size());
out->write("] = {\n"); out->write("] = {\n");
bool wrote = false; bool wrote = false;
for(std::map<std::string, Class*>::iterator it = module.classes.begin(); it != module.classes.end(); ++it) { for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second; Class* cl = it->second;
if (wrote) { if (wrote) {
out->write(",\n"); out->write(",\n");

View File

@ -49,21 +49,20 @@ class TreeContext {
bool fresh; bool fresh;
}; };
List<GcTreeNode*>* List<GcTreeNode*>* path(TreeContext* c,
path(TreeContext* c, GcTreeNode* node, List<GcTreeNode*>* next) GcTreeNode* node,
List<GcTreeNode*>* next)
{ {
return new(c->zone) List<GcTreeNode*>(node, next); return new (c->zone) List<GcTreeNode*>(node, next);
} }
inline object inline object getTreeNodeValue(Thread*, GcTreeNode* n)
getTreeNodeValue(Thread*, GcTreeNode* n)
{ {
return reinterpret_cast<object> return reinterpret_cast<object>
(alias(n, TreeNodeValue) & PointerMask); (alias(n, TreeNodeValue) & PointerMask);
} }
inline void inline void setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
{ {
intptr_t red = alias(n, TreeNodeValue) & (~PointerMask); intptr_t red = alias(n, TreeNodeValue) & (~PointerMask);
@ -72,14 +71,12 @@ setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
alias(n, TreeNodeValue) |= red; alias(n, TreeNodeValue) |= red;
} }
inline bool inline bool treeNodeRed(Thread*, GcTreeNode* n)
treeNodeRed(Thread*, GcTreeNode* n)
{ {
return (alias(n, TreeNodeValue) & (~PointerMask)) == 1; return (alias(n, TreeNodeValue) & (~PointerMask)) == 1;
} }
inline void inline void setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
{ {
if (red) { if (red) {
alias(n, TreeNodeValue) |= 1; alias(n, TreeNodeValue) |= 1;
@ -88,20 +85,21 @@ setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
} }
} }
inline GcTreeNode* inline GcTreeNode* cloneTreeNode(Thread* t, GcTreeNode* n)
cloneTreeNode(Thread* t, GcTreeNode* n)
{ {
PROTECT(t, n); PROTECT(t, n);
GcTreeNode* newNode = makeTreeNode GcTreeNode* newNode
(t, getTreeNodeValue(t, n), n->left(), n->right()); = makeTreeNode(t, getTreeNodeValue(t, n), n->left(), n->right());
setTreeNodeRed(t, newNode, treeNodeRed(t, n)); setTreeNodeRed(t, newNode, treeNodeRed(t, n));
return newNode; return newNode;
} }
GcTreeNode* GcTreeNode* treeFind(Thread* t,
treeFind(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)) intptr_t key,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
GcTreeNode* node = tree; GcTreeNode* node = tree;
while (node != sentinal) { while (node != sentinal) {
@ -118,10 +116,13 @@ treeFind(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
return 0; return 0;
} }
void void treeFind(Thread* t,
treeFind(Thread* t, TreeContext* c, GcTreeNode* old, intptr_t key, GcTreeNode* node, TreeContext* c,
GcTreeNode* sentinal, GcTreeNode* old,
intptr_t (*compare)(Thread* t, intptr_t key, object b)) intptr_t key,
GcTreeNode* node,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
PROTECT(t, old); PROTECT(t, old);
PROTECT(t, node); PROTECT(t, node);
@ -173,8 +174,7 @@ treeFind(Thread* t, TreeContext* c, GcTreeNode* old, intptr_t key, GcTreeNode* n
c->ancestors = c->ancestors; c->ancestors = c->ancestors;
} }
GcTreeNode* GcTreeNode* leftRotate(Thread* t, GcTreeNode* n)
leftRotate(Thread* t, GcTreeNode* n)
{ {
PROTECT(t, n); PROTECT(t, n);
@ -184,8 +184,7 @@ leftRotate(Thread* t, GcTreeNode* n)
return child; return child;
} }
GcTreeNode* GcTreeNode* rightRotate(Thread* t, GcTreeNode* n)
rightRotate(Thread* t, GcTreeNode* n)
{ {
PROTECT(t, n); PROTECT(t, n);
@ -195,8 +194,7 @@ rightRotate(Thread* t, GcTreeNode* n)
return child; return child;
} }
GcTreeNode* GcTreeNode* treeAdd(Thread* t, TreeContext* c)
treeAdd(Thread* t, TreeContext* c)
{ {
GcTreeNode* new_ = c->node; GcTreeNode* new_ = c->node;
PROTECT(t, new_); PROTECT(t, new_);
@ -207,16 +205,11 @@ treeAdd(Thread* t, TreeContext* c)
// rebalance // rebalance
setTreeNodeRed(t, new_, true); setTreeNodeRed(t, new_, true);
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) { while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
if (c->ancestors->item if (c->ancestors->item == c->ancestors->next->item->left()) {
== c->ancestors->next->item->left()) if (treeNodeRed(t, c->ancestors->next->item->right())) {
{
if (treeNodeRed
(t, c->ancestors->next->item->right()))
{
setTreeNodeRed(t, c->ancestors->item, false); setTreeNodeRed(t, c->ancestors->item, false);
GcTreeNode* n = cloneTreeNode GcTreeNode* n = cloneTreeNode(t, c->ancestors->next->item->right());
(t, c->ancestors->next->item->right());
c->ancestors->next->item->setRight(t, n); c->ancestors->next->item->setRight(t, n);
@ -247,8 +240,7 @@ treeAdd(Thread* t, TreeContext* c)
if (c->ancestors->next->next == 0) { if (c->ancestors->next->next == 0) {
newRoot = n; newRoot = n;
} else if (c->ancestors->next->next->item->right() } else if (c->ancestors->next->next->item->right()
== c->ancestors->next->item) == c->ancestors->next->item) {
{
c->ancestors->next->next->item->setRight(t, n); c->ancestors->next->next->item->setRight(t, n);
} else { } else {
c->ancestors->next->next->item->setLeft(t, n); c->ancestors->next->next->item->setLeft(t, n);
@ -257,13 +249,10 @@ treeAdd(Thread* t, TreeContext* c)
} }
} else { // this is just the reverse of the code above (right and } else { // this is just the reverse of the code above (right and
// left swapped): // left swapped):
if (treeNodeRed if (treeNodeRed(t, c->ancestors->next->item->left())) {
(t, c->ancestors->next->item->left()))
{
setTreeNodeRed(t, c->ancestors->item, false); setTreeNodeRed(t, c->ancestors->item, false);
GcTreeNode* n = cloneTreeNode GcTreeNode* n = cloneTreeNode(t, c->ancestors->next->item->left());
(t, c->ancestors->next->item->left());
c->ancestors->next->item->setLeft(t, n); c->ancestors->next->item->setLeft(t, n);
@ -294,8 +283,7 @@ treeAdd(Thread* t, TreeContext* c)
if (c->ancestors->next->next == 0) { if (c->ancestors->next->next == 0) {
newRoot = n; newRoot = n;
} else if (c->ancestors->next->next->item->left() } else if (c->ancestors->next->next->item->left()
== c->ancestors->next->item) == c->ancestors->next->item) {
{
c->ancestors->next->next->item->setLeft(t, n); c->ancestors->next->next->item->setLeft(t, n);
} else { } else {
c->ancestors->next->next->item->setRight(t, n); c->ancestors->next->next->item->setRight(t, n);
@ -314,17 +302,19 @@ treeAdd(Thread* t, TreeContext* c)
namespace vm { namespace vm {
GcTriple* GcTriple* hashMapFindNode(Thread* t,
hashMapFindNode(Thread* t, GcHashMap* map, object key, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)) uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object))
{ {
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type); bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
GcArray* array = map->array(); GcArray* array = map->array();
if (array) { if (array) {
unsigned index = hash(t, key) & (array->length() - 1); unsigned index = hash(t, key) & (array->length() - 1);
for (GcTriple* n = cast<GcTriple>(t, array->body()[index]); n; n = cast<GcTriple>(t, n->third())) { for (GcTriple* n = cast<GcTriple>(t, array->body()[index]); n;
n = cast<GcTriple>(t, n->third())) {
object k = n->first(); object k = n->first();
if (weak) { if (weak) {
k = cast<GcJreference>(t, k)->target(); k = cast<GcJreference>(t, k)->target();
@ -341,9 +331,10 @@ hashMapFindNode(Thread* t, GcHashMap* map, object key,
return 0; return 0;
} }
void void hashMapResize(Thread* t,
hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object), GcHashMap* map,
unsigned size) uint32_t (*hash)(Thread*, object),
unsigned size)
{ {
PROTECT(t, map); PROTECT(t, map);
@ -370,7 +361,8 @@ hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type); bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
for (unsigned i = 0; i < oldArray->length(); ++i) { for (unsigned i = 0; i < oldArray->length(); ++i) {
GcTriple* next; GcTriple* next;
for (GcTriple* p = cast<GcTriple>(t, oldArray->body()[i]); p; p = next) { for (GcTriple* p = cast<GcTriple>(t, oldArray->body()[i]); p;
p = next) {
next = cast<GcTriple>(t, p->third()); next = cast<GcTriple>(t, p->third());
object k = p->first(); object k = p->first();
@ -393,9 +385,11 @@ hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
map->setArray(t, newArray); map->setArray(t, newArray);
} }
void void hashMapInsert(Thread* t,
hashMapInsert(Thread* t, GcHashMap* map, object key, object value, GcHashMap* map,
uint32_t (*hash)(Thread*, object)) object key,
object value,
uint32_t (*hash)(Thread*, object))
{ {
// note that we reinitialize the array variable whenever an // note that we reinitialize the array variable whenever an
// allocation (and thus possibly a collection) occurs, in case the // allocation (and thus possibly a collection) occurs, in case the
@ -409,7 +403,7 @@ hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
GcArray* array = map->array(); GcArray* array = map->array();
++ map->size(); ++map->size();
if (array == 0 or map->size() >= array->length() * 2) { if (array == 0 or map->size() >= array->length() * 2) {
PROTECT(t, key); PROTECT(t, key);
@ -452,22 +446,26 @@ hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
} }
} }
GcTriple* GcTriple* hashMapRemoveNode(Thread* t,
hashMapRemoveNode(Thread* t, GcHashMap* map, unsigned index, GcTriple* p, GcTriple* n) GcHashMap* map,
unsigned index,
GcTriple* p,
GcTriple* n)
{ {
if (p) { if (p) {
p->setThird(t, n->third()); p->setThird(t, n->third());
} else { } else {
map->array()->setBodyElement(t, index, n->third()); map->array()->setBodyElement(t, index, n->third());
} }
-- map->size(); --map->size();
return n; return n;
} }
object object hashMapRemove(Thread* t,
hashMapRemove(Thread* t, GcHashMap* map, object key, GcHashMap* map,
uint32_t (*hash)(Thread*, object), object key,
bool (*equal)(Thread*, object, object)) uint32_t (*hash)(Thread*, object),
bool (*equal)(Thread*, object, object))
{ {
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type); bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
@ -481,7 +479,8 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
if (weak) { if (weak) {
k = cast<GcJreference>(t, k)->target(); k = cast<GcJreference>(t, k)->target();
if (k == 0) { if (k == 0) {
n = cast<GcTriple>(t, hashMapRemoveNode(t, map, index, p, n)->third()); n = cast<GcTriple>(t,
hashMapRemoveNode(t, map, index, p, n)->third());
continue; continue;
} }
} }
@ -495,9 +494,7 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
} }
} }
if ((not t->m->collecting) if ((not t->m->collecting) and map->size() <= array->length() / 3) {
and map->size() <= array->length() / 3)
{
PROTECT(t, o); PROTECT(t, o);
hashMapResize(t, map, hash, array->length() / 2); hashMapResize(t, map, hash, array->length() / 2);
} }
@ -506,12 +503,11 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
return o; return o;
} }
void void listAppend(Thread* t, GcList* list, object value)
listAppend(Thread* t, GcList* list, object value)
{ {
PROTECT(t, list); PROTECT(t, list);
++ list->size(); ++list->size();
object p = makePair(t, value, 0); object p = makePair(t, value, 0);
if (list->front()) { if (list->front()) {
@ -522,18 +518,17 @@ listAppend(Thread* t, GcList* list, object value)
list->setRear(t, p); list->setRear(t, p);
} }
GcVector* GcVector* vectorAppend(Thread* t, GcVector* vector, object value)
vectorAppend(Thread* t, GcVector* vector, object value)
{ {
if (vector->length() == vector->size()) { if (vector->length() == vector->size()) {
PROTECT(t, vector); PROTECT(t, vector);
PROTECT(t, value); PROTECT(t, value);
GcVector* newVector = makeVector GcVector* newVector
(t, vector->size(), max(16, vector->size() * 2)); = makeVector(t, vector->size(), max(16, vector->size() * 2));
if (vector->size()) { if (vector->size()) {
for(size_t i = 0; i < vector->size(); i++) { for (size_t i = 0; i < vector->size(); i++) {
newVector->setBodyElement(t, i, vector->body()[i]); newVector->setBodyElement(t, i, vector->body()[i]);
} }
} }
@ -542,20 +537,18 @@ vectorAppend(Thread* t, GcVector* vector, object value)
} }
vector->setBodyElement(t, vector->size(), value); vector->setBodyElement(t, vector->size(), value);
++ vector->size(); ++vector->size();
return vector; return vector;
} }
GcArray* GcArray* growArray(Thread* t, GcArray* array)
growArray(Thread* t, GcArray* array)
{ {
PROTECT(t, array); PROTECT(t, array);
GcArray* newArray = makeArray GcArray* newArray = makeArray(t, array == 0 ? 16 : (array->length() * 2));
(t, array == 0 ? 16 : (array->length() * 2));
if (array) { if (array) {
for(size_t i = 0; i < array->length(); i++) { for (size_t i = 0; i < array->length(); i++) {
newArray->setBodyElement(t, i, array->body()[i]); newArray->setBodyElement(t, i, array->body()[i]);
} }
} }
@ -563,18 +556,23 @@ growArray(Thread* t, GcArray* array)
return newArray; return newArray;
} }
object object treeQuery(Thread* t,
treeQuery(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)) intptr_t key,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
GcTreeNode* node = treeFind(t, tree, key, sentinal, compare); GcTreeNode* node = treeFind(t, tree, key, sentinal, compare);
return (node ? getTreeNodeValue(t, node) : 0); return (node ? getTreeNodeValue(t, node) : 0);
} }
GcTreeNode* GcTreeNode* treeInsert(Thread* t,
treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value, Zone* zone,
GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)) intptr_t key,
object value,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
PROTECT(t, tree); PROTECT(t, tree);
PROTECT(t, sentinal); PROTECT(t, sentinal);
@ -588,9 +586,12 @@ treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value,
return treeAdd(t, &c); return treeAdd(t, &c);
} }
void void treeUpdate(Thread* t,
treeUpdate(Thread* t, GcTreeNode* tree, intptr_t key, object value, GcTreeNode* sentinal, GcTreeNode* tree,
intptr_t (*compare)(Thread* t, intptr_t key, object b)) intptr_t key,
object value,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
setTreeNodeValue(t, treeFind(t, tree, key, sentinal, compare), value); setTreeNodeValue(t, treeFind(t, tree, key, sentinal, compare), value);
} }