summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2010-01-04 12:29:56 -0800
committerBen Cheng <bccheng@google.com>2010-01-07 13:42:30 -0800
commit60c24f436d603c564d5351a6f81821f12635733c (patch)
treea7891b72a6390aed9692803e84642e6bcc61dc50 /vm/compiler/codegen
parent81315cc4a0209073e0ae4946a6400b2cb571e616 (diff)
downloadandroid_dalvik-60c24f436d603c564d5351a6f81821f12635733c.tar.gz
android_dalvik-60c24f436d603c564d5351a6f81821f12635733c.tar.bz2
android_dalvik-60c24f436d603c564d5351a6f81821f12635733c.zip
Tear down the code cache when it is full and restart from scratch.
Because the code cache may be wiped out after safe points now the patching of inline cache for predicted chains is done through the compiler thread's work queue.
Diffstat (limited to 'vm/compiler/codegen')
-rw-r--r--vm/compiler/codegen/CompilerCodegen.h3
-rw-r--r--vm/compiler/codegen/arm/Assemble.c60
-rw-r--r--vm/compiler/codegen/arm/CodegenDriver.c3
3 files changed, 51 insertions, 15 deletions
diff --git a/vm/compiler/codegen/CompilerCodegen.h b/vm/compiler/codegen/CompilerCodegen.h
index 3e9718c6d..ff39cd408 100644
--- a/vm/compiler/codegen/CompilerCodegen.h
+++ b/vm/compiler/codegen/CompilerCodegen.h
@@ -31,6 +31,9 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit);
/* Assemble LIR into machine code */
void dvmCompilerAssembleLIR(CompilationUnit *cUnit, JitTranslationInfo *info);
+/* Patch inline cache content for polymorphic callsites */
+bool dvmJitPatchInlineCache(void *cellPtr, void *contentPtr);
+
/* Implemented in the codegen/<target>/ArchUtility.c */
void dvmCompilerCodegenDump(CompilationUnit *cUnit);
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 26e227fd3..7444b3eba 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -1407,35 +1407,65 @@ const Method *dvmJitToPatchPredictedChain(const Method *method,
*/
cell->counter = PREDICTED_CHAIN_COUNTER_AVOID;
- /* Stop the world */
- dvmSuspendAllThreads(SUSPEND_FOR_IC_PATCH);
+ PredictedChainingCell *newCell =
+ (PredictedChainingCell *) malloc(sizeof(PredictedChainingCell));
int baseAddr = (int) cell + 4; // PC is cur_addr + 4
int branchOffset = tgtAddr - baseAddr;
- COMPILER_TRACE_CHAINING(
- LOGD("Jit Runtime: predicted chain %p from %s to %s (%s) patched",
- cell, cell->clazz ? cell->clazz->descriptor : "NULL",
- clazz->descriptor,
- method->name));
+ newCell->branch = assembleChainingBranch(branchOffset, true);
+ newCell->clazz = clazz;
+ newCell->method = method;
- cell->branch = assembleChainingBranch(branchOffset, true);
- cell->clazz = clazz;
- cell->method = method;
/*
* Reset the counter again in case other mutator threads got invoked
* between the previous rest and dvmSuspendAllThreads call.
*/
- cell->counter = PREDICTED_CHAIN_COUNTER_RECHAIN;
+ newCell->counter = PREDICTED_CHAIN_COUNTER_RECHAIN;
- cacheflush((long) cell, (long) (cell+1), 0);
+ /*
+ * Enter the work order to the queue for the compiler thread to patch the
+ * chaining cell.
+ *
+ * No blocking call is added here because the patched result is not
+ * intended to be immediately consumed by the requesting thread. Its
+ * execution is simply resumed by chasing the class pointer to resolve the
+ * callsite.
+ */
+ dvmCompilerWorkEnqueue((const u2 *) cell, kWorkOrderICPatch, newCell);
+#endif
+done:
+ return method;
+}
+
+/*
+ * Patch the inline cache content based on the content passed from the work
+ * order.
+ */
+bool dvmJitPatchInlineCache(void *cellPtr, void *contentPtr)
+{
+ PredictedChainingCell *cellDest = (PredictedChainingCell *) cellPtr;
+ PredictedChainingCell *newContent = (PredictedChainingCell *) contentPtr;
+
+ /* Stop the world */
+ dvmSuspendAllThreads(SUSPEND_FOR_IC_PATCH);
+
+ COMPILER_TRACE_CHAINING(
+ LOGD("Jit Runtime: predicted chain %p from %s to %s (%s) patched",
+ cellDest, cellDest->clazz ? cellDest->clazz->descriptor : "NULL",
+ newContent->clazz->descriptor,
+ newContent->method->name));
+
+ /* Install the new cell content */
+ *cellDest = *newContent;
+
+ /* Then synchronize the I/D$ */
+ cacheflush((long) cellDest, (long) (cellDest+1), 0);
/* All done - resume all other threads */
dvmResumeAllThreads(SUSPEND_FOR_IC_PATCH);
-#endif
-done:
- return method;
+ return true;
}
/*
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index f3648b9bd..010e8ca23 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -4117,6 +4117,9 @@ bool dvmCompilerDoWork(CompilerWorkOrder *work)
gDvmJit.printMe = oldPrintMe;;
break;
}
+ case kWorkOrderICPatch:
+ res = dvmJitPatchInlineCache((void *) work->pc, work->info);
+ break;
default:
res = false;
dvmAbort();