Support for SetVReg and add SetGPR.
These changes are useful for debugging and are required for being able
to change all GC roots.
MIPS is untested.
Change-Id: I2ba055de64264098bffe869a4fb192d0975f1c8f
diff --git a/src/stack.h b/src/stack.h
index ce84807..ecfa846 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -51,9 +51,10 @@
kUndefined,
};
-// ShadowFrame has 3 possible layouts: portable (VRegs & references overlap),
-// interpreter (VRegs and separate references array), JNI (just VRegs, but where
-// VRegs really => references).
+// ShadowFrame has 3 possible layouts:
+// - portable - a unified array of VRegs and references. Precise references need GC maps.
+// - interpreter - separate VRegs and reference arrays. References are in the reference array.
+// - JNI - just VRegs, but where every VReg holds a reference.
class ShadowFrame {
public:
// Create ShadowFrame for interpreter.
@@ -77,7 +78,6 @@
}
void SetNumberOfVRegs(uint32_t number_of_vregs) {
- DCHECK(number_of_vregs < kHasReferenceArray);
number_of_vregs_ = number_of_vregs | (number_of_vregs_ & kHasReferenceArray);
}
@@ -207,18 +207,21 @@
ShadowFrame(uint32_t num_vregs, ShadowFrame* link, AbstractMethod* method, uint32_t dex_pc,
bool has_reference_array)
: number_of_vregs_(num_vregs), link_(link), method_(method), dex_pc_(dex_pc) {
+ CHECK_LT(num_vregs, static_cast<uint32_t>(kHasReferenceArray));
if (has_reference_array) {
number_of_vregs_ |= kHasReferenceArray;
for (size_t i = 0; i < num_vregs; ++i) {
SetVRegReference(i, NULL);
}
- }
- for (size_t i = 0; i < num_vregs; ++i) {
- SetVReg(i, 0);
+ } else {
+ for (size_t i = 0; i < num_vregs; ++i) {
+ SetVReg(i, 0);
+ }
}
}
Object* const* References() const {
+ DCHECK(HasReferenceArray());
const uint32_t* vreg_end = &vregs_[NumberOfVRegs()];
return reinterpret_cast<Object* const*>(vreg_end);
}
@@ -362,16 +365,15 @@
size_t GetNativePcOffset() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uintptr_t LoadCalleeSave(int num, size_t frame_size) const {
+ uintptr_t* CalleeSaveAddress(int num, size_t frame_size) const {
// Callee saves are held at the top of the frame
- AbstractMethod* method = GetMethod();
- DCHECK(method != NULL);
+ DCHECK(GetMethod() != NULL);
byte* save_addr =
reinterpret_cast<byte*>(cur_quick_frame_) + frame_size - ((num + 1) * kPointerSize);
#if defined(__i386__)
save_addr -= kPointerSize; // account for return address
#endif
- return *reinterpret_cast<uintptr_t*>(save_addr);
+ return reinterpret_cast<uintptr_t*>(save_addr);
}
// Returns the height of the stack in the managed stack frames, including transitions.
@@ -398,6 +400,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
uintptr_t GetGPR(uint32_t reg) const;
+ void SetGPR(uint32_t reg, uintptr_t value);
uint32_t GetVReg(AbstractMethod** cur_quick_frame, const DexFile::CodeItem* code_item,
uint32_t core_spills, uint32_t fp_spills, size_t frame_size,