225 Commits

Author SHA1 Message Date
Joel Dice
e5ecb5b549 add optional avian.error.log system property
This property may be used to specify a file name to use for printing
stack traces for unhandled exceptions.  The default is stderr.
2011-03-15 17:27:17 -06:00
Joel Dice
874890e317 assert exception parameter is not null in throw_ 2011-03-04 16:01:50 -07:00
Joel Dice
25f1a9f1e8 fix Thread::exit/Thread::dispose race condition
There was a race between these two functions such that one thread A
would run dispose on thread B just before thread B finishes exit, with
the result that Thread::lock and/or Thread::systemThread would be
disposed twice, resulting in a crash.
2011-02-28 10:14:01 -07:00
Joel Dice
0bbd11e9be return false if javaThread is null in Thread::Runnable::interrupted
This field may be null if the thread is in the process of being
attached to the VM.
2011-02-15 21:44:27 -07:00
Joel Dice
86c48f3ff6 handle null p->javaThread in addThread and removeThread
These functions may be called when p->javaThread is null, in which
case we must not try to set the threadPeer field.
2011-02-15 08:47:48 -07:00
Joel Dice
468edb97d2 work around GCC name mangling bug
It seems that older versions of GCC (4.0 and older, at least) generate
assembly files with duplicate symbols for function templates which
differ only by the attributes of the templated types.  Newer versions
have no such problem, but we need to support both, hence the
workaround in this commit of using a dedicated, non-template "alias"
function where we previously used "cast<alias_t>".
2011-02-14 11:47:59 -07:00
Joel Dice
8d50d0fd76 fix aliasing bug in util.cpp
We use a template function called "cast" to get raw access to fields
in in the VM.  In particular, we use this function in util.cpp to
treat reference fields as intptr_t fields so we can use the least
significant bit as the red/black flag in red/black tree nodes.
Unfortunately, this runs afoul of the type aliasing rules in C/C++,
and the compiler is permitted to optimize in a way that assumes such
aliasing cannot occur.  Such optimization caused all the nodes in the
tree to be black, leading to extremely unbalanced trees and thus slow
performance.

The fix in this case is to use the __may_alias__ attribute to tell the
compiler we're doing something devious.  I've also used this technique
to avoid other potential aliasing problems.  There may be others
lurking, so a complete audit of the VM might be a good idea.
2011-02-11 21:57:27 -07:00
Joel Dice
cb7dc1aeef fix various regressions due to 0.5 work 2011-02-11 21:13:11 -07:00
Joel Dice
6e79e98d18 increase default stack size to 128KB
64KB was too small for many apps.  SWT in particular can use a lot of
stack space, especially on 64-bit systems.
2011-02-07 11:45:39 -07:00
Joel Dice
51a1081adc remove unused Heap::Client::outOfMemory method
The heap-dump-on-OOM feature has been moved to the collect function.
2011-02-02 08:46:20 -07:00
Joel Dice
cce89c8ddd fix MSVC build 2011-02-02 08:15:25 -07:00
Joel Dice
9ef9d9619d avoid deadlock due to entering active state before running destroyJavaVM
We risked deadlock when waiting for other non-daemon threads to exit
since they could not exit without entering exclusive state, which
required waiting for all other threads to go idle.
2011-02-01 17:45:43 -07:00
Joel Dice
f980ceb13e enable use-frame-pointer=true build
Also, include Continuations, Coroutines, and DynamicWind tests in test
suite for continuations=true build.
2011-01-27 21:06:01 -07:00
Joel Dice
b7157c802a fix continuations=true build 2011-01-27 11:54:41 -07:00
Joel Dice
43cbfd3f3a support stack unwinding without using a frame pointer
Previously, we unwound the stack by following the chain of frame
pointers for normal returns, stack trace creation, and exception
unwinding.  On x86, this required reserving EBP/RBP for frame pointer
duties, making it unavailable for general computation and requiring
that it be explicitly saved and restored on entry and exit,
respectively.

On PowerPC, we use an ABI that makes the stack pointer double as a
frame pointer, so it doesn't cost us anything.  We've been using the
same convention on ARM, but it doesn't match the native calling
convention, which makes it unusable when we want to call native code
from Java and pass arguments on the stack.

So far, the ARM calling convention mismatch hasn't been an issue
because we've never passed more arguments from Java to native code
than would fit in registers.  However, we must now pass an extra
argument (the thread pointer) to e.g. divideLong so it can throw an
exception on divide by zero, which means the last argument must be
passed on the stack.  This will clobber the linkage area we've been
using to hold the frame pointer, so we need to stop using it.

One solution would be to use the same convention on ARM as we do on
x86, but this would introduce the same overhead of making a register
unavailable for general use and extra code at method entry and exit.

Instead, this commit removes the need for a frame pointer.  Unwinding
involves consulting a map of instruction offsets to frame sizes which
is generated at compile time.  This is necessary because stack trace
creation can happen at any time due to Thread.getStackTrace being
called by another thread, and the frame size varies during the
execution of a method.

So far, only x86(_64) is working, and continuations and tail call
optimization are probably broken.  More to come.
2011-01-16 19:05:05 -07:00
Joel Dice
afabe8e07e rework VM exception handling; throw OOMEs when appropriate
This rather large commit modifies the VM to use non-local returns to
throw exceptions instead of simply setting Thread::exception and
returning frame-by-frame as it used to.  This has several benefits:

 * Functions no longer need to check Thread::exception after each call
   which might throw an exception (which would be especially tedious
   and error-prone now that any function which allocates objects
   directly or indirectly might throw an OutOfMemoryError)

 * There's no need to audit the code for calls to functions which
   previously did not throw exceptions but later do

 * Performance should be improved slightly due to both the reduced
   need for conditionals and because undwinding now occurs in a single
   jump instead of a series of returns

The main disadvantages are:

 * Slightly higher overhead for entering and leaving the VM via the
   JNI and JDK methods

 * Non-local returns can make the code harder to read

 * We must be careful to register destructors for stack-allocated
   resources with the Thread so they can be called prior to a
   non-local return

The non-local return implementation is similar to setjmp/longjmp,
except it uses continuation-passing style to avoid the need for
cooperation from the C/C++ compiler.  Native C++ exceptions would have
also been an option, but that would introduce a dependence on
libstdc++, which we're trying to avoid for portability reasons.

Finally, this commit ensures that the VM throws an OutOfMemoryError
instead of aborting when it reaches its memory ceiling.  Currently, we
treat the ceiling as a soft limit and temporarily exceed it as
necessary to allow garbage collection and certain internal allocations
to succeed, but refuse to allocate any Java objects until the heap
size drops back below the ceiling.
2010-12-27 15:55:23 -07:00
Joel Dice
5da8b96931 Merge remote branch 'origin/master' into r0.5 2010-12-21 15:28:34 -07:00
Joel Dice
2e86f0ac57 fix race condition leading to deadlock on exit
There is a delay between when we tell the OS to start a thread and
when it actually starts, and during that time a thread might
mistakenly think it was the last to exit, try to shut down the VM, and
then block in joinAll when it finds it wasn't the last one after all.

The solution is to increment Machine::liveCount and add the new thread
to the process tree before starting it -- all while holding
Machine::stateLock for atomicity.  This helps guarantee that when
liveCount is one, we can be sure there's really only one thread
running or staged to run.
2010-12-20 19:00:23 -07:00
Joel Dice
306f1282d0 throw ArithmeticException on divide-by-zero 2010-12-19 17:47:21 -07:00
Joel Dice
d18240cbd6 check for stack overflow on entry to all non-leaf methods
We now check for stack overflow in the JIT build as well as the
interpreted build, throwing a StackOverflowError if the limit
(currently hard-coded to 64KB, but should be easy to make
configurable) is exceeded.
2010-12-19 15:23:19 -07:00
Joel Dice
cac2d2cac5 fix race condition in monitorRelease
There was an unlikely but dangerous race condition in monitorRelease
such that when a thread released a monitor and then tried to notify
the next thread in line, the latter thread might exit before it can be
notified.  This potentially led to a crash as the former thread tried
to acquire and notify the latter thread's private lock after it had
been disposed.

The solution is to do as we do in the interrupt and join cases: call
acquireSystem first and thereby either block the target thread from
exiting until we're done or find that it has already exited, in which
case nothing needs to be done.

I also looked at monitorNotify to see if we have a similar bug there,
but in that case the target thread can't exit without first acquiring
and releasing the monitor, and since we ensure that no thread can
execute monitorNotify without holding the monitor, there's no
potential for a race.
2010-12-16 16:46:25 -07:00
Joel Dice
651ad20fc3 fix GC safety bugs 2010-12-09 22:17:57 -07:00
Joel Dice
3d49173b0b avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc..  This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.

While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.

Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-09 19:38:12 -07:00
Joel Dice
a5742f5985 update copyright years 2010-12-05 20:21:09 -07:00
Joel Dice
3d56a3211d revert part of earlier comment involving setDaemon and runJavaThread
The code added to runJavaThread was unecessary and harmful since it
allowed the global daemon thread count to become permanently
out-of-sync with the actual number of daemon threads.
2010-12-01 20:29:56 -07:00
Joel Dice
1722b68277 handle case of not-yet-started thread in setDaemon 2010-12-01 15:42:46 -07:00
Joel Dice
70a36c05b9 fix time==0 case in Unsafe.park and implement JVM_DumpThreads
Also, set name field on system threads for OpenJDK build to avoid NPEs
in Thread.getName.
2010-11-27 16:27:30 -07:00
Joel Dice
e68dfe1e89 various fixes to get Eclipse 3.6 working
* add libnet.so and libnio.so to built-in libraries for openjdk-src build

 * implement sun.misc.Unsafe.park/unpark

 * implement JVM_SetClassSigners/JVM_GetClassSigners

 * etc.
2010-11-27 11:25:02 -07:00
Joel Dice
459f4d5194 fix openjdk-src bootimage build
The main change here is to use a lazily-populated vector to associate
runtime data with classes instead of referencing them directly from
the class which requires updating immutable references in the heap
image.  The other changes employ other strategies to avoid trying to
update immutable references.
2010-11-26 12:41:31 -07:00
Joel Dice
aea02e545f fix race condition in interrupting/joining threads as they are exiting
My recent commit to ensure that OS resources are released immediately
upon thread exit introduced a race condition where interrupting or
joining a thread as it exited could lead to attempts to use
already-released resources.  This commit adds locking to avoid the
race.
2010-11-16 10:50:19 -07:00
Joel Dice
a611ccda6f Merge remote branch 'origin/master' into openjdk
Conflicts:
	makefile
	src/compile.cpp
	src/compiler.cpp
	src/type-generator.cpp
2010-11-16 10:18:08 -07:00
Joel Dice
f64d6c857b clean up OS resources immediately upon thread exit
Previously, we waited until the next GC to do this, but that can be
too long for workloads which create a lot of short-lived threads but
don't do much allocation.
2010-11-09 15:46:16 -07:00
Joel Dice
d0a6096eb0 add support for accessing embedded JARs as if they were directories
This allows OpenJDK to access time zone data which is normally found
under java.home, but which we must embed in the executable itself to
create a self-contained build.  The VM intercepts various file
operations, looking for paths which start with a prefix specified by
the avian.embed.prefix property and redirecting those operations to an
embedded JAR.

For example, if avian.embed.prefix is "/avian-embedded", and code
calls File.exists() with a path of
"/avian-embedded/javahomeJar/foo.txt", the VM looks for a function
named javahomeJar via dlsym, calls the function to find the memory
region containing the embeded JAR, and finally consults the JAR to see
if the file "foo.txt" exists.
2010-11-05 13:18:28 -06:00
Joel Dice
cabad6926f enable standalone OpenJDK builds
As described in readme.txt, a standalone OpenJDK build embeds all
libraries, classes, and other files needed at runtime in the resulting
binary, eliminating dependencies on external resources.
2010-11-04 11:02:09 -06:00
Joel Dice
268d2de175 cache array class lookups in element class; misc. bugfixes 2010-09-25 15:54:01 -06:00
Joel Dice
89f6adc93c fix various classloading deadlocks and races 2010-09-22 13:58:46 -06:00
Joel Dice
efd3ccb04f set java.home to path of JRE, not JDK 2010-09-20 18:38:38 -06:00
Joel Dice
17f495eb27 rework OpenJDK build to derive classpath and library path from environment
We now consult the JAVA_HOME environment variable to determine where
to find the system library JARs and SOs.  Ultimately, we'll want to
support self-contained build, but this allows Avian to behave like a
conventional libjvm.so.
2010-09-20 17:31:23 -06:00
Joel Dice
d0d53e2e10 fix custom-classloader-related concurrency problems and other bugs
The main changes in this commit ensure that we don't hold the global
class lock when doing class resolution using application-defined
classloaders.  Such classloaders may do their own locking (in fact,
it's almost certain), making deadlock likely when mixed with VM-level
locking in various orders.

Other changes include a fix to avoid overflow when waiting for
extremely long intervals and a GC root stack mapping bug.
2010-09-16 20:49:02 -06:00
Joel Dice
d819a75f36 more work towards OpenJDK classpath support
The biggest change in this commit is to split the system classloader
into two: one for boot classes (e.g. java.lang.*) and another for
application classes.  This is necessary to make OpenJDK's security
checks happy.

The rest of the changes include bugfixes and additional JVM method
implementations in classpath-openjdk.cpp.
2010-09-14 10:49:41 -06:00
Joel Dice
cddea7187d preliminary support for using OpenJDK's class library
Whereas the GNU Classpath port used the strategy of patching Classpath
with core classes from Avian so as to minimize changes to the VM, this
port uses the opposite strategy: abstract and isolate
classpath-specific features in the VM similar to how we abstract away
platform-specific features in system.h.  This allows us to use an
unmodified copy of OpenJDK's class library, including its core classes
and augmented by a few VM-specific classes in the "avian" package.
2010-09-10 15:05:29 -06:00
Joel Dice
17c1a552d5 break each Class, Field, and Method into separate classes
In order to facilitate making the VM compatible with multiple class
libraries, it's useful to separate the VM-specific representation of
these classes from the library implementations.  This commit
introduces VMClass, VMField, and VMMethod for that purpose.
2010-09-01 10:13:52 -06:00
Joel Dice
4034a219d0 do nothing in System.arraycopy if length <= 0
Previously, we risked segfaults by passing negative numbers to memcpy.

This commit also makes arraycopy throw an IndexOutOfBounds exception
instead of an ArrayStoreException if the specified offsets and lengths
would take us outside the bounds of one or both of the arrays, per the
Sun documentation.
2010-07-13 18:40:29 -06:00
Joel Dice
3018290238 pre-allocate Thread::backupHeap for signal safety
It's not safe to use malloc from a signal handler, so we can't
allocate new memory when handling segfaults or Thread.getStackTrace
signals.  Instead, we allocate a fixed-size backup heap for each
thread ahead of time and use it if there's no space left in the normal
heap pool.  In the rare case that the backup heap isn't large enough,
we fall back to using a preallocated exception without a stack trace
as a last resort.
2010-06-19 16:40:21 -06:00
JET
c666ab58e3 Improved (should now be complete) Unicode support (UTF-8 for *nix and UTF-16 for Windows). 2010-04-20 10:03:07 -06:00
Joel Dice
c9b9db1621 reimplement Java object monitors (second try)
See commit 8120bee4dc5f9ae2dec75a907778f1479ad398bd for the original
problem description and solution.  That commit and a couple of related
ones had to be reverted when we found they had introduced GC-safety
regressions leading to crashes.

This commit restores the reverted code and fixes the regressions.
2010-02-04 17:56:21 -07:00
Joel Dice
48834be209 revert recent commits to reimplement Java object monitors
We're seeing race conditions which occasionally lead to assertion
failures and thus crashes, so I'm reverting these changes for now:

29309fb4149ec02f993f84ffe4675e95c98db832
e92674cb7337355dc4dd6317219010e5d1ce7e1c
8120bee4dc5f9ae2dec75a907778f1479ad398bd
2010-02-04 08:18:39 -07:00
Joel Dice
e92674cb73 fix race condition in monitorWait
We don't want to check Thread::waiting until we have re-acquired the
monitor, since another thread might notify us between releasing
Thread::lock and acquiring the monitor.
2010-02-02 12:24:05 -07:00
Joel Dice
8120bee4dc reimplement Java object monitors to avoid running out of OS handles
Due to SWT's nasty habit of creating a new object monitor for every
task added to Display.asyncExec, we've found that, on Windows at
least, we tend to run out of OS handles due to the large number of
mutexes we create between garbage collections.

One way to address this might be to trigger a GC when either the
number of monitors created since the last GC exceeds a certain number
or when the total number of monitors in the VM reaches a certain
number.  Both of these risk hurting performance, especially if they
force major collections which would otherwise be infrequent.  Also,
it's hard to know what the values of such thresholds should be on a
given system.

Instead, we reimplement Java monitors using atomic compare-and-swap
(CAS) and thread-specific native locks for blocking in the case of
contention.  This way, we can create an arbitrary number of monitors
without creating any new native locks.  The total number of native
locks needed by the VM is bounded instead by the number of live
threads plus a small constant.

Note that if we ever add support for an architecture which does not
support CAS, we'll need to provide a fallback monitor implementation.
2010-02-01 18:40:47 -07:00
Joel Dice
4c0ede8b9a reuse JNI references when possible
Before allocating a new reference in NewGlobalReference or when
creating a local reference, we look for a previously-allocated
reference pointing to the same object.  This is a linear search, but
usually the number of elements in the reference list is small, whereas
the memory, locking, and allocation overhead of creating duplicate
references can be large.
2009-12-16 19:16:51 -07:00