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);
|