blob: b1453b35a61bef4e0edf92ece9e09b23ab0c709b [file] [log] [blame]
Brian Carlstrome24fa612011-09-29 00:53:55 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "oat_file.h"
4#include "oat_writer.h"
5
6#include "common_test.h"
7
8namespace art {
9
10class OatTest : public CommonTest {};
11
12TEST_F(OatTest, WriteRead) {
13 const bool compile = false; // DISABLED_ due to the time to compile libcore
14
15 const ClassLoader* class_loader = NULL;
16 if (compile) {
17 compiler_->CompileAll(class_loader);
18 }
19
20 ScratchFile tmp;
21 bool success = OatWriter::Create(tmp.GetFilename(), class_loader);
22 ASSERT_TRUE(success);
23
24 if (compile) { // OatWriter strips the code, regenerate to compare
25 compiler_->CompileAll(class_loader);
26 }
27 UniquePtr<OatFile> oat_file(OatFile::Open(std::string(tmp.GetFilename()), "", NULL));
28 ASSERT_TRUE(oat_file.get() != NULL);
29 const OatHeader& oat_header = oat_file->GetOatHeader();
30 ASSERT_EQ(1U, oat_header.GetDexFileCount());
31
32 const Runtime* runtime = Runtime::Current();
33 ClassLinker* class_linker = runtime->GetClassLinker();
34 ByteArray* jni_stub_array = runtime->GetJniStubArray();
35 ByteArray* ame_stub_array = runtime->GetAbstractMethodErrorStubArray();
36
37 const DexFile& dex_file = *java_lang_dex_file_.get();
38 const OatFile::OatDexFile& oat_dex_file = oat_file->GetOatDexFile(dex_file);
39 for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
40 const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
41 const byte* class_data = dex_file.GetClassData(class_def);
42 DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data);
43 size_t num_virtual_methods = header.virtual_methods_size_;
44 const char* descriptor = dex_file.GetClassDescriptor(class_def);
45
46 const OatFile::OatClass oat_class = oat_dex_file.GetOatClass(i);
47
48 Class* klass = class_linker->FindClass(descriptor, class_loader);
49
50 size_t method_index = 0;
51 for (size_t i = 0; i < klass->NumDirectMethods(); i++, method_index++) {
52 Method* method = klass->GetDirectMethod(i);
53 const void* oat_code = oat_class.GetMethodCode(method_index);
54 uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2);
55 oat_code = reinterpret_cast<const void*>(oat_code_aligned);
56 const ByteArray* code_array = method->GetCodeArray();
57 if (code_array == NULL || code_array == jni_stub_array || code_array == ame_stub_array) {
58 ASSERT_TRUE(oat_code == NULL);
59 } else {
60 ASSERT_EQ(0, memcmp(oat_code, code_array->GetData(), code_array->GetLength()));
61 }
62 }
63 for (size_t i = 0; i < num_virtual_methods; i++, method_index++) {
64 Method* method = klass->GetVirtualMethod(i);
65 const void* oat_code = oat_class.GetMethodCode(method_index);
66 uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2);
67 oat_code = reinterpret_cast<const void*>(oat_code_aligned);
68 const ByteArray* code_array = method->GetCodeArray();
69 if (code_array == NULL || code_array == jni_stub_array || code_array == ame_stub_array) {
70 ASSERT_TRUE(oat_code == NULL);
71 } else {
72 ASSERT_TRUE(oat_code != NULL);
73 ASSERT_EQ(0, memcmp(oat_code, code_array->GetData(), code_array->GetLength()));
74 }
75 }
76 }
77}
78
79} // namespace art