// choose to squeeze the Type into fewer than 8 bits, we'll have to declare
// patch_type_ as an uintN_t and do explicit static_cast<>s.
enum class Type : uint8_t {
- kRecordPosition, // Just record patch position for patchoat.
kMethod,
kCall,
kCallRelative, // NOTE: Actual patching is instruction_set-dependent.
kDexCacheArray, // NOTE: Actual patching is instruction_set-dependent.
};
- static LinkerPatch RecordPosition(size_t literal_offset) {
- return LinkerPatch(literal_offset, Type::kRecordPosition, /* target_dex_file */ nullptr);
- }
-
static LinkerPatch MethodPatch(size_t literal_offset,
const DexFile* target_dex_file,
uint32_t target_method_idx) {
no_inline_from_(nullptr),
boot_image_(false),
app_image_(false),
- include_patch_information_(kDefaultIncludePatchInformation),
top_k_profile_threshold_(kDefaultTopKProfileThreshold),
debuggable_(false),
generate_debug_info_(kDefaultGenerateDebugInfo),
size_t inline_depth_limit,
size_t inline_max_code_units,
const std::vector<const DexFile*>* no_inline_from,
- bool include_patch_information,
double top_k_profile_threshold,
bool debuggable,
bool generate_debug_info,
no_inline_from_(no_inline_from),
boot_image_(false),
app_image_(false),
- include_patch_information_(include_patch_information),
top_k_profile_threshold_(top_k_profile_threshold),
debuggable_(debuggable),
generate_debug_info_(generate_debug_info),
debuggable_ = true;
} else if (option.starts_with("--top-k-profile-threshold=")) {
ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold_, Usage);
- } else if (option == "--include-patch-information") {
- include_patch_information_ = true;
- } else if (option == "--no-include-patch-information") {
- include_patch_information_ = false;
} else if (option == "--abort-on-hard-verifier-error") {
abort_on_hard_verifier_failure_ = true;
} else if (option.starts_with("--dump-init-failures=")) {
static constexpr double kDefaultTopKProfileThreshold = 90.0;
static const bool kDefaultGenerateDebugInfo = false;
static const bool kDefaultGenerateMiniDebugInfo = false;
- static const bool kDefaultIncludePatchInformation = false;
static const size_t kDefaultInlineDepthLimit = 3;
static const size_t kDefaultInlineMaxCodeUnits = 32;
static constexpr size_t kUnsetInlineDepthLimit = -1;
size_t inline_depth_limit,
size_t inline_max_code_units,
const std::vector<const DexFile*>* no_inline_from,
- bool include_patch_information,
double top_k_profile_threshold,
bool debuggable,
bool generate_debug_info,
return implicit_suspend_checks_;
}
- bool GetIncludePatchInformation() const {
- return include_patch_information_;
- }
-
bool IsBootImage() const {
return boot_image_;
}
bool boot_image_;
bool app_image_;
- bool include_patch_information_;
// When using a profile file only the top K% of the profiled samples will be compiled.
double top_k_profile_threshold_;
bool debuggable_;
virtual void EndText(OutputStream* text) = 0;
virtual void WriteDynamicSection() = 0;
virtual void WriteDebugInfo(const ArrayRef<const debug::MethodDebugInfo>& method_infos) = 0;
- virtual void WritePatchLocations(const ArrayRef<const uintptr_t>& patch_locations) = 0;
virtual bool End() = 0;
// Get the ELF writer's stream. This stream can be used for writing data directly
void EndText(OutputStream* text) OVERRIDE;
void WriteDynamicSection() OVERRIDE;
void WriteDebugInfo(const ArrayRef<const debug::MethodDebugInfo>& method_infos) OVERRIDE;
- void WritePatchLocations(const ArrayRef<const uintptr_t>& patch_locations) OVERRIDE;
bool End() OVERRIDE;
virtual OutputStream* GetStream() OVERRIDE;
}
template <typename ElfTypes>
-void ElfWriterQuick<ElfTypes>::WritePatchLocations(
- const ArrayRef<const uintptr_t>& patch_locations) {
- // Add relocation section for .text.
- if (compiler_options_->GetIncludePatchInformation()) {
- // Note that ElfWriter::Fixup will be called regardless and therefore
- // we need to include oat_patches for debug sections unconditionally.
- builder_->WritePatches(".text.oat_patches", patch_locations);
- }
-}
-
-template <typename ElfTypes>
bool ElfWriterQuick<ElfTypes>::End() {
builder_->End();
if (compiler_options_->GetGenerateBuildId()) {
elf_writer->WriteDynamicSection();
elf_writer->WriteDebugInfo(oat_writer->GetMethodDebugInfo());
- elf_writer->WritePatchLocations(oat_writer->GetAbsolutePatchLocations());
bool success = elf_writer->End();
ASSERT_TRUE(success);
CompilerOptions::kDefaultInlineDepthLimit,
CompilerOptions::kDefaultInlineMaxCodeUnits,
/* no_inline_from */ nullptr,
- /* include_patch_information */ false,
CompilerOptions::kDefaultTopKProfileThreshold,
Runtime::Current()->IsJavaDebuggable(),
CompilerOptions::kDefaultGenerateDebugInfo,
elf_writer->WriteDynamicSection();
elf_writer->WriteDebugInfo(oat_writer.GetMethodDebugInfo());
- elf_writer->WritePatchLocations(oat_writer.GetAbsolutePatchLocations());
if (!elf_writer->End()) {
return false;
break;
}
default: {
- DCHECK_EQ(patch.GetType(), LinkerPatch::Type::kRecordPosition);
+ DCHECK(false) << "Unexpected linker patch type: " << patch.GetType();
break;
}
}
return oat_data_offset_;
}
- ArrayRef<const uintptr_t> GetAbsolutePatchLocations() const {
- return ArrayRef<const uintptr_t>(absolute_patch_locations_);
- }
-
~OatWriter();
void AddMethodDebugInfos(const std::vector<debug::MethodDebugInfo>& infos) {
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
pc_relative_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- boot_image_address_patches_(std::less<uint32_t>(),
- graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_string_patches_(StringReferenceValueComparator(),
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_class_patches_(TypeReferenceValueComparator(),
}
Literal* CodeGeneratorARM::DeduplicateBootImageAddressLiteral(uint32_t address) {
- bool needs_patch = GetCompilerOptions().GetIncludePatchInformation();
- Uint32ToLiteralMap* map = needs_patch ? &boot_image_address_patches_ : &uint32_literals_;
- return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), map);
+ return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), &uint32_literals_);
}
Literal* CodeGeneratorARM::DeduplicateJitStringLiteral(const DexFile& dex_file,
/* MOVW+MOVT for each entry */ 2u * pc_relative_string_patches_.size() +
boot_image_type_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * pc_relative_type_patches_.size() +
- /* MOVW+MOVT for each entry */ 2u * type_bss_entry_patches_.size() +
- boot_image_address_patches_.size();
+ /* MOVW+MOVT for each entry */ 2u * type_bss_entry_patches_.size();
linker_patches->reserve(size);
EmitPcRelativeLinkerPatches<LinkerPatch::DexCacheArrayPatch>(pc_relative_dex_cache_patches_,
linker_patches);
target_type.dex_file,
target_type.type_index.index_));
}
- for (const auto& entry : boot_image_address_patches_) {
- DCHECK(GetCompilerOptions().GetIncludePatchInformation());
- Literal* literal = entry.second;
- DCHECK(literal->GetLabel()->IsBound());
- uint32_t literal_offset = literal->GetLabel()->Position();
- linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset));
- }
DCHECK_EQ(size, linker_patches->size());
}
ArenaDeque<PcRelativePatchInfo> pc_relative_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
- // Deduplication map for patchable boot image addresses.
- Uint32ToLiteralMap boot_image_address_patches_;
// Patches for string literals in JIT compiled code.
StringToLiteralMap jit_string_patches_;
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
pc_relative_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- boot_image_address_patches_(std::less<uint32_t>(),
- graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_string_patches_(StringReferenceValueComparator(),
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_class_patches_(TypeReferenceValueComparator(),
vixl::aarch64::Literal<uint32_t>* CodeGeneratorARM64::DeduplicateBootImageAddressLiteral(
uint64_t address) {
- bool needs_patch = GetCompilerOptions().GetIncludePatchInformation();
- Uint32ToLiteralMap* map = needs_patch ? &boot_image_address_patches_ : &uint32_literals_;
- return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), map);
+ return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), &uint32_literals_);
}
vixl::aarch64::Literal<uint32_t>* CodeGeneratorARM64::DeduplicateJitStringLiteral(
pc_relative_string_patches_.size() +
boot_image_type_patches_.size() +
pc_relative_type_patches_.size() +
- type_bss_entry_patches_.size() +
- boot_image_address_patches_.size();
+ type_bss_entry_patches_.size();
linker_patches->reserve(size);
for (const PcRelativePatchInfo& info : pc_relative_dex_cache_patches_) {
linker_patches->push_back(LinkerPatch::DexCacheArrayPatch(info.label.GetLocation(),
target_type.dex_file,
target_type.type_index.index_));
}
- for (const auto& entry : boot_image_address_patches_) {
- DCHECK(GetCompilerOptions().GetIncludePatchInformation());
- vixl::aarch64::Literal<uint32_t>* literal = entry.second;
- linker_patches->push_back(LinkerPatch::RecordPosition(literal->GetOffset()));
- }
DCHECK_EQ(size, linker_patches->size());
}
ArenaDeque<PcRelativePatchInfo> pc_relative_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
- // Deduplication map for patchable boot image addresses.
- Uint32ToLiteralMap boot_image_address_patches_;
// Patches for string literals in JIT compiled code.
StringToLiteralMap jit_string_patches_;
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
pc_relative_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- boot_image_address_patches_(std::less<uint32_t>(),
- graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_string_patches_(StringReferenceValueComparator(),
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_class_patches_(TypeReferenceValueComparator(),
}
VIXLUInt32Literal* CodeGeneratorARMVIXL::DeduplicateBootImageAddressLiteral(uint32_t address) {
- bool needs_patch = GetCompilerOptions().GetIncludePatchInformation();
- Uint32ToLiteralMap* map = needs_patch ? &boot_image_address_patches_ : &uint32_literals_;
- return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), map);
+ return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), &uint32_literals_);
}
VIXLUInt32Literal* CodeGeneratorARMVIXL::DeduplicateDexCacheAddressLiteral(uint32_t address) {
/* MOVW+MOVT for each entry */ 2u * pc_relative_string_patches_.size() +
boot_image_type_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * pc_relative_type_patches_.size() +
- /* MOVW+MOVT for each entry */ 2u * type_bss_entry_patches_.size() +
- boot_image_address_patches_.size();
+ /* MOVW+MOVT for each entry */ 2u * type_bss_entry_patches_.size();
linker_patches->reserve(size);
EmitPcRelativeLinkerPatches<LinkerPatch::DexCacheArrayPatch>(pc_relative_dex_cache_patches_,
linker_patches);
target_type.dex_file,
target_type.type_index.index_));
}
- for (const auto& entry : boot_image_address_patches_) {
- DCHECK(GetCompilerOptions().GetIncludePatchInformation());
- VIXLUInt32Literal* literal = entry.second;
- DCHECK(literal->IsBound());
- uint32_t literal_offset = literal->GetLocation();
- linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset));
- }
DCHECK_EQ(size, linker_patches->size());
}
ArenaDeque<PcRelativePatchInfo> pc_relative_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
- // Deduplication map for patchable boot image addresses.
- Uint32ToLiteralMap boot_image_address_patches_;
// Patches for string literals in JIT compiled code.
StringToLiteralMap jit_string_patches_;
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
pc_relative_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- boot_image_address_patches_(std::less<uint32_t>(),
- graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_string_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_class_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
clobbered_ra_(false) {
pc_relative_type_patches_.size() +
type_bss_entry_patches_.size() +
boot_image_string_patches_.size() +
- boot_image_type_patches_.size() +
- boot_image_address_patches_.size();
+ boot_image_type_patches_.size();
linker_patches->reserve(size);
EmitPcRelativeLinkerPatches<LinkerPatch::DexCacheArrayPatch>(pc_relative_dex_cache_patches_,
linker_patches);
target_type.dex_file,
target_type.type_index.index_));
}
- for (const auto& entry : boot_image_address_patches_) {
- DCHECK(GetCompilerOptions().GetIncludePatchInformation());
- Literal* literal = entry.second;
- DCHECK(literal->GetLabel()->IsBound());
- uint32_t literal_offset = __ GetLabelLocation(literal->GetLabel());
- linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset));
- }
DCHECK_EQ(size, linker_patches->size());
}
}
Literal* CodeGeneratorMIPS::DeduplicateBootImageAddressLiteral(uint32_t address) {
- bool needs_patch = GetCompilerOptions().GetIncludePatchInformation();
- Uint32ToLiteralMap* map = needs_patch ? &boot_image_address_patches_ : &uint32_literals_;
- return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), map);
+ return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), &uint32_literals_);
}
void CodeGeneratorMIPS::EmitPcRelativeAddressPlaceholderHigh(PcRelativePatchInfo* info,
ArenaDeque<PcRelativePatchInfo> pc_relative_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
- // Deduplication map for patchable boot image addresses.
- Uint32ToLiteralMap boot_image_address_patches_;
// Patches for string root accesses in JIT compiled code.
ArenaDeque<JitPatchInfo> jit_string_patches_;
// Patches for class root accesses in JIT compiled code.
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
pc_relative_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- boot_image_address_patches_(std::less<uint32_t>(),
- graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_string_patches_(StringReferenceValueComparator(),
graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
jit_class_patches_(TypeReferenceValueComparator(),
pc_relative_type_patches_.size() +
type_bss_entry_patches_.size() +
boot_image_string_patches_.size() +
- boot_image_type_patches_.size() +
- boot_image_address_patches_.size();
+ boot_image_type_patches_.size();
linker_patches->reserve(size);
EmitPcRelativeLinkerPatches<LinkerPatch::DexCacheArrayPatch>(pc_relative_dex_cache_patches_,
linker_patches);
target_type.dex_file,
target_type.type_index.index_));
}
- for (const auto& entry : boot_image_address_patches_) {
- DCHECK(GetCompilerOptions().GetIncludePatchInformation());
- Literal* literal = entry.second;
- DCHECK(literal->GetLabel()->IsBound());
- uint32_t literal_offset = __ GetLabelLocation(literal->GetLabel());
- linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset));
- }
DCHECK_EQ(size, linker_patches->size());
}
}
Literal* CodeGeneratorMIPS64::DeduplicateBootImageAddressLiteral(uint64_t address) {
- bool needs_patch = GetCompilerOptions().GetIncludePatchInformation();
- Uint32ToLiteralMap* map = needs_patch ? &boot_image_address_patches_ : &uint32_literals_;
- return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), map);
+ return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), &uint32_literals_);
}
void CodeGeneratorMIPS64::EmitPcRelativeAddressPlaceholderHigh(PcRelativePatchInfo* info,
ArenaDeque<PcRelativePatchInfo> pc_relative_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
- // Deduplication map for patchable boot image addresses.
- Uint32ToLiteralMap boot_image_address_patches_;
// Patches for string root accesses in JIT compiled code.
StringToLiteralMap jit_string_patches_;
// Patches for class root accesses in JIT compiled code.
assembler_(graph->GetArena()),
isa_features_(isa_features),
pc_relative_dex_cache_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- simple_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
string_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
temp, ArtMethod::EntryPointFromQuickCompiledCodeOffset(kX86PointerSize).Int32Value()));
}
-void CodeGeneratorX86::RecordSimplePatch() {
- if (GetCompilerOptions().GetIncludePatchInformation()) {
- simple_patches_.emplace_back();
- __ Bind(&simple_patches_.back());
- }
-}
-
void CodeGeneratorX86::RecordBootStringPatch(HLoadString* load_string) {
DCHECK(GetCompilerOptions().IsBootImage());
HX86ComputeBaseMethodAddress* address = nullptr;
DCHECK(linker_patches->empty());
size_t size =
pc_relative_dex_cache_patches_.size() +
- simple_patches_.size() +
string_patches_.size() +
boot_image_type_patches_.size() +
type_bss_entry_patches_.size();
linker_patches->reserve(size);
EmitPcRelativeLinkerPatches<LinkerPatch::DexCacheArrayPatch>(pc_relative_dex_cache_patches_,
linker_patches);
- for (const Label& label : simple_patches_) {
- uint32_t literal_offset = label.Position() - kLabelPositionToLiteralOffsetAdjustment;
- linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset));
- }
if (!GetCompilerOptions().IsBootImage()) {
DCHECK(boot_image_type_patches_.empty());
EmitPcRelativeLinkerPatches<LinkerPatch::StringBssEntryPatch>(string_patches_, linker_patches);
reinterpret_cast<uintptr_t>(cls->GetClass().Get()));
DCHECK_NE(address, 0u);
__ movl(out, Immediate(address));
- codegen_->RecordSimplePatch();
break;
}
case HLoadClass::LoadKind::kBssEntry: {
reinterpret_cast<uintptr_t>(load->GetString().Get()));
DCHECK_NE(address, 0u);
__ movl(out, Immediate(address));
- codegen_->RecordSimplePatch();
return; // No dex cache slow path.
}
case HLoadString::LoadKind::kBssEntry: {
// Generate a call to a virtual method.
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
- void RecordSimplePatch();
void RecordBootStringPatch(HLoadString* load_string);
void RecordBootTypePatch(HLoadClass* load_class);
Label* NewTypeBssEntryPatch(HLoadClass* load_class);
// PC-relative DexCache access info.
ArenaDeque<X86PcRelativePatchInfo> pc_relative_dex_cache_patches_;
- // Patch locations for patchoat where the linker doesn't do any other work.
- ArenaDeque<Label> simple_patches_;
// String patch locations; type depends on configuration (app .bss or boot image PIC/non-PIC).
ArenaDeque<X86PcRelativePatchInfo> string_patches_;
// Type patch locations for boot image; type depends on configuration (boot image PIC/non-PIC).
kX86_64PointerSize).SizeValue()));
}
-void CodeGeneratorX86_64::RecordSimplePatch() {
- if (GetCompilerOptions().GetIncludePatchInformation()) {
- simple_patches_.emplace_back();
- __ Bind(&simple_patches_.back());
- }
-}
-
void CodeGeneratorX86_64::RecordBootStringPatch(HLoadString* load_string) {
DCHECK(GetCompilerOptions().IsBootImage());
string_patches_.emplace_back(load_string->GetDexFile(), load_string->GetStringIndex().index_);
DCHECK(linker_patches->empty());
size_t size =
pc_relative_dex_cache_patches_.size() +
- simple_patches_.size() +
string_patches_.size() +
boot_image_type_patches_.size() +
type_bss_entry_patches_.size();
linker_patches->reserve(size);
EmitPcRelativeLinkerPatches<LinkerPatch::DexCacheArrayPatch>(pc_relative_dex_cache_patches_,
linker_patches);
- for (const Label& label : simple_patches_) {
- uint32_t literal_offset = label.Position() - kLabelPositionToLiteralOffsetAdjustment;
- linker_patches->push_back(LinkerPatch::RecordPosition(literal_offset));
- }
if (!GetCompilerOptions().IsBootImage()) {
DCHECK(boot_image_type_patches_.empty());
EmitPcRelativeLinkerPatches<LinkerPatch::StringBssEntryPatch>(string_patches_, linker_patches);
isa_features_(isa_features),
constant_area_start_(0),
pc_relative_dex_cache_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
- simple_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
string_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
reinterpret_cast<uintptr_t>(cls->GetClass().Get()));
DCHECK_NE(address, 0u);
__ movl(out, Immediate(address)); // Zero-extended.
- codegen_->RecordSimplePatch();
break;
}
case HLoadClass::LoadKind::kBssEntry: {
reinterpret_cast<uintptr_t>(load->GetString().Get()));
DCHECK_NE(address, 0u);
__ movl(out, Immediate(address)); // Zero-extended.
- codegen_->RecordSimplePatch();
return; // No dex cache slow path.
}
case HLoadString::LoadKind::kBssEntry: {
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
- void RecordSimplePatch();
void RecordBootStringPatch(HLoadString* load_string);
void RecordBootTypePatch(HLoadClass* load_class);
Label* NewTypeBssEntryPatch(HLoadClass* load_class);
// PC-relative DexCache access info.
ArenaDeque<PatchInfo<Label>> pc_relative_dex_cache_patches_;
- // Patch locations for patchoat where the linker doesn't do any other work.
- ArenaDeque<Label> simple_patches_;
// String patch locations; type depends on configuration (app .bss or boot image PIC).
ArenaDeque<PatchInfo<Label>> string_patches_;
// Type patch locations for boot image (always PIC).
// Use a known boot image Class* address, embedded in the code by the codegen.
// Used for boot image classes referenced by apps in AOT- and JIT-compiled code.
- // Note: codegen needs to emit a linker patch if indicated by compiler options'
- // GetIncludePatchInformation().
kBootImageAddress,
// Load from an entry in the .bss section using a PC-relative load.
// Use a known boot image String* address, embedded in the code by the codegen.
// Used for boot image strings referenced by apps in AOT- and JIT-compiled code.
- // Note: codegen needs to emit a linker patch if indicated by compiler options'
- // GetIncludePatchInformation().
kBootImageAddress,
// Load from an entry in the .bss section using a PC-relative load.
}
static bool AOTCanEmbedMethod(ArtMethod* method, const CompilerOptions& options) {
- // Including patch information means the AOT code will be patched, which we don't
- // support in the compiler, and is anyways moving away b/33192586.
- return IsInBootImage(method) && !options.GetCompilePic() && !options.GetIncludePatchInformation();
+ return IsInBootImage(method) && !options.GetCompilePic();
}
void HSharpening::ProcessInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
UsageError("");
UsageError(" --dump-timing: display a breakdown of where time was spent");
UsageError("");
- UsageError(" --include-patch-information: Include patching information so the generated code");
- UsageError(" can have its base address moved without full recompilation.");
- UsageError("");
- UsageError(" --no-include-patch-information: Do not include patching information.");
- UsageError("");
UsageError(" -g");
UsageError(" --generate-debug-info: Generate debug information for native debugging,");
UsageError(" such as stack unwinding information, ELF symbols and DWARF sections.");
elf_writer->WriteDynamicSection();
elf_writer->WriteDebugInfo(oat_writer->GetMethodDebugInfo());
- elf_writer->WritePatchLocations(oat_writer->GetAbsolutePatchLocations());
if (!elf_writer->End()) {
LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
if [ "$RELOCATE" = "y" ]; then
- COMPILE_FLAGS="${COMPILE_FLAGS} --include-patch-information --runtime-arg -Xnorelocate"
- FLAGS="${FLAGS} -Xrelocate -Xcompiler-option --include-patch-information"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xnorelocate"
+ FLAGS="${FLAGS} -Xrelocate"
if [ "$HOST" = "y" ]; then
# Run test sets a fairly draconian ulimit that we will likely blow right over
# since we are relocating. Get the total size of the /system/framework directory