Merge "Trampoline and assembly fixes for ARM64"
diff --git a/compiler/dex/local_value_numbering.cc b/compiler/dex/local_value_numbering.cc
index 45167a8..8dbc2bb 100644
--- a/compiler/dex/local_value_numbering.cc
+++ b/compiler/dex/local_value_numbering.cc
@@ -482,9 +482,9 @@
case Instruction::SHL_INT_LIT8:
case Instruction::SHR_INT_LIT8:
case Instruction::USHR_INT_LIT8: {
- // Same as res = op + 2 operands, except use vB as operand 2
+ // Same as res = op + 2 operands, except use vC as operand 2
uint16_t operand1 = GetOperandValue(mir->ssa_rep->uses[0]);
- uint16_t operand2 = LookupValue(Instruction::CONST, mir->dalvikInsn.vB, 0, 0);
+ uint16_t operand2 = LookupValue(Instruction::CONST, mir->dalvikInsn.vC, 0, 0);
res = LookupValue(opcode, operand1, operand2, NO_VALUE);
SetOperandValue(mir->ssa_rep->defs[0], res);
}
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 34f140b..8ce4f1f 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -766,7 +766,7 @@
for (idx = 0; idx < num_blocks; idx++) {
int block_idx = all_blocks ? idx : dfs_order_->Get(idx);
BasicBlock *bb = GetBasicBlock(block_idx);
- if (bb == NULL) break;
+ if (bb == NULL) continue;
if (bb->block_type == kDead) continue;
if (bb->block_type == kEntryBlock) {
fprintf(file, " entry_%d [shape=Mdiamond];\n", bb->id);
@@ -838,21 +838,19 @@
fprintf(file, " %s:s -> succ%04x_%d:n [style=dashed]\n",
block_name1, bb->start_offset, bb->id);
- if (bb->successor_block_list_type == kPackedSwitch ||
- bb->successor_block_list_type == kSparseSwitch) {
- GrowableArray<SuccessorBlockInfo*>::Iterator iter(bb->successor_blocks);
+ // Link the successor pseudo-block with all of its potential targets.
+ GrowableArray<SuccessorBlockInfo*>::Iterator iter(bb->successor_blocks);
- succ_id = 0;
- while (true) {
- SuccessorBlockInfo *successor_block_info = iter.Next();
- if (successor_block_info == NULL) break;
+ succ_id = 0;
+ while (true) {
+ SuccessorBlockInfo *successor_block_info = iter.Next();
+ if (successor_block_info == NULL) break;
- BasicBlock* dest_block = GetBasicBlock(successor_block_info->block);
+ BasicBlock* dest_block = GetBasicBlock(successor_block_info->block);
- GetBlockName(dest_block, block_name2);
- fprintf(file, " succ%04x_%d:f%d:e -> %s:n\n", bb->start_offset,
- bb->id, succ_id++, block_name2);
- }
+ GetBlockName(dest_block, block_name2);
+ fprintf(file, " succ%04x_%d:f%d:e -> %s:n\n", bb->start_offset,
+ bb->id, succ_id++, block_name2);
}
}
fprintf(file, "\n");
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 5078182..6824183 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -579,37 +579,51 @@
image_writer->FixupObject(obj, copy);
}
+class FixupVisitor {
+ public:
+ FixupVisitor(ImageWriter* image_writer, Object* copy) : image_writer_(image_writer), copy_(copy) {
+ }
+
+ void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
+ Object* ref = obj->GetFieldObject<Object, kVerifyNone>(offset, false);
+ // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
+ // image.
+ copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ offset, image_writer_->GetImageAddress(ref), false);
+ }
+
+ // java.lang.ref.Reference visitor.
+ void operator()(mirror::Class* /*klass*/, mirror::Reference* ref) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+ copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ mirror::Reference::ReferentOffset(), image_writer_->GetImageAddress(ref->GetReferent()),
+ false);
+ }
+
+ private:
+ ImageWriter* const image_writer_;
+ mirror::Object* const copy_;
+};
+
void ImageWriter::FixupObject(Object* orig, Object* copy) {
- DCHECK(orig != NULL);
- DCHECK(copy != NULL);
- copy->SetClass<kVerifyNone>(down_cast<Class*>(GetImageAddress(orig->GetClass())));
+ DCHECK(orig != nullptr);
+ DCHECK(copy != nullptr);
if (kUseBrooksPointer) {
orig->AssertSelfBrooksPointer();
// Note the address 'copy' isn't the same as the image address of 'orig'.
copy->SetBrooksPointer(GetImageAddress(orig));
- DCHECK(copy->GetBrooksPointer() == GetImageAddress(orig));
+ DCHECK_EQ(copy->GetBrooksPointer(), GetImageAddress(orig));
}
- // TODO: special case init of pointers to malloc data (or removal of these pointers)
- if (orig->IsClass<kVerifyNone>()) {
- FixupClass(orig->AsClass<kVerifyNone>(), down_cast<Class*>(copy));
- } else if (orig->IsObjectArray<kVerifyNone>()) {
- FixupObjectArray(orig->AsObjectArray<Object, kVerifyNone>(),
- down_cast<ObjectArray<Object>*>(copy));
- } else if (orig->IsArtMethod<kVerifyNone>()) {
+ FixupVisitor visitor(this, copy);
+ orig->VisitReferences<true /*visit class*/>(visitor, visitor);
+ if (orig->IsArtMethod<kVerifyNone>()) {
FixupMethod(orig->AsArtMethod<kVerifyNone>(), down_cast<ArtMethod*>(copy));
- } else {
- FixupInstanceFields(orig, copy);
}
}
-void ImageWriter::FixupClass(Class* orig, Class* copy) {
- FixupInstanceFields(orig, copy);
- FixupStaticFields(orig, copy);
-}
-
void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) {
- FixupInstanceFields(orig, copy);
-
// OatWriter replaces the code_ with an offset value. Here we re-adjust to a pointer relative to
// oat_begin_
@@ -680,79 +694,6 @@
}
}
-void ImageWriter::FixupObjectArray(ObjectArray<Object>* orig, ObjectArray<Object>* copy) {
- for (int32_t i = 0; i < orig->GetLength(); ++i) {
- Object* element = orig->Get(i);
- copy->SetWithoutChecksAndWriteBarrier<false, true, kVerifyNone>(i, GetImageAddress(element));
- }
-}
-
-void ImageWriter::FixupInstanceFields(Object* orig, Object* copy) {
- DCHECK(orig != NULL);
- DCHECK(copy != NULL);
- Class* klass = orig->GetClass();
- DCHECK(klass != NULL);
- FixupFields(orig, copy, klass->GetReferenceInstanceOffsets(), false);
-}
-
-void ImageWriter::FixupStaticFields(Class* orig, Class* copy) {
- DCHECK(orig != NULL);
- DCHECK(copy != NULL);
- FixupFields(orig, copy, orig->GetReferenceStaticOffsets(), true);
-}
-
-void ImageWriter::FixupFields(Object* orig,
- Object* copy,
- uint32_t ref_offsets,
- bool is_static) {
- if (ref_offsets != CLASS_WALK_SUPER) {
- // Found a reference offset bitmap. Fixup the specified offsets.
- while (ref_offsets != 0) {
- size_t right_shift = CLZ(ref_offsets);
- MemberOffset byte_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
- Object* ref = orig->GetFieldObject<Object, kVerifyNone>(byte_offset, false);
- // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
- // image.
- copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
- byte_offset, GetImageAddress(ref), false);
- ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
- }
- } else {
- // 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 (Class *klass = is_static ? orig->AsClass() : orig->GetClass();
- klass != NULL;
- klass = is_static ? NULL : klass->GetSuperClass()) {
- size_t num_reference_fields = (is_static
- ? klass->NumReferenceStaticFields()
- : klass->NumReferenceInstanceFields());
- for (size_t i = 0; i < num_reference_fields; ++i) {
- ArtField* field = (is_static
- ? klass->GetStaticField(i)
- : klass->GetInstanceField(i));
- MemberOffset field_offset = field->GetOffset();
- Object* ref = orig->GetFieldObject<Object, kVerifyNone>(field_offset, false);
- // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
- // image.
- copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
- field_offset, GetImageAddress(ref), false);
- }
- }
- }
- if (!is_static && orig->IsReferenceInstance()) {
- // Fix-up referent, that isn't marked as an object field, for References.
- ArtField* field = orig->GetClass()->FindInstanceField("referent", "Ljava/lang/Object;");
- MemberOffset field_offset = field->GetOffset();
- Object* ref = orig->GetFieldObject<Object>(field_offset, false);
- // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
- // image.
- copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
- field_offset, GetImageAddress(ref), false);
- }
-}
-
static ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index dff33ba..92b24f6 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -141,22 +141,10 @@
void CopyAndFixupObjects();
static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupClass(mirror::Class* orig, mirror::Class* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupMethod(mirror::ArtMethod* orig, mirror::ArtMethod* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupObject(mirror::Object* orig, mirror::Object* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupObjectArray(mirror::ObjectArray<mirror::Object>* orig,
- mirror::ObjectArray<mirror::Object>* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupInstanceFields(mirror::Object* orig, mirror::Object* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupStaticFields(mirror::Class* orig, mirror::Class* copy)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupFields(mirror::Object* orig, mirror::Object* copy, uint32_t ref_offsets,
- bool is_static)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Patches references in OatFile to expect runtime addresses.
void PatchOatCodeAndMethods()
@@ -164,7 +152,6 @@
void SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
const CompilerDriver& compiler_driver_;
// oat file with code for this image
@@ -199,6 +186,9 @@
uint32_t quick_imt_conflict_trampoline_offset_;
uint32_t quick_resolution_trampoline_offset_;
uint32_t quick_to_interpreter_bridge_offset_;
+
+ friend class FixupVisitor;
+ DISALLOW_COPY_AND_ASSIGN(ImageWriter);
};
} // namespace art