summaryrefslogtreecommitdiffstats
path: root/runtime/stack.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/stack.h')
-rw-r--r--runtime/stack.h38
1 files changed, 37 insertions, 1 deletions
diff --git a/runtime/stack.h b/runtime/stack.h
index a4b93bc..3d6b06a 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -150,10 +150,15 @@ class ShadowFrame {
return *reinterpret_cast<unaligned_double*>(vreg);
}
+ template <bool kChecked = false>
mirror::Object* GetVRegReference(size_t i) const {
DCHECK_LT(i, NumberOfVRegs());
if (HasReferenceArray()) {
mirror::Object* ref = References()[i];
+ if (kChecked) {
+ CHECK(VerifyReference(ref)) << "VReg " << i << "(" << ref
+ << ") is in protected space, reference array " << true;
+ }
// If the vreg reference is not equal to the vreg then the vreg reference is stale.
if (reinterpret_cast<uint32_t>(ref) != vregs_[i]) {
return nullptr;
@@ -161,7 +166,12 @@ class ShadowFrame {
return ref;
} else {
const uint32_t* vreg = &vregs_[i];
- return *reinterpret_cast<mirror::Object* const*>(vreg);
+ mirror::Object* ref = *reinterpret_cast<mirror::Object* const*>(vreg);
+ if (kChecked) {
+ CHECK(VerifyReference(ref)) << "VReg " << i
+ << "(" << ref << ") is in protected space, reference array " << false;
+ }
+ return ref;
}
}
@@ -174,12 +184,22 @@ class ShadowFrame {
DCHECK_LT(i, NumberOfVRegs());
uint32_t* vreg = &vregs_[i];
*reinterpret_cast<int32_t*>(vreg) = val;
+ // This is needed for moving collectors since these can update the vreg references if they
+ // happen to agree with references in the reference array.
+ if (kMovingCollector && HasReferenceArray()) {
+ References()[i] = nullptr;
+ }
}
void SetVRegFloat(size_t i, float val) {
DCHECK_LT(i, NumberOfVRegs());
uint32_t* vreg = &vregs_[i];
*reinterpret_cast<float*>(vreg) = val;
+ // This is needed for moving collectors since these can update the vreg references if they
+ // happen to agree with references in the reference array.
+ if (kMovingCollector && HasReferenceArray()) {
+ References()[i] = nullptr;
+ }
}
void SetVRegLong(size_t i, int64_t val) {
@@ -188,6 +208,12 @@ class ShadowFrame {
// Alignment attribute required for GCC 4.8
typedef int64_t unaligned_int64 __attribute__ ((aligned (4)));
*reinterpret_cast<unaligned_int64*>(vreg) = val;
+ // This is needed for moving collectors since these can update the vreg references if they
+ // happen to agree with references in the reference array.
+ if (kMovingCollector && HasReferenceArray()) {
+ References()[i] = nullptr;
+ References()[i + 1] = nullptr;
+ }
}
void SetVRegDouble(size_t i, double val) {
@@ -196,10 +222,18 @@ class ShadowFrame {
// Alignment attribute required for GCC 4.8
typedef double unaligned_double __attribute__ ((aligned (4)));
*reinterpret_cast<unaligned_double*>(vreg) = val;
+ // This is needed for moving collectors since these can update the vreg references if they
+ // happen to agree with references in the reference array.
+ if (kMovingCollector && HasReferenceArray()) {
+ References()[i] = nullptr;
+ References()[i + 1] = nullptr;
+ }
}
void SetVRegReference(size_t i, mirror::Object* val) {
DCHECK_LT(i, NumberOfVRegs());
+ DCHECK(!kMovingCollector || VerifyReference(val))
+ << "VReg " << i << "(" << val << ") is in protected space";
uint32_t* vreg = &vregs_[i];
*reinterpret_cast<mirror::Object**>(vreg) = val;
if (HasReferenceArray()) {
@@ -280,6 +314,8 @@ class ShadowFrame {
return reinterpret_cast<mirror::Object* const*>(vreg_end);
}
+ bool VerifyReference(const mirror::Object* val) const;
+
mirror::Object** References() {
return const_cast<mirror::Object**>(const_cast<const ShadowFrame*>(this)->References());
}