summaryrefslogtreecommitdiffstats
path: root/vm/interp
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2011-05-25 14:21:14 -0700
committerbuzbee <buzbee@google.com>2011-05-25 14:21:14 -0700
commitcf4a20cf0cbc53f03a5b16c7152bbb29907f7108 (patch)
tree6fbd3def6f4ba9cb914d9c0e28108a162bf51050 /vm/interp
parent9522632b57b4df3249e4ee5fee3c1cfec8440e57 (diff)
downloadandroid_dalvik-cf4a20cf0cbc53f03a5b16c7152bbb29907f7108.tar.gz
android_dalvik-cf4a20cf0cbc53f03a5b16c7152bbb29907f7108.tar.bz2
android_dalvik-cf4a20cf0cbc53f03a5b16c7152bbb29907f7108.zip
Interpreter/Debugger fix #4479968
This one was tricky to track down. The underlying problem arose with the consolidation of InterpState with Thread. Rather than having a state structure for each instance of the interpreter, we moved to a model that had a single thread-local struct shared by all interpreter instances running on that thread. A portion of interpreter state can't be shared - and thus was saved and restored on nested invocations of the interpreter. The bug here was that the storage for method return values was not included in the state that needed save/retore. In normal operation, it doesn't need to be saved - that storage isn't live across an invoke that could trigger a nested interpreter activation. However, when debugging, the debugger itself may hijack threads and create new interpreter instances for its own purposed - and there is a small window in which live retval can be trashed. The fix is simply to move retval into the InterpSave struct. Change-Id: Ib621824b799c5caa16fdfa8f5689a181159059df
Diffstat (limited to 'vm/interp')
-rw-r--r--vm/interp/Interp.cpp2
-rw-r--r--vm/interp/InterpState.h1
-rw-r--r--vm/interp/Jit.cpp4
3 files changed, 4 insertions, 3 deletions
diff --git a/vm/interp/Interp.cpp b/vm/interp/Interp.cpp
index 67566e86d..7c68e903c 100644
--- a/vm/interp/Interp.cpp
+++ b/vm/interp/Interp.cpp
@@ -1984,7 +1984,7 @@ void dvmInterpret(Thread* self, const Method* method, JValue* pResult)
// Call the interpreter
(*stdInterp)(self);
- *pResult = self->retval;
+ *pResult = self->interpSave.retval;
/* Restore interpreter state from previous activation */
self->interpSave = interpSaveState;
diff --git a/vm/interp/InterpState.h b/vm/interp/InterpState.h
index b782275d2..999795347 100644
--- a/vm/interp/InterpState.h
+++ b/vm/interp/InterpState.h
@@ -99,6 +99,7 @@ struct InterpSaveState {
u4* curFrame; // Dalvik frame pointer
const Method *method; // Method being executed
DvmDex* methodClassDex;
+ JValue retval;
void* bailPtr;
#if defined(WITH_TRACKREF_CHECKS)
int debugTrackedRefStart;
diff --git a/vm/interp/Jit.cpp b/vm/interp/Jit.cpp
index bb8d6d7ee..9632e9723 100644
--- a/vm/interp/Jit.cpp
+++ b/vm/interp/Jit.cpp
@@ -96,7 +96,7 @@ void* dvmSelfVerificationSaveState(const u2* pc, u4* fp,
// Remember original state
shadowSpace->startPC = pc;
shadowSpace->fp = fp;
- shadowSpace->retval = self->retval;
+ shadowSpace->retval = self->interpSave.retval;
shadowSpace->interpStackEnd = self->interpStackEnd;
/*
@@ -165,7 +165,7 @@ void* dvmSelfVerificationRestoreState(const u2* pc, u4* fp,
self->interpSave.curFrame = shadowSpace->fp;
self->interpSave.method = shadowSpace->method;
self->interpSave.methodClassDex = shadowSpace->methodClassDex;
- self->retval = shadowSpace->retval;
+ self->interpSave.retval = shadowSpace->retval;
self->interpStackEnd = shadowSpace->interpStackEnd;
return shadowSpace;