Index: vm/include/open/rt_helpers.h =================================================================== --- vm/include/open/rt_helpers.h (revision 637959) +++ vm/include/open/rt_helpers.h (working copy) @@ -127,62 +127,9 @@ */ VM_RT_THROW_LAZY=201, -/** - * @param The parameters are the following: - * \arg Method handle - * \arg ... - * \arg arg 2 - * \arg arg 1 - * \arg Class handle - * - * @return None. - * - * The arguments to the constructor are pushed the same way they would have - * been pushed to invoke the constructor, except that the (non-existing) - * this pointer is replaced with the class handle of the exception. - * The method handle representing the constructor is pushed last. - * - * This function never returns. - */ - - VM_RT_IDX_OUT_OF_BOUNDS=202, /** * @param none - * - * @return None. - * - * Throw the java/lang/ArrayIndexOutOfBoundsException. - * - * This function never returns. - */ - VM_RT_NULL_PTR_EXCEPTION=203, - -/** - * @param none - * - * @return None. - * - * Throw the java/lang/NullPointerException - * - * This function never returns. - */ - VM_RT_DIVIDE_BY_ZERO_EXCEPTION=204, - -/** - * @param none - * - * @return None. - * - * Throw the java/lang/ArithmeticException. - * - * This function never returns. - */ - - VM_RT_ARRAY_STORE_EXCEPTION=205, - -/** - * @param none * * @return None. * Index: vm/vmcore/include/exceptions_jit.h =================================================================== --- vm/vmcore/include/exceptions_jit.h (revision 637959) +++ vm/vmcore/include/exceptions_jit.h (working copy) @@ -79,7 +79,7 @@ NativeCodePtr exn_get_rth_throw_array_store(); // rth_throw_arithmetic throws an arithmetic exception (lazily) -NativeCodePtr exn_get_rth_throw_arithmetic(); +//NativeCodePtr exn_get_rth_throw_arithmetic(); // rth_throw_class_cast_exception throws a class cast exception (lazily) NativeCodePtr exn_get_rth_throw_class_cast_exception(); Index: vm/vmcore/src/jit/rt_helper_info.cpp =================================================================== --- vm/vmcore/src/jit/rt_helper_info.cpp (revision 637959) +++ vm/vmcore/src/jit/rt_helper_info.cpp (working copy) @@ -62,18 +62,6 @@ {VM_RT_THROW_LAZY, "VM_RT_THROW_LAZY", INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_DRL, 8, NULL, NULL, NULL, NULL}, - {VM_RT_IDX_OUT_OF_BOUNDS, "VM_RT_IDX_OUT_OF_BOUNDS", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, - NULL, NULL, NULL, NULL}, - {VM_RT_NULL_PTR_EXCEPTION, "VM_RT_NULL_PTR_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, - NULL, NULL, NULL, NULL}, - {VM_RT_DIVIDE_BY_ZERO_EXCEPTION, "VM_RT_DIVIDE_BY_ZERO_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, - NULL, NULL, NULL, NULL}, - {VM_RT_ARRAY_STORE_EXCEPTION, "VM_RT_ARRAY_STORE_EXCEPTION", - INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, - NULL, NULL, NULL, NULL}, {VM_RT_THROW_LINKING_EXCEPTION, "VM_RT_THROW_LINKING_EXCEPTION", INTERRUPTIBLE_ALWAYS, CALLING_CONVENTION_STDCALL, 0, NULL, NULL, NULL, NULL}, Index: vm/vmcore/src/jit/jit_runtime_support.cpp =================================================================== --- vm/vmcore/src/jit/jit_runtime_support.cpp (revision 637959) +++ vm/vmcore/src/jit/jit_runtime_support.cpp (working copy) @@ -1968,14 +1968,6 @@ return rth_wrap_exn_throw(dyn_count, "rth_throw", exn_get_rth_throw()); case VM_RT_THROW_LAZY: return rth_wrap_exn_throw(dyn_count, "rth_throw_lazy", exn_get_rth_throw_lazy()); - case VM_RT_IDX_OUT_OF_BOUNDS: - return rth_wrap_exn_throw(dyn_count, "rth_throw_index_out_of_bounds", exn_get_rth_throw_array_index_out_of_bounds()); - case VM_RT_NULL_PTR_EXCEPTION: - return rth_wrap_exn_throw(dyn_count, "rth_throw_null_pointer", exn_get_rth_throw_null_pointer()); - case VM_RT_DIVIDE_BY_ZERO_EXCEPTION: - return rth_wrap_exn_throw(dyn_count, "rth_throw_arithmetic", exn_get_rth_throw_arithmetic()); - case VM_RT_ARRAY_STORE_EXCEPTION: - return rth_wrap_exn_throw(dyn_count, "rth_throw_array_store", exn_get_rth_throw_array_store()); case VM_RT_THROW_LINKING_EXCEPTION: return rth_get_lil_throw_linking_exception(dyn_count); // Type tests @@ -2096,34 +2088,22 @@ assert(!hythread_is_suspend_enabled()); assert(struct_Class_to_java_lang_Class(c)); + class_initialize(c); ManagedObject* obj = c->allocate_instance(); if(!obj) { exn_raise_object( VM_Global_State::loader_env->java_lang_OutOfMemoryError); return NULL; // whether this return is reached or not is solved via is_unwindable state } - return obj; + return obj; } // class_alloc_new_object ManagedObject *class_alloc_new_object_using_vtable(VTable *vtable) { ASSERT_RAISE_AREA; assert(!hythread_is_suspend_enabled()); - assert(struct_Class_to_java_lang_Class(vtable->clss)); -#ifdef VM_STATS - VM_Statistics::get_vm_stats().num_class_alloc_new_object++; - vtable->clss->instance_allocated(vtable->allocated_size); -#endif //VM_STATS - // From vm_types.h: this is the same as instance_data_size with the constraint bit cleared. - ManagedObject* o = (ManagedObject*) vm_alloc_and_report_ti( - vtable->allocated_size, vtable->clss->get_allocation_handle(), - vm_get_gc_thread_local(), vtable->clss); - if (!o) { - exn_raise_object( - VM_Global_State::loader_env->java_lang_OutOfMemoryError); - return NULL; // reached by interpreter and from JNI - } - return o; + assert(struct_Class_to_java_lang_Class(vtable->clss)); + return class_alloc_new_object(vtable->clss); } //class_alloc_new_object_using_vtable ManagedObject* class_alloc_new_object_and_run_default_constructor(Class* clss) @@ -2141,10 +2121,8 @@ assert(struct_Class_to_java_lang_Class(clss)); ObjectHandle obj = oh_allocate_local_handle(); - obj->object = clss->allocate_instance(); + obj->object = class_alloc_new_object(clss); if(!obj->object) { - exn_raise_object( - VM_Global_State::loader_env->java_lang_OutOfMemoryError); return NULL; } @@ -2208,6 +2186,11 @@ } break; default: + fprintf(stderr, "arg_num = %d, class = %p, constructor = %p", + arg_num, clss, constructor); + fprintf(stderr, "%s.%s%s \n", + clss->get_name()->bytes, constructor->get_name()->bytes, constructor->get_descriptor()->bytes); + fflush(stderr); ABORT("Unexpected java type"); break; } Index: vm/vmcore/src/exception/exceptions_jit.cpp =================================================================== --- vm/vmcore/src/exception/exceptions_jit.cpp (revision 637959) +++ vm/vmcore/src/exception/exceptions_jit.cpp (working copy) @@ -784,7 +784,11 @@ ABORT("Lazy exceptions are not supported on this platform"); #else uint8 *args = (uint8 *) (m2n_get_args(m2n_get_last_frame()) + 1); // +1 to skip constructor - args += exn_constr->get_num_arg_slots() * 4 - 4; + if (NULL != exn_constr) { + args += exn_constr->get_num_arg_slots() * 4 - 4; + } else { + args += 1*4 /*default constructor*/ - 4; + } exn_athrow(NULL, *(Class_Handle *) args, exn_constr, args); #endif } //rth_throw_lazy @@ -1084,29 +1088,29 @@ // rth_throw_arithmetic throws an arithmetic exception (lazily) -NativeCodePtr exn_get_rth_throw_arithmetic() -{ - static NativeCodePtr addr = NULL; - if (addr) { - return addr; - } +//NativeCodePtr exn_get_rth_throw_arithmetic() +//{ +// static NativeCodePtr addr = NULL; +// if (addr) { +// return addr; +// } +// +// Global_Env *env = VM_Global_State::loader_env; +// LilCodeStub *cs = lil_parse_code_stub("entry 0:stdcall::void;" +// "std_places 1;" "sp0=%0i;" "tailcall %1i;", +// env->java_lang_ArithmeticException_Class, +// lil_npc_to_fp(exn_get_rth_throw_lazy_trampoline())); +// assert(lil_is_valid(cs)); +// addr = LilCodeGenerator::get_platform()->compile(cs); +// +// DUMP_STUB(addr, "rth_throw_arithmetic", lil_cs_get_code_size(cs)); +// +// lil_free_code_stub(cs); +// +// return addr; +//} //exn_get_rth_throw_arithmetic - Global_Env *env = VM_Global_State::loader_env; - LilCodeStub *cs = lil_parse_code_stub("entry 0:stdcall::void;" - "std_places 1;" "sp0=%0i;" "tailcall %1i;", - env->java_lang_ArithmeticException_Class, - lil_npc_to_fp(exn_get_rth_throw_lazy_trampoline())); - assert(lil_is_valid(cs)); - addr = LilCodeGenerator::get_platform()->compile(cs); - DUMP_STUB(addr, "rth_throw_arithmetic", lil_cs_get_code_size(cs)); - - lil_free_code_stub(cs); - - return addr; -} //exn_get_rth_throw_arithmetic - - // Return the type of class cast exception Class_Handle exn_get_class_cast_exception_type() { Index: vm/vmcore/src/class_support/Initialize.cpp =================================================================== --- vm/vmcore/src/class_support/Initialize.cpp (revision 637959) +++ vm/vmcore/src/class_support/Initialize.cpp (working copy) @@ -226,16 +226,16 @@ ASSERT_RAISE_AREA; assert(!hythread_is_suspend_enabled()); - // check verifier constraints - tmn_suspend_enable(); - if(!clss->verify_constraints(VM_Global_State::loader_env)) { - assert(exn_raised()); + if(class_needs_initialization(clss)) { + // check verifier constraints + tmn_suspend_enable(); + if(!clss->verify_constraints(VM_Global_State::loader_env)) { + assert(exn_raised()); + tmn_suspend_disable(); + return; + } tmn_suspend_disable(); - return; - } - tmn_suspend_disable(); - if(class_needs_initialization(clss)) { clss->initialize(); } } // class_initialize_ex Index: vm/vmcore/src/class_support/Class.cpp =================================================================== --- vm/vmcore/src/class_support/Class.cpp (revision 637959) +++ vm/vmcore/src/class_support/Class.cpp (working copy) @@ -475,6 +475,7 @@ ManagedObject* Class::allocate_instance() { assert(!hythread_is_suspend_enabled()); + //assert(is_initialized()); ManagedObject* new_instance = (ManagedObject*)vm_alloc_and_report_ti(m_instance_data_size, m_allocation_handle, vm_get_gc_thread_local(), this); Index: vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp (revision 637959) +++ vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp (working copy) @@ -1027,14 +1027,6 @@ if (res) return res; switch(f) { - case VM_RT_NULL_PTR_EXCEPTION: - return exn_get_rth_throw_null_pointer(); - case VM_RT_IDX_OUT_OF_BOUNDS: - return exn_get_rth_throw_array_index_out_of_bounds(); - case VM_RT_ARRAY_STORE_EXCEPTION: - return exn_get_rth_throw_array_store(); - case VM_RT_DIVIDE_BY_ZERO_EXCEPTION: - return exn_get_rth_throw_arithmetic(); case VM_RT_THROW: case VM_RT_THROW_SET_STACK_TRACE: return exn_get_rth_throw(); Index: vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp =================================================================== --- vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp (revision 637959) +++ vm/vmcore/src/util/ipf/base/exceptions_ipf.cpp (working copy) @@ -146,36 +146,6 @@ return stub; } //gen_vm_rt_exception_throw - - -void *get_vm_rt_idx_out_of_bounds_address() -{ - static void *addr = 0; - if(addr) { - return addr; - } - Class * exc_clss = VM_Global_State::loader_env->java_lang_ArrayIndexOutOfBoundsException_Class; - - addr = gen_vm_rt_exception_throw(exc_clss, "rt_idx_out_of_bounds"); - return addr; -} //get_vm_rt_idx_out_of_bounds_address - - - -void *get_vm_rt_array_store_exception_address() -{ - static void *addr = 0; - if(addr) { - return addr; - } - - addr = gen_vm_rt_exception_throw(VM_Global_State::loader_env->java_lang_ArrayStoreException_Class, "rt_array_store_exception"); - - return addr; -} //get_vm_rt_array_store_exception_address - - - void *get_vm_rt_null_ptr_exception_address() { static void *addr = 0; @@ -188,17 +158,3 @@ return addr; } //get_vm_rt_null_ptr_exception_address - - - -void *get_vm_rt_divide_by_zero_exception_address() -{ - static void *addr = 0; - if(addr) { - return addr; - } - Class * exc_clss = VM_Global_State::loader_env->java_lang_ArithmeticException_Class; - - addr = gen_vm_rt_exception_throw(exc_clss, "rt_divide_by_zero_exception"); - return addr; -} //get_vm_rt_divide_by_zero_exception_address Index: vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp =================================================================== --- vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp (revision 637959) +++ vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp (working copy) @@ -95,10 +95,7 @@ void *gen_vm_rt_exception_throw(Class *exc, char *stub_name); void gen_vm_rt_athrow_internal_compactor(Merced_Code_Emitter &emitter); void *get_vm_rt_athrow_naked_compactor(); -void *get_vm_rt_idx_out_of_bounds_address(); -void *get_vm_rt_array_store_exception_address(); void *get_vm_rt_null_ptr_exception_address(); -void *get_vm_rt_divide_by_zero_exception_address(); ///////// end exceptions @@ -2567,22 +2564,6 @@ fptr = get_aastore_test_compactor(); dereference_fptr = false; break; - case VM_RT_IDX_OUT_OF_BOUNDS: - fptr = get_vm_rt_idx_out_of_bounds_address(); - dereference_fptr = false; - break; - case VM_RT_ARRAY_STORE_EXCEPTION: - fptr = get_vm_rt_array_store_exception_address(); - dereference_fptr = false; - break; - case VM_RT_NULL_PTR_EXCEPTION: - fptr = get_vm_rt_null_ptr_exception_address(); - dereference_fptr = false; - break; - case VM_RT_DIVIDE_BY_ZERO_EXCEPTION: - fptr = get_vm_rt_divide_by_zero_exception_address(); - dereference_fptr = false; - break; case VM_RT_THROW: case VM_RT_THROW_SET_STACK_TRACE: fptr = get_vm_rt_athrow_naked_compactor(); Index: vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (revision 637959) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (working copy) @@ -1898,14 +1898,16 @@ Node* dispatchNode= dispatchEdge->getTargetNode(); if ((dispatchNode!=fg->getUnwindNode()) ||(checkOpnds[opnd] == (POINTER_SIZE_INT)-1 #ifdef _EM64T_ - ||!Type::isCompressedReference(opnd->getType()->tag) + ||!Type::isCompressedReference(opnd->getType()->tag) #endif - )){ + )){ Node* throwBasicBlock = fg->createBlockNode(); - Inst* throwInst = newRuntimeHelperCallInst(VM_RT_NULL_PTR_EXCEPTION, 0, NULL, NULL); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); assert(lastInst->getBCOffset()!=ILLEGAL_BC_MAPPING_VALUE); - throwInst->setBCOffset(lastInst->getBCOffset()); - throwBasicBlock->appendInst(throwInst); + throwException(excType, lastInst->getBCOffset(), throwBasicBlock); + //Inst* throwInst = newRuntimeHelperCallInst(VM_RT_NULL_PTR_EXCEPTION, 0, NULL, NULL); + //throwInst->setBCOffset(lastInst->getBCOffset()); + //throwBasicBlock->appendInst(throwInst); int64 zero = 0; if( refsCompressed && opnd->getType()->isReference() ) { assert(!Type::isCompressedReference(opnd->getType()->tag)); @@ -1946,6 +1948,61 @@ lastInst->unlink(); } } +void IRManager::throwException(ObjectType* excType, uint16 bcOffset, Node* basicBlock){ + + assert(excType); + +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif + Inst* throwInst = NULL; + assert(bcOffset!=ILLEGAL_BC_MAPPING_VALUE); + + if (lazy){ + Opnd * helperOpnds[] = { + // first parameter exception class + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getIntPtrType()), + Opnd::RuntimeInfo::Kind_TypeRuntimeId, excType), + // second is constructor method handle, 0 - means default constructor + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getIntPtrType()), 0) + }; + throwInst=newRuntimeHelperCallInst( + VM_RT_THROW_LAZY, lengthof(helperOpnds), helperOpnds, NULL); + } else { + Opnd * helperOpnds1[] = { + newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_Size, excType), + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getIntPtrType()), + Opnd::RuntimeInfo::Kind_AllocationHandle, excType) + }; + Opnd * retOpnd=newOpnd(excType); + CallInst * callInst=newRuntimeHelperCallInst( + VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, + lengthof(helperOpnds1), helperOpnds1, retOpnd); + + callInst->setBCOffset(bcOffset); + basicBlock->appendInst(callInst); + + MethodDesc* md = compilationInterface.resolveMethod( excType, + DEFAUlT_COSTRUCTOR_NAME, DEFAUlT_COSTRUCTOR_DESCRIPTOR); + + Opnd * target = newImmOpnd(typeManager.getIntPtrType(), Opnd::RuntimeInfo::Kind_MethodDirectAddr, md); + Opnd * helperOpnds2[] = { (Opnd*)retOpnd }; + callInst=newCallInst(target, getDefaultManagedCallingConvention(), + lengthof(helperOpnds2), helperOpnds2, NULL); + callInst->setBCOffset(bcOffset); + basicBlock->appendInst(callInst); + + Opnd * helperOpnds3[] = { (Opnd*)retOpnd }; + throwInst=newRuntimeHelperCallInst( + VM_RT_THROW, + lengthof(helperOpnds3), helperOpnds3, NULL); + } + throwInst->setBCOffset(bcOffset); + basicBlock->appendInst(throwInst); +} + //_____________________________________________________________________________________________ void IRManager::translateToNativeForm() { Index: vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (revision 637959) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (working copy) @@ -375,6 +375,9 @@ /** expands SystemExceptionCheckPseudoInst */ void expandSystemExceptions(uint32 reservedForFlags); + /** generater code to throw noted type exception, set for code BC offset and include into basic block*/ + void throwException(ObjectType* excType, uint16 bcOffset, Node* basicBlock); + /** changes all Extended insts to Native form by calling makeInstNative */ void translateToNativeForm(); Index: vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (revision 637959) +++ vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (working copy) @@ -1437,29 +1437,79 @@ void InstCodeSelector::throwSystemException(CompilationInterface::SystemExceptionId id) { +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif + CallInst * callInst = NULL; + ObjectType* excType = NULL; - CallInst * callInst=NULL; switch (id) { case CompilationInterface::Exception_NullPointer: - callInst=irManager.newRuntimeHelperCallInst( - VM_RT_NULL_PTR_EXCEPTION, 0, NULL, NULL); + { + excType = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); + //callInst=irManager.newRuntimeHelperCallInst( + // VM_RT_NULL_PTR_EXCEPTION, 0, NULL, NULL); + }; break; case CompilationInterface::Exception_ArrayIndexOutOfBounds: - callInst=irManager.newRuntimeHelperCallInst( - VM_RT_IDX_OUT_OF_BOUNDS, 0, NULL, NULL); + excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + //callInst=irManager.newRuntimeHelperCallInst( + // VM_RT_IDX_OUT_OF_BOUNDS, 0, NULL, NULL); break; case CompilationInterface::Exception_ArrayTypeMismatch: - callInst=irManager.newRuntimeHelperCallInst( - VM_RT_ARRAY_STORE_EXCEPTION, 0, NULL, NULL); + excType = compilationInterface.findClassUsingBootstrapClassloader(ARRAY_STORE_EXCEPTION); + //callInst=irManager.newRuntimeHelperCallInst( + // VM_RT_ARRAY_STORE_EXCEPTION, 0, NULL, NULL); break; case CompilationInterface::Exception_DivideByZero: - callInst=irManager.newRuntimeHelperCallInst( - VM_RT_DIVIDE_BY_ZERO_EXCEPTION, 0, NULL, NULL); + excType = compilationInterface.findClassUsingBootstrapClassloader(DIVIDE_BY_ZERO_EXCEPTION); + //callInst=irManager.newRuntimeHelperCallInst( + // VM_RT_DIVIDE_BY_ZERO_EXCEPTION, 0, NULL, NULL); break; default: assert(0); } - appendInsts(callInst); + + assert(excType); + + if (lazy){ + Opnd * helperOpnds[] = { + // first parameter exception class + irManager.newImmOpnd(getRuntimeIdType(), Opnd::RuntimeInfo::Kind_TypeRuntimeId, excType), + // second is constructor method handle, 0 - means default constructor + irManager.newImmOpnd(getRuntimeIdType(), 0) + }; + callInst=irManager.newRuntimeHelperCallInst( + VM_RT_THROW_LAZY, lengthof(helperOpnds), helperOpnds, NULL); + appendInsts(callInst); + } else { + Opnd * helperOpnds1[] = { + irManager.newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_Size, excType), + irManager.newImmOpnd(getRuntimeIdType(), Opnd::RuntimeInfo::Kind_AllocationHandle, excType) + }; + Opnd * retOpnd=irManager.newOpnd(excType); + callInst=irManager.newRuntimeHelperCallInst( + VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, + lengthof(helperOpnds1), helperOpnds1, retOpnd); + appendInsts(callInst); + + MethodDesc* md = compilationInterface.resolveMethod( excType, + DEFAUlT_COSTRUCTOR_NAME, DEFAUlT_COSTRUCTOR_DESCRIPTOR); + + Opnd * target=irManager.newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_MethodDirectAddr, md); + Opnd * helperOpnds2[] = { (Opnd*)retOpnd }; + callInst=irManager.newCallInst(target, irManager.getDefaultManagedCallingConvention(), + lengthof(helperOpnds2), helperOpnds2, NULL); + appendInsts(callInst); + + Opnd * helperOpnds3[] = { (Opnd*)retOpnd }; + callInst=irManager.newRuntimeHelperCallInst( + VM_RT_THROW, + lengthof(helperOpnds3), helperOpnds3, NULL); + appendInsts(callInst); + } } //_______________________________________________________________________________________________________________ @@ -1571,11 +1621,14 @@ cmpType = CompareOp::I; Node* throwBasicBlock = irManager.getFlowGraph()->createBlockNode(); - Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_IDX_OUT_OF_BOUNDS, 0, NULL, NULL); - throwInst->setBCOffset(currentHIRInstBCOffset); - throwBasicBlock->appendInst(throwInst); - + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + irManager.throwException(excType, currentHIRInstBCOffset, throwBasicBlock); + + //Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_IDX_OUT_OF_BOUNDS, 0, NULL, NULL); + //throwInst->setBCOffset(currentHIRInstBCOffset); + //throwBasicBlock->appendInst(throwInst); + branch(CompareOp::Geu, cmpType, (Opnd*)index, (Opnd*)arrayLen); codeSelector.genTrueEdge(currentBasicBlock, throwBasicBlock, 0); return getTauUnsafe(); @@ -1605,11 +1658,13 @@ cmpOp = CompareOp::Gtu; } Node* throwBasicBlock = irManager.getFlowGraph()->createBlockNode(); - Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_IDX_OUT_OF_BOUNDS, 0, NULL, NULL); - throwInst->setBCOffset(currentHIRInstBCOffset); - throwBasicBlock->appendInst(throwInst); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + irManager.throwException(excType, currentHIRInstBCOffset, throwBasicBlock); - + //Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_IDX_OUT_OF_BOUNDS, 0, NULL, NULL); + //throwInst->setBCOffset(currentHIRInstBCOffset); + //throwBasicBlock->appendInst(throwInst); + branch(cmpOp, cmpType, (Opnd*)a, (Opnd*)b); codeSelector.genTrueEdge(currentBasicBlock, throwBasicBlock, 0); return getTauUnsafe(); @@ -1635,10 +1690,12 @@ CG_OpndHandle* tauIsArray) { Node* throwBasicBlock = irManager.getFlowGraph()->createBlockNode(); - Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_ARRAY_STORE_EXCEPTION, 0, NULL, NULL); assert(currentHIRInstBCOffset!=ILLEGAL_BC_MAPPING_VALUE); - throwInst->setBCOffset(currentHIRInstBCOffset); - throwBasicBlock->appendInst(throwInst); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(ARRAY_STORE_EXCEPTION); + irManager.throwException(excType, currentHIRInstBCOffset, throwBasicBlock); + //Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_ARRAY_STORE_EXCEPTION, 0, NULL, NULL); + //throwInst->setBCOffset(currentHIRInstBCOffset); + //throwBasicBlock->appendInst(throwInst); Opnd * args[] = { (Opnd*)src, (Opnd*)array }; Opnd * flag = irManager.newOpnd(typeManager.getInt32Type()); @@ -1659,10 +1716,12 @@ CG_OpndHandle* InstCodeSelector::tau_checkZero(CG_OpndHandle* src) { Node* throwBasicBlock = irManager.getFlowGraph()->createBlockNode(); - Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_DIVIDE_BY_ZERO_EXCEPTION, 0, NULL, NULL); assert(currentHIRInstBCOffset!=ILLEGAL_BC_MAPPING_VALUE); - throwInst->setBCOffset(currentHIRInstBCOffset); - throwBasicBlock->appendInst(throwInst); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(DIVIDE_BY_ZERO_EXCEPTION); + irManager.throwException(excType, currentHIRInstBCOffset, throwBasicBlock); + //Inst* throwInst = irManager.newRuntimeHelperCallInst(VM_RT_DIVIDE_BY_ZERO_EXCEPTION, 0, NULL, NULL); + //throwInst->setBCOffset(currentHIRInstBCOffset); + //throwBasicBlock->appendInst(throwInst); Opnd * srcOpnd = (Opnd*)src; Type * type = srcOpnd->getType(); CompareZeroOp::Types opType = CompareZeroOp::I; Index: vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h (revision 637959) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h (working copy) @@ -184,6 +184,7 @@ //---------------------------------------------------------------------------// void throwException(CG_OpndHandle*, bool); + void throwException(ObjectType* excType);// generater code to throw noted type exception void throwSystemException(CompilationInterface::SystemExceptionId); void throwLinkingException(Class_Handle, uint32, uint32); CG_OpndHandle *catchException(Type*); Index: vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp (revision 637959) +++ vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp (working copy) @@ -1381,26 +1381,63 @@ IPF_LOG << " throwSystemException" << endl; - VM_RT_SUPPORT hId = VM_RT_UNKNOWN; + //VM_RT_SUPPORT hId = VM_RT_UNKNOWN; + ObjectType* excType = NULL; switch (id) { case CompilationInterface::Exception_NullPointer: - hId = VM_RT_NULL_PTR_EXCEPTION; break; + excType = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); + //hId = VM_RT_NULL_PTR_EXCEPTION; + break; case CompilationInterface::Exception_ArrayIndexOutOfBounds: - hId = VM_RT_IDX_OUT_OF_BOUNDS; break; + excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + //hId = VM_RT_IDX_OUT_OF_BOUNDS; + break; case CompilationInterface::Exception_ArrayTypeMismatch: - hId = VM_RT_ARRAY_STORE_EXCEPTION; break; + excType = compilationInterface.findClassUsingBootstrapClassloader(ARRAY_STORE_EXCEPTION); + //hId = VM_RT_ARRAY_STORE_EXCEPTION; + break; case CompilationInterface::Exception_DivideByZero: - hId = VM_RT_DIVIDE_BY_ZERO_EXCEPTION; break; + excType = compilationInterface.findClassUsingBootstrapClassloader(DIVIDE_BY_ZERO_EXCEPTION); + //hId = VM_RT_DIVIDE_BY_ZERO_EXCEPTION; + break; default: IPF_ERR << "unexpected id " << id << endl; } - uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress = opndManager->newImm(address); + throwException(excType); +} - directCall(0, NULL, NULL, helperAddress, p0); +void IpfInstCodeSelector::throwException(ObjectType* excType) +{ + assert(excType); + + Opnd *helperOpnds1[] = { + opndManager->newImm((int64) excType->getObjectSize()), + opndManager->newImm((int64) excType->getAllocationHandle()) + }; + + VM_RT_SUPPORT hId = VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE; + uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + Opnd* helperAddress = opndManager->newImm(address); + OpndKind opndKind = toOpndKind(excType->tag); + DataKind dataKind = toDataKind(excType->tag); + RegOpnd* retOpnd = opndManager->newRegOpnd(opndKind, dataKind); + + directCall(2, helperOpnds1, retOpnd, helperAddress, p0); + + Opnd * helperOpnds2[] = { (Opnd*)retOpnd }; + MethodDesc* md = compilationInterface.resolveMethod( excType, + DEFAUlT_COSTRUCTOR_NAME, DEFAUlT_COSTRUCTOR_DESCRIPTOR); + call(1, (CG_OpndHandle **)helperOpnds2, NULL, md); + + Opnd * helperOpnds3[] = { (Opnd*)retOpnd }; + + hId = VM_RT_THROW; + address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + helperAddress = opndManager->newImm(address); + + directCall(1, helperOpnds3, NULL, helperAddress, p0); } - //----------------------------------------------------------------------------// // Throw linking exception @@ -1460,10 +1497,12 @@ cmp(CMPLT_CMP_CREL_EQ, truePred, p0, base, zero); // p2 brl.call b0 = helperAddress - VM_RT_SUPPORT hId = VM_RT_NULL_PTR_EXCEPTION; - uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); + throwException(excType); + //VM_RT_SUPPORT hId = VM_RT_NULL_PTR_EXCEPTION; + //uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + //Opnd *helperAddress = opndManager->newImm(address); + //directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau) } @@ -1481,10 +1520,12 @@ cmp(CMPLT_CMP_CREL_GE, truePred, p0, index, arrayLen); // p2 brl.call b0 = helperAddress - VM_RT_SUPPORT hId = VM_RT_IDX_OUT_OF_BOUNDS; - uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + throwException(excType); + //VM_RT_SUPPORT hId = VM_RT_IDX_OUT_OF_BOUNDS; + //uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + //Opnd *helperAddress = opndManager->newImm(address); + //directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1502,10 +1543,12 @@ cmp(CMPLT_CMP_CREL_GT, truePred, p0, a, b); // p2 brl.call b0 = helperAddress - VM_RT_SUPPORT hId = VM_RT_IDX_OUT_OF_BOUNDS; - uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + throwException(excType); + //VM_RT_SUPPORT hId = VM_RT_IDX_OUT_OF_BOUNDS; + //uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + //Opnd *helperAddress = opndManager->newImm(address); + //directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1523,10 +1566,12 @@ cmp(CMPLT_CMP_CREL_GEU, truePred, p0, a, b); // p2 brl.call b0 = helperAddress - VM_RT_SUPPORT hId = VM_RT_IDX_OUT_OF_BOUNDS; - uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(INDEX_OUT_OF_BOUNDS); + throwException(excType); + //VM_RT_SUPPORT hId = VM_RT_IDX_OUT_OF_BOUNDS; + //uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + //Opnd *helperAddress = opndManager->newImm(address); + //directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1563,10 +1608,12 @@ cmp(CMPLT_CMP_CREL_EQ, truePred, p0, retOpnd, r0); // p3 brl.call b0, Helper_ElemTypeException - hId = VM_RT_ARRAY_STORE_EXCEPTION; - address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress2 = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress2, truePred, CMPLT_WH_DPNT); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(ARRAY_STORE_EXCEPTION); + throwException(excType); + //hId = VM_RT_ARRAY_STORE_EXCEPTION; + //address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + //Opnd *helperAddress2 = opndManager->newImm(address); + //directCall(0, NULL, NULL, helperAddress2, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1585,10 +1632,12 @@ cmp(CMPLT_CMP_CREL_EQ, truePred, p0, src, r0); // p2 brl.call b0 = helperAddress - VM_RT_SUPPORT hId = VM_RT_DIVIDE_BY_ZERO_EXCEPTION; - uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); - Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); + ObjectType* excType = compilationInterface.findClassUsingBootstrapClassloader(DIVIDE_BY_ZERO_EXCEPTION); + throwException(excType); + //VM_RT_SUPPORT hId = VM_RT_DIVIDE_BY_ZERO_EXCEPTION; + //uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + //Opnd *helperAddress = opndManager->newImm(address); + //directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau) } Index: vm/jitrino/src/jet/cg.h =================================================================== --- vm/jitrino/src/jet/cg.h (revision 637959) +++ vm/jitrino/src/jet/cg.h (working copy) @@ -493,6 +493,13 @@ */ void gen_dbg_rt(bool save_regs, const char * fmt, ...); + /** + * @brief Generates code to throw specified tipe of exception. + * + * The generated code which throws exception of soecified type. + * Also it can updates GC info and synchronizes both stack and local vars. + */ + void gen_throw(Class_Handle exnClass, bool restore); /** * The opcode may be one of AASTORE, PUTFIELD or PUTSTATIC. Index: vm/jitrino/src/jet/sconsts.h =================================================================== --- vm/jitrino/src/jet/sconsts.h (revision 637959) +++ vm/jitrino/src/jet/sconsts.h (working copy) @@ -48,10 +48,8 @@ class StaticConsts { public: static char * rt_helper_throw; - static char * rt_helper_throw_out_of_bounds; + static char * rt_helper_throw_lazy; static char * rt_helper_throw_linking_exc; - static char * rt_helper_throw_npe; - static char * rt_helper_throw_div_by_zero_exc; static char * rt_helper_new; static char * rt_helper_new_array; Index: vm/jitrino/src/jet/compiler.cpp =================================================================== --- vm/jitrino/src/jet/compiler.cpp (revision 637959) +++ vm/jitrino/src/jet/compiler.cpp (working copy) @@ -338,7 +338,7 @@ m_bc = (unsigned char*)method_get_byte_code_addr(m_method); unsigned bc_size = (unsigned)method_get_byte_code_size(m_method); unsigned num_locals = method_vars_get_number(m_method); - unsigned max_stack = method_get_max_stack(m_method); + unsigned max_stack = method_get_max_stack(m_method) + NATIVE_STACK_SIZE_2_THROW_SYN_EXC; // Input arguments ::std::vector inargs; @@ -1494,17 +1494,12 @@ rt_helper_get_vtable = (char*)vm_helper_get_addr(VM_RT_GET_INTERFACE_VTABLE_VER0); - rt_helper_throw_npe = - (char*)vm_helper_get_addr(VM_RT_NULL_PTR_EXCEPTION); - rt_helper_throw = (char*)vm_helper_get_addr(VM_RT_THROW); - rt_helper_throw_out_of_bounds = - (char*)vm_helper_get_addr(VM_RT_IDX_OUT_OF_BOUNDS); + rt_helper_throw_lazy = + (char*)vm_helper_get_addr(VM_RT_THROW_LAZY); rt_helper_throw_linking_exc = (char*)vm_helper_get_addr(VM_RT_THROW_LINKING_EXCEPTION); - rt_helper_throw_div_by_zero_exc = - (char*)vm_helper_get_addr(VM_RT_DIVIDE_BY_ZERO_EXCEPTION); rt_helper_checkcast = (char*)vm_helper_get_addr(VM_RT_CHECKCAST); Index: vm/jitrino/src/jet/cg.cpp =================================================================== --- vm/jitrino/src/jet/cg.cpp (revision 637959) +++ vm/jitrino/src/jet/cg.cpp (working copy) @@ -51,6 +51,7 @@ const CallSig ci_helper_o(CCONV_HELPERS, jvoid, jobj); const CallSig ci_helper_v(CCONV_HELPERS, jvoid); const CallSig ci_helper_oi(CCONV_HELPERS, jobj, jobj, i32); +const CallSig ci_helper_lazy(CCONV_MANAGED, jvoid, jobj, jobj); const CallSig ci_helper_linkerr(CCONV_HELPERS, jvoid, jobj, i32, i32); void CodeGen::do_mov(const Val& dst_s, const Val& src_s, bool skipTypeCheck) @@ -138,7 +139,10 @@ if (obj.is_imm()) { STATS_INC(Stats::npesEliminated,1); if (obj.pval() == NULL_REF) { - gen_call_throw(ci_helper_v, rt_helper_throw_npe, 0); + //gen_args(const CallSig& cs, unsigned idx, const Val * parg0 = NULL, + // const Val * parg1 = NULL, const Val * parg2 = NULL); + Class_Handle npeClass = class_lookup_class_by_name_using_bootstrap_class_loader(NULL_POINTER_EXCEPTION); + gen_throw(npeClass, false); } return; } @@ -232,7 +236,9 @@ } runlock(obj); unsigned br_off = br(ne, 0, 0, taken); - gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_npe, 0); + Class_Handle npeClass = class_lookup_class_by_name_using_bootstrap_class_loader(NULL_POINTER_EXCEPTION); + gen_throw(npeClass, true); + patch(br_off, ip()); } // if !useHW @@ -269,7 +275,9 @@ // Unsigned condition here - aka 'len > (unsigned)index' - this also // covers 'index < 0' - in a single comparation. unsigned br_off = br(above, 0, 0, taken); - gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_out_of_bounds, 0); + //gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_out_of_bounds, 0); + Class_Handle ioobClass = class_lookup_class_by_name_using_bootstrap_class_loader(INDEX_OUT_OF_BOUNDS); + gen_throw(ioobClass, true); patch(br_off, ip()); if (is_set(DBG_TRACE_CG)) {dbg(";;>~check.bounds\n");} } @@ -288,7 +296,9 @@ // if it's i32, then nothing to do more - throw exception ... if (jt == i32) { // IS zero. Why do people want to divide on zero explicitly?.. - gen_call_throw(ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + //gen_call_throw(ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + Class_Handle aeClass = class_lookup_class_by_name_using_bootstrap_class_loader(DIVIDE_BY_ZERO_EXCEPTION); + gen_throw(aeClass, false); if (is_set(DBG_TRACE_CG)) {dbg(";;>~check.div_by_zero\n");} return; } @@ -298,7 +308,9 @@ if (shi.is_imm() && shi.ival() == 0) { // ... yes, it's zero too - throw ... // Why do people want to divide on zero explicitly?.. - gen_call_throw(ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + //gen_call_throw(ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + Class_Handle aeClass = class_lookup_class_by_name_using_bootstrap_class_loader(DIVIDE_BY_ZERO_EXCEPTION); + gen_throw(aeClass, false); if (is_set(DBG_TRACE_CG)) {dbg(";;>~check.div_by_zero\n");} return; } @@ -315,7 +327,9 @@ if (s.is_imm() && jt == i64 && !is_big(i64)) { if (s.lval() == 0) { // IS zero. Why do people want to divide on zero explicitly?.. - gen_call_throw(ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + //gen_call_throw(ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + Class_Handle aeClass = class_lookup_class_by_name_using_bootstrap_class_loader(DIVIDE_BY_ZERO_EXCEPTION); + gen_throw(aeClass, false); } if (is_set(DBG_TRACE_CG)) {dbg(";;>~check.div_by_zero\n");} return; @@ -335,7 +349,9 @@ } if (jt == i32 || !is_big(jt)) { unsigned br_off = br(nz, 0, 0, taken); - gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + //gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + Class_Handle aeClass = class_lookup_class_by_name_using_bootstrap_class_loader(DIVIDE_BY_ZERO_EXCEPTION); + gen_throw(aeClass, true); patch(br_off, ip()); if (is_set(DBG_TRACE_CG)) {dbg(";;>~check.div_by_zero\n");} return; @@ -363,7 +379,9 @@ alu(alu_cmp, mem, Opnd(0)); } unsigned br_hi = br(nz, 0, 0, taken); - gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + //gen_call_vm_restore(true, ci_helper_v, rt_helper_throw_div_by_zero_exc, 0); + Class_Handle aeClass = class_lookup_class_by_name_using_bootstrap_class_loader(DIVIDE_BY_ZERO_EXCEPTION); + gen_throw(aeClass, true); patch(br_hi, ip()); if (!s.is_imm()) { // [1] --> connect to here @@ -707,4 +725,59 @@ // } +void CodeGen::gen_throw(Class_Handle exnClass, bool restore) +{ +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif + BBState saveBB; + + if (restore){ + saveBB = *m_bbstate; + for (unsigned i=0; i" +#define DEFAUlT_COSTRUCTOR_DESCRIPTOR "()V" + + namespace Jitrino { // external and forward declarations