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
diff --git a/runtime/verify_object-inl.h b/runtime/verify_object-inl.h
new file mode 100644
index 0000000..e211c83
--- /dev/null
+++ b/runtime/verify_object-inl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_VERIFY_OBJECT_INL_H_
+#define ART_RUNTIME_VERIFY_OBJECT_INL_H_
+
+#include "verify_object.h"
+
+#include "gc/heap.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
+
+namespace art {
+
+inline void VerifyObject(mirror::Object* obj) {
+ if (kVerifyObjectSupport > kVerifyObjectModeDisabled && obj != nullptr) {
+ if (kVerifyObjectSupport > kVerifyObjectModeFast) {
+ // Slow object verification, try the heap right away.
+ Runtime::Current()->GetHeap()->VerifyObjectBody(obj);
+ } else {
+ // Fast object verification, only call the heap if our quick sanity tests fail. The heap will
+ // print the diagnostic message.
+ bool failed = !IsAligned<kObjectAlignment>(obj);
+ if (!failed) {
+ mirror::Class* c = obj->GetClass<kVerifyNone>();
+ failed = failed || c == nullptr;
+ failed = failed ||!IsAligned<kObjectAlignment>(c);
+ failed = failed ||!VerifyClassClass(c);
+ }
+ if (UNLIKELY(failed)) {
+ Runtime::Current()->GetHeap()->VerifyObjectBody(obj);
+ }
+ }
+ }
+}
+
+inline bool VerifyClassClass(mirror::Class* c) {
+ if (UNLIKELY(c == nullptr)) {
+ return false;
+ }
+ // Note: We pass in flags to ensure that the accessors don't call VerifyObject.
+ mirror::Class* c_c = c->GetClass<kVerifyNone>();
+ return c_c != nullptr && c_c == c_c->GetClass<kVerifyNone>();
+}
+
+} // namespace art
+
+#endif // ART_RUNTIME_VERIFY_OBJECT_INL_H_