diff options
author | buzbee <buzbee@google.com> | 2011-05-25 14:21:14 -0700 |
---|---|---|
committer | buzbee <buzbee@google.com> | 2011-05-25 14:21:14 -0700 |
commit | cf4a20cf0cbc53f03a5b16c7152bbb29907f7108 (patch) | |
tree | 6fbd3def6f4ba9cb914d9c0e28108a162bf51050 /vm/interp | |
parent | 9522632b57b4df3249e4ee5fee3c1cfec8440e57 (diff) | |
download | android_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.cpp | 2 | ||||
-rw-r--r-- | vm/interp/InterpState.h | 1 | ||||
-rw-r--r-- | vm/interp/Jit.cpp | 4 |
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; |