harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfur...@apache.org
Subject svn commit: r587413 - in /harmony/enhanced/drlvm/trunk/vm: include/ jitrino/config/ia32/ jitrino/src/codegenerator/ jitrino/src/codegenerator/ia32/ jitrino/src/optimizer/ jitrino/src/shared/ jitrino/src/translator/java/ jitrino/src/vm/ port/src/encoder...
Date Tue, 23 Oct 2007 08:13:58 GMT
Author: mfursov
Date: Tue Oct 23 01:13:56 2007
New Revision: 587413

URL: http://svn.apache.org/viewvc?rev=587413&view=rev
Log:
Fix for HARMONY-4553 [drlvm][jit][perf] String.compareTo method works slowly


Added:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.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/Ia32GCSafePoints.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/Inst.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/deadcodeeliminator.cpp
    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
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h Tue Oct 23 01:13:56 2007
@@ -207,6 +207,9 @@
 VMEXPORT Field_Handle class_get_field(Class_Handle ch, unsigned idx);
 VMEXPORT int          class_get_super_offset();
 
+VMEXPORT Field_Handle   class_get_field_by_name(Class_Handle ch, const char* name);
+VMEXPORT Method_Handle  class_get_method_by_name(Class_Handle ch, const char* name);
+
 VMEXPORT int          class_get_depth(Class_Handle cl);
 //#endif
 //::

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf Tue Oct 23 01:13:56 2007
@@ -53,7 +53,7 @@
 
 -XX:jit.CD_OPT.path=opt_init,lock_method,translator,optimizer,hir2lir,codegen,unlock_method
 
--XX:jit.CD_OPT.path.optimizer=ssa,devirt,inline,purge,simplify,dce,uce,lazyexc,throwopt,memopt,simplify,dce,uce,lower,statprof,unroll,ssa,simplify,dce,uce,dessa,statprof
+-XX:jit.CD_OPT.path.optimizer=ssa,devirt,hlo_api_magic,inline,purge,simplify,dce,uce,lazyexc,throwopt,memopt,simplify,dce,uce,lower,statprof,unroll,ssa,simplify,dce,uce,dessa,statprof
 -XX:jit.CD_OPT.path.codegen=bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info
 -XX:jit.CD_OPT.path.dce1=cg_dce
 -XX:jit.CD_OPT.path.dce2=cg_dce
@@ -63,7 +63,7 @@
 
 #inliner configuration
 -XX:jit.CD_OPT.CD_OPT_inliner_pipeline.filter=-
--XX:jit.CD_OPT.CD_OPT_inliner_pipeline.path=ssa,devirt
+-XX:jit.CD_OPT.CD_OPT_inliner_pipeline.path=ssa,devirt,hlo_api_magic
 -XX:jit.CD_OPT.arg.optimizer.inline.pipeline=CD_OPT_inliner_pipeline
 
 -XX:jit.CD_OPT.arg.codegen.dce1.early=yes

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf Tue Oct 23 01:13:56 2007
@@ -24,7 +24,7 @@
 
 -XX:jit.CS_OPT.path=opt_init,lock_method,translator,optimizer,hir2lir,codegen,unlock_method
 
--XX:jit.CS_OPT.path.optimizer=ssa,devirt,inline,purge,simplify,dce,uce,lazyexc,throwopt,escape,dce,uce,memopt,simplify,dce,uce,lower,statprof,unroll,ssa,simplify,dce,uce,dessa,statprof
+-XX:jit.CS_OPT.path.optimizer=ssa,devirt,hlo_api_magic,inline,purge,simplify,dce,uce,lazyexc,throwopt,escape,dce,uce,memopt,simplify,dce,uce,lower,statprof,unroll,ssa,simplify,dce,uce,dessa,statprof
 -XX:jit.CS_OPT.path.codegen=bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info
 -XX:jit.CS_OPT.path.dce1=cg_dce
 -XX:jit.CS_OPT.path.dce2=cg_dce
@@ -34,7 +34,7 @@
 
 #inliner configuration
 -XX:jit.CS_OPT.CS_OPT_inliner_pipeline.filter=-
--XX:jit.CS_OPT.CS_OPT_inliner_pipeline.path=ssa,devirt
+-XX:jit.CS_OPT.CS_OPT_inliner_pipeline.path=ssa,devirt,hlo_api_magic
 -XX:jit.CS_OPT.arg.optimizer.inline.pipeline=CS_OPT_inliner_pipeline
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Tue Oct 23 01:13:56 2007
@@ -71,7 +71,7 @@
 
 -XX:jit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
--XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,purge,simplify,dce,uce,lazyexc,throwopt,so2-,simplify,dce,uce,escape,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,statprof,unroll,ssa,simplify,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
+-XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,hlo_api_magic,inline,purge,simplify,dce,uce,lazyexc,throwopt,so2-,simplify,dce,uce,escape,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,statprof,unroll,ssa,simplify,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
 -XX:jit.SD2_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XX:jit.SD2_OPT.path.dce1=cg_dce
 -XX:jit.SD2_OPT.path.dce2=cg_dce
@@ -85,7 +85,7 @@
 
 #inliner configuration
 -XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.filter=-
--XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.path=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf
+-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.path=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,hlo_api_magic
 -XX:jit.SD2_OPT.arg.optimizer.inline.pipeline=SD2_OPT_inliner_pipeline
 -XX:jit.SD2_OPT.arg.optimizer.inline.connect_early=false
 #devirt configuration for inliner pipeline

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf Tue Oct 23 01:13:56 2007
@@ -24,7 +24,7 @@
 
 -XX:jit.SS_OPT.path=opt_init,lock_method,translator,optimizer,hir2lir,codegen,unlock_method
 
--XX:jit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,statprof,devirt,inline,purge,simplify,dce,uce,lazyexc,throwopt,statprof,hvn,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,unroll,ssa,simplify,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,statprof
+-XX:jit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,statprof,devirt,hlo_api_magic,inline,purge,simplify,dce,uce,lazyexc,throwopt,statprof,hvn,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,unroll,ssa,simplify,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,classic_abcd,dce,uce,gcm,dessa,statprof
 -XX:jit.SS_OPT.path.codegen=bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info
 -XX:jit.SS_OPT.path.dce1=cg_dce
 -XX:jit.SS_OPT.path.dce2=cg_dce
@@ -34,7 +34,7 @@
 
 #inliner configuration
 -XX:jit.SS_OPT.SS_OPT_inliner_pipeline.filter=-
--XX:jit.SS_OPT.SS_OPT_inliner_pipeline.path=ssa,simplify,dce,uce,statprof,devirt
+-XX:jit.SS_OPT.SS_OPT_inliner_pipeline.path=ssa,simplify,dce,uce,statprof,devirt,hlo_api_magic
 -XX:jit.SS_OPT.arg.optimizer.inline.pipeline=SS_OPT_inliner_pipeline
 
 -XX:jit.SS_OPT.arg.codegen.dce1.early=yes

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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Tue Oct 23 01:13:56 2007
@@ -169,7 +169,9 @@
         SaveThisState,
         ReadThisState,
         LockedCompareAndExchange,
-        AddValueProfileValue
+        AddValueProfileValue,
+        StringCompareTo,
+        StringRegionMatches
     };
 };
 

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=587413&r1=587412&r2=587413&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 Tue Oct 23 01:13:56 2007
@@ -60,6 +60,8 @@
     virtual void run()=0;
 protected:
 
+    Opnd*  addElemIndexWithLEA(Opnd* array, Opnd* index, Node* node);
+
     IRManager* irm;
     CallInst* callInst;
     MethodDesc*  md;
@@ -79,6 +81,8 @@
 DECLARE_HELPER_INLINER(Integer_numberOfTrailingZeros_Handler_x_I_x_I);
 DECLARE_HELPER_INLINER(Long_numberOfLeadingZeros_Handler_x_J_x_I);
 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);
 
 void APIMagicsHandlerSession::runImpl() {
     CompilationContext* cc = getCompilationContext();
@@ -92,34 +96,45 @@
         Node* node = *it;
         if (node->isBlockNode()) {
             for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) {
-                if (!inst->hasKind(Inst::Kind_CallInst) || !((CallInst*)inst)->isDirect()) {
+                if (!inst->hasKind(Inst::Kind_CallInst)) {
                     continue;
                 }
-                CallInst* callInst = (CallInst*)inst;
-                Opnd * targetOpnd=callInst->getOpnd(callInst->getTargetOpndIndex());
-                assert(targetOpnd->isPlacedIn(OpndKind_Imm));
-                Opnd::RuntimeInfo * ri=targetOpnd->getRuntimeInfo();
-                if( !ri || ri->getKind() != Opnd::RuntimeInfo::Kind_MethodDirectAddr) { 
-                    continue; 
-                };
-                MethodDesc * md = (MethodDesc*)ri->getValue(0);
-                const char* className = md->getParentType()->getName();
-                const char* methodName = md->getName();
-                const char* signature = md->getSignatureString();
-                if (!strcmp(className, "java/lang/Integer")) {
-                    if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(I)I")) {
-                        handlers.push_back(new (tmpMM) Integer_numberOfLeadingZeros_Handler_x_I_x_I(irm, callInst, md));
-                    } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(I)I")) {
-                        handlers.push_back(new (tmpMM) Integer_numberOfTrailingZeros_Handler_x_I_x_I(irm, callInst, md));
-                    }
-                } else if (!strcmp(className, "java/lang/Long")) {
-                    if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(J)I")) {
-                        handlers.push_back(new (tmpMM) Long_numberOfLeadingZeros_Handler_x_J_x_I(irm, callInst, md));
-                    } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(J)I")) {
-                        handlers.push_back(new (tmpMM) Long_numberOfTrailingZeros_Handler_x_J_x_I(irm, callInst, md));
+                if ( ((CallInst*)inst)->isDirect() ) {
+                    CallInst* callInst = (CallInst*)inst;
+                    Opnd * targetOpnd=callInst->getOpnd(callInst->getTargetOpndIndex());
+                    assert(targetOpnd->isPlacedIn(OpndKind_Imm));
+                    Opnd::RuntimeInfo * ri=targetOpnd->getRuntimeInfo();
+                    if( !ri ) { 
+                        continue; 
+                    };
+                    if( ri->getKind() == Opnd::RuntimeInfo::Kind_MethodDirectAddr ){
+                        MethodDesc * md = (MethodDesc*)ri->getValue(0);
+                        const char* className = md->getParentType()->getName();
+                        const char* methodName = md->getName();
+                        const char* signature = md->getSignatureString();
+                        if (!strcmp(className, "java/lang/Integer")) {
+                            if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(I)I")) {
+                                handlers.push_back(new (tmpMM) Integer_numberOfLeadingZeros_Handler_x_I_x_I(irm, callInst, md));
+                            } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(I)I")) {
+                                handlers.push_back(new (tmpMM) Integer_numberOfTrailingZeros_Handler_x_I_x_I(irm, callInst, md));
+                            }
+                        } else if (!strcmp(className, "java/lang/Long")) {
+                            if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(J)I")) {
+                                handlers.push_back(new (tmpMM) Long_numberOfLeadingZeros_Handler_x_J_x_I(irm, callInst, md));
+                            } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(J)I")) {
+                                handlers.push_back(new (tmpMM) Long_numberOfTrailingZeros_Handler_x_J_x_I(irm, callInst, md));
+                            }
+                        }
+                    } else if( ri->getKind() == Opnd::RuntimeInfo::Kind_InternalHelperAddress ) {
+                        if( strcmp((char*)ri->getValue(0),"String_compareTo")==0 ) {
+                            if(getBoolArg("String_compareTo_as_magic", true))
+                                handlers.push_back(new (tmpMM) String_compareTo_Handler_x_String_x_I(irm, callInst, NULL));
+                        } 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));
+                        }
                     }
                 }
-
             }
         }
     }
@@ -294,6 +309,238 @@
     cfg->addEdge(zeroNode, nextNode);
 
 #endif
+}
+
+void String_compareTo_Handler_x_String_x_I::run() {
+    //mov ds:esi, this
+    //mov es:edi, src
+    //mov ecx, min(this.count, src.count)
+    //repne cmpw
+    //if ZF == 0 (one of strings is a prefix)
+    //  return this.count - src.count
+    //else
+    //  return [ds:esi-2] - [es:edi-2]
+
+    Node* callInstNode = callInst->getNode();
+    Node* nextNode = callInstNode->getUnconditionalEdgeTarget();
+    assert(nextNode!=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* thisIdx = getCallSrc(callInst, 1);
+    Opnd* thisLen = getCallSrc(callInst, 2);
+    Opnd* trgtArr = getCallSrc(callInst, 3);
+    Opnd* trgtIdx = getCallSrc(callInst, 4);
+    Opnd* trgtLen = getCallSrc(callInst, 5);
+    Opnd* valForCounter = getCallSrc(callInst, 6);
+    Opnd* res = getCallDst(callInst);
+
+#ifdef _EM64T_
+    RegName counterRegName = RegName_RCX;
+    RegName thisAddrRegName = RegName_RSI;
+    RegName trgtAddrRegName = RegName_RDI;
+    Type*   counterType = irm->getTypeManager().getInt64Type();
+#else
+    RegName counterRegName = RegName_ECX;
+    RegName thisAddrRegName = RegName_ESI;
+    RegName trgtAddrRegName = RegName_EDI;
+    Type*   counterType = irm->getTypeManager().getInt32Type();
+#endif
+
+    Node* counterIsZeroNode = irm->getFlowGraph()->createBlockNode();
+    // if counter is zero jump to counterIsZeroNode immediately
+    callInstNode->appendInst(irm->newInst(Mnemonic_TEST, valForCounter, valForCounter));
+    BranchInst* br = irm->newBranchInst(Mnemonic_JZ, NULL, NULL);
+    callInstNode->appendInst(br);
+    Node* node = irm->getFlowGraph()->createBlockNode();
+    br->setTrueTarget(counterIsZeroNode);
+    br->setFalseTarget(node);
+    irm->getFlowGraph()->addEdge(counterIsZeroNode, nextNode, 1);
+    irm->getFlowGraph()->addEdge(callInstNode, counterIsZeroNode, 0.05);
+    irm->getFlowGraph()->addEdge(callInstNode, node, 0.95);
+
+    // prepare counter
+    Opnd* counter = irm->newRegOpnd(counterType,counterRegName);
+    node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, counter, valForCounter));
+
+    // prepare this position
+    Opnd* thisAddr = addElemIndexWithLEA(thisArr,thisIdx,node);
+    Opnd* thisAddrReg = irm->newRegOpnd(thisAddr->getType(),thisAddrRegName);
+    node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, thisAddrReg, thisAddr));
+
+    // prepare trgt position
+    Opnd* trgtAddr = addElemIndexWithLEA(trgtArr,trgtIdx,node);
+    Opnd* trgtAddrReg = irm->newRegOpnd(trgtAddr->getType(),trgtAddrRegName);
+    node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, trgtAddrReg, trgtAddr));
+
+    Inst* compareInst = irm->newInst(Mnemonic_CMPSW,thisAddrReg,trgtAddrReg,counter);
+    compareInst->setPrefix(InstPrefix_REPZ);
+    node->appendInst(compareInst);
+
+    // counter is 0 means the same as last comparison leaves zero at ZF
+    br = irm->newBranchInst(Mnemonic_JZ, NULL, NULL);
+    node->appendInst(br);
+
+    Node* differentStringsNode = irm->getFlowGraph()->createBlockNode();
+    br->setTrueTarget(counterIsZeroNode);
+    br->setFalseTarget(differentStringsNode);
+    irm->getFlowGraph()->addEdge(node, counterIsZeroNode, 0.5);
+    irm->getFlowGraph()->addEdge(node, differentStringsNode, 0.5);
+    irm->getFlowGraph()->addEdge(differentStringsNode, nextNode, 1);
+
+    // counter is zero
+    counterIsZeroNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, res, thisLen, trgtLen));
+
+    // strings are different
+    Opnd* two = irm->newImmOpnd(counterType,2);
+    differentStringsNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, thisAddrReg, thisAddrReg, two));
+    differentStringsNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, trgtAddrReg, trgtAddrReg, two));
+    Type* charType = irm->getTypeManager().getCharType();
+    Opnd* thisChar = irm->newMemOpnd(charType, thisAddrReg);
+    Opnd* trgtChar = irm->newMemOpnd(charType, trgtAddrReg);
+    Opnd* dst = irm->newOpnd(charType);
+    differentStringsNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, dst, thisChar, trgtChar));
+    differentStringsNode->appendInst(irm->newInstEx(Mnemonic_MOVSX, 1, res, dst));
+
+    callInst->unlink();
+}
+
+void String_regionMatches_Handler_x_I_x_String_x_I_x_I_x_Z::run() {
+    //mov ds:esi, this
+    //mov es:edi, src
+    //mov ecx, counter
+    //repne cmpw
+    //if ZF == 0 (one of strings is a prefix)
+    //  return this.count - src.count
+    //else
+    //  return [ds:esi-2] - [es:edi-2]
+
+    Node* node = callInst->getNode();
+    Node* nextNode = NULL;
+
+    if(callInst == node->getLastInst()) {
+        nextNode = node->getUnconditionalEdgeTarget();
+        assert(nextNode!=NULL);
+    } else {
+        nextNode = irm->getFlowGraph()->splitNodeAtInstruction(callInst, true, true, NULL);
+    }
+    cfg->removeEdge(node->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* thisIdx = getCallSrc(callInst, 1);
+    Opnd* trgtArr = getCallSrc(callInst, 2);
+    Opnd* trgtIdx = getCallSrc(callInst, 3);
+    Opnd* valForCounter = getCallSrc(callInst, 4);
+    Opnd* res = getCallDst(callInst);
+
+#ifdef _EM64T_
+    RegName counterRegName = RegName_RCX;
+    RegName thisAddrRegName = RegName_RSI;
+    RegName trgtAddrRegName = RegName_RDI;
+    Type*   counterType = irm->getTypeManager().getInt64Type();
+#else
+    RegName counterRegName = RegName_ECX;
+    RegName thisAddrRegName = RegName_ESI;
+    RegName trgtAddrRegName = RegName_EDI;
+    Type*   counterType = irm->getTypeManager().getInt32Type();
+#endif
+
+    // prepare counter
+    Opnd* counter = irm->newRegOpnd(counterType,counterRegName);
+    node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, counter, valForCounter));
+
+    // prepare this position
+    Opnd* thisAddr = addElemIndexWithLEA(thisArr,thisIdx,node);
+    Opnd* thisAddrReg = irm->newRegOpnd(thisAddr->getType(),thisAddrRegName);
+    node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, thisAddrReg, thisAddr));
+
+    // prepare trgt position
+    Opnd* trgtAddr = addElemIndexWithLEA(trgtArr,trgtIdx,node);
+    Opnd* trgtAddrReg = irm->newRegOpnd(trgtAddr->getType(),trgtAddrRegName);
+    node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, trgtAddrReg, trgtAddr));
+
+    Inst* compareInst = irm->newInst(Mnemonic_CMPSW,thisAddrReg,trgtAddrReg,counter);
+    compareInst->setPrefix(InstPrefix_REPZ);
+    node->appendInst(compareInst);
+
+    // counter is 0 means the same as last comparison leaves zero at ZF
+    BranchInst* br = irm->newBranchInst(Mnemonic_JZ, NULL, NULL);
+    node->appendInst(br);
+
+    Node* sameRegionsNode = irm->getFlowGraph()->createBlockNode();
+    Node* diffRegionsNode = irm->getFlowGraph()->createBlockNode();
+    br->setTrueTarget(sameRegionsNode);
+    br->setFalseTarget(diffRegionsNode);
+    irm->getFlowGraph()->addEdge(node, sameRegionsNode, 0.5);
+    irm->getFlowGraph()->addEdge(sameRegionsNode, nextNode, 1);
+    irm->getFlowGraph()->addEdge(node, diffRegionsNode, 0.5);
+    irm->getFlowGraph()->addEdge(diffRegionsNode, nextNode, 1);
+
+    // regions are equal
+    Opnd* one = irm->newImmOpnd(res->getType(),1);
+    sameRegionsNode->appendInst(irm->newInst(Mnemonic_MOV, res, one));
+
+    // regions are different
+    Opnd* zero = irm->newImmOpnd(res->getType(),0);
+    diffRegionsNode->appendInst(irm->newInst(Mnemonic_MOV, res, zero));
+
+    callInst->unlink();
+}
+
+//  Compute address of the array element given 
+//  address of the first element and index
+//  using 'LEA' instruction
+
+Opnd*  APIMagicHandler::addElemIndexWithLEA(Opnd* array, Opnd* index, Node* node) 
+{
+    ArrayType * arrayType=((Opnd*)array)->getType()->asArrayType();
+    Type * elemType=arrayType->getElementType();
+    Type * dstType=irm->getManagedPtrType(elemType);
+
+    TypeManager& typeManager = irm->getTypeManager();
+#ifdef _EM64T_
+    Type * indexType = typeManager.getInt64Type();
+    Type * offType = typeManager.getInt64Type();
+#else
+    Type * indexType = typeManager.getInt32Type();
+    Type * offType = typeManager.getInt32Type();
+#endif
+        
+    uint32 elemSize = 0;
+    if (elemType->isReference()
+        && Type::isCompressedReference(elemType->tag, irm->getCompilationInterface()) 
+        && !elemType->isCompressedReference()) {
+        elemSize = 4;
+    } else {
+        elemSize = getByteSize(irm->getTypeSize(elemType));
+    }
+    Opnd * elemSizeOpnd  = irm->newImmOpnd(indexType, elemSize);
+    
+    Opnd * indexOpnd = index;
+    assert(index->getType() == indexType); //when this assertion fails 'convert' should be implemented
+//    indexOpnd = convert(indexOpnd, indexType);
+
+    if ( indexOpnd->isPlacedIn(OpndKind_Imm) ) {
+        // we need to put index operand on a register to satisfy LEA constraint
+        int64 immValue = indexOpnd->getImmValue();
+        if (immValue == 0) {
+            indexOpnd = NULL;
+            elemSizeOpnd = NULL;
+        } else {
+            Opnd * indexReg = irm->newOpnd(indexType);
+            node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, indexReg, indexOpnd));
+            indexOpnd = indexReg;
+        }
+    }    
+    Opnd * arrOffset = irm->newImmOpnd(offType, arrayType->getArrayElemOffset());
+    Opnd * addr = irm->newMemOpnd(dstType,(Opnd*)array, indexOpnd, elemSizeOpnd, arrOffset);
+    Opnd * dst = irm->newOpnd(dstType);
+    node->appendInst(irm->newInstEx(Mnemonic_LEA, 1, dst, addr));
+    return dst;
 }
 
 }} //namespace

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp Tue Oct 23 01:13:56 2007
@@ -513,7 +513,10 @@
         if (inst->hasKind(Inst::Kind_ControlTransferInst) ||
             inst->getMnemonic() == Mnemonic_MOVS8         ||
             inst->getMnemonic() == Mnemonic_MOVS16        ||
-            inst->getMnemonic() == Mnemonic_MOVS32        ) {
+            inst->getMnemonic() == Mnemonic_MOVS32        ||
+            inst->getMnemonic() == Mnemonic_CMPSB         ||
+            inst->getMnemonic() == Mnemonic_CMPSW         ||
+            inst->getMnemonic() == Mnemonic_CMPSD         ) {
             //Do nothing, calls return only bases
         } else {
             Opnd* fromOpnd = NULL;
@@ -532,9 +535,7 @@
                     fromOpnd = inst->getOpnd(useIndex1);
                     break;                
                 case Mnemonic_ADD: { 
-#ifdef _EM64T_
                 case Mnemonic_SUB:
-#endif
                         fromOpnd = opnd;
                         Opnd* offsetOpnd = inst->getOpnd(useIndex1);
                         Opnd* immOffset = findImmediateSource(offsetOpnd);

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=587413&r1=587412&r2=587413&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 Tue Oct 23 01:13:56 2007
@@ -178,6 +178,8 @@
     irManager.registerInternalHelperInfo("add_value_profile_value", IRManager::InternalHelperInfo((void*)&add_value_profile_value,&CallingConvention_STDCALL));
 
     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));
 }
 
 //_______________________________________________________________________________________________________________
@@ -2686,6 +2688,20 @@
         assert(numArgs == 4);
         Opnd * newArgs[4] = {(Opnd *)args[0], (Opnd *)args[1], (Opnd *)args[2], (Opnd *)args[3]};
         appendInsts(irManager.newInternalRuntimeHelperCallInst("fill_array_with_const", numArgs, newArgs, dstOpnd));
+        break;
+    }
+    case StringCompareTo:
+    {
+        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_compareTo", numArgs, newArgs, dstOpnd));
+        break;
+    }
+    case StringRegionMatches:
+    {
+        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;
     }
     default:

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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp Tue Oct 23 01:13:56 2007
@@ -403,12 +403,14 @@
 
 JitHelperCallOp::Id _BlockCodeSelector::convertJitHelperId(JitHelperCallId callId) {
     switch(callId) {
-    case InitializeArray: return JitHelperCallOp::InitializeArray;
-    case SaveThisState: return JitHelperCallOp::SaveThisState;
-    case ReadThisState: return JitHelperCallOp::ReadThisState;
-    case LockedCompareAndExchange: return JitHelperCallOp::LockedCompareAndExchange;
-    case AddValueProfileValue: return JitHelperCallOp::AddValueProfileValue;
-    case FillArrayWithConst: return JitHelperCallOp::FillArrayWithConst;
+    case InitializeArray:           return JitHelperCallOp::InitializeArray;
+    case SaveThisState:             return JitHelperCallOp::SaveThisState;
+    case ReadThisState:             return JitHelperCallOp::ReadThisState;
+    case LockedCompareAndExchange:  return JitHelperCallOp::LockedCompareAndExchange;
+    case AddValueProfileValue:      return JitHelperCallOp::AddValueProfileValue;
+    case FillArrayWithConst:        return JitHelperCallOp::FillArrayWithConst;
+    case StringCompareTo:           return JitHelperCallOp::StringCompareTo;
+    case StringRegionMatches:       return JitHelperCallOp::StringRegionMatches;
     }
     assert(0);
     return JitHelperCallOp::InitializeArray; // to keep compiler quiet

Added: 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=587413&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp Tue Oct 23 01:13:56 2007
@@ -0,0 +1,470 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Intel, George A. Timoshenko
+ */
+
+#include "HLOAPIMagics.h"
+#include "Opcode.h"
+#include "PMF.h"
+#include "VMInterface.h"
+
+namespace Jitrino {
+
+void
+String_compareTo_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);
+    
+    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);
+    // this field is optional
+    FieldDesc* offsetDesc = irm->getCompilationInterface().getFieldByName(string,"offset");
+    Type* fieldType = fieldCountDesc->getFieldType();
+    Type::Tag fieldTag = fieldType->tag;
+
+    // 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* thisLength = builder->genLdField(fieldCountDesc, thisStr, tauThisNullChecked, tauThisInRange);
+    Opnd *tauTrgtNullChecked = builder->genTauCheckNull(trgtStr);
+
+    // node
+    Node* branch = builder->genFallthroughNode();
+    Opnd *tauTrgtInRange = builder->genTauHasType(trgtStr, fieldCountDesc->getParentType());
+    Opnd* trgtLength = builder->genLdField(fieldCountDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+
+    LabelInst * ThisIsLonger = (LabelInst*)instFactory.makeLabel();
+    builder->appendInst(instFactory.makeBranch(Cmp_GT,fieldTag,thisLength,trgtLength,ThisIsLonger));
+
+    VarOpnd* counterVar = builder->createVarOpnd(fieldType,false);
+
+    // node (trgt is longer here)
+    builder->genFallthroughNode();
+    SsaVarOpnd* thisLengthVar = builder->createSsaVarOpnd(counterVar);
+    builder->genStVar(thisLengthVar,thisLength);
+    builder->genEdgeFromCurrent(lastNode); // jump to merge
+
+    // node (this is longer here)
+    builder->genNodeAfter(branch,ThisIsLonger);
+    SsaVarOpnd* trgtLengthVar = builder->createSsaVarOpnd(counterVar);
+    builder->genStVar(trgtLengthVar,trgtLength);
+    builder->genEdgeFromCurrent(lastNode); // jump to merge
+
+    // last node (merge after counter definition)
+    builder->setCurrentNode(lastNode);
+    // gather counter value
+    Opnd* phiArgs[] = {thisLengthVar,trgtLengthVar};
+    SsaVarOpnd* var = builder->createSsaVarOpnd(counterVar);
+    lastNode->appendInst(instFactory.makePhi(var,2,phiArgs));
+    Opnd* counter = builder->createOpnd(fieldType);
+    lastNode->appendInst(instFactory.makeLdVar(counter,var));
+    Opnd* thisStart = builder->genLdConstant(0);
+    Opnd* trgtStart = builder->genLdConstant(0);
+    if(offsetDesc) {
+        Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
+        Opnd* thisOffset = builder->genLdField(offsetDesc, thisStr, tauThisNullChecked, tauThisInRange);
+        Opnd* trgtOffset = builder->genLdField(offsetDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+        thisStart = builder->genAdd(fieldType, mod, thisOffset, thisStart);
+        trgtStart = builder->genAdd(fieldType, mod, trgtOffset, trgtStart);
+    }
+    Opnd* thisValue = builder->genLdField(fieldValueDesc, thisStr, tauThisNullChecked, tauThisInRange);
+    Opnd* trgtValue = builder->genLdField(fieldValueDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+    Opnd* opnds[] = {thisValue,thisStart,thisLength,trgtValue,trgtStart,trgtLength,counter};
+
+    // This helper call will be processed in Ia32ApiMagics pass
+    builder->appendInst(instFactory.makeJitHelperCall(dst, StringCompareTo, 7, opnds));
+
+    cfg.orderNodes(true);
+}
+
+void
+String_regionMatches_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* thisStart = callInst->getSrc(3);
+    Opnd* trgtStr   = callInst->getSrc(4);
+    Opnd* trgtStart = callInst->getSrc(5);
+    Opnd* counter   = callInst->getSrc(6);
+
+    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);
+    // this field is optional
+    FieldDesc* offsetDesc = irm->getCompilationInterface().getFieldByName(string,"offset");
+
+    Type* fieldType = fieldCountDesc->getFieldType();
+    Type::Tag fieldTag = fieldType->tag;
+
+    // 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);
+
+    LabelInst * FalseResult = (LabelInst*)instFactory.makeLabel();
+    Node* returnFalse = cfg.createBlockNode(FalseResult);
+
+    // node
+    builder->genFallthroughNode();
+    Opnd* zero = builder->genLdConstant(0);
+    Opnd *tauTrgtInRange = builder->genTauHasType(trgtStr, fieldCountDesc->getParentType());
+    builder->appendInst(instFactory.makeBranch(Cmp_GT,fieldTag,zero,trgtStart,FalseResult));
+    builder->genEdgeFromCurrent(returnFalse);
+
+    // node
+    builder->genFallthroughNode();
+    builder->appendInst(instFactory.makeBranch(Cmp_GT,fieldTag,zero,thisStart,FalseResult));
+    builder->genEdgeFromCurrent(returnFalse);
+
+    Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
+
+    // node
+    builder->genFallthroughNode();
+    Opnd* trgtLength = builder->genLdField(fieldCountDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+    Opnd* trgtDiff = builder->genSub(fieldType, mod,trgtLength,trgtStart);
+    builder->appendInst(instFactory.makeBranch(Cmp_GT,fieldTag,counter,trgtDiff,FalseResult));
+    builder->genEdgeFromCurrent(returnFalse);
+
+    // node
+    builder->genFallthroughNode();
+    Opnd* thisLength = builder->genLdField(fieldCountDesc, thisStr, tauThisNullChecked, tauThisInRange);
+    Opnd* thisDiff = builder->genSub(fieldType, mod,thisLength,thisStart);
+    builder->appendInst(instFactory.makeBranch(Cmp_GT,fieldTag,counter,thisDiff,FalseResult));
+    builder->genEdgeFromCurrent(returnFalse);
+
+    LabelInst * TrueResult = (LabelInst*)instFactory.makeLabel();
+    Node* returnTrue = cfg.createBlockNode(TrueResult);
+
+    // node
+    builder->genFallthroughNode();
+    builder->appendInst(instFactory.makeBranch(Cmp_GTE,fieldTag,zero,counter,TrueResult));
+    builder->genEdgeFromCurrent(returnTrue);
+
+    // node
+    builder->genFallthroughNode();
+    if(offsetDesc) {
+        Opnd* thisOffset = builder->genLdField(offsetDesc, thisStr, tauThisNullChecked, tauThisInRange);
+        Opnd* trgtOffset = builder->genLdField(offsetDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+        thisStart = builder->genAdd(fieldType, mod, thisOffset, thisStart);
+        trgtStart = builder->genAdd(fieldType, mod, trgtOffset, trgtStart);
+    }
+    Opnd* thisValue = builder->genLdField(fieldValueDesc, thisStr, tauThisNullChecked, tauThisInRange);
+    Opnd* trgtValue = builder->genLdField(fieldValueDesc, trgtStr, tauTrgtNullChecked, tauTrgtInRange);
+    Opnd* opnds[] = {thisValue,thisStart,trgtValue,trgtStart,counter};
+
+    // This helper call will be processed in Ia32ApiMagics pass
+    VarOpnd* resultVar = builder->createVarOpnd(dst->getType(),false);
+    SsaVarOpnd* resVar = builder->createSsaVarOpnd(resultVar);
+    Opnd* res = builder->createOpnd(dst->getType());
+    builder->appendInst(instFactory.makeJitHelperCall(res, StringRegionMatches, 5, opnds));
+    builder->genStVar(resVar,res);
+    builder->genEdgeFromCurrent(lastNode);
+
+    // returnFalse
+    builder->setCurrentNode(returnFalse);
+    Opnd* resFalse  = builder->genLdConstant(0);
+    SsaVarOpnd* resFalseVar = builder->createSsaVarOpnd(resultVar);
+    builder->genStVar(resFalseVar,resFalse);
+    builder->genEdgeFromCurrent(lastNode);
+
+    // returnTrue
+    builder->setCurrentNode(returnTrue);
+    Opnd* resTrue  = builder->genLdConstant(1);
+    SsaVarOpnd* resTrueVar = builder->createSsaVarOpnd(resultVar);
+    builder->genStVar(resTrueVar,resTrue);
+    builder->genEdgeFromCurrent(lastNode);
+
+    // lastNode
+    Opnd* phiArgs[] = {resVar,resFalseVar,resTrueVar};
+    SsaVarOpnd* var = builder->createSsaVarOpnd(resultVar);
+    lastNode->appendInst(instFactory.makePhi(var,3,phiArgs));
+    lastNode->appendInst(instFactory.makeLdVar(dst,var));
+
+    cfg.orderNodes(true);
+}
+
+Node*
+HLOAPIMagicIRBuilder::genNodeAfter(Node* srcNode, LabelInst* label, Node* dispatch) {
+    currentNode = cfg.createBlockNode(label);
+    cfg.addEdge(srcNode, currentNode);
+    if (dispatch != NULL) {
+        cfg.addEdge(currentNode, dispatch, 0.001);
+    }
+    return currentNode;
+}
+
+Node*
+HLOAPIMagicIRBuilder::genNodeAfterCurrent(LabelInst* label, Node* dispatch) {
+    return genNodeAfter(currentNode,label,dispatch);
+}
+
+Node*
+HLOAPIMagicIRBuilder::genFallthroughNode(Node* dispatch) {
+    return genNodeAfter(currentNode,instFactory.makeLabel(),dispatch);
+}
+
+void
+HLOAPIMagicIRBuilder::appendInst(Inst* inst) {
+    inst->setBCOffset(currentBCOffset);
+    currentNode->appendInst(inst);
+}
+
+void
+HLOAPIMagicIRBuilder::genCopy(Opnd* trgt, Opnd* src) {
+    appendInst(instFactory.makeCopy(trgt,src));
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genLdField(FieldDesc* fieldDesc, Opnd* base,
+                                 Opnd* tauBaseNonNull, Opnd* tauAddressInRange) {
+    Type* fieldType = fieldDesc->getFieldType();
+    assert(fieldType);
+
+    Opnd* fieldAddr;
+    Modifier mod;
+
+    if (compRefs) {
+        // until VM type system is upgraded,
+        // fieldDesc type will have uncompressed ref type;
+        // compress it
+        Type *compressedType = typeManager.compressType(fieldType);
+        fieldAddr = createOpnd(typeManager.getManagedPtrType(compressedType));
+        mod = AutoCompress_Yes;
+    } else {
+        fieldAddr = createOpnd(typeManager.getManagedPtrType(fieldType));
+        mod = AutoCompress_No;
+    }
+    appendInst(instFactory.makeLdFieldAddr(fieldAddr, base, fieldDesc));
+
+    Opnd* fieldVal = createOpnd(fieldType);
+    appendInst(instFactory.makeTauLdInd(mod, fieldType->tag, fieldVal, fieldAddr, 
+                                              tauBaseNonNull, tauAddressInRange));
+    return fieldVal;
+}
+
+
+
+Opnd*
+HLOAPIMagicIRBuilder::createOpnd(Type* type) {
+    if (type->tag == Type::Void)
+        return OpndManager::getNullOpnd();
+    return opndManager.createSsaTmpOpnd(type);
+}
+
+VarOpnd*
+HLOAPIMagicIRBuilder::createVarOpnd(Type* type, bool isPinned) {
+    assert(type->tag != Type::Void);
+    return opndManager.createVarOpnd(type,isPinned);
+}
+
+SsaVarOpnd*
+HLOAPIMagicIRBuilder::createSsaVarOpnd(VarOpnd* var) {
+    return opndManager.createSsaVarOpnd(var);
+}
+
+void
+HLOAPIMagicIRBuilder::genStVar(SsaVarOpnd* var, Opnd* src) {
+    appendInst(instFactory.makeStVar(var, src));
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauCheckNull(Opnd* base)
+{
+    Opnd* dst = createOpnd(typeManager.getTauType());
+    Inst* inst = instFactory.makeTauCheckNull(dst, base);
+    appendInst(inst);
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genAnd(Type* dstType, Opnd* src1, Opnd* src2) {   
+    Opnd* dst = createOpnd(dstType);
+    appendInst(instFactory.makeAnd(dst, src1, src2));
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauAnd(Opnd *src1, Opnd *src2) {
+    if (src1->getId() > src2->getId()) {
+        Opnd *tmp = src1;
+        src1 = src2;
+        src2 = tmp;
+    }
+    Opnd* dst = createOpnd(typeManager.getTauType());
+    Opnd* srcs[2] = { src1, src2 };
+    appendInst(instFactory.makeTauAnd(dst, 2, srcs));
+
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genAdd(Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {    
+    Opnd* dst = createOpnd(dstType);
+    Inst *newi = instFactory.makeAdd(mod, dst, src1, src2);
+    appendInst(newi);
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genSub(Type* dstType, Modifier mod, Opnd* src1, Opnd* src2) {    
+    Opnd* dst = createOpnd(dstType);
+    Inst *newi = instFactory.makeSub(mod, dst, src1, src2);
+    appendInst(newi);
+    return dst;
+}
+
+
+Opnd*
+HLOAPIMagicIRBuilder::genLdConstant(int32 val) {
+    Opnd* dst = createOpnd(typeManager.getInt32Type());
+    appendInst(instFactory.makeLdConst(dst, val));
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genArrayLen(Type* dstType, Type::Tag type, Opnd* array, Opnd* tauNonNull) {
+    Opnd *tauIsArray = genTauHasType(array, array->getType());
+    
+    return genTauArrayLen(dstType, type, array, tauNonNull, tauIsArray);
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauArrayLen(Type* dstType, Type::Tag type, Opnd* array,
+                          Opnd* tauNullChecked, Opnd *tauTypeChecked) {
+    Opnd* dst = createOpnd(dstType);
+    appendInst(instFactory.makeTauArrayLen(dst, type, array, tauNullChecked,
+                                           tauTypeChecked));
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genCmp3(Type* dstType,
+                   Type::Tag instType, // source type for inst
+                   ComparisonModifier mod,
+                   Opnd* src1,
+                   Opnd* src2) {
+    // result of comparison is always a 32-bit int
+    Opnd* dst = createOpnd(dstType);
+    Inst* i = instFactory.makeCmp3(mod, instType, dst, src1, src2);
+    appendInst(i);
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genCmp(Type* dstType,
+                  Type::Tag instType, // source type for inst
+                  ComparisonModifier mod,
+                  Opnd* src1,
+                  Opnd* src2) {
+    // result of comparison is always a 32-bit int
+    Opnd* dst = createOpnd(dstType);
+    Inst *i = instFactory.makeCmp(mod, instType, dst, src1, src2);
+    appendInst(i);
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauSafe() {
+    Opnd* dst = createOpnd(typeManager.getTauType());
+    appendInst(instFactory.makeTauSafe(dst));
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauCheckBounds(Opnd* array, Opnd* index, Opnd *tauNullChecked) {
+    Opnd *tauArrayTypeChecked = genTauHasType(array, array->getType());
+    Opnd* arrayLen = genTauArrayLen(typeManager.getInt32Type(), Type::Int32, array, 
+                                    tauNullChecked, tauArrayTypeChecked);
+
+    Opnd* dst = genTauCheckBounds(arrayLen, index);
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauCheckBounds(Opnd* ub, Opnd *index) {
+    Opnd* dst = createOpnd(typeManager.getTauType());
+    appendInst(instFactory.makeTauCheckBounds(dst, ub, index));
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genTauHasType(Opnd *src, Type *castType) {
+    Opnd* dst = createOpnd(typeManager.getTauType());
+    appendInst(instFactory.makeTauHasType(dst, src, castType));
+    return dst;
+}
+
+Opnd*
+HLOAPIMagicIRBuilder::genIntrinsicCall(IntrinsicCallId intrinsicId,
+                            Type* returnType,
+                            Opnd* tauNullCheckedRefArgs,
+                            Opnd* tauTypesChecked,
+                            uint32 numArgs,
+                            Opnd*  args[]) {
+    Opnd * dst = createOpnd(returnType);
+    appendInst(instFactory.makeIntrinsicCall(dst, intrinsicId, 
+                                             tauNullCheckedRefArgs,
+                                             tauTypesChecked,
+                                             numArgs, args));
+    return dst;
+}
+
+} //namespace Jitrino

Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 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=587413&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h Tue Oct 23 01:13:56 2007
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Intel, George A. Timoshenko
+ */
+
+#ifndef _HLOAPIMAGICS_H_
+#define _HLOAPIMAGICS_H_
+
+#include "optpass.h"
+#include "Inst.h"
+#include "irmanager.h"
+
+namespace Jitrino {
+                    
+class HLOAPIMagicIRBuilder {
+public:
+    HLOAPIMagicIRBuilder(IRManager* irmanager, MemoryManager& _mm, bool _compRefs)
+    : irm(irmanager),
+      instFactory(irm->getInstFactory()),
+      opndManager(irm->getOpndManager()),
+      typeManager(irm->getTypeManager()),
+      cfg(irm->getFlowGraph()),
+      mm(_mm),
+      compRefs(_compRefs),
+      currentNode(NULL),
+      currentBCOffset(ILLEGAL_BC_MAPPING_VALUE)
+    {}
+
+public:
+    IRManager*          getIRManager()          {return irm;}
+    InstFactory&        getInstFactory()        {return instFactory;}
+    OpndManager&        getOpndManager()        {return opndManager;}
+    TypeManager&        getTypeManager()        {return typeManager;}
+    ControlFlowGraph&   getControlFlowGraph()   {return cfg;}
+    MemoryManager&      getMemoryManager()      {return mm;}
+
+    // Flow Graph building
+    Node* getCurrentNode() {return currentNode;}
+    void  setCurrentNode(Node* node) {currentNode = node;}
+    uint16 getCurrentBCOffset() {return currentBCOffset;}
+    void   setCurrentBCOffset(uint16 offset) {currentBCOffset = offset;}
+
+    void  genEdgeFromCurrent(Node* target) {cfg.addEdge(currentNode, target);}
+    void  genEdgeToCurrent(Node* source) {cfg.addEdge(source,currentNode);}
+
+    Node* genNodeAfter(Node* node, LabelInst* label, Node* dispatch=NULL);
+    Node* genNodeAfterCurrent(LabelInst* label, Node* dispatch=NULL);
+    Node* genFallthroughNode(Node* dispatch=NULL);
+
+    // IR building
+    void  appendInst(Inst* inst);
+    void  genCopy(Opnd* trgt, Opnd* src);
+    Opnd* genLdField(FieldDesc* fieldDesc, Opnd* base, Opnd* tauBaseNonNull, Opnd* tauAddressInRange);
+    Opnd* createOpnd(Type* type);
+    VarOpnd* createVarOpnd(Type* type, bool isPinned);
+    SsaVarOpnd* createSsaVarOpnd(VarOpnd* var);
+    void  genStVar(SsaVarOpnd* var, Opnd* src);
+    Opnd* genTauCheckNull(Opnd* base);
+    Opnd* genAnd(Type* dstType, Opnd* src1, Opnd* src2);
+    Opnd* genTauAnd(Opnd* src1, Opnd* src2);
+    Opnd* genAdd(Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd* genSub(Type* dstType, Modifier mod, Opnd* src1, Opnd* src2);
+    Opnd* genLdConstant(int32 val);
+    Opnd* genArrayLen(Type* dstType, Type::Tag type, Opnd* array, Opnd* tauNonNull);
+    Opnd* genTauArrayLen(Type* dstType, Type::Tag type, Opnd* array,
+                         Opnd* tauNullChecked, Opnd *tauTypeChecked);
+    Opnd* genCmp3(Type* dstType, Type::Tag instType, // source type for inst
+                  ComparisonModifier mod, Opnd* src1, Opnd* src2);
+    Opnd* genCmp(Type* dstType, Type::Tag instType, // source type for inst
+                 ComparisonModifier mod, Opnd* src1, Opnd* src2);
+    Opnd* genTauSafe();
+    Opnd* genTauCheckBounds(Opnd* array, Opnd* index, Opnd *tauNullChecked);
+    Opnd* genTauCheckBounds(Opnd* ub, Opnd *index);
+    Opnd* genTauHasType(Opnd *src, Type *castType);
+    Opnd* genIntrinsicCall(IntrinsicCallId intrinsicId, Type* returnType, Opnd* tauNullCheckedRefArgs,
+                           Opnd* tauTypesChecked, uint32 numArgs, Opnd*  args[]);
+
+private:
+    IRManager*          irm;
+    InstFactory&        instFactory;
+    OpndManager&        opndManager;
+    TypeManager&        typeManager;
+    ControlFlowGraph&   cfg;
+    MemoryManager&      mm;
+    bool                compRefs;
+    Node*               currentNode;
+    uint16              currentBCOffset;
+};
+
+class HLOAPIMagicHandler {
+public:
+    HLOAPIMagicHandler(MethodCallInst* inst)
+    : callInst(inst)
+    {}
+    void setIRBuilder(HLOAPIMagicIRBuilder* irb) {builder = irb;}
+    virtual void run() = 0;
+
+protected:
+    HLOAPIMagicIRBuilder* builder;
+    MethodCallInst*       callInst;
+};
+
+#define DECLARE_HLO_MAGIC_INLINER(name)\
+class name : public HLOAPIMagicHandler {\
+public:\
+    name (MethodCallInst* inst)\
+    : HLOAPIMagicHandler(inst){}\
+    \
+    virtual void run();\
+};\
+
+DECLARE_HLO_MAGIC_INLINER(String_compareTo_HLO_Handler);
+DECLARE_HLO_MAGIC_INLINER(String_regionMatches_HLO_Handler);
+
+DEFINE_SESSION_ACTION(HLOAPIMagicSession, hlo_api_magic, "APIMagics HLO Pass")
+
+void
+HLOAPIMagicSession::_run(IRManager& irm)
+{
+    MemoryManager mm("HLOAPIMagicSession mm");
+ 
+    //finding all api magic calls
+    StlVector<HLOAPIMagicHandler*> handlers(mm);
+    ControlFlowGraph& fg = irm.getFlowGraph();
+    const Nodes& nodes = fg.getNodesPostOrder();//process checking only reachable nodes.
+    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->getOpcode() != Op_DirectCall) {
+                    continue;
+                }
+                MethodCallInst* callInst = (MethodCallInst*)inst;
+                MethodDesc* md = callInst->getMethodDesc();
+                const char* className = md->getParentType()->getName();
+                const char* methodName = md->getName();
+                const char* signature = md->getSignatureString();
+                if (!strcmp(className, "java/lang/String")) {
+                    if (!strcmp(methodName, "compareTo") && !strcmp(signature, "(Ljava/lang/String;)I")) {
+                        if(getBoolArg("String_compareTo_as_magic", true))
+                            handlers.push_back(new (mm) String_compareTo_HLO_Handler(callInst));
+                    } 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));
+                    }
+                }
+            }
+        }
+    }
+
+    if(handlers.size() != 0) {
+        bool compRefs = getBoolArg("compressedReferences", false);
+        HLOAPIMagicIRBuilder builder = HLOAPIMagicIRBuilder(&irm, mm, compRefs);
+        //running all handlers
+        for (StlVector<HLOAPIMagicHandler*>::const_iterator it = handlers.begin(), end = handlers.end(); it!=end; ++it) {
+            HLOAPIMagicHandler* handler = *it;
+            handler->setIRBuilder(&builder);
+            handler->run();
+        }
+    }
+}
+
+
+
+
+
+
+} //namespace Jitrino 
+
+#endif // _HLOAPIMAGICS_H_

Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/HLOAPIMagics.h
------------------------------------------------------------------------------
    svn:eol-style = native

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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Tue Oct 23 01:13:56 2007
@@ -476,6 +476,10 @@
         os << "AddValueProfileValue"; break;
     case FillArrayWithConst:
         os << "FillArrayWithConst"; break;
+    case StringCompareTo:
+        os << "StringCompareTo"; break;
+    case StringRegionMatches:
+        os << "StringRegionMatches"; break;
     default:
         assert(0); break;
         }
@@ -2038,8 +2042,16 @@
 InstFactory::makeJitHelperCall(Opnd* dst, JitHelperCallId id, uint32 numArgs, Opnd** args) {
     Type::Tag returnType = dst->isNull()? Type::Void : dst->getType()->tag;
     args = copyOpnds(args, numArgs);
-    return makeJitHelperCallInst(Op_JitHelperCall, Modifier(Exception_Sometimes), 
-                                 returnType, dst, numArgs, args, id);
+    Modifier mod;
+    switch(id) {
+        case StringCompareTo:
+        case StringRegionMatches:
+            mod = Modifier(Exception_Never);
+            break;
+        default:
+            mod = Modifier(Exception_Sometimes);
+    }
+    return makeJitHelperCallInst(Op_JitHelperCall, mod, returnType, dst, numArgs, args, id);
 }
 
 Inst*

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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Tue Oct 23 01:13:56 2007
@@ -275,7 +275,9 @@
     SaveThisState, //todo: replace with GetTLS + offset sequence
     ReadThisState, //todo: replace with GetTLS + offset sequence
     LockedCompareAndExchange,
-    AddValueProfileValue
+    AddValueProfileValue,
+    StringCompareTo,
+    StringRegionMatches
 };
 
 enum Opcode {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/deadcodeeliminator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/deadcodeeliminator.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/deadcodeeliminator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/deadcodeeliminator.cpp Tue Oct 23 01:13:56 2007
@@ -354,7 +354,16 @@
 DeadCodeEliminator::copyPropagate(Inst* inst) {
     uint32 numSrcs = inst->getNumSrcOperands();
     for (uint32 i=0; i<numSrcs; i++) {
-        inst->setSrc(i, copyPropagate(inst->getSrc(i)));
+        Opnd* opnd = inst->getSrc(i);
+        Opnd* propagated = copyPropagate(opnd);
+        if (opnd != propagated) {
+            if (Log::isEnabled()) {
+                Log::out() << "    Operand "; opnd->print(Log::out());
+                Log::out() << " replaced by "; propagated->print(Log::out());
+                Log::out() << std::endl;
+            }
+            inst->setSrc(i, propagated);
+        }
     }
 }
 

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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Tue Oct 23 01:13:56 2007
@@ -413,6 +413,8 @@
                         case ReadThisState:
                         case LockedCompareAndExchange:
                         case AddValueProfileValue:
+                        case StringCompareTo:
+                        case StringRegionMatches:
                             break;
                         default:
                             assert(0);

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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp Tue Oct 23 01:13:56 2007
@@ -134,6 +134,12 @@
             _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);
+            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);
+            }
 #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=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Tue Oct 23 01:13:56 2007
@@ -666,6 +666,8 @@
             case ReadThisState:
             case LockedCompareAndExchange:
             case AddValueProfileValue:
+            case StringCompareTo:
+            case StringRegionMatches:
                 break;
             default:
                 assert(0);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h Tue Oct 23 01:13:56 2007
@@ -1254,7 +1254,7 @@
     
   /** 
    * Orders the nodes in the graph. 
-   * If <code>isForwarisForward</code> is <code>TRUE</code>, updates the  
+   * If <code>isForward</code> is <code>TRUE</code>, updates the  
    * internal CFG collection of nodes and node df-numbers.
    * Affects nodes and graph traversal and ordering numbers.
    *  

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp Tue Oct 23 01:13:56 2007
@@ -562,6 +562,7 @@
         jsrEntryMap->insert(std::make_pair(entry_inst, ret_inst));
     }
     irBuilder.getIRManager()->setJsrEntryMap(jsrEntryMap);
+    if (Log::isEnabled()) Log::out() << ::std::endl << "================= TRANSLATOR IS FINISHED =================" << ::std::endl << ::std::endl;
 }
 
 //-----------------------------------------------------------------------------

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h Tue Oct 23 01:13:56 2007
@@ -56,7 +56,9 @@
     void offset_done(uint32 offset);
     void checkStack();
     // called before parsing starts
-    virtual void parseInit() {}
+    virtual void parseInit() {
+        if (Log::isEnabled()) Log::out() << ::std::endl << "================= TRANSLATOR STARTED =================" << ::std::endl << ::std::endl;
+    }
     // called after parsing ends, but not if an error occurs
     virtual void parseDone();
     // called when an error occurs during the byte code parsing

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp Tue Oct 23 01:13:56 2007
@@ -635,6 +635,7 @@
     labelOffsets = new (memManager) uint32[numLabels];
     struct LabelOffsetVisitor avisitor(labelOffsets);
     labels->visitElems(avisitor);
+    if (Log::isEnabled()) Log::out() << ::std::endl << "================= PREPASS IS FINISHED =================" << ::std::endl << ::std::endl;
 }
 
 uint32 JavaLabelPrepass::getLabelId(uint32 offset) {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.h?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.h Tue Oct 23 01:13:56 2007
@@ -225,7 +225,9 @@
     void parseError();
 
     // called to initialize parsing
-    void parseInit() {}
+    void parseInit() {
+        if (Log::isEnabled()) Log::out() << ::std::endl << "================= PREPASS STARTED =================" << ::std::endl << ::std::endl;
+    }
 
     // called to indicate end of parsing
     void parseDone();

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp Tue Oct 23 01:13:56 2007
@@ -872,6 +872,19 @@
     return getFieldDesc(res);
 }
 
+MethodDesc*  
+CompilationInterface::getMethodByName(Class_Handle enclClass, const char* name) {
+    Method_Handle res = class_get_method_by_name(enclClass, name);
+    assert(res != NULL); // this functionality should be used only for those resolved for sure
+    return getMethodDesc(res);
+}
+
+FieldDesc*  
+CompilationInterface::getFieldByName(Class_Handle enclClass, const char* name) {
+    Field_Handle res = class_get_field_by_name(enclClass, name);
+    return res == NULL ? NULL : getFieldDesc(res);
+}
+
 Type*
 CompilationInterface::getFieldType(Class_Handle enclClass, uint32 cpIndex) {
     Java_Type drlType = (Java_Type)class_get_cp_field_type(enclClass, (unsigned short)cpIndex);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h Tue Oct 23 01:13:56 2007
@@ -328,6 +328,8 @@
     FieldDesc*  getNonStaticField(Class_Handle enclClass, uint32 cpIndex, bool putfield);
     FieldDesc*  getStaticField(Class_Handle enclClass, uint32 cpIndex, bool putfield);
 
+    FieldDesc*  getFieldByName(Class_Handle enclClass, const char* name);
+    MethodDesc* getMethodByName(Class_Handle enclClass, const char* name);
     
 
     // resolve-by-name methods

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h Tue Oct 23 01:13:56 2007
@@ -436,6 +436,9 @@
 Mnemonic_CMP,                           // Compare Two Operands
 Mnemonic_CMPXCHG,                       // Compare and exchange
 Mnemonic_CMPXCHG8B,                     // Compare and Exchange 8 Bytes
+Mnemonic_CMPSB,                         // Compare Two Bytes at DS:ESI and ES:EDI
+Mnemonic_CMPSW,                         // Compare Two Words at DS:ESI and ES:EDI
+Mnemonic_CMPSD,                         // Compare Two Doublewords at DS:ESI and ES:EDI
 //
 // double -> float
 Mnemonic_CVTSD2SS,                      // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp Tue Oct 23 01:13:56 2007
@@ -436,7 +436,6 @@
 END_OPCODES()
 END_MNEMONIC()
  
-
 #undef DEFINE_ALU_OPCODES
 //
 //
@@ -1409,7 +1408,7 @@
 END_MNEMONIC()
 
 /*
-MOVS is a special case. 
+MOVS and CMPS are the special cases. 
 Most the code in both CG and Encoder do not expect 2 memory operands. 
 Also, they are not supposed to setup constrains on which register the 
 memory reference must reside - m8,m8 or m32,m32 is not the choice.
@@ -1435,6 +1434,27 @@
 BEGIN_OPCODES()
     {OpcodeInfo::ia32,  {0xA5},         {r32,r32,ECX},  DU_DU_DU },
     {OpcodeInfo::em64t, {0xA5},         {r64,r64,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPSB, MF_AFFECTS_FLAGS, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {0xA6},         {r32,r32,ECX},    DU_DU_DU },
+    {OpcodeInfo::em64t, {0xA6},         {r64,r64,RCX},    DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPSW, MF_AFFECTS_FLAGS, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {Size16, 0xA7}, {r32,r32,ECX},  DU_DU_DU },
+    {OpcodeInfo::em64t, {Size16, 0xA7}, {r64,r64,RCX},  DU_DU_DU },
+END_OPCODES()
+END_MNEMONIC()
+
+BEGIN_MNEMONIC(CMPSD, MF_AFFECTS_FLAGS, DU_DU_DU)
+BEGIN_OPCODES()
+    {OpcodeInfo::ia32,  {0xA7},         {r32,r32,ECX},  DU_DU_DU },
+    {OpcodeInfo::em64t, {0xA7},         {r64,r64,RCX},  DU_DU_DU },
 END_OPCODES()
 END_MNEMONIC()
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp?rev=587413&r1=587412&r2=587413&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp Tue Oct 23 01:13:56 2007
@@ -1780,6 +1780,30 @@
     return ch->get_field(idx);
 } // class_get_field
 
+Method_Handle class_get_method_by_name(Class_Handle ch, const char* name)
+{
+    assert(ch);
+    for(int idx = 0; idx < ch->get_number_of_methods(); idx++) {
+        Method_Handle meth = ch->get_method(idx);
+        if(strcmp(meth->get_name()->bytes, name) == 0) {
+            return meth;
+        }
+    }
+    return NULL;
+} // class_get_method_by_name
+
+Field_Handle class_get_field_by_name(Class_Handle ch, const char* name)
+{
+    assert(ch);
+    for(int idx = 0; idx < ch->get_number_of_fields(); idx++) {
+        Field_Handle fld = ch->get_field(idx);
+        if(strcmp(fld->get_name()->bytes, name) == 0) {
+            return fld;
+        }
+    }
+    return NULL;
+} // class_get_field_by_name
+
 Field_Handle class_get_instance_field(Class_Handle ch, unsigned idx)
 {
     assert(ch);



Mime
View raw message