Index: build/make/excludes/exclude.drlvm_smoke.linux.x86.srv =================================================================== --- build/make/excludes/exclude.drlvm_smoke.linux.x86.srv (revision 528389) +++ build/make/excludes/exclude.drlvm_smoke.linux.x86.srv (working copy) @@ -6,6 +6,3 @@ # HARMONY-3495 hangs intermittently gc/NPE.java - -# HARMONY-3519 -thread/ThreadInterrupt.java Index: build/make/excludes/exclude.drlvm_smoke.windows.x86.srv =================================================================== --- build/make/excludes/exclude.drlvm_smoke.windows.x86.srv (revision 528389) +++ build/make/excludes/exclude.drlvm_smoke.windows.x86.srv (working copy) @@ -3,6 +3,3 @@ # HARMONY-2977 io/Integers.java - -# HARMONY-3519 -thread/ThreadInterrupt.java Index: build/make/excludes/exclude.drlvm_smoke.windows.x86_64.srv =================================================================== --- build/make/excludes/exclude.drlvm_smoke.windows.x86_64.srv (revision 528389) +++ build/make/excludes/exclude.drlvm_smoke.windows.x86_64.srv (working copy) @@ -17,6 +17,3 @@ # Server mode failures specific to Windows x86_64 stress/Mix.java - -# HARMONY-3519 -thread/ThreadInterrupt.java Index: build/make/excludes/exclude.drlvm_smoke.linux.x86_64.srv =================================================================== --- build/make/excludes/exclude.drlvm_smoke.linux.x86_64.srv (revision 528389) +++ build/make/excludes/exclude.drlvm_smoke.linux.x86_64.srv (working copy) @@ -22,6 +22,3 @@ # HARMONY-3495 hangs intermittently gc/NPE.java - -# HARMONY-3519 -thread/ThreadInterrupt.java Index: vm/jitrino/src/codegenerator/CodeGenIntfc.h =================================================================== --- vm/jitrino/src/codegenerator/CodeGenIntfc.h (revision 528389) +++ vm/jitrino/src/codegenerator/CodeGenIntfc.h (working copy) @@ -167,7 +167,6 @@ enum Id { InitializeArray, FillArrayWithConst, - PseudoCanThrow, SaveThisState, ReadThisState, LockedCompareAndExchange, Index: vm/jitrino/src/optimizer/Opcode.cpp =================================================================== --- vm/jitrino/src/optimizer/Opcode.cpp (revision 528389) +++ vm/jitrino/src/optimizer/Opcode.cpp (working copy) @@ -112,8 +112,9 @@ { Op_Return, true, MB::ControlFlow, MK::None, "return", "return %s", }, { Op_Catch, true, MB::ControlFlow, MK::None, "catch", "catch -) %l", }, { Op_Throw, true, MB::Exception, MK::Throw, "throw ", "throw %0", }, - { Op_ThrowSystemException, true, MB::Exception, MK::None, "throwsys ", "throwsys %d", }, - { Op_ThrowLinkingException, true, MB::Exception, MK::None, "throwLink ", "throwLink", }, + { Op_PseudoThrow, true, MB::Exception, MK::Exception, "pseudoThrow ", "pseudoThrow", }, + { Op_ThrowSystemException, true, MB::Exception, MK::None, "throwsys ", "throwsys %d", }, + { Op_ThrowLinkingException, true, MB::Exception, MK::None, "throwLink ", "throwLink", }, { Op_Leave, true, MB::ControlFlow, MK::None, "leave ", "leave %l", }, // CLI only -- DELETE { Op_EndFinally, true, MB::ControlFlow, MK::None, "endfinally", "endfinally", }, // CLI only -- DELETE { Op_EndFilter, true, MB::ControlFlow, MK::None, "endfilter", "endfilter", }, // CLI only -- DELETE Index: vm/jitrino/src/optimizer/codelowerer.h =================================================================== --- vm/jitrino/src/optimizer/codelowerer.h (revision 528389) +++ vm/jitrino/src/optimizer/codelowerer.h (working copy) @@ -148,6 +148,8 @@ Inst* caseThrow(Inst* inst) {return caseDefault(inst);} + Inst* casePseudoThrow(Inst* inst) {return caseDefault(inst);} + Inst* caseThrowSystemException(Inst* inst) {return caseDefault(inst);} Inst* caseThrowLinkingException(Inst* inst) {return caseDefault(inst);} Index: vm/jitrino/src/optimizer/deadcodeeliminator.h =================================================================== --- vm/jitrino/src/optimizer/deadcodeeliminator.h (revision 528389) +++ vm/jitrino/src/optimizer/deadcodeeliminator.h (working copy) @@ -26,6 +26,7 @@ #include "Stl.h" #include "optpass.h" +#include "LoopTree.h" namespace Jitrino { @@ -43,13 +44,14 @@ static void copyPropagate(Inst*); static Opnd* copyPropagate(Opnd*); bool eliminateUnreachableCode(); // returns true if any node is eliminated + void removeExtraPseudoThrow(); private: void sweepInst(Node* node, Inst* inst, BitSet& usefulInstSet, BitSet& usefulVarSet, uint8 *usedInstWidth, uint32 minInstId, uint32 maxInstId, bool canRemoveStvars); void sweepInst1(Node* node, Inst* inst, BitSet& usefulInstSet, BitSet& usefulVarSet, uint32 minInstId, uint32 maxInstId, bool canRemoveStvars); // if we're skipping instWidth static Opnd* findDefiningTemp(Opnd* var); + void markEssentialPseudoThrows(LoopNode* loopNode, BitSet& essentialNodes); - IRManager& irManager; ControlFlowGraph& flowGraph; Opnd* returnOpnd; Index: vm/jitrino/src/optimizer/FlowGraph.cpp =================================================================== --- vm/jitrino/src/optimizer/FlowGraph.cpp (revision 528389) +++ vm/jitrino/src/optimizer/FlowGraph.cpp (working copy) @@ -32,6 +32,7 @@ #include "XTimer.h" #include "StaticProfiler.h" #include "escapeanalyzer.h" +#include "deadcodeeliminator.h" #include "TranslatorIntfc.h" #include "CGSupport.h" #include "LoopTree.h" @@ -996,6 +997,10 @@ } } } + // Remove extra PseudoThrow insts + DeadCodeEliminator dce(irm); + dce.removeExtraPseudoThrow(); + // // a quick cleanup of unreachable and empty basic blocks // @@ -1162,7 +1167,7 @@ out << "tn: " << (int) node->getTraversalNum() << " pre:" << (int)node->getPreNum() << " post:" << (int)node->getPostNum() << " "; out << "id: " << (int) node->getId() << " "; if(fg.hasEdgeProfile()) { - out << " execCount:" << (int)node->getExecCount()<< " "; + out << " execCount:" << node->getExecCount() << " "; } Node* idom = dom==NULL ? NULL: dom->getIdom(node); if (idom!=NULL) { Index: vm/jitrino/src/optimizer/lazyexceptionopt.cpp =================================================================== --- vm/jitrino/src/optimizer/lazyexceptionopt.cpp (revision 528389) +++ vm/jitrino/src/optimizer/lazyexceptionopt.cpp (working copy) @@ -904,6 +904,8 @@ case Op_Return: case Op_Catch: return false; + case Op_PseudoThrow: + return false; case Op_Throw: case Op_ThrowSystemException: case Op_ThrowLinkingException: Index: vm/jitrino/src/optimizer/Inst.h =================================================================== --- vm/jitrino/src/optimizer/Inst.h (revision 528389) +++ vm/jitrino/src/optimizer/Inst.h (working copy) @@ -1156,6 +1156,7 @@ Inst* makeCatchLabel(uint32 labelId, uint32 exceptionOrder, Type* exceptionType); CatchLabelInst* makeCatchLabel(uint32 exceptionOrder, Type* exceptionType); Inst* makeThrow(ThrowModifier mod, Opnd* exceptionObj); + Inst* makePseudoThrow(); Inst* makeThrowSystemException(CompilationInterface::SystemExceptionId exceptionId); Inst* makeThrowLinkingException(Class_Handle encClass, uint32 CPIndex, uint32 operation); Inst* makeLeave(LabelInst* labelInst); @@ -1683,6 +1684,9 @@ caseThrow(Inst* inst)=0;// {return caseDefault(inst);} virtual Inst* + casePseudoThrow(Inst* inst)=0;// {return caseDefault(inst);} + + virtual Inst* caseThrowSystemException(Inst* inst)=0;// {return caseDefault(inst);} virtual Inst* Index: vm/jitrino/src/optimizer/IRBuilder.h =================================================================== --- vm/jitrino/src/optimizer/IRBuilder.h (revision 528389) +++ vm/jitrino/src/optimizer/IRBuilder.h (working copy) @@ -168,6 +168,7 @@ void genReturn();//TR Opnd* genCatch(Type* exceptionType); // TR void genThrow(ThrowModifier mod, Opnd* exceptionObj);//TR + void genPseudoThrow();//TR void genThrowSystemException(CompilationInterface::SystemExceptionId);//SI void genThrowLinkingException(Class_Handle encClass, uint32 CPIndex, uint32 operation);//SI void genLeave(LabelInst* label);//TR Index: vm/jitrino/src/optimizer/Inst.cpp =================================================================== --- vm/jitrino/src/optimizer/Inst.cpp (revision 528389) +++ vm/jitrino/src/optimizer/Inst.cpp (working copy) @@ -458,8 +458,6 @@ switch(jitHelperId) { case InitializeArray: os << "InitializeArray"; break; - case PseudoCanThrow: - os << "PseudoCanThrow"; break; case SaveThisState: os << "SaveThisState"; break; case ReadThisState: @@ -1893,6 +1891,10 @@ return makeInst(Op_Throw, Modifier(mod), Type::Void, OpndManager::getNullOpnd(), exceptionObj); } +Inst* InstFactory::makePseudoThrow() { + return makeInst(Op_PseudoThrow, Modifier(Exception_Sometimes), Type::Void, OpndManager::getNullOpnd()); +} + Inst* InstFactory::makeThrowSystemException(CompilationInterface::SystemExceptionId exceptionId) { MethodDesc* enclosingMethod = 0; return makeTokenInst(Op_ThrowSystemException, Modifier(), Type::Void, @@ -2688,6 +2690,7 @@ case Op_Return: return caseReturn(inst); case Op_Catch: return caseCatch(inst); case Op_Throw: return caseThrow(inst); + case Op_PseudoThrow: return casePseudoThrow(inst); case Op_ThrowSystemException: return caseThrowSystemException(inst); case Op_ThrowLinkingException: return caseThrowLinkingException(inst); case Op_Leave: return caseLeave(inst); Index: vm/jitrino/src/optimizer/hashvaluenumberer.cpp =================================================================== --- vm/jitrino/src/optimizer/hashvaluenumberer.cpp (revision 528389) +++ vm/jitrino/src/optimizer/hashvaluenumberer.cpp (working copy) @@ -210,6 +210,8 @@ Inst* caseThrow(Inst* inst) { return caseDefault(inst); } + Inst* casePseudoThrow(Inst* inst) { return caseDefault(inst); } + Inst* caseThrowSystemException(Inst* inst) { return caseDefault(inst); } Inst* caseThrowLinkingException(Inst* inst) { return caseDefault(inst); } Index: vm/jitrino/src/optimizer/IRBuilder.cpp =================================================================== --- vm/jitrino/src/optimizer/IRBuilder.cpp (revision 528389) +++ vm/jitrino/src/optimizer/IRBuilder.cpp (working copy) @@ -1264,6 +1264,11 @@ } void +IRBuilder::genPseudoThrow() { + appendInst(instFactory->makePseudoThrow()); +} + +void IRBuilder::genThrowSystemException(CompilationInterface::SystemExceptionId id) { appendInst(instFactory->makeThrowSystemException(id)); } Index: vm/jitrino/src/optimizer/CodeSelectors.cpp =================================================================== --- vm/jitrino/src/optimizer/CodeSelectors.cpp (revision 528389) +++ vm/jitrino/src/optimizer/CodeSelectors.cpp (working copy) @@ -404,7 +404,6 @@ JitHelperCallOp::Id _BlockCodeSelector::convertJitHelperId(JitHelperCallId callId) { switch(callId) { case InitializeArray: return JitHelperCallOp::InitializeArray; - case PseudoCanThrow: return JitHelperCallOp::PseudoCanThrow; case SaveThisState: return JitHelperCallOp::SaveThisState; case ReadThisState: return JitHelperCallOp::ReadThisState; case LockedCompareAndExchange: return JitHelperCallOp::LockedCompareAndExchange; @@ -897,17 +896,11 @@ { JitHelperCallInst* call = inst->asJitHelperCallInst(); JitHelperCallId callId = call->getJitHelperId(); - - if( callId == PseudoCanThrow ){ - instructionCallback.pseudoInst(); - - } else { - cgInst = - instructionCallback.callhelper(inst->getNumSrcOperands(), - genCallArgs(call,0), - inst->getDst()->getType(), - convertJitHelperId(callId)); - } + cgInst = + instructionCallback.callhelper(inst->getNumSrcOperands(), + genCallArgs(call,0), + inst->getDst()->getType(), + convertJitHelperId(callId)); } break; case Op_VMHelperCall: @@ -941,6 +934,9 @@ instructionCallback.throwException(getCGInst(inst->getSrc(0)), inst->getThrowModifier() == Throw_CreateStackTrace); } break; + case Op_PseudoThrow: + instructionCallback.pseudoInst(); + break; case Op_ThrowSystemException: { TokenInst *tokenInst = (TokenInst *)inst; Index: vm/jitrino/src/optimizer/simplifier.h =================================================================== --- vm/jitrino/src/optimizer/simplifier.h (revision 528389) +++ vm/jitrino/src/optimizer/simplifier.h (working copy) @@ -510,6 +510,8 @@ Inst* caseThrow(Inst* inst) {return caseDefault(inst);} + Inst* casePseudoThrow(Inst* inst) {return caseDefault(inst);} + Inst* caseThrowSystemException(Inst* inst) {return caseDefault(inst);} Inst* caseThrowLinkingException(Inst* inst) {return caseDefault(inst);} Index: vm/jitrino/src/optimizer/deadcodeeliminator.cpp =================================================================== --- vm/jitrino/src/optimizer/deadcodeeliminator.cpp (revision 528389) +++ vm/jitrino/src/optimizer/deadcodeeliminator.cpp (working copy) @@ -62,6 +62,15 @@ } } +DEFINE_SESSION_ACTION(ExtraPseudoThrowRemovalPass, rept, "Removal of Extra PseudoThrow Instructions"); + +void +ExtraPseudoThrowRemovalPass::_run(IRManager& irm) { + DeadCodeEliminator dce(irm); + dce.removeExtraPseudoThrow(); +} + + //Empty Node Removal class PurgeEmptyNodesPass: public SessionAction { public: @@ -1053,4 +1062,109 @@ } +// +// Leave one PseudoThrow instruction only for those loops which +// do not contain other dispatch edges exiting the loop. +// +void +DeadCodeEliminator::removeExtraPseudoThrow() { + MemoryManager memManager(flowGraph.getMaxNodeId(),"DeadCodeEliminator::removeExtraPseudoThrow"); + + OptPass::computeLoops(irManager); + LoopTree* loopTree = irManager.getLoopTree(); + assert(loopTree && loopTree->isValid()); + + if (Log::isLogEnabled(LogStream::DOTDUMP)) { + OptPass::printDotFile(irManager, Log::getStageId(), "rept", "after_loop_tree"); + } + + // Nodes containing essential PseudoThrow instructions + BitSet essentialNodes(memManager, flowGraph.getMaxNodeId()); + + if (loopTree->hasLoops()) { + LoopNode* loopNode = ((LoopNode*)loopTree->getRoot())->getChild(); + markEssentialPseudoThrows(loopNode, essentialNodes); + } + + const Nodes& cfgNodes = flowGraph.getNodes(); + if (Log::isEnabled()) { + Log::out() << "Removing useless PseudoThrow instructions:" << std::endl; + } + for (Nodes::const_iterator it = cfgNodes.begin(), end = cfgNodes.end(); it!=end; ++it) { + Node* node = *it; + Inst* lastInst = (Inst*)node->getLastInst(); + if (!essentialNodes.getBit(node->getId()) && (lastInst->getOpcode() == Op_PseudoThrow)) { + if (Log::isEnabled()) { + Log::out() << " Removing instruction: "; + lastInst->print(Log::out()); + Log::out() << std::endl; + } + lastInst->unlink(); + Edge* dispatchEdge = node->getExceptionEdge(); + assert(dispatchEdge != NULL); + flowGraph.removeEdge(dispatchEdge); + } + } + if (Log::isEnabled()) { + Log::out() << "Done." << std::endl; + } + eliminateUnreachableCode(); +} + +void +DeadCodeEliminator::markEssentialPseudoThrows(LoopNode* loopNode, BitSet& essentialNodes) { + LoopNode* childNode = loopNode->getChild(); + if (childNode != NULL) + markEssentialPseudoThrows(childNode, essentialNodes); + LoopNode* siblingNode = loopNode->getSiblings(); + if (siblingNode != NULL) + markEssentialPseudoThrows(siblingNode, essentialNodes); + if (Log::isEnabled()) { + Log::out() << "Analyzing loop nodes with the loop header ID: " + << loopNode->getHeader()->getId() << std::endl; + } + Node* mbEssentialNode = NULL; + const Nodes& loopNodes = loopNode->getNodesInLoop(); + for (Nodes::const_iterator it = loopNodes.begin(), end = loopNodes.end(); it!=end; ++it) { + Node* node = *it; + if (Log::isEnabled()) { + Log::out() << "Analyzing Node ID: " << node->getId() << std::endl; + } + Edge* exceptionEdge = node->getExceptionEdge(); + if ((exceptionEdge != NULL) && !loopNode->inLoop(exceptionEdge->getTargetNode())) { + if (Log::isEnabled()) { + Log::out() << " Loop ID exit exception edge detected: "; + } + if (((Inst*)node->getLastInst())->getOpcode() == Op_PseudoThrow) { + if (essentialNodes.getBit(node->getId())) { + // There is an essential PseudoThrow instruction in this loop + if (Log::isEnabled()) { + Log::out() << " essential PseudoThrow inst" << std::endl; + } + return; + } else { + // A candidate to essential nodes + if (Log::isEnabled()) { + Log::out() << " essential candidate" << std::endl; + } + mbEssentialNode = node; + } + } else { + // No essential PseudoThrow insts in this loop + if (Log::isEnabled()) { + Log::out() << " PseudoThrow killer inst" << std::endl; + } + return; + } + } + } + assert(mbEssentialNode != NULL); + essentialNodes.setBit(mbEssentialNode->getId()); + if (Log::isEnabled()) { + Log::out() << "Found essential PseudoThrow in node ID: " + << mbEssentialNode->getId() << std::endl; + } + return; +} + } //namespace Jitrino Index: vm/jitrino/src/optimizer/Opcode.h =================================================================== --- vm/jitrino/src/optimizer/Opcode.h (revision 528389) +++ vm/jitrino/src/optimizer/Opcode.h (working copy) @@ -272,7 +272,6 @@ enum JitHelperCallId { InitializeArray, FillArrayWithConst, - PseudoCanThrow, SaveThisState, //todo: replace with GetTLS + offset sequence ReadThisState, //todo: replace with GetTLS + offset sequence LockedCompareAndExchange, @@ -318,7 +317,8 @@ Op_Return, // Exception processing Op_Catch, - Op_Throw, + Op_Throw, + Op_PseudoThrow, // pseudo instruction to break infinte loops Op_ThrowSystemException, // takes a CompilationInterface::SystemExceptionId parameter Op_ThrowLinkingException, // generate a call to Helper_Throw_LinkingException Op_Leave, Index: vm/jitrino/src/optimizer/simplifytaus.cpp =================================================================== --- vm/jitrino/src/optimizer/simplifytaus.cpp (revision 528389) +++ vm/jitrino/src/optimizer/simplifytaus.cpp (working copy) @@ -496,6 +496,7 @@ } case Op_Throw: + case Op_PseudoThrow: case Op_Leave: case Op_EndFinally: case Op_EndFilter: Index: vm/jitrino/src/optimizer/memoryopt.cpp =================================================================== --- vm/jitrino/src/optimizer/memoryopt.cpp (revision 528389) +++ vm/jitrino/src/optimizer/memoryopt.cpp (working copy) @@ -662,7 +662,6 @@ JitHelperCallId callId = jitcalli->getJitHelperId(); switch (callId) { case InitializeArray: - case PseudoCanThrow: case SaveThisState: case ReadThisState: case LockedCompareAndExchange: @@ -674,6 +673,8 @@ } } break; + case Op_PseudoThrow: + break; case Op_Return: case Op_Throw: case Op_ThrowSystemException: Index: vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp =================================================================== --- vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp (revision 528389) +++ vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp (working copy) @@ -226,126 +226,6 @@ } } -#define WHITE 0 // node has not been touched yet -#define BLACK 1 // node can reach exit node - -// -// Traverse all the nodes in a reverse DFS manner, and mark all the ndoes -// that are reachable from exit node with BLACK. -// -void JavaFlowGraphBuilder::reverseDFS( StlVector& state, - Node* targetNode, - uint32* nodesCounter ) -{ - const Edges& in_edges = targetNode->getInEdges(); - - assert( state[targetNode->getId()] == WHITE ); - state[targetNode->getId()] = BLACK; - - *nodesCounter += 1; - - for( Edges::const_iterator in_iter = in_edges.begin(); in_iter != in_edges.end(); in_iter++ ){ - Node* srcNode = (*in_iter)->getSourceNode(); - - if( state[srcNode->getId()] != BLACK ){ - reverseDFS( state, srcNode, nodesCounter ); - } - } - - return; -} - -// -// Traverse all the nodes in a forward DFS manner, and add dispatches -// for while(true){;} loops, if they exist. -// -void JavaFlowGraphBuilder::forwardDFS( StlVector& state, - Node* srcNode, - Edges& edgesForSplicing) -{ - // Flip the state, so the same node will not be visited more than twice. - state[srcNode->getId()] = ~state[srcNode->getId()]; - - const Edges& out_edges = srcNode->getOutEdges(); - - for( Edges::const_iterator out_iter = out_edges.begin(); out_iter != out_edges.end(); out_iter++ ){ - - Node* targetNode = (*out_iter)->getTargetNode(); - const int32 targetState = state[targetNode->getId()]; - - if( targetState == BLACK || - targetState == WHITE ){ - // Keep searching ... - forwardDFS( state, targetNode, edgesForSplicing ); - } else if( targetState == ~WHITE){ - state[targetNode->getId()] = ~BLACK; // Now it can reach exit node. - edgesForSplicing.push_back((*out_iter)); - } - } - - // Don't visit ~WHITE node again. - state[srcNode->getId()] = ~BLACK; - - return; -} - -// -// Introduce a dispatch edge from an infinite loop, if exists, to the -// unwind node, so that the graph is connected from entry to exit. -// -void JavaFlowGraphBuilder::resolveWhileTrue() -{ - MemoryManager mm( fg->getMaxNodeId(), "ControlFlowGraph::resolveWhileTrue" ); - - StlVector state( mm, fg->getMaxNodeId() ); - - // - // Pass 1: Identify all the nodes that are reachable from exit node. - // - uint32 nodesAffected = 0; - reverseDFS( state, fg->getExitNode(), &nodesAffected ); - - // - // Pass 2: Add dispatches for while(true){;} loops, if they exist. - // - if( nodesAffected < fg->getNodes().size() ){ - Edges edgesForSplicing(mm); - forwardDFS( state, fg->getEntryNode(), edgesForSplicing ); - for (uint32 i=0; i < edgesForSplicing.size(); i++) { - Edge* e= edgesForSplicing[i]; - Node* targetNode = e->getTargetNode(); - LabelInst* newLabel = irBuilder.createLabel(); - Node* node = fg->spliceBlockOnEdge(e, newLabel); - irBuilder.genLabel(newLabel); - - Opnd* args[] = { irBuilder.genTauSafe(), irBuilder.genTauSafe() }; - Type* returnType = irBuilder.getTypeManager()->getVoidType(); - irBuilder.genJitHelperCall( PseudoCanThrow, - returnType, - sizeof(args) / sizeof(args[0]), - args ); - - ExceptionInfo* exceptionInfo = - (CatchBlock*)((LabelInst*)targetNode->getFirstInst())->getState(); - Node* dispatch = NULL; - - if( exceptionInfo != NULL) { - dispatch = exceptionInfo->getLabelInst()->getNode(); - } else { - dispatch = fg->getUnwindNode(); - } - - fg->addEdge(node, dispatch); - } - if( Log::isEnabled() ){ - MethodDesc &methodDesc = irBuilder.getIRManager()->getMethodDesc(); - Log::out() << "PRINTING LOG: After resolveWhileTrue" << ::std::endl; - FlowGraph::printHIR(Log::out(), *fg, methodDesc ); - } - - } -} - Node* JavaFlowGraphBuilder::createBlockNodeOrdered(LabelInst* label) { if (label == NULL) { label = irBuilder.getInstFactory()->makeLabel(); @@ -396,10 +276,6 @@ // second phase: construct edges // createCFGEdges(); - // - // third phase: add dispatches for infinite loop(s) - // - resolveWhileTrue(); eliminateUnnestedLoopsOnDispatch(); } Index: vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h =================================================================== --- vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h (revision 528389) +++ vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h (working copy) @@ -48,9 +48,6 @@ void edgeForFallthrough(Node* block); void eliminateUnnestedLoopsOnDispatch(); bool lastInstIsMonitorExit(Node* node); - void resolveWhileTrue(); - void reverseDFS( StlVector& state, Node* targetNode, uint32* NodesCounter ); - void forwardDFS( StlVector& state, Node* srcNode, Edges& edges); Node* createBlockNodeOrdered(LabelInst* label = NULL); Node* createBlockNodeAfter(Node* node, LabelInst* label = NULL); Index: vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp =================================================================== --- vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (revision 528389) +++ vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (working copy) @@ -1605,6 +1605,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset)); @@ -1617,6 +1620,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset)); @@ -1627,6 +1633,9 @@ JavaByteCodeTranslator::goto_(uint32 targetOffset,uint32 nextOffset) { if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); uint32 lid = labelId(targetOffset); @@ -1638,6 +1647,9 @@ //----------------------------------------------------------------------------- void JavaByteCodeTranslator::jsr(uint32 targetOffset, uint32 nextOffset) { + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); irBuilder.genJSR(getLabel(labelId(targetOffset))); @@ -2605,6 +2617,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset)); @@ -2619,6 +2634,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset)); @@ -2634,6 +2652,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset)); @@ -2648,6 +2669,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset)); @@ -2661,6 +2685,9 @@ Opnd* src1 = popOpnd(); if (targetOffset == nextOffset) return; + if (targetOffset < nextOffset) { + irBuilder.genPseudoThrow(); + } lastInstructionWasABranch = true; checkStack(); LabelInst *target = getLabel(labelId(targetOffset));