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:
Joel Dice 2007-07-25 18:48:28 -06:00
parent 38a982c7dd
commit 9ab88ef619
14 changed files with 233 additions and 49 deletions

View File

@ -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;

View 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));
}
}

View File

@ -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);
}
}

View 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));
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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))) {

View File

@ -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

View File

@ -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) {

View File

@ -11,8 +11,10 @@ tests=${@}
echo -n "" >${log}
echo
for test in ${tests}; do
printf "${test}: "
printf "%16s" "${test}: "
case ${mode} in
debug )