Index: build/custom/msvc_2005/vmcore/vmcore.vcproj =================================================================== --- build/custom/msvc_2005/vmcore/vmcore.vcproj (revision 637959) +++ build/custom/msvc_2005/vmcore/vmcore.vcproj (working copy) @@ -131,7 +131,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""$(ProjectDir)\..\..\..\..\vm\include";"$(ProjectDir)\..\..\..\..\vm\vmcore\include";"$(ProjectDir)\..\..\..\..\vm\vmcore\src\util\em64t\base_natives";"$(ProjectDir)\..\..\..\..\vm\vmcore\src\util\win\include";"$(ProjectDir)\..\..\..\..\vm\port\include";"$(ProjectDir)\..\..\..\..\vm\port\src\lil\em64t\pim\include";"$(ProjectDir)\..\..\..\..\vm\port\src\encoder\ia32_em64t";"$(ProjectDir)\..\..\..\win_em64t_msvc_$(ConfigurationName)\semis\extra\zlib\include";"$(ProjectDir)\..\..\..\win_em64t_msvc_$(ConfigurationName)\semis\extra\apr\include\apr-1";"$(ProjectDir)\..\..\..\..\..\working_classlib\deploy\include\icu4c"" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BUILDING_VM;GC_V4;USE_DLL_JIT;APR_DECLARE_STATIC;PLATFORM_NT;_WIN32_WINNT=0x0501;_EM64T_;POINTER64" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BUILDING_VM;GC_V4;USE_DLL_JIT;APR_DECLARE_STATIC;PLATFORM_NT;_WIN32_WINNT=0x0501;_EM64T_;POINTER64;_WIN64" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" 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 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,11 +1898,50 @@ 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); + Inst* throwInst = NULL; + ObjectType* encClass = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif + + if (lazy){ + printf("Lazy is compiled.\n"); + Opnd * helperOpnds[] = { + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getSingleType()), + Opnd::RuntimeInfo::Kind_TypeRuntimeId, encClass), + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getSingleType()), NULL), + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getSingleType()), NULL) + }; + throwInst=newRuntimeHelperCallInst( + VM_RT_THROW_LAZY, lengthof(helperOpnds), helperOpnds, NULL); + } else { + printf("Direct is compiled.\n"); + Opnd * helperOpnds1[] = { + newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_Size, encClass), + newImmOpnd(typeManager.getUnmanagedPtrType(typeManager.getSingleType()), + Opnd::RuntimeInfo::Kind_AllocationHandle, encClass) + }; + Opnd * retOpnd=newOpnd(encClass); + CallInst * callInst=newRuntimeHelperCallInst( + VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, + lengthof(helperOpnds1), helperOpnds1, retOpnd); + + assert(lastInst->getBCOffset()!=ILLEGAL_BC_MAPPING_VALUE); + callInst->setBCOffset(lastInst->getBCOffset()); + throwBasicBlock->appendInst(callInst); + + Opnd * helperOpnds2[] = { (Opnd*)retOpnd }; + throwInst=newRuntimeHelperCallInst( + VM_RT_THROW, + lengthof(helperOpnds2), helperOpnds2, NULL); + } + //Inst* throwInst = newRuntimeHelperCallInst(VM_RT_NULL_PTR_EXCEPTION, 0, NULL, NULL); assert(lastInst->getBCOffset()!=ILLEGAL_BC_MAPPING_VALUE); throwInst->setBCOffset(lastInst->getBCOffset()); throwBasicBlock->appendInst(throwInst); 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,69 @@ void InstCodeSelector::throwSystemException(CompilationInterface::SystemExceptionId id) { +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif + CallInst * callInst = NULL; + ObjectType* encClass = NULL; - CallInst * callInst=NULL; switch (id) { case CompilationInterface::Exception_NullPointer: - callInst=irManager.newRuntimeHelperCallInst( - VM_RT_NULL_PTR_EXCEPTION, 0, NULL, NULL); + { + encClass = 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); + encClass = 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); + encClass = 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); + encClass = compilationInterface.findClassUsingBootstrapClassloader(DIVIDE_BY_ZERO_EXCEPTION); + //callInst=irManager.newRuntimeHelperCallInst( + // VM_RT_DIVIDE_BY_ZERO_EXCEPTION, 0, NULL, NULL); break; default: assert(0); } - appendInsts(callInst); + + if (lazy){ + printf("Lazy is compiled.\n"); + Opnd * helperOpnds[] = { + irManager.newImmOpnd(getRuntimeIdType(), Opnd::RuntimeInfo::Kind_TypeRuntimeId, encClass), + irManager.newImmOpnd(getRuntimeIdType(), NULL), + irManager.newImmOpnd(getRuntimeIdType(), NULL) + }; + callInst=irManager.newRuntimeHelperCallInst( + VM_RT_THROW_LAZY, lengthof(helperOpnds), helperOpnds, NULL); + appendInsts(callInst); + } else { + printf("Direct is compiled.\n"); + Opnd * helperOpnds1[] = { + irManager.newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_Size, encClass), + irManager.newImmOpnd(getRuntimeIdType(), Opnd::RuntimeInfo::Kind_AllocationHandle, encClass) + }; + Opnd * retOpnd=irManager.newOpnd(encClass); + callInst=irManager.newRuntimeHelperCallInst( + VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, + lengthof(helperOpnds1), helperOpnds1, retOpnd); + appendInsts(callInst); + + Opnd * helperOpnds2[] = { (Opnd*)retOpnd }; + callInst=irManager.newRuntimeHelperCallInst( + VM_RT_THROW, + lengthof(helperOpnds2), helperOpnds2, NULL); + appendInsts(callInst); + } } //_______________________________________________________________________________________________________________ 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,24 +1381,51 @@ IPF_LOG << " throwSystemException" << endl; - VM_RT_SUPPORT hId = VM_RT_UNKNOWN; + //VM_RT_SUPPORT hId = VM_RT_UNKNOWN; + ObjectType* encClass = NULL; switch (id) { case CompilationInterface::Exception_NullPointer: - hId = VM_RT_NULL_PTR_EXCEPTION; break; + encClass = compilationInterface.findClassUsingBootstrapClassloader(NULL_POINTER_EXCEPTION); + //hId = VM_RT_NULL_PTR_EXCEPTION; + break; case CompilationInterface::Exception_ArrayIndexOutOfBounds: - hId = VM_RT_IDX_OUT_OF_BOUNDS; break; + encClass = 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; + encClass = compilationInterface.findClassUsingBootstrapClassloader(ARRAY_STORE_EXCEPTION); + //hId = VM_RT_ARRAY_STORE_EXCEPTION; + break; case CompilationInterface::Exception_DivideByZero: - hId = VM_RT_DIVIDE_BY_ZERO_EXCEPTION; break; + encClass = 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); + printf("Direct is compiled.\n"); + Opnd *helperOpnds1[] = { + opndManager->newImm((int64) encClass->getObjectSize()), + opndManager->newImm((int64) encClass->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(encClass->tag); + DataKind dataKind = toDataKind(encClass->tag); + RegOpnd* retOpnd = opndManager->newRegOpnd(opndKind, dataKind); + + directCall(2, helperOpnds1, retOpnd, helperAddress, p0); - directCall(0, NULL, NULL, helperAddress, p0); + Opnd * helperOpnds2[] = { (Opnd*)retOpnd }; + + hId = VM_RT_THROW; + address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); + helperAddress = opndManager->newImm(address); + + directCall(1, helperOpnds2, NULL, helperAddress, p0); } //----------------------------------------------------------------------------// Index: vm/jitrino/src/jet/sconsts.h =================================================================== --- vm/jitrino/src/jet/sconsts.h (revision 637959) +++ vm/jitrino/src/jet/sconsts.h (working copy) @@ -48,6 +48,7 @@ class StaticConsts { public: static char * rt_helper_throw; + static char * rt_helper_throw_lazy; static char * rt_helper_throw_out_of_bounds; static char * rt_helper_throw_linking_exc; static char * rt_helper_throw_npe; Index: vm/jitrino/src/jet/compiler.cpp =================================================================== --- vm/jitrino/src/jet/compiler.cpp (revision 637959) +++ vm/jitrino/src/jet/compiler.cpp (working copy) @@ -1499,6 +1499,8 @@ rt_helper_throw = (char*)vm_helper_get_addr(VM_RT_THROW); + rt_helper_throw_lazy = + (char*)vm_helper_get_addr(VM_RT_THROW_LAZY); rt_helper_throw_out_of_bounds = (char*)vm_helper_get_addr(VM_RT_IDX_OUT_OF_BOUNDS); rt_helper_throw_linking_exc = 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_HELPERS, jvoid, jobj, 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) @@ -124,6 +125,11 @@ void CodeGen::gen_check_null(Val& obj, bool hw_ok) { +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif assert(obj.jt() == jobj); if (obj.has(VA_NZ)) { UNSAFE_REGION_START @@ -138,7 +144,23 @@ 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); + + if (lazy) { + printf("Compile lazy throw\n"); + gen_call_throw(ci_helper_lazy, rt_helper_throw_lazy, 0, npeClass, NULL, NULL); + } else { + printf("Compile direct throw\n"); + static const CallSig ci_new(CCONV_HELPERS, jobj, i32, jobj); + unsigned size = class_get_boxed_data_size(npeClass); + Allocation_Handle ah = class_get_allocation_handle(npeClass); + gen_call_vm(ci_new, rt_helper_new, 0, size, ah); + static const CallSig cs_throw(CCONV_HELPERS, jvoid, jobj); + unsigned stackFix = gen_stack_to_args(true, cs_throw, 0); + gen_call_vm(cs_throw, rt_helper_throw, 1); + } } return; } @@ -232,7 +254,41 @@ } 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); + +#ifdef _EM64T_ + bool lazy = false; +#else + bool lazy = true; +#endif + //gen_call_vm_restore(true, ci_helper_lazy, rt_helper_throw_lazy, 0, npeClass, NULL, NULL); + if (lazy) { + printf("Compile2 lazy throw\n"); + gen_call_vm_restore(true, ci_helper_lazy, rt_helper_throw_lazy, 0, npeClass, NULL, NULL); + } else { + printf("Compile2 direct throw\n"); + BBState saveBB = *m_bbstate; + for (unsigned i=0; i