void OSR::replace(SsaOpnd* opnd, SsaOpnd* iv, SsaOpnd* rc) { Inst* inst = opnd->getInst(); SsaOpnd* dstInst = reduce(inst->getDst()->getType(), inst->getOpcode(), inst->getOperation(), iv, rc); Inst* copyInst = irManager.getInstFactory().makeCopy(opnd, dstInst); copyInst->insertBefore(inst); inst->unlink(); writeLeadingOperand(opnd, getLeadingOperand(iv)); }
//_________________________________________________________________________________________________ void InternalTrace::runImpl() { MemoryManager mm("InternalTrace"); irManager->registerInternalHelperInfo("itrace_method_entry", IRManager::InternalHelperInfo((void*)&methodEntry, &CallingConvention_STDCALL)); irManager->registerInternalHelperInfo("itrace_method_exit", IRManager::InternalHelperInfo((void*)&methodExit, &CallingConvention_STDCALL)); irManager->registerInternalHelperInfo("itrace_field_write", IRManager::InternalHelperInfo((void*)&fieldWrite, &CallingConvention_STDCALL)); char methodFullName[0x1000]=""; MethodDesc & md=irManager->getMethodDesc(); strcat(methodFullName, md.getParentType()->getName()); strcat(methodFullName, "."); strcat(methodFullName, md.getName()); strcat(methodFullName, " "); strcat(methodFullName, md.getSignatureString()); Opnd * methodNameOpnd=irManager->newInternalStringConstantImmOpnd(methodFullName); irManager->setInfo("itraceMethodExitString", methodNameOpnd->getRuntimeInfo()->getValue(0)); Node* prolog=irManager->getFlowGraph()->getEntryNode(); Inst * inst=(Inst*)prolog->getFirstInst(); if (inst->hasKind(Inst::Kind_EntryPointPseudoInst)){ EntryPointPseudoInst * entryPointPseudoInst = (EntryPointPseudoInst *)inst; entryPointPseudoInst->getCallingConventionClient().finalizeInfos(Inst::OpndRole_Def, CallingConvention::ArgKind_InArg); const StlVector<CallingConvention::OpndInfo> & infos=((const EntryPointPseudoInst *)entryPointPseudoInst)->getCallingConventionClient().getInfos(Inst::OpndRole_Def); Opnd * argInfoOpnd=irManager->newBinaryConstantImmOpnd((U_32)infos.size()*sizeof(CallingConvention::OpndInfo), &infos.front()); Opnd * args[3]={ methodNameOpnd, irManager->newImmOpnd(irManager->getTypeManager().getInt32Type(), infos.size()), argInfoOpnd, }; Inst * internalTraceInst=irManager->newInternalRuntimeHelperCallInst("itrace_method_entry", 3, args, NULL); internalTraceInst->insertBefore(inst); }else{ Opnd * args[3]={ methodNameOpnd, irManager->newImmOpnd(irManager->getTypeManager().getInt32Type(), 0), irManager->newImmOpnd(irManager->getTypeManager().getUnmanagedPtrType(irManager->getTypeManager().getIntPtrType()), 0), }; Inst * internalTraceInst=irManager->newInternalRuntimeHelperCallInst("itrace_method_entry", 3, args, NULL); prolog->prependInst(internalTraceInst); } const Edges& inEdges = irManager->getFlowGraph()->getExitNode()->getInEdges(); for (Edges::const_iterator ite = inEdges.begin(), ende = inEdges.end(); ite!=ende; ++ite) { Edge* edge = *ite; if (irManager->isEpilog(edge->getSourceNode())) { Node* epilog = edge->getSourceNode(); Inst * retInst=(Inst*)epilog->getLastInst(); assert(retInst->hasKind(Inst::Kind_RetInst)); Opnd * args[1]={ methodNameOpnd }; Inst * internalTraceInst=irManager->newInternalRuntimeHelperCallInst("itrace_method_exit", 1, args, NULL); internalTraceInst->insertBefore(retInst); } } #ifdef IA32_EXTENDED_TRACE const Nodes& nodes = irManager->getFlowGraph()->getNodes(); for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) { Node* node = *it; if (node->isBlockNode()){ for (Inst * inst=(Inst*)node->getFirstInst(); inst!=NULL; inst=inst->getNextInst()){ if (inst->getMnemonic()==Mnemonic_MOV){ Opnd * dest=inst->getOpnd(0); if (dest->isPlacedIn(OpndKind_Memory) && dest->getMemOpndKind()==MemOpndKind_Heap){ Opnd * opnd=irManager->newOpnd(Type::UnmanagedPtr); Inst* newIns = irManager->newInst(Mnemonic_LEA, opnd, dest); newIns->insertBefore(inst); Opnd * args[1]={ opnd }; newIns = irManager->newInternalRuntimeHelperCallInst("itrace_field_write", 1, args, NULL); newIns->insertBefore(inst); } } } } } #endif }
/** * Checks that exception edges are equal for newobj instruction node and * throw instruction node. * @param bs - bit set of operands that may be optimized */ void LazyExceptionOpt::fixOptCandidates(BitSet* bs) { OptCandidates::iterator it; Inst* oinst; MethodCallInst* iinst; Inst* tinst; Inst* tlinst; U_32 opcount; Opnd **opnds = NULL; if (optCandidates == NULL) { return; } for (it = optCandidates->begin( ); it != optCandidates->end( ); it++ ) { if (bs->getBit((*it)->opndId)) { oinst = (*it)->objInst; assert(oinst != NULL); #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " to remove "; oinst->print(Log::out()); Log::out() << std::endl; } #endif if ((*it)->initInst == NULL) { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " init inst is null "; Log::out() << std::endl; } #endif continue; } iinst = (*it)->initInst->asMethodCallInst(); // inline info from constructor should be propagated to lazy // exception if any #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " to remove "; iinst->print(Log::out()); Log::out() << std::endl; } #endif assert((*it)->throwInsts != NULL); assert(iinst->getNumSrcOperands() >= 3); if (!removeInsts(oinst,iinst)) continue; // to null bitset? TypeManager& tm = irManager.getTypeManager(); Opnd* mpt = irManager.getOpndManager().createSsaTmpOpnd( tm.getMethodPtrType(iinst->getMethodDesc())); opcount = iinst->getNumSrcOperands()-2; //numSrc-3+1 if (opcount >0) { opnds = new (leMemManager) Opnd*[opcount]; //local mem should be used opnds[0] = mpt; for (U_32 i = 0; i < opcount-1; i++) opnds[i+1] = iinst->getSrc(i+3); } Inst* mptinst = irManager.getInstFactory().makeLdFunAddr(mpt,iinst->getMethodDesc()); #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " 1st "; mptinst->print(Log::out()); Log::out() << std::endl; } #endif ThrowInsts::iterator it1; for (it1 = (*it)->throwInsts->begin(); it1 !=(*it)->throwInsts->end(); it1++) { tinst = *it1; assert(tinst != NULL); tlinst=irManager.getInstFactory().makeVMHelperCall( OpndManager::getNullOpnd(), VM_RT_THROW_LAZY, opcount, opnds); #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " 2nd "; tlinst->print(Log::out()); Log::out() << std::endl; } if (Log::isEnabled()) { Log::out() << " to change "; tinst->print(Log::out()); Log::out() << std::endl; } #endif mptinst->insertBefore(tinst); tlinst->insertBefore(tinst); tinst->unlink(); uint16 bcOffset = iinst->getBCOffset(); mptinst->setBCOffset(bcOffset); tlinst->setBCOffset(bcOffset); } } } }