mirror of
https://github.com/corda/corda.git
synced 2025-02-02 01:08:09 +00:00
87b02eb949
Previously, I used a shell script to extract modification date ranges from the Git history, but that was complicated and unreliable, so now every file just gets the same year range in its copyright header. If someone needs to know when a specific file was modified and by whom, they can look at the Git history themselves; no need to include it redundantly in the header.
742 lines
19 KiB
C++
742 lines
19 KiB
C++
/* Copyright (c) 2008-2013, 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"
|
|
|
|
#include <avian/util/runtime-array.h>
|
|
|
|
using namespace vm;
|
|
|
|
namespace {
|
|
|
|
int64_t
|
|
search(Thread* t, object loader, object name,
|
|
object (*op)(Thread*, object, object), bool replaceDots)
|
|
{
|
|
if (LIKELY(name)) {
|
|
PROTECT(t, loader);
|
|
PROTECT(t, name);
|
|
|
|
object n = makeByteArray(t, stringLength(t, name) + 1);
|
|
char* s = reinterpret_cast<char*>(&byteArrayBody(t, n, 0));
|
|
stringChars(t, name, s);
|
|
|
|
if (replaceDots) {
|
|
replace('.', '/', s);
|
|
}
|
|
|
|
return reinterpret_cast<int64_t>(op(t, loader, n));
|
|
} else {
|
|
throwNew(t, Machine::NullPointerExceptionType);
|
|
}
|
|
}
|
|
|
|
object
|
|
resolveSystemClassThrow(Thread* t, object loader, object spec)
|
|
{
|
|
return resolveSystemClass
|
|
(t, loader, spec, true, Machine::ClassNotFoundExceptionType);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Classes_initialize
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
|
|
|
initClass(t, this_);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Classes_acquireClassLock
|
|
(Thread* t, object, uintptr_t*)
|
|
{
|
|
acquire(t, t->m->classLock);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Classes_releaseClassLock
|
|
(Thread* t, object, uintptr_t*)
|
|
{
|
|
release(t, t->m->classLock);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_Classes_resolveVMClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
object spec = reinterpret_cast<object>(arguments[1]);
|
|
|
|
return reinterpret_cast<int64_t>
|
|
(resolveClass(t, loader, spec, true, Machine::ClassNotFoundExceptionType));
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_Classes_defineVMClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
object b = reinterpret_cast<object>(arguments[1]);
|
|
int offset = arguments[2];
|
|
int length = arguments[3];
|
|
|
|
uint8_t* buffer = static_cast<uint8_t*>
|
|
(t->m->heap->allocate(length));
|
|
|
|
THREAD_RESOURCE2(t, uint8_t*, buffer, int, length,
|
|
t->m->heap->free(buffer, length));
|
|
|
|
memcpy(buffer, &byteArrayBody(t, b, offset), length);
|
|
|
|
return reinterpret_cast<int64_t>(defineClass(t, loader, buffer, length));
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_SystemClassLoader_findLoadedVMClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
object name = reinterpret_cast<object>(arguments[1]);
|
|
|
|
return search(t, loader, name, findLoadedClass, true);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_SystemClassLoader_vmClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
return reinterpret_cast<int64_t>
|
|
(jclassVmClass(t, reinterpret_cast<object>(arguments[0])));
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_SystemClassLoader_findVMClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
object name = reinterpret_cast<object>(arguments[1]);
|
|
|
|
return search(t, loader, name, resolveSystemClassThrow, true);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_SystemClassLoader_resourceURLPrefix
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
object name = reinterpret_cast<object>(arguments[1]);
|
|
|
|
if (LIKELY(name)) {
|
|
THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1);
|
|
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
|
|
|
const char* name = static_cast<Finder*>
|
|
(systemClassLoaderFinder(t, loader))->urlPrefix(RUNTIME_ARRAY_BODY(n));
|
|
|
|
return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0;
|
|
} else {
|
|
throwNew(t, Machine::NullPointerExceptionType);
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_SystemClassLoader_getClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
return reinterpret_cast<int64_t>
|
|
(getJClass(t, reinterpret_cast<object>(arguments[0])));
|
|
}
|
|
|
|
#ifdef AVIAN_HEAPDUMP
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Machine_dumpHeap
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object outputFile = reinterpret_cast<object>(*arguments);
|
|
|
|
unsigned length = stringLength(t, outputFile);
|
|
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) {
|
|
{ ENTER(t, Thread::ExclusiveState);
|
|
dumpHeap(t, out);
|
|
}
|
|
fclose(out);
|
|
} else {
|
|
throwNew(t, Machine::RuntimeExceptionType, "file not found: %s",
|
|
RUNTIME_ARRAY_BODY(n));
|
|
}
|
|
}
|
|
|
|
#endif//AVIAN_HEAPDUMP
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_java_lang_Runtime_exit
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
shutDown(t);
|
|
|
|
t->m->system->exit(arguments[1]);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_getContentLength
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object path = reinterpret_cast<object>(*arguments);
|
|
|
|
if (LIKELY(path)) {
|
|
THREAD_RUNTIME_ARRAY(t, char, p, stringLength(t, path) + 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" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_open
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object path = reinterpret_cast<object>(*arguments);
|
|
|
|
if (LIKELY(path)) {
|
|
THREAD_RUNTIME_ARRAY(t, char, p, stringLength(t, path) + 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 {
|
|
throwNew(t, Machine::NullPointerExceptionType);
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_available
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
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" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
|
int32_t position = arguments[2];
|
|
|
|
System::Region* region = reinterpret_cast<System::Region*>(peer);
|
|
if (position >= static_cast<jint>(region->length())) {
|
|
return -1;
|
|
} else {
|
|
return region->start()[position];
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_read__JI_3BII
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
|
int32_t position = arguments[2];
|
|
object buffer = reinterpret_cast<object>(arguments[3]);
|
|
int32_t offset = arguments[4];
|
|
int32_t length = arguments[5];
|
|
|
|
if (length == 0) return 0;
|
|
|
|
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 {
|
|
memcpy(&byteArrayBody(t, buffer, offset), region->start() + position,
|
|
length);
|
|
return length;
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_avianvmresource_Handler_00024ResourceInputStream_close
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
|
reinterpret_cast<System::Region*>(peer)->dispose();
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Continuations_callWithCurrentContinuation
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
t->m->processor->callWithCurrentContinuation
|
|
(t, reinterpret_cast<object>(*arguments));
|
|
|
|
abort(t);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Continuations_dynamicWind2
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
t->m->processor->dynamicWind
|
|
(t, reinterpret_cast<object>(arguments[0]),
|
|
reinterpret_cast<object>(arguments[1]),
|
|
reinterpret_cast<object>(arguments[2]));
|
|
|
|
abort(t);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Continuations_00024Continuation_handleResult
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
t->m->processor->feedResultToContinuation
|
|
(t, reinterpret_cast<object>(arguments[0]),
|
|
reinterpret_cast<object>(arguments[1]));
|
|
|
|
abort(t);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_avian_Continuations_00024Continuation_handleException
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
t->m->processor->feedExceptionToContinuation
|
|
(t, reinterpret_cast<object>(arguments[0]),
|
|
reinterpret_cast<object>(arguments[1]));
|
|
|
|
abort(t);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_Singleton_getObject
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
return reinterpret_cast<int64_t>
|
|
(singletonObject(t, reinterpret_cast<object>(arguments[0]), arguments[1]));
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_Singleton_getInt
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
return singletonValue
|
|
(t, reinterpret_cast<object>(arguments[0]), arguments[1]);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_Singleton_getLong
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
int64_t v;
|
|
memcpy(&v, &singletonValue
|
|
(t, reinterpret_cast<object>(arguments[0]), arguments[1]), 8);
|
|
return v;
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_allocateMemory
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
int64_t size; memcpy(&size, arguments + 1, 8);
|
|
void* p = malloc(size);
|
|
if (p) {
|
|
return reinterpret_cast<int64_t>(p);
|
|
} else {
|
|
throwNew(t, Machine::OutOfMemoryErrorType);
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_freeMemory
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
if (p) {
|
|
free(reinterpret_cast<void*>(p));
|
|
}
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_setMemory
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object base = reinterpret_cast<object>(arguments[1]);
|
|
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) {
|
|
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" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putByte__JB
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
int8_t v = arguments[3];
|
|
|
|
*reinterpret_cast<int8_t*>(p) = v;
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putShort__JS
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
int16_t v = arguments[3];
|
|
|
|
*reinterpret_cast<int16_t*>(p) = v;
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putChar__JC
|
|
(Thread* t, object method, uintptr_t* arguments)
|
|
{
|
|
Avian_sun_misc_Unsafe_putShort__JS(t, method, arguments);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putInt__JI
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
int32_t v = arguments[3];
|
|
|
|
*reinterpret_cast<int32_t*>(p) = v;
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putFloat__JF
|
|
(Thread* t, object method, uintptr_t* arguments)
|
|
{
|
|
Avian_sun_misc_Unsafe_putInt__JI(t, method, arguments);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putLong__JJ
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
int64_t v; memcpy(&v, arguments + 3, 8);
|
|
|
|
*reinterpret_cast<int64_t*>(p) = v;
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putDouble__JD
|
|
(Thread* t, object method, uintptr_t* arguments)
|
|
{
|
|
Avian_sun_misc_Unsafe_putLong__JJ(t, method, arguments);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putAddress__JJ
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
int64_t v; memcpy(&v, arguments + 3, 8);
|
|
|
|
*reinterpret_cast<intptr_t*>(p) = v;
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_getByte__J
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
|
|
return *reinterpret_cast<int8_t*>(p);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_getShort__J
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
|
|
return *reinterpret_cast<int16_t*>(p);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
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" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_getInt__J
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
|
|
return *reinterpret_cast<int32_t*>(p);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
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" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_getLong__J
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
|
|
return *reinterpret_cast<int64_t*>(p);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
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" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_getAddress__J
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
int64_t p; memcpy(&p, arguments + 1, 8);
|
|
|
|
return *reinterpret_cast<intptr_t*>(p);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_copyMemory
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object srcBase = reinterpret_cast<object>(arguments[1]);
|
|
int64_t srcOffset; memcpy(&srcOffset, arguments + 2, 8);
|
|
object dstBase = reinterpret_cast<object>(arguments[4]);
|
|
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);
|
|
|
|
void* src = srcBase
|
|
? &fieldAtOffset<uint8_t>(srcBase, srcOffset)
|
|
: reinterpret_cast<uint8_t*>(srcOffset);
|
|
|
|
void* dst = dstBase
|
|
? &fieldAtOffset<uint8_t>(dstBase, dstOffset)
|
|
: reinterpret_cast<uint8_t*>(dstOffset);
|
|
|
|
memcpy(dst, src, count);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_arrayBaseOffset
|
|
(Thread*, object, uintptr_t*)
|
|
{
|
|
return ArrayBody;
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_java_nio_FixedArrayByteBuffer_allocateFixed
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
int capacity = arguments[0];
|
|
object address = reinterpret_cast<object>(arguments[1]);
|
|
PROTECT(t, address);
|
|
|
|
object array = allocate3
|
|
(t, t->m->heap, Machine::FixedAllocation, ArrayBody + capacity, false);
|
|
|
|
setObjectClass(t, array, type(t, Machine::ByteArrayType));
|
|
byteArrayLength(t, array) = capacity;
|
|
|
|
longArrayBody(t, address, 0) = reinterpret_cast<intptr_t>(array) + ArrayBody;
|
|
|
|
return reinterpret_cast<intptr_t>(array);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_getObject
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
|
|
|
return fieldAtOffset<uintptr_t>(o, offset);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putObject
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
|
uintptr_t value = arguments[4];
|
|
|
|
set(t, o, offset, reinterpret_cast<object>(value));
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_compareAndSwapObject
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object target = reinterpret_cast<object>(arguments[1]);
|
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
|
uintptr_t expect = arguments[4];
|
|
uintptr_t update = arguments[5];
|
|
|
|
bool success = atomicCompareAndSwap
|
|
(&fieldAtOffset<uintptr_t>(target, offset), expect, update);
|
|
|
|
if (success) {
|
|
mark(t, target, offset);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_sun_misc_Unsafe_compareAndSwapInt
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
object target = reinterpret_cast<object>(arguments[1]);
|
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
|
uint32_t expect = arguments[4];
|
|
uint32_t update = arguments[5];
|
|
|
|
return atomicCompareAndSwap32
|
|
(&fieldAtOffset<uint32_t>(target, offset), expect, update);
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_unpark
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
object thread = reinterpret_cast<object>(arguments[1]);
|
|
|
|
monitorAcquire(t, interruptLock(t, thread));
|
|
threadUnparked(t, thread) = true;
|
|
monitorNotify(t, interruptLock(t, thread));
|
|
monitorRelease(t, interruptLock(t, thread));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_park
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
bool absolute = arguments[1];
|
|
int64_t time; memcpy(&time, arguments + 2, 8);
|
|
|
|
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;
|
|
}
|
|
|
|
monitorAcquire(t, interruptLock(t, t->javaThread));
|
|
bool interrupted = false;
|
|
while (time >= 0
|
|
and (not (threadUnparked(t, t->javaThread)
|
|
or threadInterrupted(t, t->javaThread)
|
|
or (interrupted = monitorWait
|
|
(t, interruptLock(t, t->javaThread), time)))))
|
|
{
|
|
int64_t now = t->m->system->now();
|
|
time -= now - then;
|
|
then = now;
|
|
|
|
if (time == 0) {
|
|
break;
|
|
}
|
|
}
|
|
if (interrupted) {
|
|
threadInterrupted(t, t->javaThread) = true;
|
|
}
|
|
threadUnparked(t, t->javaThread) = false;
|
|
monitorRelease(t, interruptLock(t, t->javaThread));
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putIntVolatile
|
|
(Thread*, object, uintptr_t* arguments)
|
|
{
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
|
int32_t value = arguments[4];
|
|
|
|
storeStoreMemoryBarrier();
|
|
fieldAtOffset<int32_t>(o, offset) = value;
|
|
storeLoadMemoryBarrier();
|
|
}
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Avian_sun_misc_Unsafe_putOrderedInt
|
|
(Thread* t, object method, uintptr_t* arguments)
|
|
{
|
|
Avian_sun_misc_Unsafe_putIntVolatile(t, method, arguments);
|
|
}
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
Avian_avian_Classes_primitiveClass
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
{
|
|
return reinterpret_cast<int64_t>(primitiveClass(t, arguments[0]));
|
|
}
|