You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/05/29 08:27:29 UTC
svn commit: r542423 - in /harmony/enhanced/drlvm/trunk:
src/test/microbenchmark/harmony-3630/
src/test/microbenchmark/harmony-3630/abstractCall/
src/test/microbenchmark/harmony-3630/directCall/
src/test/microbenchmark/harmony-3630/interfaceCall/ src/te...
Author: varlax
Date: Mon May 28 23:27:25 2007
New Revision: 542423
URL: http://svn.apache.org/viewvc?view=rev&rev=542423
Log:
Applied HARMONY-3630 [drlvm][jit] profile-based devirtualization of abstract and virtual calls
Added:
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/abstractCall/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/abstractCall/test.java
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/directCall/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/directCall/test.java
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/interfaceCall/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/interfaceCall/test.java
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualCall/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualCall/test.java
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualIndirectCall/
harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualIndirectCall/test.java
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/CGSupport.h
Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/abstractCall/test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/abstractCall/test.java?view=auto&rev=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/abstractCall/test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/abstractCall/test.java Mon May 28 23:27:25 2007
@@ -0,0 +1,53 @@
+/**
+ * Microbenchmark to measure performance for abstract calls.
+ */
+
+abstract class Abst {
+ public abstract void inc();
+ public abstract long getNum();
+ public abstract void reset();
+}
+
+class AbstImpl extends Abst {
+
+ private long num;
+
+ public AbstImpl() { num = 0; }
+ public void inc() { num++; }
+ public long getNum() { return num; }
+ public void reset() { num = 0; }
+}
+
+public class test {
+
+ static final long limit = 1000000000;
+
+ static Abst obj = new AbstImpl();
+
+ public static void main(String[] args) {
+ test testObject = new test();
+ long before = 0, after = 0;
+ long best = 0;
+
+ for (int i = 0; i < 5; i++) {
+ obj.reset();
+
+ before = System.currentTimeMillis();
+ testObject.run();
+ after = System.currentTimeMillis();
+
+ long current = obj.getNum() / (((after - before)==0) ? 1 : (after - before));
+ System.out.println("Current score: " + current);
+ if (current > best) best = current;
+ }
+ System.out.println("Calls per millisecond: " + best);
+ }
+
+ public void run() {
+
+ for (long k = 0; k < limit; k++ ) {
+ obj.inc();
+ }
+ }
+
+}
Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/directCall/test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/directCall/test.java?view=auto&rev=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/directCall/test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/directCall/test.java Mon May 28 23:27:25 2007
@@ -0,0 +1,49 @@
+/**
+ * Microbenchmark to measure performance for direct calls.
+ */
+
+
+final class Child {
+
+ private long num;
+
+ public Child() { num = 0; }
+ public void inc() { num++; }
+ public long getNum() { return num; }
+ public void reset() { num = 0; }
+}
+
+public class test {
+
+ static final long limit = 1000000000;
+
+ static final Child obj = new Child();
+
+ public static void main(String[] args) {
+ test testObject = new test();
+
+ long before = 0, after = 0;
+ long best = 0;
+
+ for (int i = 0; i < 5; i++) {
+ obj.reset();
+
+ before = System.currentTimeMillis();
+ testObject.run();
+ after = System.currentTimeMillis();
+
+ long current = obj.getNum() / (((after - before)==0) ? 1 : (after - before));
+ System.out.println("Current score: " + current);
+ if (current > best) best = current;
+ }
+ System.out.println("Calls per millisecond: " + best);
+ }
+
+ public void run() {
+
+ for (long k = 0; k < limit; k++ ) {
+ obj.inc();
+ }
+ }
+
+}
Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/interfaceCall/test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/interfaceCall/test.java?view=auto&rev=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/interfaceCall/test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/interfaceCall/test.java Mon May 28 23:27:25 2007
@@ -0,0 +1,55 @@
+/**
+ * Microbenchmark to measure performance for interface calls.
+ */
+
+
+interface Intf {
+ public void inc();
+ public long getNum();
+ public void reset();
+}
+
+class IntfImpl implements Intf {
+
+ private long num;
+
+ public IntfImpl() { num = 0; }
+ public void inc() { num++; }
+ public long getNum() { return num; }
+ public void reset() { num = 0; }
+}
+
+public class test {
+
+ static final long limit = 1000000000;
+
+ static Intf obj = new IntfImpl();
+
+ public static void main(String[] args) {
+ test testObject = new test();
+
+ long before = 0, after = 0;
+ long best = 0;
+
+ for (int i = 0; i < 5; i++) {
+ obj.reset();
+
+ before = System.currentTimeMillis();
+ testObject.run();
+ after = System.currentTimeMillis();
+
+ long current = obj.getNum() / (((after - before)==0) ? 1 : (after - before));
+ System.out.println("Current score: " + current);
+ if (current > best) best = current;
+ }
+ System.out.println("Calls per millisecond: " + best);
+ }
+
+ public void run() {
+
+ for (long k = 0; k < limit; k++ ) {
+ obj.inc();
+ }
+ }
+
+}
Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualCall/test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualCall/test.java?view=auto&rev=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualCall/test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualCall/test.java Mon May 28 23:27:25 2007
@@ -0,0 +1,48 @@
+/**
+ * Microbenchmark to measure performance for virtual calls.
+ */
+
+class Child {
+
+ private long num;
+
+ public Child() { num = 0; }
+ public void inc() { num++; }
+ public long getNum() { return num; }
+ public void reset() { num = 0; }
+}
+
+public class test {
+
+ static final long limit = 1000000000;
+
+ static Child obj = new Child();
+
+ public static void main(String[] args) {
+ test testObject = new test();
+
+ long before = 0, after = 0;
+ long best = 0;
+
+ for (int i = 0; i < 5; i++) {
+ obj.reset();
+
+ before = System.currentTimeMillis();
+ testObject.run();
+ after = System.currentTimeMillis();
+
+ long current = obj.getNum() / (((after - before)==0) ? 1 : (after - before));
+ System.out.println("Current score: " + current);
+ if (current > best) best = current;
+ }
+ System.out.println("Calls per millisecond: " + best);
+ }
+
+ public void run() {
+
+ for (long k = 0; k < limit; k++ ) {
+ obj.inc();
+ }
+ }
+
+}
Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualIndirectCall/test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualIndirectCall/test.java?view=auto&rev=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualIndirectCall/test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-3630/virtualIndirectCall/test.java Mon May 28 23:27:25 2007
@@ -0,0 +1,56 @@
+/**
+ * Microbenchmark to measure performance for virtual calls
+ * in case when a formal call receiver is of a parent type.
+ */
+
+
+class Parent {
+ public void inc() {}
+ public long getNum() {return 0;}
+ public void reset() {}
+}
+
+class Child extends Parent {
+
+ private long num;
+
+ public Child() { num = 0; }
+ public void inc() { num++; }
+ public long getNum() { return num; }
+ public void reset() { num = 0; }
+}
+
+public class test {
+
+ static final long limit = 1000000000;
+
+ static Parent obj = new Child();
+
+ public static void main(String[] args) {
+ test testObject = new test();
+
+ long before = 0, after = 0;
+ long best = 0;
+
+ for (int i = 0; i < 5; i++) {
+ obj.reset();
+
+ before = System.currentTimeMillis();
+ testObject.run();
+ after = System.currentTimeMillis();
+
+ long current = obj.getNum() / (((after - before)==0) ? 1 : (after - before));
+ System.out.println("Current score: " + current);
+ if (current > best) best = current;
+ }
+ System.out.println("Calls per millisecond: " + best);
+ }
+
+ public void run() {
+
+ for (long k = 0; k < limit; k++ ) {
+ obj.inc();
+ }
+ }
+
+}
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf Mon May 28 23:27:25 2007
@@ -58,6 +58,10 @@
-XX:jit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
+#enable profiling of all virtual calls
+-XX:jit.SD1_OPT.arg.optimizer.vp_instrument.profile_abstract=true
+
+
-XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,so2-,simplify,dce,uce,escape,dce,uce,hvn,dce,uce,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
-XX:jit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l-,early_prop-,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,layout,copy,rce-,stack,break-,iprof-,emitter!,si_insts,gcmap,info,unlock_method
-XX:jit.SD2_OPT.path.dce1=cg_dce
@@ -67,6 +71,7 @@
-XX:jit.SD2_OPT.path.devirt_virtual=devirt
-XX:jit.SD2_OPT.path.devirt_intf=devirt
-XX:jit.SD2_OPT.arg.optimizer.devirt_intf.devirt_intf_calls=true
+-XX:jit.SD2_OPT.arg.optimizer.devirt_intf.devirt_abstract_calls=true
-XX:jit.SD2_OPT.arg.optimizer.devirt_intf.devirt_virtual_calls=false
#inliner configuration
@@ -78,6 +83,7 @@
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.path.devirt_virtual=devirt
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.path.devirt_intf=devirt
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.arg.devirt_intf.devirt_intf_calls=true
+-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.arg.devirt_intf.devirt_abstract_calls=true
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.arg.devirt_intf.devirt_virtual_calls=false
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?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Mon May 28 23:27:25 2007
@@ -58,6 +58,10 @@
-XX:jit.SD1_OPT.path.regalloc=webmaker,cg_regalloc,spillgen
-XX:jit.SD1_OPT.arg.codegen.regalloc.webmaker.calc=true
+#enable profiling of all virtual calls
+-XX:jit.SD1_OPT.arg.optimizer.vp_instrument.profile_abstract=true
+
+
-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,uce,purge,simplify,dce,uce,lazyexc,so2-,simplify,dce,uce,escape,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,abcd,dce,uce,gcm,dessa,fastArrayFill,statprof,markglobals
@@ -69,6 +73,7 @@
-XX:jit.SD2_OPT.path.devirt_virtual=devirt
-XX:jit.SD2_OPT.path.devirt_intf=devirt
-XX:jit.SD2_OPT.arg.optimizer.devirt_intf.devirt_intf_calls=true
+-XX:jit.SD2_OPT.arg.optimizer.devirt_intf.devirt_abstract_calls=true
-XX:jit.SD2_OPT.arg.optimizer.devirt_intf.devirt_virtual_calls=false
#inliner configuration
@@ -80,6 +85,7 @@
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.path.devirt_virtual=devirt
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.path.devirt_intf=devirt
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.arg.devirt_intf.devirt_intf_calls=true
+-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.arg.devirt_intf.devirt_abstract_calls=true
-XX:jit.SD2_OPT.SD2_OPT_inliner_pipeline.arg.devirt_intf.devirt_virtual_calls=false
#helper inliner configuration
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp Mon May 28 23:27:25 2007
@@ -46,6 +46,9 @@
TypeManager& typeManager = irm.getTypeManager();
StlVector<uint32> counterKeys(mm);
bool debug = Log::isEnabled();
+ bool profileAbstractCalls = getBoolArg("profile_abstract", false);
+ bool profileAllVirtualCalls = getBoolArg("profile_all_virtual", false);
+
uint32 key = 0;
StlVector<Node*> nodes(mm);
@@ -88,18 +91,16 @@
Log::out() << std::endl;
}
} else {
- // That is what we are looking for
- if (debug) {
- Log::out() << "\tFound ldVTable instruction to instrument: ";
- vtableInst->print(Log::out());
- Log::out() << std::endl;
+ // Profile abstract calls, or all virtual calls
+ ObjectType* baseType = (ObjectType*) base->getType();
+ if(!((baseType->isAbstract() && profileAbstractCalls) || profileAllVirtualCalls)) {
+ continue;
}
- // Don't profile virtual calls so far
- continue;
}
- VectorHandler* bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, &md);
+ VectorHandler* bc2HIRMapHandler = new (mm) VectorHandler(bcOffset2HIRHandlerName, &md);
uint64 callInstId = (uint64)lastInst->getId();
key = (uint32)bc2HIRMapHandler->getVectorEntry(callInstId);
+ assert(key != ILLEGAL_VALUE);
assert(key != 0);
if (debug) {
Log::out() << "Use call instruction bcOffset = " << (int32)key << std::endl;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp Mon May 28 23:27:25 2007
@@ -591,6 +591,29 @@
Node* newEntry = _duplicateRegion(*irManager, entryJSR, nodesInJSR, defUses, *nodeRenameTable, *opndRenameTable, 0);
+ // update the BCMap
+ if(irManager->getCompilationInterface().isBCMapInfoRequired()) {
+ MethodDesc* meth = irManager->getCompilationInterface().getMethodToCompile();
+ VectorHandler *bc2HIRmapHandler = new(inlineManager) VectorHandler(bcOffset2HIRHandlerName, meth);
+
+ // update the BCMap for each copied node
+ NodeRenameTable::Iter nodeIter(nodeRenameTable);
+ Node* oldNode = NULL;
+ Node* newNode = NULL;
+ StlBitVector regionNodes(inlineManager);
+ while(nodeIter.getNextElem(oldNode, newNode)) {
+ Inst* oldLast = (Inst*)oldNode->getLastInst();
+ Inst* newLast = (Inst*)newNode->getLastInst();
+ if (oldLast->asMethodCallInst() || oldLast->asCallInst()) {
+ assert(newLast->asMethodCallInst() || newLast->asCallInst());
+ uint32 bcOffset = bc2HIRmapHandler->getVectorEntry(oldLast->getId());
+ assert((bcOffset != 0) && (bcOffset != ILLEGAL_VALUE));
+ bc2HIRmapHandler->setVectorEntry(newLast->getId(), bcOffset);
+ }
+
+ }
+ }
+
fg.removeEdge(block,retTarget);
fg.removeEdge(block,entryJSR);
jsrInst->unlink();
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp Mon May 28 23:27:25 2007
@@ -55,13 +55,13 @@
const OptimizerFlags& optFlags = irm.getOptimizerFlags();
_doAggressiveGuardedDevirtualization = !_hasProfileInfo || optFlags.devirt_do_aggressive_guarded_devirtualization;
- _devirtUseCHAWithProfile = optFlags.devirt_use_cha_with_profile;
- _devirtUseCHAWithProfileThreshold = optFlags.devirt_use_cha_with_profile_threshold;
_devirtSkipExceptionPath = optFlags.devirt_skip_exception_path;
_devirtBlockHotnessMultiplier = optFlags.devirt_block_hotness_multiplier;
_devirtSkipJLObjectMethods = optFlags.devirt_skip_object_methods;
_devirtInterfaceCalls = sa ? sa->getBoolArg("devirt_intf_calls", false) : optFlags.devirt_intf_calls;
_devirtVirtualCalls = sa ? sa->getBoolArg("devirt_virtual_calls", true) : true;
+ _devirtAbstractCalls = sa ? sa->getBoolArg("devirt_abstract_calls", false) : false;
+ _devirtUsingProfile = sa ? sa->getBoolArg("devirt_using_profile", false) : false;
_directCallPercent = optFlags.unguard_dcall_percent;
_directCallPercientOfEntry = optFlags.unguard_dcall_percent_of_entry;
@@ -147,10 +147,11 @@
Log::out() << "Devirt params: " << std::endl;
Log::out() << " _doAggressiveGuardedDevirtualization: " << _doAggressiveGuardedDevirtualization << std::endl;
- Log::out() << " _devirtUseCHAWithProfile: " << _devirtUseCHAWithProfile << std::endl;
Log::out() << " _devirtSkipJLObjectMethods: " << _devirtSkipJLObjectMethods << std::endl;
Log::out() << " _devirtInterfaceCalls: " << _devirtInterfaceCalls << std::endl;
Log::out() << " _devirtVirtualCalls: " << _devirtVirtualCalls << std::endl;
+ Log::out() << " _devirtAbstractCalls: " << _devirtAbstractCalls << std::endl;
+ Log::out() << " _devirtUsingProfile: " << _devirtUsingProfile << std::endl;
assert(dtree->isValid());
StlDeque<DominatorNode *> dom_stack(regionIRM.getMemoryManager());
@@ -347,7 +348,7 @@
//
Opnd* base = directCall->getSrc(2); // skip over taus
assert(base->getType()->isObject());
- assert(base->getType()->isInterface() || (((ObjectType*) base->getType()) == objectType));
+ assert(base->getType()->isInterface() || base->getType()->isAbstract() || (((ObjectType*) base->getType()) == objectType) || _devirtUsingProfile);
Opnd* dynamicVTableAddr = _opndManager.createSsaTmpOpnd(_typeManager.getVTablePtrType(objectType));
Opnd* staticVTableAddr = _opndManager.createSsaTmpOpnd(_typeManager.getVTablePtrType(objectType));
guard->appendInst(_instFactory.makeTauLdVTableAddr(dynamicVTableAddr, base, tauNullChecked));
@@ -398,6 +399,42 @@
return true;
}
+ObjectType *
+Devirtualizer::getTopProfiledCalleeType(IRManager& regionIRM, MethodDesc *origMethodDesc, Inst *call) {
+ assert(regionIRM.getCompilationInterface().isBCMapInfoRequired());
+ CompilationContext* cc = regionIRM.getCompilationContext();
+ MethodDesc& methDesc = regionIRM.getMethodDesc();
+
+ ProfilingInterface* pi = cc->getProfilingInterface();
+ // Don't devirtualize if there is no value profile
+ if (!pi->hasMethodProfile(ProfileType_Value, methDesc)) return 0;
+ ValueMethodProfile* mp = pi->getValueMethodProfile(regionIRM.getMemoryManager(), methDesc);
+ if (Log::isLogEnabled(LogStream::DBG)) {
+ mp->dumpValues(Log::out());
+ }
+ MethodDesc* rootMethodDesc = regionIRM.getCompilationInterface().getMethodToCompile();
+
+ // Get bytecode offset of the call
+ VectorHandler* bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, rootMethodDesc);
+ uint64 callInstId = (uint64)call->getId();
+ uint32 bcOffset = (uint32)bc2HIRMapHandler->getVectorEntry(callInstId);
+ assert(bcOffset != 0);
+ assert(bcOffset != ILLEGAL_VALUE);
+ Log::out() << "Call instruction bcOffset = " << (int32)bcOffset << std::endl;
+
+ // Get profiled vtable value
+ POINTER_SIZE_INT vtHandle = mp->getTopValue(bcOffset);
+ if (vtHandle == 0) {
+ // Do not devirtualize - there were no real calls here
+ return 0;
+ }
+
+ // get desired MethodDesc object
+ assert(vtHandle != 0);
+ ObjectType* clssObjectType = _typeManager.getObjectType(VMInterface::getTypeHandleFromVTable((void*)vtHandle));
+ return clssObjectType;
+}
+
void
Devirtualizer::guardCallsInBlock(IRManager& regionIRM, Node* node) {
@@ -423,53 +460,30 @@
assert(!baseType->isUnresolvedType());
- if (! ((_devirtInterfaceCalls && isIntfCall) || (_devirtVirtualCalls && !isIntfCall))) {
+ ObjectType* devirtType = NULL;
+ if (! ((_devirtInterfaceCalls && isIntfCall) || (_devirtVirtualCalls && !isIntfCall) ||
+ (baseType->isAbstract() && _devirtAbstractCalls))) {
return;
}
// If base type is concrete, consider an explicit guarded test against it
- if((_devirtInterfaceCalls && isIntfCall) || !baseType->isAbstract() || baseType->isArray()) {
+ if((_devirtInterfaceCalls && isIntfCall) || !baseType->isAbstract() || baseType->isArray() || (baseType->isAbstract() && _devirtAbstractCalls)) {
MethodDesc* origMethodDesc = methodInst->getMethodDesc();
MethodDesc* candidateMeth = NULL;
- int candidateExecCount = 0;
- CompilationContext* cc = regionIRM.getCompilationContext();
- bool profileSelection = _devirtUseCHAWithProfile && cc->hasDynamicProfileToUse();
- if (baseType->isInterface()) {
- assert(regionIRM.getCompilationInterface().isBCMapInfoRequired());
- MethodDesc& methDesc = regionIRM.getMethodDesc();
- Log::out() << std::endl << "Devirtualizing interface call in the method :" << std::endl << "\t";
+ if (_devirtUsingProfile || baseType->isInterface() || baseType->isAbstract()) {
+
+ MethodDesc& methDesc = regionIRM.getMethodDesc();
+ Log::out() << std::endl << "Devirtualizing interface/abstract call in the method :" << std::endl << "\t";
methDesc.printFullName(Log::out());
Log::out() << std::endl << "call to the method: " << std::endl << "\t";
origMethodDesc->printFullName(Log::out());
Log::out() << std::endl << "from the CFG node: " << node->getId() <<
", node exec count: " << node->getExecCount() << std::endl;
- ProfilingInterface* pi = cc->getProfilingInterface();
- // Don't devirtualize if there is no value profile
- if (!pi->hasMethodProfile(ProfileType_Value, methDesc)) return;
- ValueMethodProfile* mp = pi->getValueMethodProfile(regionIRM.getMemoryManager(), methDesc);
- if (Log::isLogEnabled(LogStream::DBG)) {
- mp->dumpValues(Log::out());
- }
- MethodDesc* rootMethodDesc = regionIRM.getCompilationInterface().getMethodToCompile();
-
- // Get bytecode offset of the call
- VectorHandler* bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, rootMethodDesc);
- uint64 callInstId = (uint64)last->getId();
- uint32 bcOffset = (uint32)bc2HIRMapHandler->getVectorEntry(callInstId);
- assert(bcOffset != 0);
- Log::out() << "Call instruction bcOffset = " << (int32)bcOffset << std::endl;
-
- // Get profiled vtable value
- POINTER_SIZE_INT vtHandle = mp->getTopValue(bcOffset);
- if (vtHandle == 0) {
- // Do not devirtualize - there were no real calls here
+ ObjectType* clssObjectType = getTopProfiledCalleeType(regionIRM, origMethodDesc, last);
+ if(clssObjectType == 0) {
return;
}
-
- // get desired MethodDesc object
- assert(vtHandle != 0);
- ObjectType* clssObjectType = _typeManager.getObjectType(VMInterface::getTypeHandleFromVTable((void*)vtHandle));
Log::out() << "Valued type: ";
clssObjectType->print(Log::out());
Log::out() << std::endl;
@@ -478,47 +492,27 @@
candidateMeth->printFullName(Log::out());
Log::out() << std::endl;
- if(doGuard(regionIRM, node, *candidateMeth )) {
- Log::out() << "Guard call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
- genGuardedDirectCall(regionIRM, node, last, candidateMeth, clssObjectType, tauNullChecked, tauTypesChecked, argOffset);
- Log::out() << "Done guarding call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
- } else {
- Log::out() << "Don't guard call to " << baseType->getName() << "::" << origMethodDesc->getName() << std::endl;
- }
-
- return;
+ devirtType = clssObjectType;
- } else if (profileSelection) {
- ClassHierarchyMethodIterator* iterator = regionIRM.getCompilationInterface().getClassHierarchyMethodIterator(baseType, origMethodDesc);
- if(iterator->isValid()) {
- ProfilingInterface* pi = cc->getProfilingInterface();
- while (iterator->hasNext()) {
- MethodDesc* tmpMeth = iterator->getNext();
- int tmpCount = pi->getProfileMethodCount(*tmpMeth);
- Log::out() << "CHA devirt profile-selection: " << baseType->getName() << "::" << tmpMeth->getName() << tmpMeth->getSignatureString()
- << " exec_count=" << tmpCount << std::endl;
- if (candidateExecCount < tmpCount) {
- candidateExecCount = tmpCount;
- candidateMeth = tmpMeth;
- }
- }
- }
} else {
NamedType* methodType = origMethodDesc->getParentType();
if (_typeManager.isSubClassOf(baseType, methodType)) {
- candidateMeth = regionIRM.getCompilationInterface().getOverriddenMethod(baseType, origMethodDesc);
- }
+ candidateMeth = regionIRM.getCompilationInterface().getOverriddenMethod(baseType, origMethodDesc);
+ if (candidateMeth) {
+ jitrino_assert(origMethodDesc->getParentType()->isClass());
+ methodInst->setMethodDesc(candidateMeth);
+ devirtType = baseType;
+ }
+ }
}
if (candidateMeth) {
- jitrino_assert(origMethodDesc->getParentType()->isClass());
- methodInst->setMethodDesc(candidateMeth);
//
// Try to guard this call
//
+ assert(devirtType);
if(doGuard(regionIRM, node, *candidateMeth )) {
- Log::out() << "Guard call to " << baseType->getName() << "::" << candidateMeth->getName()
- <<" CHAWithProfile="<<(profileSelection ? "true":"false")<<" execCnt="<<candidateExecCount<< std::endl;
- genGuardedDirectCall(regionIRM, node, last, candidateMeth, baseType, tauNullChecked, tauTypesChecked, argOffset);
+ Log::out() << "Guard call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
+ genGuardedDirectCall(regionIRM, node, last, candidateMeth, devirtType, tauNullChecked, tauTypesChecked, argOffset);
Log::out() << "Done guarding call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
} else {
Log::out() << "Don't guard call to " << baseType->getName() << "::" << origMethodDesc->getName() << std::endl;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h Mon May 28 23:27:25 2007
@@ -45,18 +45,18 @@
void guardCallsInBlock(IRManager& irm, Node* node);
void genGuardedDirectCall(IRManager& irm, Node* node, Inst* call, MethodDesc* methodDesc, ObjectType* valuedType, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset);
bool doGuard(IRManager& irm, Node* node, MethodDesc& methodDesc);
+ ObjectType *getTopProfiledCalleeType(IRManager& irm, MethodDesc *origMethodDesc, Inst *call);
bool _hasProfileInfo;
bool _doProfileOnlyGuardedDevirtualization;
bool _doAggressiveGuardedDevirtualization;
- bool _devirtUseCHAWithProfile;
- bool _devirtUseCHAWithProfileThreshold;
bool _devirtSkipExceptionPath;
float _devirtBlockHotnessMultiplier;
bool _devirtSkipJLObjectMethods;
bool _devirtInterfaceCalls;
bool _devirtVirtualCalls;
-
+ bool _devirtAbstractCalls;
+ bool _devirtUsingProfile;
//unguard pass params
int _directCallPercent;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp Mon May 28 23:27:25 2007
@@ -158,8 +158,6 @@
//devirtualizer flags
optimizerFlags.devirt_do_aggressive_guarded_devirtualization = getBoolArg("devirt_aggressive", false);
- optimizerFlags.devirt_use_cha_with_profile = getBoolArg("devirt_use_cha_with_profile", false);
- optimizerFlags.devirt_use_cha_with_profile_threshold = getIntArg("devirt_use_cha_with_profile_threshold", -1);
optimizerFlags.devirt_skip_exception_path = getBoolArg("devirt_skip_exception_path", true);
optimizerFlags.devirt_block_hotness_multiplier= (float)getIntArg("devirt_block_hotness_multiplier", 10);
optimizerFlags.devirt_skip_object_methods = getBoolArg("devirt_skip_object_methods", false);
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h Mon May 28 23:27:25 2007
@@ -92,8 +92,6 @@
//devirt
bool devirt_do_aggressive_guarded_devirtualization;
- bool devirt_use_cha_with_profile;
- int devirt_use_cha_with_profile_threshold;
bool devirt_skip_exception_path;
float devirt_block_hotness_multiplier;
bool devirt_skip_object_methods;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/CGSupport.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/CGSupport.h?view=diff&rev=542423&r1=542422&r2=542423
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/CGSupport.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/CGSupport.h Mon May 28 23:27:25 2007
@@ -15,12 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Intel, Vitaly N. Chaiko
-* @version $Revision: 1.6.22.4 $
-*
-*/
-
#ifndef _CG_SUPPORT_H_
#define _CG_SUPPORT_H_
@@ -28,11 +22,8 @@
#include "MemoryManager.h"
#include "VMInterface.h"
-#if defined(_IPF_)
- #define ILLEGAL_VALUE 0xFFFFFFFFFFFFFFFF
-#else
- #define ILLEGAL_VALUE 0xFFFFFFFF
-#endif
+//FIXME 64-bit usage
+#define ILLEGAL_VALUE 0xFFFFFFFF
#define ESTIMATED_LIR_SIZE_PER_HIR 0x3
#define ESTIMATED_HIR_SIZE_PER_BYTECODE 0x8