Tail calls in the VM

昨日は JVM の TCO (Tail Call Optimization) の話が良く流れていたので The Da Vinci Machine Project の tail call を再確認。そこそこ動くプロトタイプはあった様だ。

中身に関しては John Rose 氏の次の blog にまとめられている。

https://blogs.oracle.com/jrose/entry/tail_calls_in_the_vm

JVM 上の tail call (hard tail call) のサポートとして bytecode prefix tailcall を導入して tail call になってほしい invoke* 命令の前に置く。これは wide bytecode と同じ値を流用する。wide は invoke* を修飾する事がないからこれは OK. tailcall prefix が付いている invoke* 命令は had tail call として扱われる。

verifier は tailcall prefix 付きの invoke を次の様にチェックする:

  • callee method の return signature は caller method の return signature と同一
  • invoke 命令のあとは return 命令
  • invoke 処理にたいする exception handler は定義されていない
  • caller method は synchronized ではない
  • caller method は object lock をもたない
  • callee method は caller method からアクセス、リンク可能

JVM は tailcall prefix が無い場合の様に invoke 命令を実行するが、callee を実行する前に caller の stack frame を破棄する。続く return 命令は実行しない。stack frame を破棄する事で、stack trace が変わってくる。アクセス権は一旦破棄されるが、callee にいく前に戻される。

java.lang.Claas.*, java.lang.reflect.Method.*, java.lang.reflect.Constructor.*, java.security.AccessController.* などは caller access を正しく行うのが難しいので対象外。

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6804517 という拡張要求も出ている。

某 Haskell 勉強会で入手したλカ娘第(2期)という読み物には tail call の goto 的な方法、トランポリンの実現方法、The Da Vinci Machine Project の上記拡張のパッチを組み込んで試してみたりする記事が載ってます。goto 的な方法では関数を一つに合成するアプローチを取るけど、この時に 64kb のメソッドサイズの制限が問題になってくる。うまく分割できない物かな...

Safepoint patent

HotSpot の Safepoint に関するパテント発見。斜め読み。

US Patent 6523059 SYSTEM AND METHOD FOR FACILITATING SAFEPOINT SYNCHRONIZATION IN A MULTITHREADED COMPUTER SYSTEM

GC の様な global operation の際にはオブジェクトの位置、参照するポインタの位置が分かっていなければならない。stop 命令で単に止めても safe region にいるかもしれないし、unsafe region にいるかもしれない。safe region はポインタを触っていない事が分かっている領域。unsafe はポインタを触っているかもしれない。スレッドをサスペンドして、safe ならよし、unsafe なら resume して後でまた suspend でもいいのだが、スレッドが多いと重い処理になる。

各スレッドに safepoint に関する状態と、その遷移時の処理を持たせ、また safepoint lock を設けて、比較的軽い処理を実現したというもの。

各スレッドが safe, unsafe, transitional の状態を持つ様にするとサスペンドしなくても状態が分かる。スレッドが safe region にいるなら、global safepoint operation の最中でも動作可能。global safepoint operation 中にtransitional region に入ると自動的に(ロックで)ブロックされる。

safepoint を開始する方は safepoint lock を取り、global safepoint operation が終わったら解放する。

lock を取った後、各スレッドの状態を調べて、safe, blocked で無い物に関しては、suspend して状態を確認する事を繰り返し、それらが 0 になるまで待つ。

カウンタの操作をどこでやるか、実際のグローバルな safepoint 同期をどのように伝えるか、細かい違いはあるけれど、OpenJDK と基本的な流れは変わらない様だ。

safe region にいるスレッドは unsafe への transition までは global safepoint operation 中でも動作できるとしている。

Building OpenJDK Mac-port

ML で次の bug を見かけたので、Mac-port を久々にビルドしてみる。

Bug ID: 7113349
Synopsis Initial changeset for Macosx port to jdk
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7113349

OS X 10.6.8 Xcode 3.2.6

手順は Mac OS X Port Project http://openjdk.java.net/projects/macosx-port/
の wiki https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port

Minimum requirements が 10.7.3 (Lion) になってる、、、けど気にせず Snow Leopard でやってみる。

ソースの取得

これは特に問題ない。Mercurial の Forest extension fclone に依存してない。

hg clone http://hg.openjdk.java.net/jdk7u/jdk7u-dev
cd jdk7u-dev
chmod 755 get_source.sh
./get_source.sh

ビルド

export LANG=C する様に書いてある。OS X (日本語環境?)の Java6 は LANG に関係なく Shift JIS を使うという困った動作をするので、実はこれだけでは不十分。 -Dfile.encoding=ASCII というオプションを渡さないと、ビルド中に生成した corba 等のコードのコンパイルに失敗してしまう。手っ取り早いのは _JAVA_OPTIONS=-Dfile.encoding=ASCII という環境変数をセットすること。これでこの環境変数が設定された環境ではこのオプションが設定される様になる。ビルドの進行具合を見ていると結構な数の java, javac などが呼び出されているので、このような設定の仕方が便利かもしれない。OpenJDK Mac port ではこの問題は解決されていたはず。

ビルドには既存の JDK が必要で、ALT_BOOTDIR で指定するという事が他のプラットホームでのビルドでも必要。また JAVA_HOME を設定しているとはねられるので、もし設定していたら外しておく。上記の wiki page ではビルドの仕方を(過去にビルドまたはインストールした) Java7 の場合と、Apple の Java6 の場合でコマンドラインが書いてある。

Java7
make ALLOW_DOWNLOADS=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.7+` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu`
Apple Java6
make ALLOW_DOWNLOADS=true SA_APPLE_BOOT_JAVA=true ALWAYS_PASS_TEST_GAMMA=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.6` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu`

/usr/libexec/java_home … はシステムや、ユーザーのディレクトリにある java のディレクトリを返してくれるコマンド。

$ /usr/libexec/java_home -v 1.7+
/Users//Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
$ /usr/libexec/java_home -v 1.6
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

HOTSPOT_BUILD_JOBS は hotspot の repositry のコードに関しての並列ビルドの指定。PARALLEL_COMPILE_JOBS というのもある様だ。いずれも最終的には GNU make -j N になる。

https://blogs.oracle.com/kto/entry/faster_openjdk_build_tricks

最初に -Dfile.encoding=ASCII を忘れて実行した場合、次の様に失敗した。

$ make ALLOW_DOWNLOADS=true SA_APPLE_BOOT_JAVA=true ALWAYS_PASS_TEST_GAMMA=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.6` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu`
( cd  ./jdk/make && \
…
/Users/.../local/openjdk-mac/jdk7u-dev/build/macosx-amd64/corba/gensrc/org/omg/PortableServer/Current.java:6: ?G???[: ???̕????́A?G???R?[?f?B???Oascii?Ƀ}?b?v?ł??܂???
 * IDL-to-Java ?R???p?C?? (?|?[?^?u??), ?o?[?W???? "3.1" ??????
                                         ^
/Users/.../local/openjdk-mac/jdk7u-dev/build/macosx-amd64/corba/gensrc/org/omg/PortableServer/Current.java:6: ?G???[: ???̕????́A?G???R?[?f?B???Oascii?Ƀ}?b?v?ł??܂???
 * IDL-to-Java ?R???p?C?? (?|?[?^?u??), ?o?[?W???? "3.1" ??????
                                           ^
?G???[100??
make[5]: *** [.compile.classlist] Error 1
make[4]: *** [build] Error 1
make[3]: *** [build] Error 1
make[2]: *** [build] Error 1
make[1]: *** [corba-build] Error 2
make: *** [build_product_image] Error 2

一回おかしなソースが生成されているので、_JAVA_OPTIONS=-Dfile.encoding=ASCII を指定してビルドしてもダメ。メッセージの中に次の行があったので、

/bin/mkdir -p /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/corba

このディレクトリを削除、または rename して、やり直す。

$ mv /Users/<user>/local/openjdk-mac/jdk7u-dev/build/macosx-amd64/corba /Users/<user>/local/openjdk-mac/jdk7u-dev/build/macosx-amd64/corba.bad
$ _JAVA_OPTIONS=-Dfile.encoding=ASCII make ALLOW_DOWNLOADS=true SA_APPLE_BOOT_JAVA=true ALWAYS_PASS_TEST_GAMMA=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.6` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu`

:
Property "env.CONFIGURATION_BUILD_DIR" has not been set
Property "env.INSTALL_PATH" has not been set
     [echo] (Settings :src '.' :cfg 'Debug' :obj '/Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/JObjC.build' :dst '/Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/JObjC.dst/Debug')
Property "env.BENCH_MATCH" has not been set
Build sequence for target(s) `all' is [gen-pcoder, build-core, build-core-native, build-generator, run-generator, build-generated, build-additions, build-additions-native, assemble-product, all]
Complete build sequence is [gen-pcoder, build-core, build-core-native, build-generator, run-generator, build-generated, build-additions, build-additions-native, assemble-product, all, clean, clean-all, build-test-installed, build-test-native-installed, bench-installed, test-installed, all-but-gen, run-generator-old, all-test, build-test, build-test-native, install, installsrc, installhdrs, test, bench, clean-all-test, doc-core, ]

gen-pcoder:
     [exec] Current OS is Mac OS X
     [exec] Executing 'ruby' with arguments:
     [exec] './run-and-write-if-okay'
     [exec] './src/core/PrimitiveCoder.hs'
     [exec] './src/core/java/com/apple/jobjc/PrimitiveCoder.java'
     [exec] 
     [exec] The ' characters around the executable and arguments are
     [exec] not part of the command.
     [exec] ./run-and-write-if-okay:40:in ``': Permission denied - ./src/core/PrimitiveCoder.hs (Errno::EACCES)
     [exec] 	from ./run-and-write-if-okay:40:in `
' BUILD FAILED /Users//local/openjdk-mac/jdk7u-dev/jdk/src/macosx/native/jobjc/build.xml:131: exec returned: 1 at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:646) at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:672) at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:498) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:390) at org.apache.tools.ant.Target.performTasks(Target.java:411) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399) at org.apache.tools.ant.Project.executeTarget(Project.java:1368) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1251) at org.apache.tools.ant.Main.runBuild(Main.java:809) at org.apache.tools.ant.Main.startAnt(Main.java:217) at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) Total time: 0 seconds make[4]: *** [/Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/JObjC.build/JObjC.jar] Error 1 make[3]: *** [all] Error 1 make[2]: *** [all] Error 1 make[1]: *** [jdk-build] Error 2 make: *** [build_product_image] Error 2

メッセージから、ruby の実行で失敗したらしい事が分かる。

     [exec] Executing 'ruby' with arguments:

rvm で ruby を 1.9.2 に設定していた為かと、rvm reset で一旦 OS X の物に戻してみる。

$ rvm reset
$ _JAVA_OPTIONS=-Dfile.encoding=ASCII make ALLOW_DOWNLOADS=true SA_APPLE_BOOT_JAVA=true ALWAYS_PASS_TEST_GAMMA=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.6` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu`
:
>>>Finished making images @ Sun Mar 18 14:04:20 JST 2012 ...
########################################################################
##### Leaving jdk for target(s) sanity all docs images             #####
########################################################################
##### Build time 00:13:57 jdk for target(s) sanity all docs images #####
########################################################################

#-- Build times ----------
Target all_product_build
Start 2012-03-18 13:50:00
End   2012-03-18 14:04:20
00:00:07 corba
00:00:04 hotspot
00:00:03 jaxp
00:00:05 jaxws
00:13:57 jdk
00:00:04 langtools
00:14:20 TOTAL
-------------------------

今回はビルド完了。build/macosx-amd64 の下にいろんなファイル、ディレクトリが出来ている。

$ ls build/macosx-amd64/
JObjC.build		demo			j2sdk-image
JObjC.dst		democlasses		jaxp
bin			demos-bundles		jaxws
bridge_metadata		docs			langtools
btbins			gennativesrc		lib
btclasses		gensrc			sample
btjars			hotspot			sanityCheckMessages.txt
bundles			impsrc			source-bundles
classes			include			source_tips
corba			j2re-bundle		stable_bridge_metadata
corba.bad		j2re-image		symbols
corba.bad2		j2sdk-bundle		tmp

~/Library/Java/JavaVirtualMachines を作り、その下に build/macosx-amd64/j2sdk-bundle/1.7.0.jdk をコピーすると、/lib/libexec/java_home でも認識される様になる。

$ mkdir -p ~/Library/Java/JavaVirtualMachines
$ cp -R build/macosx-amd64/j2sdk-bundle/1.7.0.jdk ~/Library/Java/JavaVirtualMachines
$ /usr/libexec/java_home --version 1.7
/Users/<user>/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
$ export JAVA_HOME=$(/usr/libexec/java_home --version 1.7)
$ java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-<user>_2012_03_18_13_34-b00)

SwingSet2 を実行してみる。Cocoa の UI で表示される。まぁ、Cocoa 対応は去年出来ていたのだけど。

$ $JAVA_HOME/bin/java -XX:+PrintCompilation -jar /Developer/Extras/Java/JFC/SwingSet2/SwingSet2.jar
     64    1       3       java.lang.String::hashCode (67 bytes)
     65    2       3       java.lang.String::charAt (33 bytes)
     66    3       3       java.lang.String::equals (88 bytes)
     66    4       3       java.lang.Math::min (11 bytes)
      :
   1611  582       4       java.lang.Object::equals (11 bytes)
   1611  253       3       java.lang.Object::equals (11 bytes)   made not entrant
   1612  583   !   3       java.awt.Component::enableEvents (164 bytes)
   1612  584       4       java.awt.Component::getParent (5 bytes)
   1612  217       3       java.awt.Component::getParent (5 bytes)   made not entrant

ここでは、-XX:+PrintCompilation を使用している。最初のカラムは起動からの msec, 次のカラムが compile id. java.lang.Object::equals の 253 が made not entrant になり、その上で、同じメソッドが 582 でコンパイルされている。253 が C1 client compiler でコンパイルされた物で、582 は C2 でコンパイルされた物。C2 でより強い最適化のかかったコードが出来たので、C1 の物は破棄されるということ。

今回使用したソースでは TieredCompilation がデフォルトで true になっている様だ。ソースで確認してもいいのだけれど、コマンドラインで指定されていないフラグを実行前に変更することもあるので、動いている物にアタッチして確認。

$ gdb
(gdb) attach 60870
(gdb) handle all nostop noprint
(gdb) x/bd &TieredCompilation
0x101f0e348 :	1

// 確かに TieredCompilation が true (=1) になっている。

// 適当に C1 compiler の関数にブレークポイントを設定
(gdb) info func C1
0x000000010197083e  C1_MacroAssembler::build_frame(int)

(gdb) tb *0x000000010197083e
Breakpoint 1 at 0x10197083e
(gdb) cont
Continuing.
[Switching to process 60870]

Breakpoint 1, 0x000000010197083e in C1_MacroAssembler::build_frame ()
(gdb) where
#0  0x000000010197083e in C1_MacroAssembler::build_frame ()
#1  0x00000001019420cc in LIR_Assembler::emit_op0 ()
#2  0x0000000101942d90 in LIR_Assembler::emit_lir_list ()
#3  0x0000000101942e30 in LIR_Assembler::emit_code ()
#4  0x0000000101928f80 in Compilation::emit_code_body ()
#5  0x00000001019293b5 in Compilation::compile_java_method ()
#6  0x000000010192951a in Compilation::compile_method ()
#7  0x000000010192972b in Compilation::Compilation ()
#8  0x0000000101929c07 in Compiler::compile_method ()
#9  0x00000001019c4bc9 in CompileBroker::invoke_compiler_on_method ()
#10 0x00000001019c61b5 in CompileBroker::compiler_thread_loop ()
#11 0x0000000101c77998 in JavaThread::thread_main_inner ()
#12 0x0000000101c78ce7 in JavaThread::run ()
#13 0x0000000101bcd8f1 in java_start ()
#14 0x00007fff822a3fd6 in _pthread_start ()
#15 0x00007fff822a3e89 in thread_start ()

// 適当に C2 compiler の関数にブレークポイントを設定
(gdb) info func Code_Gen
All functions matching regular expression "Code_Gen":

Non-debugging symbols:
0x00000001019bfaa8  Compile::Code_Gen()
(gdb) tb *0x00000001019bfaa8
Breakpoint 2 at 0x1019bfaa8
(gdb) cont
Continuing.
[Switching to process 60870]

Breakpoint 2, 0x00000001019bfaa8 in Compile::Code_Gen ()
(gdb) where
#0  0x00000001019bfaa8 in Compile::Code_Gen ()
#1  0x00000001019c2c8f in Compile::Compile ()
#2  0x0000000101983123 in C2Compiler::compile_method ()
#3  0x00000001019c4bc9 in CompileBroker::invoke_compiler_on_method ()
#4  0x00000001019c61b5 in CompileBroker::compiler_thread_loop ()
#5  0x0000000101c77998 in JavaThread::thread_main_inner ()
#6  0x0000000101c78ce7 in JavaThread::run ()
#7  0x0000000101bcd8f1 in java_start ()
#8  0x00007fff822a3fd6 in _pthread_start ()
#9  0x00007fff822a3e89 in thread_start ()

// C1, C2 両方が動いている事が分かった。
(gdb) detach

いろいろと環境変数引数は渡しているけど、make のターゲットはここまでは指定していない。デフォルトのターゲットは product で、これは JRE/JDK として配布されているのと同等。 globals.hpp というファイルには多くの -XX オプションが定義されているが product として定義されている物、あるいはexperimental とか manageable で定義されている物しか使用できない。debug や notproduct で定義されている物は fastdebug, debug build でしか使用できない。make に fastdebug_build や debug_build というターゲットを与えると、これらのデバッグ用のものも作る事が出来る。fastdebug は最適化つきのデバッグ版で debug 用の -XX flag を使う分にはこれで十分な事がおおい。ソースとの細かいマッチングをしたければ debug build を使う事になるが、それなりに大きいし、遅い。

出来上がった java7 で fastdebug をビルドしてみる。

$ make ALLOW_DOWNLOADS=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.7+` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu` fastdebug_build
 :
 -jaf_src-url-bundle:
     [echo] Downloading from https://java.net/downloads/jax-ws/JDK7/jdk7-jaf-2010_08_19.zip
      [get] Getting: https://java.net/downloads/jax-ws/JDK7/jdk7-jaf-2010_08_19.zip
      [get] To: /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64-fastdebug/jaxws/drop/bundles/jdk7-jaf-2010_08_19.zip.temp
      [get] Error getting https://java.net/downloads/jax-ws/JDK7/jdk7-jaf-2010_08_19.zip to /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64-fastdebug/jaxws/drop/bundles/jdk7-jaf-2010_08_19.zip.temp

BUILD FAILED
/Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64-fastdebug/jaxws/build/xml_generated/build-drop-jaf_src.xml:96: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1826)
	at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1809)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1328)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
	at org.apache.tools.ant.taskdefs.Get$GetThread.openConnection(Get.java:660)
	at org.apache.tools.ant.taskdefs.Get$GetThread.get(Get.java:579)
	at org.apache.tools.ant.taskdefs.Get$GetThread.run(Get.java:569)
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at sun.security.validator.PKIXValidator.(PKIXValidator.java:90)
	at sun.security.validator.Validator.getInstance(Validator.java:179)
	at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:314)
	at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:173)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:186)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321)
	... 7 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
	at java.security.cert.PKIXParameters.(PKIXParameters.java:120)
	at java.security.cert.PKIXBuilderParameters.(PKIXBuilderParameters.java:104)
	at sun.security.validator.PKIXValidator.(PKIXValidator.java:88)
	... 19 more

Total time: 10 seconds
make[3]: *** [all] Error 1
make[2]: *** [jaxws-build] Error 2
make[1]: *** [generic_debug_build] Error 2
make: *** [build_fastdebug_image] Error 2

Certificate まわりで失敗しているらしい。諦めて、java6 でビルド。

$ _JAVA_OPTIONS=-Dfile.encoding=ASCII make ALLOW_DOWNLOADS=true SA_APPLE_BOOT_JAVA=true ALWAYS_PASS_TEST_GAMMA=true ALT_BOOTDIR=`/usr/libexec/java_home -v 1.6` HOTSPOT_BUILD_JOBS=`sysctl -n hw.ncpu` fastdebug_build
:
ln -s ../Home/jre/lib/jli/libjli.dylib /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/../macosx-amd64-fastdebug/j2sdk-bundle/1.7.0.jdk/Contents/MacOS/
/bin/cp -r /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/../macosx-amd64-fastdebug/j2sdk-image /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/../macosx-amd64-fastdebug/j2sdk-bundle/1.7.0.jdk/Contents/Home
/usr/bin/sed -e "s/@@ID@@//g" -e "s/@@NAME@@/OpenJDK 7/g" -e "s/@@INFO@@/OpenJDK (1.7.0)/g" -e "s/@@PLATFORM_VERSION@@/1.7/g" -e "s/@@VERSION@@/1.7.0/g" -e "s/@@VENDOR@@/UNDEFINED/g" < /Users//local/openjdk-mac/jdk7u-dev/jdk/src/macosx/bundle/JDK-Info.plist > /Users//local/openjdk-mac/jdk7u-dev/build/macosx-amd64/../macosx-amd64-fastdebug/j2sdk-bundle/1.7.0.jdk/Contents/Info.plist
/usr/bin/SetFile -a B /Users/<>/local/openjdk-mac/jdk7u-dev/build/macosx-amd64/../macosx-amd64-fastdebug/j2sdk-bundle/1.7.0.jdk/Contents/../
>>>Finished making images @ Sun Mar 18 15:03:52 JST 2012 ...
########################################################################
##### Leaving jdk for target(s) sanity all  images                 #####
########################################################################
##### Build time 00:14:21 jdk for target(s) sanity all  images     #####
########################################################################

#-- Build times ----------
Target fastdebug_build
Start 2012-03-18 14:45:03
End   2012-03-18 15:03:52
00:00:07 corba
00:03:31 hotspot
00:00:04 jaxp
00:00:37 jaxws
00:14:21 jdk
00:00:08 langtools
00:18:49 TOTAL
                                                • -

今回はビルド成功。build/macosx-amd64-fastdebug 以下にできている。

$ build/macosx-amd64-fastdebug/bin/java -version
openjdk version "1.7.0-internal-fastdebug"
OpenJDK Runtime Environment (build 1.7.0-internal-fastdebug-<user>_2012_03_18_14_45-b00)
OpenJDK 64-Bit Server VM (build 23.0-b16-fastdebug, mixed mode)

fastdebug で nonproduct flag の PrintOptoAssembly を付けて、C2 の生成した命令を表示させながら実行してみる。

$ build/macosx-amd64-fastdebug/bin/java -XX:+PrintOptoAssembly -jar /Developer/Extras/Java/JFC/SwingSet2/SwingSet2.jar
:
#
#  bool ( java/util/concurrent/locks/AbstractQueuedSynchronizer:NotNull *, int )
#
#r018 rsi:rsi   : parm 0: java/util/concurrent/locks/AbstractQueuedSynchronizer:NotNull *
#r016 rdx   : parm 1: int
# -- Old rsp -- Framesize: 32 --
#r089 rsp+28: in_preserve
#r088 rsp+24: return address
#r087 rsp+20: in_preserve
#r086 rsp+16: saved fp register
#r085 rsp+12: pad2, stack alignment
#r084 rsp+ 8: pad2, stack alignment
#r083 rsp+ 4: Fixed slot 1
#r082 rsp+ 0: Fixed slot 0
#
000   N265: #	B1 <- BLOCK HEAD IS JUNK   Freq: 1
000   	movl    rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]	# compressed klass
	decode_heap_oop_not_null rscratch1, rscratch1
	cmpq    rax, rscratch1	 # Inline cache check
	jne     SharedRuntime::_ic_miss_stub
	nop	# nops to align entry point

      	nop 	# 12 bytes pad for loops and calls

020   B1: #	B25 B2 <- BLOCK HEAD IS JUNK   Freq: 1
020   	# stack bang
	pushq   rbp	# Save rbp
	subq    rsp, #16	# Create frame

02c   	movq    RBP, RSI	# spill
      	nop 	# 2 bytes pad for loops and calls
031   	movq    rax, #Universe::non_oop_word()
	call,dynamic  java.util.concurrent.locks.AbstractQueuedSynchronizer::tryRelease
        # java.util.concurrent.locks.AbstractQueuedSynchronizer::release @ bci:2  L[0]=RBP L[1]=_ L[2]=_
        # OopMap{rbp=Oop off=64}

いろんなデバッグフラグを試したり、改造をしてみる環境が出来た。