/* * 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 = ¤t(); 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(¤t); 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); } }