diff options
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
| -rw-r--r-- | compiler/optimizing/code_generator.cc | 55 | 
1 files changed, 55 insertions, 0 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 6abda9b3026..231017f55e6 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -51,6 +51,8 @@  #include "dex/verified_method.h"  #include "driver/compiler_driver.h"  #include "graph_visualizer.h" +#include "image.h" +#include "gc/space/image_space.h"  #include "intern_table.h"  #include "intrinsics.h"  #include "mirror/array-inl.h" @@ -447,6 +449,18 @@ void CodeGenerator::EmitLinkerPatches(    // No linker patches by default.  } +bool CodeGenerator::NeedsThunkCode(const linker::LinkerPatch& patch ATTRIBUTE_UNUSED) const { +  // Code generators that create patches requiring thunk compilation should override this function. +  return false; +} + +void CodeGenerator::EmitThunkCode(const linker::LinkerPatch& patch ATTRIBUTE_UNUSED, +                                  /*out*/ ArenaVector<uint8_t>* code ATTRIBUTE_UNUSED, +                                  /*out*/ std::string* debug_name ATTRIBUTE_UNUSED) { +  // Code generators that create patches requiring thunk compilation should override this function. +  LOG(FATAL) << "Unexpected call to EmitThunkCode()."; +} +  void CodeGenerator::InitializeCodeGeneration(size_t number_of_spill_slots,                                               size_t maximum_safepoint_spill_size,                                               size_t number_of_out_slots, @@ -722,6 +736,47 @@ void CodeGenerator::GenerateLoadClassRuntimeCall(HLoadClass* cls) {    }  } +static uint32_t GetBootImageOffsetImpl(const void* object, ImageHeader::ImageSections section) { +  Runtime* runtime = Runtime::Current(); +  DCHECK(runtime->IsAotCompiler()); +  const std::vector<gc::space::ImageSpace*>& boot_image_spaces = +      runtime->GetHeap()->GetBootImageSpaces(); +  // Check that the `object` is in the expected section of one of the boot image files. +  DCHECK(std::any_of(boot_image_spaces.begin(), +                     boot_image_spaces.end(), +                     [object, section](gc::space::ImageSpace* space) { +                       uintptr_t begin = reinterpret_cast<uintptr_t>(space->Begin()); +                       uintptr_t offset = reinterpret_cast<uintptr_t>(object) - begin; +                       return space->GetImageHeader().GetImageSection(section).Contains(offset); +                     })); +  uintptr_t begin = reinterpret_cast<uintptr_t>(boot_image_spaces.front()->Begin()); +  uintptr_t offset = reinterpret_cast<uintptr_t>(object) - begin; +  return dchecked_integral_cast<uint32_t>(offset); +} + +// NO_THREAD_SAFETY_ANALYSIS: Avoid taking the mutator lock, boot image classes are non-moveable. +uint32_t CodeGenerator::GetBootImageOffset(HLoadClass* load_class) NO_THREAD_SAFETY_ANALYSIS { +  DCHECK_EQ(load_class->GetLoadKind(), HLoadClass::LoadKind::kBootImageRelRo); +  ObjPtr<mirror::Class> klass = load_class->GetClass().Get(); +  DCHECK(klass != nullptr); +  return GetBootImageOffsetImpl(klass.Ptr(), ImageHeader::kSectionObjects); +} + +// NO_THREAD_SAFETY_ANALYSIS: Avoid taking the mutator lock, boot image strings are non-moveable. +uint32_t CodeGenerator::GetBootImageOffset(HLoadString* load_string) NO_THREAD_SAFETY_ANALYSIS { +  DCHECK_EQ(load_string->GetLoadKind(), HLoadString::LoadKind::kBootImageRelRo); +  ObjPtr<mirror::String> string = load_string->GetString().Get(); +  DCHECK(string != nullptr); +  return GetBootImageOffsetImpl(string.Ptr(), ImageHeader::kSectionObjects); +} + +uint32_t CodeGenerator::GetBootImageOffset(HInvokeStaticOrDirect* invoke) { +  DCHECK_EQ(invoke->GetMethodLoadKind(), HInvokeStaticOrDirect::MethodLoadKind::kBootImageRelRo); +  ArtMethod* method = invoke->GetResolvedMethod(); +  DCHECK(method != nullptr); +  return GetBootImageOffsetImpl(method, ImageHeader::kSectionArtMethods); +} +  void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const {    // The DCHECKS below check that a register is not specified twice in    // the summary. The out location can overlap with an input, so we need  | 
