image_writer.cc revision 507dfdd147c97bfbadebfd63584d094b6a4e7b47
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 "image_writer.h" 18 19#include <sys/stat.h> 20 21#include <vector> 22 23#include "base/logging.h" 24#include "base/unix_file/fd_file.h" 25#include "class_linker.h" 26#include "compiled_method.h" 27#include "dex_file-inl.h" 28#include "driver/compiler_driver.h" 29#include "elf_writer.h" 30#include "gc/accounting/card_table-inl.h" 31#include "gc/accounting/heap_bitmap.h" 32#include "gc/accounting/space_bitmap-inl.h" 33#include "gc/heap.h" 34#include "gc/space/large_object_space.h" 35#include "gc/space/space-inl.h" 36#include "globals.h" 37#include "image.h" 38#include "intern_table.h" 39#include "lock_word.h" 40#include "mirror/art_field-inl.h" 41#include "mirror/art_method-inl.h" 42#include "mirror/array-inl.h" 43#include "mirror/class-inl.h" 44#include "mirror/class_loader.h" 45#include "mirror/dex_cache-inl.h" 46#include "mirror/object-inl.h" 47#include "mirror/object_array-inl.h" 48#include "mirror/string-inl.h" 49#include "oat.h" 50#include "oat_file.h" 51#include "object_utils.h" 52#include "runtime.h" 53#include "scoped_thread_state_change.h" 54#include "handle_scope-inl.h" 55#include "UniquePtrCompat.h" 56#include "utils.h" 57 58using ::art::mirror::ArtField; 59using ::art::mirror::ArtMethod; 60using ::art::mirror::Class; 61using ::art::mirror::DexCache; 62using ::art::mirror::EntryPointFromInterpreter; 63using ::art::mirror::Object; 64using ::art::mirror::ObjectArray; 65using ::art::mirror::String; 66 67namespace art { 68 69bool ImageWriter::Write(const std::string& image_filename, 70 uintptr_t image_begin, 71 const std::string& oat_filename, 72 const std::string& oat_location) { 73 CHECK(!image_filename.empty()); 74 75 CHECK_NE(image_begin, 0U); 76 image_begin_ = reinterpret_cast<byte*>(image_begin); 77 78 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 79 80 UniquePtr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str())); 81 if (oat_file.get() == NULL) { 82 LOG(ERROR) << "Failed to open oat file " << oat_filename << " for " << oat_location; 83 return false; 84 } 85 std::string error_msg; 86 oat_file_ = OatFile::OpenWritable(oat_file.get(), oat_location, &error_msg); 87 if (oat_file_ == nullptr) { 88 LOG(ERROR) << "Failed to open writable oat file " << oat_filename << " for " << oat_location 89 << ": " << error_msg; 90 return false; 91 } 92 CHECK_EQ(class_linker->RegisterOatFile(oat_file_), oat_file_); 93 94 interpreter_to_interpreter_bridge_offset_ = 95 oat_file_->GetOatHeader().GetInterpreterToInterpreterBridgeOffset(); 96 interpreter_to_compiled_code_bridge_offset_ = 97 oat_file_->GetOatHeader().GetInterpreterToCompiledCodeBridgeOffset(); 98 99 jni_dlsym_lookup_offset_ = oat_file_->GetOatHeader().GetJniDlsymLookupOffset(); 100 101 portable_imt_conflict_trampoline_offset_ = 102 oat_file_->GetOatHeader().GetPortableImtConflictTrampolineOffset(); 103 portable_resolution_trampoline_offset_ = 104 oat_file_->GetOatHeader().GetPortableResolutionTrampolineOffset(); 105 portable_to_interpreter_bridge_offset_ = 106 oat_file_->GetOatHeader().GetPortableToInterpreterBridgeOffset(); 107 108 quick_generic_jni_trampoline_offset_ = 109 oat_file_->GetOatHeader().GetQuickGenericJniTrampolineOffset(); 110 quick_imt_conflict_trampoline_offset_ = 111 oat_file_->GetOatHeader().GetQuickImtConflictTrampolineOffset(); 112 quick_resolution_trampoline_offset_ = 113 oat_file_->GetOatHeader().GetQuickResolutionTrampolineOffset(); 114 quick_to_interpreter_bridge_offset_ = 115 oat_file_->GetOatHeader().GetQuickToInterpreterBridgeOffset(); 116 { 117 Thread::Current()->TransitionFromSuspendedToRunnable(); 118 PruneNonImageClasses(); // Remove junk 119 ComputeLazyFieldsForImageClasses(); // Add useful information 120 ComputeEagerResolvedStrings(); 121 Thread::Current()->TransitionFromRunnableToSuspended(kNative); 122 } 123 gc::Heap* heap = Runtime::Current()->GetHeap(); 124 heap->CollectGarbage(false); // Remove garbage. 125 126 if (!AllocMemory()) { 127 return false; 128 } 129 130 if (kIsDebugBuild) { 131 ScopedObjectAccess soa(Thread::Current()); 132 CheckNonImageClassesRemoved(); 133 } 134 135 Thread::Current()->TransitionFromSuspendedToRunnable(); 136 size_t oat_loaded_size = 0; 137 size_t oat_data_offset = 0; 138 ElfWriter::GetOatElfInformation(oat_file.get(), oat_loaded_size, oat_data_offset); 139 CalculateNewObjectOffsets(oat_loaded_size, oat_data_offset); 140 CopyAndFixupObjects(); 141 PatchOatCodeAndMethods(); 142 Thread::Current()->TransitionFromRunnableToSuspended(kNative); 143 144 UniquePtr<File> image_file(OS::CreateEmptyFile(image_filename.c_str())); 145 ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin()); 146 if (image_file.get() == NULL) { 147 LOG(ERROR) << "Failed to open image file " << image_filename; 148 return false; 149 } 150 if (fchmod(image_file->Fd(), 0644) != 0) { 151 PLOG(ERROR) << "Failed to make image file world readable: " << image_filename; 152 return EXIT_FAILURE; 153 } 154 155 // Write out the image. 156 CHECK_EQ(image_end_, image_header->GetImageSize()); 157 if (!image_file->WriteFully(image_->Begin(), image_end_)) { 158 PLOG(ERROR) << "Failed to write image file " << image_filename; 159 return false; 160 } 161 162 // Write out the image bitmap at the page aligned start of the image end. 163 CHECK_ALIGNED(image_header->GetImageBitmapOffset(), kPageSize); 164 if (!image_file->Write(reinterpret_cast<char*>(image_bitmap_->Begin()), 165 image_header->GetImageBitmapSize(), 166 image_header->GetImageBitmapOffset())) { 167 PLOG(ERROR) << "Failed to write image file " << image_filename; 168 return false; 169 } 170 171 return true; 172} 173 174void ImageWriter::SetImageOffset(mirror::Object* object, size_t offset) { 175 DCHECK(object != nullptr); 176 DCHECK_NE(offset, 0U); 177 DCHECK(!IsImageOffsetAssigned(object)); 178 mirror::Object* obj = reinterpret_cast<mirror::Object*>(image_->Begin() + offset); 179 DCHECK_ALIGNED(obj, kObjectAlignment); 180 image_bitmap_->Set(obj); 181 // Before we stomp over the lock word, save the hash code for later. 182 Monitor::Deflate(Thread::Current(), object);; 183 LockWord lw(object->GetLockWord(false)); 184 switch (lw.GetState()) { 185 case LockWord::kFatLocked: { 186 LOG(FATAL) << "Fat locked object " << obj << " found during object copy"; 187 break; 188 } 189 case LockWord::kThinLocked: { 190 LOG(FATAL) << "Thin locked object " << obj << " found during object copy"; 191 break; 192 } 193 case LockWord::kUnlocked: 194 // No hash, don't need to save it. 195 break; 196 case LockWord::kHashCode: 197 saved_hashes_.push_back(std::make_pair(obj, lw.GetHashCode())); 198 break; 199 default: 200 LOG(FATAL) << "Unreachable."; 201 break; 202 } 203 object->SetLockWord(LockWord::FromForwardingAddress(offset), false); 204 DCHECK(IsImageOffsetAssigned(object)); 205} 206 207void ImageWriter::AssignImageOffset(mirror::Object* object) { 208 DCHECK(object != nullptr); 209 SetImageOffset(object, image_end_); 210 image_end_ += RoundUp(object->SizeOf(), 8); // 64-bit alignment 211 DCHECK_LT(image_end_, image_->Size()); 212} 213 214bool ImageWriter::IsImageOffsetAssigned(mirror::Object* object) const { 215 DCHECK(object != nullptr); 216 return object->GetLockWord(false).GetState() == LockWord::kForwardingAddress; 217} 218 219size_t ImageWriter::GetImageOffset(mirror::Object* object) const { 220 DCHECK(object != nullptr); 221 DCHECK(IsImageOffsetAssigned(object)); 222 LockWord lock_word = object->GetLockWord(false); 223 size_t offset = lock_word.ForwardingAddress(); 224 DCHECK_LT(offset, image_end_); 225 return offset; 226} 227 228bool ImageWriter::AllocMemory() { 229 size_t length = RoundUp(Runtime::Current()->GetHeap()->GetTotalMemory(), kPageSize); 230 std::string error_msg; 231 image_.reset(MemMap::MapAnonymous("image writer image", NULL, length, PROT_READ | PROT_WRITE, 232 true, &error_msg)); 233 if (UNLIKELY(image_.get() == nullptr)) { 234 LOG(ERROR) << "Failed to allocate memory for image file generation: " << error_msg; 235 return false; 236 } 237 238 // Create the image bitmap. 239 image_bitmap_.reset(gc::accounting::ContinuousSpaceBitmap::Create("image bitmap", image_->Begin(), 240 length)); 241 if (image_bitmap_.get() == nullptr) { 242 LOG(ERROR) << "Failed to allocate memory for image bitmap"; 243 return false; 244 } 245 return true; 246} 247 248void ImageWriter::ComputeLazyFieldsForImageClasses() { 249 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 250 class_linker->VisitClassesWithoutClassesLock(ComputeLazyFieldsForClassesVisitor, NULL); 251} 252 253bool ImageWriter::ComputeLazyFieldsForClassesVisitor(Class* c, void* /*arg*/) { 254 c->ComputeName(); 255 return true; 256} 257 258void ImageWriter::ComputeEagerResolvedStringsCallback(Object* obj, void* arg) { 259 if (!obj->GetClass()->IsStringClass()) { 260 return; 261 } 262 mirror::String* string = obj->AsString(); 263 const uint16_t* utf16_string = string->GetCharArray()->GetData() + string->GetOffset(); 264 for (DexCache* dex_cache : Runtime::Current()->GetClassLinker()->GetDexCaches()) { 265 const DexFile& dex_file = *dex_cache->GetDexFile(); 266 const DexFile::StringId* string_id; 267 if (UNLIKELY(string->GetLength() == 0)) { 268 string_id = dex_file.FindStringId(""); 269 } else { 270 string_id = dex_file.FindStringId(utf16_string); 271 } 272 if (string_id != nullptr) { 273 // This string occurs in this dex file, assign the dex cache entry. 274 uint32_t string_idx = dex_file.GetIndexForStringId(*string_id); 275 if (dex_cache->GetResolvedString(string_idx) == NULL) { 276 dex_cache->SetResolvedString(string_idx, string); 277 } 278 } 279 } 280} 281 282void ImageWriter::ComputeEagerResolvedStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 283 ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 284 Runtime::Current()->GetHeap()->VisitObjects(ComputeEagerResolvedStringsCallback, this); 285} 286 287bool ImageWriter::IsImageClass(Class* klass) { 288 return compiler_driver_.IsImageClass(ClassHelper(klass).GetDescriptor()); 289} 290 291struct NonImageClasses { 292 ImageWriter* image_writer; 293 std::set<std::string>* non_image_classes; 294}; 295 296void ImageWriter::PruneNonImageClasses() { 297 if (compiler_driver_.GetImageClasses() == NULL) { 298 return; 299 } 300 Runtime* runtime = Runtime::Current(); 301 ClassLinker* class_linker = runtime->GetClassLinker(); 302 303 // Make a list of classes we would like to prune. 304 std::set<std::string> non_image_classes; 305 NonImageClasses context; 306 context.image_writer = this; 307 context.non_image_classes = &non_image_classes; 308 class_linker->VisitClasses(NonImageClassesVisitor, &context); 309 310 // Remove the undesired classes from the class roots. 311 for (const std::string& it : non_image_classes) { 312 class_linker->RemoveClass(it.c_str(), NULL); 313 } 314 315 // Clear references to removed classes from the DexCaches. 316 ArtMethod* resolution_method = runtime->GetResolutionMethod(); 317 for (DexCache* dex_cache : class_linker->GetDexCaches()) { 318 for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { 319 Class* klass = dex_cache->GetResolvedType(i); 320 if (klass != NULL && !IsImageClass(klass)) { 321 dex_cache->SetResolvedType(i, NULL); 322 } 323 } 324 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { 325 ArtMethod* method = dex_cache->GetResolvedMethod(i); 326 if (method != NULL && !IsImageClass(method->GetDeclaringClass())) { 327 dex_cache->SetResolvedMethod(i, resolution_method); 328 } 329 } 330 for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) { 331 ArtField* field = dex_cache->GetResolvedField(i); 332 if (field != NULL && !IsImageClass(field->GetDeclaringClass())) { 333 dex_cache->SetResolvedField(i, NULL); 334 } 335 } 336 } 337} 338 339bool ImageWriter::NonImageClassesVisitor(Class* klass, void* arg) { 340 NonImageClasses* context = reinterpret_cast<NonImageClasses*>(arg); 341 if (!context->image_writer->IsImageClass(klass)) { 342 context->non_image_classes->insert(ClassHelper(klass).GetDescriptor()); 343 } 344 return true; 345} 346 347void ImageWriter::CheckNonImageClassesRemoved() 348 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 349 if (compiler_driver_.GetImageClasses() != nullptr) { 350 gc::Heap* heap = Runtime::Current()->GetHeap(); 351 ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 352 heap->VisitObjects(CheckNonImageClassesRemovedCallback, this); 353 } 354} 355 356void ImageWriter::CheckNonImageClassesRemovedCallback(Object* obj, void* arg) { 357 ImageWriter* image_writer = reinterpret_cast<ImageWriter*>(arg); 358 if (obj->IsClass()) { 359 Class* klass = obj->AsClass(); 360 if (!image_writer->IsImageClass(klass)) { 361 image_writer->DumpImageClasses(); 362 CHECK(image_writer->IsImageClass(klass)) << ClassHelper(klass).GetDescriptor() 363 << " " << PrettyDescriptor(klass); 364 } 365 } 366} 367 368void ImageWriter::DumpImageClasses() { 369 CompilerDriver::DescriptorSet* image_classes = compiler_driver_.GetImageClasses(); 370 CHECK(image_classes != NULL); 371 for (const std::string& image_class : *image_classes) { 372 LOG(INFO) << " " << image_class; 373 } 374} 375 376void ImageWriter::CalculateObjectOffsets(Object* obj) { 377 DCHECK(obj != NULL); 378 // if it is a string, we want to intern it if its not interned. 379 if (obj->GetClass()->IsStringClass()) { 380 // we must be an interned string that was forward referenced and already assigned 381 if (IsImageOffsetAssigned(obj)) { 382 DCHECK_EQ(obj, obj->AsString()->Intern()); 383 return; 384 } 385 mirror::String* const interned = obj->AsString()->Intern(); 386 if (obj != interned) { 387 if (!IsImageOffsetAssigned(interned)) { 388 // interned obj is after us, allocate its location early 389 AssignImageOffset(interned); 390 } 391 // point those looking for this object to the interned version. 392 SetImageOffset(obj, GetImageOffset(interned)); 393 return; 394 } 395 // else (obj == interned), nothing to do but fall through to the normal case 396 } 397 398 AssignImageOffset(obj); 399} 400 401ObjectArray<Object>* ImageWriter::CreateImageRoots() const { 402 Runtime* runtime = Runtime::Current(); 403 ClassLinker* class_linker = runtime->GetClassLinker(); 404 Thread* self = Thread::Current(); 405 StackHandleScope<3> hs(self); 406 Handle<Class> object_array_class(hs.NewHandle( 407 class_linker->FindSystemClass(self, "[Ljava/lang/Object;"))); 408 409 // build an Object[] of all the DexCaches used in the source_space_ 410 Handle<ObjectArray<Object>> dex_caches( 411 hs.NewHandle(ObjectArray<Object>::Alloc(self, object_array_class.Get(), 412 class_linker->GetDexCaches().size()))); 413 int i = 0; 414 for (DexCache* dex_cache : class_linker->GetDexCaches()) { 415 dex_caches->Set<false>(i++, dex_cache); 416 } 417 418 // build an Object[] of the roots needed to restore the runtime 419 Handle<ObjectArray<Object> > image_roots(hs.NewHandle( 420 ObjectArray<Object>::Alloc(self, object_array_class.Get(), ImageHeader::kImageRootsMax))); 421 image_roots->Set<false>(ImageHeader::kResolutionMethod, runtime->GetResolutionMethod()); 422 image_roots->Set<false>(ImageHeader::kImtConflictMethod, runtime->GetImtConflictMethod()); 423 image_roots->Set<false>(ImageHeader::kDefaultImt, runtime->GetDefaultImt()); 424 image_roots->Set<false>(ImageHeader::kCalleeSaveMethod, 425 runtime->GetCalleeSaveMethod(Runtime::kSaveAll)); 426 image_roots->Set<false>(ImageHeader::kRefsOnlySaveMethod, 427 runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)); 428 image_roots->Set<false>(ImageHeader::kRefsAndArgsSaveMethod, 429 runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)); 430 image_roots->Set<false>(ImageHeader::kDexCaches, dex_caches.Get()); 431 image_roots->Set<false>(ImageHeader::kClassRoots, class_linker->GetClassRoots()); 432 for (int i = 0; i < ImageHeader::kImageRootsMax; i++) { 433 CHECK(image_roots->Get(i) != NULL); 434 } 435 return image_roots.Get(); 436} 437 438// Walk instance fields of the given Class. Separate function to allow recursion on the super 439// class. 440void ImageWriter::WalkInstanceFields(mirror::Object* obj, mirror::Class* klass) { 441 // Visit fields of parent classes first. 442 StackHandleScope<1> hs(Thread::Current()); 443 Handle<mirror::Class> h_class(hs.NewHandle(klass)); 444 mirror::Class* super = h_class->GetSuperClass(); 445 if (super != nullptr) { 446 WalkInstanceFields(obj, super); 447 } 448 // 449 size_t num_reference_fields = h_class->NumReferenceInstanceFields(); 450 for (size_t i = 0; i < num_reference_fields; ++i) { 451 mirror::ArtField* field = h_class->GetInstanceField(i); 452 MemberOffset field_offset = field->GetOffset(); 453 mirror::Object* value = obj->GetFieldObject<mirror::Object>(field_offset); 454 if (value != nullptr) { 455 WalkFieldsInOrder(value); 456 } 457 } 458} 459 460// For an unvisited object, visit it then all its children found via fields. 461void ImageWriter::WalkFieldsInOrder(mirror::Object* obj) { 462 if (!IsImageOffsetAssigned(obj)) { 463 // Walk instance fields of all objects 464 StackHandleScope<2> hs(Thread::Current()); 465 Handle<mirror::Object> h_obj(hs.NewHandle(obj)); 466 Handle<mirror::Class> klass(hs.NewHandle(obj->GetClass())); 467 // visit the object itself. 468 CalculateObjectOffsets(h_obj.Get()); 469 WalkInstanceFields(h_obj.Get(), klass.Get()); 470 // Walk static fields of a Class. 471 if (h_obj->IsClass()) { 472 size_t num_static_fields = klass->NumReferenceStaticFields(); 473 for (size_t i = 0; i < num_static_fields; ++i) { 474 mirror::ArtField* field = klass->GetStaticField(i); 475 MemberOffset field_offset = field->GetOffset(); 476 mirror::Object* value = h_obj->GetFieldObject<mirror::Object>(field_offset); 477 if (value != nullptr) { 478 WalkFieldsInOrder(value); 479 } 480 } 481 } else if (h_obj->IsObjectArray()) { 482 // Walk elements of an object array. 483 int32_t length = h_obj->AsObjectArray<mirror::Object>()->GetLength(); 484 for (int32_t i = 0; i < length; i++) { 485 mirror::ObjectArray<mirror::Object>* obj_array = h_obj->AsObjectArray<mirror::Object>(); 486 mirror::Object* value = obj_array->Get(i); 487 if (value != nullptr) { 488 WalkFieldsInOrder(value); 489 } 490 } 491 } 492 } 493} 494 495void ImageWriter::WalkFieldsCallback(mirror::Object* obj, void* arg) { 496 ImageWriter* writer = reinterpret_cast<ImageWriter*>(arg); 497 DCHECK(writer != nullptr); 498 writer->WalkFieldsInOrder(obj); 499} 500 501void ImageWriter::CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_data_offset) { 502 CHECK_NE(0U, oat_loaded_size); 503 Thread* self = Thread::Current(); 504 StackHandleScope<1> hs(self); 505 Handle<ObjectArray<Object>> image_roots(hs.NewHandle(CreateImageRoots())); 506 507 gc::Heap* heap = Runtime::Current()->GetHeap(); 508 DCHECK_EQ(0U, image_end_); 509 510 // Leave space for the header, but do not write it yet, we need to 511 // know where image_roots is going to end up 512 image_end_ += RoundUp(sizeof(ImageHeader), 8); // 64-bit-alignment 513 514 { 515 WriterMutexLock mu(self, *Locks::heap_bitmap_lock_); 516 // TODO: Image spaces only? 517 const char* old = self->StartAssertNoThreadSuspension("ImageWriter"); 518 DCHECK_LT(image_end_, image_->Size()); 519 // Clear any pre-existing monitors which may have been in the monitor words. 520 heap->VisitObjects(WalkFieldsCallback, this); 521 self->EndAssertNoThreadSuspension(old); 522 } 523 524 const byte* oat_file_begin = image_begin_ + RoundUp(image_end_, kPageSize); 525 const byte* oat_file_end = oat_file_begin + oat_loaded_size; 526 oat_data_begin_ = oat_file_begin + oat_data_offset; 527 const byte* oat_data_end = oat_data_begin_ + oat_file_->Size(); 528 529 // Return to write header at start of image with future location of image_roots. At this point, 530 // image_end_ is the size of the image (excluding bitmaps). 531 const size_t heap_bytes_per_bitmap_byte = kBitsPerByte * kObjectAlignment; 532 const size_t bitmap_bytes = RoundUp(image_end_, heap_bytes_per_bitmap_byte) / 533 heap_bytes_per_bitmap_byte; 534 ImageHeader image_header(PointerToLowMemUInt32(image_begin_), 535 static_cast<uint32_t>(image_end_), 536 RoundUp(image_end_, kPageSize), 537 RoundUp(bitmap_bytes, kPageSize), 538 PointerToLowMemUInt32(GetImageAddress(image_roots.Get())), 539 oat_file_->GetOatHeader().GetChecksum(), 540 PointerToLowMemUInt32(oat_file_begin), 541 PointerToLowMemUInt32(oat_data_begin_), 542 PointerToLowMemUInt32(oat_data_end), 543 PointerToLowMemUInt32(oat_file_end)); 544 memcpy(image_->Begin(), &image_header, sizeof(image_header)); 545 546 // Note that image_end_ is left at end of used space 547} 548 549void ImageWriter::CopyAndFixupObjects() 550 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 551 Thread* self = Thread::Current(); 552 const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter"); 553 gc::Heap* heap = Runtime::Current()->GetHeap(); 554 // TODO: heap validation can't handle this fix up pass 555 heap->DisableObjectValidation(); 556 // TODO: Image spaces only? 557 WriterMutexLock mu(self, *Locks::heap_bitmap_lock_); 558 heap->VisitObjects(CopyAndFixupObjectsCallback, this); 559 // Fix up the object previously had hash codes. 560 for (const std::pair<mirror::Object*, uint32_t>& hash_pair : saved_hashes_) { 561 hash_pair.first->SetLockWord(LockWord::FromHashCode(hash_pair.second), false); 562 } 563 saved_hashes_.clear(); 564 self->EndAssertNoThreadSuspension(old_cause); 565} 566 567void ImageWriter::CopyAndFixupObjectsCallback(Object* obj, void* arg) { 568 DCHECK(obj != nullptr); 569 DCHECK(arg != nullptr); 570 ImageWriter* image_writer = reinterpret_cast<ImageWriter*>(arg); 571 // see GetLocalAddress for similar computation 572 size_t offset = image_writer->GetImageOffset(obj); 573 byte* dst = image_writer->image_->Begin() + offset; 574 const byte* src = reinterpret_cast<const byte*>(obj); 575 size_t n = obj->SizeOf(); 576 DCHECK_LT(offset + n, image_writer->image_->Size()); 577 memcpy(dst, src, n); 578 Object* copy = reinterpret_cast<Object*>(dst); 579 // Write in a hash code of objects which have inflated monitors or a hash code in their monitor 580 // word. 581 copy->SetLockWord(LockWord(), false); 582 image_writer->FixupObject(obj, copy); 583} 584 585class FixupVisitor { 586 public: 587 FixupVisitor(ImageWriter* image_writer, Object* copy) : image_writer_(image_writer), copy_(copy) { 588 } 589 590 void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const 591 EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) { 592 Object* ref = obj->GetFieldObject<Object, kVerifyNone>(offset); 593 // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the 594 // image. 595 copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>( 596 offset, image_writer_->GetImageAddress(ref)); 597 } 598 599 // java.lang.ref.Reference visitor. 600 void operator()(mirror::Class* /*klass*/, mirror::Reference* ref) const 601 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 602 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 603 copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>( 604 mirror::Reference::ReferentOffset(), image_writer_->GetImageAddress(ref->GetReferent())); 605 } 606 607 private: 608 ImageWriter* const image_writer_; 609 mirror::Object* const copy_; 610}; 611 612void ImageWriter::FixupObject(Object* orig, Object* copy) { 613 DCHECK(orig != nullptr); 614 DCHECK(copy != nullptr); 615 if (kUseBakerOrBrooksReadBarrier) { 616 orig->AssertReadBarrierPointer(); 617 if (kUseBrooksReadBarrier) { 618 // Note the address 'copy' isn't the same as the image address of 'orig'. 619 copy->SetReadBarrierPointer(GetImageAddress(orig)); 620 DCHECK_EQ(copy->GetReadBarrierPointer(), GetImageAddress(orig)); 621 } 622 } 623 FixupVisitor visitor(this, copy); 624 orig->VisitReferences<true /*visit class*/>(visitor, visitor); 625 if (orig->IsArtMethod<kVerifyNone>()) { 626 FixupMethod(orig->AsArtMethod<kVerifyNone>(), down_cast<ArtMethod*>(copy)); 627 } 628} 629 630void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) { 631 // OatWriter replaces the code_ with an offset value. Here we re-adjust to a pointer relative to 632 // oat_begin_ 633 634 // The resolution method has a special trampoline to call. 635 if (UNLIKELY(orig == Runtime::Current()->GetResolutionMethod())) { 636 copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_resolution_trampoline_offset_)); 637 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_)); 638 } else if (UNLIKELY(orig == Runtime::Current()->GetImtConflictMethod())) { 639 copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_imt_conflict_trampoline_offset_)); 640 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_imt_conflict_trampoline_offset_)); 641 } else { 642 // We assume all methods have code. If they don't currently then we set them to the use the 643 // resolution trampoline. Abstract methods never have code and so we need to make sure their 644 // use results in an AbstractMethodError. We use the interpreter to achieve this. 645 if (UNLIKELY(orig->IsAbstract())) { 646 copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_to_interpreter_bridge_offset_)); 647 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_to_interpreter_bridge_offset_)); 648 copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*> 649 (const_cast<byte*>(GetOatAddress(interpreter_to_interpreter_bridge_offset_)))); 650 } else { 651 copy->SetEntryPointFromInterpreter<kVerifyNone>(reinterpret_cast<EntryPointFromInterpreter*> 652 (const_cast<byte*>(GetOatAddress(interpreter_to_compiled_code_bridge_offset_)))); 653 // Use original code if it exists. Otherwise, set the code pointer to the resolution 654 // trampoline. 655 const byte* quick_code = GetOatAddress(orig->GetQuickOatCodeOffset()); 656 if (quick_code != nullptr && 657 (!orig->IsStatic() || orig->IsConstructor() || orig->GetDeclaringClass()->IsInitialized())) { 658 // We have code for a non-static or initialized method, just use the code. 659 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(quick_code); 660 } else if (quick_code == nullptr && orig->IsNative() && 661 (!orig->IsStatic() || orig->GetDeclaringClass()->IsInitialized())) { 662 // Non-static or initialized native method missing compiled code, use generic JNI version. 663 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_generic_jni_trampoline_offset_)); 664 } else if (quick_code == nullptr && !orig->IsNative()) { 665 // We don't have code at all for a non-native method, use the interpreter. 666 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_to_interpreter_bridge_offset_)); 667 } else { 668 CHECK(!orig->GetDeclaringClass()->IsInitialized()); 669 // We have code for a static method, but need to go through the resolution stub for class 670 // initialization. 671 copy->SetEntryPointFromQuickCompiledCode<kVerifyNone>(GetOatAddress(quick_resolution_trampoline_offset_)); 672 } 673 const byte* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset()); 674 if (portable_code != nullptr) { 675 copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(portable_code); 676 } else { 677 copy->SetEntryPointFromPortableCompiledCode<kVerifyNone>(GetOatAddress(portable_resolution_trampoline_offset_)); 678 } 679 if (orig->IsNative()) { 680 // The native method's pointer is set to a stub to lookup via dlsym. 681 // Note this is not the code_ pointer, that is handled above. 682 copy->SetNativeMethod<kVerifyNone>(GetOatAddress(jni_dlsym_lookup_offset_)); 683 } else { 684 // Normal (non-abstract non-native) methods have various tables to relocate. 685 uint32_t native_gc_map_offset = orig->GetOatNativeGcMapOffset(); 686 const byte* native_gc_map = GetOatAddress(native_gc_map_offset); 687 copy->SetNativeGcMap<kVerifyNone>(reinterpret_cast<const uint8_t*>(native_gc_map)); 688 } 689 } 690 } 691} 692 693static ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch) 694 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 695 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 696 StackHandleScope<2> hs(Thread::Current()); 697 Handle<mirror::DexCache> dex_cache( 698 hs.NewHandle(class_linker->FindDexCache(*patch->GetTargetDexFile()))); 699 auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); 700 ArtMethod* method = class_linker->ResolveMethod(*patch->GetTargetDexFile(), 701 patch->GetTargetMethodIdx(), 702 dex_cache, 703 class_loader, 704 NULL, 705 patch->GetTargetInvokeType()); 706 CHECK(method != NULL) 707 << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx(); 708 CHECK(!method->IsRuntimeMethod()) 709 << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx(); 710 CHECK(dex_cache->GetResolvedMethods()->Get(patch->GetTargetMethodIdx()) == method) 711 << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetReferrerMethodIdx() << " " 712 << PrettyMethod(dex_cache->GetResolvedMethods()->Get(patch->GetTargetMethodIdx())) << " " 713 << PrettyMethod(method); 714 return method; 715} 716 717static Class* GetTargetType(const CompilerDriver::TypePatchInformation* patch) 718 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 719 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 720 StackHandleScope<2> hs(Thread::Current()); 721 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(patch->GetDexFile()))); 722 auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); 723 Class* klass = class_linker->ResolveType(patch->GetDexFile(), 724 patch->GetTargetTypeIdx(), 725 dex_cache, 726 class_loader); 727 CHECK(klass != NULL) 728 << patch->GetDexFile().GetLocation() << " " << patch->GetTargetTypeIdx(); 729 CHECK(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx()) == klass) 730 << patch->GetDexFile().GetLocation() << " " << patch->GetReferrerMethodIdx() << " " 731 << PrettyClass(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx())) << " " 732 << PrettyClass(klass); 733 return klass; 734} 735 736void ImageWriter::PatchOatCodeAndMethods() { 737 Thread* self = Thread::Current(); 738 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 739 const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter"); 740 741 typedef std::vector<const CompilerDriver::CallPatchInformation*> CallPatches; 742 const CallPatches& code_to_patch = compiler_driver_.GetCodeToPatch(); 743 for (size_t i = 0; i < code_to_patch.size(); i++) { 744 const CompilerDriver::CallPatchInformation* patch = code_to_patch[i]; 745 ArtMethod* target = GetTargetMethod(patch); 746 uintptr_t quick_code = reinterpret_cast<uintptr_t>(class_linker->GetQuickOatCodeFor(target)); 747 uintptr_t code_base = reinterpret_cast<uintptr_t>(&oat_file_->GetOatHeader()); 748 uintptr_t code_offset = quick_code - code_base; 749 if (patch->IsRelative()) { 750 // value to patch is relative to the location being patched 751 const void* quick_oat_code = 752 class_linker->GetQuickOatCodeFor(patch->GetDexFile(), 753 patch->GetReferrerClassDefIdx(), 754 patch->GetReferrerMethodIdx()); 755 uintptr_t base = reinterpret_cast<uintptr_t>(quick_oat_code); 756 uintptr_t patch_location = base + patch->GetLiteralOffset(); 757 uintptr_t value = quick_code - patch_location + patch->RelativeOffset(); 758 SetPatchLocation(patch, value); 759 } else { 760 if (quick_code == reinterpret_cast<uintptr_t>(GetQuickToInterpreterBridge())) { 761 if (target->IsNative()) { 762 // generic JNI, not interpreter bridge from GetQuickOatCodeFor(). 763 code_offset = quick_generic_jni_trampoline_offset_; 764 } else { 765 code_offset = quick_to_interpreter_bridge_offset_; 766 } 767 } 768 SetPatchLocation(patch, PointerToLowMemUInt32(GetOatAddress(code_offset))); 769 } 770 } 771 772 const CallPatches& methods_to_patch = compiler_driver_.GetMethodsToPatch(); 773 for (size_t i = 0; i < methods_to_patch.size(); i++) { 774 const CompilerDriver::CallPatchInformation* patch = methods_to_patch[i]; 775 ArtMethod* target = GetTargetMethod(patch); 776 SetPatchLocation(patch, PointerToLowMemUInt32(GetImageAddress(target))); 777 } 778 779 const std::vector<const CompilerDriver::TypePatchInformation*>& classes_to_patch = 780 compiler_driver_.GetClassesToPatch(); 781 for (size_t i = 0; i < classes_to_patch.size(); i++) { 782 const CompilerDriver::TypePatchInformation* patch = classes_to_patch[i]; 783 Class* target = GetTargetType(patch); 784 SetPatchLocation(patch, PointerToLowMemUInt32(GetImageAddress(target))); 785 } 786 787 // Update the image header with the new checksum after patching 788 ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin()); 789 image_header->SetOatChecksum(oat_file_->GetOatHeader().GetChecksum()); 790 self->EndAssertNoThreadSuspension(old_cause); 791} 792 793void ImageWriter::SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value) { 794 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 795 const void* quick_oat_code = class_linker->GetQuickOatCodeFor(patch->GetDexFile(), 796 patch->GetReferrerClassDefIdx(), 797 patch->GetReferrerMethodIdx()); 798 OatHeader& oat_header = const_cast<OatHeader&>(oat_file_->GetOatHeader()); 799 // TODO: make this Thumb2 specific 800 uint8_t* base = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(quick_oat_code) & ~0x1); 801 uint32_t* patch_location = reinterpret_cast<uint32_t*>(base + patch->GetLiteralOffset()); 802 if (kIsDebugBuild) { 803 if (patch->IsCall()) { 804 const CompilerDriver::CallPatchInformation* cpatch = patch->AsCall(); 805 const DexFile::MethodId& id = cpatch->GetTargetDexFile()->GetMethodId(cpatch->GetTargetMethodIdx()); 806 uint32_t expected = reinterpret_cast<uintptr_t>(&id) & 0xFFFFFFFF; 807 uint32_t actual = *patch_location; 808 CHECK(actual == expected || actual == value) << std::hex 809 << "actual=" << actual 810 << "expected=" << expected 811 << "value=" << value; 812 } 813 if (patch->IsType()) { 814 const CompilerDriver::TypePatchInformation* tpatch = patch->AsType(); 815 const DexFile::TypeId& id = tpatch->GetDexFile().GetTypeId(tpatch->GetTargetTypeIdx()); 816 uint32_t expected = reinterpret_cast<uintptr_t>(&id) & 0xFFFFFFFF; 817 uint32_t actual = *patch_location; 818 CHECK(actual == expected || actual == value) << std::hex 819 << "actual=" << actual 820 << "expected=" << expected 821 << "value=" << value; 822 } 823 } 824 *patch_location = value; 825 oat_header.UpdateChecksum(patch_location, sizeof(value)); 826} 827 828} // namespace art 829