Esempio n. 1
0
/*
 * void nativeStart(Object [] startupState)
 * where startupState contains the following:
 * String classname
 * String [] args
 * String [][] context
 *
 * Note: all objects passed in parameters belongs to the new isolate
 * and no copy are necessary. See comments in com.sun.cldc.isolate.Isolate.
 */
void Java_com_sun_cldc_isolate_Isolate_nativeStart(JVM_SINGLE_ARG_TRAPS) {
  Thread::Raw saved;
  bool has_exception = false;
  const int id = Task::allocate_task_id(JVM_SINGLE_ARG_CHECK);
  {
    UsingFastOops fast_oops;
    IsolateObj::Fast isolate = GET_PARAMETER_AS_OOP(0);
    ObjectHeap::set_task_memory_quota(id, isolate().memory_reserve(),
                                          isolate().memory_limit() JVM_CHECK);

    const int prev = ObjectHeap::on_task_switch( id );
    saved = Task::create_task(id, &isolate JVM_NO_CHECK);    
    ObjectHeap::on_task_switch( prev );
    
    if( saved.is_null() ) {
      ObjectHeap::reset_task_memory_usage(id);
      Task::cleanup_unstarted_task(id);
      isolate().terminate(-1 JVM_NO_CHECK_AT_BOTTOM);
      return;
    }
  }

  // save current thread pointer, no non-raw handles please!
  Thread::Raw current = Thread::current();
  Thread::set_current(&saved);
  {
    // handles ok now
    UsingFastOops fast_oops;
    Thread::Fast orig = &current();
    Thread::Fast t = &saved();
    // IMPL_NOTE: SHOULDN'T WE DO SOMETHING HERE IF THERE IS SOME EXCEPTION
    // RELATED TO STARTUP FAILURE (i.e., reclaim the task's id and
    // proceed to task termination cleanup, including sending of
    // isolate events)
    Task::start_task(&t JVM_NO_CHECK);
    has_exception = (CURRENT_HAS_PENDING_EXCEPTION != NULL);
    
    current = orig;  // GC may have happened. Reload.
    saved = t;       // GC may have happened. Reload.
  }

  // we set the current thread back to the original so that the C interpreter
  // will switch threads correctly.  The new thread/task is set to be the
  // next thread/task to run when switch_thread is called a few instructions
  // from now.
  Thread::set_current(&current);
  if (has_exception) {
    UsingFastOops fast_oops;
    // new isolate got an exception somewhere during start_task().  The isolate
    // may not be able to handle the exception since we don't know at which
    // point it got the exception. Some classes may not be initialized,
    // task mirrors may not be setup etc.  We just tear down the new isolate
    // and return an exception to the parent.
    Task::Fast task = Task::get_task(id);
    IsolateObj::Fast isolate = GET_PARAMETER_AS_OOP(0);
    Thread::Fast thrd = &saved();
    GUARANTEE(!task.is_null(), "Task should not be null at this point");
    task().set_status(Task::TASK_STOPPED);
    task().set_thread_count(0);
    isolate().terminate(-1 JVM_NO_CHECK);
    saved = thrd;       // GC may have happened. Reload.
  }
  if (has_exception) {
    // Convoluted dance here.  Child isolate failed to start
    // We check the type of exception
    //  if (exception == oome)
    //    throw oome to parent
    //  else if (exception == isolateresourceerror)
    //    throw IsolateResourceError to parent
    //  else
    //    throw java.lang.Error to parent
    // Make sure we don't have any handles to child objects before
    // calling Task::cleanup_terminated_task()
    //    
    UsingFastOops fast_oops;
    Thread::Fast thrd = &saved();
    JavaOop::Fast exception = thrd().noncurrent_pending_exception();
    String::Fast str;
    {
      ThreadObj::Raw thread_obj = thrd().thread_obj();
      // Mark thread as terminated even though it never really started
      if (!thread_obj.is_null()) {
        thread_obj().set_terminated();
      }
    }
    Scheduler::terminate(&thrd JVM_NO_CHECK);
    thrd.set_null();  // thrd handle has to be disposed here

    JavaOop::Fast new_exception = Universe::out_of_memory_error_instance();
    JavaClass::Fast exception_class = exception().blueprint();
    // oome class *must* be loaded in parent, how can it not be?
    InstanceClass::Fast oome_class =
      SystemDictionary::resolve(Symbols::java_lang_OutOfMemoryError(),
                               ErrorOnFailure JVM_NO_CHECK);
    InstanceClass::Fast ire_class =
      SystemDictionary::resolve(Symbols::com_sun_cldc_isolate_IsolateResourceError(),
                               ErrorOnFailure JVM_NO_CHECK);

    if( oome_class.not_null() && !oome_class.equals(&exception_class)
        && ire_class.not_null() ) {
      new_exception = Throw::allocate_exception(
        ire_class.equals(&exception_class) ? 
          Symbols::com_sun_cldc_isolate_IsolateResourceError() :
          Symbols::java_lang_Error(),
        &str JVM_NO_CHECK);
    }
    exception_class.set_null(); // cleared handles to child objects
    exception.set_null();       //
    Task::cleanup_terminated_task(id JVM_NO_CHECK);
    Thread::set_current_pending_exception(&new_exception);
  }
}