mirror of
https://github.com/corda/corda.git
synced 2025-01-19 03:06:36 +00:00
reformat changes since master
This commit is contained in:
parent
cbad6931af
commit
7642b94308
@ -58,21 +58,23 @@ Java_java_net_Socket_closeInput(JNIEnv* e, jclass, SOCKET sock) {
|
||||
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 */
|
||||
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
|
||||
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(t, reinterpret_cast<vm::object>(arguments[2]));
|
||||
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
|
||||
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
|
||||
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]));
|
||||
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
|
||||
avian::classpath::sockets::send((JNIEnv*)t, s, buffer, count);
|
||||
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
|
||||
avian::classpath::sockets::send((JNIEnv*)t, s, buffer, count);
|
||||
}
|
||||
|
||||
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 */
|
||||
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
|
||||
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(t, reinterpret_cast<vm::object>(arguments[2]));
|
||||
int32_t& start_pos = *(reinterpret_cast<int32_t*>(&arguments[3]));
|
||||
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
|
||||
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]));
|
||||
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
|
||||
return avian::classpath::sockets::recv((JNIEnv*)t, s, buffer, count);
|
||||
char* buffer = reinterpret_cast<char*>(&buffer_obj->body()[start_pos]);
|
||||
return avian::classpath::sockets::recv((JNIEnv*)t, s, buffer, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
|
@ -160,4 +160,4 @@ class DelayedPromise: public ListenPromise {
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
||||
#endif // AVIAN_CODEGEN_PROMISE_H
|
||||
#endif // AVIAN_CODEGEN_PROMISE_H
|
||||
|
@ -70,4 +70,4 @@ public:
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
||||
#endif // AVIAN_CODEGEN_REGISTERS_H
|
||||
#endif // AVIAN_CODEGEN_REGISTERS_H
|
||||
|
@ -75,7 +75,7 @@ class Heap : public avian::util::Allocator {
|
||||
virtual void pad(void* p) = 0;
|
||||
virtual void* follow(void* p) = 0;
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
T* follow(T* p)
|
||||
{
|
||||
return static_cast<T*>(follow((void*)p));
|
||||
|
@ -44,8 +44,9 @@ inline void expect(T t, bool v) {
|
||||
#ifdef NDEBUG
|
||||
#define assertT(t, v)
|
||||
#else
|
||||
template<class T>
|
||||
inline void assertT(T t, bool v) {
|
||||
template <class T>
|
||||
inline void assertT(T t, bool v)
|
||||
{
|
||||
expect(t, v);
|
||||
}
|
||||
#endif
|
||||
|
@ -46,4 +46,4 @@ public:
|
||||
} // namespace avian
|
||||
} // namespace util
|
||||
|
||||
#endif // AVIAN_UTIL_ARG_PARSER_H
|
||||
#endif // AVIAN_UTIL_ARG_PARSER_H
|
||||
|
@ -37,8 +37,8 @@ inline uint32_t hash(Slice<const uint8_t> data)
|
||||
|
||||
inline uint32_t hash(Slice<const int8_t> data)
|
||||
{
|
||||
return hash(
|
||||
Slice<const uint8_t>(reinterpret_cast<const uint8_t*>(data.begin()), data.count));
|
||||
return hash(Slice<const uint8_t>(
|
||||
reinterpret_cast<const uint8_t*>(data.begin()), data.count));
|
||||
}
|
||||
|
||||
inline uint32_t hash(Slice<const uint16_t> data)
|
||||
|
@ -21,7 +21,6 @@ namespace util {
|
||||
template <class T>
|
||||
struct NonConst;
|
||||
|
||||
|
||||
template <class T>
|
||||
struct NonConst<const T> {
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -30,12 +30,9 @@ getTrace(Thread* t, unsigned skipCount)
|
||||
virtual bool visit(Processor::StackWalker* walker) {
|
||||
if (skipCount == 0) {
|
||||
GcMethod* method = walker->method();
|
||||
if (isAssignableFrom
|
||||
(t, type(t, GcThrowable::Type), method->class_())
|
||||
if (isAssignableFrom(t, type(t, GcThrowable::Type), method->class_())
|
||||
and vm::strcmp(reinterpret_cast<const int8_t*>("<init>"),
|
||||
method->name()->body().begin())
|
||||
== 0)
|
||||
{
|
||||
method->name()->body().begin()) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
trace = makeTrace(t, walker);
|
||||
@ -59,14 +56,11 @@ getTrace(Thread* t, unsigned skipCount)
|
||||
return v.trace;
|
||||
}
|
||||
|
||||
bool
|
||||
compatibleArrayTypes(Thread* t UNUSED, GcClass* a, GcClass* b)
|
||||
bool compatibleArrayTypes(Thread* t UNUSED, GcClass* a, GcClass* b)
|
||||
{
|
||||
return a->arrayElementSize()
|
||||
and b->arrayElementSize()
|
||||
and (a == b
|
||||
or (not ((a->vmFlags() & PrimitiveFlag)
|
||||
or (b->vmFlags() & PrimitiveFlag))));
|
||||
return a->arrayElementSize() and b->arrayElementSize()
|
||||
and (a == b or (not((a->vmFlags() & PrimitiveFlag)
|
||||
or (b->vmFlags() & PrimitiveFlag))));
|
||||
}
|
||||
|
||||
void
|
||||
@ -239,8 +233,11 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
|
||||
runOnLoadIfFound(t, lib);
|
||||
}
|
||||
} else if (throw_) {
|
||||
throwNew(t, GcUnsatisfiedLinkError::Type,
|
||||
"library not found in %s: %s", path, name);
|
||||
throwNew(t,
|
||||
GcUnsatisfiedLinkError::Type,
|
||||
"library not found in %s: %s",
|
||||
path,
|
||||
name);
|
||||
}
|
||||
|
||||
return lib;
|
||||
@ -268,17 +265,20 @@ clone(Thread* t, object o)
|
||||
} else {
|
||||
GcByteArray* classNameSlash = objectClass(t, o)->name();
|
||||
THREAD_RUNTIME_ARRAY(t, char, classNameDot, classNameSlash->length());
|
||||
replace('/', '.', RUNTIME_ARRAY_BODY(classNameDot),
|
||||
replace('/',
|
||||
'.',
|
||||
RUNTIME_ARRAY_BODY(classNameDot),
|
||||
reinterpret_cast<char*>(classNameSlash->body().begin()));
|
||||
throwNew(t, GcCloneNotSupportedException::Type, "%s",
|
||||
throwNew(t,
|
||||
GcCloneNotSupportedException::Type,
|
||||
"%s",
|
||||
RUNTIME_ARRAY_BODY(classNameDot));
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
GcStackTraceElement*
|
||||
makeStackTraceElement(Thread* t, GcTraceElement* e)
|
||||
GcStackTraceElement* makeStackTraceElement(Thread* t, GcTraceElement* e)
|
||||
{
|
||||
PROTECT(t, e);
|
||||
|
||||
@ -289,7 +289,9 @@ makeStackTraceElement(Thread* t, GcTraceElement* e)
|
||||
PROTECT(t, class_name);
|
||||
|
||||
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()));
|
||||
GcString* class_name_string = makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
|
||||
PROTECT(t, class_name_string);
|
||||
@ -297,22 +299,21 @@ makeStackTraceElement(Thread* t, GcTraceElement* e)
|
||||
GcByteArray* method_name = method->name();
|
||||
PROTECT(t, method_name);
|
||||
|
||||
GcString* method_name_string = t->m->classpath->makeString
|
||||
(t, method_name, 0, method_name->length() - 1);
|
||||
GcString* method_name_string = t->m->classpath->makeString(
|
||||
t, method_name, 0, method_name->length() - 1);
|
||||
PROTECT(t, method_name_string);
|
||||
|
||||
unsigned line = t->m->processor->lineNumber
|
||||
(t, method, e->ip());
|
||||
unsigned line = t->m->processor->lineNumber(t, method, e->ip());
|
||||
|
||||
GcByteArray* file = method->class_()->sourceFile();
|
||||
GcString* file_string = file ? t->m->classpath->makeString
|
||||
(t, file, 0, file->length() - 1) : 0;
|
||||
GcString* file_string
|
||||
= 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*
|
||||
translateInvokeResult(Thread* t, unsigned returnCode, object o)
|
||||
GcObject* translateInvokeResult(Thread* t, unsigned returnCode, object o)
|
||||
{
|
||||
switch (returnCode) {
|
||||
case ByteField:
|
||||
@ -344,9 +345,10 @@ translateInvokeResult(Thread* t, unsigned returnCode, object o)
|
||||
}
|
||||
}
|
||||
|
||||
GcClass*
|
||||
resolveClassBySpec(Thread* t, GcClassLoader* loader, const char* spec,
|
||||
unsigned specLength)
|
||||
GcClass* resolveClassBySpec(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
const char* spec,
|
||||
unsigned specLength)
|
||||
{
|
||||
switch (*spec) {
|
||||
case 'L': {
|
||||
@ -368,15 +370,19 @@ resolveClassBySpec(Thread* t, GcClassLoader* loader, const char* spec,
|
||||
}
|
||||
}
|
||||
|
||||
GcJclass*
|
||||
resolveJType(Thread* t, GcClassLoader* loader, const char* spec, unsigned specLength)
|
||||
GcJclass* resolveJType(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
const char* spec,
|
||||
unsigned specLength)
|
||||
{
|
||||
return getJClass(t, resolveClassBySpec(t, loader, spec, specLength));
|
||||
}
|
||||
|
||||
GcPair*
|
||||
resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
unsigned* parameterCount, unsigned* returnTypeSpec)
|
||||
GcPair* resolveParameterTypes(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
GcByteArray* spec,
|
||||
unsigned* parameterCount,
|
||||
unsigned* returnTypeSpec)
|
||||
{
|
||||
PROTECT(t, loader);
|
||||
PROTECT(t, spec);
|
||||
@ -391,12 +397,15 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
case 'L': {
|
||||
unsigned start = offset;
|
||||
++ offset;
|
||||
while (spec->body()[offset] != ';') ++ offset;
|
||||
while (spec->body()[offset] != ';')
|
||||
++offset;
|
||||
++ offset;
|
||||
|
||||
GcClass* type = resolveClassBySpec
|
||||
(t, loader, reinterpret_cast<char*>(&spec->body()[start]),
|
||||
offset - start);
|
||||
GcClass* type
|
||||
= resolveClassBySpec(t,
|
||||
loader,
|
||||
reinterpret_cast<char*>(&spec->body()[start]),
|
||||
offset - start);
|
||||
|
||||
list = makePair(t, type, list);
|
||||
|
||||
@ -405,11 +414,13 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
|
||||
case '[': {
|
||||
unsigned start = offset;
|
||||
while (spec->body()[offset] == '[') ++ offset;
|
||||
while (spec->body()[offset] == '[')
|
||||
++offset;
|
||||
switch (spec->body()[offset]) {
|
||||
case 'L':
|
||||
++ offset;
|
||||
while (spec->body()[offset] != ';') ++ offset;
|
||||
while (spec->body()[offset] != ';')
|
||||
++offset;
|
||||
++ offset;
|
||||
break;
|
||||
|
||||
@ -418,17 +429,18 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
break;
|
||||
}
|
||||
|
||||
GcClass* type = resolveClassBySpec
|
||||
(t, loader, reinterpret_cast<char*>(&spec->body()[start]),
|
||||
offset - start);
|
||||
GcClass* type
|
||||
= resolveClassBySpec(t,
|
||||
loader,
|
||||
reinterpret_cast<char*>(&spec->body()[start]),
|
||||
offset - start);
|
||||
|
||||
list = makePair(t, type, list);
|
||||
++ count;
|
||||
} break;
|
||||
|
||||
default:
|
||||
list = makePair
|
||||
(t, primitiveClass(t, spec->body()[offset]), list);
|
||||
list = makePair(t, primitiveClass(t, spec->body()[offset]), list);
|
||||
++ offset;
|
||||
++ count;
|
||||
break;
|
||||
@ -440,17 +452,18 @@ resolveParameterTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
return list;
|
||||
}
|
||||
|
||||
object
|
||||
resolveParameterJTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
unsigned* parameterCount, unsigned* returnTypeSpec)
|
||||
object resolveParameterJTypes(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
GcByteArray* spec,
|
||||
unsigned* parameterCount,
|
||||
unsigned* returnTypeSpec)
|
||||
{
|
||||
GcPair* list = resolveParameterTypes
|
||||
(t, loader, spec, parameterCount, returnTypeSpec);
|
||||
GcPair* list
|
||||
= resolveParameterTypes(t, loader, spec, parameterCount, returnTypeSpec);
|
||||
|
||||
PROTECT(t, list);
|
||||
|
||||
object array = makeObjectArray
|
||||
(t, type(t, GcJclass::Type), *parameterCount);
|
||||
object array = makeObjectArray(t, type(t, GcJclass::Type), *parameterCount);
|
||||
PROTECT(t, array);
|
||||
|
||||
for (int i = *parameterCount - 1; i >= 0; --i) {
|
||||
@ -462,8 +475,9 @@ resolveParameterJTypes(Thread* t, GcClassLoader* loader, GcByteArray* spec,
|
||||
return array;
|
||||
}
|
||||
|
||||
object
|
||||
resolveExceptionJTypes(Thread* t, GcClassLoader* loader, GcMethodAddendum* addendum)
|
||||
object resolveExceptionJTypes(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
GcMethodAddendum* addendum)
|
||||
{
|
||||
if (addendum == 0 or addendum->exceptionTable() == 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, addendum);
|
||||
|
||||
GcShortArray* exceptionTable = cast<GcShortArray>(t, addendum->exceptionTable());
|
||||
GcShortArray* exceptionTable
|
||||
= cast<GcShortArray>(t, addendum->exceptionTable());
|
||||
PROTECT(t, exceptionTable);
|
||||
|
||||
object array = makeObjectArray
|
||||
(t, type(t, GcJclass::Type),
|
||||
exceptionTable->length());
|
||||
object array
|
||||
= makeObjectArray(t, type(t, GcJclass::Type), exceptionTable->length());
|
||||
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;
|
||||
|
||||
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)) {
|
||||
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));
|
||||
@ -500,8 +514,7 @@ resolveExceptionJTypes(Thread* t, GcClassLoader* loader, GcMethodAddendum* adden
|
||||
return array;
|
||||
}
|
||||
|
||||
object
|
||||
invoke(Thread* t, GcMethod* method, object instance, object args)
|
||||
object invoke(Thread* t, GcMethod* method, object instance, object args)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
PROTECT(t, instance);
|
||||
@ -512,30 +525,45 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
|
||||
}
|
||||
|
||||
if ((args == 0 ? 0 : objectArrayLength(t, args))
|
||||
!= method->parameterCount())
|
||||
{
|
||||
!= method->parameterCount()) {
|
||||
throwNew(t, GcIllegalArgumentException::Type);
|
||||
}
|
||||
|
||||
if (method->parameterCount()) {
|
||||
unsigned specLength = method->spec()->length();
|
||||
THREAD_RUNTIME_ARRAY(t, char, spec, specLength);
|
||||
memcpy(RUNTIME_ARRAY_BODY(spec),
|
||||
method->spec()->body().begin(), specLength);
|
||||
memcpy(
|
||||
RUNTIME_ARRAY_BODY(spec), method->spec()->body().begin(), specLength);
|
||||
unsigned i = 0;
|
||||
for (MethodSpecIterator it(t, RUNTIME_ARRAY_BODY(spec)); it.hasNext();) {
|
||||
GcClass* type;
|
||||
bool objectType = false;
|
||||
const char* p = it.next();
|
||||
switch (*p) {
|
||||
case 'Z': type = vm::type(t, GcBoolean::Type); break;
|
||||
case 'B': type = vm::type(t, GcByte::Type); break;
|
||||
case 'S': 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 'Z':
|
||||
type = vm::type(t, GcBoolean::Type);
|
||||
break;
|
||||
case 'B':
|
||||
type = vm::type(t, GcByte::Type);
|
||||
break;
|
||||
case 'S':
|
||||
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 '[': {
|
||||
@ -550,9 +578,8 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
|
||||
THREAD_RUNTIME_ARRAY(t, char, name, nameLength);
|
||||
memcpy(RUNTIME_ARRAY_BODY(name), p, nameLength - 1);
|
||||
RUNTIME_ARRAY_BODY(name)[nameLength - 1] = 0;
|
||||
type = resolveClass
|
||||
(t, method->class_()->loader(),
|
||||
RUNTIME_ARRAY_BODY(name));
|
||||
type = resolveClass(
|
||||
t, method->class_()->loader(), RUNTIME_ARRAY_BODY(name));
|
||||
} break;
|
||||
|
||||
default:
|
||||
@ -576,10 +603,11 @@ invoke(Thread* t, GcMethod* method, object instance, object args)
|
||||
|
||||
THREAD_RESOURCE0(t, {
|
||||
if (t->exception) {
|
||||
t->exception = makeThrowable
|
||||
(t, GcInvocationTargetException::Type, 0, 0, t->exception);
|
||||
t->exception = makeThrowable(
|
||||
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
|
||||
// running:
|
||||
void
|
||||
intercept(Thread* t, GcClass* c, const char* name, const char* spec,
|
||||
void* function, bool updateRuntimeData)
|
||||
void intercept(Thread* t,
|
||||
GcClass* c,
|
||||
const char* name,
|
||||
const char* spec,
|
||||
void* function,
|
||||
bool updateRuntimeData)
|
||||
{
|
||||
GcMethod* m = findMethodOrNull(t, c, name, spec);
|
||||
if (m) {
|
||||
@ -638,14 +669,11 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
|
||||
{
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
for (GcFinder* p = roots(t)->virtualFileFinders();
|
||||
p; p = p->next())
|
||||
{
|
||||
for (GcFinder* p = roots(t)->virtualFileFinders(); p; p = p->next()) {
|
||||
if (p->name()->length() == nameLength
|
||||
and strncmp(reinterpret_cast<const char*>
|
||||
(p->name()->body().begin()),
|
||||
name, nameLength))
|
||||
{
|
||||
and strncmp(reinterpret_cast<const char*>(p->name()->body().begin()),
|
||||
name,
|
||||
nameLength)) {
|
||||
return static_cast<Finder*>(p->finder());
|
||||
}
|
||||
}
|
||||
@ -653,8 +681,8 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
|
||||
GcByteArray* n = makeByteArray(t, nameLength + 1);
|
||||
memcpy(n->body().begin(), name, nameLength);
|
||||
|
||||
void* p = t->m->libraries->resolve
|
||||
(reinterpret_cast<const char*>(n->body().begin()));
|
||||
void* p = t->m->libraries->resolve(
|
||||
reinterpret_cast<const char*>(n->body().begin()));
|
||||
|
||||
if (p) {
|
||||
uint8_t* (*function)(unsigned*);
|
||||
@ -664,8 +692,7 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
|
||||
uint8_t* data = function(&size);
|
||||
if (data) {
|
||||
Finder* f = makeFinder(t->m->system, t->m->heap, data, size);
|
||||
GcFinder* finder = makeFinder
|
||||
(t, f, n, roots(t)->virtualFileFinders());
|
||||
GcFinder* finder = makeFinder(t, f, n, roots(t)->virtualFileFinders());
|
||||
|
||||
roots(t)->setVirtualFileFinders(t, finder);
|
||||
|
||||
@ -676,8 +703,7 @@ getFinder(Thread* t, const char* name, unsigned nameLength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
object
|
||||
getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
|
||||
object getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
|
||||
{
|
||||
GcClassAddendum* addendum = c->addendum();
|
||||
if (addendum) {
|
||||
@ -687,12 +713,11 @@ getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
|
||||
|
||||
unsigned count = 0;
|
||||
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();
|
||||
if (outer and byteArrayEqual(t, outer, c->name())
|
||||
and ((not publicOnly)
|
||||
or (reference->flags() & ACC_PUBLIC)))
|
||||
{
|
||||
and ((not publicOnly) or (reference->flags() & ACC_PUBLIC))) {
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
@ -701,18 +726,13 @@ getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
|
||||
PROTECT(t, result);
|
||||
|
||||
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();
|
||||
if (outer and byteArrayEqual(t, outer, c->name())
|
||||
and ((not publicOnly)
|
||||
or (reference->flags() & ACC_PUBLIC)))
|
||||
{
|
||||
object inner = getJClass(
|
||||
t,
|
||||
resolveClass(
|
||||
t,
|
||||
c->loader(),
|
||||
reference->inner()));
|
||||
and ((not publicOnly) or (reference->flags() & ACC_PUBLIC))) {
|
||||
object inner
|
||||
= getJClass(t, resolveClass(t, c->loader(), reference->inner()));
|
||||
|
||||
-- count;
|
||||
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);
|
||||
}
|
||||
|
||||
GcJclass*
|
||||
getDeclaringClass(Thread* t, GcClass* c)
|
||||
GcJclass* getDeclaringClass(Thread* t, GcClass* c)
|
||||
{
|
||||
GcClassAddendum* addendum = c->addendum();
|
||||
if (addendum) {
|
||||
GcArray* table = cast<GcArray>(t, addendum->innerClassTable());
|
||||
if (table) {
|
||||
for (unsigned i = 0; i < table->length(); ++i) {
|
||||
GcInnerClassReference* reference = cast<GcInnerClassReference>(t, table->body()[i]);
|
||||
if (reference->outer() and strcmp
|
||||
(reference->inner()->body().begin(),
|
||||
c->name()->body().begin()) == 0)
|
||||
{
|
||||
return getJClass(
|
||||
t,
|
||||
resolveClass(t,
|
||||
c->loader(),
|
||||
reference->outer()));
|
||||
GcInnerClassReference* reference
|
||||
= cast<GcInnerClassReference>(t, table->body()[i]);
|
||||
if (reference->outer()
|
||||
and strcmp(reference->inner()->body().begin(),
|
||||
c->name()->body().begin()) == 0) {
|
||||
return getJClass(t, resolveClass(t, c->loader(), reference->outer()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -752,19 +767,17 @@ getDeclaringClass(Thread* t, GcClass* c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
classModifiers(Thread* t, GcClass* c)
|
||||
unsigned classModifiers(Thread* t, GcClass* c)
|
||||
{
|
||||
GcClassAddendum* addendum = c->addendum();
|
||||
if (addendum) {
|
||||
GcArray* table = cast<GcArray>(t, addendum->innerClassTable());
|
||||
if (table) {
|
||||
for (unsigned i = 0; i < table->length(); ++i) {
|
||||
GcInnerClassReference* reference = cast<GcInnerClassReference>(t, table->body()[i]);
|
||||
if (0 == strcmp
|
||||
(c->name()->body().begin(),
|
||||
reference->inner()->body().begin()))
|
||||
{
|
||||
GcInnerClassReference* reference
|
||||
= cast<GcInnerClassReference>(t, table->body()[i]);
|
||||
if (0 == strcmp(c->name()->body().begin(),
|
||||
reference->inner()->body().begin())) {
|
||||
return reference->flags();
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ namespace vm {
|
||||
class Machine;
|
||||
class Thread;
|
||||
|
||||
class GcObject;;
|
||||
class GcObject;
|
||||
;
|
||||
|
||||
typedef GcObject* object;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,16 +18,14 @@
|
||||
|
||||
namespace vm {
|
||||
|
||||
inline int16_t
|
||||
codeReadInt16(Thread* t UNUSED, GcCode* code, unsigned& ip)
|
||||
inline int16_t codeReadInt16(Thread* t UNUSED, GcCode* code, unsigned& ip)
|
||||
{
|
||||
uint8_t v1 = code->body()[ip++];
|
||||
uint8_t v2 = code->body()[ip++];
|
||||
return ((v1 << 8) | v2);
|
||||
}
|
||||
|
||||
inline int32_t
|
||||
codeReadInt32(Thread* t UNUSED, GcCode* code, unsigned& ip)
|
||||
inline int32_t codeReadInt32(Thread* t UNUSED, GcCode* code, unsigned& ip)
|
||||
{
|
||||
uint8_t v1 = 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);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isSuperclass(Thread* t UNUSED, GcClass* class_, GcClass* base)
|
||||
inline bool isSuperclass(Thread* t UNUSED, GcClass* class_, GcClass* base)
|
||||
{
|
||||
for (GcClass* oc = base->super(); oc; oc = oc->super()) {
|
||||
if (oc == class_) {
|
||||
@ -47,20 +44,17 @@ isSuperclass(Thread* t UNUSED, GcClass* class_, GcClass* base)
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isSpecialMethod(Thread* t, GcMethod* method, GcClass* class_)
|
||||
inline bool isSpecialMethod(Thread* t, GcMethod* method, GcClass* class_)
|
||||
{
|
||||
return (class_->flags() & ACC_SUPER)
|
||||
and strcmp(reinterpret_cast<const int8_t*>("<init>"),
|
||||
method->name()->body().begin()) != 0
|
||||
and isSuperclass(t, method->class_(), class_);
|
||||
and strcmp(reinterpret_cast<const int8_t*>("<init>"),
|
||||
method->name()->body().begin()) != 0
|
||||
and isSuperclass(t, method->class_(), class_);
|
||||
}
|
||||
|
||||
void
|
||||
resolveNative(Thread* t, GcMethod* method);
|
||||
void resolveNative(Thread* t, GcMethod* method);
|
||||
|
||||
int
|
||||
findLineNumber(Thread* t, GcMethod* method, unsigned ip);
|
||||
int findLineNumber(Thread* t, GcMethod* method, unsigned ip);
|
||||
|
||||
} // namespace vm
|
||||
|
||||
|
@ -74,46 +74,43 @@ class Processor {
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
||||
virtual Thread*
|
||||
makeThread(Machine* m, GcThread* javaThread, Thread* parent) = 0;
|
||||
virtual Thread* makeThread(Machine* m, GcThread* javaThread, Thread* parent)
|
||||
= 0;
|
||||
|
||||
virtual GcMethod*
|
||||
makeMethod(Thread* t,
|
||||
uint8_t vmFlags,
|
||||
uint8_t returnCode,
|
||||
uint8_t parameterCount,
|
||||
uint8_t parameterFootprint,
|
||||
uint16_t flags,
|
||||
uint16_t offset,
|
||||
GcByteArray* name,
|
||||
GcByteArray* spec,
|
||||
GcMethodAddendum* addendum,
|
||||
GcClass* class_,
|
||||
GcCode* code) = 0;
|
||||
virtual GcMethod* makeMethod(Thread* t,
|
||||
uint8_t vmFlags,
|
||||
uint8_t returnCode,
|
||||
uint8_t parameterCount,
|
||||
uint8_t parameterFootprint,
|
||||
uint16_t flags,
|
||||
uint16_t offset,
|
||||
GcByteArray* name,
|
||||
GcByteArray* spec,
|
||||
GcMethodAddendum* addendum,
|
||||
GcClass* class_,
|
||||
GcCode* code) = 0;
|
||||
|
||||
virtual GcClass*
|
||||
makeClass(Thread* t,
|
||||
uint16_t flags,
|
||||
uint16_t vmFlags,
|
||||
uint16_t fixedSize,
|
||||
uint8_t arrayElementSize,
|
||||
uint8_t arrayDimensions,
|
||||
GcClass* arrayElementClass,
|
||||
GcIntArray* objectMask,
|
||||
GcByteArray* name,
|
||||
GcByteArray* sourceFile,
|
||||
GcClass* super,
|
||||
object interfaceTable,
|
||||
object virtualTable,
|
||||
object fieldTable,
|
||||
object methodTable,
|
||||
GcClassAddendum* addendum,
|
||||
GcSingleton* staticTable,
|
||||
GcClassLoader* loader,
|
||||
unsigned vtableLength) = 0;
|
||||
virtual GcClass* makeClass(Thread* t,
|
||||
uint16_t flags,
|
||||
uint16_t vmFlags,
|
||||
uint16_t fixedSize,
|
||||
uint8_t arrayElementSize,
|
||||
uint8_t arrayDimensions,
|
||||
GcClass* arrayElementClass,
|
||||
GcIntArray* objectMask,
|
||||
GcByteArray* name,
|
||||
GcByteArray* sourceFile,
|
||||
GcClass* super,
|
||||
object interfaceTable,
|
||||
object virtualTable,
|
||||
object fieldTable,
|
||||
object methodTable,
|
||||
GcClassAddendum* addendum,
|
||||
GcSingleton* staticTable,
|
||||
GcClassLoader* loader,
|
||||
unsigned vtableLength) = 0;
|
||||
|
||||
virtual void
|
||||
initVtable(Thread* t, GcClass* c) = 0;
|
||||
virtual void initVtable(Thread* t, GcClass* c) = 0;
|
||||
|
||||
virtual void
|
||||
visitObjects(Thread* t, Heap::Visitor* v) = 0;
|
||||
@ -121,8 +118,7 @@ class Processor {
|
||||
virtual void
|
||||
walkStack(Thread* t, StackVisitor* v) = 0;
|
||||
|
||||
virtual int
|
||||
lineNumber(Thread* t, GcMethod* method, int ip) = 0;
|
||||
virtual int lineNumber(Thread* t, GcMethod* method, int ip) = 0;
|
||||
|
||||
virtual object*
|
||||
makeLocalReference(Thread* t, object o) = 0;
|
||||
@ -136,21 +132,29 @@ class Processor {
|
||||
virtual void
|
||||
popLocalFrame(Thread* t) = 0;
|
||||
|
||||
virtual object
|
||||
invokeArray(Thread* t, GcMethod* method, object this_, object arguments) = 0;
|
||||
virtual object invokeArray(Thread* t,
|
||||
GcMethod* method,
|
||||
object this_,
|
||||
object arguments) = 0;
|
||||
|
||||
virtual object
|
||||
invokeArray(Thread* t, GcMethod* method, object this_, const jvalue* arguments)
|
||||
= 0;
|
||||
virtual object invokeArray(Thread* t,
|
||||
GcMethod* method,
|
||||
object this_,
|
||||
const jvalue* arguments) = 0;
|
||||
|
||||
virtual object
|
||||
invokeList(Thread* t, GcMethod* method, object this_, bool indirectObjects,
|
||||
va_list arguments) = 0;
|
||||
virtual object invokeList(Thread* t,
|
||||
GcMethod* method,
|
||||
object this_,
|
||||
bool indirectObjects,
|
||||
va_list arguments) = 0;
|
||||
|
||||
virtual object
|
||||
invokeList(Thread* t, GcClassLoader* loader, const char* className,
|
||||
const char* methodName, const char* methodSpec,
|
||||
object this_, va_list arguments) = 0;
|
||||
virtual object invokeList(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
const char* className,
|
||||
const char* methodName,
|
||||
const char* methodSpec,
|
||||
object this_,
|
||||
va_list arguments) = 0;
|
||||
|
||||
virtual void
|
||||
dispose(Thread* t) = 0;
|
||||
@ -167,10 +171,13 @@ class Processor {
|
||||
virtual void
|
||||
addCompilationHandler(CompilationHandler* handler) = 0;
|
||||
|
||||
virtual void
|
||||
compileMethod(Thread* t, Zone* zone, GcTriple** constants, GcTriple** calls,
|
||||
avian::codegen::DelayedPromise** addresses, GcMethod* method,
|
||||
OffsetResolver* resolver) = 0;
|
||||
virtual void compileMethod(Thread* t,
|
||||
Zone* zone,
|
||||
GcTriple** constants,
|
||||
GcTriple** calls,
|
||||
avian::codegen::DelayedPromise** addresses,
|
||||
GcMethod* method,
|
||||
OffsetResolver* resolver) = 0;
|
||||
|
||||
virtual void
|
||||
visitRoots(Thread* t, HeapWalker* w) = 0;
|
||||
@ -190,19 +197,19 @@ class Processor {
|
||||
virtual void
|
||||
dynamicWind(Thread* t, object before, object thunk, object after) = 0;
|
||||
|
||||
virtual void
|
||||
feedResultToContinuation(Thread* t, GcContinuation* continuation, object result) = 0;
|
||||
virtual void feedResultToContinuation(Thread* t,
|
||||
GcContinuation* continuation,
|
||||
object result) = 0;
|
||||
|
||||
virtual void
|
||||
feedExceptionToContinuation(Thread* t, GcContinuation* continuation,
|
||||
GcThrowable* exception) = 0;
|
||||
virtual void feedExceptionToContinuation(Thread* t,
|
||||
GcContinuation* continuation,
|
||||
GcThrowable* exception) = 0;
|
||||
|
||||
virtual void
|
||||
walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start)
|
||||
= 0;
|
||||
|
||||
object
|
||||
invoke(Thread* t, GcMethod* method, object this_, ...)
|
||||
object invoke(Thread* t, GcMethod* method, object this_, ...)
|
||||
{
|
||||
va_list a;
|
||||
va_start(a, this_);
|
||||
@ -214,9 +221,13 @@ class Processor {
|
||||
return r;
|
||||
}
|
||||
|
||||
object
|
||||
invoke(Thread* t, GcClassLoader* loader, const char* className,
|
||||
const char* methodName, const char* methodSpec, object this_, ...)
|
||||
object invoke(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
const char* className,
|
||||
const char* methodName,
|
||||
const char* methodSpec,
|
||||
object this_,
|
||||
...)
|
||||
{
|
||||
va_list a;
|
||||
va_start(a, this_);
|
||||
|
106
src/avian/util.h
106
src/avian/util.h
@ -16,32 +16,39 @@
|
||||
|
||||
namespace vm {
|
||||
|
||||
GcTriple*
|
||||
hashMapFindNode(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object));
|
||||
GcTriple* hashMapFindNode(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object));
|
||||
|
||||
inline object
|
||||
hashMapFind(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
inline object hashMapFind(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
|
||||
return (n ? n->second() : 0);
|
||||
}
|
||||
|
||||
void
|
||||
hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
|
||||
unsigned size);
|
||||
void hashMapResize(Thread* t,
|
||||
GcHashMap* map,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
unsigned size);
|
||||
|
||||
void
|
||||
hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
|
||||
uint32_t (*hash)(Thread*, object));
|
||||
void hashMapInsert(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
object value,
|
||||
uint32_t (*hash)(Thread*, object));
|
||||
|
||||
inline bool
|
||||
hashMapInsertOrReplace(Thread* t, GcHashMap* map, object key, object value,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
inline bool hashMapInsertOrReplace(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
object value,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
|
||||
if (n == 0) {
|
||||
@ -53,10 +60,12 @@ hashMapInsertOrReplace(Thread* t, GcHashMap* map, object key, object value,
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
hashMapInsertMaybe(Thread* t, GcHashMap* map, object key, object value,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
inline bool hashMapInsertMaybe(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
object value,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
GcTriple* n = hashMapFindNode(t, map, key, hash, equal);
|
||||
if (n == 0) {
|
||||
@ -67,43 +76,49 @@ hashMapInsertMaybe(Thread* t, GcHashMap* map, object key, object value,
|
||||
}
|
||||
}
|
||||
|
||||
object
|
||||
hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object));
|
||||
object hashMapRemove(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object));
|
||||
|
||||
object
|
||||
hashMapIterator(Thread* t, GcHashMap* map);
|
||||
object hashMapIterator(Thread* t, GcHashMap* map);
|
||||
|
||||
object
|
||||
hashMapIteratorNext(Thread* t, object it);
|
||||
|
||||
void
|
||||
listAppend(Thread* t, GcList* list, object value);
|
||||
void listAppend(Thread* t, GcList* list, object value);
|
||||
|
||||
GcVector*
|
||||
vectorAppend(Thread* t, GcVector* vector, object value);
|
||||
GcVector* vectorAppend(Thread* t, GcVector* vector, object value);
|
||||
|
||||
object
|
||||
growArray(Thread* t, object array);
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
object treeQuery(Thread* t,
|
||||
GcTreeNode* tree,
|
||||
intptr_t key,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
|
||||
GcTreeNode*
|
||||
treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
GcTreeNode* treeInsert(Thread* t,
|
||||
Zone* zone,
|
||||
GcTreeNode* tree,
|
||||
intptr_t key,
|
||||
object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
|
||||
void
|
||||
treeUpdate(Thread* t, GcTreeNode* tree, intptr_t key, object value, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
void treeUpdate(Thread* t,
|
||||
GcTreeNode* tree,
|
||||
intptr_t key,
|
||||
object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b));
|
||||
|
||||
class HashMapIterator: public Thread::Protector {
|
||||
public:
|
||||
HashMapIterator(Thread* t, GcHashMap* map):
|
||||
Protector(t), map(map), node(0), index(0)
|
||||
HashMapIterator(Thread* t, GcHashMap* map)
|
||||
: Protector(t), map(map), node(0), index(0)
|
||||
{
|
||||
find();
|
||||
}
|
||||
@ -126,7 +141,8 @@ class HashMapIterator: public Thread::Protector {
|
||||
return node != 0;
|
||||
}
|
||||
|
||||
GcTriple* next() {
|
||||
GcTriple* next()
|
||||
{
|
||||
if (node) {
|
||||
GcTriple* n = node;
|
||||
if (node->third()) {
|
||||
|
170
src/builtin.cpp
170
src/builtin.cpp
@ -19,9 +19,11 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
int64_t
|
||||
search(Thread* t, GcClassLoader* loader, GcString* name,
|
||||
GcClass* (*op)(Thread*, GcClassLoader*, GcByteArray*), bool replaceDots)
|
||||
int64_t search(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
GcString* name,
|
||||
GcClass* (*op)(Thread*, GcClassLoader*, GcByteArray*),
|
||||
bool replaceDots)
|
||||
{
|
||||
if (LIKELY(name)) {
|
||||
PROTECT(t, loader);
|
||||
@ -41,15 +43,15 @@ search(Thread* t, GcClassLoader* loader, GcString* name,
|
||||
}
|
||||
}
|
||||
|
||||
GcClass*
|
||||
resolveSystemClassThrow(Thread* t, GcClassLoader* loader, GcByteArray* spec)
|
||||
GcClass* resolveSystemClassThrow(Thread* t,
|
||||
GcClassLoader* loader,
|
||||
GcByteArray* spec)
|
||||
{
|
||||
return resolveSystemClass
|
||||
(t, loader, spec, true, GcClassNotFoundException::Type);
|
||||
return resolveSystemClass(
|
||||
t, loader, spec, true, GcClassNotFoundException::Type);
|
||||
}
|
||||
|
||||
GcField*
|
||||
fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
|
||||
GcField* fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
|
||||
{
|
||||
GcClass* super = c->super();
|
||||
if (super) {
|
||||
@ -63,9 +65,7 @@ fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
|
||||
if (table) {
|
||||
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
|
||||
GcField* field = cast<GcField>(t, objectArrayBody(t, table, i));
|
||||
if ((field->flags() & ACC_STATIC) == 0
|
||||
and field->offset() == offset)
|
||||
{
|
||||
if ((field->flags() & ACC_STATIC) == 0 and field->offset() == offset) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
@ -74,8 +74,7 @@ fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GcField*
|
||||
fieldForOffset(Thread* t, GcSingleton* o, unsigned offset)
|
||||
GcField* fieldForOffset(Thread* t, GcSingleton* o, unsigned offset)
|
||||
{
|
||||
GcClass* c = objectClass(t, o);
|
||||
if (c->vmFlags() & SingletonFlag) {
|
||||
@ -84,9 +83,7 @@ fieldForOffset(Thread* t, GcSingleton* o, unsigned offset)
|
||||
if (table) {
|
||||
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
|
||||
GcField* field = cast<GcField>(t, objectArrayBody(t, table, i));
|
||||
if ((field->flags() & ACC_STATIC)
|
||||
and field->offset() == offset)
|
||||
{
|
||||
if ((field->flags() & ACC_STATIC) and field->offset() == offset) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
@ -131,18 +128,21 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_Classes_resolveVMClass
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
GcClassLoader* loader = cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
|
||||
GcByteArray* spec = cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
|
||||
GcClassLoader* loader
|
||||
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
|
||||
GcByteArray* spec
|
||||
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
|
||||
|
||||
return reinterpret_cast<int64_t>
|
||||
(resolveClass(t, loader, spec, true, GcClassNotFoundException::Type));
|
||||
return reinterpret_cast<int64_t>(
|
||||
resolveClass(t, loader, spec, true, GcClassNotFoundException::Type));
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_Classes_defineVMClass
|
||||
(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]));
|
||||
int offset = arguments[2];
|
||||
int length = arguments[3];
|
||||
@ -162,7 +162,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_findLoadedVMClass
|
||||
(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]));
|
||||
|
||||
return search(t, loader, name, findLoadedClass, true);
|
||||
@ -172,15 +173,16 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_vmClass
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
return reinterpret_cast<int64_t>
|
||||
(cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
|
||||
return reinterpret_cast<int64_t>(
|
||||
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_findVMClass
|
||||
(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]));
|
||||
|
||||
return search(t, loader, name, resolveSystemClassThrow, true);
|
||||
@ -190,15 +192,17 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_resourceURLPrefix
|
||||
(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]));
|
||||
|
||||
if (LIKELY(name)) {
|
||||
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
|
||||
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
||||
|
||||
const char* name = static_cast<Finder*>
|
||||
(loader->as<GcSystemClassLoader>(t)->finder())->urlPrefix(RUNTIME_ARRAY_BODY(n));
|
||||
const char* name
|
||||
= static_cast<Finder*>(loader->as<GcSystemClassLoader>(t)->finder())
|
||||
->urlPrefix(RUNTIME_ARRAY_BODY(n));
|
||||
|
||||
return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0;
|
||||
} else {
|
||||
@ -210,18 +214,21 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_00024ResourceEnumeration_nextResourceURLPrefix
|
||||
(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]));
|
||||
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)) {
|
||||
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
|
||||
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
||||
|
||||
void *&finderElementPtr = reinterpret_cast<void *&>(finderElementPtrPtr->body()[0]);
|
||||
const char* name = static_cast<Finder*>
|
||||
(loader->as<GcSystemClassLoader>(t)->finder())->nextUrlPrefix(RUNTIME_ARRAY_BODY(n),
|
||||
finderElementPtr);
|
||||
void*& finderElementPtr
|
||||
= reinterpret_cast<void*&>(finderElementPtrPtr->body()[0]);
|
||||
const char* name
|
||||
= 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;
|
||||
} else {
|
||||
@ -233,8 +240,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_getClass
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
return reinterpret_cast<int64_t>
|
||||
(getJClass(t, cast<GcClass>(t, reinterpret_cast<object>(arguments[0]))));
|
||||
return reinterpret_cast<int64_t>(
|
||||
getJClass(t, cast<GcClass>(t, reinterpret_cast<object>(arguments[0]))));
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
@ -254,14 +261,14 @@ Avian_avian_SystemClassLoader_getPackageSource
|
||||
|
||||
GcByteArray* key = makeByteArray(t, RUNTIME_ARRAY_BODY(chars));
|
||||
|
||||
GcByteArray* array = cast<GcByteArray>(t, hashMapFind
|
||||
(t, roots(t)->packageMap(), key, byteArrayHash, byteArrayEqual));
|
||||
GcByteArray* array = cast<GcByteArray>(
|
||||
t,
|
||||
hashMapFind(
|
||||
t, roots(t)->packageMap(), key, byteArrayHash, byteArrayEqual));
|
||||
|
||||
if (array) {
|
||||
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
||||
t,
|
||||
t->m->classpath->makeString(
|
||||
t, array, 0, array->length())));
|
||||
t, t->m->classpath->makeString(t, array, 0, array->length())));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@ -285,7 +292,9 @@ Avian_avian_Machine_dumpHeap
|
||||
}
|
||||
fclose(out);
|
||||
} else {
|
||||
throwNew(t, GcRuntimeException::Type, "file not found: %s",
|
||||
throwNew(t,
|
||||
GcRuntimeException::Type,
|
||||
"file not found: %s",
|
||||
RUNTIME_ARRAY_BODY(n));
|
||||
}
|
||||
}
|
||||
@ -392,7 +401,8 @@ Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI_3BII
|
||||
{
|
||||
int64_t peer; memcpy(&peer, arguments, 8);
|
||||
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 length = arguments[5];
|
||||
|
||||
@ -405,8 +415,7 @@ Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI_3BII
|
||||
if (length <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(&buffer->body()[offset], region->start() + position,
|
||||
length);
|
||||
memcpy(&buffer->body()[offset], region->start() + position, length);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
@ -445,9 +454,10 @@ extern "C" AVIAN_EXPORT void JNICALL
|
||||
Avian_avian_Continuations_00024Continuation_handleResult
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
t->m->processor->feedResultToContinuation
|
||||
(t, cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
|
||||
reinterpret_cast<object>(arguments[1]));
|
||||
t->m->processor->feedResultToContinuation(
|
||||
t,
|
||||
cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
|
||||
reinterpret_cast<object>(arguments[1]));
|
||||
|
||||
abort(t);
|
||||
}
|
||||
@ -456,9 +466,10 @@ extern "C" AVIAN_EXPORT void JNICALL
|
||||
Avian_avian_Continuations_00024Continuation_handleException
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
t->m->processor->feedExceptionToContinuation
|
||||
(t, cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
|
||||
cast<GcThrowable>(t, reinterpret_cast<object>(arguments[1])));
|
||||
t->m->processor->feedExceptionToContinuation(
|
||||
t,
|
||||
cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
|
||||
cast<GcThrowable>(t, reinterpret_cast<object>(arguments[1])));
|
||||
|
||||
abort(t);
|
||||
}
|
||||
@ -467,16 +478,20 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_Singleton_getObject
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
return reinterpret_cast<int64_t>
|
||||
(singletonObject(t, cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])), arguments[1]));
|
||||
return reinterpret_cast<int64_t>(singletonObject(
|
||||
t,
|
||||
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
|
||||
arguments[1]));
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_Singleton_getInt
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
return singletonValue
|
||||
(t, cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])), arguments[1]);
|
||||
return singletonValue(
|
||||
t,
|
||||
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
|
||||
arguments[1]);
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
@ -484,8 +499,12 @@ Avian_avian_Singleton_getLong
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
int64_t v;
|
||||
memcpy(&v, &singletonValue
|
||||
(t, cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])), arguments[1]), 8);
|
||||
memcpy(&v,
|
||||
&singletonValue(
|
||||
t,
|
||||
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
|
||||
arguments[1]),
|
||||
8);
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -710,19 +729,16 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_sun_misc_Unsafe_arrayIndexScale
|
||||
(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)
|
||||
|| c == type(t, GcByteArray::Type))
|
||||
if (c == type(t, GcBooleanArray::Type) || c == type(t, GcByteArray::Type))
|
||||
return 1;
|
||||
else if (c == type(t, GcShortArray::Type)
|
||||
|| c == type(t, GcCharArray::Type))
|
||||
else if (c == type(t, GcShortArray::Type) || c == type(t, GcCharArray::Type))
|
||||
return 2;
|
||||
else if (c == type(t, GcIntArray::Type)
|
||||
|| c == type(t, GcFloatArray::Type))
|
||||
else if (c == type(t, GcIntArray::Type) || c == type(t, GcFloatArray::Type))
|
||||
return 4;
|
||||
else if (c == type(t, GcLongArray::Type)
|
||||
|| c == type(t, GcDoubleArray::Type))
|
||||
else if (c == type(t, GcLongArray::Type) || c == type(t, GcDoubleArray::Type))
|
||||
return 8;
|
||||
else
|
||||
return BytesPerWord;
|
||||
@ -733,13 +749,15 @@ Avian_java_nio_FixedArrayByteBuffer_allocateFixed
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
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);
|
||||
|
||||
GcArray* array = reinterpret_cast<GcArray*>(allocate3
|
||||
(t, t->m->heap, Machine::FixedAllocation, ArrayBody + capacity, false));
|
||||
GcArray* array = reinterpret_cast<GcArray*>(allocate3(
|
||||
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;
|
||||
|
||||
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)));
|
||||
bool interrupted = false;
|
||||
while (time >= 0
|
||||
and (not (t->javaThread->unparked()
|
||||
or t->javaThread->interrupted()
|
||||
or (interrupted = monitorWait
|
||||
(t, cast<GcMonitor>(t, interruptLock(t, t->javaThread)), time)))))
|
||||
{
|
||||
and (not(t->javaThread->unparked() or t->javaThread->interrupted()
|
||||
or (interrupted = monitorWait(
|
||||
t,
|
||||
cast<GcMonitor>(t, interruptLock(t, t->javaThread)),
|
||||
time))))) {
|
||||
int64_t now = t->m->system->now();
|
||||
time -= now - then;
|
||||
then = now;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,20 +26,20 @@ class MyClasspath : public Classpath {
|
||||
allocator(allocator)
|
||||
{ }
|
||||
|
||||
virtual GcJclass*
|
||||
makeJclass(Thread* t, GcClass* class_)
|
||||
virtual GcJclass* makeJclass(Thread* t, GcClass* class_)
|
||||
{
|
||||
return vm::makeJclass(t, class_);
|
||||
}
|
||||
|
||||
virtual GcString*
|
||||
makeString(Thread* t, object array, int32_t offset, int32_t length)
|
||||
virtual GcString* makeString(Thread* t,
|
||||
object array,
|
||||
int32_t offset,
|
||||
int32_t length)
|
||||
{
|
||||
return vm::makeString(t, array, offset, length, 0);
|
||||
}
|
||||
|
||||
virtual GcThread*
|
||||
makeThread(Thread* t, Thread* parent)
|
||||
virtual GcThread* makeThread(Thread* t, Thread* parent)
|
||||
{
|
||||
GcThreadGroup* group;
|
||||
if (parent) {
|
||||
@ -51,38 +51,48 @@ class MyClasspath : public Classpath {
|
||||
const unsigned NewState = 0;
|
||||
const unsigned NormalPriority = 5;
|
||||
|
||||
return vm::makeThread
|
||||
(t, 0, 0, 0, 0, 0, NewState, NormalPriority, 0, 0, 0,
|
||||
roots(t)->appLoader(), 0, 0, group, 0);
|
||||
return vm::makeThread(t,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NewState,
|
||||
NormalPriority,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
roots(t)->appLoader(),
|
||||
0,
|
||||
0,
|
||||
group,
|
||||
0);
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJMethod(Thread* t, GcMethod* vmMethod)
|
||||
virtual object makeJMethod(Thread* t, GcMethod* vmMethod)
|
||||
{
|
||||
PROTECT(t, vmMethod);
|
||||
|
||||
GcJmethod* jmethod = makeJmethod(t, vmMethod, false);
|
||||
|
||||
return vmMethod->name()->body()[0] == '<'
|
||||
? (object)makeJconstructor(t, jmethod) : (object)jmethod;
|
||||
? (object)makeJconstructor(t, jmethod)
|
||||
: (object)jmethod;
|
||||
}
|
||||
|
||||
virtual GcMethod*
|
||||
getVMMethod(Thread* t, object jmethod)
|
||||
virtual GcMethod* getVMMethod(Thread* t, object jmethod)
|
||||
{
|
||||
return objectClass(t, jmethod) == type(t, GcJmethod::Type)
|
||||
? cast<GcJmethod>(t, jmethod)->vmMethod()
|
||||
: cast<GcJconstructor>(t, jmethod)->method()->vmMethod();
|
||||
? cast<GcJmethod>(t, jmethod)->vmMethod()
|
||||
: cast<GcJconstructor>(t, jmethod)->method()->vmMethod();
|
||||
}
|
||||
|
||||
virtual object
|
||||
makeJField(Thread* t, GcField* vmField)
|
||||
virtual object makeJField(Thread* t, GcField* vmField)
|
||||
{
|
||||
return makeJfield(t, vmField, false);
|
||||
}
|
||||
|
||||
virtual GcField*
|
||||
getVMField(Thread* t UNUSED, GcJfield* jfield)
|
||||
virtual GcField* getVMField(Thread* t UNUSED, GcJfield* jfield)
|
||||
{
|
||||
return jfield->vmField();
|
||||
}
|
||||
@ -96,15 +106,16 @@ class MyClasspath : public Classpath {
|
||||
virtual void
|
||||
runThread(Thread* t)
|
||||
{
|
||||
GcMethod* method = resolveMethod
|
||||
(t, roots(t)->bootLoader(), "java/lang/Thread", "run",
|
||||
"(Ljava/lang/Thread;)V");
|
||||
GcMethod* method = resolveMethod(t,
|
||||
roots(t)->bootLoader(),
|
||||
"java/lang/Thread",
|
||||
"run",
|
||||
"(Ljava/lang/Thread;)V");
|
||||
|
||||
t->m->processor->invoke(t, method, 0, t->javaThread);
|
||||
}
|
||||
|
||||
virtual void
|
||||
resolveNative(Thread* t, GcMethod* method)
|
||||
virtual void resolveNative(Thread* t, GcMethod* method)
|
||||
{
|
||||
vm::resolveNative(t, method);
|
||||
}
|
||||
@ -141,8 +152,8 @@ class MyClasspath : public Classpath {
|
||||
virtual object
|
||||
makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
|
||||
{
|
||||
GcClass* c = resolveClass
|
||||
(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer");
|
||||
GcClass* c
|
||||
= resolveClass(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer");
|
||||
PROTECT(t, c);
|
||||
|
||||
object instance = makeNew(t, c);
|
||||
@ -164,8 +175,7 @@ class MyClasspath : public Classpath {
|
||||
|
||||
GcField* field = resolveField(t, objectClass(t, b), "address", "J");
|
||||
|
||||
return reinterpret_cast<void*>
|
||||
(fieldAtOffset<int64_t>(b, field->offset()));
|
||||
return reinterpret_cast<void*>(fieldAtOffset<int64_t>(b, field->offset()));
|
||||
}
|
||||
|
||||
virtual int64_t
|
||||
@ -173,8 +183,7 @@ class MyClasspath : public Classpath {
|
||||
{
|
||||
PROTECT(t, b);
|
||||
|
||||
GcField* field = resolveField
|
||||
(t, objectClass(t, b), "capacity", "I");
|
||||
GcField* field = resolveField(t, objectClass(t, b), "capacity", "I");
|
||||
|
||||
return fieldAtOffset<int32_t>(b, field->offset());
|
||||
}
|
||||
@ -194,14 +203,12 @@ class MyClasspath : public Classpath {
|
||||
(strcmp("loadLibrary",
|
||||
reinterpret_cast<char*>(calleeMethodName->body().begin()))
|
||||
and strcmp("load",
|
||||
reinterpret_cast<char*>(
|
||||
calleeMethodName->body().begin())))
|
||||
or (strcmp(
|
||||
"java/lang/System",
|
||||
reinterpret_cast<char*>(calleeClassName->body().begin()))
|
||||
and strcmp("java/lang/Runtime",
|
||||
reinterpret_cast<char*>(
|
||||
calleeClassName->body().begin()))));
|
||||
reinterpret_cast<char*>(calleeMethodName->body().begin())))
|
||||
or (strcmp("java/lang/System",
|
||||
reinterpret_cast<char*>(calleeClassName->body().begin()))
|
||||
and strcmp(
|
||||
"java/lang/Runtime",
|
||||
reinterpret_cast<char*>(calleeClassName->body().begin()))));
|
||||
}
|
||||
|
||||
virtual GcClassLoader* libraryClassLoader(Thread* t, GcMethod* caller)
|
||||
@ -227,9 +234,11 @@ class MyClasspath : public Classpath {
|
||||
Allocator* allocator;
|
||||
};
|
||||
|
||||
void
|
||||
enumerateThreads(Thread* t, Thread* x, GcArray* array, unsigned* index,
|
||||
unsigned limit)
|
||||
void enumerateThreads(Thread* t,
|
||||
Thread* x,
|
||||
GcArray* array,
|
||||
unsigned* index,
|
||||
unsigned limit)
|
||||
{
|
||||
if (*index < limit) {
|
||||
array->setBodyElement(t, *index, x->javaThread);
|
||||
@ -263,10 +272,8 @@ Avian_java_lang_Object_toString
|
||||
object this_ = reinterpret_cast<object>(arguments[0]);
|
||||
|
||||
unsigned hash = objectHash(t, this_);
|
||||
GcString* s = makeString
|
||||
(t, "%s@0x%x",
|
||||
objectClass(t, this_)->name()->body().begin(),
|
||||
hash);
|
||||
GcString* s = makeString(
|
||||
t, "%s@0x%x", objectClass(t, this_)->name()->body().begin(), hash);
|
||||
|
||||
return reinterpret_cast<int64_t>(s);
|
||||
}
|
||||
@ -457,8 +464,8 @@ Avian_java_lang_reflect_Method_invoke
|
||||
THREAD_RESOURCE0(t, {
|
||||
if (t->exception) {
|
||||
GcThrowable* exception = t->exception;
|
||||
t->exception = makeThrowable
|
||||
(t, GcInvocationTargetException::Type, 0, 0, exception);
|
||||
t->exception = makeThrowable(
|
||||
t, GcInvocationTargetException::Type, 0, 0, exception);
|
||||
}
|
||||
});
|
||||
|
||||
@ -492,11 +499,12 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_java_lang_reflect_Array_makeObjectArray
|
||||
(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];
|
||||
|
||||
return reinterpret_cast<int64_t>
|
||||
(makeObjectArray(t, elementType->vmClass(), length));
|
||||
return reinterpret_cast<int64_t>(
|
||||
makeObjectArray(t, elementType->vmClass(), length));
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
@ -580,8 +588,7 @@ Avian_java_lang_System_identityHashCode
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_java_lang_ClassLoader_getCaller(Thread* t, object, uintptr_t*)
|
||||
{
|
||||
return reinterpret_cast<int64_t>(
|
||||
getJClass(t, getCaller(t, 2)->class_()));
|
||||
return reinterpret_cast<int64_t>(getJClass(t, getCaller(t, 2)->class_()));
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT void JNICALL
|
||||
@ -591,7 +598,9 @@ extern "C" AVIAN_EXPORT void JNICALL
|
||||
|
||||
Thread::LibraryLoadStack stack(
|
||||
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];
|
||||
|
||||
@ -643,7 +652,8 @@ Avian_java_lang_Throwable_resolveTrace
|
||||
PROTECT(t, array);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -661,8 +671,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_java_lang_Thread_doStart
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
return reinterpret_cast<int64_t>
|
||||
(startThread(t, cast<GcThread>(t, reinterpret_cast<object>(*arguments))));
|
||||
return reinterpret_cast<int64_t>(
|
||||
startThread(t, cast<GcThread>(t, reinterpret_cast<object>(*arguments))));
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT void JNICALL
|
||||
@ -713,7 +723,8 @@ Avian_java_lang_Thread_enumerate
|
||||
|
||||
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;
|
||||
local::enumerateThreads(t, t->m->rootThread, array, &index, count);
|
||||
return count;
|
||||
@ -730,14 +741,18 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_avian_Atomic_getOffset
|
||||
(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
|
||||
Avian_sun_misc_Unsafe_objectFieldOffset
|
||||
(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
|
||||
@ -793,8 +808,8 @@ Avian_avian_Classes_makeMethod
|
||||
->methodTable())->body()[arguments[1]]);
|
||||
PROTECT(t, method);
|
||||
|
||||
GcClass* c = resolveClass
|
||||
(t, roots(t)->bootLoader(), "java/lang/reflect/Method");
|
||||
GcClass* c
|
||||
= resolveClass(t, roots(t)->bootLoader(), "java/lang/reflect/Method");
|
||||
PROTECT(t, c);
|
||||
|
||||
object instance = makeNew(t, c);
|
||||
@ -807,13 +822,13 @@ Avian_avian_Classes_makeMethod
|
||||
if (method->name()->body()[0] == '<') {
|
||||
object oldInstance = instance;
|
||||
|
||||
c = resolveClass
|
||||
(t, roots(t)->bootLoader(), "java/lang/reflect/Constructor");
|
||||
c = resolveClass(
|
||||
t, roots(t)->bootLoader(), "java/lang/reflect/Constructor");
|
||||
|
||||
object instance = makeNew(t, c);
|
||||
|
||||
GcMethod* constructor = resolveMethod
|
||||
(t, c, "<init>", "(Ljava/lang/Method;)V");
|
||||
GcMethod* constructor
|
||||
= resolveMethod(t, c, "<init>", "(Ljava/lang/Method;)V");
|
||||
|
||||
t->m->processor->invoke(t, constructor, instance, oldInstance);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -586,7 +586,8 @@ acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask)
|
||||
if (s->type(c) == lir::RegisterOperand) {
|
||||
return c->availableGeneralRegisterCount > ResolveRegisterReserveCount;
|
||||
} 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
|
||||
(c, static_cast<MemorySite*>(s)->offset));
|
||||
@ -1138,9 +1139,11 @@ pop(Context* c, unsigned footprint)
|
||||
high = low->next;
|
||||
}
|
||||
|
||||
assertT(c, (TargetBytesPerWord == 8
|
||||
and low->value->nextWord == low->value and high->value == 0)
|
||||
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value));
|
||||
assertT(
|
||||
c,
|
||||
(TargetBytesPerWord == 8 and low->value->nextWord == low->value
|
||||
and high->value == 0)
|
||||
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value));
|
||||
#endif // not NDEBUG
|
||||
|
||||
popWord(c);
|
||||
@ -2379,10 +2382,11 @@ class MyCompiler: public Compiler {
|
||||
high = s->next;
|
||||
}
|
||||
|
||||
assertT(&c, (TargetBytesPerWord == 8
|
||||
and low->value->nextWord == low->value and high->value == 0)
|
||||
or (TargetBytesPerWord == 4
|
||||
and low->value->nextWord == high->value));
|
||||
assertT(
|
||||
&c,
|
||||
(TargetBytesPerWord == 8 and low->value->nextWord == low->value
|
||||
and high->value == 0)
|
||||
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value));
|
||||
#endif // not NDEBUG
|
||||
|
||||
if (bigEndian) {
|
||||
@ -2649,8 +2653,8 @@ class MyCompiler: public Compiler {
|
||||
ir::Value* addr)
|
||||
{
|
||||
assertT(&c,
|
||||
(isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))or(
|
||||
isFloatBranch(op) and isFloatValue(a) and isFloatValue(b)));
|
||||
(isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))
|
||||
or (isFloatBranch(op) and isFloatValue(a) and isFloatValue(b)));
|
||||
|
||||
assertT(&c, a->type == b->type);
|
||||
assertT(&c, addr->type == ir::Type::iptr());
|
||||
@ -2678,8 +2682,8 @@ class MyCompiler: public Compiler {
|
||||
ir::Value* b)
|
||||
{
|
||||
assertT(&c,
|
||||
(isGeneralBinaryOp(op) and isGeneralValue(a) and isGeneralValue(b))
|
||||
or(isFloatBinaryOp(op) and isFloatValue(a) and isFloatValue(b)));
|
||||
(isGeneralBinaryOp(op) and isGeneralValue(a) and isGeneralValue(b))
|
||||
or (isFloatBinaryOp(op) and isFloatValue(a) and isFloatValue(b)));
|
||||
|
||||
Value* result = value(&c, type);
|
||||
|
||||
@ -2695,8 +2699,8 @@ class MyCompiler: public Compiler {
|
||||
ir::Value* a)
|
||||
{
|
||||
assertT(&c,
|
||||
(isGeneralUnaryOp(op) and isGeneralValue(a))or(isFloatUnaryOp(op)
|
||||
and isFloatValue(a)));
|
||||
(isGeneralUnaryOp(op) and isGeneralValue(a))
|
||||
or (isFloatUnaryOp(op) and isFloatValue(a)));
|
||||
Value* result = value(&c, a->type);
|
||||
appendTranslate(
|
||||
&c, op, static_cast<Value*>(a), result);
|
||||
|
@ -400,8 +400,8 @@ class CallEvent: public Event {
|
||||
&& (v == 0 || (i >= 1 && arguments[i - 1] == 0)))
|
||||
|| (c->targetInfo.pointerSize == 4 && v->nextWord != v)) {
|
||||
assertT(c,
|
||||
c->targetInfo.pointerSize == 8
|
||||
or v->nextWord == arguments[i - 1]);
|
||||
c->targetInfo.pointerSize == 8
|
||||
or v->nextWord == arguments[i - 1]);
|
||||
|
||||
arguments[i] = arguments[i - 1];
|
||||
--i;
|
||||
@ -512,10 +512,14 @@ class CallEvent: public Event {
|
||||
op = lir::Jump;
|
||||
}
|
||||
|
||||
assertT(c, returnAddressSurrogate == 0
|
||||
or returnAddressSurrogate->source->type(c) == lir::RegisterOperand);
|
||||
assertT(c, framePointerSurrogate == 0
|
||||
or framePointerSurrogate->source->type(c) == lir::RegisterOperand);
|
||||
assertT(
|
||||
c,
|
||||
returnAddressSurrogate == 0
|
||||
or returnAddressSurrogate->source->type(c) == lir::RegisterOperand);
|
||||
assertT(
|
||||
c,
|
||||
framePointerSurrogate == 0
|
||||
or framePointerSurrogate->source->type(c) == lir::RegisterOperand);
|
||||
|
||||
int ras;
|
||||
if (returnAddressSurrogate) {
|
||||
@ -1004,7 +1008,9 @@ class CombineEvent: public Event {
|
||||
}
|
||||
|
||||
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)) {
|
||||
// fprintf(stderr, "%p %p %d : %p %p %d\n",
|
||||
@ -1013,7 +1019,9 @@ class CombineEvent: public Event {
|
||||
// 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);
|
||||
|
||||
@ -1197,7 +1205,9 @@ class TranslateEvent: public Event {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -1266,11 +1276,11 @@ void appendTranslate(Context* c,
|
||||
Value* resultValue)
|
||||
{
|
||||
assertT(c,
|
||||
firstValue->type.size(c->targetInfo)
|
||||
== firstValue->type.size(c->targetInfo));
|
||||
firstValue->type.size(c->targetInfo)
|
||||
== firstValue->type.size(c->targetInfo));
|
||||
assertT(c,
|
||||
resultValue->type.size(c->targetInfo)
|
||||
== resultValue->type.size(c->targetInfo));
|
||||
resultValue->type.size(c->targetInfo)
|
||||
== resultValue->type.size(c->targetInfo));
|
||||
|
||||
bool thunk;
|
||||
OperandMask first;
|
||||
|
@ -50,11 +50,11 @@ unsigned frameIndexToOffset(Context* c, unsigned frameIndex) {
|
||||
|
||||
unsigned offsetToFrameIndex(Context* c, unsigned offset) {
|
||||
assertT(c,
|
||||
static_cast<int>((offset / c->targetInfo.pointerSize)
|
||||
- c->arch->frameFooterSize()) >= 0);
|
||||
static_cast<int>((offset / c->targetInfo.pointerSize)
|
||||
- c->arch->frameFooterSize()) >= 0);
|
||||
assertT(c,
|
||||
((offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize())
|
||||
< totalFrameSize(c));
|
||||
((offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize())
|
||||
< totalFrameSize(c));
|
||||
|
||||
return (offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize();
|
||||
}
|
||||
|
@ -181,7 +181,8 @@ Read* StubRead::next(Context*) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ resourceCost(Context* c, Value* v, Resource* r, SiteMask mask,
|
||||
|
||||
if (r->value) {
|
||||
assertT(c, r->value->findSite(r->site));
|
||||
|
||||
|
||||
if (v and r->value->isBuddyOf(v)) {
|
||||
return baseCost;
|
||||
} else if (r->value->uniqueSite(c, r->site)) {
|
||||
|
@ -223,4 +223,4 @@ void release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNU
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
} // namespace avian
|
||||
|
@ -378,8 +378,9 @@ unsigned RegisterSite::registerMask(Context* c UNUSED) {
|
||||
|
||||
Site* registerSite(Context* c, int number) {
|
||||
assertT(c, number >= 0);
|
||||
assertT(c, (1 << number) & (c->regFile->generalRegisters.mask
|
||||
| c->regFile->floatRegisters.mask));
|
||||
assertT(c,
|
||||
(1 << number) & (c->regFile->generalRegisters.mask
|
||||
| c->regFile->floatRegisters.mask));
|
||||
|
||||
return new(c->zone) RegisterSite(1 << number, number);
|
||||
}
|
||||
@ -402,7 +403,7 @@ unsigned MemorySite::toString(Context*, char* buffer, unsigned bufferSize) {
|
||||
}
|
||||
|
||||
unsigned MemorySite::copyCost(Context* c, Site* s) {
|
||||
assertT(c, acquired);
|
||||
assertT(c, acquired);
|
||||
|
||||
if (s and
|
||||
(this == s or
|
||||
@ -488,8 +489,7 @@ void MemorySite::acquire(Context* c, Value* v) {
|
||||
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, index == lir::NoRegister);
|
||||
assertT
|
||||
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||
assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||
|
||||
compiler::acquire
|
||||
(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) {
|
||||
if (base == c->arch->stack()) {
|
||||
assertT(c, index == lir::NoRegister);
|
||||
assertT
|
||||
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||
assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||
|
||||
compiler::release
|
||||
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
|
||||
@ -552,12 +551,12 @@ void MemorySite::asAssemblerOperand(Context* c UNUSED, Site* high UNUSED,
|
||||
{
|
||||
// todo: endianness?
|
||||
assertT(c,
|
||||
high == this
|
||||
or (static_cast<MemorySite*>(high)->base == base
|
||||
and static_cast<MemorySite*>(high)->offset
|
||||
== static_cast<int>(offset + c->targetInfo.pointerSize)
|
||||
and static_cast<MemorySite*>(high)->index == index
|
||||
and static_cast<MemorySite*>(high)->scale == scale));
|
||||
high == this
|
||||
or (static_cast<MemorySite*>(high)->base == base
|
||||
and static_cast<MemorySite*>(high)->offset
|
||||
== static_cast<int>(offset + c->targetInfo.pointerSize)
|
||||
and static_cast<MemorySite*>(high)->index == index
|
||||
and static_cast<MemorySite*>(high)->scale == scale));
|
||||
|
||||
assertT(c, acquired);
|
||||
|
||||
|
@ -884,11 +884,11 @@ void moveAR(Context* con, unsigned srcSize, lir::Address* src,
|
||||
void compareRR(Context* con, unsigned aSize, lir::Register* a,
|
||||
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
|
||||
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));
|
||||
} else { // FPR compare
|
||||
assertT(con, aSize == bSize);
|
||||
|
@ -143,11 +143,13 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
||||
}
|
||||
|
||||
if (UseFramePointer and not mostRecent) {
|
||||
assertT(c, static_cast<void***>(*stack)[-1] + 1
|
||||
== static_cast<void**>(*stack) + offset);
|
||||
assertT(c,
|
||||
static_cast<void***>(*stack)[-1] + 1
|
||||
== static_cast<void**>(*stack) + offset);
|
||||
|
||||
assertT(c, static_cast<void***>(*stack)[-1][1]
|
||||
== static_cast<void**>(*stack)[offset]);
|
||||
assertT(c,
|
||||
static_cast<void***>(*stack)[-1][1]
|
||||
== static_cast<void**>(*stack)[offset]);
|
||||
}
|
||||
|
||||
*ip = static_cast<void**>(*stack)[offset];
|
||||
@ -340,13 +342,17 @@ class MyArchitecture: public Architecture {
|
||||
|
||||
if (TargetBytesPerWord == 4 or op == lir::Call or op == lir::Jump) {
|
||||
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
||||
|
||||
assertT(&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)
|
||||
or reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
||||
|
||||
assertT(
|
||||
&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)
|
||||
or reinterpret_cast<uintptr_t>(instruction + 1) % 4 == 0);
|
||||
|
||||
intptr_t v = static_cast<uint8_t*>(newTarget)
|
||||
- static_cast<uint8_t*>(returnAddress);
|
||||
|
||||
@ -360,12 +366,14 @@ class MyArchitecture: public Architecture {
|
||||
|
||||
assertT(&c, instruction[0] == 0x49 and instruction[1] == 0xBA);
|
||||
assertT(&c, instruction[10] == 0x41 and instruction[11] == 0xFF);
|
||||
assertT(&c, (op == lir::LongCall and instruction[12] == 0xD2)
|
||||
or (op == lir::LongJump and instruction[12] == 0xE2));
|
||||
assertT(&c,
|
||||
(op == lir::LongCall and instruction[12] == 0xD2)
|
||||
or (op == lir::LongJump and instruction[12] == 0xE2));
|
||||
|
||||
assertT(&c,
|
||||
(not assertTAlignment)
|
||||
or reinterpret_cast<uintptr_t>(instruction + 2) % 8 == 0);
|
||||
|
||||
assertT(&c, (not assertTAlignment)
|
||||
or reinterpret_cast<uintptr_t>(instruction + 2) % 8 == 0);
|
||||
|
||||
memcpy(instruction + 2, &newTarget, 8);
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ void jumpC(Context* c, unsigned size UNUSED, lir::Constant* a) {
|
||||
|
||||
void jumpM(Context* c, unsigned size UNUSED, lir::Memory* a) {
|
||||
assertT(c, size == vm::TargetBytesPerWord);
|
||||
|
||||
|
||||
maybeRex(c, 4, a);
|
||||
opcode(c, 0xff);
|
||||
modrmSibImm(c, rsp, a->scale, a->index, a->base, a->offset);
|
||||
@ -122,7 +122,7 @@ void callR(Context* c, unsigned size UNUSED, lir::Register* a) {
|
||||
|
||||
void callM(Context* c, unsigned size UNUSED, lir::Memory* a) {
|
||||
assertT(c, size == vm::TargetBytesPerWord);
|
||||
|
||||
|
||||
maybeRex(c, 4, a);
|
||||
opcode(c, 0xff);
|
||||
modrmSibImm(c, rdx, a->scale, a->index, a->base, a->offset);
|
||||
@ -244,7 +244,7 @@ void swapRR(Context* c, unsigned aSize UNUSED, lir::Register* a,
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
assertT(c, aSize == vm::TargetBytesPerWord);
|
||||
|
||||
|
||||
alwaysRex(c, aSize, a, b);
|
||||
opcode(c, 0x87);
|
||||
modrm(c, 0xc0, b, a);
|
||||
@ -359,7 +359,7 @@ void moveMR(Context* c, unsigned aSize, lir::Memory* a,
|
||||
} else {
|
||||
if (bSize == 8) {
|
||||
assertT(c, b->low == rax and b->high == rdx);
|
||||
|
||||
|
||||
moveMR(c, 4, a, 4, b);
|
||||
moveRR(c, 4, b, 8, b);
|
||||
} else {
|
||||
@ -392,7 +392,7 @@ void moveRM(Context* c, unsigned aSize, lir::Register* a,
|
||||
unsigned bSize UNUSED, lir::Memory* b)
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
|
||||
|
||||
if (isFloatReg(a)) {
|
||||
sseMoveRM(c, aSize, a, bSize, b);
|
||||
return;
|
||||
@ -533,7 +533,7 @@ void moveZMR(Context* c, unsigned aSize UNUSED, lir::Memory* a,
|
||||
{
|
||||
assertT(c, bSize == vm::TargetBytesPerWord);
|
||||
assertT(c, aSize == 2);
|
||||
|
||||
|
||||
maybeRex(c, bSize, b, a);
|
||||
opcode(c, 0x0f, 0xb7);
|
||||
modrmSibImm(c, b->low, a->scale, a->index, a->base, a->offset);
|
||||
@ -543,7 +543,7 @@ void addCarryRR(Context* c, unsigned size, lir::Register* a,
|
||||
lir::Register* b)
|
||||
{
|
||||
assertT(c, vm::TargetBytesPerWord == 8 or size == 4);
|
||||
|
||||
|
||||
maybeRex(c, size, a, b);
|
||||
opcode(c, 0x11);
|
||||
modrm(c, 0xc0, b, a);
|
||||
@ -625,7 +625,7 @@ void subtractBorrowCR(Context* c, unsigned size UNUSED, lir::Constant* a,
|
||||
lir::Register* b)
|
||||
{
|
||||
assertT(c, vm::TargetBytesPerWord == 8 or size == 4);
|
||||
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (vm::fitsInInt8(v)) {
|
||||
opcode(c, 0x83, 0xd8 + regCode(b));
|
||||
@ -679,7 +679,7 @@ void subtractBorrowRR(Context* c, unsigned size, lir::Register* a,
|
||||
lir::Register* b)
|
||||
{
|
||||
assertT(c, vm::TargetBytesPerWord == 8 or size == 4);
|
||||
|
||||
|
||||
maybeRex(c, size, a, b);
|
||||
opcode(c, 0x19);
|
||||
modrm(c, 0xc0, b, a);
|
||||
@ -689,7 +689,7 @@ void subtractRR(Context* c, unsigned aSize, lir::Register* a,
|
||||
unsigned bSize UNUSED, lir::Register* b)
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
|
||||
|
||||
if (vm::TargetBytesPerWord == 4 and aSize == 8) {
|
||||
lir::Register ah(a->high);
|
||||
lir::Register bh(b->high);
|
||||
@ -708,7 +708,6 @@ void andRR(Context* c, unsigned aSize, lir::Register* a,
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
|
||||
|
||||
if (vm::TargetBytesPerWord == 4 and aSize == 8) {
|
||||
lir::Register ah(a->high);
|
||||
lir::Register bh(b->high);
|
||||
@ -877,7 +876,6 @@ void multiplyRR(Context* c, unsigned aSize, lir::Register* a,
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
|
||||
|
||||
if (vm::TargetBytesPerWord == 4 and aSize == 8) {
|
||||
assertT(c, b->high == rdx);
|
||||
assertT(c, b->low != rax);
|
||||
@ -938,7 +936,7 @@ void compareCR(Context* c, unsigned aSize, lir::Constant* a,
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
assertT(c, vm::TargetBytesPerWord == 8 or aSize == 4);
|
||||
|
||||
|
||||
if (a->value->resolved() and vm::fitsInInt32(a->value->value())) {
|
||||
int64_t v = a->value->value();
|
||||
maybeRex(c, aSize, b);
|
||||
@ -962,7 +960,7 @@ void compareRM(Context* c, unsigned aSize, lir::Register* a,
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
assertT(c, vm::TargetBytesPerWord == 8 or aSize == 4);
|
||||
|
||||
|
||||
if (vm::TargetBytesPerWord == 8 and aSize == 4) {
|
||||
moveRR(c, 4, a, 8, a);
|
||||
}
|
||||
@ -976,7 +974,7 @@ void compareCM(Context* c, unsigned aSize, lir::Constant* a,
|
||||
{
|
||||
assertT(c, aSize == bSize);
|
||||
assertT(c, vm::TargetBytesPerWord == 8 or aSize == 4);
|
||||
|
||||
|
||||
if (a->value->resolved()) {
|
||||
int64_t v = a->value->value();
|
||||
maybeRex(c, aSize, b);
|
||||
@ -1290,7 +1288,7 @@ void shiftLeftRR(Context* c, UNUSED unsigned aSize, lir::Register* a,
|
||||
moveRR(c, 4, b, 4, &bh); // 2 bytes
|
||||
xorRR(c, 4, b, 4, b); // 2 bytes
|
||||
} else {
|
||||
assertT(c, a->low == rcx);
|
||||
assertT(c, a->low == rcx);
|
||||
|
||||
maybeRex(c, bSize, a, b);
|
||||
opcode(c, 0xd3, 0xe0 + regCode(b));
|
||||
|
1964
src/compile.cpp
1964
src/compile.cpp
File diff suppressed because it is too large
Load Diff
@ -284,7 +284,8 @@ class JarIndex {
|
||||
|
||||
while (p < end) {
|
||||
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);
|
||||
} else {
|
||||
|
@ -342,7 +342,7 @@ class Segment {
|
||||
if (minimum == 0) {
|
||||
minimum = 1;
|
||||
}
|
||||
|
||||
|
||||
assertT(context, desired >= minimum);
|
||||
|
||||
capacity_ = desired;
|
||||
|
@ -34,14 +34,13 @@ const unsigned FrameFootprint = 4;
|
||||
|
||||
class Thread: public vm::Thread {
|
||||
public:
|
||||
|
||||
Thread(Machine* m, GcThread* javaThread, vm::Thread* parent):
|
||||
vm::Thread(m, javaThread, parent),
|
||||
ip(0),
|
||||
sp(0),
|
||||
frame(-1),
|
||||
code(0),
|
||||
stackPointers(0)
|
||||
Thread(Machine* m, GcThread* javaThread, vm::Thread* parent)
|
||||
: vm::Thread(m, javaThread, parent),
|
||||
ip(0),
|
||||
sp(0),
|
||||
frame(-1),
|
||||
code(0),
|
||||
stackPointers(0)
|
||||
{ }
|
||||
|
||||
unsigned ip;
|
||||
@ -249,8 +248,7 @@ frameNext(Thread* t, int frame)
|
||||
return peekInt(t, frame + FrameNextOffset);
|
||||
}
|
||||
|
||||
inline GcMethod*
|
||||
frameMethod(Thread* t, int frame)
|
||||
inline GcMethod* frameMethod(Thread* t, int frame)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
pushFrame(Thread* t, GcMethod* method)
|
||||
void pushFrame(Thread* t, GcMethod* method)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -386,7 +383,8 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
}
|
||||
}
|
||||
|
||||
virtual GcMethod* method() {
|
||||
virtual GcMethod* method()
|
||||
{
|
||||
return frameMethod(t, frame);
|
||||
}
|
||||
|
||||
@ -406,16 +404,11 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
int frame;
|
||||
};
|
||||
|
||||
inline void
|
||||
checkStack(Thread* t, GcMethod* method)
|
||||
inline void checkStack(Thread* t, GcMethod* method)
|
||||
{
|
||||
if (UNLIKELY(t->sp
|
||||
+ method->parameterFootprint()
|
||||
+ method->code()->maxLocals()
|
||||
+ FrameFootprint
|
||||
+ method->code()->maxStack()
|
||||
> stackSizeInWords(t) / 2))
|
||||
{
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint()
|
||||
+ method->code()->maxLocals() + FrameFootprint
|
||||
+ method->code()->maxStack() > stackSizeInWords(t) / 2)) {
|
||||
throwNew(t, GcStackOverflowError::Type);
|
||||
}
|
||||
}
|
||||
@ -488,13 +481,15 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
marshalArguments(Thread* t, uintptr_t* args, uint8_t* types, unsigned sp,
|
||||
GcMethod* method, bool fastCallingConvention)
|
||||
void marshalArguments(Thread* t,
|
||||
uintptr_t* args,
|
||||
uint8_t* types,
|
||||
unsigned sp,
|
||||
GcMethod* method,
|
||||
bool fastCallingConvention)
|
||||
{
|
||||
MethodSpecIterator it
|
||||
(t, reinterpret_cast<const char*>
|
||||
(method->spec()->body().begin()));
|
||||
MethodSpecIterator it(
|
||||
t, reinterpret_cast<const char*>(method->spec()->body().begin()));
|
||||
|
||||
unsigned argOffset = 0;
|
||||
unsigned typeOffset = 0;
|
||||
@ -538,8 +533,7 @@ marshalArguments(Thread* t, uintptr_t* args, uint8_t* types, unsigned sp,
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
invokeNativeSlow(Thread* t, GcMethod* method, void* function)
|
||||
unsigned invokeNativeSlow(Thread* t, GcMethod* method, void* function)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -587,7 +581,8 @@ invokeNativeSlow(Thread* t, GcMethod* method, void* function)
|
||||
uint64_t result;
|
||||
|
||||
if (DebugRun) {
|
||||
fprintf(stderr, "invoke native method %s.%s\n",
|
||||
fprintf(stderr,
|
||||
"invoke native method %s.%s\n",
|
||||
method->class_()->name()->body().begin(),
|
||||
method->name()->body().begin());
|
||||
}
|
||||
@ -607,7 +602,8 @@ invokeNativeSlow(Thread* t, GcMethod* method, void* function)
|
||||
}
|
||||
|
||||
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)->name()->body().begin());
|
||||
}
|
||||
@ -625,8 +621,7 @@ invokeNativeSlow(Thread* t, GcMethod* method, void* function)
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
unsigned
|
||||
invokeNative(Thread* t, GcMethod* method)
|
||||
unsigned invokeNative(Thread* t, GcMethod* method)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -651,8 +646,8 @@ invokeNative(Thread* t, GcMethod* method)
|
||||
marshalArguments
|
||||
(t, RUNTIME_ARRAY_BODY(args) + argOffset, 0, sp, method, true);
|
||||
|
||||
result = reinterpret_cast<FastNativeFunction>
|
||||
(native->function())(t, method, RUNTIME_ARRAY_BODY(args));
|
||||
result = reinterpret_cast<FastNativeFunction>(native->function())(
|
||||
t, method, RUNTIME_ARRAY_BODY(args));
|
||||
}
|
||||
|
||||
pushResult(t, method->returnCode(), result, false);
|
||||
@ -683,12 +678,12 @@ isNaN(float v)
|
||||
return fpclassify(v) == FP_NAN;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
findExceptionHandler(Thread* t, GcMethod* method, unsigned ip)
|
||||
uint64_t findExceptionHandler(Thread* t, GcMethod* method, unsigned ip)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
GcExceptionHandlerTable* eht = cast<GcExceptionHandlerTable>(t, method->code()->exceptionHandlerTable());
|
||||
GcExceptionHandlerTable* eht = cast<GcExceptionHandlerTable>(
|
||||
t, method->code()->exceptionHandlerTable());
|
||||
|
||||
if (eht) {
|
||||
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));
|
||||
}
|
||||
|
||||
void
|
||||
pushField(Thread* t, object target, GcField* field)
|
||||
void pushField(Thread* t, object target, GcField* field)
|
||||
{
|
||||
switch (field->code()) {
|
||||
case ByteField:
|
||||
@ -791,10 +785,11 @@ interpret3(Thread* t, const int base)
|
||||
}
|
||||
|
||||
loop:
|
||||
instruction = code->body()[ip++];
|
||||
instruction = code->body()[ip++];
|
||||
|
||||
if (DebugRun) {
|
||||
fprintf(stderr, "ip: %d; instruction: 0x%x in %s.%s ",
|
||||
fprintf(stderr,
|
||||
"ip: %d; instruction: 0x%x in %s.%s ",
|
||||
ip - 1,
|
||||
instruction,
|
||||
frameMethod(t, frame)->class_()->name()->body().begin(),
|
||||
@ -824,9 +819,11 @@ interpret3(Thread* t, const int base)
|
||||
{
|
||||
pushObject(t, objectArrayBody(t, array, index));
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, objectArrayLength(t, array));
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
objectArrayLength(t, array));
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -846,9 +843,11 @@ interpret3(Thread* t, const int base)
|
||||
{
|
||||
setField(t, array, ArrayBody + (index * BytesPerWord), value);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, objectArrayLength(t, array));
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
objectArrayLength(t, array));
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -891,8 +890,8 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
pushObject(t, makeObjectArray(t, class_, count));
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcNegativeArraySizeException::Type, "%d", count);
|
||||
exception
|
||||
= makeThrowable(t, GcNegativeArraySizeException::Type, "%d", count);
|
||||
goto throw_;
|
||||
}
|
||||
} goto loop;
|
||||
@ -952,28 +951,28 @@ interpret3(Thread* t, const int base)
|
||||
if (LIKELY(array)) {
|
||||
if (objectClass(t, array) == type(t, GcBooleanArray::Type)) {
|
||||
GcBooleanArray* a = cast<GcBooleanArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index)
|
||||
< a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0
|
||||
and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushInt(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)", index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
GcByteArray* a = cast<GcByteArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index)
|
||||
< a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0
|
||||
and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushInt(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)", index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
}
|
||||
@ -991,27 +990,28 @@ interpret3(Thread* t, const int base)
|
||||
if (LIKELY(array)) {
|
||||
if (objectClass(t, array) == type(t, GcBooleanArray::Type)) {
|
||||
GcBooleanArray* a = cast<GcBooleanArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index)
|
||||
< a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0
|
||||
and static_cast<uintptr_t>(index) < a->length())) {
|
||||
a->body()[index] = value;
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)", index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
GcByteArray* a = cast<GcByteArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0
|
||||
and static_cast<uintptr_t>(index) < a->length())) {
|
||||
a->body()[index] = value;
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)", index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
}
|
||||
@ -1031,14 +1031,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcCharArray* a = cast<GcCharArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushInt(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1054,14 +1054,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcCharArray* a = cast<GcCharArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
a->body()[index] = value;
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1078,10 +1078,12 @@ interpret3(Thread* t, const int base)
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
|
||||
if (not instanceOf(t, class_, peekObject(t, sp - 1))) {
|
||||
exception = makeThrowable
|
||||
(t, GcClassCastException::Type, "%s as %s",
|
||||
objectClass(t, peekObject(t, sp - 1))->name()->body().begin(),
|
||||
class_->name()->body().begin());
|
||||
exception = makeThrowable(
|
||||
t,
|
||||
GcClassCastException::Type,
|
||||
"%s as %s",
|
||||
objectClass(t, peekObject(t, sp - 1))->name()->body().begin(),
|
||||
class_->name()->body().begin());
|
||||
goto throw_;
|
||||
}
|
||||
}
|
||||
@ -1128,14 +1130,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcDoubleArray* a = cast<GcDoubleArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushLong(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1151,14 +1153,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcDoubleArray* a = cast<GcDoubleArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
memcpy(&a->body()[index], &value, sizeof(uint64_t));
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1347,14 +1349,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcFloatArray* a = cast<GcFloatArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushInt(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1370,14 +1372,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcFloatArray* a = cast<GcFloatArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
memcpy(&a->body()[index], &value, sizeof(uint32_t));
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1548,14 +1550,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcIntArray* a = cast<GcIntArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushInt(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1578,14 +1580,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcIntArray* a = cast<GcIntArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
a->body()[index] = value;
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -1855,8 +1857,8 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
unsigned parameterFootprint = m->parameterFootprint();
|
||||
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
||||
method = findInterfaceMethod
|
||||
(t, m, objectClass(t, peekObject(t, sp - parameterFootprint)));
|
||||
method = findInterfaceMethod(
|
||||
t, m, objectClass(t, peekObject(t, sp - parameterFootprint)));
|
||||
goto invoke;
|
||||
} else {
|
||||
exception = makeThrowable(t, GcNullPointerException::Type);
|
||||
@ -2051,14 +2053,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcLongArray* a = cast<GcLongArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushLong(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -2081,14 +2083,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcLongArray* a = cast<GcLongArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
a->body()[index] = value;
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -2127,12 +2129,13 @@ interpret3(Thread* t, const int base)
|
||||
if (singletonIsObject(t, pool, index - 1)) {
|
||||
object v = singletonObject(t, pool, index - 1);
|
||||
if (objectClass(t, v) == type(t, GcReference::Type)) {
|
||||
GcClass* class_ = resolveClassInPool
|
||||
(t, frameMethod(t, frame), index - 1);
|
||||
GcClass* class_
|
||||
= resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||
|
||||
pushObject(t, reinterpret_cast<object>(getJClass(t, class_)));
|
||||
} 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 {
|
||||
pushObject(t, v);
|
||||
}
|
||||
@ -2353,9 +2356,10 @@ interpret3(Thread* t, const int base)
|
||||
for (int i = dimensions - 1; i >= 0; --i) {
|
||||
RUNTIME_ARRAY_BODY(counts)[i] = popInt(t);
|
||||
if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) {
|
||||
exception = makeThrowable
|
||||
(t, GcNegativeArraySizeException::Type, "%d",
|
||||
RUNTIME_ARRAY_BODY(counts)[i]);
|
||||
exception = makeThrowable(t,
|
||||
GcNegativeArraySizeException::Type,
|
||||
"%d",
|
||||
RUNTIME_ARRAY_BODY(counts)[i]);
|
||||
goto throw_;
|
||||
}
|
||||
}
|
||||
@ -2426,8 +2430,8 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
pushObject(t, array);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcNegativeArraySizeException::Type, "%d", count);
|
||||
exception
|
||||
= makeThrowable(t, GcNegativeArraySizeException::Type, "%d", count);
|
||||
goto throw_;
|
||||
}
|
||||
} goto loop;
|
||||
@ -2574,8 +2578,7 @@ interpret3(Thread* t, const int base)
|
||||
case return_: {
|
||||
GcMethod* method = frameMethod(t, frame);
|
||||
if ((method->flags() & ConstructorFlag)
|
||||
and (method->class_()->vmFlags() & HasFinalMemberFlag))
|
||||
{
|
||||
and (method->class_()->vmFlags() & HasFinalMemberFlag)) {
|
||||
storeStoreMemoryBarrier();
|
||||
}
|
||||
|
||||
@ -2593,14 +2596,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcShortArray* a = cast<GcShortArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
pushInt(t, a->body()[index]);
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -2616,14 +2619,14 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
if (LIKELY(array)) {
|
||||
GcShortArray* a = cast<GcShortArray>(t, array);
|
||||
if (LIKELY(index >= 0 and
|
||||
static_cast<uintptr_t>(index) < a->length()))
|
||||
{
|
||||
if (LIKELY(index >= 0 and static_cast<uintptr_t>(index) < a->length())) {
|
||||
a->body()[index] = value;
|
||||
} else {
|
||||
exception = makeThrowable
|
||||
(t, GcArrayIndexOutOfBoundsException::Type, "%d not in [0,%d)",
|
||||
index, a->length());
|
||||
exception = makeThrowable(t,
|
||||
GcArrayIndexOutOfBoundsException::Type,
|
||||
"%d not in [0,%d)",
|
||||
index,
|
||||
a->length());
|
||||
goto throw_;
|
||||
}
|
||||
} else {
|
||||
@ -2683,8 +2686,7 @@ interpret3(Thread* t, const int base)
|
||||
GcClass* class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
||||
assertT(t, class_->vmFlags() & BootstrapFlag);
|
||||
|
||||
resolveClass(t, frameMethod(t, frame)->class_()->loader(),
|
||||
class_->name());
|
||||
resolveClass(t, frameMethod(t, frame)->class_()->loader(), class_->name());
|
||||
|
||||
ip -= 3;
|
||||
} goto loop;
|
||||
@ -2693,7 +2695,7 @@ interpret3(Thread* t, const int base)
|
||||
}
|
||||
|
||||
wide:
|
||||
switch (code->body()[ip++]) {
|
||||
switch (code->body()[ip++]) {
|
||||
case aload: {
|
||||
pushObject(t, localObject(t, codeReadInt16(t, code, ip)));
|
||||
} goto loop;
|
||||
@ -2737,8 +2739,8 @@ interpret3(Thread* t, const int base)
|
||||
goto loop;
|
||||
|
||||
invoke: {
|
||||
if (method->flags() & ACC_NATIVE) {
|
||||
invokeNative(t, method);
|
||||
if (method->flags() & ACC_NATIVE) {
|
||||
invokeNative(t, method);
|
||||
} else {
|
||||
checkStack(t, method);
|
||||
pushFrame(t, method);
|
||||
@ -2896,8 +2898,7 @@ pushArguments(Thread* t, object this_, const char* spec, object a)
|
||||
}
|
||||
}
|
||||
|
||||
object
|
||||
invoke(Thread* t, GcMethod* method)
|
||||
object invoke(Thread* t, GcMethod* method)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -2982,8 +2983,9 @@ class MyProcessor: public Processor {
|
||||
signals.setCrashDumpDirectory(crashDumpDirectory);
|
||||
}
|
||||
|
||||
virtual vm::Thread*
|
||||
makeThread(Machine* m, GcThread* javaThread, vm::Thread* parent)
|
||||
virtual vm::Thread* makeThread(Machine* m,
|
||||
GcThread* javaThread,
|
||||
vm::Thread* parent)
|
||||
{
|
||||
Thread* t = new (m->heap->allocate(sizeof(Thread) + m->stackSizeInBytes))
|
||||
Thread(m, javaThread, parent);
|
||||
@ -2991,19 +2993,18 @@ class MyProcessor: public Processor {
|
||||
return t;
|
||||
}
|
||||
|
||||
virtual GcMethod*
|
||||
makeMethod(vm::Thread* t,
|
||||
uint8_t vmFlags,
|
||||
uint8_t returnCode,
|
||||
uint8_t parameterCount,
|
||||
uint8_t parameterFootprint,
|
||||
uint16_t flags,
|
||||
uint16_t offset,
|
||||
GcByteArray* name,
|
||||
GcByteArray* spec,
|
||||
GcMethodAddendum* addendum,
|
||||
GcClass* class_,
|
||||
GcCode* code)
|
||||
virtual GcMethod* makeMethod(vm::Thread* t,
|
||||
uint8_t vmFlags,
|
||||
uint8_t returnCode,
|
||||
uint8_t parameterCount,
|
||||
uint8_t parameterFootprint,
|
||||
uint16_t flags,
|
||||
uint16_t offset,
|
||||
GcByteArray* name,
|
||||
GcByteArray* spec,
|
||||
GcMethodAddendum* addendum,
|
||||
GcClass* class_,
|
||||
GcCode* code)
|
||||
{
|
||||
return vm::makeMethod(t,
|
||||
vmFlags,
|
||||
@ -3021,26 +3022,25 @@ class MyProcessor: public Processor {
|
||||
code);
|
||||
}
|
||||
|
||||
virtual GcClass*
|
||||
makeClass(vm::Thread* t,
|
||||
uint16_t flags,
|
||||
uint16_t vmFlags,
|
||||
uint16_t fixedSize,
|
||||
uint8_t arrayElementSize,
|
||||
uint8_t arrayDimensions,
|
||||
GcClass* arrayElementClass,
|
||||
GcIntArray* objectMask,
|
||||
GcByteArray* name,
|
||||
GcByteArray* sourceFile,
|
||||
GcClass* super,
|
||||
object interfaceTable,
|
||||
object virtualTable,
|
||||
object fieldTable,
|
||||
object methodTable,
|
||||
GcClassAddendum* addendum,
|
||||
GcSingleton* staticTable,
|
||||
GcClassLoader* loader,
|
||||
unsigned vtableLength UNUSED)
|
||||
virtual GcClass* makeClass(vm::Thread* t,
|
||||
uint16_t flags,
|
||||
uint16_t vmFlags,
|
||||
uint16_t fixedSize,
|
||||
uint8_t arrayElementSize,
|
||||
uint8_t arrayDimensions,
|
||||
GcClass* arrayElementClass,
|
||||
GcIntArray* objectMask,
|
||||
GcByteArray* name,
|
||||
GcByteArray* sourceFile,
|
||||
GcClass* super,
|
||||
object interfaceTable,
|
||||
object virtualTable,
|
||||
object fieldTable,
|
||||
object methodTable,
|
||||
GcClassAddendum* addendum,
|
||||
GcSingleton* staticTable,
|
||||
GcClassLoader* loader,
|
||||
unsigned vtableLength UNUSED)
|
||||
{
|
||||
return vm::makeClass(t,
|
||||
flags,
|
||||
@ -3065,8 +3065,7 @@ class MyProcessor: public Processor {
|
||||
0);
|
||||
}
|
||||
|
||||
virtual void
|
||||
initVtable(vm::Thread*, GcClass*)
|
||||
virtual void initVtable(vm::Thread*, GcClass*)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
@ -3098,8 +3097,7 @@ class MyProcessor: public Processor {
|
||||
walker.walk(v);
|
||||
}
|
||||
|
||||
virtual int
|
||||
lineNumber(vm::Thread* t, GcMethod* method, int ip)
|
||||
virtual int lineNumber(vm::Thread* t, GcMethod* method, int 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>));
|
||||
}
|
||||
|
||||
virtual object
|
||||
invokeArray(vm::Thread* vmt, GcMethod* method, object this_, object arguments)
|
||||
virtual object invokeArray(vm::Thread* vmt,
|
||||
GcMethod* method,
|
||||
object this_,
|
||||
object arguments)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
assertT(t, t->state == Thread::ActiveState
|
||||
or t->state == Thread::ExclusiveState);
|
||||
assertT(
|
||||
t,
|
||||
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
|
||||
|
||||
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
|
||||
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint() + 1
|
||||
> stackSizeInWords(t) / 2))
|
||||
{
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint() + 1 > stackSizeInWords(t)
|
||||
/ 2)) {
|
||||
throwNew(t, GcStackOverflowError::Type);
|
||||
}
|
||||
|
||||
const char* spec = reinterpret_cast<char*>
|
||||
(method->spec()->body().begin());
|
||||
const char* spec = reinterpret_cast<char*>(method->spec()->body().begin());
|
||||
pushArguments(t, this_, spec, arguments);
|
||||
|
||||
return local::invoke(t, method);
|
||||
}
|
||||
|
||||
virtual object
|
||||
invokeArray(vm::Thread* vmt, GcMethod* method, object this_,
|
||||
const jvalue* arguments)
|
||||
virtual object invokeArray(vm::Thread* vmt,
|
||||
GcMethod* method,
|
||||
object this_,
|
||||
const jvalue* arguments)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
assertT(t, t->state == Thread::ActiveState
|
||||
or t->state == Thread::ExclusiveState);
|
||||
assertT(
|
||||
t,
|
||||
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
|
||||
|
||||
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
|
||||
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint() + 1
|
||||
> stackSizeInWords(t) / 2))
|
||||
{
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint() + 1 > stackSizeInWords(t)
|
||||
/ 2)) {
|
||||
throwNew(t, GcStackOverflowError::Type);
|
||||
}
|
||||
|
||||
const char* spec = reinterpret_cast<char*>
|
||||
(method->spec()->body().begin());
|
||||
const char* spec = reinterpret_cast<char*>(method->spec()->body().begin());
|
||||
pushArguments(t, this_, spec, arguments);
|
||||
|
||||
return local::invoke(t, method);
|
||||
}
|
||||
|
||||
virtual object
|
||||
invokeList(vm::Thread* vmt, GcMethod* method, object this_,
|
||||
bool indirectObjects, va_list arguments)
|
||||
virtual object invokeList(vm::Thread* vmt,
|
||||
GcMethod* method,
|
||||
object this_,
|
||||
bool indirectObjects,
|
||||
va_list arguments)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
assertT(t, t->state == Thread::ActiveState
|
||||
or t->state == Thread::ExclusiveState);
|
||||
assertT(
|
||||
t,
|
||||
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
|
||||
|
||||
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
|
||||
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint() + 1
|
||||
> stackSizeInWords(t) / 2))
|
||||
{
|
||||
if (UNLIKELY(t->sp + method->parameterFootprint() + 1 > stackSizeInWords(t)
|
||||
/ 2)) {
|
||||
throwNew(t, GcStackOverflowError::Type);
|
||||
}
|
||||
|
||||
const char* spec = reinterpret_cast<char*>
|
||||
(method->spec()->body().begin());
|
||||
const char* spec = reinterpret_cast<char*>(method->spec()->body().begin());
|
||||
pushArguments(t, this_, spec, indirectObjects, arguments);
|
||||
|
||||
return local::invoke(t, method);
|
||||
}
|
||||
|
||||
virtual object
|
||||
invokeList(vm::Thread* vmt, GcClassLoader* loader, const char* className,
|
||||
const char* methodName, const char* methodSpec, object this_,
|
||||
va_list arguments)
|
||||
virtual object invokeList(vm::Thread* vmt,
|
||||
GcClassLoader* loader,
|
||||
const char* className,
|
||||
const char* methodName,
|
||||
const char* methodSpec,
|
||||
object this_,
|
||||
va_list arguments)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
assertT(t, t->state == Thread::ActiveState
|
||||
or t->state == Thread::ExclusiveState);
|
||||
assertT(
|
||||
t,
|
||||
t->state == Thread::ActiveState or t->state == Thread::ExclusiveState);
|
||||
|
||||
if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false)
|
||||
> stackSizeInWords(t) / 2))
|
||||
@ -3236,8 +3240,8 @@ class MyProcessor: public Processor {
|
||||
|
||||
pushArguments(t, this_, methodSpec, false, arguments);
|
||||
|
||||
GcMethod* method = resolveMethod
|
||||
(t, loader, className, methodName, methodSpec);
|
||||
GcMethod* method
|
||||
= resolveMethod(t, loader, className, methodName, methodSpec);
|
||||
|
||||
assertT(t, ((method->flags() & ACC_STATIC) == 0) xor (this_ == 0));
|
||||
|
||||
@ -3258,8 +3262,13 @@ class MyProcessor: public Processor {
|
||||
abort(s);
|
||||
}
|
||||
|
||||
virtual void compileMethod(vm::Thread*, Zone*, GcTriple**, GcTriple**,
|
||||
avian::codegen::DelayedPromise**, GcMethod*, OffsetResolver*)
|
||||
virtual void compileMethod(vm::Thread*,
|
||||
Zone*,
|
||||
GcTriple**,
|
||||
GcTriple**,
|
||||
avian::codegen::DelayedPromise**,
|
||||
GcMethod*,
|
||||
OffsetResolver*)
|
||||
{
|
||||
abort(s);
|
||||
}
|
||||
@ -3288,11 +3297,15 @@ class MyProcessor: public Processor {
|
||||
abort(s);
|
||||
}
|
||||
|
||||
virtual void feedResultToContinuation(vm::Thread*, GcContinuation*, object){
|
||||
virtual void feedResultToContinuation(vm::Thread*, GcContinuation*, object)
|
||||
{
|
||||
abort(s);
|
||||
}
|
||||
|
||||
virtual void feedExceptionToContinuation(vm::Thread*, GcContinuation*, GcThrowable*) {
|
||||
virtual void feedExceptionToContinuation(vm::Thread*,
|
||||
GcContinuation*,
|
||||
GcThrowable*)
|
||||
{
|
||||
abort(s);
|
||||
}
|
||||
|
||||
|
253
src/jnienv.cpp
253
src/jnienv.cpp
@ -150,8 +150,8 @@ GetStringChars(Thread* t, jstring s, jboolean* isCopy)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
jchar* chars = static_cast<jchar*>
|
||||
(t->m->heap->allocate(((*s)->length(t) + 1) * sizeof(jchar)));
|
||||
jchar* chars = static_cast<jchar*>(
|
||||
t->m->heap->allocate(((*s)->length(t) + 1) * sizeof(jchar)));
|
||||
stringChars(t, *s, chars);
|
||||
|
||||
if (isCopy) *isCopy = true;
|
||||
@ -266,9 +266,7 @@ newString(Thread* t, uintptr_t* arguments)
|
||||
}
|
||||
|
||||
return reinterpret_cast<uint64_t>(
|
||||
makeLocalReference(t,
|
||||
t->m->classpath->makeString(
|
||||
t, a, 0, size)));
|
||||
makeLocalReference(t, t->m->classpath->makeString(t, a, 0, size)));
|
||||
}
|
||||
|
||||
jstring JNICALL
|
||||
@ -325,14 +323,14 @@ defineClass(Thread* t, uintptr_t* arguments)
|
||||
|
||||
return reinterpret_cast<uint64_t>(makeLocalReference(
|
||||
t,
|
||||
getJClass(t,
|
||||
cast<GcClass>(
|
||||
t,
|
||||
defineClass(t,
|
||||
loader ? cast<GcClassLoader>(t, *loader)
|
||||
: roots(t)->bootLoader(),
|
||||
buffer,
|
||||
length)))));
|
||||
getJClass(
|
||||
t,
|
||||
cast<GcClass>(t,
|
||||
defineClass(t,
|
||||
loader ? cast<GcClassLoader>(t, *loader)
|
||||
: roots(t)->bootLoader(),
|
||||
buffer,
|
||||
length)))));
|
||||
}
|
||||
|
||||
jclass JNICALL
|
||||
@ -456,8 +454,8 @@ getObjectClass(Thread* t, uintptr_t* arguments)
|
||||
{
|
||||
jobject o = reinterpret_cast<jobject>(arguments[0]);
|
||||
|
||||
return reinterpret_cast<uint64_t>(makeLocalReference(
|
||||
t, getJClass(t, objectClass(t, *o))));
|
||||
return reinterpret_cast<uint64_t>(
|
||||
makeLocalReference(t, getJClass(t, objectClass(t, *o))));
|
||||
}
|
||||
|
||||
jclass JNICALL
|
||||
@ -525,8 +523,7 @@ IsAssignableFrom(Thread* t, jclass b, jclass a)
|
||||
return run(t, isAssignableFrom, arguments);
|
||||
}
|
||||
|
||||
GcMethod*
|
||||
findMethod(Thread* t, jclass c, const char* name, const char* spec)
|
||||
GcMethod* findMethod(Thread* t, jclass c, const char* name, const char* spec)
|
||||
{
|
||||
GcByteArray* n = makeByteArray(t, "%s", name);
|
||||
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);
|
||||
}
|
||||
|
||||
jint
|
||||
methodID(Thread* t, GcMethod* method)
|
||||
jint methodID(Thread* t, GcMethod* method)
|
||||
{
|
||||
int id = method->nativeID();
|
||||
|
||||
@ -548,8 +544,7 @@ methodID(Thread* t, GcMethod* method)
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
if (method->nativeID() == 0) {
|
||||
GcVector* v = vectorAppend(
|
||||
t, roots(t)->jNIMethodTable(), method);
|
||||
GcVector* v = vectorAppend(t, roots(t)->jNIMethodTable(), method);
|
||||
// sequence point, for gc (don't recombine statements)
|
||||
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);
|
||||
}
|
||||
|
||||
GcMethod*
|
||||
getMethod(Thread* t, jmethodID m)
|
||||
GcMethod* getMethod(Thread* t, jmethodID 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);
|
||||
|
||||
@ -675,12 +670,10 @@ newObjectA(Thread* t, uintptr_t* arguments)
|
||||
return reinterpret_cast<uint64_t>(makeLocalReference(t, o));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
NewObjectA(Thread* t, jclass c, jmethodID m, const jvalue* a)
|
||||
jobject JNICALL NewObjectA(Thread* t, jclass c, jmethodID m, const jvalue* a)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
m,
|
||||
reinterpret_cast<uintptr_t>(a) };
|
||||
uintptr_t arguments[]
|
||||
= {reinterpret_cast<uintptr_t>(c), m, reinterpret_cast<uintptr_t>(a)};
|
||||
|
||||
return reinterpret_cast<jobject>(run(t, newObjectA, arguments));
|
||||
}
|
||||
@ -749,8 +742,9 @@ callIntMethodV(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[1];
|
||||
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
||||
|
||||
return cast<GcInt>
|
||||
(t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))->value();
|
||||
return cast<GcInt>(
|
||||
t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))
|
||||
->value();
|
||||
}
|
||||
|
||||
jboolean JNICALL
|
||||
@ -783,8 +777,8 @@ callIntMethodA(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[1];
|
||||
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[2]);
|
||||
|
||||
return cast<GcInt>
|
||||
(t, t->m->processor->invokeArray(t, getMethod(t, m), *o, a))->value();
|
||||
return cast<GcInt>(t, t->m->processor->invokeArray(t, getMethod(t, m), *o, a))
|
||||
->value();
|
||||
}
|
||||
|
||||
jboolean JNICALL
|
||||
@ -936,8 +930,9 @@ callLongMethodV(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[1];
|
||||
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
|
||||
|
||||
return cast<GcLong>
|
||||
(t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))->value();
|
||||
return cast<GcLong>(
|
||||
t, t->m->processor->invokeList(t, getMethod(t, m), *o, true, *a))
|
||||
->value();
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
@ -970,8 +965,9 @@ callLongMethodA(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[1];
|
||||
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[2]);
|
||||
|
||||
return cast<GcLong>
|
||||
(t, t->m->processor->invokeArray(t, getMethod(t, m), *o, a))->value();
|
||||
return cast<GcLong>(t,
|
||||
t->m->processor->invokeArray(t, getMethod(t, m), *o, a))
|
||||
->value();
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
@ -1105,12 +1101,12 @@ CallVoidMethodA(Thread* t, jobject o, jmethodID m, const jvalue* a)
|
||||
run(t, callVoidMethodA, arguments);
|
||||
}
|
||||
|
||||
GcMethod*
|
||||
getStaticMethod(Thread* t, jmethodID m)
|
||||
GcMethod* getStaticMethod(Thread* t, jmethodID 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);
|
||||
|
||||
@ -1174,8 +1170,9 @@ callStaticIntMethodV(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[0];
|
||||
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
|
||||
|
||||
return cast<GcInt>
|
||||
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a))->value();
|
||||
return cast<GcInt>(t,
|
||||
t->m->processor->invokeList(
|
||||
t, getStaticMethod(t, m), 0, true, *a))->value();
|
||||
}
|
||||
|
||||
jboolean JNICALL
|
||||
@ -1205,8 +1202,9 @@ callStaticIntMethodA(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[0];
|
||||
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[1]);
|
||||
|
||||
return cast<GcInt>
|
||||
(t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))->value();
|
||||
return cast<GcInt>(
|
||||
t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))
|
||||
->value();
|
||||
}
|
||||
|
||||
jboolean JNICALL
|
||||
@ -1339,8 +1337,9 @@ callStaticLongMethodV(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[0];
|
||||
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
|
||||
|
||||
return cast<GcLong>
|
||||
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a))->value();
|
||||
return cast<GcLong>(t,
|
||||
t->m->processor->invokeList(
|
||||
t, getStaticMethod(t, m), 0, true, *a))->value();
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
@ -1370,8 +1369,9 @@ callStaticLongMethodA(Thread* t, uintptr_t* arguments)
|
||||
jmethodID m = arguments[0];
|
||||
const jvalue* a = reinterpret_cast<const jvalue*>(arguments[1]);
|
||||
|
||||
return cast<GcLong>
|
||||
(t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))->value();
|
||||
return cast<GcLong>(
|
||||
t, t->m->processor->invokeArray(t, getStaticMethod(t, m), 0, a))
|
||||
->value();
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
@ -1489,8 +1489,7 @@ CallStaticVoidMethodA(Thread* t, jclass, jmethodID m, const jvalue* a)
|
||||
run(t, callStaticVoidMethodA, arguments);
|
||||
}
|
||||
|
||||
jint
|
||||
fieldID(Thread* t, GcField* field)
|
||||
jint fieldID(Thread* t, GcField* field)
|
||||
{
|
||||
int id = field->nativeID();
|
||||
|
||||
@ -1502,8 +1501,7 @@ fieldID(Thread* t, GcField* field)
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
if (field->nativeID() == 0) {
|
||||
GcVector* v = vectorAppend(
|
||||
t, roots(t)->jNIFieldTable(), field);
|
||||
GcVector* v = vectorAppend(t, roots(t)->jNIFieldTable(), field);
|
||||
// sequence point, for gc (don't recombine statements)
|
||||
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);
|
||||
}
|
||||
|
||||
GcField*
|
||||
getField(Thread* t, jfieldID f)
|
||||
GcField* getField(Thread* t, jfieldID f)
|
||||
{
|
||||
assertT(t, f);
|
||||
|
||||
@ -1567,8 +1564,8 @@ getObjectField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return reinterpret_cast<uintptr_t>
|
||||
(makeLocalReference(t, fieldAtOffset<object>(*o, field->offset())));
|
||||
return reinterpret_cast<uintptr_t>(
|
||||
makeLocalReference(t, fieldAtOffset<object>(*o, field->offset())));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
@ -1975,8 +1972,7 @@ SetDoubleField(Thread* t, jobject o, jfieldID field, jdouble v)
|
||||
run(t, setDoubleField, arguments);
|
||||
}
|
||||
|
||||
GcField*
|
||||
getStaticField(Thread* t, jfieldID f)
|
||||
GcField* getStaticField(Thread* t, jfieldID f)
|
||||
{
|
||||
assertT(t, f);
|
||||
|
||||
@ -1999,14 +1995,11 @@ getStaticObjectField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return reinterpret_cast<uintptr_t>
|
||||
(makeLocalReference
|
||||
(t, fieldAtOffset<object>
|
||||
(c->vmClass()->staticTable(), field->offset())));
|
||||
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
||||
t, fieldAtOffset<object>(c->vmClass()->staticTable(), field->offset())));
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
GetStaticObjectField(Thread* t, jclass c, jfieldID field)
|
||||
jobject JNICALL GetStaticObjectField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2026,12 +2019,10 @@ getStaticBooleanField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return fieldAtOffset<jboolean>
|
||||
(c->vmClass()->staticTable(), field->offset());
|
||||
return fieldAtOffset<jboolean>(c->vmClass()->staticTable(), field->offset());
|
||||
}
|
||||
|
||||
jboolean JNICALL
|
||||
GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
|
||||
jboolean JNICALL GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2051,12 +2042,10 @@ getStaticByteField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return fieldAtOffset<jbyte>
|
||||
(c->vmClass()->staticTable(), field->offset());
|
||||
return fieldAtOffset<jbyte>(c->vmClass()->staticTable(), field->offset());
|
||||
}
|
||||
|
||||
jbyte JNICALL
|
||||
GetStaticByteField(Thread* t, jclass c, jfieldID field)
|
||||
jbyte JNICALL GetStaticByteField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2076,12 +2065,10 @@ getStaticCharField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return fieldAtOffset<jchar>
|
||||
(c->vmClass()->staticTable(), field->offset());
|
||||
return fieldAtOffset<jchar>(c->vmClass()->staticTable(), field->offset());
|
||||
}
|
||||
|
||||
jchar JNICALL
|
||||
GetStaticCharField(Thread* t, jclass c, jfieldID field)
|
||||
jchar JNICALL GetStaticCharField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2101,12 +2088,10 @@ getStaticShortField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return fieldAtOffset<jshort>
|
||||
(c->vmClass()->staticTable(), field->offset());
|
||||
return fieldAtOffset<jshort>(c->vmClass()->staticTable(), field->offset());
|
||||
}
|
||||
|
||||
jshort JNICALL
|
||||
GetStaticShortField(Thread* t, jclass c, jfieldID field)
|
||||
jshort JNICALL GetStaticShortField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2126,12 +2111,10 @@ getStaticIntField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return fieldAtOffset<jint>
|
||||
(c->vmClass()->staticTable(), field->offset());
|
||||
return fieldAtOffset<jint>(c->vmClass()->staticTable(), field->offset());
|
||||
}
|
||||
|
||||
jint JNICALL
|
||||
GetStaticIntField(Thread* t, jclass c, jfieldID field)
|
||||
jint JNICALL GetStaticIntField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2151,12 +2134,10 @@ getStaticLongField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return fieldAtOffset<jlong>
|
||||
(c->vmClass()->staticTable(), field->offset());
|
||||
return fieldAtOffset<jlong>(c->vmClass()->staticTable(), field->offset());
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
GetStaticLongField(Thread* t, jclass c, jfieldID field)
|
||||
jlong JNICALL GetStaticLongField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2176,13 +2157,11 @@ getStaticFloatField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return floatToBits
|
||||
(fieldAtOffset<jfloat>
|
||||
(c->vmClass()->staticTable(), field->offset()));
|
||||
return floatToBits(
|
||||
fieldAtOffset<jfloat>(c->vmClass()->staticTable(), field->offset()));
|
||||
}
|
||||
|
||||
jfloat JNICALL
|
||||
GetStaticFloatField(Thread* t, jclass c, jfieldID field)
|
||||
jfloat JNICALL GetStaticFloatField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2202,13 +2181,11 @@ getStaticDoubleField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_READ(t, field);
|
||||
|
||||
return doubleToBits
|
||||
(fieldAtOffset<jdouble>
|
||||
(c->vmClass()->staticTable(), field->offset()));
|
||||
return doubleToBits(
|
||||
fieldAtOffset<jdouble>(c->vmClass()->staticTable(), field->offset()));
|
||||
}
|
||||
|
||||
jdouble JNICALL
|
||||
GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
|
||||
jdouble JNICALL GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field };
|
||||
@ -2229,14 +2206,13 @@ setStaticObjectField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
setField(t, c->vmClass()->staticTable(), field->offset(),
|
||||
(v ? *v : 0));
|
||||
setField(t, c->vmClass()->staticTable(), field->offset(), (v ? *v : 0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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),
|
||||
field,
|
||||
@ -2258,14 +2234,13 @@ setStaticBooleanField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jboolean>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jboolean>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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),
|
||||
field,
|
||||
@ -2287,14 +2262,12 @@ setStaticByteField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jbyte>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jbyte>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
|
||||
void JNICALL SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field,
|
||||
@ -2316,14 +2289,12 @@ setStaticCharField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jchar>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jchar>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
|
||||
void JNICALL SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field,
|
||||
@ -2345,14 +2316,12 @@ setStaticShortField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jshort>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jshort>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
|
||||
void JNICALL SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field,
|
||||
@ -2374,14 +2343,12 @@ setStaticIntField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jint>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jint>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
|
||||
void JNICALL SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field,
|
||||
@ -2403,14 +2370,12 @@ setStaticLongField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jlong>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jlong>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
|
||||
void JNICALL SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
|
||||
{
|
||||
uintptr_t arguments[2 + (sizeof(jlong) / BytesPerWord)];
|
||||
arguments[0] = reinterpret_cast<uintptr_t>(c);
|
||||
@ -2433,14 +2398,12 @@ setStaticFloatField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jfloat>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jfloat>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
|
||||
void JNICALL SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
|
||||
{
|
||||
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
|
||||
field,
|
||||
@ -2462,14 +2425,13 @@ setStaticDoubleField(Thread* t, uintptr_t* arguments)
|
||||
PROTECT(t, field);
|
||||
ACQUIRE_FIELD_FOR_WRITE(t, field);
|
||||
|
||||
fieldAtOffset<jdouble>
|
||||
(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
fieldAtOffset<jdouble>(c->vmClass()->staticTable(), field->offset()) = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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)];
|
||||
arguments[0] = reinterpret_cast<uintptr_t>(c);
|
||||
@ -2596,7 +2558,8 @@ GetObjectArrayElement(Thread* t, jobjectArray array, jsize index)
|
||||
{
|
||||
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
|
||||
@ -2605,7 +2568,10 @@ SetObjectArrayElement(Thread* t, jobjectArray array, jsize index,
|
||||
{
|
||||
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
|
||||
@ -3003,8 +2969,7 @@ GetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
if (length) {
|
||||
memcpy(dst, &(*array)->body()[offset],
|
||||
length * sizeof(jboolean));
|
||||
memcpy(dst, &(*array)->body()[offset], length * sizeof(jboolean));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3092,8 +3057,7 @@ SetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
if (length) {
|
||||
memcpy(&(*array)->body()[offset], src,
|
||||
length * sizeof(jboolean));
|
||||
memcpy(&(*array)->body()[offset], src, length * sizeof(jboolean));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3291,15 +3255,16 @@ registerNatives(Thread* t, uintptr_t* arguments)
|
||||
const char* sig = methods[i].signature;
|
||||
if (*sig == '!') ++ sig;
|
||||
|
||||
GcMethod* method = findMethodOrNull
|
||||
(t, (*c)->vmClass(), methods[i].name, sig);
|
||||
GcMethod* method
|
||||
= findMethodOrNull(t, (*c)->vmClass(), methods[i].name, sig);
|
||||
|
||||
if (method == 0 or (method->flags() & ACC_NATIVE) == 0) {
|
||||
// The JNI spec says we must throw a NoSuchMethodError in this
|
||||
// case, but that would prevent using a code shrinker like
|
||||
// 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);
|
||||
} else {
|
||||
registerNative(t, method, methods[i].function);
|
||||
@ -3578,9 +3543,11 @@ boot(Thread* t, uintptr_t*)
|
||||
GcString* host = makeString(t, "0.0.0.0");
|
||||
PROTECT(t, host);
|
||||
|
||||
GcMethod* method = resolveMethod
|
||||
(t, roots(t)->bootLoader(), "avian/Traces", "startTraceListener",
|
||||
"(Ljava/lang/String;I)V");
|
||||
GcMethod* method = resolveMethod(t,
|
||||
roots(t)->bootLoader(),
|
||||
"avian/Traces",
|
||||
"startTraceListener",
|
||||
"(Ljava/lang/String;I)V");
|
||||
|
||||
t->m->processor->invoke(t, method, 0, host, atoi(port));
|
||||
}
|
||||
|
1537
src/machine.cpp
1537
src/machine.cpp
File diff suppressed because it is too large
Load Diff
@ -66,8 +66,7 @@ mangle(int8_t c, char* dst)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
|
||||
unsigned jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
|
||||
{
|
||||
unsigned size = 0;
|
||||
|
||||
@ -87,9 +86,9 @@ jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
|
||||
size += 2;
|
||||
|
||||
GcByteArray* methodSpec = method->spec();
|
||||
for (unsigned i = 1; i < methodSpec->length() - 1
|
||||
and methodSpec->body()[i] != ')'; ++i)
|
||||
{
|
||||
for (unsigned i = 1;
|
||||
i < methodSpec->length() - 1 and methodSpec->body()[i] != ')';
|
||||
++i) {
|
||||
size += mangledSize(methodSpec->body()[i]);
|
||||
}
|
||||
}
|
||||
@ -97,9 +96,12 @@ jniNameLength(Thread* t UNUSED, GcMethod* method, bool decorate)
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
makeJNIName(Thread* t UNUSED, const char* prefix, unsigned prefixLength, char* name,
|
||||
GcMethod* method, bool decorate)
|
||||
void makeJNIName(Thread* t UNUSED,
|
||||
const char* prefix,
|
||||
unsigned prefixLength,
|
||||
char* name,
|
||||
GcMethod* method,
|
||||
bool decorate)
|
||||
{
|
||||
memcpy(name, prefix, prefixLength);
|
||||
name += prefixLength;
|
||||
@ -121,9 +123,9 @@ makeJNIName(Thread* t UNUSED, const char* prefix, unsigned prefixLength, char* n
|
||||
*(name++) = '_';
|
||||
|
||||
GcByteArray* methodSpec = method->spec();
|
||||
for (unsigned i = 1; i < methodSpec->length() - 1
|
||||
and methodSpec->body()[i] != ')'; ++i)
|
||||
{
|
||||
for (unsigned i = 1;
|
||||
i < methodSpec->length() - 1 and methodSpec->body()[i] != ')';
|
||||
++i) {
|
||||
name += mangle(methodSpec->body()[i], name);
|
||||
}
|
||||
}
|
||||
@ -149,9 +151,11 @@ resolveNativeMethod(Thread* t, const char* undecorated, const char* decorated)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
resolveNativeMethod(Thread* t, GcMethod* method, const char* prefix,
|
||||
unsigned prefixLength, int footprint UNUSED)
|
||||
void* resolveNativeMethod(Thread* t,
|
||||
GcMethod* method,
|
||||
const char* prefix,
|
||||
unsigned prefixLength,
|
||||
int footprint UNUSED)
|
||||
{
|
||||
unsigned undecoratedSize = prefixLength + jniNameLength(t, method, false);
|
||||
// extra 6 is for code below:
|
||||
@ -205,8 +209,7 @@ resolveNativeMethod(Thread* t, GcMethod* method, const char* prefix,
|
||||
return 0;
|
||||
}
|
||||
|
||||
GcNative*
|
||||
resolveNativeMethod(Thread* t, GcMethod* method)
|
||||
GcNative* resolveNativeMethod(Thread* t, GcMethod* method)
|
||||
{
|
||||
void* p = resolveNativeMethod(t, method, "Avian_", 6, 3);
|
||||
if (p) {
|
||||
@ -225,8 +228,7 @@ resolveNativeMethod(Thread* t, GcMethod* method)
|
||||
|
||||
namespace vm {
|
||||
|
||||
void
|
||||
resolveNative(Thread* t, GcMethod* method)
|
||||
void resolveNative(Thread* t, GcMethod* method)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -237,7 +239,9 @@ resolveNative(Thread* t, GcMethod* method)
|
||||
if (getMethodRuntimeData(t, method)->native() == 0) {
|
||||
GcNative* native = resolveNativeMethod(t, method);
|
||||
if (UNLIKELY(native == 0)) {
|
||||
throwNew(t, GcUnsatisfiedLinkError::Type, "%s.%s%s",
|
||||
throwNew(t,
|
||||
GcUnsatisfiedLinkError::Type,
|
||||
"%s.%s%s",
|
||||
method->class_()->name()->body().begin(),
|
||||
method->name()->body().begin(),
|
||||
method->spec()->body().begin());
|
||||
@ -255,8 +259,7 @@ resolveNative(Thread* t, GcMethod* method)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
findLineNumber(Thread* t UNUSED, GcMethod* method, unsigned ip)
|
||||
int findLineNumber(Thread* t UNUSED, GcMethod* method, unsigned ip)
|
||||
{
|
||||
if (method->flags() & ACC_NATIVE) {
|
||||
return NativeLine;
|
||||
@ -276,8 +279,7 @@ findLineNumber(Thread* t UNUSED, GcMethod* method, unsigned ip)
|
||||
|
||||
if (ip >= lineNumberIp(ln)
|
||||
and (middle + 1 == lnt->length()
|
||||
or ip < lineNumberIp(lnt->body()[middle + 1])))
|
||||
{
|
||||
or ip < lineNumberIp(lnt->body()[middle + 1]))) {
|
||||
return lineNumberLine(ln);
|
||||
} else if (ip < lineNumberIp(ln)) {
|
||||
top = middle;
|
||||
|
@ -175,23 +175,29 @@ endsWith(const char* suffix, const char* s, unsigned length)
|
||||
and memcmp(suffix, s + (length - suffixLength), suffixLength) == 0;
|
||||
}
|
||||
|
||||
GcVector*
|
||||
getNonStaticFields(Thread* t, GcHashMap* typeMaps, GcClass* c, GcVector* fields,
|
||||
unsigned* count, GcByteArray** array)
|
||||
GcVector* getNonStaticFields(Thread* t,
|
||||
GcHashMap* typeMaps,
|
||||
GcClass* c,
|
||||
GcVector* fields,
|
||||
unsigned* count,
|
||||
GcByteArray** array)
|
||||
{
|
||||
PROTECT(t, typeMaps);
|
||||
PROTECT(t, c);
|
||||
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) {
|
||||
*count += reinterpret_cast<TypeMap*>((*array)->body().begin())
|
||||
->fixedFieldCount;
|
||||
->fixedFieldCount;
|
||||
} else {
|
||||
if (c->super()) {
|
||||
fields = getNonStaticFields
|
||||
(t, typeMaps, c->super(), fields, count, array);
|
||||
fields
|
||||
= getNonStaticFields(t, typeMaps, c->super(), fields, count, array);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
GcVector*
|
||||
allFields(Thread* t, GcHashMap* typeMaps, GcClass* c, unsigned* count, GcByteArray** array)
|
||||
GcVector* allFields(Thread* t,
|
||||
GcHashMap* typeMaps,
|
||||
GcClass* c,
|
||||
unsigned* count,
|
||||
GcByteArray** array)
|
||||
{
|
||||
PROTECT(t, typeMaps);
|
||||
PROTECT(t, c);
|
||||
@ -219,18 +228,21 @@ allFields(Thread* t, GcHashMap* typeMaps, GcClass* c, unsigned* count, GcByteArr
|
||||
GcVector* fields = makeVector(t, 0, 0);
|
||||
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;
|
||||
if (*array) {
|
||||
includeMembers = false;
|
||||
*count += reinterpret_cast<TypeMap*>((*array)->body().begin())
|
||||
->fixedFieldCount;
|
||||
->fixedFieldCount;
|
||||
} else {
|
||||
includeMembers = true;
|
||||
if (c->super()) {
|
||||
fields = getNonStaticFields
|
||||
(t, typeMaps, c->super(), fields, count, array);
|
||||
fields
|
||||
= getNonStaticFields(t, typeMaps, c->super(), fields, count, array);
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,41 +261,54 @@ allFields(Thread* t, GcHashMap* typeMaps, GcClass* c, unsigned* count, GcByteArr
|
||||
return fields;
|
||||
}
|
||||
|
||||
TypeMap*
|
||||
classTypeMap(Thread* t, GcHashMap* typeMaps, object p)
|
||||
TypeMap* classTypeMap(Thread* t, GcHashMap* typeMaps, object p)
|
||||
{
|
||||
return reinterpret_cast<TypeMap*>
|
||||
(cast<GcByteArray>
|
||||
(t, hashMapFind(t, typeMaps, p, objectHash, objectEqual))->body().begin());
|
||||
return reinterpret_cast<TypeMap*>(
|
||||
cast<GcByteArray>(t, hashMapFind(t, typeMaps, p, objectHash, objectEqual))
|
||||
->body()
|
||||
.begin());
|
||||
}
|
||||
|
||||
TypeMap*
|
||||
typeMap(Thread* t, GcHashMap* typeMaps, object p)
|
||||
TypeMap* typeMap(Thread* t, GcHashMap* typeMaps, object p)
|
||||
{
|
||||
return reinterpret_cast<TypeMap*>
|
||||
(cast<GcByteArray>
|
||||
(t, objectClass(t, p) == type(t, GcSingleton::Type)
|
||||
? hashMapFind(t, typeMaps, p, objectHash, objectEqual)
|
||||
: hashMapFind(t, typeMaps, reinterpret_cast<object>(objectClass(t, p)), objectHash, objectEqual))->body().begin());
|
||||
return reinterpret_cast<TypeMap*>(
|
||||
cast<GcByteArray>(
|
||||
t,
|
||||
objectClass(t, p) == type(t, GcSingleton::Type)
|
||||
? hashMapFind(t, typeMaps, p, objectHash, objectEqual)
|
||||
: hashMapFind(t,
|
||||
typeMaps,
|
||||
reinterpret_cast<object>(objectClass(t, p)),
|
||||
objectHash,
|
||||
objectEqual))
|
||||
->body()
|
||||
.begin());
|
||||
}
|
||||
|
||||
unsigned
|
||||
targetFieldOffset(Thread* t, GcHashMap* typeMaps, GcField* field)
|
||||
unsigned targetFieldOffset(Thread* t, GcHashMap* typeMaps, GcField* field)
|
||||
{
|
||||
// if (strcmp(reinterpret_cast<const char*>
|
||||
// (&byteArrayBody(t, className(t, field->class_()), 0)),
|
||||
// "java/lang/Throwable") == 0) trap();
|
||||
|
||||
return ((field->flags() & ACC_STATIC)
|
||||
? typeMap(t, typeMaps, reinterpret_cast<object>(field->class_()->staticTable()))
|
||||
: classTypeMap(t, typeMaps, reinterpret_cast<object>(field->class_())))
|
||||
->targetFixedOffsets()[field->offset()];
|
||||
? typeMap(
|
||||
t,
|
||||
typeMaps,
|
||||
reinterpret_cast<object>(field->class_()->staticTable()))
|
||||
: classTypeMap(
|
||||
t, typeMaps, reinterpret_cast<object>(field->class_())))
|
||||
->targetFixedOffsets()[field->offset()];
|
||||
}
|
||||
|
||||
GcTriple*
|
||||
makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
const char* className, const char* methodName,
|
||||
const char* methodSpec, GcHashMap* typeMaps)
|
||||
GcTriple* makeCodeImage(Thread* t,
|
||||
Zone* zone,
|
||||
BootImage* image,
|
||||
uint8_t* code,
|
||||
const char* className,
|
||||
const char* methodName,
|
||||
const char* methodSpec,
|
||||
GcHashMap* typeMaps)
|
||||
{
|
||||
PROTECT(t, typeMaps);
|
||||
|
||||
@ -291,7 +316,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
|
||||
GcTriple* constants = 0;
|
||||
PROTECT(t, constants);
|
||||
|
||||
|
||||
GcTriple* calls = 0;
|
||||
PROTECT(t, calls);
|
||||
|
||||
@ -302,17 +327,20 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
|
||||
class MyOffsetResolver: public OffsetResolver {
|
||||
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);
|
||||
}
|
||||
|
||||
GcHashMap** typeMaps;
|
||||
} resolver(&typeMaps);
|
||||
|
||||
Finder* finder = static_cast<Finder*>
|
||||
(roots(t)->bootLoader()->as<GcSystemClassLoader>(t)->finder());
|
||||
Finder* finder = static_cast<Finder*>(
|
||||
roots(t)->bootLoader()->as<GcSystemClassLoader>(t)->finder());
|
||||
|
||||
for (Finder::Iterator it(finder); it.hasMore();) {
|
||||
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))
|
||||
{
|
||||
// fprintf(stderr, "pass 1 %.*s\n", nameSize - 6, name);
|
||||
GcClass* c = resolveSystemClass
|
||||
(t, roots(t)->bootLoader(),
|
||||
makeByteArray(t, "%.*s", nameSize - 6, name), true);
|
||||
GcClass* c
|
||||
= resolveSystemClass(t,
|
||||
roots(t)->bootLoader(),
|
||||
makeByteArray(t, "%.*s", nameSize - 6, name),
|
||||
true);
|
||||
|
||||
PROTECT(t, c);
|
||||
|
||||
@ -400,11 +430,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
}
|
||||
}
|
||||
|
||||
GcByteArray* array = makeByteArray
|
||||
(t, TypeMap::sizeInBytes(count + 2, count + 2));
|
||||
GcByteArray* array
|
||||
= makeByteArray(t, TypeMap::sizeInBytes(count + 2, count + 2));
|
||||
|
||||
TypeMap* map = new (array->body().begin()) TypeMap
|
||||
(count + 2, count + 2, count + 2, TypeMap::PoolKind);
|
||||
TypeMap* map = new (array->body().begin())
|
||||
TypeMap(count + 2, count + 2, count + 2, TypeMap::PoolKind);
|
||||
|
||||
for (unsigned i = 0; i < count + 2; ++i) {
|
||||
expect(t, i < map->buildFixedSizeInWords);
|
||||
@ -417,14 +447,21 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
TargetBytesPerWord);
|
||||
}
|
||||
|
||||
hashMapInsert
|
||||
(t, typeMaps, reinterpret_cast<object>(hashMapFind
|
||||
(t, roots(t)->poolMap(), reinterpret_cast<object>(c), objectHash, objectEqual)), reinterpret_cast<object>(array),
|
||||
objectHash);
|
||||
hashMapInsert(
|
||||
t,
|
||||
typeMaps,
|
||||
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);
|
||||
|
||||
unsigned count = 0;
|
||||
@ -442,8 +479,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
buildMemberOffset = 0;
|
||||
targetMemberOffset = 0;
|
||||
|
||||
TypeMap* map = reinterpret_cast<TypeMap*>
|
||||
(array->body().begin());
|
||||
TypeMap* map = reinterpret_cast<TypeMap*>(array->body().begin());
|
||||
|
||||
for (unsigned j = 0; j < map->fixedFieldCount; ++j) {
|
||||
Field* f = map->fixedFields() + j;
|
||||
@ -547,15 +583,21 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
targetMemberOffset = pad(targetMemberOffset, TargetBytesPerWord);
|
||||
}
|
||||
}
|
||||
|
||||
if (hashMapFind(t, typeMaps, reinterpret_cast<object>(c), objectHash, objectEqual) == 0) {
|
||||
GcByteArray* array = makeByteArray
|
||||
(t, TypeMap::sizeInBytes
|
||||
(ceilingDivide(c->fixedSize(), BytesPerWord), memberIndex));
|
||||
|
||||
TypeMap* map = new (array->body().begin()) TypeMap
|
||||
(ceilingDivide(c->fixedSize(), BytesPerWord),
|
||||
ceilingDivide(targetMemberOffset, TargetBytesPerWord), memberIndex);
|
||||
if (hashMapFind(t,
|
||||
typeMaps,
|
||||
reinterpret_cast<object>(c),
|
||||
objectHash,
|
||||
objectEqual) == 0) {
|
||||
GcByteArray* array = makeByteArray(
|
||||
t,
|
||||
TypeMap::sizeInBytes(ceilingDivide(c->fixedSize(), BytesPerWord),
|
||||
memberIndex));
|
||||
|
||||
TypeMap* map = new (array->body().begin())
|
||||
TypeMap(ceilingDivide(c->fixedSize(), BytesPerWord),
|
||||
ceilingDivide(targetMemberOffset, TargetBytesPerWord),
|
||||
memberIndex);
|
||||
|
||||
for (unsigned i = 0; i < memberIndex; ++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;
|
||||
}
|
||||
|
||||
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()) {
|
||||
GcByteArray* array = makeByteArray
|
||||
(t, TypeMap::sizeInBytes
|
||||
(singletonCount(t, c->staticTable()) + 2, staticIndex));
|
||||
GcByteArray* array = makeByteArray(
|
||||
t,
|
||||
TypeMap::sizeInBytes(singletonCount(t, c->staticTable()) + 2,
|
||||
staticIndex));
|
||||
|
||||
TypeMap* map = new (array->body().begin()) TypeMap
|
||||
(singletonCount(t, c->staticTable()) + 2,
|
||||
ceilingDivide(targetStaticOffset, TargetBytesPerWord), staticIndex,
|
||||
TypeMap::SingletonKind);
|
||||
TypeMap* map = new (array->body().begin())
|
||||
TypeMap(singletonCount(t, c->staticTable()) + 2,
|
||||
ceilingDivide(targetStaticOffset, TargetBytesPerWord),
|
||||
staticIndex,
|
||||
TypeMap::SingletonKind);
|
||||
|
||||
for (unsigned i = 0; i < staticIndex; ++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;
|
||||
}
|
||||
|
||||
hashMapInsert
|
||||
(t, typeMaps, reinterpret_cast<object>(c->staticTable()), reinterpret_cast<object>(array), objectHash);
|
||||
hashMapInsert(t,
|
||||
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;
|
||||
PROTECT(t, c);
|
||||
|
||||
c = resolveSystemClass
|
||||
(t, roots(t)->bootLoader(),
|
||||
makeByteArray(t, "%.*s", nameSize - 6, name), true);
|
||||
c = resolveSystemClass(t,
|
||||
roots(t)->bootLoader(),
|
||||
makeByteArray(t, "%.*s", nameSize - 6, name),
|
||||
true);
|
||||
|
||||
if (GcArray* mtable = cast<GcArray>(t, c->methodTable())) {
|
||||
PROTECT(t, mtable);
|
||||
for (unsigned i = 0; i < mtable->length(); ++i) {
|
||||
GcMethod* method = cast<GcMethod>(t, mtable->body()[i]);
|
||||
if (((methodName == 0
|
||||
or ::strcmp
|
||||
(reinterpret_cast<char*>
|
||||
(method->name()->body().begin()), methodName) == 0)
|
||||
or ::strcmp(
|
||||
reinterpret_cast<char*>(method->name()->body().begin()),
|
||||
methodName) == 0)
|
||||
and (methodSpec == 0
|
||||
or ::strcmp
|
||||
(reinterpret_cast<char*>
|
||||
(method->spec()->body().begin()), methodSpec)
|
||||
== 0)))
|
||||
{
|
||||
if (method->code()
|
||||
or (method->flags() & ACC_NATIVE))
|
||||
{
|
||||
or ::strcmp(reinterpret_cast<char*>(
|
||||
method->spec()->body().begin()),
|
||||
methodSpec) == 0))) {
|
||||
if (method->code() or (method->flags() & ACC_NATIVE)) {
|
||||
PROTECT(t, method);
|
||||
|
||||
t->m->processor->compileMethod
|
||||
(t, zone, reinterpret_cast<GcTriple**>(&constants), reinterpret_cast<GcTriple**>(&calls), &addresses, method, &resolver);
|
||||
t->m->processor->compileMethod(
|
||||
t,
|
||||
zone,
|
||||
reinterpret_cast<GcTriple**>(&constants),
|
||||
reinterpret_cast<GcTriple**>(&calls),
|
||||
&addresses,
|
||||
method,
|
||||
&resolver);
|
||||
|
||||
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();
|
||||
if (addendum and addendum->exceptionTable()) {
|
||||
PROTECT(t, addendum);
|
||||
GcShortArray* exceptionTable = cast<GcShortArray>(t, addendum->exceptionTable());
|
||||
GcShortArray* exceptionTable
|
||||
= cast<GcShortArray>(t, addendum->exceptionTable());
|
||||
PROTECT(t, exceptionTable);
|
||||
|
||||
// resolve exception types now to avoid trying to update
|
||||
// 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;
|
||||
|
||||
object o = singletonObject(t, addendum->pool(), index);
|
||||
|
||||
if (objectClass(t, o) == type(t, GcReference::Type)) {
|
||||
o = reinterpret_cast<object>(resolveClass
|
||||
(t, roots(t)->bootLoader(), cast<GcReference>(t, o)->name()));
|
||||
o = reinterpret_cast<object>(
|
||||
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())
|
||||
->listener->resolve(address, 0);
|
||||
->listener->resolve(address, 0);
|
||||
}
|
||||
|
||||
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())) {
|
||||
cast<GcMethod>(t, methods->first())->code()->compiled()
|
||||
-= reinterpret_cast<uintptr_t>(code);
|
||||
-= reinterpret_cast<uintptr_t>(code);
|
||||
}
|
||||
|
||||
t->m->processor->normalizeVirtualThunks(t);
|
||||
@ -700,19 +759,19 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
|
||||
return constants;
|
||||
}
|
||||
|
||||
void
|
||||
visitRoots(Thread* t, BootImage* image, HeapWalker* w, GcTriple* constants)
|
||||
void visitRoots(Thread* t, BootImage* image, HeapWalker* w, GcTriple* constants)
|
||||
{
|
||||
Machine* m = t->m;
|
||||
|
||||
for (HashMapIterator it(t, cast<GcHashMap>(t, roots(t)->bootLoader()->map()));
|
||||
it.hasMore();)
|
||||
{
|
||||
it.hasMore();) {
|
||||
w->visitRoot(it.next()->second());
|
||||
}
|
||||
|
||||
image->bootLoader = w->visitRoot(reinterpret_cast<object>(roots(t)->bootLoader()));
|
||||
image->appLoader = w->visitRoot(reinterpret_cast<object>(roots(t)->appLoader()));
|
||||
image->bootLoader
|
||||
= 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));
|
||||
|
||||
m->processor->visitRoots(t, w);
|
||||
@ -722,8 +781,7 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, GcTriple* constants)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
targetOffset(Thread* t, GcHashMap* typeMaps, object p, unsigned offset)
|
||||
unsigned targetOffset(Thread* t, GcHashMap* typeMaps, object p, unsigned offset)
|
||||
{
|
||||
TypeMap* map = typeMap(t, typeMaps, p);
|
||||
|
||||
@ -739,8 +797,7 @@ targetOffset(Thread* t, GcHashMap* typeMaps, object p, unsigned offset)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
targetSize(Thread* t, GcHashMap* typeMaps, object p)
|
||||
unsigned targetSize(Thread* t, GcHashMap* typeMaps, object p)
|
||||
{
|
||||
TypeMap* map = typeMap(t, typeMaps, p);
|
||||
|
||||
@ -784,14 +841,14 @@ objectMaskCount(TypeMap* map)
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned
|
||||
targetSize(Thread* t, GcHashMap* typeMaps, object referer, unsigned refererOffset,
|
||||
object p)
|
||||
unsigned targetSize(Thread* t,
|
||||
GcHashMap* typeMaps,
|
||||
object referer,
|
||||
unsigned refererOffset,
|
||||
object p)
|
||||
{
|
||||
if (referer
|
||||
and objectClass(t, referer) == type(t, GcClass::Type)
|
||||
and (refererOffset * BytesPerWord) == ClassObjectMask)
|
||||
{
|
||||
if (referer and objectClass(t, referer) == type(t, GcClass::Type)
|
||||
and (refererOffset * BytesPerWord) == ClassObjectMask) {
|
||||
return (TargetBytesPerWord * 2)
|
||||
+ pad
|
||||
(ceilingDivide
|
||||
@ -911,8 +968,7 @@ nonObjectsEqual(TypeMap* map, uint8_t* src, uint8_t* dst)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
|
||||
void copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
|
||||
{
|
||||
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)) {
|
||||
uint16_t fixedSize;
|
||||
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);
|
||||
|
||||
GcClass* c = cast<GcClass>(t, p);
|
||||
PROTECT(t, c);
|
||||
|
||||
if (array) {
|
||||
TypeMap* classMap = reinterpret_cast<TypeMap*>
|
||||
(array->body().begin());
|
||||
TypeMap* classMap = reinterpret_cast<TypeMap*>(array->body().begin());
|
||||
|
||||
fixedSize = targetV2
|
||||
(classMap->targetFixedSizeInWords * TargetBytesPerWord);
|
||||
|
||||
arrayElementSize = classMap->targetArrayElementSizeInBytes;
|
||||
} else if (c->fixedSize() == BytesPerWord * 2
|
||||
and c->arrayElementSize() == BytesPerWord)
|
||||
{
|
||||
and c->arrayElementSize() == BytesPerWord) {
|
||||
fixedSize = targetV2(TargetBytesPerWord * 2);
|
||||
|
||||
arrayElementSize = TargetBytesPerWord;
|
||||
@ -975,7 +1030,8 @@ copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
|
||||
switch (map->kind) {
|
||||
case TypeMap::NormalKind:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
@ -1068,14 +1124,15 @@ copy(Thread* t, GcHashMap* typeMaps, object p, uint8_t* dst)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
copy(Thread* t, GcHashMap* typeMaps, object referer, unsigned refererOffset,
|
||||
object p, uint8_t* dst)
|
||||
void copy(Thread* t,
|
||||
GcHashMap* typeMaps,
|
||||
object referer,
|
||||
unsigned refererOffset,
|
||||
object p,
|
||||
uint8_t* dst)
|
||||
{
|
||||
if (referer
|
||||
and objectClass(t, referer) == type(t, GcClass::Type)
|
||||
and (refererOffset * BytesPerWord) == ClassObjectMask)
|
||||
{
|
||||
if (referer and objectClass(t, referer) == type(t, GcClass::Type)
|
||||
and (refererOffset * BytesPerWord) == ClassObjectMask) {
|
||||
TypeMap* map = classTypeMap(t, typeMaps, referer);
|
||||
|
||||
memset(dst, 0, TargetBytesPerWord);
|
||||
@ -1115,17 +1172,30 @@ copy(Thread* t, GcHashMap* typeMaps, object referer, unsigned refererOffset,
|
||||
}
|
||||
}
|
||||
|
||||
HeapWalker*
|
||||
makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap,
|
||||
target_uintptr_t* map, unsigned capacity, GcTriple* constants,
|
||||
GcHashMap* typeMaps)
|
||||
HeapWalker* makeHeapImage(Thread* t,
|
||||
BootImage* image,
|
||||
target_uintptr_t* heap,
|
||||
target_uintptr_t* map,
|
||||
unsigned capacity,
|
||||
GcTriple* constants,
|
||||
GcHashMap* typeMaps)
|
||||
{
|
||||
class Visitor: public HeapVisitor {
|
||||
public:
|
||||
Visitor(Thread* t, GcHashMap* typeMaps, target_uintptr_t* heap,
|
||||
target_uintptr_t* map, unsigned capacity):
|
||||
t(t), typeMaps(typeMaps), currentObject(0), currentNumber(0),
|
||||
currentOffset(0), heap(heap), map(map), position(0), capacity(capacity)
|
||||
Visitor(Thread* t,
|
||||
GcHashMap* typeMaps,
|
||||
target_uintptr_t* heap,
|
||||
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) {
|
||||
@ -1164,8 +1234,7 @@ makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap,
|
||||
if ((currentObject
|
||||
and objectClass(t, currentObject) == type(t, GcClass::Type)
|
||||
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
|
||||
// as fixed objects in the heap image so that they can be
|
||||
// marked as dirty and visited during GC. Otherwise,
|
||||
@ -1256,17 +1325,17 @@ makeHeapImage(Thread* t, BootImage* image, target_uintptr_t* heap,
|
||||
return w;
|
||||
}
|
||||
|
||||
void
|
||||
updateConstants(Thread* t, GcTriple* constants, HeapMap* heapTable)
|
||||
void updateConstants(Thread* t, GcTriple* constants, HeapMap* heapTable)
|
||||
{
|
||||
for (; constants; constants = cast<GcTriple>(t, constants->third())) {
|
||||
unsigned target = heapTable->find(constants->first());
|
||||
expect(t, target > 0);
|
||||
|
||||
for (Promise::Listener* pl = static_cast<ListenPromise*>
|
||||
(cast<GcPointer>(t, constants->second())->value())->listener;
|
||||
pl; pl = pl->next)
|
||||
{
|
||||
for (Promise::Listener* pl
|
||||
= static_cast<ListenPromise*>(
|
||||
cast<GcPointer>(t, constants->second())->value())->listener;
|
||||
pl;
|
||||
pl = pl->next) {
|
||||
pl->resolve((target - 1) * TargetBytesPerWord, 0);
|
||||
}
|
||||
}
|
||||
@ -1287,7 +1356,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
const char* codeimageStart, const char* codeimageEnd,
|
||||
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)
|
||||
roots(t)->setOutOfMemoryError(t, throwable);
|
||||
|
||||
@ -1460,15 +1530,19 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
targetArrayElementSize = 0;
|
||||
}
|
||||
|
||||
GcByteArray* array = makeByteArray
|
||||
(t, TypeMap::sizeInBytes
|
||||
(ceilingDivide(buildOffset, BytesPerWord), fixedFieldCount));
|
||||
GcByteArray* array = makeByteArray(
|
||||
t,
|
||||
TypeMap::sizeInBytes(ceilingDivide(buildOffset, BytesPerWord),
|
||||
fixedFieldCount));
|
||||
|
||||
TypeMap* map = new (array->body().begin()) TypeMap
|
||||
(ceilingDivide(buildOffset, BytesPerWord),
|
||||
ceilingDivide(targetOffset, TargetBytesPerWord),
|
||||
fixedFieldCount, TypeMap::NormalKind, buildArrayElementSize,
|
||||
targetArrayElementSize, arrayElementType);
|
||||
TypeMap* map = new (array->body().begin())
|
||||
TypeMap(ceilingDivide(buildOffset, BytesPerWord),
|
||||
ceilingDivide(targetOffset, TargetBytesPerWord),
|
||||
fixedFieldCount,
|
||||
TypeMap::NormalKind,
|
||||
buildArrayElementSize,
|
||||
targetArrayElementSize,
|
||||
arrayElementType);
|
||||
|
||||
for (unsigned j = 0; j < fixedFieldCount; ++j) {
|
||||
Field* f = RUNTIME_ARRAY_BODY(fields) + j;
|
||||
@ -1481,9 +1555,12 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
map->fixedFields()[j] = *f;
|
||||
}
|
||||
|
||||
hashMapInsert
|
||||
(t, typeMaps, reinterpret_cast<object>(vm::type(t, static_cast<Gc::Type>(i))), reinterpret_cast<object>(array),
|
||||
objectHash);
|
||||
hashMapInsert(
|
||||
t,
|
||||
typeMaps,
|
||||
reinterpret_cast<object>(vm::type(t, static_cast<Gc::Type>(i))),
|
||||
reinterpret_cast<object>(array),
|
||||
objectHash);
|
||||
}
|
||||
|
||||
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
|
||||
// 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);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// resolve primitive array classes in case they are needed at
|
||||
// runtime:
|
||||
{ GcByteArray* name = makeByteArray(t, "[B");
|
||||
{
|
||||
GcByteArray* name = makeByteArray(t, "[B");
|
||||
resolveSystemClass(t, roots(t)->bootLoader(), name, true);
|
||||
|
||||
name = makeByteArray(t, "[Z");
|
||||
@ -1578,35 +1657,33 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
|
||||
updateConstants(t, constants, heapWalker->map());
|
||||
|
||||
image->bootClassCount = cast<GcHashMap>
|
||||
(t, roots(t)->bootLoader()->map())->size();
|
||||
image->bootClassCount
|
||||
= cast<GcHashMap>(t, roots(t)->bootLoader()->map())->size();
|
||||
|
||||
unsigned* bootClassTable = static_cast<unsigned*>
|
||||
(t->m->heap->allocate(image->bootClassCount * sizeof(unsigned)));
|
||||
|
||||
{ unsigned i = 0;
|
||||
for (HashMapIterator it
|
||||
(t, cast<GcHashMap>(t, roots(t)->bootLoader()->map()));
|
||||
it.hasMore();)
|
||||
{
|
||||
bootClassTable[i++] = targetVW
|
||||
(heapWalker->map()->find(it.next()->second()));
|
||||
for (HashMapIterator it(t,
|
||||
cast<GcHashMap>(t, roots(t)->bootLoader()->map()));
|
||||
it.hasMore();) {
|
||||
bootClassTable[i++]
|
||||
= targetVW(heapWalker->map()->find(it.next()->second()));
|
||||
}
|
||||
}
|
||||
|
||||
image->appClassCount = cast<GcHashMap>
|
||||
(t, roots(t)->appLoader()->map())->size();
|
||||
image->appClassCount
|
||||
= cast<GcHashMap>(t, roots(t)->appLoader()->map())->size();
|
||||
|
||||
unsigned* appClassTable = static_cast<unsigned*>
|
||||
(t->m->heap->allocate(image->appClassCount * sizeof(unsigned)));
|
||||
|
||||
{ unsigned i = 0;
|
||||
for (HashMapIterator it
|
||||
(t, cast<GcHashMap>(t, roots(t)->appLoader()->map()));
|
||||
it.hasMore();)
|
||||
{
|
||||
appClassTable[i++] = targetVW
|
||||
(heapWalker->map()->find(it.next()->second()));
|
||||
for (
|
||||
HashMapIterator it(t, cast<GcHashMap>(t, roots(t)->appLoader()->map()));
|
||||
it.hasMore();) {
|
||||
appClassTable[i++]
|
||||
= targetVW(heapWalker->map()->find(it.next()->second()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1616,9 +1693,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
|
||||
|
||||
{ unsigned i = 0;
|
||||
for (HashMapIterator it(t, roots(t)->stringMap()); it.hasMore();) {
|
||||
stringTable[i++] = targetVW
|
||||
(heapWalker->map()->find
|
||||
(reinterpret_cast<object>(cast<GcJreference>(t, it.next()->first())->target())));
|
||||
stringTable[i++]
|
||||
= targetVW(heapWalker->map()->find(reinterpret_cast<object>(
|
||||
cast<GcJreference>(t, it.next()->first())->target())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -77,16 +77,18 @@ class Field {
|
||||
{
|
||||
}
|
||||
|
||||
std::string dump() const {
|
||||
std::string dump() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "field " << name << ":" << typeName << ":" << javaSpec << ", size=" << elementSize << ", offset=" << offset;
|
||||
if(noassert) {
|
||||
ss << "field " << name << ":" << typeName << ":" << javaSpec
|
||||
<< ", size=" << elementSize << ", offset=" << offset;
|
||||
if (noassert) {
|
||||
ss << " noassert";
|
||||
}
|
||||
if(nogc) {
|
||||
if (nogc) {
|
||||
ss << " nogc";
|
||||
}
|
||||
if(polyfill) {
|
||||
if (polyfill) {
|
||||
ss << " polyfill";
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
bool operator < (const Method& o) const {
|
||||
return javaName < o.javaName || (javaName == o.javaName && javaSpec < o.javaSpec);
|
||||
bool operator<(const Method& o) const
|
||||
{
|
||||
return javaName < o.javaName
|
||||
|| (javaName == o.javaName && javaSpec < o.javaSpec);
|
||||
}
|
||||
std::string dump() const {
|
||||
std::string dump() const
|
||||
{
|
||||
return "method " + javaName + javaSpec;
|
||||
}
|
||||
};
|
||||
@ -134,33 +140,44 @@ class Class {
|
||||
|
||||
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;
|
||||
ss << "class " << name;
|
||||
if(javaName.size() > 0) {
|
||||
if (javaName.size() > 0) {
|
||||
ss << "(" << javaName << ")";
|
||||
}
|
||||
if(super) {
|
||||
if (super) {
|
||||
ss << " : " << super->name << "(" << super->javaName << ")";
|
||||
}
|
||||
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";
|
||||
}
|
||||
|
||||
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 << "}";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void dumpToStdout() const AVIAN_EXPORT {
|
||||
void dumpToStdout() const AVIAN_EXPORT
|
||||
{
|
||||
printf("%s\n", dump().c_str());
|
||||
}
|
||||
};
|
||||
@ -172,10 +189,11 @@ class Module {
|
||||
|
||||
std::map<std::string, Class*> classes;
|
||||
|
||||
void add(Class* cl) {
|
||||
void add(Class* cl)
|
||||
{
|
||||
assert(classes.find(cl->name) == classes.end());
|
||||
classes[cl->name] = cl;
|
||||
if(cl->javaName != "") {
|
||||
if (cl->javaName != "") {
|
||||
assert(javaClasses.find(cl->javaName) == javaClasses.end());
|
||||
javaClasses[cl->javaName] = cl;
|
||||
}
|
||||
@ -191,19 +209,17 @@ namespace {
|
||||
namespace local {
|
||||
|
||||
#ifndef POINTER_SIZE
|
||||
# define POINTER_SIZE sizeof(void*)
|
||||
#define POINTER_SIZE sizeof(void*)
|
||||
#endif
|
||||
|
||||
const unsigned BytesPerWord = POINTER_SIZE;
|
||||
|
||||
inline bool
|
||||
equal(const char* a, const char* b)
|
||||
inline bool equal(const char* a, const char* b)
|
||||
{
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
endsWith(const std::string& b, const std::string& a)
|
||||
inline bool endsWith(const std::string& b, const std::string& a)
|
||||
{
|
||||
if (b.size() > a.size()) {
|
||||
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());
|
||||
}
|
||||
|
||||
std::string enumName(Module& module, Field& f) {
|
||||
std::string enumName(Module& module, Field& f)
|
||||
{
|
||||
std::string& type = f.typeName;
|
||||
if (type == "void*") {
|
||||
return "word";
|
||||
} else if(type == "maybe_object") {
|
||||
} else if (type == "maybe_object") {
|
||||
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";
|
||||
}
|
||||
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
|
||||
assert(f.typeName.size() > 0);
|
||||
if(it != module.classes.end()) {
|
||||
if (it != module.classes.end()) {
|
||||
return "object";
|
||||
} else {
|
||||
return f.typeName;
|
||||
@ -288,10 +306,9 @@ class Singleton : public Object {
|
||||
}
|
||||
};
|
||||
|
||||
std::string
|
||||
capitalize(const std::string& s)
|
||||
std::string 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 s;
|
||||
@ -358,20 +375,15 @@ read(Input* in, Object* eos, int level)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
namesPointer(const std::string& s)
|
||||
bool namesPointer(const std::string& s)
|
||||
{
|
||||
return s == "Collector"
|
||||
or s == "Disposer"
|
||||
or endsWith("*", s);
|
||||
return s == "Collector" or s == "Disposer" or endsWith("*", s);
|
||||
}
|
||||
|
||||
unsigned
|
||||
sizeOf(Module& module, const std::string& type)
|
||||
unsigned sizeOf(Module& module, const std::string& type)
|
||||
{
|
||||
if (type == "object"
|
||||
or type == "intptr_t" or type == "uintptr_t" or type == "maybe_object")
|
||||
{
|
||||
if (type == "object" or type == "intptr_t" or type == "uintptr_t"
|
||||
or type == "maybe_object") {
|
||||
return BytesPerWord;
|
||||
} else if (type == "unsigned" or type == "int") {
|
||||
return sizeof(int);
|
||||
@ -393,7 +405,7 @@ sizeOf(Module& module, const std::string& type)
|
||||
return BytesPerWord;
|
||||
} else {
|
||||
std::map<std::string, Class*>::iterator it = module.classes.find(type);
|
||||
if(it != module.classes.end()) {
|
||||
if (it != module.classes.end()) {
|
||||
return BytesPerWord;
|
||||
} else {
|
||||
fprintf(stderr, "unexpected type: %s\n", type.c_str());
|
||||
@ -408,9 +420,14 @@ struct FieldSpec {
|
||||
bool require;
|
||||
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 {
|
||||
@ -422,9 +439,10 @@ class ClassParser {
|
||||
{
|
||||
}
|
||||
|
||||
void add(FieldSpec f) {
|
||||
if(f.field->polyfill) {
|
||||
if(fields.find(f.field->name) == fields.end()) {
|
||||
void add(FieldSpec f)
|
||||
{
|
||||
if (f.field->polyfill) {
|
||||
if (fields.find(f.field->name) == fields.end()) {
|
||||
fields[f.field->name] = f.field;
|
||||
cl->fields.push_back(f.field);
|
||||
} else {
|
||||
@ -432,11 +450,13 @@ class ClassParser {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(f.aliasName.size() > 0) {
|
||||
if(fields.find(f.aliasName) == 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());
|
||||
std::map<std::string, Field*>::iterator it = fields.find(f.field->name);
|
||||
if (f.aliasName.size() > 0) {
|
||||
if (fields.find(f.aliasName) == 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());
|
||||
std::map<std::string, Field*>::iterator it
|
||||
= fields.find(f.field->name);
|
||||
assert(it != fields.end());
|
||||
Field* renamed = it->second;
|
||||
fields.erase(it);
|
||||
@ -444,20 +464,24 @@ class ClassParser {
|
||||
|
||||
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->javaSpec = f.field->javaSpec;
|
||||
} 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 {
|
||||
// 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 {
|
||||
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());
|
||||
fields[f.field->name] = f.field;
|
||||
if(f.isArray) {
|
||||
if (f.isArray) {
|
||||
add(FieldSpec(false, new Field(cl, "uintptr_t", "", "length")));
|
||||
assert(!cl->arrayField);
|
||||
cl->arrayField = f.field;
|
||||
@ -465,7 +489,8 @@ class ClassParser {
|
||||
cl->fields.push_back(f.field);
|
||||
}
|
||||
} 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);
|
||||
fields[f.field->name]->nogc |= f.field->nogc;
|
||||
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);
|
||||
cl->super = super;
|
||||
assert(!super->arrayField);
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -495,12 +523,11 @@ FieldSpec parseArray(Module&, ClassParser& clparser, Object* p)
|
||||
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* name = string(car(cdr(p)));
|
||||
return FieldSpec(
|
||||
false,
|
||||
new Field(clparser.cl, spec, "", name));
|
||||
return FieldSpec(false, new Field(clparser.cl, spec, "", name));
|
||||
}
|
||||
|
||||
FieldSpec parseField(Module& module, ClassParser& clparser, Object* p)
|
||||
@ -535,8 +562,7 @@ FieldSpec parseField(Module& module, ClassParser& clparser, Object* p)
|
||||
return f;
|
||||
}
|
||||
|
||||
void
|
||||
parseSubdeclaration(Module& module, ClassParser& clparser, Object* p)
|
||||
void parseSubdeclaration(Module& module, ClassParser& clparser, Object* p)
|
||||
{
|
||||
const char* front = string(car(p));
|
||||
if (equal(front, "extends")) {
|
||||
@ -592,8 +618,7 @@ fieldType(const char* spec)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
|
||||
void parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
|
||||
{
|
||||
uint32_t magic = s->read4();
|
||||
assert(magic == 0xCAFEBABE);
|
||||
@ -659,8 +684,8 @@ parseJavaClass(Module& module, ClassParser& clparser, Stream* s)
|
||||
s->skip(interfaceCount * 2);
|
||||
// for (unsigned i = 0; i < interfaceCount; ++i) {
|
||||
// const char* name = reinterpret_cast<const char*>
|
||||
// (pool[pool[s->read2() - 1] - 1]);
|
||||
// }
|
||||
// (pool[pool[s->read2() - 1] - 1]);
|
||||
// }
|
||||
|
||||
unsigned fieldCount = s->read2();
|
||||
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* 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) {
|
||||
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();
|
||||
@ -782,8 +809,9 @@ void parse(Finder* finder, Input* in, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void layoutClass(Module& module, Class* cl) {
|
||||
if(cl->fixedSize >= 0) {
|
||||
void layoutClass(Module& module, Class* cl)
|
||||
{
|
||||
if (cl->fixedSize >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -794,12 +822,14 @@ void layoutClass(Module& module, Class* cl) {
|
||||
|
||||
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;
|
||||
|
||||
f.elementSize = sizeOf(module, f.typeName);
|
||||
|
||||
if(!f.polyfill) { // polyfills contribute no size
|
||||
if (!f.polyfill) { // polyfills contribute no size
|
||||
alignment = f.elementSize;
|
||||
offset = (offset + alignment - 1) & ~(alignment - 1);
|
||||
f.offset = offset;
|
||||
@ -809,7 +839,7 @@ void layoutClass(Module& module, Class* cl) {
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
Field& f = *cl->arrayField;
|
||||
|
||||
f.elementSize = sizeOf(module, f.typeName);
|
||||
@ -824,65 +854,68 @@ void layoutClass(Module& module, Class* cl) {
|
||||
|
||||
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;
|
||||
layoutClass(module, cl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeOffset(Output* out, size_t offset)
|
||||
void writeOffset(Output* out, size_t offset)
|
||||
{
|
||||
out->write(offset);
|
||||
}
|
||||
|
||||
void
|
||||
writeOffset(Output* out, Class* cl)
|
||||
void writeOffset(Output* out, Class* cl)
|
||||
{
|
||||
out->write(cl->fixedSize);
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
out->write(" + pad(length * ");
|
||||
out->write(cl->arrayField->elementSize);
|
||||
out->write(")");
|
||||
}
|
||||
}
|
||||
|
||||
std::string cppClassName(Class* cl) {
|
||||
if(cl->name == "jobject") {
|
||||
std::string cppClassName(Class* cl)
|
||||
{
|
||||
if (cl->name == "jobject") {
|
||||
return "object";
|
||||
} else {
|
||||
return "Gc" + capitalize(cl->name) + "*";
|
||||
}
|
||||
}
|
||||
|
||||
std::string cppFieldType(Module& module, Field& f) {
|
||||
if(f.javaSpec.size() != 0) {
|
||||
if(f.javaSpec[0] == 'L') {
|
||||
std::string cppFieldType(Module& module, Field& f)
|
||||
{
|
||||
if (f.javaSpec.size() != 0) {
|
||||
if (f.javaSpec[0] == 'L') {
|
||||
std::string className = f.javaSpec.substr(1, f.javaSpec.size() - 2);
|
||||
std::map<std::string, Class*>::iterator it = module.javaClasses.find(className);
|
||||
if(it != module.javaClasses.end()) {
|
||||
std::map<std::string, Class*>::iterator it
|
||||
= module.javaClasses.find(className);
|
||||
if (it != module.javaClasses.end()) {
|
||||
return cppClassName(it->second);
|
||||
}
|
||||
} else if(f.javaSpec[0] == '[') {
|
||||
std::map<std::string, Class*>::iterator it = module.javaClasses.find(f.javaSpec);
|
||||
if(it != module.javaClasses.end()) {
|
||||
} else if (f.javaSpec[0] == '[') {
|
||||
std::map<std::string, Class*>::iterator it
|
||||
= module.javaClasses.find(f.javaSpec);
|
||||
if (it != module.javaClasses.end()) {
|
||||
return cppClassName(it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
|
||||
assert(f.typeName.size() > 0);
|
||||
if(it != module.classes.end()) {
|
||||
if (it != module.classes.end()) {
|
||||
return cppClassName(it->second);
|
||||
} else if(f.typeName == "maybe_object") {
|
||||
} else if (f.typeName == "maybe_object") {
|
||||
return "uintptr_t";
|
||||
} else {
|
||||
return f.typeName;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeAccessor(Output* out, Class* cl, Field& field)
|
||||
void writeAccessor(Output* out, Class* cl, Field& field)
|
||||
{
|
||||
std::string typeName = field.typeName;
|
||||
|
||||
@ -899,28 +932,32 @@ writeAccessor(Output* out, Class* cl, Field& field)
|
||||
out->write(" 1\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
writeAccessors(Output* out, Module& module)
|
||||
void 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;
|
||||
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;
|
||||
|
||||
if(!f.polyfill) {
|
||||
if (!f.polyfill) {
|
||||
writeAccessor(out, cl, f);
|
||||
}
|
||||
}
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
writeAccessor(out, cl, *cl->arrayField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeSizes(Output* out, Module& module)
|
||||
void 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;
|
||||
|
||||
out->write("const unsigned FixedSizeOf");
|
||||
@ -939,8 +976,7 @@ writeSizes(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
obfuscate(const std::string& s)
|
||||
std::string obfuscate(const std::string& s)
|
||||
{
|
||||
if (s == "default" || s == "template" || s == "class" || s == "register"
|
||||
|| s == "this") {
|
||||
@ -950,12 +986,13 @@ obfuscate(const std::string& s)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeConstructorParameters(Output* out, Module& module, Class* cl)
|
||||
void 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;
|
||||
if(!f.polyfill) {
|
||||
if (!f.polyfill) {
|
||||
out->write(", ");
|
||||
out->write(cppFieldType(module, f));
|
||||
out->write(" ");
|
||||
@ -964,24 +1001,26 @@ writeConstructorParameters(Output* out, Module& module, Class* cl)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeConstructorArguments(Output* out, Class* cl)
|
||||
void 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;
|
||||
if(!f.polyfill) {
|
||||
if (!f.polyfill) {
|
||||
out->write(", ");
|
||||
out->write(obfuscate(f.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeConstructorInitializations(Output* out, Class* cl)
|
||||
void 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;
|
||||
if(!f.polyfill) {
|
||||
if (!f.polyfill) {
|
||||
out->write(" o->set");
|
||||
out->write(capitalize(f.name));
|
||||
out->write("(t, ");
|
||||
@ -991,10 +1030,11 @@ writeConstructorInitializations(Output* out, Class* cl)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
out->write("class Gc");
|
||||
@ -1004,26 +1044,31 @@ void writeClassDeclarations(Output* out, Module& module)
|
||||
out->write("\n");
|
||||
}
|
||||
|
||||
bool isFieldGcVisible(Module& module, Field& f) {
|
||||
bool isFieldGcVisible(Module& module, Field& f)
|
||||
{
|
||||
return enumName(module, f) == "object" && !f.nogc;
|
||||
}
|
||||
|
||||
bool isFieldGcMarkable(Module& module, Field& f) {
|
||||
return (f.typeName == "maybe_object" || enumName(module, f) == "object") && !f.nogc;
|
||||
bool isFieldGcMarkable(Module& module, Field& f)
|
||||
{
|
||||
return (f.typeName == "maybe_object" || enumName(module, f) == "object")
|
||||
&& !f.nogc;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(!f.polyfill) {
|
||||
if (!f.polyfill) {
|
||||
out->write(" void set");
|
||||
out->write(capitalize(f.name));
|
||||
out->write("(Thread* t UNUSED, ");
|
||||
out->write(cppFieldType(module, f));
|
||||
out->write(" value) { ");
|
||||
if(isFieldGcMarkable(module, f)) {
|
||||
if (isFieldGcMarkable(module, f)) {
|
||||
out->write("setField(t, this , ");
|
||||
out->write(capitalize(cl->name));
|
||||
out->write(capitalize(f.name));
|
||||
@ -1052,17 +1097,17 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
|
||||
|
||||
out->write(" ");
|
||||
out->write(cppFieldType(module, f));
|
||||
if(!f.polyfill && !isFieldGcMarkable(module, f)) {
|
||||
if (!f.polyfill && !isFieldGcMarkable(module, f)) {
|
||||
out->write("&");
|
||||
}
|
||||
out->write(" ");
|
||||
out->write(obfuscate(f.name));
|
||||
if(f.threadParam || f.polyfill) {
|
||||
if (f.threadParam || f.polyfill) {
|
||||
out->write("(Thread*");
|
||||
} else {
|
||||
out->write("(");
|
||||
}
|
||||
if(f.polyfill) {
|
||||
if (f.polyfill) {
|
||||
out->write("); // polyfill, assumed to be implemented elsewhere\n");
|
||||
} else {
|
||||
out->write(") { return field_at<");
|
||||
@ -1073,22 +1118,22 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
|
||||
out->write("); }\n");
|
||||
}
|
||||
}
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
Field& f = *cl->arrayField;
|
||||
out->write(" avian::util::Slice<");
|
||||
if(isFieldGcVisible(module, f)) {
|
||||
if (isFieldGcVisible(module, f)) {
|
||||
out->write("const ");
|
||||
}
|
||||
out->write(cppFieldType(module, f));
|
||||
out->write("> ");
|
||||
out->write(obfuscate(f.name));
|
||||
out->write("() { return avian::util::Slice<");
|
||||
if(isFieldGcVisible(module, f)) {
|
||||
if (isFieldGcVisible(module, f)) {
|
||||
out->write("const ");
|
||||
}
|
||||
out->write(cppFieldType(module, f));
|
||||
out->write("> (&field_at<");
|
||||
if(isFieldGcVisible(module, f)) {
|
||||
if (isFieldGcVisible(module, f)) {
|
||||
out->write("const ");
|
||||
}
|
||||
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(cppFieldType(module, f));
|
||||
out->write(" value) { ");
|
||||
if(isFieldGcMarkable(module, f)) {
|
||||
if (isFieldGcMarkable(module, f)) {
|
||||
out->write("setField(t, this , ");
|
||||
out->write(capitalize(cl->name));
|
||||
out->write(capitalize(f.name));
|
||||
@ -1127,7 +1172,9 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
|
||||
|
||||
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;
|
||||
|
||||
out->write("class Gc");
|
||||
@ -1147,10 +1194,11 @@ void writeClasses(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeInitializerDeclarations(Output* out, Module& module)
|
||||
void 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;
|
||||
out->write("void init");
|
||||
out->write(capitalize(cl->name));
|
||||
@ -1164,10 +1212,11 @@ writeInitializerDeclarations(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeConstructorDeclarations(Output* out, Module& module)
|
||||
void 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;
|
||||
out->write("Gc");
|
||||
out->write(capitalize(cl->name));
|
||||
@ -1181,10 +1230,11 @@ writeConstructorDeclarations(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeInitializers(Output* out, Module& module)
|
||||
void 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;
|
||||
out->write("void init");
|
||||
out->write(capitalize(cl->name));
|
||||
@ -1197,7 +1247,9 @@ writeInitializers(Output* out, Module& module)
|
||||
out->write(")\n{\n");
|
||||
|
||||
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("Type]));\n");
|
||||
|
||||
@ -1207,10 +1259,11 @@ writeInitializers(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeConstructors(Output* out, Module& module)
|
||||
void 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;
|
||||
out->write("Gc");
|
||||
out->write(capitalize(cl->name));
|
||||
@ -1223,11 +1276,11 @@ writeConstructors(Output* out, Module& module)
|
||||
out->write(")\n{\n");
|
||||
|
||||
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;
|
||||
if (enumName(module, f) == "object"
|
||||
and not f.nogc)
|
||||
{
|
||||
if (enumName(module, f) == "object" and not f.nogc) {
|
||||
out->write(" PROTECT(t, ");
|
||||
out->write(obfuscate(f.name));
|
||||
out->write(");\n");
|
||||
@ -1235,7 +1288,7 @@ writeConstructors(Output* out, Module& module)
|
||||
hasObjectMask = true;
|
||||
}
|
||||
}
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
Field& f = *cl->arrayField;
|
||||
if (f.typeName == "object" and not f.nogc) {
|
||||
hasObjectMask = true;
|
||||
@ -1265,11 +1318,12 @@ writeConstructors(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeEnums(Output* out, Module& module)
|
||||
void writeEnums(Output* out, Module& module)
|
||||
{
|
||||
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;
|
||||
if (wrote) {
|
||||
out->write(",\n");
|
||||
@ -1295,26 +1349,27 @@ set(uint32_t* mask, unsigned index)
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
typeObjectMask(Module& module, Class* cl)
|
||||
uint32_t typeObjectMask(Module& module, Class* cl)
|
||||
{
|
||||
assert(cl->fixedSize + (cl->arrayField ? cl->arrayField->elementSize : 0)
|
||||
< 32 * BytesPerWord);
|
||||
|
||||
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;
|
||||
unsigned offset = f.offset / BytesPerWord;
|
||||
if(isFieldGcVisible(module, f)) {
|
||||
if (isFieldGcVisible(module, f)) {
|
||||
set(&mask, offset);
|
||||
}
|
||||
}
|
||||
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
Field& f = *cl->arrayField;
|
||||
unsigned offset = f.offset / BytesPerWord;
|
||||
if(isFieldGcVisible(module, f)) {
|
||||
if (isFieldGcVisible(module, f)) {
|
||||
set(&mask, offset);
|
||||
}
|
||||
}
|
||||
@ -1322,14 +1377,16 @@ typeObjectMask(Module& module, Class* cl)
|
||||
return mask;
|
||||
}
|
||||
|
||||
void
|
||||
writeInitialization(Output* out, Module& module, std::set<Class*>& alreadyInited, Class* cl)
|
||||
void writeInitialization(Output* out,
|
||||
Module& module,
|
||||
std::set<Class*>& alreadyInited,
|
||||
Class* cl)
|
||||
{
|
||||
if(alreadyInited.find(cl) != alreadyInited.end()) {
|
||||
if (alreadyInited.find(cl) != alreadyInited.end()) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
out->write("bootClass(t, Gc::");
|
||||
@ -1362,24 +1419,24 @@ writeInitialization(Output* out, Module& module, std::set<Class*>& alreadyInited
|
||||
out->write(");\n");
|
||||
}
|
||||
|
||||
void
|
||||
writeInitializations(Output* out, Module& module)
|
||||
void writeInitializations(Output* out, Module& module)
|
||||
{
|
||||
std::set<Class*> alreadyInited;
|
||||
|
||||
writeInitialization(out, module, alreadyInited, module.classes["intArray"]);
|
||||
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;
|
||||
if(cl->name != "intArray" && cl->name != "class") {
|
||||
if (cl->name != "intArray" && cl->name != "class") {
|
||||
writeInitialization(out, module, alreadyInited, cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeJavaInitialization(Output* out, Class* cl)
|
||||
void writeJavaInitialization(Output* out, Class* cl)
|
||||
{
|
||||
out->write("bootJavaClass(t, Gc::");
|
||||
out->write(capitalize(cl->name));
|
||||
@ -1405,10 +1462,11 @@ writeJavaInitialization(Output* out, Class* cl)
|
||||
out->write(", bootMethod);\n");
|
||||
}
|
||||
|
||||
void
|
||||
writeJavaInitializations(Output* out, Module& module)
|
||||
void 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;
|
||||
if (cl->javaName.size()) {
|
||||
writeJavaInitialization(out, cl);
|
||||
@ -1416,22 +1474,14 @@ writeJavaInitializations(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeNameInitialization(Output* out, Class* cl)
|
||||
void writeNameInitialization(Output* out, Class* cl)
|
||||
{
|
||||
out->write("nameClass(t, Gc::");
|
||||
out->write(capitalize(cl->name));
|
||||
out->write("Type, \"");
|
||||
if (cl->name == "jbyte"
|
||||
or cl->name == "jboolean"
|
||||
or cl->name == "jshort"
|
||||
or cl->name == "jchar"
|
||||
or cl->name == "jint"
|
||||
or cl->name == "jlong"
|
||||
or cl->name == "jfloat"
|
||||
or cl->name == "jdouble"
|
||||
or cl->name == "jvoid")
|
||||
{
|
||||
if (cl->name == "jbyte" or cl->name == "jboolean" or cl->name == "jshort"
|
||||
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));
|
||||
} else {
|
||||
out->write("vm::");
|
||||
@ -1440,10 +1490,11 @@ writeNameInitialization(Output* out, Class* cl)
|
||||
out->write("\");\n");
|
||||
}
|
||||
|
||||
void
|
||||
writeNameInitializations(Output* out, Module& module)
|
||||
void 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;
|
||||
if (!cl->javaName.size()) {
|
||||
writeNameInitialization(out, cl);
|
||||
@ -1451,15 +1502,16 @@ writeNameInitializations(Output* out, Module& module)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeMap(Output* out, Module& module, Class* cl)
|
||||
void writeMap(Output* out, Module& module, Class* cl)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
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;
|
||||
|
||||
if(ownerId && ownerId != f.ownerId) {
|
||||
if (ownerId && ownerId != f.ownerId) {
|
||||
ss << "Type_pad, ";
|
||||
}
|
||||
ownerId = f.ownerId;
|
||||
@ -1473,9 +1525,9 @@ writeMap(Output* out, Module& module, Class* cl)
|
||||
ss << ", ";
|
||||
}
|
||||
|
||||
if(cl->arrayField) {
|
||||
if (cl->arrayField) {
|
||||
Field& f = *cl->arrayField;
|
||||
if(ownerId && ownerId != f.ownerId) {
|
||||
if (ownerId && ownerId != f.ownerId) {
|
||||
ss << "Type_pad, ";
|
||||
}
|
||||
ss << "Type_array, ";
|
||||
@ -1489,14 +1541,15 @@ writeMap(Output* out, Module& module, Class* cl)
|
||||
out->write(ss.str());
|
||||
}
|
||||
|
||||
void
|
||||
writeMaps(Output* out, Module& module)
|
||||
void writeMaps(Output* out, Module& module)
|
||||
{
|
||||
out->write("Type types[][");
|
||||
out->write(module.classes.size());
|
||||
out->write("] = {\n");
|
||||
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;
|
||||
if (wrote) {
|
||||
out->write(",\n");
|
||||
|
193
src/util.cpp
193
src/util.cpp
@ -49,21 +49,20 @@ class TreeContext {
|
||||
bool fresh;
|
||||
};
|
||||
|
||||
List<GcTreeNode*>*
|
||||
path(TreeContext* c, GcTreeNode* node, List<GcTreeNode*>* next)
|
||||
List<GcTreeNode*>* path(TreeContext* c,
|
||||
GcTreeNode* node,
|
||||
List<GcTreeNode*>* next)
|
||||
{
|
||||
return new(c->zone) List<GcTreeNode*>(node, next);
|
||||
return new (c->zone) List<GcTreeNode*>(node, next);
|
||||
}
|
||||
|
||||
inline object
|
||||
getTreeNodeValue(Thread*, GcTreeNode* n)
|
||||
inline object getTreeNodeValue(Thread*, GcTreeNode* n)
|
||||
{
|
||||
return reinterpret_cast<object>
|
||||
(alias(n, TreeNodeValue) & PointerMask);
|
||||
}
|
||||
|
||||
inline void
|
||||
setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
|
||||
inline void setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
|
||||
{
|
||||
intptr_t red = alias(n, TreeNodeValue) & (~PointerMask);
|
||||
|
||||
@ -72,14 +71,12 @@ setTreeNodeValue(Thread* t, GcTreeNode* n, object value)
|
||||
alias(n, TreeNodeValue) |= red;
|
||||
}
|
||||
|
||||
inline bool
|
||||
treeNodeRed(Thread*, GcTreeNode* n)
|
||||
inline bool treeNodeRed(Thread*, GcTreeNode* n)
|
||||
{
|
||||
return (alias(n, TreeNodeValue) & (~PointerMask)) == 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
|
||||
inline void setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
|
||||
{
|
||||
if (red) {
|
||||
alias(n, TreeNodeValue) |= 1;
|
||||
@ -88,20 +85,21 @@ setTreeNodeRed(Thread*, GcTreeNode* n, bool red)
|
||||
}
|
||||
}
|
||||
|
||||
inline GcTreeNode*
|
||||
cloneTreeNode(Thread* t, GcTreeNode* n)
|
||||
inline GcTreeNode* cloneTreeNode(Thread* t, GcTreeNode* n)
|
||||
{
|
||||
PROTECT(t, n);
|
||||
|
||||
GcTreeNode* newNode = makeTreeNode
|
||||
(t, getTreeNodeValue(t, n), n->left(), n->right());
|
||||
GcTreeNode* newNode
|
||||
= makeTreeNode(t, getTreeNodeValue(t, n), n->left(), n->right());
|
||||
setTreeNodeRed(t, newNode, treeNodeRed(t, n));
|
||||
return newNode;
|
||||
}
|
||||
|
||||
GcTreeNode*
|
||||
treeFind(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
GcTreeNode* treeFind(Thread* t,
|
||||
GcTreeNode* tree,
|
||||
intptr_t key,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
GcTreeNode* node = tree;
|
||||
while (node != sentinal) {
|
||||
@ -118,10 +116,13 @@ treeFind(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
treeFind(Thread* t, TreeContext* c, GcTreeNode* old, intptr_t key, GcTreeNode* node,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
void treeFind(Thread* t,
|
||||
TreeContext* c,
|
||||
GcTreeNode* old,
|
||||
intptr_t key,
|
||||
GcTreeNode* node,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
PROTECT(t, old);
|
||||
PROTECT(t, node);
|
||||
@ -173,8 +174,7 @@ treeFind(Thread* t, TreeContext* c, GcTreeNode* old, intptr_t key, GcTreeNode* n
|
||||
c->ancestors = c->ancestors;
|
||||
}
|
||||
|
||||
GcTreeNode*
|
||||
leftRotate(Thread* t, GcTreeNode* n)
|
||||
GcTreeNode* leftRotate(Thread* t, GcTreeNode* n)
|
||||
{
|
||||
PROTECT(t, n);
|
||||
|
||||
@ -184,8 +184,7 @@ leftRotate(Thread* t, GcTreeNode* n)
|
||||
return child;
|
||||
}
|
||||
|
||||
GcTreeNode*
|
||||
rightRotate(Thread* t, GcTreeNode* n)
|
||||
GcTreeNode* rightRotate(Thread* t, GcTreeNode* n)
|
||||
{
|
||||
PROTECT(t, n);
|
||||
|
||||
@ -195,8 +194,7 @@ rightRotate(Thread* t, GcTreeNode* n)
|
||||
return child;
|
||||
}
|
||||
|
||||
GcTreeNode*
|
||||
treeAdd(Thread* t, TreeContext* c)
|
||||
GcTreeNode* treeAdd(Thread* t, TreeContext* c)
|
||||
{
|
||||
GcTreeNode* new_ = c->node;
|
||||
PROTECT(t, new_);
|
||||
@ -207,16 +205,11 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
// rebalance
|
||||
setTreeNodeRed(t, new_, true);
|
||||
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
|
||||
if (c->ancestors->item
|
||||
== c->ancestors->next->item->left())
|
||||
{
|
||||
if (treeNodeRed
|
||||
(t, c->ancestors->next->item->right()))
|
||||
{
|
||||
if (c->ancestors->item == c->ancestors->next->item->left()) {
|
||||
if (treeNodeRed(t, c->ancestors->next->item->right())) {
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
|
||||
GcTreeNode* n = cloneTreeNode
|
||||
(t, c->ancestors->next->item->right());
|
||||
GcTreeNode* n = cloneTreeNode(t, c->ancestors->next->item->right());
|
||||
|
||||
c->ancestors->next->item->setRight(t, n);
|
||||
|
||||
@ -247,8 +240,7 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
if (c->ancestors->next->next == 0) {
|
||||
newRoot = n;
|
||||
} else if (c->ancestors->next->next->item->right()
|
||||
== c->ancestors->next->item)
|
||||
{
|
||||
== c->ancestors->next->item) {
|
||||
c->ancestors->next->next->item->setRight(t, n);
|
||||
} else {
|
||||
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
|
||||
// left swapped):
|
||||
if (treeNodeRed
|
||||
(t, c->ancestors->next->item->left()))
|
||||
{
|
||||
if (treeNodeRed(t, c->ancestors->next->item->left())) {
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
|
||||
GcTreeNode* n = cloneTreeNode
|
||||
(t, c->ancestors->next->item->left());
|
||||
GcTreeNode* n = cloneTreeNode(t, c->ancestors->next->item->left());
|
||||
|
||||
c->ancestors->next->item->setLeft(t, n);
|
||||
|
||||
@ -294,8 +283,7 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
if (c->ancestors->next->next == 0) {
|
||||
newRoot = n;
|
||||
} else if (c->ancestors->next->next->item->left()
|
||||
== c->ancestors->next->item)
|
||||
{
|
||||
== c->ancestors->next->item) {
|
||||
c->ancestors->next->next->item->setLeft(t, n);
|
||||
} else {
|
||||
c->ancestors->next->next->item->setRight(t, n);
|
||||
@ -314,17 +302,19 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
|
||||
namespace vm {
|
||||
|
||||
GcTriple*
|
||||
hashMapFindNode(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
GcTriple* hashMapFindNode(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
|
||||
|
||||
GcArray* array = map->array();
|
||||
if (array) {
|
||||
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();
|
||||
if (weak) {
|
||||
k = cast<GcJreference>(t, k)->target();
|
||||
@ -341,9 +331,10 @@ hashMapFindNode(Thread* t, GcHashMap* map, object key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
|
||||
unsigned size)
|
||||
void hashMapResize(Thread* t,
|
||||
GcHashMap* map,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
unsigned size)
|
||||
{
|
||||
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);
|
||||
for (unsigned i = 0; i < oldArray->length(); ++i) {
|
||||
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());
|
||||
|
||||
object k = p->first();
|
||||
@ -389,13 +381,15 @@ hashMapResize(Thread* t, GcHashMap* map, uint32_t (*hash)(Thread*, object),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
map->setArray(t, newArray);
|
||||
}
|
||||
|
||||
void
|
||||
hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
|
||||
uint32_t (*hash)(Thread*, object))
|
||||
void hashMapInsert(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
object value,
|
||||
uint32_t (*hash)(Thread*, object))
|
||||
{
|
||||
// note that we reinitialize the array variable whenever an
|
||||
// allocation (and thus possibly a collection) occurs, in case the
|
||||
@ -409,9 +403,9 @@ hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
|
||||
|
||||
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, value);
|
||||
|
||||
@ -452,22 +446,26 @@ hashMapInsert(Thread* t, GcHashMap* map, object key, object value,
|
||||
}
|
||||
}
|
||||
|
||||
GcTriple*
|
||||
hashMapRemoveNode(Thread* t, GcHashMap* map, unsigned index, GcTriple* p, GcTriple* n)
|
||||
GcTriple* hashMapRemoveNode(Thread* t,
|
||||
GcHashMap* map,
|
||||
unsigned index,
|
||||
GcTriple* p,
|
||||
GcTriple* n)
|
||||
{
|
||||
if (p) {
|
||||
p->setThird(t, n->third());
|
||||
} else {
|
||||
map->array()->setBodyElement(t, index, n->third());
|
||||
}
|
||||
-- map->size();
|
||||
--map->size();
|
||||
return n;
|
||||
}
|
||||
|
||||
object
|
||||
hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
object hashMapRemove(Thread* t,
|
||||
GcHashMap* map,
|
||||
object key,
|
||||
uint32_t (*hash)(Thread*, object),
|
||||
bool (*equal)(Thread*, object, object))
|
||||
{
|
||||
bool weak = objectClass(t, map) == type(t, GcWeakHashMap::Type);
|
||||
|
||||
@ -481,7 +479,8 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
if (weak) {
|
||||
k = cast<GcJreference>(t, k)->target();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -495,9 +494,7 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
}
|
||||
}
|
||||
|
||||
if ((not t->m->collecting)
|
||||
and map->size() <= array->length() / 3)
|
||||
{
|
||||
if ((not t->m->collecting) and map->size() <= array->length() / 3) {
|
||||
PROTECT(t, o);
|
||||
hashMapResize(t, map, hash, array->length() / 2);
|
||||
}
|
||||
@ -506,13 +503,12 @@ hashMapRemove(Thread* t, GcHashMap* map, object key,
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
listAppend(Thread* t, GcList* list, object value)
|
||||
void listAppend(Thread* t, GcList* list, object value)
|
||||
{
|
||||
PROTECT(t, list);
|
||||
|
||||
++ list->size();
|
||||
|
||||
++list->size();
|
||||
|
||||
object p = makePair(t, value, 0);
|
||||
if (list->front()) {
|
||||
cast<GcPair>(t, list->rear())->setSecond(t, p);
|
||||
@ -522,18 +518,17 @@ listAppend(Thread* t, GcList* list, object value)
|
||||
list->setRear(t, p);
|
||||
}
|
||||
|
||||
GcVector*
|
||||
vectorAppend(Thread* t, GcVector* vector, object value)
|
||||
GcVector* vectorAppend(Thread* t, GcVector* vector, object value)
|
||||
{
|
||||
if (vector->length() == vector->size()) {
|
||||
PROTECT(t, vector);
|
||||
PROTECT(t, value);
|
||||
|
||||
GcVector* newVector = makeVector
|
||||
(t, vector->size(), max(16, vector->size() * 2));
|
||||
GcVector* newVector
|
||||
= makeVector(t, vector->size(), max(16, vector->size() * 2));
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
@ -542,20 +537,18 @@ vectorAppend(Thread* t, GcVector* vector, object value)
|
||||
}
|
||||
|
||||
vector->setBodyElement(t, vector->size(), value);
|
||||
++ vector->size();
|
||||
++vector->size();
|
||||
return vector;
|
||||
}
|
||||
|
||||
GcArray*
|
||||
growArray(Thread* t, GcArray* array)
|
||||
GcArray* growArray(Thread* t, GcArray* array)
|
||||
{
|
||||
PROTECT(t, array);
|
||||
|
||||
GcArray* newArray = makeArray
|
||||
(t, array == 0 ? 16 : (array->length() * 2));
|
||||
GcArray* newArray = makeArray(t, array == 0 ? 16 : (array->length() * 2));
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
@ -563,18 +556,23 @@ growArray(Thread* t, GcArray* array)
|
||||
return newArray;
|
||||
}
|
||||
|
||||
object
|
||||
treeQuery(Thread* t, GcTreeNode* tree, intptr_t key, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
object treeQuery(Thread* t,
|
||||
GcTreeNode* tree,
|
||||
intptr_t key,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
GcTreeNode* node = treeFind(t, tree, key, sentinal, compare);
|
||||
return (node ? getTreeNodeValue(t, node) : 0);
|
||||
}
|
||||
|
||||
GcTreeNode*
|
||||
treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
GcTreeNode* treeInsert(Thread* t,
|
||||
Zone* zone,
|
||||
GcTreeNode* tree,
|
||||
intptr_t key,
|
||||
object value,
|
||||
GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
{
|
||||
PROTECT(t, tree);
|
||||
PROTECT(t, sentinal);
|
||||
@ -588,9 +586,12 @@ treeInsert(Thread* t, Zone* zone, GcTreeNode* tree, intptr_t key, object value,
|
||||
return treeAdd(t, &c);
|
||||
}
|
||||
|
||||
void
|
||||
treeUpdate(Thread* t, GcTreeNode* tree, intptr_t key, object value, GcTreeNode* sentinal,
|
||||
intptr_t (*compare)(Thread* t, intptr_t key, object b))
|
||||
void treeUpdate(Thread* t,
|
||||
GcTreeNode* tree,
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user