Using gcmap instead of shadow frame.
Fix misuse of TBAAJRuntime & TBAARuntimeInfo. Now, the TBAAJRuntime is
only for runtime support function.
Update DexPC before lock object and suspend.
Change-Id: I40fa37f4863fe6e127328a8413285ee3c62e8505
diff --git a/src/stack.h b/src/stack.h
index 1134b25..ce84807 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -51,26 +51,34 @@
kUndefined,
};
+// ShadowFrame has 3 possible layouts: portable (VRegs & references overlap),
+// interpreter (VRegs and separate references array), JNI (just VRegs, but where
+// VRegs really => references).
class ShadowFrame {
public:
- static ShadowFrame* Create(uint16_t num_refs, uint16_t num_vregs, ShadowFrame* link,
+ // Create ShadowFrame for interpreter.
+ static ShadowFrame* Create(uint32_t num_vregs, ShadowFrame* link,
AbstractMethod* method, uint32_t dex_pc) {
- size_t sz = sizeof(ShadowFrame) + (sizeof(Object*) * num_refs) + (sizeof(uint32_t) * num_vregs);
+ size_t sz = sizeof(ShadowFrame) +
+ (sizeof(uint32_t) * num_vregs) +
+ (sizeof(Object*) * num_vregs);
uint8_t* memory = new uint8_t[sz];
- return new (memory) ShadowFrame(num_refs, num_vregs, link, method, dex_pc);
+ ShadowFrame* sf = new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true);
+ return sf;
}
~ShadowFrame() {}
- uint32_t NumberOfReferences() const {
- return number_of_references_;
+ bool HasReferenceArray() const {
+ return (number_of_vregs_ & kHasReferenceArray) != 0;
}
- void SetNumberOfReferences(uint16_t number_of_references) {
- number_of_references_ = number_of_references;
+ uint32_t NumberOfVRegs() const {
+ return number_of_vregs_ & ~kHasReferenceArray;
}
- void SetNumberOfVRegs(uint16_t number_of_vregs) {
- number_of_vregs_ = number_of_vregs;
+ void SetNumberOfVRegs(uint32_t number_of_vregs) {
+ DCHECK(number_of_vregs < kHasReferenceArray);
+ number_of_vregs_ = number_of_vregs | (number_of_vregs_ & kHasReferenceArray);
}
uint32_t GetDexPC() const {
@@ -90,67 +98,68 @@
link_ = frame;
}
- Object* GetReference(size_t i) const {
- DCHECK_LT(i, number_of_references_);
- return references_[i];
- }
-
- void SetReference(size_t i, Object* object) {
- DCHECK_LT(i, number_of_references_);
- references_[i] = object;
- }
-
int32_t GetVReg(size_t i) const {
- DCHECK_LT(i, number_of_vregs_);
- const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
- return reinterpret_cast<const int32_t*>(vregs)[i];
+ DCHECK_LT(i, NumberOfVRegs());
+ const uint32_t* vreg = &vregs_[i];
+ return *reinterpret_cast<const int32_t*>(vreg);
}
float GetVRegFloat(size_t i) const {
- DCHECK_LT(i, number_of_vregs_);
- const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
- return reinterpret_cast<const float*>(vregs)[i];
+ DCHECK_LT(i, NumberOfVRegs());
+ // NOTE: Strict-aliasing?
+ const uint32_t* vreg = &vregs_[i];
+ return *reinterpret_cast<const float*>(vreg);
}
int64_t GetVRegLong(size_t i) const {
- const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
- const int32_t* low_half = &reinterpret_cast<const int32_t*>(vregs)[i];
- return *reinterpret_cast<const int64_t*>(low_half);
+ const uint32_t* vreg = &vregs_[i];
+ return *reinterpret_cast<const int64_t*>(vreg);
}
double GetVRegDouble(size_t i) const {
- const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
- const int32_t* low_half = &reinterpret_cast<const int32_t*>(vregs)[i];
- return *reinterpret_cast<const double*>(low_half);
+ const uint32_t* vreg = &vregs_[i];
+ return *reinterpret_cast<const double*>(vreg);
+ }
+
+ Object* GetVRegReference(size_t i) const {
+ DCHECK_LT(i, NumberOfVRegs());
+ if (HasReferenceArray()) {
+ return References()[i];
+ } else {
+ const uint32_t* vreg = &vregs_[i];
+ return *reinterpret_cast<Object* const*>(vreg);
+ }
}
void SetVReg(size_t i, int32_t val) {
- DCHECK_LT(i, number_of_vregs_);
- int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
- reinterpret_cast<int32_t*>(vregs)[i] = val;
+ DCHECK_LT(i, NumberOfVRegs());
+ uint32_t* vreg = &vregs_[i];
+ *reinterpret_cast<int32_t*>(vreg) = val;
}
void SetVRegFloat(size_t i, float val) {
- DCHECK_LT(i, number_of_vregs_);
- int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
- reinterpret_cast<float*>(vregs)[i] = val;
+ DCHECK_LT(i, NumberOfVRegs());
+ uint32_t* vreg = &vregs_[i];
+ *reinterpret_cast<float*>(vreg) = val;
}
void SetVRegLong(size_t i, int64_t val) {
- int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
- int32_t* low_half = &reinterpret_cast<int32_t*>(vregs)[i];
- *reinterpret_cast<int64_t*>(low_half) = val;
+ uint32_t* vreg = &vregs_[i];
+ *reinterpret_cast<int64_t*>(vreg) = val;
}
void SetVRegDouble(size_t i, double val) {
- int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
- int32_t* low_half = &reinterpret_cast<int32_t*>(vregs)[i];
- *reinterpret_cast<double*>(low_half) = val;
+ uint32_t* vreg = &vregs_[i];
+ *reinterpret_cast<double*>(vreg) = val;
}
- void SetReferenceAndVReg(size_t i, Object* val) {
- SetReference(i, val);
- SetVReg(i, reinterpret_cast<int32_t>(val));
+ void SetVRegReference(size_t i, Object* val) {
+ DCHECK_LT(i, NumberOfVRegs());
+ uint32_t* vreg = &vregs_[i];
+ *reinterpret_cast<Object**>(vreg) = val;
+ if (HasReferenceArray()) {
+ References()[i] = val;
+ }
}
AbstractMethod* GetMethod() const {
@@ -163,19 +172,14 @@
method_ = method;
}
- bool Contains(Object** shadow_frame_entry) const {
- return ((&references_[0] <= shadow_frame_entry) &&
- (shadow_frame_entry <= (&references_[number_of_references_ - 1])));
- }
-
- template <typename Visitor>
- void VisitRoots(const Visitor& visitor) {
- size_t num_refs = NumberOfReferences();
- for (size_t j = 0; j < num_refs; j++) {
- Object* object = GetReference(j);
- if (object != NULL) {
- visitor(object, j);
- }
+ bool Contains(Object** shadow_frame_entry_obj) const {
+ if (HasReferenceArray()) {
+ return ((&References()[0] <= shadow_frame_entry_obj) &&
+ (shadow_frame_entry_obj <= (&References()[NumberOfVRegs() - 1])));
+ } else {
+ uint32_t* shadow_frame_entry = reinterpret_cast<uint32_t*>(shadow_frame_entry_obj);
+ return ((&vregs_[0] <= shadow_frame_entry) &&
+ (shadow_frame_entry <= (&vregs_[NumberOfVRegs() - 1])));
}
}
@@ -191,43 +195,48 @@
return OFFSETOF_MEMBER(ShadowFrame, dex_pc_);
}
- static size_t NumberOfReferencesOffset() {
- return OFFSETOF_MEMBER(ShadowFrame, number_of_references_);
- }
-
static size_t NumberOfVRegsOffset() {
return OFFSETOF_MEMBER(ShadowFrame, number_of_vregs_);
}
- static size_t ReferencesOffset() {
- return OFFSETOF_MEMBER(ShadowFrame, references_);
- }
-
- size_t VRegsOffset() const {
- return ReferencesOffset() + (sizeof(Object*) * NumberOfReferences());
+ static size_t VRegsOffset() {
+ return OFFSETOF_MEMBER(ShadowFrame, vregs_);
}
private:
- ShadowFrame(uint16_t num_refs, uint16_t num_vregs, ShadowFrame* link, AbstractMethod* method,
- uint32_t dex_pc)
- : number_of_references_ (num_refs), number_of_vregs_(num_vregs), link_(link),
- method_(method), dex_pc_(dex_pc) {
- for (size_t i = 0; i < num_refs; ++i) {
- SetReference(i, NULL);
+ 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) {
+ 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);
}
}
+ Object* const* References() const {
+ const uint32_t* vreg_end = &vregs_[NumberOfVRegs()];
+ return reinterpret_cast<Object* const*>(vreg_end);
+ }
+
+ Object** References() {
+ return const_cast<Object**>(const_cast<const ShadowFrame*>(this)->References());
+ }
+
+ enum ShadowFrameFlag {
+ kHasReferenceArray = 1ul << 31
+ };
// TODO: make the majority of these fields const.
- uint16_t number_of_references_;
- uint16_t number_of_vregs_;
+ uint32_t number_of_vregs_;
// Link to previous shadow frame or NULL.
ShadowFrame* link_;
AbstractMethod* method_;
uint32_t dex_pc_;
- Object* references_[0];
+ uint32_t vregs_[0];
DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame);
};
@@ -306,7 +315,7 @@
return OFFSETOF_MEMBER(ManagedStack, top_shadow_frame_);
}
- size_t NumShadowFrameReferences() const;
+ size_t NumJniShadowFrameReferences() const;
bool ShadowFramesContain(Object** shadow_frame_entry) const;