Top


定義場所(file name)

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

名前(function name)

Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, objArrayHandle methods, TRAPS)

本体部(body)

  {- -------------------------------------------
  (1) (フィールドの初期化)
      ---------------------------------------- -}

      : _klass(klass),
        _pool(cpool),
        _methods(methods)
    {

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert(_pool->cache() == NULL, "constant pool cache must not be set yet");

  {- -------------------------------------------
  (1) まず, Rewriter::compute_index_maps() を呼んで
      Constant Pool 中のフィールドやメソッドへの参照数を調べ, 
      対応する constant pool cache の index を作成しておく.
      ---------------------------------------- -}

      // determine index maps for methodOop rewriting
      compute_index_maps();

  {- -------------------------------------------
  (1) 処理対象のクラスが java.lang.Object である場合, 
      RegisterFinalizersAtInit オプションがセットされていれば,
      コンストラクタ (= <init> メソッド) 内の return 命令を 
      Bytecodes::_return_register_finalizer 命令(HotSpot 独自のバイトコード命令) に置き換える.

      (これは, 実行したオブジェクトを Finalizer に登録してからリターンするという命令)
      ---------------------------------------- -}

      if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) {
        bool did_rewrite = false;
        int i = _methods->length();
        while (i-- > 0) {
          methodOop method = (methodOop)_methods->obj_at(i);
          if (method->intrinsic_id() == vmIntrinsics::_Object_init) {
            // rewrite the return bytecodes of Object.<init> to register the
            // object for finalization if needed.
            methodHandle m(THREAD, method);
            rewrite_Object_init(m, CHECK);
            did_rewrite = true;
            break;
          }
        }
        assert(did_rewrite, "must find Object::<init> to rewrite it");
      }

  {- -------------------------------------------
  (1) 処理対象クラスの全てのメソッドに対して 
      Rewriter::scan_method() を呼び出し, 
      バイトコードの書き換え処理を行う.
      ---------------------------------------- -}

      // rewrite methods, in two passes
      int len = _methods->length();

      for (int i = len-1; i >= 0; i--) {
        methodOop method = (methodOop)_methods->obj_at(i);
        scan_method(method);
      }

  {- -------------------------------------------
  (1) Rewriter::make_constant_pool_cache() を呼んで, 
      以上の処理で収集した constant pool cache index の情報を元に
      constant pool cache を生成する.
      ---------------------------------------- -}

      // allocate constant pool cache, now that we've seen all the bytecodes
      make_constant_pool_cache(THREAD);

  {- -------------------------------------------
  (1) 処理中に例外が発生していた場合は (= rewrite 処理が何らかの理由で失敗していた場合は)
      Rewriter::restore_bytecodes() でバイトコードを元に戻す.
      ---------------------------------------- -}

      // Restore bytecodes to their unrewritten state if there are exceptions
      // rewriting bytecodes or allocating the cpCache
      if (HAS_PENDING_EXCEPTION) {
        restore_bytecodes();
        return;
      }
    }

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