Merge branch 'master' into arm

This commit is contained in:
Joel Dice 2010-09-03 23:26:08 +01:00
commit d9e79db062
23 changed files with 343 additions and 95 deletions

View File

@ -212,9 +212,11 @@ public class PersistentSet <T> implements Iterable <T> {
Node<T> child;
if (dead.left != NullNode) {
child = dead.left;
child = new Node(dead.left);
} else if (dead.right != NullNode) {
child = new Node(dead.right);
} else {
child = dead.right;
child = NullNode;
}
if (ancestors == null) {
@ -453,6 +455,7 @@ public class PersistentSet <T> implements Iterable <T> {
return new Path(false, s.value, p.root, s.next);
}
}
private static class Node <T> {
public T value;
public Node left;

View File

@ -593,11 +593,11 @@ Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd)
}
extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path)
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path, jboolean append)
{
string_t chars = getChars(e, path);
if (chars) {
int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC);
int fd = doOpen(e, chars, append ? (O_WRONLY | O_APPEND) : (O_WRONLY | O_CREAT | O_TRUNC));
releaseChars(e, path, chars);
return fd;
} else {

View File

@ -72,6 +72,10 @@ public class BufferedInputStream extends InputStream {
return count;
}
public int available() throws IOException {
return in.available() + (limit - position);
}
public void close() throws IOException {
in.close();
}

View File

@ -22,14 +22,19 @@ public class FileOutputStream extends OutputStream {
}
public FileOutputStream(String path) throws IOException {
fd = open(path);
this(path, false);
}
public FileOutputStream(String path, boolean append) throws IOException {
fd = open(path, append);
}
public FileOutputStream(File file) throws IOException {
this(file.getPath());
}
private static native int open(String path) throws IOException;
private static native int open(String path, boolean append) throws IOException;
private static native void write(int fd, int c) throws IOException;

View File

@ -13,6 +13,10 @@ package java.lang;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
public abstract class ClassLoader {
private final ClassLoader parent;
@ -123,4 +127,24 @@ public abstract class ClassLoader {
public static InputStream getSystemResourceAsStream(String path) {
return getSystemClassLoader().getResourceAsStream(path);
}
public static Enumeration<URL> getSystemResources(String name) throws IOException {
return getSystemClassLoader().getResources(name);
}
public Enumeration<URL> getResources(String name)
throws IOException {
Collection<URL> resources = collectResources(name);
return Collections.enumeration(resources);
}
private Collection<URL> collectResources(String name) {
Collection<URL> urls = parent != null ? parent.collectResources(name) : new ArrayList<URL>(5);
URL url = findResource(name);
if (url != null) {
urls.add(url);
}
return urls;
}
}

View File

@ -0,0 +1,26 @@
/* Copyright (c) 2010, 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. */
package java.lang;
/**
* TODO : current Avian runtime doesn't check, need to be implemented.
*
*/
public class IllegalAccessError extends IncompatibleClassChangeError {
public IllegalAccessError(String message) {
super(message);
}
public IllegalAccessError() {
}
}

View File

@ -0,0 +1,26 @@
/* Copyright (c) 2010, 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. */
package java.lang;
/**
* TODO : current Avian runtime doesn't check, need to be implemented.
*
*/
public class InstantiationError extends IncompatibleClassChangeError {
public InstantiationError(String message) {
super(message);
}
public InstantiationError() {
}
}

View File

@ -0,0 +1,75 @@
/* Copyright (c) 2010, 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. */
package java.nio.channels;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
public class Channels {
public static InputStream newInputStream(ReadableByteChannel channel) {
return new MyInputStream(channel);
}
public static OutputStream newOutputStream(WritableByteChannel channel) {
return new MyOutputStream(channel);
}
private static class MyInputStream extends InputStream {
private final ReadableByteChannel channel;
public MyInputStream(ReadableByteChannel channel) {
this.channel = channel;
}
public int read() throws IOException {
byte[] buffer = new byte[1];
int r = read(buffer);
if (r == -1) {
return -1;
} else {
return buffer[0] & 0xFF;
}
}
public int read(byte[] buffer, int offset, int length) throws IOException {
return channel.read(ByteBuffer.wrap(buffer, offset, length));
}
public void close() throws IOException {
channel.close();
}
}
private static class MyOutputStream extends OutputStream {
private final WritableByteChannel channel;
public MyOutputStream(WritableByteChannel channel) {
this.channel = channel;
}
public void write(int v) throws IOException {
byte[] buffer = new byte[] { (byte) (v & 0xFF) };
write(buffer);
}
public void write(byte[] buffer, int offset, int length)
throws IOException
{
channel.write(ByteBuffer.wrap(buffer, offset, length));
}
public void close() throws IOException {
channel.close();
}
}
}

View File

@ -79,6 +79,10 @@ public class Collections {
sb.append("}");
return sb.toString();
}
public static <T> Enumeration<T> enumeration(Collection<T> c) {
return new IteratorEnumeration<T> (c.iterator());
}
static class IteratorEnumeration<T> implements Enumeration<T> {
private final Iterator<T> it;

View File

@ -48,6 +48,10 @@ public class Properties extends Hashtable {
public Object setProperty(String key, String value) {
return put(key, value);
}
public Enumeration<?> propertyNames() {
return keys();
}
private static class Parser {
private StringBuilder key = null;

View File

@ -61,6 +61,8 @@ public class InflaterInputStream extends InputStream {
return count;
} else if (inflater.needsDictionary()) {
throw new IOException("missing dictionary");
} else if (inflater.finished()) {
return -1;
}
} catch (DataFormatException e) {
throw new IOException(e);
@ -68,6 +70,10 @@ public class InflaterInputStream extends InputStream {
}
}
public int available() throws IOException {
return inflater.finished() ? 0 : 1;
}
public void close() throws IOException {
in.close();
inflater.dispose();

View File

@ -201,9 +201,18 @@ By default, Avian uses its own lightweight class library. However,
that library only contains a relatively small subset of the classes
and methods included in the JRE. If your application requires
features beyond that subset, you may want to tell Avian to use GNU
Classpath instead. To do so, specify the directory where Classpath is
Classpath instead. In order for this to work, you must configure
Classpath with "--enable-static" and "--with-pic". For example:
$ cd classpath-0.98
$ ./configure --prefix=/usr/local/classpath-0.98 --disable-plugin \
--enable-static --with-pic
$ make && make install
Then, when building Avian, specify the directory where Classpath is
installed, e.g.:
$ cd ../avian
$ make clean
$ make gnu=/usr/local/classpath-0.98

View File

@ -594,25 +594,32 @@ Avian_java_lang_System_arraycopy
if (LIKELY(elementSize)) {
intptr_t sl = cast<uintptr_t>(src, BytesPerWord);
intptr_t dl = cast<uintptr_t>(dst, BytesPerWord);
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
dstOffset >= 0 and dstOffset + length <= dl))
{
uint8_t* sbody = &cast<uint8_t>(src, ArrayBody);
uint8_t* dbody = &cast<uint8_t>(dst, ArrayBody);
if (src == dst) {
memmove(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
if (LIKELY(length > 0)) {
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
dstOffset >= 0 and dstOffset + length <= dl))
{
uint8_t* sbody = &cast<uint8_t>(src, ArrayBody);
uint8_t* dbody = &cast<uint8_t>(dst, ArrayBody);
if (src == dst) {
memmove(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
} else {
memcpy(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
}
if (classObjectMask(t, objectClass(t, dst))) {
mark(t, dst, ArrayBody + (dstOffset * BytesPerWord), length);
}
return;
} else {
memcpy(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
t->exception = makeIndexOutOfBoundsException(t);
return;
}
if (classObjectMask(t, objectClass(t, dst))) {
mark(t, dst, ArrayBody + (dstOffset * BytesPerWord), length);
}
} else {
return;
}
}

View File

@ -7332,6 +7332,17 @@ class MyProcessor: public Processor {
}
}
virtual bool
isInitializing(Thread* t, object c)
{
for (Thread::ClassInitStack* s = t->classInitStack; s; s = s->next) {
if (s->class_ == c) {
return true;
}
}
return false;
}
virtual void
visitObjects(Thread* vmt, Heap::Visitor* v)
{

View File

@ -761,12 +761,6 @@ invokeNative(Thread* t, object method)
bool
classInit2(Thread* t, object class_, unsigned ipOffset)
{
for (ClassInitList* list = t->classInitList; list; list = list->next) {
if (list->class_ == class_) {
return false;
}
}
PROTECT(t, class_);
if (preInitClass(t, class_)) {
@ -3111,6 +3105,26 @@ class MyProcessor: public Processor {
// ignore
}
virtual bool
isInitializing(vm::Thread* vmt, object c)
{
Thread* t = static_cast<Thread*>(vmt);
for (ClassInitList* list = t->classInitList; list; list = list->next) {
if (list->class_ == c) {
return true;
}
}
for (Thread::ClassInitStack* s = t->classInitStack; s; s = s->next) {
if (s->class_ == c) {
return true;
}
}
return false;
}
virtual void
visitObjects(vm::Thread* vmt, Heap::Visitor* v)
{

View File

@ -1952,9 +1952,15 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
envTable->FindClass = local::FindClass;
envTable->ThrowNew = local::ThrowNew;
envTable->ExceptionCheck = local::ExceptionCheck;
#ifdef AVIAN_GNU
envTable->NewDirectByteBuffer = vm::NewDirectByteBuffer;
envTable->GetDirectBufferAddress = vm::GetDirectBufferAddress;
envTable->GetDirectBufferCapacity = vm::GetDirectBufferCapacity;
#else
envTable->NewDirectByteBuffer = local::NewDirectByteBuffer;
envTable->GetDirectBufferAddress = local::GetDirectBufferAddress;
envTable->GetDirectBufferCapacity = local::GetDirectBufferCapacity;
#endif
envTable->DeleteLocalRef = local::DeleteLocalRef;
envTable->GetObjectClass = local::GetObjectClass;
envTable->IsInstanceOf = local::IsInstanceOf;

View File

@ -3309,13 +3309,11 @@ preInitClass(Thread* t, object c)
ACQUIRE(t, t->m->classLock);
if (classVmFlags(t, c) & NeedInitFlag) {
if (classVmFlags(t, c) & InitFlag) {
// the class is currently being initialized. If this the
// thread which is initializing it, we should not try to
// initialize it recursively.
for (Thread::ClassInitStack* s = t->classInitStack; s; s = s->next) {
if (s->class_ == c) {
return false;
}
// If the class is currently being initialized and this the thread
// which is initializing it, we should not try to initialize it
// recursively.
if (t->m->processor->isInitializing(t, c)) {
return false;
}
// some other thread is on the job - wait for it to finish.

View File

@ -1759,6 +1759,12 @@ makeIllegalMonitorStateException(Thread* t)
return makeIllegalMonitorStateException(t, 0, makeTrace(t), 0);
}
inline object
makeIndexOutOfBoundsException(Thread* t)
{
return makeIndexOutOfBoundsException(t, 0, makeTrace(t), 0);
}
inline object
makeArrayIndexOutOfBoundsException(Thread* t, object message)
{

View File

@ -471,12 +471,14 @@ void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler::
if (sh < 32) {
emit(con, rlwinm(t->high,b->high,sh,0,31-sh));
emit(con, rlwimi(t->high,b->low,sh,32-sh,31));
emit(con, slwi(t->low, b->low, sh));
} else {
emit(con, rlwinm(t->high,b->low,sh-32,0,63-sh));
emit(con, li(t->low,0));
}
} else {
emit(con, slwi(t->low, b->low, sh));
}
emit(con, slwi(t->low, b->low, sh));
}
void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t)
@ -1675,62 +1677,6 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
emit(c, b(0));
}
void
jumpIfEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
{
assert(c, size == BytesPerWord);
appendOffsetTask(c, target->value, offset(c), true);
emit(c, beq(0));
}
void
jumpIfNotEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
{
assert(c, size == BytesPerWord);
appendOffsetTask(c, target->value, offset(c), true);
emit(c, bne(0));
}
void
jumpIfGreaterC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
{
assert(c, size == BytesPerWord);
appendOffsetTask(c, target->value, offset(c), true);
emit(c, bgt(0));
}
void
jumpIfGreaterOrEqualC(Context* c, unsigned size UNUSED,
Assembler::Constant* target)
{
assert(c, size == BytesPerWord);
appendOffsetTask(c, target->value, offset(c), true);
emit(c, bge(0));
}
void
jumpIfLessC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
{
assert(c, size == BytesPerWord);
appendOffsetTask(c, target->value, offset(c), true);
emit(c, blt(0));
}
void
jumpIfLessOrEqualC(Context* c, unsigned size UNUSED,
Assembler::Constant* target)
{
assert(c, size == BytesPerWord);
appendOffsetTask(c, target->value, offset(c), true);
emit(c, ble(0));
}
void
return_(Context* c)
{
@ -2196,6 +2142,12 @@ class MyAssembler: public Assembler {
}
virtual void saveFrame(unsigned stackOffset, unsigned) {
Register returnAddress(0);
emit(&c, mflr(returnAddress.low));
Memory returnAddressDst(StackRegister, 8);
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
Register stack(StackRegister);
Memory stackDst(ThreadRegister, stackOffset);
moveRM(&c, BytesPerWord, &stack, BytesPerWord, &stackDst);

View File

@ -81,6 +81,9 @@ class Processor {
virtual void
initVtable(Thread* t, object c) = 0;
virtual bool
isInitializing(Thread* t, object c) = 0;
virtual void
visitObjects(Thread* t, Heap::Visitor* v) = 0;

40
test/FileOutput.java Normal file
View File

@ -0,0 +1,40 @@
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.File;
import java.io.IOException;
public class FileOutput {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
try {
FileOutputStream f = new FileOutputStream("test.txt");
f.write("Hello world!\n".getBytes());
f.close();
FileOutputStream f2 = new FileOutputStream("test.txt", true);
f2.write("Hello world again!".getBytes());
f2.close();
FileInputStream in = new FileInputStream("test.txt");
byte[] buffer = new byte[256];
int c;
int offset = 0;
while ((c = in.read(buffer, offset, buffer.length - offset)) != -1) {
offset += c;
}
if (! "Hello world!\nHello world again!".equals
(new String(buffer, 0, offset)))
{
throw new RuntimeException();
}
} finally {
new File("test.txt").delete();
}
}
}

View File

@ -3,6 +3,22 @@ public class Longs {
if (! v) throw new RuntimeException();
}
public static long readLongFrom(java.io.InputStream in)
throws java.io.IOException
{
long b1 = in.read();
long b2 = in.read();
long b3 = in.read();
long b4 = in.read();
long b5 = in.read();
long b6 = in.read();
long b7 = in.read();
long b8 = in.read();
if (b8 == -1) throw new java.io.EOFException();
return (long) ((b1 << 56) | (b2 << 48) | (b3 << 40) | (b4 << 32) |
(b5 << 24) | (b6 << 16) | (b7 << 8) | (b8));
}
public static void putInt(int val, byte[] dst, int offset) {
System.out.println("put " + val);
dst[offset] = (byte)((val >> 24) & 0xff);
@ -43,7 +59,15 @@ public class Longs {
return x >>> 32;
}
public static void main(String[] args) {
public static void main(String[] args) throws Exception {
expect(readLongFrom(new java.io.InputStream() {
int step;
public int read() {
return ++step;
}
}) == 0x0102030405060708L);
expect(((long) negativeOne()) == -1);
{ long foo = 25214903884L;

1
vm.pro
View File

@ -38,6 +38,7 @@
-keep public class java.lang.IllegalArgumentException
-keep public class java.lang.IllegalMonitorStateException
-keep public class java.lang.IllegalThreadStateException
-keep public class java.lang.IndexOutOfBoundsException
-keep public class java.lang.ArrayIndexOutOfBoundsException
-keep public class java.lang.ArrayStoreException
-keep public class java.lang.NegativeArraySizeException