summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2014-02-19 10:54:44 -0800
committer Mathieu Chartier <mathieuc@google.com> 2014-02-21 15:24:04 -0800
commit4e30541a92381fb280cd0be9a1763b713ee4d64c (patch)
tree84093651bbf0ad95b66b846c4f4cf4101994037b /compiler
parente266ba9935bd12d685d83f73cd8d759e46c3014d (diff)
Fix and optimize verify object.
VerifyObject no longer resides in heap. You can now enable VerifyObject for non-debug builds. VerifyStack is still slow, so it is now guarded by its own flag. Fixed the image writer to not use verification at places where verification fails due to invalid reads. Fixed RosAlloc to use SizeOf which doesn't call verify object. Added a flag paremeter to some of the mirror getters / setters to be able to selectively disable VerifyObject on certain calls. Optimized the GC to not verify each object multiple times during object scanning if verify object is enabled. Added 3 verification options: verify reads, verify this, and verify writes so that you can select how much verification you want for mirror getters and setters. Removed some useless DCHECKs which would slow debug builds without providing any benefits. TODO: RosAlloc verification doesn't currently work with verify objects. Bug: 12934910 Bug: 12879358 Change-Id: Ic61033104dfc334543f89b0fc0ad8cd4f4015d69
Diffstat (limited to 'compiler')
-rw-r--r--compiler/image_writer.cc62
1 files changed, 33 insertions, 29 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 60beebb842..58f66b9a35 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -581,14 +581,15 @@ void ImageWriter::CopyAndFixupObjectsCallback(Object* obj, void* arg) {
void ImageWriter::FixupObject(Object* orig, Object* copy) {
DCHECK(orig != NULL);
DCHECK(copy != NULL);
- copy->SetClass(down_cast<Class*>(GetImageAddress(orig->GetClass())));
+ copy->SetClass<kVerifyNone>(down_cast<Class*>(GetImageAddress(orig->GetClass())));
// TODO: special case init of pointers to malloc data (or removal of these pointers)
- if (orig->IsClass()) {
- FixupClass(orig->AsClass(), down_cast<Class*>(copy));
- } else if (orig->IsObjectArray()) {
- FixupObjectArray(orig->AsObjectArray<Object>(), down_cast<ObjectArray<Object>*>(copy));
- } else if (orig->IsArtMethod()) {
- FixupMethod(orig->AsArtMethod(), down_cast<ArtMethod*>(copy));
+ 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>()) {
+ FixupMethod(orig->AsArtMethod<kVerifyNone>(), down_cast<ArtMethod*>(copy));
} else {
FixupInstanceFields(orig, copy);
}
@@ -607,54 +608,54 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) {
// The resolution method has a special trampoline to call.
if (UNLIKELY(orig == Runtime::Current()->GetResolutionMethod())) {
- copy->SetEntryPointFromPortableCompiledCode(GetOatAddress(portable_resolution_trampoline_offset_));
- copy->SetEntryPointFromQuickCompiledCode(GetOatAddress(quick_resolution_trampoline_offset_));
+ copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_resolution_trampoline_offset_));
+ copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_));
} else if (UNLIKELY(orig == Runtime::Current()->GetImtConflictMethod())) {
- copy->SetEntryPointFromPortableCompiledCode(GetOatAddress(portable_imt_conflict_trampoline_offset_));
- copy->SetEntryPointFromQuickCompiledCode(GetOatAddress(quick_imt_conflict_trampoline_offset_));
+ copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_imt_conflict_trampoline_offset_));
+ copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_imt_conflict_trampoline_offset_));
} else {
// We assume all methods have code. If they don't currently then we set them to the use the
// resolution trampoline. Abstract methods never have code and so we need to make sure their
// use results in an AbstractMethodError. We use the interpreter to achieve this.
if (UNLIKELY(orig->IsAbstract())) {
- copy->SetEntryPointFromPortableCompiledCode(GetOatAddress(portable_to_interpreter_bridge_offset_));
- copy->SetEntryPointFromQuickCompiledCode(GetOatAddress(quick_to_interpreter_bridge_offset_));
- copy->SetEntryPointFromInterpreter(reinterpret_cast<EntryPointFromInterpreter*>
+ copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_to_interpreter_bridge_offset_));
+ copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_to_interpreter_bridge_offset_));
+ copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*>
(const_cast<byte*>(GetOatAddress(interpreter_to_interpreter_bridge_offset_))));
} else {
- copy->SetEntryPointFromInterpreter(reinterpret_cast<EntryPointFromInterpreter*>
+ copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*>
(const_cast<byte*>(GetOatAddress(interpreter_to_compiled_code_bridge_offset_))));
// Use original code if it exists. Otherwise, set the code pointer to the resolution
// trampoline.
const byte* quick_code = GetOatAddress(orig->GetQuickOatCodeOffset());
if (quick_code != nullptr) {
- copy->SetEntryPointFromQuickCompiledCode(quick_code);
+ copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(quick_code);
} else {
- copy->SetEntryPointFromQuickCompiledCode(GetOatAddress(quick_resolution_trampoline_offset_));
+ copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_));
}
const byte* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset());
if (portable_code != nullptr) {
- copy->SetEntryPointFromPortableCompiledCode(portable_code);
+ copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(portable_code);
} else {
- copy->SetEntryPointFromPortableCompiledCode(GetOatAddress(portable_resolution_trampoline_offset_));
+ copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_resolution_trampoline_offset_));
}
if (orig->IsNative()) {
// The native method's pointer is set to a stub to lookup via dlsym.
// Note this is not the code_ pointer, that is handled above.
- copy->SetNativeMethod(GetOatAddress(jni_dlsym_lookup_offset_));
+ copy->SetNativeMethod<kVerifyNone>(GetOatAddress(jni_dlsym_lookup_offset_));
} else {
// Normal (non-abstract non-native) methods have various tables to relocate.
uint32_t mapping_table_off = orig->GetOatMappingTableOffset();
const byte* mapping_table = GetOatAddress(mapping_table_off);
- copy->SetMappingTable(mapping_table);
+ copy->SetMappingTable<kVerifyNone>(mapping_table);
uint32_t vmap_table_offset = orig->GetOatVmapTableOffset();
const byte* vmap_table = GetOatAddress(vmap_table_offset);
- copy->SetVmapTable(vmap_table);
+ copy->SetVmapTable<kVerifyNone>(vmap_table);
uint32_t native_gc_map_offset = orig->GetOatNativeGcMapOffset();
const byte* native_gc_map = GetOatAddress(native_gc_map_offset);
- copy->SetNativeGcMap(reinterpret_cast<const uint8_t*>(native_gc_map));
+ copy->SetNativeGcMap<kVerifyNone>(reinterpret_cast<const uint8_t*>(native_gc_map));
}
}
}
@@ -663,7 +664,7 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) {
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>(i, GetImageAddress(element));
+ copy->SetWithoutChecksAndWriteBarrier<false, true, kVerifyNone>(i, GetImageAddress(element));
}
}
@@ -690,10 +691,11 @@ void ImageWriter::FixupFields(Object* orig,
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>(byte_offset, false);
+ 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>(byte_offset, GetImageAddress(ref), false);
+ copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ byte_offset, GetImageAddress(ref), false);
ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
}
} else {
@@ -712,10 +714,11 @@ void ImageWriter::FixupFields(Object* orig,
? klass->GetStaticField(i)
: klass->GetInstanceField(i));
MemberOffset field_offset = field->GetOffset();
- Object* ref = orig->GetFieldObject<Object>(field_offset, false);
+ 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>(field_offset, GetImageAddress(ref), false);
+ copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ field_offset, GetImageAddress(ref), false);
}
}
}
@@ -726,7 +729,8 @@ void ImageWriter::FixupFields(Object* orig,
Object* ref = orig->GetFieldObject<Object>(field_offset, false);
// Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
// image.
- copy->SetFieldObjectWithoutWriteBarrier<false>(field_offset, GetImageAddress(ref), false);
+ copy->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
+ field_offset, GetImageAddress(ref), false);
}
}