Improved method invocation performance: 1.5x for virtual and 2.8x for interface.
- Implemented predicted chaining for invoke virtual and interface.
- Eliminated a little bit of fat for invoke native.
- Added 078-polymorphic-virtual for stress tests.
diff --git a/vm/compiler/Frontend.c b/vm/compiler/Frontend.c
index 76d9312..77548d9 100644
--- a/vm/compiler/Frontend.c
+++ b/vm/compiler/Frontend.c
@@ -433,24 +433,31 @@
kInstrInvoke)) == 0;
/* Target block not included in the trace */
- if (targetOffset != curOffset && curBB->taken == NULL) {
+ if (curBB->taken == NULL &&
+ (isInvoke || (targetOffset != curOffset))) {
+ BasicBlock *newBB;
if (isInvoke) {
- lastBB->next = dvmCompilerNewBB(CHAINING_CELL_INVOKE);
+ /* Monomorphic callee */
+ if (callee) {
+ newBB = dvmCompilerNewBB(CHAINING_CELL_INVOKE_SINGLETON);
+ newBB->startOffset = 0;
+ newBB->containingMethod = callee;
+ /* Will resolve at runtime */
+ } else {
+ newBB = dvmCompilerNewBB(CHAINING_CELL_INVOKE_PREDICTED);
+ newBB->startOffset = 0;
+ }
/* For unconditional branches, request a hot chaining cell */
} else {
- lastBB->next = dvmCompilerNewBB(flags & kInstrUnconditional ?
+ newBB = dvmCompilerNewBB(flags & kInstrUnconditional ?
CHAINING_CELL_HOT :
CHAINING_CELL_NORMAL);
+ newBB->startOffset = targetOffset;
}
- lastBB = lastBB->next;
- lastBB->id = numBlocks++;
- if (isInvoke) {
- lastBB->startOffset = 0;
- lastBB->containingMethod = callee;
- } else {
- lastBB->startOffset = targetOffset;
- }
- curBB->taken = lastBB;
+ newBB->id = numBlocks++;
+ curBB->taken = newBB;
+ lastBB->next = newBB;
+ lastBB = newBB;
}
/* Fallthrough block not included in the trace */