Top


定義場所(file name)

hotspot/src/share/vm/utilities/exceptions.cpp

説明(description)

// Creates an exception oop, calls the <init> method with the given signature.
// and returns a Handle
// Initializes the cause if cause non-null

名前(function name)

Handle Exceptions::new_exception(Thread *thread, Symbol* h_name,
                                 Symbol* signature,
                                 JavaCallArguments *args,
                                 Handle h_cause, Handle h_loader,
                                 Handle h_protection_domain) {

本体部(body)

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

      assert(Universe::is_fully_initialized(),
        "cannot be called during initialization");
      assert(thread->is_Java_thread(), "can only be called by a Java thread");
      assert(!thread->has_pending_exception(), "already has exception");

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      Handle h_exception;

  {- -------------------------------------------
  (1) 生成対象の例外クラスを SystemDictionary から取得.
      ---------------------------------------- -}

      // Resolve exception klass
      klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread);
      instanceKlassHandle klass (thread, ik);

  {- -------------------------------------------
  (1) instanceKlass::allocate_instance_handle() で指定の例外オブジェクトを確保した後, 
      JavaCalls::call_special() 経由でコンストラクタ(<init> メソッド)を呼び出して初期化を行う.

      (さらに, 引数の h_cause が空でなければ, 
       java.lang.Throwable.initCause() も呼び出して cause の設定も行っている)

      (ただし, 既に例外が発生している場合(= has_pending_exception() が true の場合), 
       あるいは以上の処理の途中で例外が発生した場合については, 
       そこで処理を打ち切ってそれ以上の処理は行わない)
      ---------------------------------------- -}

      if (!thread->has_pending_exception()) {
        assert(klass.not_null(), "klass must exist");
        // We are about to create an instance - so make sure that klass is initialized
        klass->initialize(thread);
        if (!thread->has_pending_exception()) {
          // Allocate new exception
          h_exception = klass->allocate_instance_handle(thread);
          if (!thread->has_pending_exception()) {
            JavaValue result(T_VOID);
            args->set_receiver(h_exception);
            // Call constructor
            JavaCalls::call_special(&result, klass,
                                             vmSymbols::object_initializer_name(),
                                             signature,
                                             args,
                                             thread);

          }
        }

        // Future: object initializer should take a cause argument
        if (h_cause() != NULL) {
          assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
              "exception cause is not a subclass of java/lang/Throwable");
          JavaValue result1(T_OBJECT);
          JavaCallArguments args1;
          args1.set_receiver(h_exception);
          args1.push_oop(h_cause);
          JavaCalls::call_virtual(&result1, klass,
                                         vmSymbols::initCause_name(),
                                         vmSymbols::throwable_throwable_signature(),
                                         &args1,
                                         thread);
        }
      }

  {- -------------------------------------------
  (1) もし, 以上の生成&初期化処理で何か例外が発生していた場合, そちらの方を優先する.
      (返値として, 生成&初期化処理で発生した例外の方を返すことにする)
      ---------------------------------------- -}

      // Check if another exception was thrown in the process, if so rethrow that one
      if (thread->has_pending_exception()) {
        h_exception = Handle(thread, thread->pending_exception());
        thread->clear_pending_exception();
      }

  {- -------------------------------------------
  (1) 結果をリターン
      ---------------------------------------- -}

      return h_exception;
    }

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