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); const char* chars = e->GetStringUTFChars(path, 0);
if (chars) { 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); e->ReleaseStringUTFChars(path, chars);
return fd; return fd;
} else { } 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; return null;
} }
} }
public boolean desiredAssertionStatus() {
return false;
}
} }

View File

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

View File

@ -10,7 +10,7 @@
package java.lang; package java.lang;
public class StringBuffer { public class StringBuffer implements CharSequence {
private final StringBuilder sb; private final StringBuilder sb;
public StringBuffer(String s) { public StringBuffer(String s) {
@ -116,4 +116,12 @@ public class StringBuffer {
public synchronized String toString() { public synchronized String toString() {
return sb.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; package java.lang;
public class StringBuilder { public class StringBuilder implements CharSequence {
private static final int BufferSize = 32; private static final int BufferSize = 32;
private Cell chain; private Cell chain;
@ -288,4 +288,15 @@ public class StringBuilder {
this.next = next; 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 { public abstract class System {
private static Property properties; private static Property properties;
// static { // static {
// loadLibrary("natives"); // loadLibrary("natives");
// } // }
public static final PrintStream out = new PrintStream public static final PrintStream out = new PrintStream
(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true); (new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
@ -53,6 +53,15 @@ public abstract class System {
return null; 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) { public static String setProperty(String name, String value) {
for (Property p = properties; p != null; p = p.next) { 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; 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 PersistentSet<Cell<T>> set;
private int size; private int size;
@ -41,12 +41,6 @@ public class TreeSet<T> implements Collection<T> {
return false; 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 // Used by hashMaps for replacement
public void addAndReplace(T value) { public void addAndReplace(T value) {
PersistentSet.Path<Cell<T>> p = set.find(new Cell(value, null)); 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() { public int size() {
return 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 #ifndef ASSEMBLER_H
#define 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 "stdint.h"
#include "stdlib.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); object target = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
unsigned parameterFootprint = methodParameterFootprint(t, target); unsigned parameterFootprint = methodParameterFootprint(t, target);
unsigned instance = parameterFootprint - 1; unsigned instance = parameterFootprint - 1;
@ -2692,6 +2694,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
target = findMethod(t, target, classSuper(t, class_)); target = findMethod(t, target, classSuper(t, class_));
} }
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
compileDirectInvoke(t, frame, target); compileDirectInvoke(t, frame, target);
} break; } break;
@ -2701,6 +2705,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object target = resolveMethod(t, codePool(t, code), index - 1); object target = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
assert(t, methodFlags(t, target) & ACC_STATIC);
compileDirectInvoke(t, frame, target); compileDirectInvoke(t, frame, target);
} break; } break;
@ -2710,6 +2716,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object target = resolveMethod(t, codePool(t, code), index - 1); object target = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
unsigned parameterFootprint = methodParameterFootprint(t, target); unsigned parameterFootprint = methodParameterFootprint(t, target);
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord); 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 unsigned
frameObjectMapSize(MyThread* t, object method, object map) frameObjectMapSize(MyThread* t, object method, object map)
{ {
@ -4314,7 +4307,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
} else { } else {
break; break;
} }
} }
} }
void void
@ -5143,13 +5136,56 @@ compile(MyThread* t, object method)
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
if (methodCompiled(t, method) == p->defaultThunk) { if (methodCompiled(t, method) == p->defaultThunk) {
object node;
object compiled; object compiled;
if (methodFlags(t, method) & ACC_NATIVE) { if (methodFlags(t, method) & ACC_NATIVE) {
node = 0;
compiled = p->nativeThunk; compiled = p->nativeThunk;
} else { } else {
Context context(t, method); Context context(t, method);
compiled = compile(t, &context); compiled = compile(t, &context);
if (UNLIKELY(t->exception)) return; 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); set(t, method, MethodCompiled, compiled);
@ -5159,15 +5195,8 @@ compile(MyThread* t, object method)
= &singletonValue(t, compiled, 0); = &singletonValue(t, compiled, 0);
} }
if ((methodFlags(t, method) & ACC_NATIVE) == 0) { if (node) {
if (DebugMethodTree) { set(t, node, TreeNodeValue, method);
fprintf(stderr, "insert method at %p\n",
&singletonValue(t, methodCompiled(t, method), 0));
}
methodTree(t) = treeInsert
(t, methodTree(t), method, methodTreeSentinal(t),
compareMethodBounds);
} }
} }
} }

View File

@ -168,7 +168,7 @@ killZombies(Thread* t, Thread* o)
unsigned unsigned
footprint(Thread* t) 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) { for (Thread* c = t->child; c; c = c->peer) {
n += footprint(c); n += footprint(c);
@ -2872,6 +2872,17 @@ makeTrace(Thread* t, Thread* target)
return v.trace ? v.trace : makeArray(t, 0, true); 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 void
noop() noop()
{ } { }

View File

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

View File

@ -59,8 +59,8 @@ cloneTreeNode(Thread* t, object n)
} }
object object
treeFind(Thread* t, object old, object node, object sentinal, treeFind(Thread* t, object old, intptr_t key, object node, object sentinal,
intptr_t (*compare)(Thread* t, object a, object b)) intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
PROTECT(t, old); PROTECT(t, old);
PROTECT(t, node); PROTECT(t, node);
@ -78,8 +78,7 @@ treeFind(Thread* t, object old, object node, object sentinal,
while (old != sentinal) { while (old != sentinal) {
ancestors = makePair(t, new_, ancestors); ancestors = makePair(t, new_, ancestors);
intptr_t difference = compare intptr_t difference = compare(t, key, getTreeNodeValue(t, old));
(t, getTreeNodeValue(t, node), getTreeNodeValue(t, old));
if (difference < 0) { if (difference < 0) {
old = treeNodeLeft(t, old); old = treeNodeLeft(t, old);
@ -302,6 +301,12 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
newArray = makeArray(t, newLength, true); 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) { if (oldArray) {
bool weak = objectClass(t, map) bool weak = objectClass(t, map)
== arrayBody(t, t->m->types, Machine::WeakHashMapType); == arrayBody(t, t->m->types, Machine::WeakHashMapType);
@ -333,7 +338,7 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
void void
hashMapInsert(Thread* t, object map, object key, object value, 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 // note that we reinitialize the array and index variables whenever
// an allocation (and thus possibly a collection) occurs, in case // 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 object
treeInsert(Thread* t, object tree, object value, object sentinal, treeInsertNode(Thread* t, object tree, intptr_t key, object node,
intptr_t (*compare)(Thread* t, object a, object b)) object sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b))
{ {
PROTECT(t, tree); PROTECT(t, tree);
PROTECT(t, sentinal); PROTECT(t, sentinal);
object node = makeTreeNode(t, value, sentinal, sentinal); object path = treeFind(t, tree, key, node, sentinal, compare);
expect(t, treePathFresh(t, path));
object path = treeFind(t, tree, node, sentinal, compare); return treeAdd(t, path);
if (treePathFresh(t, path)) {
return treeAdd(t, path);
} else {
return tree;
}
} }
} // namespace vm } // 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)); intptr_t (*compare)(Thread* t, intptr_t key, object b));
object object
treeInsert(Thread* t, object tree, object value, object sentinal, treeInsertNode(Thread* t, object tree, intptr_t key, object node,
intptr_t (*compare)(Thread* t, object a, object b)); object sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
} // vm } // 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 "assembler.h"
#include "vector.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 void
addCR(Context* c, unsigned size, Assembler::Constant* a, addCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b) Assembler::Register* b)
@ -977,7 +991,10 @@ addCR(Context* c, unsigned size, Assembler::Constant* a,
c->code.append(0xc0 | b->low); c->code.append(0xc0 | b->low);
c->code.append4(v); c->code.append4(v);
} else { } 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 void
subtractCR(Context* c, unsigned size, Assembler::Constant* a, subtractCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b) Assembler::Register* b)
@ -1027,7 +1048,10 @@ subtractCR(Context* c, unsigned size, Assembler::Constant* a,
c->code.append(0xe8 | b->low); c->code.append(0xe8 | b->low);
c->code.append4(v); c->code.append4(v);
} else { } 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); 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; byte2 = 0;
expect(byte2 == 0); expect(byte2 == 0);