Merge "Re-add read barrier to roots in the verifier."
diff --git a/compiler/dex/bb_optimizations.h b/compiler/dex/bb_optimizations.h
index 2920190..b2c348b 100644
--- a/compiler/dex/bb_optimizations.h
+++ b/compiler/dex/bb_optimizations.h
@@ -34,16 +34,16 @@
void Start(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->DoCacheFieldLoweringInfo();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->DoCacheFieldLoweringInfo();
}
bool Gate(const PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return cUnit->mir_graph->HasFieldAccess();
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return c_unit->mir_graph->HasFieldAccess();
}
};
@@ -58,16 +58,16 @@
void Start(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->DoCacheMethodLoweringInfo();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->DoCacheMethodLoweringInfo();
}
bool Gate(const PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return cUnit->mir_graph->HasInvokes();
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return c_unit->mir_graph->HasInvokes();
}
};
@@ -84,35 +84,35 @@
bool Gate(const PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return cUnit->mir_graph->InlineSpecialMethodsGate();
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return c_unit->mir_graph->InlineSpecialMethodsGate();
}
void Start(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->InlineSpecialMethodsStart();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->InlineSpecialMethodsStart();
}
bool Worker(PassDataHolder* data) const {
DCHECK(data != nullptr);
PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
- CompilationUnit* cUnit = pass_me_data_holder->c_unit;
- DCHECK(cUnit != nullptr);
+ CompilationUnit* c_unit = pass_me_data_holder->c_unit;
+ DCHECK(c_unit != nullptr);
BasicBlock* bb = pass_me_data_holder->bb;
DCHECK(bb != nullptr);
- cUnit->mir_graph->InlineSpecialMethods(bb);
+ c_unit->mir_graph->InlineSpecialMethods(bb);
// No need of repeating, so just return false.
return false;
}
void End(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->InlineSpecialMethodsEnd();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->InlineSpecialMethodsEnd();
}
};
@@ -127,9 +127,10 @@
void Start(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->VerifyDataflow();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->VerifyDataflow();
+ c_unit->mir_graph->ClearAllVisitedFlags();
}
bool Worker(PassDataHolder* data) const;
@@ -147,26 +148,26 @@
void Start(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->EliminateNullChecksAndInferTypesStart();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->EliminateNullChecksAndInferTypesStart();
}
bool Worker(PassDataHolder* data) const {
DCHECK(data != nullptr);
PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
- CompilationUnit* cUnit = pass_me_data_holder->c_unit;
- DCHECK(cUnit != nullptr);
+ CompilationUnit* c_unit = pass_me_data_holder->c_unit;
+ DCHECK(c_unit != nullptr);
BasicBlock* bb = pass_me_data_holder->bb;
DCHECK(bb != nullptr);
- return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
+ return c_unit->mir_graph->EliminateNullChecksAndInferTypes(bb);
}
void End(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->EliminateNullChecksAndInferTypesEnd();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->EliminateNullChecksAndInferTypesEnd();
}
};
@@ -178,26 +179,26 @@
bool Gate(const PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return cUnit->mir_graph->EliminateClassInitChecksGate();
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return c_unit->mir_graph->EliminateClassInitChecksGate();
}
bool Worker(PassDataHolder* data) const {
DCHECK(data != nullptr);
PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
- CompilationUnit* cUnit = pass_me_data_holder->c_unit;
- DCHECK(cUnit != nullptr);
+ CompilationUnit* c_unit = pass_me_data_holder->c_unit;
+ DCHECK(c_unit != nullptr);
BasicBlock* bb = pass_me_data_holder->bb;
DCHECK(bb != nullptr);
- return cUnit->mir_graph->EliminateClassInitChecks(bb);
+ return c_unit->mir_graph->EliminateClassInitChecks(bb);
}
void End(PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->EliminateClassInitChecksEnd();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->EliminateClassInitChecksEnd();
}
};
@@ -213,26 +214,26 @@
bool Gate(const PassDataHolder* data) const OVERRIDE {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return cUnit->mir_graph->ApplyGlobalValueNumberingGate();
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return c_unit->mir_graph->ApplyGlobalValueNumberingGate();
}
bool Worker(PassDataHolder* data) const {
DCHECK(data != nullptr);
PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
- CompilationUnit* cUnit = pass_me_data_holder->c_unit;
- DCHECK(cUnit != nullptr);
+ CompilationUnit* c_unit = pass_me_data_holder->c_unit;
+ DCHECK(c_unit != nullptr);
BasicBlock* bb = pass_me_data_holder->bb;
DCHECK(bb != nullptr);
- return cUnit->mir_graph->ApplyGlobalValueNumbering(bb);
+ return c_unit->mir_graph->ApplyGlobalValueNumbering(bb);
}
void End(PassDataHolder* data) const OVERRIDE {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- cUnit->mir_graph->ApplyGlobalValueNumberingEnd();
+ CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ c_unit->mir_graph->ApplyGlobalValueNumberingEnd();
}
};
@@ -247,9 +248,9 @@
bool Gate(const PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return ((c_unit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
}
bool Worker(PassDataHolder* data) const;
@@ -266,9 +267,9 @@
bool Gate(const PassDataHolder* data) const {
DCHECK(data != nullptr);
- CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
- DCHECK(cUnit != nullptr);
- return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
+ CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+ DCHECK(c_unit != nullptr);
+ return ((c_unit->disable_opt & (1 << kBBOpt)) == 0);
}
void Start(PassDataHolder* data) const;
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 5d7cbed..7ac878f 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -678,26 +678,40 @@
}
}
-/* Try to make common case the fallthrough path */
+/* Try to make common case the fallthrough path. */
bool MIRGraph::LayoutBlocks(BasicBlock* bb) {
- // TODO: For now, just looking for direct throws. Consider generalizing for profile feedback
+ // TODO: For now, just looking for direct throws. Consider generalizing for profile feedback.
if (!bb->explicit_throw) {
return false;
}
+
+ // If we visited it, we are done.
+ if (bb->visited) {
+ return false;
+ }
+ bb->visited = true;
+
BasicBlock* walker = bb;
while (true) {
- // Check termination conditions
+ // Check termination conditions.
if ((walker->block_type == kEntryBlock) || (Predecessors(walker) != 1)) {
break;
}
BasicBlock* prev = GetBasicBlock(walker->predecessors->Get(0));
+
+ // If we visited the predecessor, we are done.
+ if (prev->visited) {
+ return false;
+ }
+ prev->visited = true;
+
if (prev->conditional_branch) {
if (GetBasicBlock(prev->fall_through) == walker) {
- // Already done - return
+ // Already done - return.
break;
}
DCHECK_EQ(walker, GetBasicBlock(prev->taken));
- // Got one. Flip it and exit
+ // Got one. Flip it and exit.
Instruction::Code opcode = prev->last_mir_insn->dalvikInsn.opcode;
switch (opcode) {
case Instruction::IF_EQ: opcode = Instruction::IF_NE; break;
@@ -721,6 +735,10 @@
break;
}
walker = prev;
+
+ if (walker->visited) {
+ break;
+ }
}
return false;
}
diff --git a/compiler/dex/quick/arm/assemble_arm.cc b/compiler/dex/quick/arm/assemble_arm.cc
index 06d9dd5..dcec861 100644
--- a/compiler/dex/quick/arm/assemble_arm.cc
+++ b/compiler/dex/quick/arm/assemble_arm.cc
@@ -427,7 +427,7 @@
REG_DEF_LR | NEEDS_FIXUP, "vldr", "!0s, [!1C, #!2E]", 4, kFixupVLoad),
ENCODING_MAP(kThumb2Vldrd, 0xed900b00,
kFmtDfp, 22, 12, kFmtBitBlt, 19, 16, kFmtBitBlt, 7, 0,
- kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE1 | IS_LOAD_OFF |
+ kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE1 | IS_LOAD_OFF4 |
REG_DEF_LR | NEEDS_FIXUP, "vldr", "!0S, [!1C, #!2E]", 4, kFixupVLoad),
ENCODING_MAP(kThumb2Vmuls, 0xee200a00,
kFmtSfp, 22, 12, kFmtSfp, 7, 16, kFmtSfp, 5, 0,
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 26b6c60..4342234 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4427,7 +4427,6 @@
return false;
}
CreateReferenceInstanceOffsets(klass);
- CreateReferenceStaticOffsets(klass);
CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus());
if (!klass->IsTemp() || (!init_done_ && klass->GetClassSize() == class_size)) {
@@ -5160,20 +5159,13 @@
return;
}
}
- CreateReferenceOffsets(klass, false, reference_offsets);
+ CreateReferenceOffsets(klass, reference_offsets);
}
-void ClassLinker::CreateReferenceStaticOffsets(ConstHandle<mirror::Class> klass) {
- CreateReferenceOffsets(klass, true, 0);
-}
-
-void ClassLinker::CreateReferenceOffsets(ConstHandle<mirror::Class> klass, bool is_static,
+void ClassLinker::CreateReferenceOffsets(ConstHandle<mirror::Class> klass,
uint32_t reference_offsets) {
- size_t num_reference_fields =
- is_static ? klass->NumReferenceStaticFieldsDuringLinking()
- : klass->NumReferenceInstanceFieldsDuringLinking();
- mirror::ObjectArray<mirror::ArtField>* fields =
- is_static ? klass->GetSFields() : klass->GetIFields();
+ size_t num_reference_fields = klass->NumReferenceInstanceFieldsDuringLinking();
+ mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields();
// All of the fields that contain object references are guaranteed
// to be at the beginning of the fields list.
for (size_t i = 0; i < num_reference_fields; ++i) {
@@ -5191,12 +5183,7 @@
break;
}
}
- // Update fields in klass
- if (is_static) {
- klass->SetReferenceStaticOffsets(reference_offsets);
- } else {
- klass->SetReferenceInstanceOffsets(reference_offsets);
- }
+ klass->SetReferenceInstanceOffsets(reference_offsets);
}
mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, uint32_t string_idx,
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 0248a21..158816d 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -533,10 +533,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void CreateReferenceInstanceOffsets(ConstHandle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceStaticOffsets(ConstHandle<mirror::Class> klass)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceOffsets(ConstHandle<mirror::Class> klass, bool is_static,
- uint32_t reference_offsets)
+ void CreateReferenceOffsets(ConstHandle<mirror::Class> klass, uint32_t reference_offsets)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// For use by ImageWriter to find DexCaches for its roots
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 69c281e..b250918 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -528,7 +528,6 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, object_size_), "objectSize"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, primitive_type_), "primitiveType"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, reference_instance_offsets_), "referenceInstanceOffsets"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, reference_static_offsets_), "referenceStaticOffsets"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, status_), "status"));
};
};
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 760d54c..e7d8163 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -292,18 +292,6 @@
new_reference_offsets);
}
-void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
- if (new_reference_offsets != CLASS_WALK_SUPER) {
- // Sanity check that the number of bits set in the reference offset bitmap
- // agrees with the number of references
- CHECK_EQ((size_t)POPCOUNT(new_reference_offsets),
- NumReferenceStaticFieldsDuringLinking());
- }
- // Not called within a transaction.
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
- new_reference_offsets);
-}
-
bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
size_t i = 0;
while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 0d30bc6..cf9501a 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -871,14 +871,6 @@
// TODO: uint16_t
void SetStaticField(uint32_t i, ArtField* f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- uint32_t GetReferenceStaticOffsets() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_));
- }
-
- void SetReferenceStaticOffsets(uint32_t new_reference_offsets)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
// Find a static or instance field using the JLS resolution order
static ArtField* FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
const StringPiece& type)
@@ -1150,9 +1142,6 @@
// Bitmap of offsets of ifields.
uint32_t reference_instance_offsets_;
- // Bitmap of offsets of sfields.
- uint32_t reference_static_offsets_;
-
// State of class initialization.
Status status_;
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 8c1dc7d..166ea9c 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -888,9 +888,9 @@
template<bool kVisitClass, bool kIsStatic, typename Visitor>
inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
- if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
+ if (!kIsStatic && LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
if (!kVisitClass) {
- // Mask out the class from the reference offsets.
+ // Mask out the class from the reference offsets.
ref_offsets ^= kWordHighBitMask;
}
DCHECK_EQ(ClassOffset().Uint32Value(), 0U);
@@ -902,7 +902,7 @@
ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
}
} else {
- // There is no reference offset bitmap. In the non-static case, walk up the class
+ // There is no reference offset bitmap. In the non-static case, walk up the class
// inheritance hierarchy and find reference offsets the hard way. In the static case, just
// consider this class.
for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr;
@@ -930,8 +930,7 @@
template<bool kVisitClass, typename Visitor>
inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
DCHECK(!klass->IsTemp());
- klass->VisitFieldsReferences<kVisitClass, true>(
- klass->GetReferenceStaticOffsets<kVerifyNone>(), visitor);
+ klass->VisitFieldsReferences<kVisitClass, true>(0, visitor);
}
template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor,