Top


定義場所(file name)

hotspot/src/share/vm/interpreter/rewriter.cpp

説明(description)

コメントによると, 新しい finalization の semantics では (<= #TODO どこを参照すればいい??) Object.() での正常終了時に登録されることになっているが, JVMTI で変更される恐れがあるため Object.() 自体に仕込んでおくわけにはいかない. そこで, 実行時に特殊な return 命令に置き換えることにした. なお, 生成されたインスタンスオブジェクトが登録処理に分からないといけないため, local 0 が変更されているとまずい. これについては単純に local 0 を変更する操作を全て禁止することにした. とのこと.

// The new finalization semantics says that registration of
// finalizable objects must be performed on successful return from the
// Object.<init> constructor.  We could implement this trivially if
// <init> were never rewritten but since JVMTI allows this to occur, a
// more complicated solution is required.  A special return bytecode
// is used only by Object.<init> to signal the finalization
// registration point.  Additionally local 0 must be preserved so it's
// available to pass to the registration function.  For simplicty we
// require that local 0 is never overwritten so it's available as an
// argument for registration.

名前(function name)

void Rewriter::rewrite_Object_init(methodHandle method, TRAPS) {

本体部(body)

  {- -------------------------------------------
  (1) メソッド内の全部のバイトコードを辿り, 
      return 命令であれば Bytecodes::_return_register_finalizer 命令に書き換える.

      (なお, 局所変数領域の 0 番(this)を変更するバイトコード命令がある場合は IncompatibleClassChangeError
       (理由は上記コメント部参照))
      ---------------------------------------- -}

      RawBytecodeStream bcs(method);
      while (!bcs.is_last_bytecode()) {
        Bytecodes::Code opcode = bcs.raw_next();
        switch (opcode) {
          case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break;

          case Bytecodes::_istore:
          case Bytecodes::_lstore:
          case Bytecodes::_fstore:
          case Bytecodes::_dstore:
          case Bytecodes::_astore:
            if (bcs.get_index() != 0) continue;

            // fall through
          case Bytecodes::_istore_0:
          case Bytecodes::_lstore_0:
          case Bytecodes::_fstore_0:
          case Bytecodes::_dstore_0:
          case Bytecodes::_astore_0:
            THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
                      "can't overwrite local 0 in Object.<init>");
            break;
        }
      }
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.