| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 1 | // 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 |  | 
 | 8 | namespace art { | 
 | 9 |  | 
 | 10 | class OatTest : public CommonTest {}; | 
 | 11 |  | 
 | 12 | TEST_F(OatTest, WriteRead) { | 
 | 13 |   const bool compile = false;  // DISABLED_ due to the time to compile libcore | 
 | 14 |  | 
| Brian Carlstrom | 40381fb | 2011-10-19 14:13:40 -0700 | [diff] [blame] | 15 |   SirtRef<ClassLoader> class_loader(NULL); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 16 |   if (compile) { | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 17 |     compiler_.reset(new Compiler(kThumb2, false)); | 
| Brian Carlstrom | 40381fb | 2011-10-19 14:13:40 -0700 | [diff] [blame] | 18 |     compiler_->CompileAll(class_loader.get()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 19 |   } | 
 | 20 |  | 
 | 21 |   ScratchFile tmp; | 
| Brian Carlstrom | 40381fb | 2011-10-19 14:13:40 -0700 | [diff] [blame] | 22 |   bool success = OatWriter::Create(tmp.GetFilename(), class_loader.get(), *compiler_.get()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 23 |   ASSERT_TRUE(success); | 
 | 24 |  | 
 | 25 |   if (compile) {  // OatWriter strips the code, regenerate to compare | 
| Brian Carlstrom | 40381fb | 2011-10-19 14:13:40 -0700 | [diff] [blame] | 26 |     compiler_->CompileAll(class_loader.get()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 27 |   } | 
 | 28 |   UniquePtr<OatFile> oat_file(OatFile::Open(std::string(tmp.GetFilename()), "", NULL)); | 
 | 29 |   ASSERT_TRUE(oat_file.get() != NULL); | 
 | 30 |   const OatHeader& oat_header = oat_file->GetOatHeader(); | 
 | 31 |   ASSERT_EQ(1U, oat_header.GetDexFileCount()); | 
 | 32 |  | 
| Brian Carlstrom | 3320cf4 | 2011-10-04 14:58:28 -0700 | [diff] [blame] | 33 |   ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 34 |  | 
 | 35 |   const DexFile& dex_file = *java_lang_dex_file_.get(); | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 36 |   const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 37 |   for (size_t i = 0; i < dex_file.NumClassDefs(); i++) { | 
 | 38 |     const DexFile::ClassDef& class_def = dex_file.GetClassDef(i); | 
 | 39 |     const byte* class_data = dex_file.GetClassData(class_def); | 
 | 40 |     DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data); | 
 | 41 |     size_t num_virtual_methods = header.virtual_methods_size_; | 
 | 42 |     const char* descriptor = dex_file.GetClassDescriptor(class_def); | 
 | 43 |  | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 44 |     UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(i)); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 45 |  | 
| Brian Carlstrom | 40381fb | 2011-10-19 14:13:40 -0700 | [diff] [blame] | 46 |     Class* klass = class_linker->FindClass(descriptor, class_loader.get()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 47 |  | 
 | 48 |     size_t method_index = 0; | 
 | 49 |     for (size_t i = 0; i < klass->NumDirectMethods(); i++, method_index++) { | 
 | 50 |       Method* method = klass->GetDirectMethod(i); | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 51 |       const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index); | 
| Brian Carlstrom | 3320cf4 | 2011-10-04 14:58:28 -0700 | [diff] [blame] | 52 |       const CompiledMethod* compiled_method = compiler_->GetCompiledMethod(method); | 
 | 53 |  | 
 | 54 |       if (compiled_method == NULL) { | 
 | 55 |         EXPECT_TRUE(oat_method.code_ == NULL) << PrettyMethod(method) << " " << oat_method.code_; | 
 | 56 |         EXPECT_EQ(oat_method.frame_size_in_bytes_, static_cast<uint32_t>(kStackAlignment)); | 
 | 57 |         EXPECT_EQ(oat_method.return_pc_offset_in_bytes_, 0U); | 
 | 58 |         EXPECT_EQ(oat_method.core_spill_mask_, 0U); | 
 | 59 |         EXPECT_EQ(oat_method.fp_spill_mask_, 0U); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 60 |       } else { | 
| Brian Carlstrom | 3320cf4 | 2011-10-04 14:58:28 -0700 | [diff] [blame] | 61 |         const void* oat_code = oat_method.code_; | 
 | 62 |         uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2); | 
 | 63 |         oat_code = reinterpret_cast<const void*>(oat_code_aligned); | 
 | 64 |  | 
 | 65 |         const std::vector<uint8_t>& code = compiled_method->GetCode(); | 
 | 66 |         size_t code_size = code.size() * sizeof(code[0]); | 
 | 67 |         EXPECT_EQ(0, memcmp(oat_code, &code[0], code_size)) | 
 | 68 |             << PrettyMethod(method) << " " << code_size; | 
 | 69 |         CHECK_EQ(0, memcmp(oat_code, &code[0], code_size)); | 
 | 70 |         EXPECT_EQ(oat_method.frame_size_in_bytes_, compiled_method->GetFrameSizeInBytes()); | 
 | 71 |         EXPECT_EQ(oat_method.return_pc_offset_in_bytes_, compiled_method->GetReturnPcOffsetInBytes()); | 
 | 72 |         EXPECT_EQ(oat_method.core_spill_mask_, compiled_method->GetCoreSpillMask()); | 
 | 73 |         EXPECT_EQ(oat_method.fp_spill_mask_, compiled_method->GetFpSpillMask()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 74 |       } | 
 | 75 |     } | 
 | 76 |     for (size_t i = 0; i < num_virtual_methods; i++, method_index++) { | 
 | 77 |       Method* method = klass->GetVirtualMethod(i); | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 78 |       const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index); | 
| Brian Carlstrom | 3320cf4 | 2011-10-04 14:58:28 -0700 | [diff] [blame] | 79 |       const CompiledMethod* compiled_method = compiler_->GetCompiledMethod(method); | 
 | 80 |  | 
 | 81 |       if (compiled_method == NULL) { | 
 | 82 |         EXPECT_TRUE(oat_method.code_ == NULL) << PrettyMethod(method) << " " << oat_method.code_; | 
 | 83 |         EXPECT_EQ(oat_method.frame_size_in_bytes_, static_cast<uint32_t>(kStackAlignment)); | 
 | 84 |         EXPECT_EQ(oat_method.return_pc_offset_in_bytes_, 0U); | 
 | 85 |         EXPECT_EQ(oat_method.core_spill_mask_, 0U); | 
 | 86 |         EXPECT_EQ(oat_method.fp_spill_mask_, 0U); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 87 |       } else { | 
| Brian Carlstrom | 3320cf4 | 2011-10-04 14:58:28 -0700 | [diff] [blame] | 88 |         const void* oat_code = oat_method.code_; | 
 | 89 |         EXPECT_TRUE(oat_code != NULL) << PrettyMethod(method); | 
 | 90 |         uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2); | 
 | 91 |         oat_code = reinterpret_cast<const void*>(oat_code_aligned); | 
 | 92 |  | 
 | 93 |         const std::vector<uint8_t>& code = compiled_method->GetCode(); | 
 | 94 |         size_t code_size = code.size() * sizeof(code[0]); | 
 | 95 |         EXPECT_EQ(0, memcmp(oat_code, &code[0], code_size)) | 
 | 96 |             << PrettyMethod(method) << " " << code_size; | 
 | 97 |         CHECK_EQ(0, memcmp(oat_code, &code[0], code_size)); | 
 | 98 |         EXPECT_EQ(oat_method.frame_size_in_bytes_, compiled_method->GetFrameSizeInBytes()); | 
 | 99 |         EXPECT_EQ(oat_method.return_pc_offset_in_bytes_, compiled_method->GetReturnPcOffsetInBytes()); | 
 | 100 |         EXPECT_EQ(oat_method.core_spill_mask_, compiled_method->GetCoreSpillMask()); | 
 | 101 |         EXPECT_EQ(oat_method.fp_spill_mask_, compiled_method->GetFpSpillMask()); | 
| Brian Carlstrom | e24fa61 | 2011-09-29 00:53:55 -0700 | [diff] [blame] | 102 |       } | 
 | 103 |     } | 
 | 104 |   } | 
 | 105 | } | 
 | 106 |  | 
 | 107 | }  // namespace art |