17:37 Wed, 16 Dec 2009 PST -0800

OpenJDK 7 on Leopard PPC


Thanks to the work of Gary Benson on implementing and merging the Zero-Assembler Project, and Greg Lewis' work bringing it to OpenJDK BSD Port, it's now possible to bootstrap OpenJDK 7 on Mac OS X 10.5/PPC.

Gary Benson's Zero Assembler provides a portable implementation of the JVM intepreter that -- unlike the existing JVM implementations -- relies on very little assembler to provide an acceptably performing but highly portable VM, opening the door to supporting Mac OS X PPC with very little additional work.

I've committed the few small fixes to get OpenJDK running on Mac OS X 10.5/PPC, and have bootstrapped an initial OpenJDK 7 binary using Havard Eidnes's bootstrap scripts. Bootstrapping the initial VM running is sufficiently involved that I would recommend using my binaries (openjdk7-macppc-2009-12-16-b4.tar.bz2).

Source Access

OpenJDK uses Mercurial with the Forest extension. Before checking out the BSD sources, you will need to install and configure Mercurial. See the OpenJDK Developer's Guide for more information.

To check out the BSD-Port forest:

hg fclone http://hg.openjdk.java.net/bsd-port/bsd-port

Building on Leopard/PPC

Building OpenJDK requires Java 6 or OpenJDK 7 -- on PPC, you will need to download or build an OpenJDK 7 bootstrap VM (openjdk7-macppc-2009-12-16-b4.tar.bz2).

To build the JDK in build/bsd-ppc/j2sdk-image:

make \
CC=gcc-4.0 \
CXX=g++-4.0 \
ANT_HOME=/usr/share/ant \
ALT_CUPS_HEADERS_PATH=/usr/include \
ALT_CACERTS_FILE=/System/Library/Frameworks/JavaVM.framework/Home/lib/security/cacerts \
LIBFFI_CFLAGS="-I/usr/include/ffi" \
NO_DOCS=true \

Be sure to set ALT_BOOTDIR to the path of your installed openjdk7-macppc-2009-12-16-b4 bootstrap JDK.

Once built, you should now have a JDK in build/bsd-ppc/j2sdk-image:

landonf@onefish:~/openjdk-ppc/bsd-port> ./build/bsd-ppc/j2sdk-image/bin/java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-landonf_2009_12_16_12_54-b00)
OpenJDK Zero VM (build 17.0-b05, interpreted mode)

For more information or assistance, please refer to the OpenJDK BSD-Port wiki and mailing list. My testing has been very limited -- if you run into issues, please report them on the development mailing list.

[/code/java] permanent link

17:29 Wed, 16 Dec 2009 PST -0800

Using Blocks: Understanding the Memory Management Rules


I just finished uploading PLBlocks 1.0-beta2, which adds support for iPhoneOS 2.2, iPhone 3GS armv7-optimized binaries, and host support for PPC systems (release announcement). This seems like a good time a good time to continue with my ad-hoc series on developing with Blocks (previous post).

I've fielded a number of questions regarding the memory management rules surrounding blocks; This article should help you understand the basic rules necessary to use blocks successfully.

I won't delve too deep into the describing the actual block implementation, as that's a topic well-covered by Clang's Block Implementation Specification Even if you don't have time to read the implementation specification, it's important to note that blocks are really just a few functions and structures implemented for you by the compiler, coupled with a runtime to help with managing setup and tear down. You could implement the same thing yourself in pure C -- but it would be so verbose as to not be useful.

The Memory Management Rules

Apple provides a set of straight-forward memory management rules for Objective-C. I've endeavoured to provide an equivalent set of rules for blocks in C and Objective-C.

This is the single fundamental memory management rule:

The following rules derive from the fundamental rule, or cope with edge cases:

Block Ownership: Copy vs. Retain

All blocks have a valid class pointer, and appear to be Objective-C objects. According to the standard Objective-C memory management, to assume ownership of an object you must simply retain it. However, blocks differ from the standard Objective-C objects in at least one fundamental and very important way: blocks defined within a function are allocated on the stack, and will persist only until your function returns.

This is why it is necessary to copy a block, rather than retain it: If the block is stack allocated, it must be copied to a heap allocation to persist beyond the lifetime of the current stack frame. Once copied, the block will be heap allocated and persist like any other standard Objective-C object.

Thus, to ensure that you do not attempt to maintain ownership of a stack allocated block, you must always copy a block if you wish to reference it past the lifetime of your current function. As an optimization, if a block has already been copied to the heap copying will simply increment the block's reference count.

It should also be noted that there is one very real benefit to stack allocation of blocks: they are very cheap, and unless copied, require no allocations or cleanup.

Captured Variables: Copy vs. Reference

By default, local variables (variables of the "auto" storage class) are captured by your block as const copies, while global variables are accessed directly. The runtime automatically handles reference counting of captured blocks and Objective-C objects.

To allow you modify a local variable (rather than its copy), Apple has added the __block storage specifier. Any __block variables are accessed by referenced from within a block. This is best explained by example:

__block int i = 0;
int j = 0;
    // Increments the stack allocated 'i' variable by 1.

// 'j' is a const copy, and can not be modified from within the block / j++ });

If you copy a block, any captured __block variables will also be copied to the heap.

Further Reading

I hope these brief explanations have provided a reasonable introduction to memory management with blocks. For additional details, you may wish to review Jim Dovey's post on the life-cycle of blocks, and join the PLBlocks Mailing List for further discussion.

[/code/iphone] permanent link