Merge branch 'master' of oss:/var/local/git/avian into powerpc

This commit is contained in:
Joel Dice 2008-07-13 12:47:49 -06:00
commit 2343483d8e
21 changed files with 405 additions and 87 deletions

View File

@ -257,7 +257,7 @@ Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path)
{
const char* chars = e->GetStringUTFChars(path, 0);
if (chars) {
int fd = doOpen(e, chars, O_WRONLY | O_CREAT);
int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC);
e->ReleaseStringUTFChars(path, chars);
return fd;
} else {

View File

@ -0,0 +1,21 @@
/* Copyright (c) 2008, 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;
public interface CharSequence {
public char charAt(int index);
int length();
CharSequence subSequence(int start, int end);
String toString();
}

View File

@ -415,4 +415,8 @@ public final class Class <T> {
return null;
}
}
public boolean desiredAssertionStatus() {
return false;
}
}

View File

@ -12,7 +12,7 @@ package java.lang;
import java.io.UnsupportedEncodingException;
public final class String implements Comparable<String> {
public final class String implements Comparable<String>, CharSequence {
private Object data;
private int offset;
private int length;
@ -44,12 +44,12 @@ public final class String implements Comparable<String> {
public String(byte[] data, String charset)
throws UnsupportedEncodingException
{
this(data);
if (! charset.equals("US-ASCII")) {
throw new UnsupportedEncodingException(charset);
{
this(data);
if (! charset.equals("US-ASCII")) {
throw new UnsupportedEncodingException(charset);
}
}
}
private String(Object data, int offset, int length, boolean copy) {
int l;
@ -253,11 +253,11 @@ public final class String implements Comparable<String> {
if (data instanceof char[]) {
char[] buf = new char[length];
for (int i=0; i < length; i++) {
if (charAt(i) == oldChar) {
buf[i] = newChar;
} else {
buf[i] = charAt(i);
}
if (charAt(i) == oldChar) {
buf[i] = newChar;
} else {
buf[i] = charAt(i);
}
}
return new String(buf, 0, length, false);
} else {
@ -266,11 +266,11 @@ public final class String implements Comparable<String> {
byte oldByte = (byte)oldChar;
byte newByte = (byte)newChar;
for (int i=0; i < length; i++) {
if (orig[i+offset] == oldByte) {
buf[i] = newByte;
} else {
buf[i] = orig[i+offset];
}
if (orig[i+offset] == oldByte) {
buf[i] = newByte;
} else {
buf[i] = orig[i+offset];
}
}
return new String(buf, 0, length, false);
}
@ -425,6 +425,10 @@ public final class String implements Comparable<String> {
return array;
}
public CharSequence subSequence(int start, int end) {
return substring(start, end);
}
public native String intern();
public static String valueOf(Object s) {

View File

@ -10,7 +10,7 @@
package java.lang;
public class StringBuffer {
public class StringBuffer implements CharSequence {
private final StringBuilder sb;
public StringBuffer(String s) {
@ -116,4 +116,12 @@ public class StringBuffer {
public synchronized String toString() {
return sb.toString();
}
public String substring(int start, int end) {
return sb.substring(start, end);
}
public CharSequence subSequence(int start, int end) {
return sb.subSequence(start, end);
}
}

View File

@ -10,7 +10,7 @@
package java.lang;
public class StringBuilder {
public class StringBuilder implements CharSequence {
private static final int BufferSize = 32;
private Cell chain;
@ -288,4 +288,15 @@ public class StringBuilder {
this.next = next;
}
}
public String substring(int start, int end) {
int len = end-start;
char[] buf = new char[len];
getChars(start, len, buf,0 );
return new String(buf, 0, len, false);
}
public CharSequence subSequence(int start, int end) {
return substring(start, end);
}
}

View File

@ -21,9 +21,9 @@ import java.io.FileDescriptor;
public abstract class System {
private static Property properties;
// static {
// loadLibrary("natives");
// }
// static {
// loadLibrary("natives");
// }
public static final PrintStream out = new PrintStream
(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
@ -53,6 +53,15 @@ public abstract class System {
return null;
}
public static String getProperty(String name, String defaultValue) {
String result = getProperty(name);
if (result==null) {
return defaultValue;
}
return result;
}
public static String setProperty(String name, String value) {
for (Property p = properties; p != null; p = p.next) {

View File

@ -0,0 +1,71 @@
/* Copyright (c) 2008, 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.util;
/**
* @author zsombor
*
*/
public abstract class AbstractCollection<T> implements Collection<T> {
public boolean add(T element) {
throw new UnsupportedOperationException("adding to "
+ this.getClass().getName());
}
public boolean addAll(Collection<? extends T> collection) {
boolean result = false;
for (T obj : collection) {
result |= add(obj);
}
return result;
}
public void clear() {
throw new UnsupportedOperationException("clear() in "
+ this.getClass().getName());
}
public boolean contains(T element) {
if (element != null) {
for (Iterator<T> iter = iterator(); iter.hasNext();) {
if (element.equals(iter.next())) {
return true;
}
}
} else {
for (Iterator<T> iter = iterator(); iter.hasNext();) {
if (iter.next()==null) {
return true;
}
}
}
return false;
}
public boolean isEmpty() {
return size() == 0;
}
public boolean remove(T element) {
throw new UnsupportedOperationException("remove(T) in "
+ this.getClass().getName());
}
public abstract int size();
public <S> S[] toArray(S[] array) {
return Collections.toArray(this, array);
}
public abstract Iterator<T> iterator();
}

View File

@ -0,0 +1,14 @@
/* Copyright (c) 2008, 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.util;
public abstract class AbstractSet<T> extends AbstractCollection<T> implements Set<T> {
}

View File

@ -187,4 +187,53 @@ public class Collections {
}
}
}
static class UnmodifiableSet<T> implements Set<T> {
Set<T> inner;
UnmodifiableSet(Set<T> inner) {
this.inner = inner;
}
public boolean add(T element) {
throw new UnsupportedOperationException("not supported");
}
public boolean addAll(Collection<? extends T> collection) {
throw new UnsupportedOperationException("not supported");
}
public void clear() {
throw new UnsupportedOperationException("not supported");
}
public boolean contains(T element) {
return inner.contains(element);
}
public boolean isEmpty() {
return inner.isEmpty();
}
public Iterator<T> iterator() {
return inner.iterator();
}
public boolean remove(T element) {
throw new UnsupportedOperationException("not supported");
}
public int size() {
return inner.size();
}
public <S> S[] toArray(S[] array) {
return inner.toArray(array);
}
}
public static <T> Set<T> unmodifiableSet(Set<T> hs) {
return new UnmodifiableSet<T>(hs);
}
}

View File

@ -10,7 +10,7 @@
package java.util;
public class TreeSet<T> implements Collection<T> {
public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
private PersistentSet<Cell<T>> set;
private int size;
@ -41,12 +41,6 @@ public class TreeSet<T> implements Collection<T> {
return false;
}
public boolean addAll(Collection<? extends T> collection) {
boolean change = false;
for (T t: collection) if (add(t)) change = true;
return change;
}
// Used by hashMaps for replacement
public void addAndReplace(T value) {
PersistentSet.Path<Cell<T>> p = set.find(new Cell(value, null));
@ -75,10 +69,6 @@ public class TreeSet<T> implements Collection<T> {
}
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}
public int size() {
return size;
}

View File

@ -1,3 +1,13 @@
/* Copyright (c) 2008, 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. */
#ifndef ASSEMBLER_H
#define ASSEMBLER_H

View File

@ -1,3 +1,13 @@
/* Copyright (c) 2008, 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 "stdint.h"
#include "stdlib.h"

View File

@ -2654,6 +2654,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object target = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return;
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
unsigned parameterFootprint = methodParameterFootprint(t, target);
unsigned instance = parameterFootprint - 1;
@ -2692,6 +2694,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
target = findMethod(t, target, classSuper(t, class_));
}
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
compileDirectInvoke(t, frame, target);
} break;
@ -2701,6 +2705,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object target = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return;
assert(t, methodFlags(t, target) & ACC_STATIC);
compileDirectInvoke(t, frame, target);
} break;
@ -2710,6 +2716,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object target = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return;
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
unsigned parameterFootprint = methodParameterFootprint(t, target);
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
@ -3669,21 +3677,6 @@ compareTraceElementPointers(const void* va, const void* vb)
}
}
intptr_t
compareMethodBounds(Thread* t, object a, object b)
{
if (DebugMethodTree) {
fprintf(stderr, "compare %p to %p\n",
&singletonValue(t, methodCompiled(t, a), 0),
&singletonValue(t, methodCompiled(t, b), 0));
}
return reinterpret_cast<intptr_t>
(&singletonValue(t, methodCompiled(t, a), 0))
- reinterpret_cast<intptr_t>
(&singletonValue(t, methodCompiled(t, b), 0));
}
unsigned
frameObjectMapSize(MyThread* t, object method, object map)
{
@ -4314,7 +4307,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
} else {
break;
}
}
}
}
void
@ -5143,13 +5136,56 @@ compile(MyThread* t, object method)
if (UNLIKELY(t->exception)) return;
if (methodCompiled(t, method) == p->defaultThunk) {
object node;
object compiled;
if (methodFlags(t, method) & ACC_NATIVE) {
node = 0;
compiled = p->nativeThunk;
} else {
Context context(t, method);
compiled = compile(t, &context);
if (UNLIKELY(t->exception)) return;
PROTECT(t, compiled);
if (DebugMethodTree) {
fprintf(stderr, "insert method at %p\n",
&singletonValue(t, compiled, 0));
}
// We can't set the MethodCompiled field on the original
// method before it is placed into the method tree, since
// another thread might call the method, from which stack
// unwinding would fail (since there is not yet an entry in
// the method tree). However, we can't insert the original
// method into the tree before setting the MethodCompiled
// field on it since we rely on that field to determine its
// position in the tree. Therefore, we insert a clone in
// its place. Later, we'll replace the clone with the
// original to save memory.
object clone = makeMethod
(t, methodVmFlags(t, method),
methodReturnCode(t, method),
methodParameterCount(t, method),
methodParameterFootprint(t, method),
methodFlags(t, method),
methodOffset(t, method),
methodName(t, method),
methodSpec(t, method),
methodClass(t, method),
methodCode(t, method),
compiled);
node = makeTreeNode
(t, clone, methodTreeSentinal(t), methodTreeSentinal(t));
PROTECT(t, node);
methodTree(t) = treeInsertNode
(t, methodTree(t), reinterpret_cast<intptr_t>
(&singletonValue(t, compiled, 0)), node, methodTreeSentinal(t),
compareIpToMethodBounds);
}
set(t, method, MethodCompiled, compiled);
@ -5159,15 +5195,8 @@ compile(MyThread* t, object method)
= &singletonValue(t, compiled, 0);
}
if ((methodFlags(t, method) & ACC_NATIVE) == 0) {
if (DebugMethodTree) {
fprintf(stderr, "insert method at %p\n",
&singletonValue(t, methodCompiled(t, method), 0));
}
methodTree(t) = treeInsert
(t, methodTree(t), method, methodTreeSentinal(t),
compareMethodBounds);
if (node) {
set(t, node, TreeNodeValue, method);
}
}
}

View File

@ -168,7 +168,7 @@ killZombies(Thread* t, Thread* o)
unsigned
footprint(Thread* t)
{
unsigned n = t->heapOffset + t->heapIndex;
unsigned n = t->heapOffset + t->heapIndex + t->backupHeapIndex;
for (Thread* c = t->child; c; c = c->peer) {
n += footprint(c);
@ -2872,6 +2872,17 @@ makeTrace(Thread* t, Thread* target)
return v.trace ? v.trace : makeArray(t, 0, true);
}
void
runJavaThread(Thread* t)
{
object method = resolveMethod(t, "java/lang/Thread", "run", "()V");
if (t->exception == 0) {
t->m->processor->invoke
(t, findMethod(t, method, objectClass(t, t->javaThread)),
t->javaThread);
}
}
void
noop()
{ }

View File

@ -1206,6 +1206,9 @@ inline void stress(Thread* t);
#endif // not VM_STRESS
void
runJavaThread(Thread* t);
class Thread {
public:
enum State {
@ -1258,8 +1261,7 @@ class Thread {
t->m->localThread->set(t);
t->m->processor->invoke
(t, "java/lang/Thread", "run", "()V", t->javaThread);
runJavaThread(t);
if (t->exception) {
printTrace(t, t->exception);
@ -1360,6 +1362,7 @@ inline void
stress(Thread* t)
{
if ((not t->stress)
and (not t->tracing)
and t->state != Thread::NoState
and t->state != Thread::IdleState)
{
@ -2039,6 +2042,13 @@ findMethod(Thread* t, object class_, object name, object spec)
(t, class_, name, spec, findMethodInClass, makeNoSuchMethodError);
}
inline object
findMethod(Thread* t, object method, object class_)
{
return arrayBody(t, classVirtualTable(t, class_),
methodOffset(t, method));
}
inline unsigned
objectArrayLength(Thread* t UNUSED, object array)
{

View File

@ -125,13 +125,6 @@ isSpecialMethod(Thread* t, object method, object class_)
and isSuperclass(t, methodClass(t, method), class_);
}
inline object
findMethod(Thread* t, object method, object class_)
{
return arrayBody(t, classVirtualTable(t, class_),
methodOffset(t, method));
}
void*
resolveNativeMethod2(Thread* t, object method);

View File

@ -59,8 +59,8 @@ cloneTreeNode(Thread* t, object n)
}
object
treeFind(Thread* t, object old, object node, object sentinal,
intptr_t (*compare)(Thread* t, object a, object b))
treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{
PROTECT(t, old);
PROTECT(t, node);
@ -78,8 +78,7 @@ treeFind(Thread* t, object old, object node, object sentinal,
while (old != sentinal) {
ancestors = makePair(t, new_, ancestors);
intptr_t difference = compare
(t, getTreeNodeValue(t, node), getTreeNodeValue(t, old));
intptr_t difference = compare(t, key, getTreeNodeValue(t, old));
if (difference < 0) {
old = treeNodeLeft(t, old);
@ -302,6 +301,12 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
newArray = makeArray(t, newLength, true);
if (oldArray != hashMapArray(t, map)) {
// a resize was performed during a GC via the makeArray call
// above; nothing left to do
return;
}
if (oldArray) {
bool weak = objectClass(t, map)
== arrayBody(t, t->m->types, Machine::WeakHashMapType);
@ -333,7 +338,7 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
void
hashMapInsert(Thread* t, object map, object key, object value,
uint32_t (*hash)(Thread*, object))
uint32_t (*hash)(Thread*, object))
{
// note that we reinitialize the array and index variables whenever
// an allocation (and thus possibly a collection) occurs, in case
@ -536,20 +541,16 @@ treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
}
object
treeInsert(Thread* t, object tree, object value, object sentinal,
intptr_t (*compare)(Thread* t, object a, object b))
treeInsertNode(Thread* t, object tree, intptr_t key, object node,
object sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{
PROTECT(t, tree);
PROTECT(t, sentinal);
object node = makeTreeNode(t, value, sentinal, sentinal);
object path = treeFind(t, tree, node, sentinal, compare);
if (treePathFresh(t, path)) {
return treeAdd(t, path);
} else {
return tree;
}
object path = treeFind(t, tree, key, node, sentinal, compare);
expect(t, treePathFresh(t, path));
return treeAdd(t, path);
}
} // namespace vm

View File

@ -88,8 +88,9 @@ treeQuery(Thread* t, object tree, intptr_t key, object sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
object
treeInsert(Thread* t, object tree, object value, object sentinal,
intptr_t (*compare)(Thread* t, object a, object b));
treeInsertNode(Thread* t, object tree, intptr_t key, object node,
object sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
} // vm

View File

@ -1,3 +1,13 @@
/* Copyright (c) 2008, 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 "assembler.h"
#include "vector.h"
@ -949,6 +959,10 @@ addCM(Context* c, unsigned size UNUSED, Assembler::Constant* a,
}
}
void
addRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b);
void
addCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
@ -977,7 +991,10 @@ addCR(Context* c, unsigned size, Assembler::Constant* a,
c->code.append(0xc0 | b->low);
c->code.append4(v);
} else {
abort(c);
Assembler::Register tmp(c->client->acquireTemporary());
moveCR(c, size, a, &tmp);
addRR(c, size, &tmp, b);
c->client->releaseTemporary(tmp.low);
}
}
}
@ -999,6 +1016,10 @@ subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
}
}
void
subtractRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b);
void
subtractCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
@ -1027,7 +1048,10 @@ subtractCR(Context* c, unsigned size, Assembler::Constant* a,
c->code.append(0xe8 | b->low);
c->code.append4(v);
} else {
abort(c);
Assembler::Register tmp(c->client->acquireTemporary());
moveCR(c, size, a, &tmp);
subtractRR(c, size, &tmp, b);
c->client->releaseTemporary(tmp.low);
}
}
}

View File

@ -234,6 +234,54 @@ public class Misc {
expect(~a == ~25214903884L);
}
{ long b = 2;
expect((-25214903884L) >> b == -25214903884L >> 2);
expect((-25214903884L) >>> b == -25214903884L >>> 2);
expect((-25214903884L) << b == -25214903884L << 2);
expect((-25214903884L) + b == -25214903884L + 2L);
expect((-25214903884L) - b == -25214903884L - 2L);
expect((-25214903884L) * b == -25214903884L * 2L);
expect((-25214903884L) / b == -25214903884L / 2L);
expect((-25214903884L) % b == -25214903884L % 2L);
expect(((-25214903884L) & b) == (-25214903884L & 2L));
expect(((-25214903884L) | b) == (-25214903884L | 2L));
expect(((-25214903884L) ^ b) == (-25214903884L ^ 2L));
b = 2;
expect(25214903884L >> b == 25214903884L >> 2);
expect(25214903884L >>> b == 25214903884L >>> 2);
expect(25214903884L << b == 25214903884L << 2);
expect(25214903884L + b == 25214903884L + 2L);
expect(25214903884L - b == 25214903884L - 2L);
expect(25214903884L * b == 25214903884L * 2L);
expect(25214903884L / b == 25214903884L / 2L);
expect(25214903884L % b == 25214903884L % 2L);
expect((25214903884L & b) == (25214903884L & 2L));
expect((25214903884L | b) == (25214903884L | 2L));
expect((25214903884L ^ b) == (25214903884L ^ 2L));
}
{ long a = 2L;
expect(a + (-25214903884L) == 2L + (-25214903884L));
expect(a - (-25214903884L) == 2L - (-25214903884L));
expect(a * (-25214903884L) == 2L * (-25214903884L));
expect(a / (-25214903884L) == 2L / (-25214903884L));
expect(a % (-25214903884L) == 2L % (-25214903884L));
expect((a & (-25214903884L)) == (2L & (-25214903884L)));
expect((a | (-25214903884L)) == (2L | (-25214903884L)));
expect((a ^ (-25214903884L)) == (2L ^ (-25214903884L)));
a = 2L;
expect(a + 25214903884L == 2L + 25214903884L);
expect(a - 25214903884L == 2L - 25214903884L);
expect(a * 25214903884L == 2L * 25214903884L);
expect(a / 25214903884L == 2L / 25214903884L);
expect(a % 25214903884L == 2L % 25214903884L);
expect((a & 25214903884L) == (2L & 25214903884L));
expect((a | 25214903884L) == (2L | 25214903884L));
expect((a ^ 25214903884L) == (2L ^ 25214903884L));
}
byte2 = 0;
expect(byte2 == 0);