// Note: Function runs from unwindable area before exception throwing // function can be safe point & should be called with disable recursion = 1 static ManagedObject *create_lazy_exception( Class_Handle exn_class, Method_Handle exn_constr, U_8 * exn_constr_args, jvalue* vm_exn_constr_args) { assert(!hythread_is_suspend_enabled()); bool unwindable = set_unwindable(false); ManagedObject* result; if (NULL == vm_exn_constr_args) { result = class_alloc_new_object_and_run_constructor( (Class*) exn_class, (Method*) exn_constr, exn_constr_args); } else { // exception is throwing, so suspend can be enabled safely tmn_suspend_enable(); jthrowable exc_object = create_exception( (Class*) exn_class, (Method*) exn_constr, vm_exn_constr_args); if (exc_object) { result = exc_object->object; } else { result = NULL; } tmn_suspend_disable(); } set_unwindable(unwindable); exn_rethrow_if_pending(); return result; } //create_object_lazily
void exn_throw_by_class_internal(Class* exc_class, const char* exc_message, jthrowable exc_cause) { BEGIN_RAISE_AREA; // functions can be invoked in suspend disabled and enabled state if (!hythread_is_suspend_enabled()) { // exception is throwing, so suspend can be enabled safely tmn_suspend_enable(); } assert(hythread_is_suspend_enabled()); #ifdef VM_LAZY_EXCEPTION //set_unwindable(false); jvalue args[3]; Method* exc_init = prepare_exc_creating( exc_class, args, exc_message, exc_cause); if (NULL == exc_init) { CTRACE(("%s", "exn_throw_by_class(),create exception and delegating to exn_throw_for_JIT()")); jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause); exn_rethrow_if_pending(); //set_unwindable(true); exn_throw_object_internal(exc_object); } else { CTRACE(("%s", "exn_throw_by_class(), lazy delegating to exn_throw_for_JIT()")); //set_unwindable(true); // no return, so enable isn't required tmn_suspend_disable(); exn_throw_for_JIT(NULL, exc_class, exc_init, NULL, args); //tmn_suspend_enable(); } #else jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause); exn_rethrow_if_pending(); exn_throw_object_internal(exc_object); #endif END_RAISE_AREA; }