corda/src/builtin.cpp

1379 lines
40 KiB
C++
Raw Normal View History

2014-04-21 02:14:48 +00:00
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#include "avian/machine.h"
#include "avian/constants.h"
#include "avian/processor.h"
#include "avian/util.h"
2013-02-20 05:56:05 +00:00
#include <avian/util/runtime-array.h>
2007-07-24 01:44:20 +00:00
using namespace vm;
namespace {
2014-07-11 15:47:57 +00:00
int64_t search(Thread* t,
GcClassLoader* loader,
GcString* name,
GcClass* (*op)(Thread*, GcClassLoader*, GcByteArray*),
bool replaceDots)
2007-07-07 23:47:35 +00:00
{
if (LIKELY(name)) {
PROTECT(t, loader);
2009-06-11 23:13:25 +00:00
PROTECT(t, name);
2014-06-28 23:24:24 +00:00
GcByteArray* n = makeByteArray(t, name->length(t) + 1);
2014-06-02 16:31:57 +00:00
char* s = reinterpret_cast<char*>(n->body().begin());
stringChars(t, name, s);
2014-05-29 04:17:25 +00:00
if (replaceDots) {
replace('.', '/', s);
}
2014-06-28 23:24:24 +00:00
return reinterpret_cast<int64_t>(op(t, loader, n));
} else {
2014-05-29 04:17:25 +00:00
throwNew(t, GcNullPointerException::Type);
}
}
2014-07-11 15:47:57 +00:00
GcClass* resolveSystemClassThrow(Thread* t,
GcClassLoader* loader,
GcByteArray* spec)
{
2014-07-11 15:47:57 +00:00
return resolveSystemClass(
t, loader, spec, true, GcClassNotFoundException::Type);
}
2014-07-11 15:47:57 +00:00
GcField* fieldForOffsetInClass(Thread* t, GcClass* c, unsigned offset)
{
GcClass* super = c->super();
if (super) {
2014-06-29 05:34:40 +00:00
GcField* field = fieldForOffsetInClass(t, super, offset);
if (field) {
return field;
}
}
2014-05-29 04:17:25 +00:00
object table = c->fieldTable();
if (table) {
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
2014-06-29 05:34:40 +00:00
GcField* field = cast<GcField>(t, objectArrayBody(t, table, i));
2014-07-11 15:47:57 +00:00
if ((field->flags() & ACC_STATIC) == 0 and field->offset() == offset) {
return field;
}
}
}
return 0;
}
2014-07-16 14:59:50 +00:00
GcField* fieldForOffset(Thread* t, object o, unsigned offset)
{
2014-05-29 04:17:25 +00:00
GcClass* c = objectClass(t, o);
if (c->vmFlags() & SingletonFlag) {
2014-07-16 14:59:50 +00:00
GcSingleton* s = cast<GcSingleton>(t, o);
// If the object is a Singleton, we assume it's the static table of a class -
// which will always have the parent class as the first (0th) element.
c = cast<GcClass>(t, singletonObject(t, s, 0));
2014-05-29 04:17:25 +00:00
object table = c->fieldTable();
if (table) {
for (unsigned i = 0; i < objectArrayLength(t, table); ++i) {
2014-06-29 05:34:40 +00:00
GcField* field = cast<GcField>(t, objectArrayBody(t, table, i));
2014-07-11 15:47:57 +00:00
if ((field->flags() & ACC_STATIC) and field->offset() == offset) {
return field;
}
}
}
abort(t);
} else {
2014-06-29 05:34:40 +00:00
GcField* field = fieldForOffsetInClass(t, c, offset);
if (field) {
return field;
} else {
abort(t);
}
}
}
2014-07-11 15:50:18 +00:00
} // namespace
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_toVMClass(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<intptr_t>(
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Classes_initialize(Thread* t, object, uintptr_t* arguments)
2013-02-21 22:37:17 +00:00
{
2014-05-29 04:17:25 +00:00
GcClass* this_ = cast<GcClass>(t, reinterpret_cast<object>(arguments[0]));
2013-02-21 22:37:17 +00:00
initClass(t, this_);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Classes_acquireClassLock(Thread* t, object, uintptr_t*)
{
acquire(t, t->m->classLock);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Classes_releaseClassLock(Thread* t, object, uintptr_t*)
{
release(t, t->m->classLock);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Classes_resolveVMClass(Thread* t, object, uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
GcByteArray* spec
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
2014-07-11 15:47:57 +00:00
return reinterpret_cast<int64_t>(
resolveClass(t, loader, spec, true, GcClassNotFoundException::Type));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Classes_defineVMClass(Thread* t, object, uintptr_t* arguments)
2013-02-21 22:37:17 +00:00
{
2014-07-11 15:47:57 +00:00
GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
2014-06-29 05:34:40 +00:00
GcByteArray* b = cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
2013-02-21 22:37:17 +00:00
int offset = arguments[2];
int length = arguments[3];
2014-07-11 15:50:18 +00:00
uint8_t* buffer = static_cast<uint8_t*>(t->m->heap->allocate(length));
2014-05-29 04:17:25 +00:00
2014-07-11 15:50:18 +00:00
THREAD_RESOURCE2(
t, uint8_t*, buffer, int, length, t->m->heap->free(buffer, length));
2013-02-21 22:37:17 +00:00
2014-06-29 05:34:40 +00:00
memcpy(buffer, &b->body()[offset], length);
2013-02-21 22:37:17 +00:00
return reinterpret_cast<int64_t>(defineClass(t, loader, buffer, length));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_makeString(Thread* t, object, uintptr_t* arguments)
{
GcByteArray* array
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[0]));
int offset = arguments[1];
int length = arguments[2];
return reinterpret_cast<int64_t>(
t->m->classpath->makeString(t, array, offset, length));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_findLoadedVMClass(Thread* t,
object,
uintptr_t* arguments)
2007-07-24 01:44:20 +00:00
{
2014-07-11 15:47:57 +00:00
GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
2014-06-29 05:34:40 +00:00
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
2007-07-24 01:44:20 +00:00
2014-06-29 05:34:40 +00:00
return search(t, loader, name, findLoadedClass, true);
2007-07-30 23:19:05 +00:00
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_vmClass(Thread* t,
object,
uintptr_t* arguments)
2013-02-21 22:37:17 +00:00
{
2014-07-11 15:47:57 +00:00
return reinterpret_cast<int64_t>(
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
2013-02-21 22:37:17 +00:00
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_findVMClass(Thread* t,
object,
uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
2014-06-29 05:34:40 +00:00
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
2014-06-29 05:34:40 +00:00
return search(t, loader, name, resolveSystemClassThrow, true);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_resourceURLPrefix(Thread* t,
object,
uintptr_t* arguments)
2007-07-30 23:19:05 +00:00
{
2014-07-11 15:47:57 +00:00
GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[0]));
2014-06-29 05:34:40 +00:00
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
if (LIKELY(name)) {
2014-06-29 05:34:40 +00:00
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
2014-07-11 15:47:57 +00:00
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 {
2014-05-29 04:17:25 +00:00
throwNew(t, GcNullPointerException::Type);
}
2007-07-30 23:19:05 +00:00
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_00024ResourceEnumeration_nextResourceURLPrefix(
Thread* t,
object,
uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
GcClassLoader* loader
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[1]));
2014-06-29 05:34:40 +00:00
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[2]));
2014-07-11 15:47:57 +00:00
GcLongArray* finderElementPtrPtr
= cast<GcLongArray>(t, reinterpret_cast<object>(arguments[3]));
if (LIKELY(name) && LIKELY(finderElementPtrPtr)) {
2014-06-29 05:34:40 +00:00
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
2014-07-11 15:47:57 +00:00
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 {
2014-05-29 04:17:25 +00:00
throwNew(t, GcNullPointerException::Type);
}
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_getClass(Thread* t,
object,
uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
return reinterpret_cast<int64_t>(
getJClass(t, cast<GcClass>(t, reinterpret_cast<object>(arguments[0]))));
2007-07-24 01:44:20 +00:00
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_SystemClassLoader_getPackageSource(Thread* t,
object,
uintptr_t* arguments)
{
2014-06-29 05:34:40 +00:00
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[0]));
PROTECT(t, name);
ACQUIRE(t, t->m->classLock);
2014-06-29 05:34:40 +00:00
THREAD_RUNTIME_ARRAY(t, char, chars, name->length(t) + 2);
stringChars(t, name, RUNTIME_ARRAY_BODY(chars));
replace('.', '/', RUNTIME_ARRAY_BODY(chars));
2014-06-29 05:34:40 +00:00
RUNTIME_ARRAY_BODY(chars)[name->length(t)] = '/';
RUNTIME_ARRAY_BODY(chars)[name->length(t) + 1] = 0;
2014-06-29 05:34:40 +00:00
GcByteArray* key = makeByteArray(t, RUNTIME_ARRAY_BODY(chars));
2014-07-11 15:47:57 +00:00
GcByteArray* array = cast<GcByteArray>(
t,
hashMapFind(
t, roots(t)->packageMap(), key, byteArrayHash, byteArrayEqual));
if (array) {
2014-06-29 05:34:40 +00:00
return reinterpret_cast<uintptr_t>(makeLocalReference(
2014-07-11 15:47:57 +00:00
t, t->m->classpath->makeString(t, array, 0, array->length())));
} else {
return 0;
}
}
#ifdef AVIAN_HEAPDUMP
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Machine_dumpHeap(Thread* t, object, uintptr_t* arguments)
{
2014-07-16 20:18:42 +00:00
GcString* outputFile
= static_cast<GcString*>(reinterpret_cast<object>(*arguments));
2014-07-16 20:18:42 +00:00
unsigned length = outputFile->length(t);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
stringChars(t, outputFile, RUNTIME_ARRAY_BODY(n));
FILE* out = vm::fopen(RUNTIME_ARRAY_BODY(n), "wb");
if (out) {
2014-07-11 15:50:18 +00:00
{
ENTER(t, Thread::ExclusiveState);
dumpHeap(t, out);
}
fclose(out);
} else {
2014-07-11 15:47:57 +00:00
throwNew(t,
GcRuntimeException::Type,
"file not found: %s",
2013-03-04 23:00:35 +00:00
RUNTIME_ARRAY_BODY(n));
}
}
2014-07-11 15:50:18 +00:00
#endif // AVIAN_HEAPDUMP
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Machine_tryNative(Thread* t, object, uintptr_t* arguments)
{
int64_t function;
memcpy(&function, arguments, 8);
int64_t argument;
memcpy(&argument, arguments + 2, 8);
t->setFlag(Thread::TryNativeFlag);
THREAD_RESOURCE0(t, t->clearFlag(Thread::TryNativeFlag));
return reinterpret_cast<int64_t (*)(int64_t)>(function)(argument);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_java_lang_Runtime_exit(Thread* t, object, uintptr_t* arguments)
{
shutDown(t);
2009-09-18 00:28:42 +00:00
t->m->system->exit(arguments[1]);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_java_lang_Runtime_freeMemory(Thread* t, object, uintptr_t*)
{
return t->m->heap->remaining();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_java_lang_Runtime_totalMemory(Thread* t, object, uintptr_t*)
{
return t->m->heap->limit();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_getContentLength(
Thread* t,
object,
uintptr_t* arguments)
{
2014-06-29 05:34:40 +00:00
GcString* path = cast<GcString>(t, reinterpret_cast<object>(*arguments));
if (LIKELY(path)) {
2014-06-29 05:34:40 +00:00
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
System::Region* r = t->m->bootFinder->find(RUNTIME_ARRAY_BODY(p));
if (r == 0) {
r = t->m->appFinder->find(RUNTIME_ARRAY_BODY(p));
}
if (r) {
jint rSize = r->length();
r->dispose();
return rSize;
}
}
return -1;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_open(
Thread* t,
object,
uintptr_t* arguments)
{
2014-06-29 05:34:40 +00:00
GcString* path = cast<GcString>(t, reinterpret_cast<object>(*arguments));
if (LIKELY(path)) {
2014-06-29 05:34:40 +00:00
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
System::Region* r = t->m->bootFinder->find(RUNTIME_ARRAY_BODY(p));
if (r == 0) {
r = t->m->appFinder->find(RUNTIME_ARRAY_BODY(p));
}
return reinterpret_cast<int64_t>(r);
} else {
2014-05-29 04:17:25 +00:00
throwNew(t, GcNullPointerException::Type);
}
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_available(
Thread*,
object,
uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t peer;
memcpy(&peer, arguments, 8);
int32_t position = arguments[2];
System::Region* region = reinterpret_cast<System::Region*>(peer);
return static_cast<jint>(region->length()) - position;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI(
Thread*,
object,
uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t peer;
memcpy(&peer, arguments, 8);
int32_t position = arguments[2];
2007-09-17 00:13:36 +00:00
System::Region* region = reinterpret_cast<System::Region*>(peer);
if (position >= static_cast<jint>(region->length())) {
return -1;
} else {
2007-09-17 00:13:36 +00:00
return region->start()[position];
}
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI_3BII(
Thread* t,
object,
uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t peer;
memcpy(&peer, arguments, 8);
int32_t position = arguments[2];
2014-07-11 15:47:57 +00:00
GcByteArray* buffer
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[3]));
int32_t offset = arguments[4];
int32_t length = arguments[5];
2014-07-11 15:50:18 +00:00
if (length == 0)
return 0;
2014-05-29 04:17:25 +00:00
2007-09-17 00:13:36 +00:00
System::Region* region = reinterpret_cast<System::Region*>(peer);
if (length > static_cast<jint>(region->length()) - position) {
length = static_cast<jint>(region->length()) - position;
}
if (length <= 0) {
return -1;
} else {
2014-07-11 15:47:57 +00:00
memcpy(&buffer->body()[offset], region->start() + position, length);
return length;
}
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_close(
Thread*,
object,
uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t peer;
memcpy(&peer, arguments, 8);
2007-09-17 00:13:36 +00:00
reinterpret_cast<System::Region*>(peer)->dispose();
}
2009-05-06 00:29:05 +00:00
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Continuations_callWithCurrentContinuation(Thread* t,
object,
uintptr_t* arguments)
2009-05-06 00:29:05 +00:00
{
2014-07-11 15:50:18 +00:00
t->m->processor->callWithCurrentContinuation(
t, reinterpret_cast<object>(*arguments));
2009-05-06 00:29:05 +00:00
abort(t);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Continuations_dynamicWind2(Thread* t,
object,
uintptr_t* arguments)
2009-05-23 22:15:06 +00:00
{
2014-07-11 15:50:18 +00:00
t->m->processor->dynamicWind(t,
reinterpret_cast<object>(arguments[0]),
reinterpret_cast<object>(arguments[1]),
reinterpret_cast<object>(arguments[2]));
2009-05-23 22:15:06 +00:00
abort(t);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Continuations_00024Continuation_handleResult(
Thread* t,
object,
uintptr_t* arguments)
2009-05-06 00:29:05 +00:00
{
2014-07-11 15:47:57 +00:00
t->m->processor->feedResultToContinuation(
t,
cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
reinterpret_cast<object>(arguments[1]));
2009-05-06 00:29:05 +00:00
abort(t);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Continuations_00024Continuation_handleException(
Thread* t,
object,
uintptr_t* arguments)
2009-05-06 00:29:05 +00:00
{
2014-07-11 15:47:57 +00:00
t->m->processor->feedExceptionToContinuation(
t,
cast<GcContinuation>(t, reinterpret_cast<object>(arguments[0])),
cast<GcThrowable>(t, reinterpret_cast<object>(arguments[1])));
2009-05-06 00:29:05 +00:00
abort(t);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Singleton_getObject(Thread* t, object, uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
return reinterpret_cast<int64_t>(singletonObject(
t,
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
arguments[1]));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Singleton_getInt(Thread* t, object, uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
return singletonValue(
t,
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
arguments[1]);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Singleton_getLong(Thread* t, object, uintptr_t* arguments)
{
int64_t v;
2014-07-11 15:47:57 +00:00
memcpy(&v,
&singletonValue(
t,
cast<GcSingleton>(t, reinterpret_cast<object>(arguments[0])),
arguments[1]),
8);
return v;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_allocateMemory(Thread* t,
object,
uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t size;
memcpy(&size, arguments + 1, 8);
void* p = malloc(size);
if (p) {
return reinterpret_cast<int64_t>(p);
} else {
2014-05-29 04:17:25 +00:00
throwNew(t, GcOutOfMemoryError::Type);
}
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_freeMemory(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
if (p) {
free(reinterpret_cast<void*>(p));
}
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_setMemory(Thread* t, object, uintptr_t* arguments)
{
object base = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
int64_t count;
memcpy(&count, arguments + 4, 8);
int8_t value = arguments[6];
PROTECT(t, base);
ACQUIRE(t, t->m->referenceLock);
if (base) {
2013-02-11 00:38:51 +00:00
memset(&fieldAtOffset<int8_t>(base, offset), value, count);
} else {
memset(reinterpret_cast<int8_t*>(offset), value, count);
}
}
// NB: The following primitive get/put methods are only used by the
// interpreter. The JIT/AOT compiler implements them as intrinsics,
// so these versions will be ignored.
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putByte__JB(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
int8_t v = arguments[3];
*reinterpret_cast<int8_t*>(p) = v;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putShort__JS(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
int16_t v = arguments[3];
*reinterpret_cast<int16_t*>(p) = v;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putChar__JC(Thread* t,
object method,
uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putShort__JS(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putInt__JI(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
int32_t v = arguments[3];
*reinterpret_cast<int32_t*>(p) = v;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putFloat__JF(Thread* t,
object method,
uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putInt__JI(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putLong__JJ(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
int64_t v;
memcpy(&v, arguments + 3, 8);
*reinterpret_cast<int64_t*>(p) = v;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putDouble__JD(Thread* t,
object method,
uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putLong__JJ(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putAddress__JJ(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
int64_t v;
memcpy(&v, arguments + 3, 8);
*reinterpret_cast<intptr_t*>(p) = v;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getByte__J(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
return *reinterpret_cast<int8_t*>(p);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getShort__J(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
return *reinterpret_cast<int16_t*>(p);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getChar__J(Thread* t,
object method,
uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getShort__J(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getInt__J(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
return *reinterpret_cast<int32_t*>(p);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getFloat__J(Thread* t,
object method,
uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getInt__J(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getLong__J(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
return *reinterpret_cast<int64_t*>(p);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getDouble__J(Thread* t,
object method,
uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getLong__J(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getAddress__J(Thread*, object, uintptr_t* arguments)
{
2014-07-11 15:50:18 +00:00
int64_t p;
memcpy(&p, arguments + 1, 8);
return *reinterpret_cast<intptr_t*>(p);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_copyMemory(Thread* t, object, uintptr_t* arguments)
{
object srcBase = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t srcOffset;
memcpy(&srcOffset, arguments + 2, 8);
object dstBase = reinterpret_cast<object>(arguments[4]);
2014-07-11 15:50:18 +00:00
int64_t dstOffset;
memcpy(&dstOffset, arguments + 5, 8);
int64_t count;
memcpy(&count, arguments + 7, 8);
PROTECT(t, srcBase);
PROTECT(t, dstBase);
ACQUIRE(t, t->m->referenceLock);
2014-07-11 15:50:18 +00:00
void* src = srcBase ? &fieldAtOffset<uint8_t>(srcBase, srcOffset)
: reinterpret_cast<uint8_t*>(srcOffset);
2014-07-11 15:50:18 +00:00
void* dst = dstBase ? &fieldAtOffset<uint8_t>(dstBase, dstOffset)
: reinterpret_cast<uint8_t*>(dstOffset);
memcpy(dst, src, count);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_arrayBaseOffset(Thread*, object, uintptr_t*)
{
return ArrayBody;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_arrayIndexScale(Thread* t,
object,
uintptr_t* arguments)
{
2014-07-11 15:47:57 +00:00
GcClass* c
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))->vmClass();
2014-07-11 15:47:57 +00:00
if (c == type(t, GcBooleanArray::Type) || c == type(t, GcByteArray::Type))
return 1;
2014-07-11 15:47:57 +00:00
else if (c == type(t, GcShortArray::Type) || c == type(t, GcCharArray::Type))
return 2;
2014-07-11 15:47:57 +00:00
else if (c == type(t, GcIntArray::Type) || c == type(t, GcFloatArray::Type))
return 4;
2014-07-11 15:47:57 +00:00
else if (c == type(t, GcLongArray::Type) || c == type(t, GcDoubleArray::Type))
return 8;
else
return BytesPerWord;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_java_nio_FixedArrayByteBuffer_allocateFixed(Thread* t,
object,
uintptr_t* arguments)
{
int capacity = arguments[0];
2014-07-11 15:47:57 +00:00
GcLongArray* address
= cast<GcLongArray>(t, reinterpret_cast<object>(arguments[1]));
PROTECT(t, address);
2014-07-11 15:47:57 +00:00
GcArray* array = reinterpret_cast<GcArray*>(allocate3(
t, t->m->heap, Machine::FixedAllocation, ArrayBody + capacity, false));
2014-07-11 15:47:57 +00:00
setObjectClass(
t, reinterpret_cast<object>(array), type(t, GcByteArray::Type));
2014-06-29 05:34:40 +00:00
array->length() = capacity;
2014-06-29 05:34:40 +00:00
address->body()[0] = reinterpret_cast<intptr_t>(array) + ArrayBody;
return reinterpret_cast<intptr_t>(array);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getObject(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
return fieldAtOffset<uintptr_t>(o, offset);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putObject(Thread* t, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
uintptr_t value = arguments[4];
2014-06-26 02:17:27 +00:00
setField(t, o, offset, reinterpret_cast<object>(value));
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putObjectVolatile(Thread* t,
object,
uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
object value = reinterpret_cast<object>(arguments[4]);
2014-05-29 04:17:25 +00:00
storeStoreMemoryBarrier();
setField(t, o, offset, value);
storeLoadMemoryBarrier();
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putOrderedObject(Thread* t,
object method,
uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getObjectVolatile(Thread*,
object,
uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
2014-05-29 04:17:25 +00:00
uintptr_t value = fieldAtOffset<uintptr_t>(o, offset);
loadMemoryBarrier();
return value;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_compareAndSwapObject(Thread* t,
object,
uintptr_t* arguments)
{
object target = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
uintptr_t expect = arguments[4];
uintptr_t update = arguments[5];
2014-07-11 15:50:18 +00:00
bool success = atomicCompareAndSwap(
&fieldAtOffset<uintptr_t>(target, offset), expect, update);
if (success) {
mark(t, target, offset);
}
return success;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_compareAndSwapInt(Thread*,
object,
uintptr_t* arguments)
{
object target = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
uint32_t expect = arguments[4];
uint32_t update = arguments[5];
2014-07-11 15:50:18 +00:00
return atomicCompareAndSwap32(
&fieldAtOffset<uint32_t>(target, offset), expect, update);
}
2013-02-22 18:06:49 +00:00
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_compareAndSwapLong(Thread* t UNUSED,
object,
uintptr_t* arguments)
{
object target = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
uint64_t expect;
memcpy(&expect, arguments + 4, 8);
uint64_t update;
memcpy(&update, arguments + 6, 8);
#ifdef AVIAN_HAS_CAS64
2014-07-11 15:50:18 +00:00
return atomicCompareAndSwap64(
&fieldAtOffset<uint64_t>(target, offset), expect, update);
#else
PROTECT(t, target);
ACQUIRE_FIELD_FOR_WRITE(t, fieldForOffset(t, target, offset));
if (fieldAtOffset<uint64_t>(target, offset) == expect) {
fieldAtOffset<uint64_t>(target, offset) = update;
return true;
} else {
return false;
}
#endif
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getLongVolatile(Thread* t,
object,
uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
object lock;
if (BytesPerWord < 8) {
2014-05-29 04:17:25 +00:00
if (objectClass(t, o)->arrayDimensions()) {
lock = objectClass(t, o);
} else {
lock = fieldForOffset(t, cast<GcSingleton>(t, o), offset);
}
PROTECT(t, o);
PROTECT(t, lock);
2014-05-29 04:17:25 +00:00
acquire(t, lock);
}
int64_t result = fieldAtOffset<int64_t>(o, offset);
if (BytesPerWord < 8) {
2014-05-29 04:17:25 +00:00
release(t, lock);
} else {
loadMemoryBarrier();
}
return result;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putLongVolatile(Thread* t,
object,
uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
int64_t value;
memcpy(&value, arguments + 4, 8);
object lock;
if (BytesPerWord < 8) {
2014-05-29 04:17:25 +00:00
if (objectClass(t, o)->arrayDimensions()) {
lock = objectClass(t, o);
} else {
lock = fieldForOffset(t, cast<GcSingleton>(t, o), offset);
}
PROTECT(t, o);
PROTECT(t, lock);
2014-05-29 04:17:25 +00:00
acquire(t, lock);
} else {
storeStoreMemoryBarrier();
}
fieldAtOffset<int64_t>(o, offset) = value;
if (BytesPerWord < 8) {
release(t, lock);
} else {
storeLoadMemoryBarrier();
}
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putOrderedLong(Thread* t,
object method,
uintptr_t* arguments)
{
// todo: we might be able to use weaker barriers here than
// putLongVolatile does
Avian_sun_misc_Unsafe_putLongVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_unpark(Thread* t, object, uintptr_t* arguments)
{
2014-06-28 23:24:24 +00:00
GcThread* thread = cast<GcThread>(t, reinterpret_cast<object>(arguments[1]));
2014-05-29 04:17:25 +00:00
2014-06-28 23:24:24 +00:00
monitorAcquire(t, cast<GcMonitor>(t, interruptLock(t, thread)));
thread->unparked() = true;
monitorNotify(t, cast<GcMonitor>(t, interruptLock(t, thread)));
monitorRelease(t, cast<GcMonitor>(t, interruptLock(t, thread)));
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_park(Thread* t, object, uintptr_t* arguments)
{
bool absolute = arguments[1];
2014-07-11 15:50:18 +00:00
int64_t time;
memcpy(&time, arguments + 2, 8);
2014-05-29 04:17:25 +00:00
int64_t then = t->m->system->now();
if (absolute) {
time -= then;
if (time <= 0) {
return;
}
} else if (time) {
// if not absolute, interpret time as nanoseconds, but make sure
// it doesn't become zero when we convert to milliseconds, since
// zero is interpreted as infinity below
time = (time / (1000 * 1000)) + 1;
}
2014-06-28 23:24:24 +00:00
monitorAcquire(t, cast<GcMonitor>(t, interruptLock(t, t->javaThread)));
bool interrupted = false;
while (time >= 0
2014-07-11 15:47:57 +00:00
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;
2014-05-29 04:17:25 +00:00
if (time == 0) {
break;
}
}
if (interrupted) {
2014-06-28 23:24:24 +00:00
t->javaThread->interrupted() = true;
}
2014-06-28 23:24:24 +00:00
t->javaThread->unparked() = false;
monitorRelease(t, cast<GcMonitor>(t, interruptLock(t, t->javaThread)));
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putIntVolatile(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
int32_t value = arguments[4];
2014-05-29 04:17:25 +00:00
storeStoreMemoryBarrier();
fieldAtOffset<int32_t>(o, offset) = value;
storeLoadMemoryBarrier();
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putOrderedInt(Thread* t,
object method,
uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putIntVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getIntVolatile(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
int32_t result = fieldAtOffset<int32_t>(o, offset);
loadMemoryBarrier();
return result;
}
2014-03-31 21:23:42 +00:00
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putByteVolatile(Thread*, object, uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
2014-03-31 21:23:42 +00:00
int8_t value = arguments[4];
2014-05-29 04:17:25 +00:00
2014-03-31 21:23:42 +00:00
storeStoreMemoryBarrier();
fieldAtOffset<int8_t>(o, offset) = value;
storeLoadMemoryBarrier();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getByteVolatile(Thread*, object, uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
2014-03-31 21:23:42 +00:00
int8_t result = fieldAtOffset<int8_t>(o, offset);
loadMemoryBarrier();
return result;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putBooleanVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
Avian_sun_misc_Unsafe_putByteVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getBooleanVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
return Avian_sun_misc_Unsafe_getByteVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putShortVolatile(Thread*,
object,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
2014-03-31 21:23:42 +00:00
int16_t value = arguments[4];
2014-05-29 04:17:25 +00:00
2014-03-31 21:23:42 +00:00
storeStoreMemoryBarrier();
fieldAtOffset<int16_t>(o, offset) = value;
storeLoadMemoryBarrier();
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getShortVolatile(Thread*,
object,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
object o = reinterpret_cast<object>(arguments[1]);
2014-07-11 15:50:18 +00:00
int64_t offset;
memcpy(&offset, arguments + 2, 8);
2014-03-31 21:23:42 +00:00
int16_t result = fieldAtOffset<int16_t>(o, offset);
loadMemoryBarrier();
return result;
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putCharVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
Avian_sun_misc_Unsafe_putShortVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getCharVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
return Avian_sun_misc_Unsafe_getShortVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putFloatVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
Avian_sun_misc_Unsafe_putIntVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getFloatVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
return Avian_sun_misc_Unsafe_getIntVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_putDoubleVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
Avian_sun_misc_Unsafe_putLongVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_getDoubleVolatile(Thread* t,
object method,
uintptr_t* arguments)
2014-03-31 21:23:42 +00:00
{
return Avian_sun_misc_Unsafe_getLongVolatile(t, method, arguments);
}
extern "C" AVIAN_EXPORT void JNICALL
2014-07-11 15:50:18 +00:00
Avian_sun_misc_Unsafe_throwException(Thread* t,
object,
uintptr_t* arguments)
{
2014-06-28 23:24:24 +00:00
vm::throw_(t, cast<GcThrowable>(t, reinterpret_cast<object>(arguments[1])));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
2014-07-11 15:50:18 +00:00
Avian_avian_Classes_primitiveClass(Thread* t, object, uintptr_t* arguments)
2013-02-22 18:06:49 +00:00
{
return reinterpret_cast<int64_t>(primitiveClass(t, arguments[0]));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Class_getEnclosingMethod(Thread* t,
object,
uintptr_t* arguments)
{
GcClass* c
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass();
PROTECT(t, c);
GcClassAddendum* addendum = c->addendum();
if (addendum) {
PROTECT(t, addendum);
GcByteArray* enclosingClass
= cast<GcByteArray>(t, addendum->enclosingClass());
if (enclosingClass) {
GcClass* enclosing = resolveClass(t, c->loader(), enclosingClass);
GcPair* enclosingMethod = cast<GcPair>(t, addendum->enclosingMethod());
if (enclosingMethod) {
return reinterpret_cast<uintptr_t>(t->m->classpath->makeJMethod(
t,
cast<GcMethod>(
t,
findMethodInClass(
t,
enclosing,
cast<GcByteArray>(t, enclosingMethod->first()),
cast<GcByteArray>(t, enclosingMethod->second())))));
}
}
}
return 0;
}
2014-10-08 23:04:32 +00:00
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Class_getEnclosingClass(Thread* t,
object,
uintptr_t* arguments)
{
GcClass* c
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass();
PROTECT(t, c);
GcClassAddendum* addendum = c->addendum();
if (addendum) {
GcByteArray* enclosingClass
= cast<GcByteArray>(t, addendum->enclosingClass());
if (enclosingClass) {
return reinterpret_cast<uintptr_t>(
getJClass(t, resolveClass(t, c->loader(), enclosingClass)));
}
}
return 0;
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Class_getEnclosingConstructor(Thread* t,
object method,
uintptr_t* arguments)
{
return Avian_java_lang_Class_getEnclosingMethod(t, method, arguments);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_toString(Thread* t, object, uintptr_t* arguments)
{
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);
return reinterpret_cast<int64_t>(s);
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_getVMClass(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>(
objectClass(t, reinterpret_cast<object>(arguments[0])));
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Object_wait(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
int64_t milliseconds;
memcpy(&milliseconds, arguments + 1, 8);
vm::wait(t, this_, milliseconds);
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Object_notify(Thread* t, object, uintptr_t* arguments)
{
notify(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Object_notifyAll(Thread* t, object, uintptr_t* arguments)
{
notifyAll(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_hashCode(Thread* t, object, uintptr_t* arguments)
{
return objectHash(t, reinterpret_cast<object>(arguments[0]));
}
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_clone(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>(
clone(t, reinterpret_cast<object>(arguments[0])));
}