mirror of
https://github.com/corda/corda.git
synced 2025-01-16 01:40:17 +00:00
a static jni method takes the jclass for that method as its second argument; simplify pad() and divide(), and rename divide() to ceiling(); sketch FileInputStream.cpp and FileOutputStream.cpp
This commit is contained in:
parent
38a982c7dd
commit
9ab88ef619
@ -5,7 +5,7 @@ public class FileDescriptor {
|
||||
public static final FileDescriptor out = new FileDescriptor(1);
|
||||
public static final FileDescriptor err = new FileDescriptor(2);
|
||||
|
||||
private final int value;
|
||||
final int value;
|
||||
|
||||
private FileDescriptor(int value) {
|
||||
this.value = value;
|
||||
|
79
classpath/java/io/FileInputStream.cpp
Normal file
79
classpath/java/io/FileInputStream.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#undef JNIEXPORT
|
||||
#define JNIEXPORT __attribute__ ((visibility("default")))
|
||||
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
# define CLOSE _close
|
||||
# define READ _read
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# define CLOSE close
|
||||
# define READ read
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
int
|
||||
doRead(JNIEnv* e, jint fd, jbyte* data, jint length)
|
||||
{
|
||||
int r = READ(fd, data, length);
|
||||
if (r > 0) {
|
||||
return r;
|
||||
} else if (r == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
e->ThrowNew(e->FindClass("java/lang/IOException"), strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_java_io_FileInputStream_read__I(JNIEnv* e, jclass, jint fd)
|
||||
{
|
||||
jbyte data;
|
||||
int r = doRead(e, fd, &data, 1);
|
||||
if (r <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_java_io_FileInputStream_read__I_3BII
|
||||
(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length)
|
||||
{
|
||||
jbyte* data = static_cast<jbyte*>(malloc(length));
|
||||
if (data == 0) {
|
||||
e->ThrowNew(e->FindClass("java/lang/OutOfMemoryError"), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r = doRead(e, fd, data, length);
|
||||
|
||||
e->SetByteArrayRegion(b, offset, length, data);
|
||||
|
||||
free(data);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd)
|
||||
{
|
||||
int r = CLOSE(fd);
|
||||
if (r == -1) {
|
||||
e->ThrowNew(e->FindClass("java/lang/IOException"), strerror(errno));
|
||||
}
|
||||
}
|
@ -1,15 +1,28 @@
|
||||
package java.io;
|
||||
|
||||
public class FileInputStream extends InputStream {
|
||||
private final FileDescriptor fd;
|
||||
private final int fd;
|
||||
|
||||
public FileInputStream(FileDescriptor fd) {
|
||||
this.fd = fd;
|
||||
this.fd = fd.value;
|
||||
}
|
||||
|
||||
public native int read() throws IOException;
|
||||
private static native int read(int fd) throws IOException;
|
||||
|
||||
public native int read(byte[] b, int offset, int length) throws IOException;
|
||||
private static native int read(int fd, byte[] b, int offset, int length)
|
||||
throws IOException;
|
||||
|
||||
public native void close() throws IOException;
|
||||
public static native void close(int fd) throws IOException;
|
||||
|
||||
public int read() throws IOException {
|
||||
return read(fd);
|
||||
}
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
return read(fd, b, offset, length);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
69
classpath/java/io/FileOutputStream.cpp
Normal file
69
classpath/java/io/FileOutputStream.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#undef JNIEXPORT
|
||||
#define JNIEXPORT __attribute__ ((visibility("default")))
|
||||
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
# define CLOSE _close
|
||||
# define WRITE _write
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# define CLOSE close
|
||||
# define WRITE write
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
|
||||
{
|
||||
int r = WRITE(fd, data, length);
|
||||
if (r != length) {
|
||||
e->ThrowNew(e->FindClass("java/lang/IOException"), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_io_FileOutputStream_write__II(JNIEnv* e, jclass, jint fd, jint c)
|
||||
{
|
||||
jbyte data = c;
|
||||
doWrite(e, fd, &data, 1);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_io_FileOutputStream_write__I_3BII
|
||||
(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length)
|
||||
{
|
||||
jbyte* data = static_cast<jbyte*>(malloc(length));
|
||||
if (data == 0) {
|
||||
e->ThrowNew(e->FindClass("java/lang/OutOfMemoryError"), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
e->GetByteArrayRegion(b, offset, length, data);
|
||||
|
||||
if (not e->ExceptionCheck()) {
|
||||
doWrite(e, fd, data, length);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_java_io_FileOutputStream_close(JNIEnv* e, jclass, jint fd)
|
||||
{
|
||||
int r = CLOSE(fd);
|
||||
if (r == -1) {
|
||||
e->ThrowNew(e->FindClass("java/lang/IOException"), strerror(errno));
|
||||
}
|
||||
}
|
@ -1,16 +1,28 @@
|
||||
package java.io;
|
||||
|
||||
public class FileOutputStream extends OutputStream {
|
||||
private final FileDescriptor fd;
|
||||
private final int fd;
|
||||
|
||||
public FileOutputStream(FileDescriptor fd) {
|
||||
this.fd = fd;
|
||||
this.fd = fd.value;
|
||||
}
|
||||
|
||||
public native void write(int c) throws IOException;
|
||||
public static native void write(int fd, int c) throws IOException;
|
||||
|
||||
public native void write(byte[] b, int offset, int length)
|
||||
public static native void write(int fd, byte[] b, int offset, int length)
|
||||
throws IOException;
|
||||
|
||||
public native void close() throws IOException;
|
||||
public static native void close(int fd) throws IOException;
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
write(fd, c);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int offset, int length) throws IOException {
|
||||
write(fd, b, offset, length);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "jni.h"
|
||||
|
||||
@ -6,7 +5,7 @@
|
||||
#define JNIEXPORT __attribute__ ((visibility("default")))
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_java_lang_System_getProperty(JNIEnv* e, jstring key)
|
||||
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring key)
|
||||
{
|
||||
jstring value = 0;
|
||||
|
||||
|
4
makefile
4
makefile
@ -16,7 +16,7 @@ src = src
|
||||
classpath = classpath
|
||||
test = test
|
||||
|
||||
input = $(cls)/Threads.class
|
||||
input = $(cls)/Hello.class
|
||||
|
||||
cxx = g++
|
||||
cc = gcc
|
||||
@ -55,7 +55,7 @@ java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(cls)/%.class,$(x)))
|
||||
stdcpp-sources = $(src)/stdc++.cpp
|
||||
stdcpp-objects = $(call cpp-objects,$(stdcpp-sources),$(src))
|
||||
|
||||
jni-sources = $(classpath)/java/lang/System.cpp
|
||||
jni-sources = $(shell find $(classpath) -name '*.cpp')
|
||||
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath))
|
||||
jni-cflags = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux $(cflags)
|
||||
jni-library = $(bld)/libnatives.so
|
||||
|
@ -65,7 +65,7 @@ notifyAll(Thread* t, jobject this_)
|
||||
}
|
||||
|
||||
jclass
|
||||
forName(Thread* t, jstring name)
|
||||
forName(Thread* t, jclass, jstring name)
|
||||
{
|
||||
if (LIKELY(name)) {
|
||||
object n = makeByteArray(t, stringLength(t, *name) + 1, false);
|
||||
@ -207,13 +207,13 @@ invoke(Thread* t, jobject this_, jobject instancep, jobjectArray argumentsp)
|
||||
}
|
||||
|
||||
jobject
|
||||
currentThread(Thread* t)
|
||||
currentThread(Thread* t, jclass)
|
||||
{
|
||||
return pushReference(t, t->javaThread);
|
||||
}
|
||||
|
||||
void
|
||||
sleep(Thread* t, jlong milliseconds)
|
||||
sleep(Thread* t, jclass, jlong milliseconds)
|
||||
{
|
||||
if (milliseconds == 0) milliseconds = INT64_MAX;
|
||||
|
||||
@ -223,8 +223,8 @@ sleep(Thread* t, jlong milliseconds)
|
||||
}
|
||||
|
||||
void
|
||||
arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
|
||||
jint length)
|
||||
arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst,
|
||||
jint dstOffset, jint length)
|
||||
{
|
||||
if (LIKELY(src and dst)) {
|
||||
object s = *src;
|
||||
@ -263,7 +263,7 @@ arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
|
||||
}
|
||||
|
||||
jlong
|
||||
currentTimeMillis(Thread* t)
|
||||
currentTimeMillis(Thread* t, jclass)
|
||||
{
|
||||
return t->vm->system->now();
|
||||
}
|
||||
@ -311,7 +311,7 @@ exit(Thread* t, jobject, jint code)
|
||||
}
|
||||
|
||||
jobject
|
||||
trace(Thread* t, jint skipCount)
|
||||
trace(Thread* t, jclass, jint skipCount)
|
||||
{
|
||||
int frame = t->frame;
|
||||
while (skipCount-- and frame >= 0) {
|
||||
@ -334,7 +334,7 @@ trace(Thread* t, jint skipCount)
|
||||
}
|
||||
|
||||
jarray
|
||||
resolveTrace(Thread* t, jobject trace)
|
||||
resolveTrace(Thread* t, jclass, jobject trace)
|
||||
{
|
||||
unsigned length = arrayLength(t, *trace);
|
||||
object array = makeObjectArray
|
||||
|
@ -60,15 +60,14 @@ avg(unsigned a, unsigned b)
|
||||
inline unsigned
|
||||
pad(unsigned n)
|
||||
{
|
||||
unsigned extra = n % BytesPerWord;
|
||||
return (extra ? n + BytesPerWord - extra : n);
|
||||
n += BytesPerWord - 1;
|
||||
return n - (n % BytesPerWord);
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
divide(unsigned n, unsigned d)
|
||||
ceiling(unsigned n, unsigned d)
|
||||
{
|
||||
if (n and d > n) return 1;
|
||||
return (n / d) + (n % d ? 1 : 0);
|
||||
return (n + d - 1) / d;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "system.h"
|
||||
#include "common.h"
|
||||
|
||||
#define CHAIN_HEADER_SIZE divide(sizeof(Segment::Chain), BytesPerWord)
|
||||
#define CHAIN_HEADER_SIZE ceiling(sizeof(Segment::Chain), BytesPerWord)
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -164,7 +164,7 @@ class Segment {
|
||||
|
||||
unsigned size(unsigned capacity) {
|
||||
unsigned result
|
||||
= divide(divide(capacity, scale) * bitsPerRecord, BitsPerWord);
|
||||
= ceiling(ceiling(capacity, scale) * bitsPerRecord, BitsPerWord);
|
||||
assert(segment->context, result);
|
||||
return result;
|
||||
}
|
||||
|
@ -761,7 +761,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
classObjectMask(t, classSuper(t, class_)));
|
||||
} else {
|
||||
object mask = makeIntArray
|
||||
(t, divide(classFixedSize(t, class_), BitsPerWord * BytesPerWord), true);
|
||||
(t, ceiling(classFixedSize(t, class_), BitsPerWord * BytesPerWord), true);
|
||||
intArrayBody(t, mask, 0) = 1;
|
||||
|
||||
bool sawReferenceField = false;
|
||||
@ -1571,7 +1571,7 @@ allocate2(Thread* t, unsigned sizeInBytes)
|
||||
ENTER(t, Thread::IdleState);
|
||||
}
|
||||
|
||||
if (t->heapIndex + divide(sizeInBytes, BytesPerWord)
|
||||
if (t->heapIndex + ceiling(sizeInBytes, BytesPerWord)
|
||||
>= Thread::HeapSizeInWords)
|
||||
{
|
||||
ENTER(t, Thread::ExclusiveState);
|
||||
@ -2287,9 +2287,9 @@ collect(Thread* t, Heap::CollectionType type)
|
||||
// "fixed size: %d; array length: %d; element size: %d; mask: %x\n",
|
||||
// fixedSize, arrayLength, arrayElementSize, mask[0]);
|
||||
|
||||
unsigned fixedSizeInWords = divide(fixedSize, BytesPerWord);
|
||||
unsigned fixedSizeInWords = ceiling(fixedSize, BytesPerWord);
|
||||
unsigned arrayElementSizeInWords
|
||||
= divide(arrayElementSize, BytesPerWord);
|
||||
= ceiling(arrayElementSize, BytesPerWord);
|
||||
|
||||
for (unsigned i = 0; i < fixedSizeInWords; ++i) {
|
||||
if (mask[wordOf(i)] & (static_cast<uintptr_t>(1) << bitOf(i))) {
|
||||
|
@ -1303,7 +1303,7 @@ inline object
|
||||
allocateSmall(Thread* t, unsigned sizeInBytes)
|
||||
{
|
||||
object o = t->heap + t->heapIndex;
|
||||
t->heapIndex += divide(sizeInBytes, BytesPerWord);
|
||||
t->heapIndex += ceiling(sizeInBytes, BytesPerWord);
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -1315,7 +1315,7 @@ allocate(Thread* t, unsigned sizeInBytes)
|
||||
{
|
||||
stress(t);
|
||||
|
||||
if (UNLIKELY(t->heapIndex + divide(sizeInBytes, BytesPerWord)
|
||||
if (UNLIKELY(t->heapIndex + ceiling(sizeInBytes, BytesPerWord)
|
||||
>= Thread::HeapSizeInWords
|
||||
or t->vm->exclusive))
|
||||
{
|
||||
@ -1729,10 +1729,10 @@ hash(const int8_t* s, unsigned length)
|
||||
inline unsigned
|
||||
baseSize(Thread* t, object o, object class_)
|
||||
{
|
||||
return divide(classFixedSize(t, class_), BytesPerWord)
|
||||
+ divide(classArrayElementSize(t, class_)
|
||||
* cast<uintptr_t>(o, classFixedSize(t, class_) - BytesPerWord),
|
||||
BytesPerWord);
|
||||
return ceiling(classFixedSize(t, class_), BytesPerWord)
|
||||
+ ceiling(classArrayElementSize(t, class_)
|
||||
* cast<uintptr_t>(o, classFixedSize(t, class_) - BytesPerWord),
|
||||
BytesPerWord);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
27
src/run.cpp
27
src/run.cpp
@ -265,23 +265,24 @@ makeNativeMethodData(Thread* t, object method, void* function, bool builtin)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
unsigned count = methodParameterCount(t, method) + 1;
|
||||
if (methodFlags(t, method) & ACC_STATIC) {
|
||||
++ count;
|
||||
}
|
||||
|
||||
object data = makeNativeMethodData(t,
|
||||
function,
|
||||
0, // argument table size
|
||||
0, // return code,
|
||||
builtin,
|
||||
methodParameterCount(t, method) + 1,
|
||||
count,
|
||||
false);
|
||||
|
||||
unsigned argumentTableSize = BytesPerWord;
|
||||
unsigned argumentTableSize = BytesPerWord * 2;
|
||||
unsigned index = 0;
|
||||
|
||||
nativeMethodDataParameterTypes(t, data, index++) = POINTER_TYPE;
|
||||
|
||||
if ((methodFlags(t, method) & ACC_STATIC) == 0) {
|
||||
nativeMethodDataParameterTypes(t, data, index++) = POINTER_TYPE;
|
||||
argumentTableSize += BytesPerWord;
|
||||
}
|
||||
nativeMethodDataParameterTypes(t, data, index++) = POINTER_TYPE;
|
||||
|
||||
const char* s = reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodSpec(t, method), 0));
|
||||
@ -395,6 +396,9 @@ invokeNative(Thread* t, object method)
|
||||
pushFrame(t, method);
|
||||
|
||||
unsigned count = methodParameterCount(t, method);
|
||||
if (methodFlags(t, method) & ACC_STATIC) {
|
||||
++ count;
|
||||
}
|
||||
|
||||
unsigned size = nativeMethodDataArgumentTableSize(t, data);
|
||||
uintptr_t args[size / BytesPerWord];
|
||||
@ -402,8 +406,15 @@ invokeNative(Thread* t, object method)
|
||||
|
||||
args[offset++] = reinterpret_cast<uintptr_t>(t);
|
||||
|
||||
unsigned start = 0;
|
||||
if (methodFlags(t, method) & ACC_STATIC) {
|
||||
start = 1;
|
||||
args[offset++] = reinterpret_cast<uintptr_t>
|
||||
(pushReference(t, methodClass(t, method)));
|
||||
}
|
||||
|
||||
unsigned sp = frameBase(t, t->frame);
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
for (unsigned i = start; i < count; ++i) {
|
||||
unsigned type = nativeMethodDataParameterTypes(t, data, i + 1);
|
||||
|
||||
switch (type) {
|
||||
|
@ -11,8 +11,10 @@ tests=${@}
|
||||
|
||||
echo -n "" >${log}
|
||||
|
||||
echo
|
||||
|
||||
for test in ${tests}; do
|
||||
printf "${test}: "
|
||||
printf "%16s" "${test}: "
|
||||
|
||||
case ${mode} in
|
||||
debug )
|
||||
|
Loading…
Reference in New Issue
Block a user