Commits on Jul 11, 2010
  1. fix bootimage build

    dicej committed Jul 11, 2010
    We must call compileThunks before fixupMethods is run to ensure that
    we have access to the compileInterface and invokeInterface thunks when
    populating the interface method tables.
  2. optimize invokeinterface for TailCalls=false case

    dicej committed Jul 11, 2010
    When we're not optimizing tail calls by reusing stack frames, we can
    rely on the return address always pointing to the call site, which
    means we need not generate code to store a reference to the target
    method in a known location when compiling invokeinterface.  Instead,
    we add a mapping from the call site address to the target method in
    MyProcessor::callTable when compiling the caller, which we can later
    refer to from compileInterfaceMethod2 to determine the appropriate
    method to look up.
  3. optimize invokeinterface calls with hash-based interface method tables

    dicej committed Jul 11, 2010
    Previously, the JIT compiler implemented invokeinterface by calling a
    helper thunk to find the appropriate method and then calling the
    result, which was slow because it involved an out-of-line call and a
    linear search over all the implemented interfaces for the instance.
    This commit improves upon that strategy by adding a fixed-size area to
    each class's vtable for interface calls.  This area is initialized by
    hashing the name and spec of each interface method implemented and
    placing the address of a thunk at that location.  The thunk to use
    depends on whether there is a collision (more than one method maps to
    that index into the table) and thus whether we should later overwrite
    the address of the thunk with the address of the compiled method.  In
    the common case of a unique mapping (i.e. no collision), the result is
    a call which is almost as fast as an invokevirtual call.  In the case
    of a collision, we revert to the old algorithm.
    This approach was inspired by this abstract:
    The new strategy involves a few trade-offs:
     * We reserve space for the interface method table for all classes,
       not just those which implement non-empty interfaces.  We could
       avoid this by allocating it separately instead of making it part of
       the vtable, but this would add another level of indirection to each
       interface call.
     * Classes which implement only a few interface methods end up with a
       sparsely-populated IMT, which wastes memory.  We can mitigate this
       my shrinking the IMT, but that will increase the number of
     * Even in the case of a unique mapping, invokeinterface calls still
       aren't quite as fast as invokevirtual calls since we still have to
       store a reference to the actual method to be called in a known
       location, since we can't be sure when generating the call that
       there won't be a collision or that the callee has already been
       compiled.  One way around this is to maintain a map of call sites
       to target methods and use that to derive the target from the thunk.
       However, that only works if the thunk has a return address that
       points to the call site, which isn't always the case for tail
       calls.  Another thing we can do is make the store operation as
       inexpensive as possible by loading to a known register instead of a
       thread-local field, hence a todo comment to that effect in the
    This commit also includes some peripheral cleanups involving bootstrap
    classes needed to accomodate the new strategy.
Commits on Jul 6, 2010
  1. handle virtual thunk case in MyProcessor::getStackTrace

    dicej committed Jul 6, 2010
    If we catch the target thread in a virtual thunk when getting its
    stack trace, we must assume its Thread::stack field is garbage and use
    the register values instead.  Previously, we treated these thunks as
    any other native code, leading to crashes when we tried to use the
    garbage pointer.
Commits on Jul 2, 2010
  1. Merge branch 'dns'

    dicej committed Jul 2, 2010
Commits on Jun 26, 2010
  1. reduce CodeCapacity value to 16MB in bootimage.cpp

    dicej committed Jun 26, 2010
    32MB was just slightly too large for PowerPC immediate call instructions
    to span, and 16MB matches the JIT executable memory area we use in
  2. fix tails=true bootimage=true build

    dicej committed Jun 26, 2010
    compileDirectInvoke does some magic to optimize tail calls to native
    methods which involves storing the return address (which we'll never
    actually return to, since it's a tail call) in a thread-local field so
    the thunk function can figure out which native method to look up at
    runtime.  Since this address will change when the boot image is
    loaded, the boot image creation code needs to know about it.
Commits on Jun 25, 2010
  1. fix callContinuation regression

    dicej committed Jun 25, 2010
    callContinuation failed to call the correct continuation when feeding
    it an exception due to a regression introduced with the
    Thread.getStackTrace changes.
  2. update PowerPC assembly Thread field offsets

    dicej committed Jun 25, 2010
    The new Thread::defaultHeap declaration has increased the offset of all
    the fields following it.
    This commit also makes vmInvoke_returnAddress global so it can be refered
    to from compile.cpp.
  3. update assembly code field offsets to reflect new Thread field declar…

    dicej committed Jun 25, 2010
    Thread::defaultHeap is now an inline array, which means the offsets of
    all the fields following have increased.
  4. initialize MyProcessor::callTableSize in constructor

    dicej committed Jun 25, 2010
    This field was being used uninitialized, which could lead to an out of
    memory condition when we tried to grow the call table to a ridiculous
Commits on Jun 19, 2010
  1. pre-allocate Thread::backupHeap for signal safety

    dicej committed Jun 19, 2010
    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.
Commits on Jun 17, 2010
  1. fix isThunkUnsafeStack

    dicej committed Jun 17, 2010
    This function was broken in two different ways:
     1. It only checked MyProcessor::thunks, not MyProcessor::bootThunks.
        It needs to check both.
     2. When checking MyProcessor::thunks, it used fields from
        MyProcessor::bootThunks instead of from the same thunk collection.
    This fixes both problems.
  2. fix windows build

    dicej committed Jun 17, 2010
Commits on Jun 16, 2010
  1. fix typo in compile-x86.S

    dicej committed Jun 16, 2010
  2. fix Thread.getStackTrace race conditions

    dicej committed Jun 16, 2010
    Implementing Thread.getStackTrace is tricky.  A thread may interrupt
    another thread at any time to grab a stack trace, including while the
    latter is executing Java code, JNI code, helper thunks, VM code, or
    while transitioning between any of these.
    To create a stack trace we use several context fields associated with
    the target thread, including snapshots of the instruction pointer,
    stack pointer, and frame pointer.  These fields must be current,
    accurate, and consistent with each other in order to get a reliable
    trace.  Otherwise, we risk crashing the VM by trying to walk garbage
    stack frames or by misinterpreting the size and/or content of
    legitimate frames.
    This commit addresses sensitive transition points such as entering the
    helper thunks which bridge the transitions from Java to native code
    (where we must save the stack and frame registers for use from native
    code) and stack unwinding (where we must atomically update the thread
    context fields to indicate which frame we are unwinding to).  When
    grabbing a trace for another thread, we determine what kind of code we
    caught the thread executing in and use that information to choose the
    thread context values with which to begin the trace.  See
    MyProcessor::getStackTrace::Visitor::visit for details.
    In order to atomically update the thread context fields, we do the
     1. Create a temporary "transition" object to serve as a staging area
        and populate it with the new field values.
     2. Update a transition pointer in the thread object to point to the
        object created above.  As long as this pointer is non-null,
        interrupting threads will use the context values in the staging
        object instead of those in the thread object.
     3. Update the fields in the thread object.
     4. Clear the transition pointer in the thread object.
    We use a memory barrier between each of these steps to ensure they are
    made visible to other threads in program order.  See
    MyThread::doTransition for details.
Commits on Jun 14, 2010
  1. switch from gethostbyname to getaddrinfo on POSIX systems

    dicej committed Jun 14, 2010
    gethostbyname may return any combination of IPv4 and IPv6 addresses,
    and it's not safe to assume the first address is IPv4, which is all
    our code is currently prepared to handle.  In contrast, getaddrinfo
    allows us to specify whether we want IPv4, IPv6, or both.
    We should eventually make this switch on Windows as well, but the
    status of getaddrinfo in Windows 2000 is not clear, and MinGW's
    ws2tcpip.h only declares it for XP and above.
    This commit also adds InetAddress.getByName for explicit DNS lookups.
Commits on Jun 9, 2010
Commits on Jun 5, 2010
  1. use closesocket instead of close on Windows

    dicej committed Jun 5, 2010
    MinGW's close apparently does nothing, and MSVC's headers don't even
    declare it, so closesocket is the way to go.
Commits on Jun 4, 2010
  1. fix several blocking SocketChannel bugs

    dicej committed Jun 4, 2010
    In java-nio.cpp, we can't use GetPrimitiveArrayCritical when reading
    from or writing to blocking sockets since it may block the rest of the
    VM indefinitely.
    In, we can't use a null test on
    SelectableChannel.key to determine whether the channel is open since
    it might never be registered with a Selector.  According to the Sun
    documentation, a SelectableChannel is open as soon as it's created, so
    that's what we now implement.
Commits on May 26, 2010
Commits on May 17, 2010
Commits on May 13, 2010
Commits on May 10, 2010
Commits on May 4, 2010
Commits on May 3, 2010
  1. Merge branch 'wip'

    Joel Dice
    Joel Dice committed May 3, 2010