harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfur...@apache.org
Subject svn commit: r611195 - in /harmony/enhanced/drlvm/trunk/vm/jitrino: config/ia32/ src/codegenerator/ src/codegenerator/ia32/ src/optimizer/
Date Fri, 11 Jan 2008 14:57:28 GMT
Author: mfursov
Date: Fri Jan 11 06:57:21 2008
New Revision: 611195

URL: http://svn.apache.org/viewvc?rev=611195&view=rev
Log:
Fix for HARMONY-5376 [drlvm][jit][opt][perf] New API magic for String.indexOf method

enabled only in server_aggressive mode, because it has problems with reggression tests (5206)
on EM64T platform
 


Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf Fri Jan 11
06:57:21 2008
@@ -81,6 +81,9 @@
 -XX:jit.SD2_OPT.path.dce1=cg_dce
 -XX:jit.SD2_OPT.path.dce2=cg_dce
 
+
+-XX:jit.SD2_OPT.arg.String_indexOf_as_magic=true
+
 #devirt configuration
 -XX:jit.SD2_OPT.arg.optimizer.devirt.devirt_intf_calls=true
 -XX:jit.SD2_OPT.arg.optimizer.devirt.devirt_abstract_calls=true

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Fri Jan 11 06:57:21
2008
@@ -173,7 +173,8 @@
         LockedCompareAndExchange,
         AddValueProfileValue,
         StringCompareTo,
-        StringRegionMatches
+        StringRegionMatches,
+        StringIndexOf
     };
 };
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp Fri Jan
11 06:57:21 2008
@@ -84,6 +84,7 @@
 DECLARE_HELPER_INLINER(Long_numberOfTrailingZeros_Handler_x_J_x_I);
 DECLARE_HELPER_INLINER(String_compareTo_Handler_x_String_x_I);
 DECLARE_HELPER_INLINER(String_regionMatches_Handler_x_I_x_String_x_I_x_I_x_Z);
+DECLARE_HELPER_INLINER(String_indexOf_Handler_x_String_x_I_x_I);
 
 void APIMagicsHandlerSession::runImpl() {
     CompilationContext* cc = getCompilationContext();
@@ -135,6 +136,9 @@
                         } else if( strcmp((char*)ri->getValue(0),"String_regionMatches")==0
) {
                             if(getBoolArg("String_regionMatches_as_magic", true))
                                 handlers.push_back(new (tmpMM) String_regionMatches_Handler_x_I_x_String_x_I_x_I_x_Z(irm,
callInst, NULL));
+                        } else if( strcmp((char*)ri->getValue(0),"String_indexOf")==0
) {
+                            if(getBoolArg("String_indexOf_as_magic", true))
+                                handlers.push_back(new (tmpMM) String_indexOf_Handler_x_String_x_I_x_I(irm,
callInst, NULL));
                         }
                     }
                 }
@@ -495,8 +499,205 @@
     callInst->unlink();
 }
 
-// this intends for indexes and counters conversion
-// ATTENTION !!! Zero Extention is used for this
+void String_indexOf_Handler_x_String_x_I_x_I::run() {
+
+    Node* callInstNode = callInst->getNode();
+    Node* nextNode = NULL;
+
+    if(callInst == callInstNode->getLastInst()) {
+        nextNode = callInstNode->getUnconditionalEdgeTarget();
+        assert(nextNode!=NULL);
+    } else {
+        nextNode = irm->getFlowGraph()->splitNodeAtInstruction(callInst, true, true,
NULL);
+    }
+    cfg->removeEdge(callInstNode->getUnconditionalEdge());
+
+    // arguments of the call are already prepared by respective HLO pass
+    // they are not the strings but 'value' arrays
+    Opnd* thisArr = getCallSrc(callInst, 0);
+    Opnd* thisOffset = getCallSrc(callInst, 1);
+    Opnd* thisLen = getCallSrc(callInst, 2);
+    Opnd* trgtArr = getCallSrc(callInst, 3);
+    Opnd* trgtOffset = getCallSrc(callInst, 4);
+    Opnd* trgtLen = getCallSrc(callInst, 5);
+    Opnd* start = getCallSrc(callInst, 6);
+    Opnd* res = getCallDst(callInst);
+
+#ifdef _EM64T_
+    Type*   counterType = irm->getTypeManager().getInt64Type();
+    Constraint regConstr(OpndKind_GPReg, OpndSize_64);
+#else
+    Type*   counterType = irm->getTypeManager().getInt32Type();
+    Constraint regConstr(OpndKind_GPReg, OpndSize_32);
+#endif
+    Constraint reg16Constr(OpndKind_GPReg, OpndSize_16);
+
+    Opnd* zero = irm->newImmOpnd(counterType, 0);
+
+    Node* mainNode = irm->getFlowGraph()->createBlockNode();
+    
+    Node* mainLoop = irm->getFlowGraph()->createBlockNode();
+    Node* mainLoop2 = irm->getFlowGraph()->createBlockNode();
+    Node* mainLoop3 = irm->getFlowGraph()->createBlockNode();
+    Node* nestedLoop = irm->getFlowGraph()->createBlockNode();
+    Node* nestedLoop2 = irm->getFlowGraph()->createBlockNode();
+    Node* nestedLoop3 = irm->getFlowGraph()->createBlockNode();
+    Node* mainLoopEnd = irm->getFlowGraph()->createBlockNode();
+
+    Node* returnStart = irm->getFlowGraph()->createBlockNode();
+    Node* returnIndex = irm->getFlowGraph()->createBlockNode();
+    Node* returnMinusOne = irm->getFlowGraph()->createBlockNode();
+
+    irm->getFlowGraph()->addEdge(mainNode, mainLoop);
+
+    irm->getFlowGraph()->addEdge(mainLoop, mainLoop2, 0.9);
+    irm->getFlowGraph()->addEdge(mainLoop, returnMinusOne, 0.1);
+    irm->getFlowGraph()->addEdge(mainLoop2, mainLoop3, 0.1);
+    irm->getFlowGraph()->addEdge(mainLoop2, mainLoopEnd, 0.9);
+    irm->getFlowGraph()->addEdge(mainLoop3, nestedLoop);
+    irm->getFlowGraph()->addEdge(nestedLoop, returnIndex, 0.1);
+    irm->getFlowGraph()->addEdge(nestedLoop, nestedLoop2, 0.9);
+    irm->getFlowGraph()->addEdge(nestedLoop2, mainLoopEnd, 0.8);
+    irm->getFlowGraph()->addEdge(nestedLoop2, nestedLoop3, 0.2);
+    irm->getFlowGraph()->addEdge(nestedLoop3, nestedLoop);
+    irm->getFlowGraph()->addEdge(mainLoopEnd, mainLoop);
+    
+    irm->getFlowGraph()->addEdge(returnStart, nextNode);
+    irm->getFlowGraph()->addEdge(returnMinusOne, nextNode);
+    irm->getFlowGraph()->addEdge(returnIndex, nextNode);
+
+    Opnd* subLen = irm->newOpnd(counterType, regConstr);
+
+    bool startIsZero = true;
+    if ( !(start->isPlacedIn(OpndKind_Imm) && start->getImmValue() == 0) )
+        startIsZero = false;
+
+    if ( !start->isPlacedIn(OpndKind_Imm) )
+    {
+        Node* startLessThanZero = irm->getFlowGraph()->createBlockNode();
+        Node* subLenCheck = irm->getFlowGraph()->createBlockNode();
+        Node* startCheck = irm->getFlowGraph()->createBlockNode();
+
+        irm->getFlowGraph()->addEdge(callInstNode, startLessThanZero, 0);
+        irm->getFlowGraph()->addEdge(callInstNode, subLenCheck, 1);
+        irm->getFlowGraph()->addEdge(startLessThanZero, subLenCheck);
+        irm->getFlowGraph()->addEdge(subLenCheck, startCheck, 0);
+        irm->getFlowGraph()->addEdge(subLenCheck, mainNode, 1);
+        irm->getFlowGraph()->addEdge(startCheck, returnMinusOne, 0);
+        irm->getFlowGraph()->addEdge(startCheck, returnStart, 1);
+
+        callInstNode->appendInst(irm->newInst(Mnemonic_CMP, start, zero)); // cmp start,
0
+        callInstNode->appendInst(irm->newBranchInst(Mnemonic_JL, startLessThanZero,
subLenCheck)); // jl startLessThanZero
+
+        startLessThanZero->appendInst(irm->newInst(Mnemonic_MOV, start, zero)); //
mov start, 0
+
+        // saving subString.length on register
+        subLenCheck->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, subLen, trgtLen));
// mov subLen, subString.count
+        subLenCheck->appendInst(irm->newInst(Mnemonic_CMP, subLen, zero)); // cmp subLen,
0
+        subLenCheck->appendInst(irm->newBranchInst(Mnemonic_JE, startCheck, mainNode));
// je startCheck
+
+        startCheck->appendInst(irm->newInst(Mnemonic_CMP, start, thisLen)); // cmp
start, this.count
+        startCheck->appendInst(irm->newBranchInst(Mnemonic_JG, returnMinusOne, returnStart));
// jg returnMinusOne
+    }
+    else // removing unnecessary checks
+    {
+        int64 val = start->getImmValue();
+        if (val <0)
+        {
+            start = zero;
+            val = 0;
+        }
+
+        // saving subString.length on register
+        callInstNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, subLen, trgtLen));
// mov subLen, subString.count
+        callInstNode->appendInst(irm->newInst(Mnemonic_CMP, subLen, zero)); // cmp
subLen, 0
+
+        if (val != 0)
+        {
+            Node* startCheck = irm->getFlowGraph()->createBlockNode();
+            
+            irm->getFlowGraph()->addEdge(callInstNode, mainNode, 1);
+            irm->getFlowGraph()->addEdge(callInstNode, startCheck, 0);
+            irm->getFlowGraph()->addEdge(startCheck, returnMinusOne, 0);
+            irm->getFlowGraph()->addEdge(startCheck, returnStart, 1);
+
+            callInstNode->appendInst(irm->newBranchInst(Mnemonic_JE, startCheck, mainNode));
// je startCheck
+
+            startCheck->appendInst(irm->newInst(Mnemonic_CMP, thisLen, start)); //
cmp this.count, start
+            startCheck->appendInst(irm->newBranchInst(Mnemonic_JL, returnMinusOne,
returnStart)); // jl returnMinusOne
+        }
+        else
+        {
+            irm->getFlowGraph()->addEdge(callInstNode, mainNode, 1);
+            irm->getFlowGraph()->addEdge(callInstNode, returnStart, 0);
+            callInstNode->appendInst(irm->newBranchInst(Mnemonic_JE, returnStart, mainNode));
// je returnStart
+        }
+    }
+
+    // prepare this position
+    Opnd* offset = irm->newOpnd(counterType, regConstr);
+    mainNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, offset, thisOffset));
// mov offset, this.offset
+    if (!startIsZero)
+        mainNode->appendInst(irm->newInst(Mnemonic_ADD, offset, start)); // add offset,
start
+    Opnd* thisAddrReg = addElemIndexWithLEA(thisArr, offset, mainNode); // lea edi, [this.value
+ offset*sizeof(char) + 12]
+
+    // prepare trgt position
+    Opnd* trgtAddrReg = addElemIndexWithLEA(trgtArr, trgtOffset, mainNode);  // lea esi,
[subString.value + subString.offset*sizeof(char) + 12]
+    
+    // lastIndex = this.count - subString.count - start
+    Opnd* lastIndex = irm->newOpnd(counterType, regConstr);
+    mainNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, lastIndex, thisLen));
// mov lastIndex, this.count
+    mainNode->appendInst(irm->newInst(Mnemonic_SUB, lastIndex, subLen)); // sub lastIndex,
subLen
+    if (!startIsZero)
+        mainNode->appendInst(irm->newInst(Mnemonic_SUB, lastIndex, start)); // sub
lastIndex, start
+   
+    //save subString's first char
+    Opnd* firstChar = irm->newOpnd(irm->getTypeManager().getCharType(), reg16Constr);
+    mainNode->appendInst(irm->newInst(Mnemonic_MOV, firstChar, irm->newMemOpnd(irm->getTypeManager().getCharType(),
trgtAddrReg, 0, 0, 0))); // mov firstChar, word ptr [esi]
+
+     // preparing main loop iterator
+    Opnd* mainLoopIter = irm->newOpnd(counterType, regConstr);
+    mainNode->appendInst(irm->newInst(Mnemonic_MOV, mainLoopIter, zero)); // mov mainLoopIter,
0
+
+    //*****************************************************************************************************
+
+    // main loop
+    mainLoop->appendInst(irm->newInst(Mnemonic_CMP, mainLoopIter, lastIndex)); // cmp
mainLoopIter, lastIndex
+    mainLoop->appendInst(irm->newBranchInst(Mnemonic_JG, returnMinusOne, mainLoop2));
// jg returnMinusOne
+
+    Opnd* currentChar = irm->newMemOpnd(irm->getTypeManager().getCharType(), thisAddrReg,
0, 0, 0);
+    mainLoop2->appendInst(irm->newInst(Mnemonic_CMP, currentChar, firstChar)); // cmp
word ptr [edi], firstChar
+    mainLoop2->appendInst(irm->newBranchInst(Mnemonic_JNE, mainLoopEnd, mainLoop3));
// jne mainLoopEnd
+
+    // preparing nested loop iterator
+    Opnd* nestedLoopIter = irm->newOpnd(counterType, regConstr);
+    mainLoop3->appendInst(irm->newInst(Mnemonic_MOV, nestedLoopIter, irm->newImmOpnd(counterType,
1))); // mov nestedLoopIter, 1
+
+    nestedLoop->appendInst(irm->newInst(Mnemonic_CMP, nestedLoopIter, subLen)); //
cmp nestedLoopIter, subLen
+    nestedLoop->appendInst(irm->newBranchInst(Mnemonic_JGE, returnIndex, nestedLoop2));
// jge returnIndex
+
+    Opnd* tmp = irm->newRegOpnd(irm->getTypeManager().getCharType(), RegName_DX);
+    nestedLoop2->appendInst(irm->newInst(Mnemonic_MOV, tmp, irm->newMemOpnd(irm->getTypeManager().getCharType(),
thisAddrReg, nestedLoopIter, irm->newImmOpnd(counterType, 2), 0))); // mov tmp, [edi +
2*nestedLoopIter]
+    nestedLoop2->appendInst(irm->newInst(Mnemonic_CMP, tmp, irm->newMemOpnd(irm->getTypeManager().getCharType(),
trgtAddrReg, nestedLoopIter, irm->newImmOpnd(counterType, 2), 0))); // cmp tmp, [esi +
2*nestedLoopIter]
+    nestedLoop2->appendInst(irm->newBranchInst(Mnemonic_JNE, mainLoopEnd, nestedLoop3));
// jne mainLoopEnd
+    
+    nestedLoop3->appendInst(irm->newInst(Mnemonic_ADD, nestedLoopIter, irm->newImmOpnd(counterType,
1))); // add nestedLoopIter, 1
+    
+    mainLoopEnd->appendInst(irm->newInst(Mnemonic_ADD, mainLoopIter, irm->newImmOpnd(counterType,
1))); // add mainLoopIter, 1
+    mainLoopEnd->appendInst(irm->newInst(Mnemonic_ADD, thisAddrReg, irm->newImmOpnd(counterType,
2))); // add edi, 2
+
+    returnMinusOne->appendInst(irm->newInst(Mnemonic_MOV, res, irm->newImmOpnd(res->getType(),
-1)));
+    
+    returnStart->appendInst(irm->newInst(Mnemonic_MOV, res, start));
+
+    returnIndex->appendInst(irm->newInst(Mnemonic_MOV, res, mainLoopIter));
+
+    if (!startIsZero)
+        returnIndex->appendInst(irm->newInst(Mnemonic_ADD, res, start));
+
+    callInst->unlink();
+}
+
 void  APIMagicHandler::convertIntToInt(Opnd* dst, Opnd* src, Node* node) 
 {
     Type* dstType = dst->getType();
@@ -558,5 +759,8 @@
     return dst;
 }
 
+
 }} //namespace
+
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
(original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
Fri Jan 11 06:57:21 2008
@@ -180,6 +180,7 @@
     irManager.registerInternalHelperInfo("fill_array_with_const", IRManager::InternalHelperInfo((void*)&fill_array_with_const,&CallingConvention_STDCALL));
     irManager.registerInternalHelperInfo("String_compareTo", IRManager::InternalHelperInfo(NULL,&CallingConvention_STDCALL));
     irManager.registerInternalHelperInfo("String_regionMatches", IRManager::InternalHelperInfo(NULL,&CallingConvention_STDCALL));
+    irManager.registerInternalHelperInfo("String_indexOf", IRManager::InternalHelperInfo(NULL,&CallingConvention_STDCALL));
 }
 
 //_______________________________________________________________________________________________________________
@@ -2458,7 +2459,7 @@
                                          CG_OpndHandle** args, 
                                          Type*           retType,
                                          MethodDesc *    desc)
-{
+{    
     return tau_call(numArgs, args, retType, desc, getTauUnsafe(), getTauUnsafe());
 }
 
@@ -2571,6 +2572,7 @@
     // does not fit into 32 bits). If on EM64T we set IntPtrType for target address here
constraint resolver work makes all
     // calls a register-form ones. (Even for those with a short offset). But immediate calls
are faster and takes
     // less space. We should keep them when it is possible.
+
     Opnd * target=irManager.newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_MethodDirectAddr,
desc);
     Opnd * retOpnd=createResultOpnd(retType);
     CallInst * callInst=irManager.newCallInst(target, irManager.getDefaultManagedCallingConvention(),

@@ -2695,9 +2697,11 @@
           break;
     }
     case InitializeArray:
+    {
         assert(numArgs == 4);
         appendInsts(irManager.newInternalRuntimeHelperCallInst("initialize_array", numArgs,
(Opnd**)args, dstOpnd));
           break;
+    }
     case SaveThisState:
     {
         assert(numArgs == 1);
@@ -2782,11 +2786,20 @@
     }
     case StringRegionMatches:
     {
+        //printf("%d \n", callId);
         assert(numArgs == 5);
         Opnd * newArgs[5] = {(Opnd *)args[0], (Opnd *)args[1], (Opnd *)args[2], (Opnd *)args[3],
(Opnd *)args[4]};
         appendInsts(irManager.newInternalRuntimeHelperCallInst("String_regionMatches", numArgs,
newArgs, dstOpnd));
         break;
     }
+    case StringIndexOf:
+    {
+        assert(numArgs == 7);
+        Opnd * newArgs[7] = {(Opnd *)args[0], (Opnd *)args[1], (Opnd *)args[2], (Opnd *)args[3],
(Opnd *)args[4], (Opnd *)args[5], (Opnd *)args[6]};
+        appendInsts(irManager.newInternalRuntimeHelperCallInst("String_indexOf", numArgs,
newArgs, dstOpnd));
+        break;
+    }
+
     default:
     {
         assert(0);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp Fri Jan 11 06:57:21
2008
@@ -413,6 +413,7 @@
         case FillArrayWithConst:        return JitHelperCallOp::FillArrayWithConst;
         case StringCompareTo:           return JitHelperCallOp::StringCompareTo;
         case StringRegionMatches:       return JitHelperCallOp::StringRegionMatches;
+        case StringIndexOf:             return JitHelperCallOp::StringIndexOf;
         default: break;
     }
     crash("\n JIT helper in not supported in LIR : %d\n", callId);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp Fri Jan 11 06:57:21
2008
@@ -241,6 +241,100 @@
     cfg.orderNodes(true);
 }
 
+void
+String_indexOf_HLO_Handler::run()
+{
+    IRManager*          irm         = builder->getIRManager();
+    InstFactory&        instFactory = builder->getInstFactory();
+    ControlFlowGraph&   cfg         = builder->getControlFlowGraph();
+
+    Node* firstNode = callInst->getNode();
+    Node* lastNode = cfg.splitNodeAtInstruction(callInst, true, true, instFactory.makeLabel());
+    Node* dispatch = firstNode->getExceptionEdgeTarget();
+    assert(dispatch);
+    callInst->unlink();
+    cfg.removeEdge(firstNode->findEdge(true, lastNode));
+
+    builder->setCurrentBCOffset(callInst->getBCOffset());
+    
+    // the fist two are tau operands
+    Opnd* dst     = callInst->getDst();
+    Opnd* thisStr = callInst->getSrc(2);
+    Opnd* trgtStr = callInst->getSrc(3);
+    Opnd* start = callInst->getSrc(4);
+    
+    Class_Handle string = (Class_Handle)VMInterface::getSystemStringVMTypeHandle();
+    FieldDesc* fieldCountDesc = irm->getCompilationInterface().getFieldByName(string,"count");
+    assert(fieldCountDesc);
+    FieldDesc* fieldValueDesc = irm->getCompilationInterface().getFieldByName(string,"value");
+    assert(fieldValueDesc);
+    FieldDesc* offsetDesc = irm->getCompilationInterface().getFieldByName(string,"offset");
+    assert(offsetDesc);
+
+    // gen at the end of first node
+    builder->setCurrentNode(firstNode);
+    Opnd *tauThisNullChecked = builder->genTauCheckNull(thisStr);
+
+    // node
+    builder->genFallthroughNode(dispatch);
+    Opnd *tauThisInRange = builder->genTauHasType(thisStr, fieldCountDesc->getParentType());
+
+    Opnd *tauTrgtNullChecked = builder->genTauCheckNull(trgtStr);
+
+    // node
+    builder->genFallthroughNode();
+    Opnd* imm128 = builder->genLdConstant(128);
+    Opnd* imm64 = builder->genLdConstant(64);
+    Opnd *tauTrgtInRange = builder->genTauHasType(trgtStr, fieldCountDesc->getParentType());
+
+    // node
+    builder->genFallthroughNode(dispatch);
+
+    // prefetch String objects
+    Opnd * voidDst = builder->createOpnd(irm->getTypeManager().getVoidType());
+    Opnd* prefetchThis[] = {thisStr, imm128, imm64};
+    builder->appendInst(instFactory.makeJitHelperCall(voidDst, Prefetch, 3, prefetchThis));
+
+    // node
+    builder->genFallthroughNode(dispatch);
+    
+    Opnd* prefetchTrgt[] = {trgtStr, imm128, imm64};
+    builder->appendInst(instFactory.makeJitHelperCall(voidDst, Prefetch, 3, prefetchTrgt));
+
+    Opnd* thisLength = builder->genLdField(fieldCountDesc, thisStr, tauThisNullChecked,
tauThisInRange);
+    Opnd* trgtLength = builder->genLdField(fieldCountDesc, trgtStr, tauTrgtNullChecked,
tauTrgtInRange);
+    
+    Opnd* thisOffset = builder->genLdField(offsetDesc, thisStr, tauThisNullChecked, tauThisInRange);
+    Opnd* trgtOffset = builder->genLdField(offsetDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+
+    Opnd* thisValue = builder->genLdField(fieldValueDesc, thisStr, tauThisNullChecked,
tauThisInRange);
+    Opnd* trgtValue = builder->genLdField(fieldValueDesc, trgtStr, tauTrgtNullChecked,
tauTrgtInRange);
+
+    // node
+    builder->genFallthroughNode(dispatch);
+
+    // prefetch character arrays
+    Opnd* prefetchThisValue[] = {thisValue, imm128, imm64};
+    builder->appendInst(instFactory.makeJitHelperCall(voidDst, Prefetch, 3, prefetchThisValue));
+
+    // node
+    builder->genFallthroughNode(dispatch);
+    
+    Opnd* prefetchTrgtValue[] = {trgtValue, imm128, imm64};
+    builder->appendInst(instFactory.makeJitHelperCall(voidDst, Prefetch, 3, prefetchTrgtValue));
+
+    // node
+    builder->genFallthroughNode(dispatch);
+
+    Opnd* opnds[] = {thisValue, thisOffset, thisLength, trgtValue, trgtOffset, trgtLength,
start};
+    // This helper call will be processed in Ia32ApiMagics pass
+    builder->appendInst(instFactory.makeJitHelperCall(dst, StringIndexOf, 7, opnds));
+
+    builder->genEdgeFromCurrent(lastNode);
+
+    cfg.orderNodes(true);
+}
+
 Node*
 HLOAPIMagicIRBuilder::genNodeAfter(Node* srcNode, LabelInst* label, Node* dispatch) {
     currentNode = cfg.createBlockNode(label);
@@ -299,8 +393,6 @@
                                               tauBaseNonNull, tauAddressInRange));
     return fieldVal;
 }
-
-
 
 Opnd*
 HLOAPIMagicIRBuilder::createOpnd(Type* type) {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h Fri Jan 11 06:57:21
2008
@@ -128,6 +128,7 @@
 
 DECLARE_HLO_MAGIC_INLINER(String_compareTo_HLO_Handler);
 DECLARE_HLO_MAGIC_INLINER(String_regionMatches_HLO_Handler);
+DECLARE_HLO_MAGIC_INLINER(String_indexOf_HLO_Handler);
 
 DEFINE_SESSION_ACTION(HLOAPIMagicSession, hlo_api_magic, "APIMagics HLO Pass")
 
@@ -159,6 +160,9 @@
                     } else if (!strcmp(methodName, "regionMatches") && !strcmp(signature,
"(ILjava/lang/String;II)Z")) {
                         if(getBoolArg("String_regionMatches_as_magic", true))
                             handlers.push_back(new (mm) String_regionMatches_HLO_Handler(callInst));
+                    } else if (!strcmp(methodName, "indexOf") && !strcmp(signature,
"(Ljava/lang/String;I)I")) {
+                        if(getBoolArg("String_indexOf_as_magic", false))
+                            handlers.push_back(new (mm) String_indexOf_HLO_Handler(callInst));
                     }
                 }
             }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Fri Jan 11 06:57:21 2008
@@ -482,6 +482,8 @@
         os << "FillArrayWithConst"; break;
     case StringCompareTo:
         os << "StringCompareTo"; break;
+    case StringIndexOf:
+        os << "StringIndexOf"; break;
     case StringRegionMatches:
         os << "StringRegionMatches"; break;
     case ClassIsArray:
@@ -2069,6 +2071,7 @@
     Modifier mod;
     switch(id) {
         case StringCompareTo:
+        case StringIndexOf:
         case StringRegionMatches:
             mod = Modifier(Exception_Never);
             break;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Fri Jan 11 06:57:21 2008
@@ -280,6 +280,7 @@
     AddValueProfileValue,
     StringCompareTo,
     StringRegionMatches,
+    StringIndexOf,
     ClassIsArray,
     ClassGetAllocationHandle,
     ClassGetTypeSize,

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Fri Jan 11 06:57:21
2008
@@ -416,6 +416,7 @@
                         case LockedCompareAndExchange:
                         case AddValueProfileValue:
                         case StringCompareTo:
+                        case StringIndexOf:
                         case StringRegionMatches:
                         case ClassIsArray:
                         case ClassGetAllocationHandle:
@@ -5881,6 +5882,9 @@
 }
 
 } //namespace Jitrino 
+
+
+
 
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp Fri Jan 11 06:57:21
2008
@@ -136,12 +136,16 @@
             _inlineSkipMethodTable->add_method_record("java/lang/Integer", "numberOfTrailingZeros",
"(I)I", des, false);
             _inlineSkipMethodTable->add_method_record("java/lang/Long", "numberOfLeadingZeros",
"(J)I", des, false);
             _inlineSkipMethodTable->add_method_record("java/lang/Long", "numberOfTrailingZeros",
"(J)I", des, false);
+
 #endif
             if(argSource->getBoolArg("String_compareTo_as_magic",true)) {
                 _inlineSkipMethodTable->add_method_record("java/lang/String", "compareTo",
"(Ljava/lang/String;)I", des, false);
             }
             if(argSource->getBoolArg("String_regionMatches_as_magic",true)) {
                 _inlineSkipMethodTable->add_method_record("java/lang/String", "regionMatches",
"(ILjava/lang/String;II)Z", des, false);
+            }
+	    if(argSource->getBoolArg("String_indexOf_as_magic",true)) {
+                _inlineSkipMethodTable->add_method_record("java/lang/String", "indexOf",
"(Ljava/lang/String;I)I", des, false);
             }
 #endif 
         }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp?rev=611195&r1=611194&r2=611195&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Fri Jan 11 06:57:21
2008
@@ -669,6 +669,7 @@
             case LockedCompareAndExchange:
             case AddValueProfileValue:
             case StringCompareTo:
+	    case StringIndexOf:
             case StringRegionMatches:
             case FillArrayWithConst: 
             case ClassIsArray:



Mime
View raw message