もう一つ発見

JavaVMは、

  • 局所変数を65535個もてる
  • 1メソッドで最大21億バイトまでいける

ことになってます、仕様上。ただ、この仕様をまじめに実装しているVMが有るかどうかは不明です。昔、超巨大な配列をstatic finalで持つ「リソースクラス」なんてのを作ったときに「スタティックイニシャライザが32Kを超えたので動かせません」と実行時エラーを吐かれたような気が(設定ファイルを外部に持つのをいやがった手抜きです)。
そもそもその「スタティックイニシャライザ」とはなんぞや? というところから調べて、クラスファイルの隠しメソッド「」にたどり着いたんだよね。懐かしい。あの頃のEclipsejad(デコンパイラ)にまだ対応してなかったので、「コンパイルかけたものをデコンパイルする」という手順にも気づかなかったような。
ただ、おかげで携帯電話上のJavaのソフトをむやみに小さくする魔法をいくつも編み出したような。もう使わない技術だよなー。コードよりリソースの方が圧倒的に大きいもん。


で、そうそう。発見の話。
Javaアセンブラやデコンパイラでは気づきませんが、Javaには1メソッド内には「相対ジャンプ」しか有りません。なので、便宜上メソッドのエントリーポイントを0番地と割り振ってますが、位置非依存です。それどころか、メソッドのinvokeとは全く別に「サブルーチンジャンプ」なんて命令すら有ります。使ってるの、見たこと無いけど。定数はコンスタントプールとしてクラスごとに持っているので、これにも「番地」は出てきません。ただし、サブルーチン呼び出しをしたときだけPCの番地がスタックに入ります。他にPCとる方法、無いんじゃないかなー。
なんというか、Javaの盲腸を見たような気分です。
Smalltalkには「BitBltする」なんていう味わい深いバイトコードがありましたが(グラフィックコンテキストどうするんだ、とか、そもそもheadless環境でどう動かすんだ、とか考えちゃいけない。だってSmalltalkは本来GUI有ってのものだもの。ちなみにグラフィックコンテキストに近いものは擬似変数thisContextに入ってます)、Javaもかなり味わい深いものがありますね。しみじみ。