mirror of
https://github.com/corda/corda.git
synced 2025-01-09 06:23:04 +00:00
Merge branch 'master' of oss.readytalk.com:/var/local/git/avian
This commit is contained in:
commit
552f333246
@ -67,8 +67,12 @@ doOpen(JNIEnv* e, const char* path, int mask)
|
|||||||
{
|
{
|
||||||
int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR);
|
int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
throwNew(e, "java/io/FileNotFoundException", strerror(errno));
|
||||||
|
} else {
|
||||||
throwNew(e, "java/io/IOException", strerror(errno));
|
throwNew(e, "java/io/IOException", strerror(errno));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@ public abstract class Enum<E extends Enum<E>> implements Comparable<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(E other) {
|
public int compareTo(E other) {
|
||||||
|
if (getDeclaringClass() != other.getDeclaringClass()) {
|
||||||
|
throw new ClassCastException();
|
||||||
|
}
|
||||||
|
|
||||||
return ordinal - other.ordinal;
|
return ordinal - other.ordinal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ public class Runtime {
|
|||||||
return new MyProcess(process[0], (int) process[1], (int) process[2], (int) process[3]);
|
return new MyProcess(process[0], (int) process[1], (int) process[2], (int) process[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public native void addShutdownHook(Thread t);
|
||||||
|
|
||||||
private static native void exec(String[] command, long[] process);
|
private static native void exec(String[] command, long[] process);
|
||||||
|
|
||||||
private static native int exitValue(long pid);
|
private static native int exitValue(long pid);
|
||||||
|
@ -30,6 +30,16 @@ public class StringBuffer implements CharSequence {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized StringBuffer append(CharSequence s) {
|
||||||
|
sb.append(s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized StringBuffer append(StringBuffer s) {
|
||||||
|
sb.append(s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized StringBuffer append(Object o) {
|
public synchronized StringBuffer append(Object o) {
|
||||||
sb.append(o);
|
sb.append(o);
|
||||||
return this;
|
return this;
|
||||||
|
@ -54,6 +54,10 @@ public class StringBuilder implements CharSequence, Appendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringBuilder append(StringBuffer sb) {
|
||||||
|
return append(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
public StringBuilder append(CharSequence sequence) {
|
public StringBuilder append(CharSequence sequence) {
|
||||||
return append(sequence.toString());
|
return append(sequence.toString());
|
||||||
}
|
}
|
||||||
@ -104,7 +108,6 @@ public class StringBuilder implements CharSequence, Appendable {
|
|||||||
return append(String.valueOf(v));
|
return append(String.valueOf(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public char charAt(int i) {
|
public char charAt(int i) {
|
||||||
if (i < 0 || i >= length) {
|
if (i < 0 || i >= length) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
|
@ -252,9 +252,13 @@ public class Thread implements Runnable {
|
|||||||
return daemon;
|
return daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDaemon(boolean v) {
|
public synchronized void setDaemon(boolean v) {
|
||||||
daemon = v;
|
if (v != daemon) {
|
||||||
|
setDaemon(this, v);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void setDaemon(Thread t, boolean increment);
|
||||||
|
|
||||||
public static native void yield();
|
public static native void yield();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2009, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -11,17 +11,29 @@
|
|||||||
package java.util.regex;
|
package java.util.regex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation is a skeleton, useful only for compilation. At runtime it
|
* This is a work in progress.
|
||||||
* is need to be replaced by a working implementation, for example one from the
|
|
||||||
* Apache Harmony project.
|
|
||||||
*
|
|
||||||
* @author zsombor
|
|
||||||
*
|
*
|
||||||
|
* @author zsombor and others
|
||||||
*/
|
*/
|
||||||
public class Matcher {
|
public class Matcher {
|
||||||
|
private final Pattern pattern;
|
||||||
|
private CharSequence input;
|
||||||
|
private int start;
|
||||||
|
private int end;
|
||||||
|
|
||||||
|
Matcher(Pattern pattern, CharSequence input) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean matches() {
|
public boolean matches() {
|
||||||
throw new UnsupportedOperationException();
|
if (pattern.pattern().equals(input.toString())) {
|
||||||
|
start = 0;
|
||||||
|
end = input.length();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requireEnd() {
|
public boolean requireEnd() {
|
||||||
@ -37,15 +49,18 @@ public class Matcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Matcher reset() {
|
public Matcher reset() {
|
||||||
throw new UnsupportedOperationException();
|
return reset(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Matcher reset(CharSequence input) {
|
public Matcher reset(CharSequence input) {
|
||||||
throw new UnsupportedOperationException();
|
this.input = input;
|
||||||
|
start = 0;
|
||||||
|
end = 0;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int start() {
|
public int start() {
|
||||||
throw new UnsupportedOperationException();
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int start(int group) {
|
public int start(int group) {
|
||||||
@ -69,15 +84,44 @@ public class Matcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String replaceAll(String replacement) {
|
public String replaceAll(String replacement) {
|
||||||
throw new UnsupportedOperationException();
|
return replace(replacement, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String replaceFirst(String replacement) {
|
public String replaceFirst(String replacement) {
|
||||||
throw new UnsupportedOperationException();
|
return replace(replacement, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String replace(String replacement, int limit) {
|
||||||
|
reset();
|
||||||
|
|
||||||
|
StringBuilder sb = null;
|
||||||
|
int index = 0;
|
||||||
|
int count = 0;
|
||||||
|
while (count < limit && index < input.length()) {
|
||||||
|
if (find(index)) {
|
||||||
|
if (sb == null) {
|
||||||
|
sb = new StringBuilder();
|
||||||
|
}
|
||||||
|
if (start > index) {
|
||||||
|
sb.append(input.subSequence(index, start));
|
||||||
|
}
|
||||||
|
sb.append(replacement);
|
||||||
|
index = end;
|
||||||
|
++ count;
|
||||||
|
} else if (index == 0) {
|
||||||
|
return input.toString();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index < input.length()) {
|
||||||
|
sb.append(input.subSequence(index, input.length()));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int end() {
|
public int end() {
|
||||||
throw new UnsupportedOperationException();
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int end(int group) {
|
public int end(int group) {
|
||||||
@ -85,11 +129,19 @@ public class Matcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean find() {
|
public boolean find() {
|
||||||
throw new UnsupportedOperationException();
|
return find(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean find(int start) {
|
public boolean find(int start) {
|
||||||
throw new UnsupportedOperationException();
|
String p = pattern.pattern();
|
||||||
|
int i = Pattern.indexOf(input, p, start);
|
||||||
|
if (i >= 0) {
|
||||||
|
this.start = i;
|
||||||
|
this.end = i + p.length();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int groupCount() {
|
public int groupCount() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2008, Avian Contributors
|
/* Copyright (c) 2008-2009, Avian Contributors
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
for any purpose with or without fee is hereby granted, provided
|
for any purpose with or without fee is hereby granted, provided
|
||||||
@ -10,12 +10,14 @@
|
|||||||
|
|
||||||
package java.util.regex;
|
package java.util.regex;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation is a skeleton, useful only for compilation. At runtime it
|
* This is a work in progress.
|
||||||
* is need to be replaced by a working implementation, for example one from the
|
|
||||||
* Apache Harmony project.
|
|
||||||
*
|
*
|
||||||
* @author zsombor
|
* @author zsombor and others
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Pattern {
|
public class Pattern {
|
||||||
@ -29,12 +31,41 @@ public class Pattern {
|
|||||||
public static final int UNICODE_CASE = 64;
|
public static final int UNICODE_CASE = 64;
|
||||||
public static final int CANON_EQ = 128;
|
public static final int CANON_EQ = 128;
|
||||||
|
|
||||||
private int patternFlags;
|
private final int patternFlags;
|
||||||
private String pattern;
|
private final String pattern;
|
||||||
|
|
||||||
protected Pattern(String pattern, int flags) {
|
protected Pattern(String pattern, int flags) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
this.patternFlags = flags;
|
this.patternFlags = flags;
|
||||||
|
|
||||||
|
if (! trivial(pattern)) {
|
||||||
|
throw new UnsupportedOperationException
|
||||||
|
("only trivial regular expressions are supported so far");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean trivial(String pattern) {
|
||||||
|
for (int i = 0; i < pattern.length(); ++i) {
|
||||||
|
char c = pattern.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '\\':
|
||||||
|
case '.':
|
||||||
|
case '*':
|
||||||
|
case '+':
|
||||||
|
case '?':
|
||||||
|
case '|':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '^':
|
||||||
|
case '$':
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pattern compile(String regex) {
|
public static Pattern compile(String regex) {
|
||||||
@ -50,7 +81,7 @@ public class Pattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Matcher matcher(CharSequence input) {
|
public Matcher matcher(CharSequence input) {
|
||||||
throw new UnsupportedOperationException();
|
return new Matcher(this, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean matches(String regex, CharSequence input) {
|
public static boolean matches(String regex, CharSequence input) {
|
||||||
@ -66,10 +97,72 @@ public class Pattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String[] split(CharSequence input) {
|
public String[] split(CharSequence input) {
|
||||||
throw new UnsupportedOperationException();
|
return split(input, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] split(CharSequence input, int limit) {
|
public String[] split(CharSequence input, int limit) {
|
||||||
throw new UnsupportedOperationException();
|
boolean strip;
|
||||||
|
if (limit < 0) {
|
||||||
|
strip = false;
|
||||||
|
limit = Integer.MAX_VALUE;
|
||||||
|
} else if (limit == 0) {
|
||||||
|
strip = true;
|
||||||
|
limit = Integer.MAX_VALUE;
|
||||||
|
} else {
|
||||||
|
strip = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CharSequence> list = new LinkedList();
|
||||||
|
int index = 0;
|
||||||
|
int trailing = 0;
|
||||||
|
while (index < input.length() && list.size() < limit) {
|
||||||
|
int i = indexOf(input, pattern, index);
|
||||||
|
if (i >= 0) {
|
||||||
|
if (i == index) {
|
||||||
|
++ trailing;
|
||||||
|
} else {
|
||||||
|
trailing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.add(input.subSequence(index, i));
|
||||||
|
index = i + pattern.length();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strip && index == input.length()) {
|
||||||
|
++ trailing;
|
||||||
|
} else {
|
||||||
|
trailing = 0;
|
||||||
|
}
|
||||||
|
list.add(input.subSequence(index, input.length()));
|
||||||
|
|
||||||
|
String[] result = new String[list.size() - trailing];
|
||||||
|
int i = 0;
|
||||||
|
for (Iterator<CharSequence> it = list.iterator();
|
||||||
|
it.hasNext() && i < result.length; ++ i)
|
||||||
|
{
|
||||||
|
result[i] = it.next().toString();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int indexOf(CharSequence haystack, CharSequence needle, int start) {
|
||||||
|
if (needle.length() == 0) return start;
|
||||||
|
|
||||||
|
for (int i = start; i < haystack.length() - needle.length() + 1; ++i) {
|
||||||
|
int j = 0;
|
||||||
|
for (; j < needle.length(); ++j) {
|
||||||
|
if (haystack.charAt(i + j) != needle.charAt(j)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == needle.length()) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,6 +726,8 @@ extern "C" JNIEXPORT void JNICALL
|
|||||||
Avian_java_lang_Runtime_exit
|
Avian_java_lang_Runtime_exit
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
|
shutDown(t);
|
||||||
|
|
||||||
t->m->system->exit(*arguments);
|
t->m->system->exit(*arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,6 +747,18 @@ Avian_java_lang_Runtime_totalMemory
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_java_lang_Runtime_addShutdownHook
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object hook = reinterpret_cast<object>(arguments[1]);
|
||||||
|
PROTECT(t, hook);
|
||||||
|
|
||||||
|
ACQUIRE(t, t->m->shutdownLock);
|
||||||
|
|
||||||
|
t->m->shutdownHooks = makePair(t, hook, t->m->shutdownHooks);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_java_lang_Throwable_trace
|
Avian_java_lang_Throwable_trace
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
@ -840,16 +854,8 @@ extern "C" JNIEXPORT int64_t JNICALL
|
|||||||
Avian_java_lang_Thread_doStart
|
Avian_java_lang_Thread_doStart
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
object this_ = reinterpret_cast<object>(*arguments);
|
return reinterpret_cast<int64_t>
|
||||||
|
(startThread(t, reinterpret_cast<object>(*arguments)));
|
||||||
Thread* p = t->m->processor->makeThread(t->m, this_, t);
|
|
||||||
|
|
||||||
if (t->m->system->success(t->m->system->start(&(p->runnable)))) {
|
|
||||||
return reinterpret_cast<int64_t>(p);
|
|
||||||
} else {
|
|
||||||
p->exit();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
@ -896,6 +902,27 @@ Avian_java_lang_Thread_enumerate
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_java_lang_Thread_setDaemon
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object thread = reinterpret_cast<object>(arguments[0]);
|
||||||
|
bool daemon = arguments[1] != 0;
|
||||||
|
|
||||||
|
ACQUIRE_RAW(t, t->m->stateLock);
|
||||||
|
|
||||||
|
threadDaemon(t, thread) = daemon;
|
||||||
|
|
||||||
|
if (daemon) {
|
||||||
|
++ t->m->daemonCount;
|
||||||
|
} else {
|
||||||
|
expect(t, t->m->daemonCount);
|
||||||
|
-- t->m->daemonCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->m->stateLock->notifyAll(t->systemThread);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
|
Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__)
|
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__)
|
||||||
# define LD "ld"
|
# define LD "ld"
|
||||||
# ifdef __MINGW32__
|
# if (defined __MINGW32__) && __GNUC__ == 4
|
||||||
# define LLD "I64d"
|
# define LLD "I64d"
|
||||||
# else
|
# else
|
||||||
# define LLD "lld"
|
# define LLD "lld"
|
||||||
|
@ -25,37 +25,6 @@ const uintptr_t InterfaceMethodID
|
|||||||
const uintptr_t NonVirtualMethodID
|
const uintptr_t NonVirtualMethodID
|
||||||
= (static_cast<uintptr_t>(1) << (BitsPerWord - 2));
|
= (static_cast<uintptr_t>(1) << (BitsPerWord - 2));
|
||||||
|
|
||||||
jint JNICALL
|
|
||||||
DestroyJavaVM(Machine* m)
|
|
||||||
{
|
|
||||||
System* s = m->system;
|
|
||||||
Heap* h = m->heap;
|
|
||||||
Processor* p = m->processor;
|
|
||||||
Finder* f = m->finder;
|
|
||||||
Thread* t = m->rootThread;
|
|
||||||
|
|
||||||
// wait for other threads to exit
|
|
||||||
{ ACQUIRE(t, m->stateLock);
|
|
||||||
|
|
||||||
while (m->liveCount > 1) {
|
|
||||||
t->m->stateLock->wait(t->systemThread, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int exitCode = (t->exception ? -1 : 0);
|
|
||||||
enter(t, Thread::ActiveState);
|
|
||||||
t->exit();
|
|
||||||
|
|
||||||
m->dispose();
|
|
||||||
h->disposeFixies();
|
|
||||||
p->dispose();
|
|
||||||
h->dispose();
|
|
||||||
f->dispose();
|
|
||||||
s->dispose();
|
|
||||||
|
|
||||||
return exitCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
jint JNICALL
|
jint JNICALL
|
||||||
AttachCurrentThread(Machine* m, Thread** t, void*)
|
AttachCurrentThread(Machine* m, Thread** t, void*)
|
||||||
{
|
{
|
||||||
@ -84,6 +53,9 @@ DetachCurrentThread(Machine* m)
|
|||||||
ACQUIRE_RAW(t, t->m->stateLock);
|
ACQUIRE_RAW(t, t->m->stateLock);
|
||||||
|
|
||||||
enter(t, Thread::ActiveState);
|
enter(t, Thread::ActiveState);
|
||||||
|
|
||||||
|
threadPeer(t, t->javaThread) = 0;
|
||||||
|
|
||||||
enter(t, Thread::ZombieState);
|
enter(t, Thread::ZombieState);
|
||||||
|
|
||||||
t->state = Thread::JoinedState;
|
t->state = Thread::JoinedState;
|
||||||
@ -94,6 +66,30 @@ DetachCurrentThread(Machine* m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jint JNICALL
|
||||||
|
DestroyJavaVM(Machine* m)
|
||||||
|
{
|
||||||
|
Thread* t; AttachCurrentThread(m, &t, 0);
|
||||||
|
|
||||||
|
// wait for other non-daemon threads to exit
|
||||||
|
{ ACQUIRE(t, t->m->stateLock);
|
||||||
|
while (t->m->liveCount - t->m->daemonCount > 1) {
|
||||||
|
t->m->stateLock->wait(t->systemThread, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
|
shutDown(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
int exitCode = (t->exception ? -1 : 0);
|
||||||
|
|
||||||
|
t->exit();
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
jint JNICALL
|
jint JNICALL
|
||||||
GetEnv(Machine* m, Thread** t, jint version)
|
GetEnv(Machine* m, Thread** t, jint version)
|
||||||
{
|
{
|
||||||
@ -431,7 +427,7 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? false : (intValue(t, r) != 0));
|
return (r ? (intValue(t, r) != 0) : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean JNICALL
|
jboolean JNICALL
|
||||||
@ -454,7 +450,7 @@ CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyte JNICALL
|
jbyte JNICALL
|
||||||
@ -477,7 +473,7 @@ CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jchar JNICALL
|
jchar JNICALL
|
||||||
@ -500,7 +496,7 @@ CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jshort JNICALL
|
jshort JNICALL
|
||||||
@ -523,7 +519,7 @@ CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jint JNICALL
|
jint JNICALL
|
||||||
@ -546,7 +542,7 @@ CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : longValue(t, r));
|
return (r ? longValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong JNICALL
|
jlong JNICALL
|
||||||
@ -569,7 +565,7 @@ CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : bitsToFloat(intValue(t, r)));
|
return (r ? bitsToFloat(intValue(t, r)) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jfloat JNICALL
|
jfloat JNICALL
|
||||||
@ -592,7 +588,7 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a)
|
|||||||
|
|
||||||
object method = getMethod(t, m);
|
object method = getMethod(t, m);
|
||||||
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
object r = t->m->processor->invokeList(t, method, *o, true, a);
|
||||||
return (t->exception ? 0 : bitsToDouble(longValue(t, r)));
|
return (r ? bitsToDouble(longValue(t, r)) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jdouble JNICALL
|
jdouble JNICALL
|
||||||
@ -666,7 +662,7 @@ CallStaticBooleanMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : (intValue(t, r) != 0));
|
return (r ? (intValue(t, r) != 0) : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean JNICALL
|
jboolean JNICALL
|
||||||
@ -688,7 +684,7 @@ CallStaticByteMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyte JNICALL
|
jbyte JNICALL
|
||||||
@ -710,7 +706,7 @@ CallStaticCharMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jchar JNICALL
|
jchar JNICALL
|
||||||
@ -732,7 +728,7 @@ CallStaticShortMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jshort JNICALL
|
jshort JNICALL
|
||||||
@ -754,7 +750,7 @@ CallStaticIntMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : intValue(t, r));
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jint JNICALL
|
jint JNICALL
|
||||||
@ -776,7 +772,7 @@ CallStaticLongMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : longValue(t, r));
|
return (r ? longValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong JNICALL
|
jlong JNICALL
|
||||||
@ -798,7 +794,7 @@ CallStaticFloatMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : bitsToFloat(intValue(t, r)));
|
return (r ? bitsToFloat(intValue(t, r)) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jfloat JNICALL
|
jfloat JNICALL
|
||||||
@ -820,7 +816,7 @@ CallStaticDoubleMethodV(Thread* t, jclass, jmethodID m, va_list a)
|
|||||||
ENTER(t, Thread::ActiveState);
|
ENTER(t, Thread::ActiveState);
|
||||||
|
|
||||||
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a);
|
||||||
return (t->exception ? 0 : bitsToDouble(longValue(t, r)));
|
return (r ? bitsToDouble(longValue(t, r)) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
jdouble JNICALL
|
jdouble JNICALL
|
||||||
|
104
src/machine.cpp
104
src/machine.cpp
@ -146,6 +146,50 @@ disposeAll(Thread* m, Thread* o)
|
|||||||
dispose(m, o, false);
|
dispose(m, o, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
turnOffTheLights(Thread* t)
|
||||||
|
{
|
||||||
|
expect(t, t->m->liveCount == 1);
|
||||||
|
|
||||||
|
joinAll(t, t->m->rootThread);
|
||||||
|
|
||||||
|
enter(t, Thread::ExitState);
|
||||||
|
|
||||||
|
for (object* p = &(t->m->finalizers); *p;) {
|
||||||
|
object f = *p;
|
||||||
|
*p = finalizerNext(t, *p);
|
||||||
|
|
||||||
|
void (*function)(Thread*, object);
|
||||||
|
memcpy(&function, &finalizerFinalize(t, f), BytesPerWord);
|
||||||
|
function(t, finalizerTarget(t, f));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (object* p = &(t->m->tenuredFinalizers); *p;) {
|
||||||
|
object f = *p;
|
||||||
|
*p = finalizerNext(t, *p);
|
||||||
|
|
||||||
|
void (*function)(Thread*, object);
|
||||||
|
memcpy(&function, &finalizerFinalize(t, f), BytesPerWord);
|
||||||
|
function(t, finalizerTarget(t, f));
|
||||||
|
}
|
||||||
|
|
||||||
|
Machine* m = t->m;
|
||||||
|
|
||||||
|
disposeAll(t, t->m->rootThread);
|
||||||
|
|
||||||
|
System* s = m->system;
|
||||||
|
Heap* h = m->heap;
|
||||||
|
Processor* p = m->processor;
|
||||||
|
Finder* f = m->finder;
|
||||||
|
|
||||||
|
m->dispose();
|
||||||
|
h->disposeFixies();
|
||||||
|
p->dispose();
|
||||||
|
h->dispose();
|
||||||
|
f->dispose();
|
||||||
|
s->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
killZombies(Thread* t, Thread* o)
|
killZombies(Thread* t, Thread* o)
|
||||||
{
|
{
|
||||||
@ -574,6 +618,7 @@ resolveSpec(Thread* t, object loader, object spec, unsigned offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROTECT(t, spec);
|
PROTECT(t, spec);
|
||||||
|
PROTECT(t, loader);
|
||||||
|
|
||||||
unsigned length = s - &byteArrayBody(t, spec, offset);
|
unsigned length = s - &byteArrayBody(t, spec, offset);
|
||||||
|
|
||||||
@ -1976,12 +2021,14 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
|||||||
propertyCount(propertyCount),
|
propertyCount(propertyCount),
|
||||||
activeCount(0),
|
activeCount(0),
|
||||||
liveCount(0),
|
liveCount(0),
|
||||||
|
daemonCount(0),
|
||||||
fixedFootprint(0),
|
fixedFootprint(0),
|
||||||
localThread(0),
|
localThread(0),
|
||||||
stateLock(0),
|
stateLock(0),
|
||||||
heapLock(0),
|
heapLock(0),
|
||||||
classLock(0),
|
classLock(0),
|
||||||
referenceLock(0),
|
referenceLock(0),
|
||||||
|
shutdownLock(0),
|
||||||
libraries(0),
|
libraries(0),
|
||||||
loader(0),
|
loader(0),
|
||||||
loadClassMethod(0),
|
loadClassMethod(0),
|
||||||
@ -1996,6 +2043,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
|||||||
finalizeQueue(0),
|
finalizeQueue(0),
|
||||||
weakReferences(0),
|
weakReferences(0),
|
||||||
tenuredWeakReferences(0),
|
tenuredWeakReferences(0),
|
||||||
|
shutdownHooks(0),
|
||||||
unsafe(false),
|
unsafe(false),
|
||||||
triedBuiltinOnLoad(false),
|
triedBuiltinOnLoad(false),
|
||||||
heapPoolIndex(0)
|
heapPoolIndex(0)
|
||||||
@ -2009,6 +2057,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
|
|||||||
not system->success(system->make(&heapLock)) or
|
not system->success(system->make(&heapLock)) or
|
||||||
not system->success(system->make(&classLock)) or
|
not system->success(system->make(&classLock)) or
|
||||||
not system->success(system->make(&referenceLock)) or
|
not system->success(system->make(&referenceLock)) or
|
||||||
|
not system->success(system->make(&shutdownLock)) or
|
||||||
not system->success
|
not system->success
|
||||||
(system->load(&libraries, findProperty(this, "avian.bootstrap"), false)))
|
(system->load(&libraries, findProperty(this, "avian.bootstrap"), false)))
|
||||||
{
|
{
|
||||||
@ -2024,6 +2073,7 @@ Machine::dispose()
|
|||||||
heapLock->dispose();
|
heapLock->dispose();
|
||||||
classLock->dispose();
|
classLock->dispose();
|
||||||
referenceLock->dispose();
|
referenceLock->dispose();
|
||||||
|
shutdownLock->dispose();
|
||||||
|
|
||||||
if (libraries) {
|
if (libraries) {
|
||||||
libraries->disposeAll();
|
libraries->disposeAll();
|
||||||
@ -2150,8 +2200,9 @@ Thread::exit()
|
|||||||
enter(this, Thread::ExclusiveState);
|
enter(this, Thread::ExclusiveState);
|
||||||
|
|
||||||
if (m->liveCount == 1) {
|
if (m->liveCount == 1) {
|
||||||
vm::exit(this);
|
turnOffTheLights(this);
|
||||||
} else {
|
} else {
|
||||||
|
threadPeer(this, javaThread) = 0;
|
||||||
enter(this, Thread::ZombieState);
|
enter(this, Thread::ZombieState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2170,31 +2221,41 @@ Thread::dispose()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
exit(Thread* t)
|
shutDown(Thread* t)
|
||||||
{
|
{
|
||||||
enter(t, Thread::ExitState);
|
ACQUIRE(t, t->m->shutdownLock);
|
||||||
|
|
||||||
joinAll(t, t->m->rootThread);
|
object hooks = t->m->shutdownHooks;
|
||||||
|
PROTECT(t, hooks);
|
||||||
|
|
||||||
for (object* p = &(t->m->finalizers); *p;) {
|
t->m->shutdownHooks = 0;
|
||||||
object f = *p;
|
|
||||||
*p = finalizerNext(t, *p);
|
|
||||||
|
|
||||||
void (*function)(Thread*, object);
|
object h = hooks;
|
||||||
memcpy(&function, &finalizerFinalize(t, f), BytesPerWord);
|
PROTECT(t, h);
|
||||||
function(t, finalizerTarget(t, f));
|
for (; h; h = pairSecond(t, h)) {
|
||||||
|
startThread(t, pairFirst(t, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (object* p = &(t->m->tenuredFinalizers); *p;) {
|
// wait for hooks to exit
|
||||||
object f = *p;
|
h = hooks;
|
||||||
*p = finalizerNext(t, *p);
|
for (; h; h = pairSecond(t, h)) {
|
||||||
|
while (true) {
|
||||||
|
Thread* ht = reinterpret_cast<Thread*>(threadPeer(t, pairFirst(t, h)));
|
||||||
|
|
||||||
void (*function)(Thread*, object);
|
{ ACQUIRE(t, t->m->stateLock);
|
||||||
memcpy(&function, &finalizerFinalize(t, f), BytesPerWord);
|
|
||||||
function(t, finalizerTarget(t, f));
|
if (ht == 0
|
||||||
|
or ht->state == Thread::ZombieState
|
||||||
|
or ht->state == Thread::JoinedState)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ENTER(t, Thread::IdleState);
|
||||||
|
t->m->stateLock->wait(t->systemThread, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disposeAll(t, t->m->rootThread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2255,6 +2316,10 @@ enter(Thread* t, Thread::State s)
|
|||||||
if (s == Thread::ZombieState) {
|
if (s == Thread::ZombieState) {
|
||||||
assert(t, t->m->liveCount > 0);
|
assert(t, t->m->liveCount > 0);
|
||||||
-- t->m->liveCount;
|
-- t->m->liveCount;
|
||||||
|
|
||||||
|
if (threadDaemon(t, t->javaThread)) {
|
||||||
|
-- t->m->daemonCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t->state = s;
|
t->state = s;
|
||||||
|
|
||||||
@ -2308,7 +2373,7 @@ enter(Thread* t, Thread::State s)
|
|||||||
|
|
||||||
t->state = s;
|
t->state = s;
|
||||||
|
|
||||||
while (t->m->liveCount > 1) {
|
while (t->m->liveCount - t->m->daemonCount > 1) {
|
||||||
t->m->stateLock->wait(t->systemThread, 0);
|
t->m->stateLock->wait(t->systemThread, 0);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -3436,6 +3501,7 @@ visitRoots(Machine* m, Heap::Visitor* v)
|
|||||||
v->visit(&(m->byteArrayMap));
|
v->visit(&(m->byteArrayMap));
|
||||||
v->visit(&(m->types));
|
v->visit(&(m->types));
|
||||||
v->visit(&(m->jniMethodTable));
|
v->visit(&(m->jniMethodTable));
|
||||||
|
v->visit(&(m->shutdownHooks));
|
||||||
|
|
||||||
for (Thread* t = m->rootThread; t; t = t->peer) {
|
for (Thread* t = m->rootThread; t; t = t->peer) {
|
||||||
::visitRoots(t, v);
|
::visitRoots(t, v);
|
||||||
|
@ -1178,12 +1178,14 @@ class Machine {
|
|||||||
unsigned propertyCount;
|
unsigned propertyCount;
|
||||||
unsigned activeCount;
|
unsigned activeCount;
|
||||||
unsigned liveCount;
|
unsigned liveCount;
|
||||||
|
unsigned daemonCount;
|
||||||
unsigned fixedFootprint;
|
unsigned fixedFootprint;
|
||||||
System::Local* localThread;
|
System::Local* localThread;
|
||||||
System::Monitor* stateLock;
|
System::Monitor* stateLock;
|
||||||
System::Monitor* heapLock;
|
System::Monitor* heapLock;
|
||||||
System::Monitor* classLock;
|
System::Monitor* classLock;
|
||||||
System::Monitor* referenceLock;
|
System::Monitor* referenceLock;
|
||||||
|
System::Monitor* shutdownLock;
|
||||||
System::Library* libraries;
|
System::Library* libraries;
|
||||||
object loader;
|
object loader;
|
||||||
object loadClassMethod;
|
object loadClassMethod;
|
||||||
@ -1198,6 +1200,7 @@ class Machine {
|
|||||||
object finalizeQueue;
|
object finalizeQueue;
|
||||||
object weakReferences;
|
object weakReferences;
|
||||||
object tenuredWeakReferences;
|
object tenuredWeakReferences;
|
||||||
|
object shutdownHooks;
|
||||||
bool unsafe;
|
bool unsafe;
|
||||||
bool triedBuiltinOnLoad;
|
bool triedBuiltinOnLoad;
|
||||||
JavaVMVTable javaVMVTable;
|
JavaVMVTable javaVMVTable;
|
||||||
@ -1394,6 +1397,9 @@ dispose(Thread* t, Reference* r)
|
|||||||
void
|
void
|
||||||
collect(Thread* t, Heap::CollectionType type);
|
collect(Thread* t, Heap::CollectionType type);
|
||||||
|
|
||||||
|
void
|
||||||
|
shutDown(Thread* t);
|
||||||
|
|
||||||
#ifdef VM_STRESS
|
#ifdef VM_STRESS
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@ -1599,6 +1605,19 @@ setObjectClass(Thread*, object o, object value)
|
|||||||
| (reinterpret_cast<uintptr_t>(cast<object>(o, 0)) & (~PointerMask)));
|
| (reinterpret_cast<uintptr_t>(cast<object>(o, 0)) & (~PointerMask)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Thread*
|
||||||
|
startThread(Thread* t, object javaThread)
|
||||||
|
{
|
||||||
|
Thread* p = t->m->processor->makeThread(t->m, javaThread, t);
|
||||||
|
|
||||||
|
if (t->m->system->success(t->m->system->start(&(p->runnable)))) {
|
||||||
|
return p;
|
||||||
|
} else {
|
||||||
|
p->exit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline const char*
|
inline const char*
|
||||||
findProperty(Machine* m, const char* name)
|
findProperty(Machine* m, const char* name)
|
||||||
{
|
{
|
||||||
@ -2341,9 +2360,6 @@ interrupt(Thread*, Thread* target)
|
|||||||
object
|
object
|
||||||
intern(Thread* t, object s);
|
intern(Thread* t, object s);
|
||||||
|
|
||||||
void
|
|
||||||
exit(Thread* t);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
walk(Thread* t, Heap::Walker* w, object o, unsigned start);
|
walk(Thread* t, Heap::Walker* w, object o, unsigned start);
|
||||||
|
|
||||||
|
@ -9,9 +9,20 @@ public class Strings {
|
|||||||
115, 46, 83, 121, 109, 98, 111, 108 })
|
115, 46, 83, 121, 109, 98, 111, 108 })
|
||||||
.equals("com.ecovate.nat.bus.Symbol"));
|
.equals("com.ecovate.nat.bus.Symbol"));
|
||||||
|
|
||||||
// We don't yet have a regex implementation, so this test will fail:
|
final String months = "Jan\u00aeFeb\u00aeMar\u00ae";
|
||||||
// final String months = "Jan\u00aeFeb\u00aeMar\u00ae";
|
expect(months.split("\u00ae").length == 3);
|
||||||
// expect(months.split("\u00ae").length == 3);
|
expect(months.replaceAll("\u00ae", ".").equals("Jan.Feb.Mar."));
|
||||||
|
|
||||||
|
expect("foo_foofoo__foo".replaceAll("_", "__")
|
||||||
|
.equals("foo__foofoo____foo"));
|
||||||
|
|
||||||
|
expect("foo_foofoo__foo".replaceFirst("_", "__")
|
||||||
|
.equals("foo__foofoo__foo"));
|
||||||
|
|
||||||
|
expect("stereomime".matches("stereomime"));
|
||||||
|
expect(! "stereomime".matches("stereomim"));
|
||||||
|
expect(! "stereomime".matches("tereomime"));
|
||||||
|
expect(! "stereomime".matches("sterEomime"));
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append('$');
|
sb.append('$');
|
||||||
|
Loading…
Reference in New Issue
Block a user