• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <string>
18 #include <vector>
19 
20 #include "common_test.h"
21 #include "compiler/elf_fixup.h"
22 #include "compiler/image_writer.h"
23 #include "compiler/oat_writer.h"
24 #include "gc/space/image_space.h"
25 #include "image.h"
26 #include "signal_catcher.h"
27 #include "UniquePtr.h"
28 #include "utils.h"
29 #include "vector_output_stream.h"
30 
31 namespace art {
32 
33 class ImageTest : public CommonTest {
34  protected:
SetUp()35   virtual void SetUp() {
36     ReserveImageSpace();
37     CommonTest::SetUp();
38   }
39 };
40 
TEST_F(ImageTest,WriteRead)41 TEST_F(ImageTest, WriteRead) {
42   ScratchFile tmp_elf;
43   {
44     {
45       jobject class_loader = NULL;
46       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
47       base::TimingLogger timings("ImageTest::WriteRead", false, false);
48       timings.StartSplit("CompileAll");
49 #if defined(ART_USE_PORTABLE_COMPILER)
50       // TODO: we disable this for portable so the test executes in a reasonable amount of time.
51       //       We shouldn't need to do this.
52       runtime_->SetCompilerFilter(Runtime::kInterpretOnly);
53 #endif
54       for (const DexFile* dex_file : class_linker->GetBootClassPath()) {
55         dex_file->EnableWrite();
56       }
57       compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), timings);
58 
59       ScopedObjectAccess soa(Thread::Current());
60       OatWriter oat_writer(class_linker->GetBootClassPath(),
61                            0, 0, "", compiler_driver_.get());
62       bool success = compiler_driver_->WriteElf(GetTestAndroidRoot(),
63                                                 !kIsTargetBuild,
64                                                 class_linker->GetBootClassPath(),
65                                                 oat_writer,
66                                                 tmp_elf.GetFile());
67       ASSERT_TRUE(success);
68     }
69   }
70   // Workound bug that mcld::Linker::emit closes tmp_elf by reopening as tmp_oat.
71   UniquePtr<File> tmp_oat(OS::OpenFileReadWrite(tmp_elf.GetFilename().c_str()));
72   ASSERT_TRUE(tmp_oat.get() != NULL);
73 
74   ScratchFile tmp_image;
75   const uintptr_t requested_image_base = ART_BASE_ADDRESS;
76   {
77     ImageWriter writer(*compiler_driver_.get());
78     bool success_image = writer.Write(tmp_image.GetFilename(), requested_image_base,
79                                       tmp_oat->GetPath(), tmp_oat->GetPath());
80     ASSERT_TRUE(success_image);
81     bool success_fixup = ElfFixup::Fixup(tmp_oat.get(), writer.GetOatDataBegin());
82     ASSERT_TRUE(success_fixup);
83   }
84 
85   {
86     UniquePtr<File> file(OS::OpenFileForReading(tmp_image.GetFilename().c_str()));
87     ASSERT_TRUE(file.get() != NULL);
88     ImageHeader image_header;
89     file->ReadFully(&image_header, sizeof(image_header));
90     ASSERT_TRUE(image_header.IsValid());
91     ASSERT_GE(image_header.GetImageBitmapOffset(), sizeof(image_header));
92     ASSERT_NE(0U, image_header.GetImageBitmapSize());
93 
94     gc::Heap* heap = Runtime::Current()->GetHeap();
95     ASSERT_EQ(1U, heap->GetContinuousSpaces().size());
96     gc::space::ContinuousSpace* space = heap->GetContinuousSpaces().front();
97     ASSERT_FALSE(space->IsImageSpace());
98     ASSERT_TRUE(space != NULL);
99     ASSERT_TRUE(space->IsDlMallocSpace());
100     ASSERT_GE(sizeof(image_header) + space->Size(), static_cast<size_t>(file->GetLength()));
101   }
102 
103   ASSERT_TRUE(compiler_driver_->GetImageClasses() != NULL);
104   CompilerDriver::DescriptorSet image_classes(*compiler_driver_->GetImageClasses());
105 
106   // Need to delete the compiler since it has worker threads which are attached to runtime.
107   compiler_driver_.reset();
108 
109   // Tear down old runtime before making a new one, clearing out misc state.
110   runtime_.reset();
111   java_lang_dex_file_ = NULL;
112 
113   UniquePtr<const DexFile> dex(DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName()));
114   ASSERT_TRUE(dex.get() != NULL);
115 
116   // Remove the reservation of the memory for use to load the image.
117   UnreserveImageSpace();
118 
119   Runtime::Options options;
120   std::string image("-Ximage:");
121   image.append(tmp_image.GetFilename());
122   options.push_back(std::make_pair(image.c_str(), reinterpret_cast<void*>(NULL)));
123 
124   if (!Runtime::Create(options, false)) {
125     LOG(FATAL) << "Failed to create runtime";
126     return;
127   }
128   runtime_.reset(Runtime::Current());
129   // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
130   // give it away now and then switch to a more managable ScopedObjectAccess.
131   Thread::Current()->TransitionFromRunnableToSuspended(kNative);
132   ScopedObjectAccess soa(Thread::Current());
133   ASSERT_TRUE(runtime_.get() != NULL);
134   class_linker_ = runtime_->GetClassLinker();
135 
136   gc::Heap* heap = Runtime::Current()->GetHeap();
137   ASSERT_EQ(2U, heap->GetContinuousSpaces().size());
138   ASSERT_TRUE(heap->GetContinuousSpaces()[0]->IsImageSpace());
139   ASSERT_FALSE(heap->GetContinuousSpaces()[0]->IsDlMallocSpace());
140   ASSERT_FALSE(heap->GetContinuousSpaces()[1]->IsImageSpace());
141   ASSERT_TRUE(heap->GetContinuousSpaces()[1]->IsDlMallocSpace());
142 
143   gc::space::ImageSpace* image_space = heap->GetImageSpace();
144   image_space->VerifyImageAllocations();
145   byte* image_begin = image_space->Begin();
146   byte* image_end = image_space->End();
147   CHECK_EQ(requested_image_base, reinterpret_cast<uintptr_t>(image_begin));
148   for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
149     const DexFile::ClassDef& class_def = dex->GetClassDef(i);
150     const char* descriptor = dex->GetClassDescriptor(class_def);
151     mirror::Class* klass = class_linker_->FindSystemClass(descriptor);
152     EXPECT_TRUE(klass != NULL) << descriptor;
153     EXPECT_LT(image_begin, reinterpret_cast<byte*>(klass)) << descriptor;
154     if (image_classes.find(descriptor) != image_classes.end()) {
155       // image classes should be located before the end of the image.
156       EXPECT_LT(reinterpret_cast<byte*>(klass), image_end) << descriptor;
157     } else {
158       // non image classes should be in a space after the image.
159       EXPECT_GT(reinterpret_cast<byte*>(klass), image_end) << descriptor;
160     }
161     EXPECT_TRUE(Monitor::IsValidLockWord(*klass->GetRawLockWordAddress()));
162   }
163 }
164 
TEST_F(ImageTest,ImageHeaderIsValid)165 TEST_F(ImageTest, ImageHeaderIsValid) {
166     uint32_t image_begin = ART_BASE_ADDRESS;
167     uint32_t image_size_ = 16 * KB;
168     uint32_t image_bitmap_offset = 0;
169     uint32_t image_bitmap_size = 0;
170     uint32_t image_roots = ART_BASE_ADDRESS + (1 * KB);
171     uint32_t oat_checksum = 0;
172     uint32_t oat_file_begin = ART_BASE_ADDRESS + (4 * KB);  // page aligned
173     uint32_t oat_data_begin = ART_BASE_ADDRESS + (8 * KB);  // page aligned
174     uint32_t oat_data_end = ART_BASE_ADDRESS + (9 * KB);
175     uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB);
176     ImageHeader image_header(image_begin,
177                              image_size_,
178                              image_bitmap_offset,
179                              image_bitmap_size,
180                              image_roots,
181                              oat_checksum,
182                              oat_file_begin,
183                              oat_data_begin,
184                              oat_data_end,
185                              oat_file_end);
186     ASSERT_TRUE(image_header.IsValid());
187 
188     char* magic = const_cast<char*>(image_header.GetMagic());
189     strcpy(magic, "");  // bad magic
190     ASSERT_FALSE(image_header.IsValid());
191     strcpy(magic, "art\n000");  // bad version
192     ASSERT_FALSE(image_header.IsValid());
193 }
194 
195 }  // namespace art
196