summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/dex_to_dex_compiler.cc69
-rw-r--r--compiler/driver/compiler_driver-inl.h140
-rw-r--r--compiler/driver/compiler_driver.cc139
-rw-r--r--compiler/driver/compiler_driver.h28
-rw-r--r--compiler/optimizing/code_generator.cc2
-rw-r--r--compiler/optimizing/code_generator.h2
-rw-r--r--compiler/optimizing/code_generator_arm.cc4
-rw-r--r--compiler/optimizing/code_generator_arm.h2
-rw-r--r--compiler/optimizing/code_generator_arm64.cc4
-rw-r--r--compiler/optimizing/code_generator_arm64.h2
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc2
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.h2
-rw-r--r--compiler/optimizing/code_generator_mips.cc2
-rw-r--r--compiler/optimizing/code_generator_mips.h2
-rw-r--r--compiler/optimizing/code_generator_mips64.cc2
-rw-r--r--compiler/optimizing/code_generator_mips64.h2
-rw-r--r--compiler/optimizing/code_generator_x86.cc4
-rw-r--r--compiler/optimizing/code_generator_x86.h2
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc4
-rw-r--r--compiler/optimizing/code_generator_x86_64.h2
-rw-r--r--compiler/optimizing/dex_cache_array_fixups_arm.cc8
-rw-r--r--compiler/optimizing/graph_visualizer.cc2
-rw-r--r--compiler/optimizing/inliner.cc47
-rw-r--r--compiler/optimizing/instruction_builder.cc22
-rw-r--r--compiler/optimizing/instruction_simplifier.cc2
-rw-r--r--compiler/optimizing/intrinsics.cc4
-rw-r--r--compiler/optimizing/nodes.h83
-rw-r--r--compiler/optimizing/sharpening.cc55
-rw-r--r--test/555-checker-regression-x86const/build44
-rw-r--r--test/555-checker-regression-x86const/expected.txt0
-rw-r--r--test/555-checker-regression-x86const/info.txt2
-rw-r--r--test/555-checker-regression-x86const/run18
-rw-r--r--test/555-checker-regression-x86const/src/Main.java41
-rw-r--r--test/555-checker-regression-x86const/src/Unresolved.java18
34 files changed, 170 insertions, 592 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index c902d289e9..e0abf197d5 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -277,39 +277,44 @@ void DexCompiler::CompileInvokeVirtual(Instruction* inst, uint32_t dex_pc,
return;
}
uint32_t method_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
- MethodReference target_method(&GetDexFile(), method_idx);
- InvokeType invoke_type = kVirtual;
- InvokeType original_invoke_type = invoke_type;
- int vtable_idx;
- uintptr_t direct_code;
- uintptr_t direct_method;
- // TODO: support devirtualization.
- const bool kEnableDevirtualization = false;
- bool fast_path = driver_.ComputeInvokeInfo(&unit_, dex_pc,
- false, kEnableDevirtualization,
- &invoke_type,
- &target_method, &vtable_idx,
- &direct_code, &direct_method);
- if (fast_path && original_invoke_type == invoke_type) {
- if (vtable_idx >= 0 && IsUint<16>(vtable_idx)) {
- VLOG(compiler) << "Quickening " << Instruction::Name(inst->Opcode())
- << "(" << PrettyMethod(method_idx, GetDexFile(), true) << ")"
- << " to " << Instruction::Name(new_opcode)
- << " by replacing method index " << method_idx
- << " by vtable index " << vtable_idx
- << " at dex pc " << StringPrintf("0x%x", dex_pc) << " in method "
- << PrettyMethod(unit_.GetDexMethodIndex(), GetDexFile(), true);
- // We are modifying 4 consecutive bytes.
- inst->SetOpcode(new_opcode);
- // Replace method index by vtable index.
- if (is_range) {
- inst->SetVRegB_3rc(static_cast<uint16_t>(vtable_idx));
- } else {
- inst->SetVRegB_35c(static_cast<uint16_t>(vtable_idx));
- }
- quickened_info_.push_back(QuickenedInfo(dex_pc, method_idx));
- }
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
+ soa.Decode<mirror::ClassLoader*>(unit_.GetClassLoader())));
+
+ ClassLinker* class_linker = unit_.GetClassLinker();
+ ArtMethod* resolved_method = class_linker->ResolveMethod<ClassLinker::kForceICCECheck>(
+ GetDexFile(),
+ method_idx,
+ unit_.GetDexCache(),
+ class_loader,
+ /* referrer */ nullptr,
+ kVirtual);
+
+ if (UNLIKELY(resolved_method == nullptr)) {
+ // Clean up any exception left by type resolution.
+ soa.Self()->ClearException();
+ return;
+ }
+
+ uint32_t vtable_idx = resolved_method->GetMethodIndex();
+ DCHECK(IsUint<16>(vtable_idx));
+ VLOG(compiler) << "Quickening " << Instruction::Name(inst->Opcode())
+ << "(" << PrettyMethod(method_idx, GetDexFile(), true) << ")"
+ << " to " << Instruction::Name(new_opcode)
+ << " by replacing method index " << method_idx
+ << " by vtable index " << vtable_idx
+ << " at dex pc " << StringPrintf("0x%x", dex_pc) << " in method "
+ << PrettyMethod(unit_.GetDexMethodIndex(), GetDexFile(), true);
+ // We are modifying 4 consecutive bytes.
+ inst->SetOpcode(new_opcode);
+ // Replace method index by vtable index.
+ if (is_range) {
+ inst->SetVRegB_3rc(static_cast<uint16_t>(vtable_idx));
+ } else {
+ inst->SetVRegB_35c(static_cast<uint16_t>(vtable_idx));
}
+ quickened_info_.push_back(QuickenedInfo(dex_pc, method_idx));
}
CompiledMethod* ArtCompileDEX(
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 3a260f5a80..4b913f4255 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -293,146 +293,6 @@ inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex(
}
}
-inline int CompilerDriver::IsFastInvoke(
- ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
- mirror::Class* referrer_class, ArtMethod* resolved_method, InvokeType* invoke_type,
- MethodReference* target_method, const MethodReference* devirt_target,
- uintptr_t* direct_code, uintptr_t* direct_method) {
- // Don't try to fast-path if we don't understand the caller's class.
- // Referrer_class is the class that this invoke is contained in.
- if (UNLIKELY(referrer_class == nullptr)) {
- return 0;
- }
- StackHandleScope<2> hs(soa.Self());
- // Methods_class is the class refered to by the class_idx field of the methodId the method_idx is
- // pointing to.
- // For example in
- // .class LABC;
- // .super LDEF;
- // .method hi()V
- // ...
- // invoke-super {p0}, LDEF;->hi()V
- // ...
- // .end method
- // the referrer_class is 'ABC' and the methods_class is DEF. Note that the methods class is 'DEF'
- // even if 'DEF' inherits the method from it's superclass.
- Handle<mirror::Class> methods_class(hs.NewHandle(mUnit->GetClassLinker()->ResolveType(
- *target_method->dex_file,
- target_method->dex_file->GetMethodId(target_method->dex_method_index).class_idx_,
- dex_cache,
- class_loader)));
- DCHECK(methods_class.Get() != nullptr);
- mirror::Class* methods_declaring_class = resolved_method->GetDeclaringClass();
- if (UNLIKELY(!referrer_class->CanAccessResolvedMethod(methods_declaring_class, resolved_method,
- dex_cache.Get(),
- target_method->dex_method_index))) {
- return 0;
- }
- // Sharpen a virtual call into a direct call when the target is known not to have been
- // overridden (ie is final).
- const bool same_dex_file = target_method->dex_file == mUnit->GetDexFile();
- bool can_sharpen_virtual_based_on_type = same_dex_file &&
- (*invoke_type == kVirtual) && (resolved_method->IsFinal() ||
- methods_declaring_class->IsFinal());
- // For invoke-super, ensure the vtable index will be correct to dispatch in the vtable of
- // the super class.
- const PointerSize pointer_size = InstructionSetPointerSize(GetInstructionSet());
- // TODO We should be able to sharpen if we are going into the boot image as well.
- bool can_sharpen_super_based_on_type = same_dex_file &&
- (*invoke_type == kSuper) &&
- !methods_class->IsInterface() &&
- (referrer_class != methods_declaring_class) &&
- referrer_class->IsSubClass(methods_declaring_class) &&
- resolved_method->GetMethodIndex() < methods_declaring_class->GetVTableLength() &&
- (methods_declaring_class->GetVTableEntry(
- resolved_method->GetMethodIndex(), pointer_size) == resolved_method) &&
- resolved_method->IsInvokable();
- // TODO We should be able to sharpen if we are going into the boot image as well.
- bool can_sharpen_interface_super_based_on_type = same_dex_file &&
- (*invoke_type == kSuper) &&
- methods_class->IsInterface() &&
- methods_class->IsAssignableFrom(referrer_class) &&
- resolved_method->IsInvokable();
-
- if (can_sharpen_virtual_based_on_type ||
- can_sharpen_super_based_on_type ||
- can_sharpen_interface_super_based_on_type) {
- // Sharpen a virtual call into a direct call. The method_idx is into referrer's
- // dex cache, check that this resolved method is where we expect it.
- CHECK_EQ(target_method->dex_file, mUnit->GetDexFile());
- DCHECK_EQ(dex_cache.Get(), mUnit->GetClassLinker()->FindDexCache(
- soa.Self(), *mUnit->GetDexFile(), false));
- CHECK_EQ(referrer_class->GetDexCache()->GetResolvedMethod(
- target_method->dex_method_index, pointer_size),
- resolved_method) << PrettyMethod(resolved_method);
- int stats_flags = kFlagMethodResolved;
- GetCodeAndMethodForDirectCall(/*out*/invoke_type,
- kDirect, // Sharp type
- false, // The dex cache is guaranteed to be available
- referrer_class, resolved_method,
- /*out*/&stats_flags,
- target_method,
- /*out*/direct_code,
- /*out*/direct_method);
- DCHECK_NE(*invoke_type, kSuper) << PrettyMethod(resolved_method);
- if (*invoke_type == kDirect) {
- stats_flags |= kFlagsMethodResolvedVirtualMadeDirect;
- }
- return stats_flags;
- }
-
- if ((*invoke_type == kVirtual || *invoke_type == kInterface) && devirt_target != nullptr) {
- // Post-verification callback recorded a more precise invoke target based on its type info.
- ArtMethod* called_method;
- ClassLinker* class_linker = mUnit->GetClassLinker();
- if (LIKELY(devirt_target->dex_file == mUnit->GetDexFile())) {
- called_method = class_linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
- *devirt_target->dex_file, devirt_target->dex_method_index, dex_cache, class_loader,
- nullptr, kVirtual);
- } else {
- auto target_dex_cache(hs.NewHandle(class_linker->RegisterDexFile(*devirt_target->dex_file,
- class_loader.Get())));
- called_method = class_linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
- *devirt_target->dex_file, devirt_target->dex_method_index, target_dex_cache,
- class_loader, nullptr, kVirtual);
- }
- CHECK(called_method != nullptr);
- CHECK(called_method->IsInvokable());
- int stats_flags = kFlagMethodResolved;
- GetCodeAndMethodForDirectCall(/*out*/invoke_type,
- kDirect, // Sharp type
- true, // The dex cache may not be available
- referrer_class, called_method,
- /*out*/&stats_flags,
- target_method,
- /*out*/direct_code,
- /*out*/direct_method);
- DCHECK_NE(*invoke_type, kSuper);
- if (*invoke_type == kDirect) {
- stats_flags |= kFlagsMethodResolvedPreciseTypeDevirtualization;
- }
- return stats_flags;
- }
-
- if (UNLIKELY(*invoke_type == kSuper)) {
- // Unsharpened super calls are suspicious so go slow-path.
- return 0;
- }
-
- // Sharpening failed so generate a regular resolved method dispatch.
- int stats_flags = kFlagMethodResolved;
- GetCodeAndMethodForDirectCall(/*out*/invoke_type,
- *invoke_type, // Sharp type
- false, // The dex cache is guaranteed to be available
- referrer_class, resolved_method,
- /*out*/&stats_flags,
- target_method,
- /*out*/direct_code,
- /*out*/direct_method);
- return stats_flags;
-}
-
inline bool CompilerDriver::IsMethodsClassInitialized(mirror::Class* referrer_class,
ArtMethod* resolved_method) {
if (!resolved_method->IsStatic()) {
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index a149c07beb..adbf9fd0a7 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1654,12 +1654,8 @@ bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompi
}
}
-void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type,
- bool no_guarantee_of_dex_cache_entry,
- const mirror::Class* referrer_class,
+void CompilerDriver::GetCodeAndMethodForDirectCall(const mirror::Class* referrer_class,
ArtMethod* method,
- int* stats_flags,
- MethodReference* target_method,
uintptr_t* direct_code,
uintptr_t* direct_method) {
// For direct and static methods compute possible direct_code and direct_method values, ie
@@ -1671,15 +1667,11 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType
Runtime* const runtime = Runtime::Current();
gc::Heap* const heap = runtime->GetHeap();
auto* cl = runtime->GetClassLinker();
- const auto pointer_size = cl->GetImagePointerSize();
bool use_dex_cache = GetCompilerOptions().GetCompilePic(); // Off by default
const bool compiling_boot = heap->IsCompilingBoot();
// TODO This is somewhat hacky. We should refactor all of this invoke codepath.
const bool force_relocations = (compiling_boot ||
GetCompilerOptions().GetIncludePatchInformation());
- if (sharp_type != kStatic && sharp_type != kDirect) {
- return;
- }
// TODO: support patching on all architectures.
use_dex_cache = use_dex_cache || (force_relocations && !support_boot_image_fixup_);
mirror::Class* declaring_class = method->GetDeclaringClass();
@@ -1687,14 +1679,12 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType
if (!use_dex_cache) {
if (!method_code_in_boot) {
use_dex_cache = true;
- } else {
- bool has_clinit_trampoline =
- method->IsStatic() && !declaring_class->IsInitialized();
- if (has_clinit_trampoline && declaring_class != referrer_class) {
- // Ensure we run the clinit trampoline unless we are invoking a static method in the same
- // class.
- use_dex_cache = true;
- }
+ } else if (method->IsStatic() &&
+ declaring_class != referrer_class &&
+ !declaring_class->IsInitialized()) {
+ // Ensure we run the clinit trampoline unless we are invoking a static method in the same
+ // class.
+ use_dex_cache = true;
}
}
if (runtime->UseJitCompilation()) {
@@ -1705,9 +1695,7 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType
use_dex_cache = true;
}
}
- if (method_code_in_boot) {
- *stats_flags |= kFlagDirectCallToBoot | kFlagDirectMethodToBoot;
- }
+
if (!use_dex_cache && force_relocations) {
bool is_in_image;
if (IsBootImage()) {
@@ -1724,39 +1712,8 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType
use_dex_cache = true;
}
}
- // The method is defined not within this dex file. We need a dex cache slot within the current
- // dex file or direct pointers.
- bool must_use_direct_pointers = false;
- mirror::DexCache* dex_cache = declaring_class->GetDexCache();
- if (target_method->dex_file == dex_cache->GetDexFile() &&
- !(runtime->UseJitCompilation() && dex_cache->GetResolvedMethod(
- method->GetDexMethodIndex(), pointer_size) == nullptr)) {
- target_method->dex_method_index = method->GetDexMethodIndex();
- } else {
- if (no_guarantee_of_dex_cache_entry) {
- // See if the method is also declared in this dex cache.
- uint32_t dex_method_idx = method->FindDexMethodIndexInOtherDexFile(
- *target_method->dex_file, target_method->dex_method_index);
- if (dex_method_idx != DexFile::kDexNoIndex) {
- target_method->dex_method_index = dex_method_idx;
- } else {
- if (force_relocations && !use_dex_cache) {
- target_method->dex_method_index = method->GetDexMethodIndex();
- target_method->dex_file = dex_cache->GetDexFile();
- }
- must_use_direct_pointers = true;
- }
- }
- }
- if (use_dex_cache) {
- if (must_use_direct_pointers) {
- // Fail. Test above showed the only safe dispatch was via the dex cache, however, the direct
- // pointers are required as the dex cache lacks an appropriate entry.
- VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
- } else {
- *type = sharp_type;
- }
- } else {
+
+ if (!use_dex_cache) {
bool method_in_image = false;
const std::vector<gc::space::ImageSpace*> image_spaces = heap->GetBootImageSpaces();
for (gc::space::ImageSpace* image_space : image_spaces) {
@@ -1772,85 +1729,13 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType
// the method and its code are / will be. We don't sharpen to interpreter bridge since we
// check IsQuickToInterpreterBridge above.
CHECK(!method->IsAbstract());
- *type = sharp_type;
*direct_method = force_relocations ? -1 : reinterpret_cast<uintptr_t>(method);
*direct_code = force_relocations ? -1 : compiler_->GetEntryPointOf(method);
- target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
- target_method->dex_method_index = method->GetDexMethodIndex();
- } else if (!must_use_direct_pointers) {
- // Set the code and rely on the dex cache for the method.
- *type = sharp_type;
- if (force_relocations) {
- *direct_code = -1;
- target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
- target_method->dex_method_index = method->GetDexMethodIndex();
- } else {
- *direct_code = compiler_->GetEntryPointOf(method);
- }
} else {
- // Direct pointers were required but none were available.
- VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
- }
- }
-}
-
-bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc,
- bool update_stats, bool enable_devirtualization,
- InvokeType* invoke_type, MethodReference* target_method,
- int* vtable_idx, uintptr_t* direct_code,
- uintptr_t* direct_method) {
- InvokeType orig_invoke_type = *invoke_type;
- int stats_flags = 0;
- ScopedObjectAccess soa(Thread::Current());
- // Try to resolve the method and compiling method's class.
- StackHandleScope<2> hs(soa.Self());
- Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache());
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
- soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
- uint32_t method_idx = target_method->dex_method_index;
- ArtMethod* resolved_method = ResolveMethod(
- soa, dex_cache, class_loader, mUnit, method_idx, orig_invoke_type);
- auto h_referrer_class = hs.NewHandle(resolved_method != nullptr ?
- ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit) : nullptr);
- bool result = false;
- if (resolved_method != nullptr) {
- *vtable_idx = GetResolvedMethodVTableIndex(resolved_method, orig_invoke_type);
-
- if (enable_devirtualization && mUnit->GetVerifiedMethod() != nullptr) {
- const MethodReference* devirt_target = mUnit->GetVerifiedMethod()->GetDevirtTarget(dex_pc);
-
- stats_flags = IsFastInvoke(
- soa, dex_cache, class_loader, mUnit, h_referrer_class.Get(), resolved_method,
- invoke_type, target_method, devirt_target, direct_code, direct_method);
- result = stats_flags != 0;
- } else {
- // Devirtualization not enabled. Inline IsFastInvoke(), dropping the devirtualization parts.
- if (UNLIKELY(h_referrer_class.Get() == nullptr) ||
- UNLIKELY(!h_referrer_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
- resolved_method, dex_cache.Get(),
- target_method->dex_method_index)) ||
- *invoke_type == kSuper) {
- // Slow path. (Without devirtualization, all super calls go slow path as well.)
- } else {
- // Sharpening failed so generate a regular resolved method dispatch.
- stats_flags = kFlagMethodResolved;
- GetCodeAndMethodForDirectCall(
- invoke_type, *invoke_type, false, h_referrer_class.Get(), resolved_method, &stats_flags,
- target_method, direct_code, direct_method);
- result = true;
- }
+ // Set the code and rely on the dex cache for the method.
+ *direct_code = force_relocations ? -1 : compiler_->GetEntryPointOf(method);
}
}
- if (!result) {
- // Conservative defaults.
- *vtable_idx = -1;
- *direct_code = 0u;
- *direct_method = 0u;
- }
- if (update_stats) {
- ProcessedInvoke(orig_invoke_type, stats_flags);
- }
- return result;
}
const VerifiedMethod* CompilerDriver::GetVerifiedMethod(const DexFile* dex_file,
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index ee21efa854..1f4c3aca34 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -328,16 +328,6 @@ class CompilerDriver {
ArtMethod* resolved_method, InvokeType type)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Can we fast-path an INVOKE? If no, returns 0. If yes, returns a non-zero opaque flags value
- // for ProcessedInvoke() and computes the necessary lowering info.
- int IsFastInvoke(
- ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
- mirror::Class* referrer_class, ArtMethod* resolved_method, InvokeType* invoke_type,
- MethodReference* target_method, const MethodReference* devirt_target,
- uintptr_t* direct_code, uintptr_t* direct_method)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Is method's class initialized for an invoke?
// For static invokes to determine whether we need to consider potential call to <clinit>().
// For non-static invokes, assuming a non-null reference, the class is always initialized.
@@ -371,14 +361,6 @@ class CompilerDriver {
REQUIRES_SHARED(Locks::mutator_lock_);
- // Can we fastpath a interface, super class or virtual method call? Computes method's vtable
- // index.
- bool ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc,
- bool update_stats, bool enable_devirtualization,
- InvokeType* type, MethodReference* target_method, int* vtable_idx,
- uintptr_t* direct_code, uintptr_t* direct_method)
- REQUIRES(!Locks::mutator_lock_);
-
const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;
bool IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc);
@@ -538,14 +520,10 @@ class CompilerDriver {
public: // TODO make private or eliminate.
// Compute constant code and method pointers when possible.
- void GetCodeAndMethodForDirectCall(/*out*/InvokeType* type,
- InvokeType sharp_type,
- bool no_guarantee_of_dex_cache_entry,
- const mirror::Class* referrer_class,
+ void GetCodeAndMethodForDirectCall(const mirror::Class* referrer_class,
ArtMethod* method,
- /*out*/int* stats_flags,
- MethodReference* target_method,
- uintptr_t* direct_code, uintptr_t* direct_method)
+ /* out */ uintptr_t* direct_code,
+ /* out */ uintptr_t* direct_method)
REQUIRES_SHARED(Locks::mutator_lock_);
private:
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index cf633df496..0f8cdbb19b 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -346,7 +346,7 @@ void CodeGenerator::GenerateInvokeUnresolvedRuntimeCall(HInvokeUnresolved* invok
// Initialize to anything to silent compiler warnings.
QuickEntrypointEnum entrypoint = kQuickInvokeStaticTrampolineWithAccessCheck;
- switch (invoke->GetOriginalInvokeType()) {
+ switch (invoke->GetInvokeType()) {
case kStatic:
entrypoint = kQuickInvokeStaticTrampolineWithAccessCheck;
break;
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index c0c798d862..85002045a3 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -515,7 +515,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> {
// otherwise return a fall-back info that should be used instead.
virtual HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) = 0;
+ HInvokeStaticOrDirect* invoke) = 0;
// Generate a call to a static or direct method.
virtual void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) = 0;
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index a052873afd..6be458ce26 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -6672,7 +6672,7 @@ void CodeGeneratorARM::GenerateReadBarrierForRootSlow(HInstruction* instruction,
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorARM::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) {
+ HInvokeStaticOrDirect* invoke) {
HInvokeStaticOrDirect::DispatchInfo dispatch_info = desired_dispatch_info;
// We disable pc-relative load when there is an irreducible loop, as the optimization
// is incompatible with it.
@@ -6686,7 +6686,7 @@ HInvokeStaticOrDirect::DispatchInfo CodeGeneratorARM::GetSupportedInvokeStaticOr
if (dispatch_info.code_ptr_location == HInvokeStaticOrDirect::CodePtrLocation::kCallPCRelative) {
const DexFile& outer_dex_file = GetGraph()->GetDexFile();
- if (&outer_dex_file != target_method.dex_file) {
+ if (&outer_dex_file != invoke->GetTargetMethod().dex_file) {
// Calls across dex files are more likely to exceed the available BL range,
// so use absolute patch with fixup if available and kCallArtMethod otherwise.
HInvokeStaticOrDirect::CodePtrLocation code_ptr_location =
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 424a1a1455..6416d40f7f 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -454,7 +454,7 @@ class CodeGeneratorARM : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index a29e9f3e80..7160607687 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -3544,7 +3544,7 @@ static bool TryGenerateIntrinsicCode(HInvoke* invoke, CodeGeneratorARM64* codege
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorARM64::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method ATTRIBUTE_UNUSED) {
+ HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) {
// On ARM64 we support all dispatch types.
return desired_dispatch_info;
}
@@ -3588,7 +3588,7 @@ void CodeGeneratorARM64::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invok
break;
case HInvokeStaticOrDirect::MethodLoadKind::kDexCachePcRelative: {
// Add ADRP with its PC-relative DexCache access patch.
- const DexFile& dex_file = *invoke->GetTargetMethod().dex_file;
+ const DexFile& dex_file = invoke->GetDexFile();
uint32_t element_offset = invoke->GetDexCacheArrayOffset();
vixl::aarch64::Label* adrp_label = NewPcRelativeDexCacheArrayPatch(dex_file, element_offset);
{
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index f1dc7eecb5..a15224578d 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -522,7 +522,7 @@ class CodeGeneratorARM64 : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index b06c84dd58..226f109bec 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -432,7 +432,7 @@ HLoadClass::LoadKind CodeGeneratorARMVIXL::GetSupportedLoadClassKind(
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorARMVIXL::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) {
+ HInvokeStaticOrDirect* invoke) {
TODO_VIXL32(FATAL);
return desired_dispatch_info;
}
diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h
index d0c2c85b6a..7b7118cb3e 100644
--- a/compiler/optimizing/code_generator_arm_vixl.h
+++ b/compiler/optimizing/code_generator_arm_vixl.h
@@ -363,7 +363,7 @@ class CodeGeneratorARMVIXL : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 2211ea3846..f560207d3e 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -4327,7 +4327,7 @@ Register CodeGeneratorMIPS::GetInvokeStaticOrDirectExtraParameter(HInvokeStaticO
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorMIPS::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method ATTRIBUTE_UNUSED) {
+ HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) {
HInvokeStaticOrDirect::DispatchInfo dispatch_info = desired_dispatch_info;
// We disable PC-relative load when there is an irreducible loop, as the optimization
// is incompatible with it.
diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h
index 553a7e6674..f943978b3b 100644
--- a/compiler/optimizing/code_generator_mips.h
+++ b/compiler/optimizing/code_generator_mips.h
@@ -395,7 +395,7 @@ class CodeGeneratorMIPS : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp);
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 5039fad708..a5e23511a4 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -2972,7 +2972,7 @@ HLoadClass::LoadKind CodeGeneratorMIPS64::GetSupportedLoadClassKind(
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorMIPS64::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method ATTRIBUTE_UNUSED) {
+ HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) {
switch (desired_dispatch_info.method_load_kind) {
case HInvokeStaticOrDirect::MethodLoadKind::kDirectAddressWithFixup:
case HInvokeStaticOrDirect::MethodLoadKind::kDexCachePcRelative:
diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h
index 2dd409a224..690eccb7d8 100644
--- a/compiler/optimizing/code_generator_mips64.h
+++ b/compiler/optimizing/code_generator_mips64.h
@@ -343,7 +343,7 @@ class CodeGeneratorMIPS64 : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
void GenerateVirtualCall(HInvokeVirtual* invoke, Location temp) OVERRIDE;
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index cc9fe832f1..47dfb2e921 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -4217,7 +4217,7 @@ void CodeGeneratorX86::GenerateMemoryBarrier(MemBarrierKind kind) {
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorX86::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method ATTRIBUTE_UNUSED) {
+ HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) {
HInvokeStaticOrDirect::DispatchInfo dispatch_info = desired_dispatch_info;
// We disable pc-relative load when there is an irreducible loop, as the optimization
@@ -4297,7 +4297,7 @@ Location CodeGeneratorX86::GenerateCalleeMethodStaticOrDirectCall(HInvokeStaticO
__ movl(temp.AsRegister<Register>(), Address(base_reg, kDummy32BitOffset));
// Bind a new fixup label at the end of the "movl" insn.
uint32_t offset = invoke->GetDexCacheArrayOffset();
- __ Bind(NewPcRelativeDexCacheArrayPatch(*invoke->GetTargetMethod().dex_file, offset));
+ __ Bind(NewPcRelativeDexCacheArrayPatch(invoke->GetDexFile(), offset));
break;
}
case HInvokeStaticOrDirect::MethodLoadKind::kDexCacheViaMethod: {
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index 5866e65d88..1ae9af3b94 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -402,7 +402,7 @@ class CodeGeneratorX86 : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
// Generate a call to a static or direct method.
Location GenerateCalleeMethodStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp);
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 1d87bf6198..59c0ca47f8 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -733,7 +733,7 @@ inline Condition X86_64FPCondition(IfCondition cond) {
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorX86_64::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method ATTRIBUTE_UNUSED) {
+ HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) {
switch (desired_dispatch_info.code_ptr_location) {
case HInvokeStaticOrDirect::CodePtrLocation::kCallDirectWithFixup:
case HInvokeStaticOrDirect::CodePtrLocation::kCallDirect:
@@ -775,7 +775,7 @@ Location CodeGeneratorX86_64::GenerateCalleeMethodStaticOrDirectCall(HInvokeStat
Address::Absolute(kDummy32BitOffset, /* no_rip */ false));
// Bind a new fixup label at the end of the "movl" insn.
uint32_t offset = invoke->GetDexCacheArrayOffset();
- __ Bind(NewPcRelativeDexCacheArrayPatch(*invoke->GetTargetMethod().dex_file, offset));
+ __ Bind(NewPcRelativeDexCacheArrayPatch(invoke->GetDexFile(), offset));
break;
}
case HInvokeStaticOrDirect::MethodLoadKind::kDexCacheViaMethod: {
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index 7108676b8e..594f05157b 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -399,7 +399,7 @@ class CodeGeneratorX86_64 : public CodeGenerator {
// otherwise return a fall-back info that should be used instead.
HInvokeStaticOrDirect::DispatchInfo GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
- MethodReference target_method) OVERRIDE;
+ HInvokeStaticOrDirect* invoke) OVERRIDE;
Location GenerateCalleeMethodStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp);
void GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke, Location temp) OVERRIDE;
diff --git a/compiler/optimizing/dex_cache_array_fixups_arm.cc b/compiler/optimizing/dex_cache_array_fixups_arm.cc
index 6ad9b07f1a..7010171c80 100644
--- a/compiler/optimizing/dex_cache_array_fixups_arm.cc
+++ b/compiler/optimizing/dex_cache_array_fixups_arm.cc
@@ -82,12 +82,10 @@ class DexCacheArrayFixupsVisitor : public HGraphVisitor {
// we need to add the dex cache arrays base as the special input.
if (invoke->HasPcRelativeDexCache() &&
!IsCallFreeIntrinsic<IntrinsicLocationsBuilderARM>(invoke, codegen_)) {
- // Initialize base for target method dex file if needed.
- MethodReference target_method = invoke->GetTargetMethod();
- HArmDexCacheArraysBase* base = GetOrCreateDexCacheArrayBase(*target_method.dex_file);
+ HArmDexCacheArraysBase* base = GetOrCreateDexCacheArrayBase(invoke->GetDexFile());
// Update the element offset in base.
- DexCacheArraysLayout layout(kArmPointerSize, target_method.dex_file);
- base->UpdateElementOffset(layout.MethodOffset(target_method.dex_method_index));
+ DexCacheArraysLayout layout(kArmPointerSize, &invoke->GetDexFile());
+ base->UpdateElementOffset(layout.MethodOffset(invoke->GetDexMethodIndex()));
// Add the special argument base to the method.
DCHECK(!invoke->HasCurrentMethodInput());
invoke->AddSpecialInput(base);
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index b3d5341de0..912ee29cdb 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -447,7 +447,7 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor {
void VisitInvokeUnresolved(HInvokeUnresolved* invoke) OVERRIDE {
VisitInvoke(invoke);
- StartAttributeStream("invoke_type") << invoke->GetOriginalInvokeType();
+ StartAttributeStream("invoke_type") << invoke->GetInvokeType();
}
void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE {
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index ce53134235..f21dc0e7e4 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -263,42 +263,24 @@ bool HInliner::TryInline(HInvoke* invoke_instruction) {
return false; // Don't bother to move further if we know the method is unresolved.
}
- uint32_t method_index = invoke_instruction->GetDexMethodIndex();
ScopedObjectAccess soa(Thread::Current());
+ uint32_t method_index = invoke_instruction->GetDexMethodIndex();
const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile();
VLOG(compiler) << "Try inlining " << PrettyMethod(method_index, caller_dex_file);
- ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
// We can query the dex cache directly. The verifier has populated it already.
- ArtMethod* resolved_method;
+ ArtMethod* resolved_method = invoke_instruction->GetResolvedMethod();
ArtMethod* actual_method = nullptr;
- if (invoke_instruction->IsInvokeStaticOrDirect()) {
- if (invoke_instruction->AsInvokeStaticOrDirect()->IsStringInit()) {
- VLOG(compiler) << "Not inlining a String.<init> method";
- return false;
- }
- MethodReference ref = invoke_instruction->AsInvokeStaticOrDirect()->GetTargetMethod();
- mirror::DexCache* const dex_cache = IsSameDexFile(caller_dex_file, *ref.dex_file)
- ? caller_compilation_unit_.GetDexCache().Get()
- : class_linker->FindDexCache(soa.Self(), *ref.dex_file);
- resolved_method = dex_cache->GetResolvedMethod(
- ref.dex_method_index, class_linker->GetImagePointerSize());
- // actual_method == resolved_method for direct or static calls.
- actual_method = resolved_method;
- } else {
- resolved_method = caller_compilation_unit_.GetDexCache().Get()->GetResolvedMethod(
- method_index, class_linker->GetImagePointerSize());
- if (resolved_method != nullptr) {
- // Check if we can statically find the method.
- actual_method = FindVirtualOrInterfaceTarget(invoke_instruction, resolved_method);
- }
- }
-
if (resolved_method == nullptr) {
- // TODO: Can this still happen?
- // Method cannot be resolved if it is in another dex file we do not have access to.
- VLOG(compiler) << "Method cannot be resolved " << PrettyMethod(method_index, caller_dex_file);
+ DCHECK(invoke_instruction->IsInvokeStaticOrDirect());
+ DCHECK(invoke_instruction->AsInvokeStaticOrDirect()->IsStringInit());
+ VLOG(compiler) << "Not inlining a String.<init> method";
return false;
+ } else if (invoke_instruction->IsInvokeStaticOrDirect()) {
+ actual_method = resolved_method;
+ } else {
+ // Check if we can statically find the method.
+ actual_method = FindVirtualOrInterfaceTarget(invoke_instruction, resolved_method);
}
if (actual_method != nullptr) {
@@ -763,9 +745,9 @@ bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ArtMethod* metho
// 2) We will not go to the conflict trampoline with an invoke-virtual.
// TODO: Consider sharpening once it is not dependent on the compiler driver.
const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile();
- uint32_t method_index = FindMethodIndexIn(
+ uint32_t dex_method_index = FindMethodIndexIn(
method, caller_dex_file, invoke_instruction->GetDexMethodIndex());
- if (method_index == DexFile::kDexNoIndex) {
+ if (dex_method_index == DexFile::kDexNoIndex) {
return false;
}
HInvokeVirtual* new_invoke = new (graph_->GetArena()) HInvokeVirtual(
@@ -773,7 +755,8 @@ bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ArtMethod* metho
invoke_instruction->GetNumberOfArguments(),
invoke_instruction->GetType(),
invoke_instruction->GetDexPc(),
- method_index,
+ dex_method_index,
+ method,
method->GetMethodIndex());
HInputsRef inputs = invoke_instruction->GetInputs();
for (size_t index = 0; index != inputs.size(); ++index) {
@@ -1122,7 +1105,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction,
}
}
- InvokeType invoke_type = invoke_instruction->GetOriginalInvokeType();
+ InvokeType invoke_type = invoke_instruction->GetInvokeType();
if (invoke_type == kInterface) {
// We have statically resolved the dispatch. To please the class linker
// at runtime, we change this call as if it was a virtual call.
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index d7e4c53df0..5a6a212cc9 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -785,8 +785,6 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
number_of_arguments++;
}
- MethodReference target_method(dex_file_, method_idx);
-
// Special handling for string init.
int32_t string_init_offset = 0;
bool is_string_init = compiler_driver_->IsStringInit(method_idx,
@@ -800,16 +798,17 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
dchecked_integral_cast<uint64_t>(string_init_offset),
0U
};
+ MethodReference target_method(dex_file_, method_idx);
HInvoke* invoke = new (arena_) HInvokeStaticOrDirect(
arena_,
number_of_arguments - 1,
Primitive::kPrimNot /*return_type */,
dex_pc,
method_idx,
- target_method,
+ nullptr,
dispatch_info,
invoke_type,
- kStatic /* optimized_invoke_type */,
+ target_method,
HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
return HandleStringInit(invoke,
number_of_vreg_arguments,
@@ -853,10 +852,9 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
dex_pc, resolved_method, method_idx, &clinit_check_requirement);
} else if (invoke_type == kSuper) {
if (IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) {
- // Update the target method to the one resolved. Note that this may be a no-op if
+ // Update the method index to the one resolved. Note that this may be a no-op if
// we resolved to the method referenced by the instruction.
method_idx = resolved_method->GetDexMethodIndex();
- target_method = MethodReference(dex_file_, method_idx);
}
}
@@ -866,15 +864,17 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
0u,
0U
};
+ MethodReference target_method(resolved_method->GetDexFile(),
+ resolved_method->GetDexMethodIndex());
invoke = new (arena_) HInvokeStaticOrDirect(arena_,
number_of_arguments,
return_type,
dex_pc,
method_idx,
- target_method,
+ resolved_method,
dispatch_info,
invoke_type,
- invoke_type,
+ target_method,
clinit_check_requirement);
} else if (invoke_type == kVirtual) {
ScopedObjectAccess soa(Thread::Current()); // Needed for the method index
@@ -883,15 +883,17 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
return_type,
dex_pc,
method_idx,
+ resolved_method,
resolved_method->GetMethodIndex());
} else {
DCHECK_EQ(invoke_type, kInterface);
- ScopedObjectAccess soa(Thread::Current()); // Needed for the method index
+ ScopedObjectAccess soa(Thread::Current()); // Needed for the IMT index.
invoke = new (arena_) HInvokeInterface(arena_,
number_of_arguments,
return_type,
dex_pc,
method_idx,
+ resolved_method,
resolved_method->GetImtIndex());
}
@@ -1103,7 +1105,7 @@ bool HInstructionBuilder::HandleInvoke(HInvoke* invoke,
size_t start_index = 0;
size_t argument_index = 0;
- if (invoke->GetOriginalInvokeType() != InvokeType::kStatic) { // Instance call.
+ if (invoke->GetInvokeType() != InvokeType::kStatic) { // Instance call.
uint32_t obj_reg = is_range ? register_index : args[0];
HInstruction* arg = is_unresolved
? LoadLocal(obj_reg, Primitive::kPrimNot)
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index b7878880d2..ff829af4c2 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1657,7 +1657,7 @@ void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke,
bool is_left,
Primitive::Type type) {
DCHECK(invoke->IsInvokeStaticOrDirect());
- DCHECK_EQ(invoke->GetOriginalInvokeType(), InvokeType::kStatic);
+ DCHECK_EQ(invoke->GetInvokeType(), InvokeType::kStatic);
HInstruction* value = invoke->InputAt(0);
HInstruction* distance = invoke->InputAt(1);
// Replace the invoke with an HRor.
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 418d59c6cb..4d4bbcf616 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -532,9 +532,7 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile
// inline. If the precise type is known, however, the instruction will be sharpened to an
// InvokeStaticOrDirect.
InvokeType intrinsic_type = GetIntrinsicInvokeType(intrinsic);
- InvokeType invoke_type = invoke->IsInvokeStaticOrDirect() ?
- invoke->AsInvokeStaticOrDirect()->GetOptimizedInvokeType() :
- invoke->IsInvokeVirtual() ? kVirtual : kSuper;
+ InvokeType invoke_type = invoke->GetInvokeType();
switch (intrinsic_type) {
case kStatic:
return (invoke_type == kStatic);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 6d207765e3..57ae555caa 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -3742,8 +3742,8 @@ class HInvoke : public HInstruction {
uint32_t GetDexMethodIndex() const { return dex_method_index_; }
const DexFile& GetDexFile() const { return GetEnvironment()->GetDexFile(); }
- InvokeType GetOriginalInvokeType() const {
- return GetPackedField<OriginalInvokeTypeField>();
+ InvokeType GetInvokeType() const {
+ return GetPackedField<InvokeTypeField>();
}
Intrinsics GetIntrinsic() const {
@@ -3777,21 +3777,22 @@ class HInvoke : public HInstruction {
bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; }
+ ArtMethod* GetResolvedMethod() const { return resolved_method_; }
+
DECLARE_ABSTRACT_INSTRUCTION(Invoke);
protected:
- static constexpr size_t kFieldOriginalInvokeType = kNumberOfGenericPackedBits;
- static constexpr size_t kFieldOriginalInvokeTypeSize =
+ static constexpr size_t kFieldInvokeType = kNumberOfGenericPackedBits;
+ static constexpr size_t kFieldInvokeTypeSize =
MinimumBitsToStore(static_cast<size_t>(kMaxInvokeType));
static constexpr size_t kFieldReturnType =
- kFieldOriginalInvokeType + kFieldOriginalInvokeTypeSize;
+ kFieldInvokeType + kFieldInvokeTypeSize;
static constexpr size_t kFieldReturnTypeSize =
MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast));
static constexpr size_t kFlagCanThrow = kFieldReturnType + kFieldReturnTypeSize;
static constexpr size_t kNumberOfInvokePackedBits = kFlagCanThrow + 1;
static_assert(kNumberOfInvokePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
- using OriginalInvokeTypeField =
- BitField<InvokeType, kFieldOriginalInvokeType, kFieldOriginalInvokeTypeSize>;
+ using InvokeTypeField = BitField<InvokeType, kFieldInvokeType, kFieldInvokeTypeSize>;
using ReturnTypeField = BitField<Primitive::Type, kFieldReturnType, kFieldReturnTypeSize>;
HInvoke(ArenaAllocator* arena,
@@ -3800,23 +3801,26 @@ class HInvoke : public HInstruction {
Primitive::Type return_type,
uint32_t dex_pc,
uint32_t dex_method_index,
- InvokeType original_invoke_type)
+ ArtMethod* resolved_method,
+ InvokeType invoke_type)
: HInstruction(
SideEffects::AllExceptGCDependency(), dex_pc), // Assume write/read on all fields/arrays.
number_of_arguments_(number_of_arguments),
+ resolved_method_(resolved_method),
inputs_(number_of_arguments + number_of_other_inputs,
arena->Adapter(kArenaAllocInvokeInputs)),
dex_method_index_(dex_method_index),
intrinsic_(Intrinsics::kNone),
intrinsic_optimizations_(0) {
SetPackedField<ReturnTypeField>(return_type);
- SetPackedField<OriginalInvokeTypeField>(original_invoke_type);
+ SetPackedField<InvokeTypeField>(invoke_type);
SetPackedFlag<kFlagCanThrow>(true);
}
void SetCanThrow(bool can_throw) { SetPackedFlag<kFlagCanThrow>(can_throw); }
uint32_t number_of_arguments_;
+ ArtMethod* const resolved_method_;
ArenaVector<HUserRecord<HInstruction*>> inputs_;
const uint32_t dex_method_index_;
Intrinsics intrinsic_;
@@ -3842,6 +3846,7 @@ class HInvokeUnresolved FINAL : public HInvoke {
return_type,
dex_pc,
dex_method_index,
+ nullptr,
invoke_type) {
}
@@ -3935,10 +3940,10 @@ class HInvokeStaticOrDirect FINAL : public HInvoke {
Primitive::Type return_type,
uint32_t dex_pc,
uint32_t method_index,
- MethodReference target_method,
+ ArtMethod* resolved_method,
DispatchInfo dispatch_info,
- InvokeType original_invoke_type,
- InvokeType optimized_invoke_type,
+ InvokeType invoke_type,
+ MethodReference target_method,
ClinitCheckRequirement clinit_check_requirement)
: HInvoke(arena,
number_of_arguments,
@@ -3950,10 +3955,10 @@ class HInvokeStaticOrDirect FINAL : public HInvoke {
return_type,
dex_pc,
method_index,
- original_invoke_type),
+ resolved_method,
+ invoke_type),
target_method_(target_method),
dispatch_info_(dispatch_info) {
- SetPackedField<OptimizedInvokeTypeField>(optimized_invoke_type);
SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement);
}
@@ -4017,14 +4022,6 @@ class HInvokeStaticOrDirect FINAL : public HInvoke {
uint32_t GetSpecialInputIndex() const { return GetNumberOfArguments(); }
bool HasSpecialInput() const { return GetNumberOfArguments() != InputCount(); }
- InvokeType GetOptimizedInvokeType() const {
- return GetPackedField<OptimizedInvokeTypeField>();
- }
-
- void SetOptimizedInvokeType(InvokeType invoke_type) {
- SetPackedField<OptimizedInvokeTypeField>(invoke_type);
- }
-
MethodLoadKind GetMethodLoadKind() const { return dispatch_info_.method_load_kind; }
CodePtrLocation GetCodePtrLocation() const { return dispatch_info_.code_ptr_location; }
bool IsRecursive() const { return GetMethodLoadKind() == MethodLoadKind::kRecursive; }
@@ -4046,8 +4043,6 @@ class HInvokeStaticOrDirect FINAL : public HInvoke {
}
}
bool HasDirectCodePtr() const { return GetCodePtrLocation() == CodePtrLocation::kCallDirect; }
- MethodReference GetTargetMethod() const { return target_method_; }
- void SetTargetMethod(MethodReference method) { target_method_ = method; }
int32_t GetStringInitOffset() const {
DCHECK(IsStringInit());
@@ -4075,7 +4070,11 @@ class HInvokeStaticOrDirect FINAL : public HInvoke {
// Is this instruction a call to a static method?
bool IsStatic() const {
- return GetOriginalInvokeType() == kStatic;
+ return GetInvokeType() == kStatic;
+ }
+
+ MethodReference GetTargetMethod() const {
+ return target_method_;
}
// Remove the HClinitCheck or the replacement HLoadClass (set as last input by
@@ -4117,26 +4116,18 @@ class HInvokeStaticOrDirect FINAL : public HInvoke {
void RemoveInputAt(size_t index);
private:
- static constexpr size_t kFieldOptimizedInvokeType = kNumberOfInvokePackedBits;
- static constexpr size_t kFieldOptimizedInvokeTypeSize =
- MinimumBitsToStore(static_cast<size_t>(kMaxInvokeType));
- static constexpr size_t kFieldClinitCheckRequirement =
- kFieldOptimizedInvokeType + kFieldOptimizedInvokeTypeSize;
+ static constexpr size_t kFieldClinitCheckRequirement = kNumberOfInvokePackedBits;
static constexpr size_t kFieldClinitCheckRequirementSize =
MinimumBitsToStore(static_cast<size_t>(ClinitCheckRequirement::kLast));
static constexpr size_t kNumberOfInvokeStaticOrDirectPackedBits =
kFieldClinitCheckRequirement + kFieldClinitCheckRequirementSize;
static_assert(kNumberOfInvokeStaticOrDirectPackedBits <= kMaxNumberOfPackedBits,
"Too many packed fields.");
- using OptimizedInvokeTypeField =
- BitField<InvokeType, kFieldOptimizedInvokeType, kFieldOptimizedInvokeTypeSize>;
using ClinitCheckRequirementField = BitField<ClinitCheckRequirement,
kFieldClinitCheckRequirement,
kFieldClinitCheckRequirementSize>;
- // The target method may refer to different dex file or method index than the original
- // invoke. This happens for sharpened calls and for calls where a method was redeclared
- // in derived class to increase visibility.
+ // Cached values of the resolved method, to avoid needing the mutator lock.
MethodReference target_method_;
DispatchInfo dispatch_info_;
@@ -4152,8 +4143,16 @@ class HInvokeVirtual FINAL : public HInvoke {
Primitive::Type return_type,
uint32_t dex_pc,
uint32_t dex_method_index,
+ ArtMethod* resolved_method,
uint32_t vtable_index)
- : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index, kVirtual),
+ : HInvoke(arena,
+ number_of_arguments,
+ 0u,
+ return_type,
+ dex_pc,
+ dex_method_index,
+ resolved_method,
+ kVirtual),
vtable_index_(vtable_index) {}
bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
@@ -4166,6 +4165,7 @@ class HInvokeVirtual FINAL : public HInvoke {
DECLARE_INSTRUCTION(InvokeVirtual);
private:
+ // Cached value of the resolved method, to avoid needing the mutator lock.
const uint32_t vtable_index_;
DISALLOW_COPY_AND_ASSIGN(HInvokeVirtual);
@@ -4178,8 +4178,16 @@ class HInvokeInterface FINAL : public HInvoke {
Primitive::Type return_type,
uint32_t dex_pc,
uint32_t dex_method_index,
+ ArtMethod* resolved_method,
uint32_t imt_index)
- : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index, kInterface),
+ : HInvoke(arena,
+ number_of_arguments,
+ 0u,
+ return_type,
+ dex_pc,
+ dex_method_index,
+ resolved_method,
+ kInterface),
imt_index_(imt_index) {}
bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
@@ -4193,6 +4201,7 @@ class HInvokeInterface FINAL : public HInvoke {
DECLARE_INSTRUCTION(InvokeInterface);
private:
+ // Cached value of the resolved method, to avoid needing the mutator lock.
const uint32_t imt_index_;
DISALLOW_COPY_AND_ASSIGN(HInvokeInterface);
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index e64c005410..abec55f25c 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -61,44 +61,28 @@ void HSharpening::ProcessInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
return;
}
- // TODO: Avoid CompilerDriver.
- InvokeType original_invoke_type = invoke->GetOriginalInvokeType();
- InvokeType optimized_invoke_type = original_invoke_type;
- MethodReference target_method(&graph_->GetDexFile(), invoke->GetDexMethodIndex());
- int vtable_idx;
- uintptr_t direct_code, direct_method;
- bool success = compiler_driver_->ComputeInvokeInfo(
- &compilation_unit_,
- invoke->GetDexPc(),
- false /* update_stats: already updated in builder */,
- true /* enable_devirtualization */,
- &optimized_invoke_type,
- &target_method,
- &vtable_idx,
- &direct_code,
- &direct_method);
- if (!success) {
- // TODO: try using kDexCachePcRelative. It's always a valid method load
- // kind as long as it's supported by the codegen
- return;
- }
- invoke->SetOptimizedInvokeType(optimized_invoke_type);
- invoke->SetTargetMethod(target_method);
+ HGraph* outer_graph = codegen_->GetGraph();
+ ArtMethod* compiling_method = graph_->GetArtMethod();
HInvokeStaticOrDirect::MethodLoadKind method_load_kind;
HInvokeStaticOrDirect::CodePtrLocation code_ptr_location;
uint64_t method_load_data = 0u;
uint64_t direct_code_ptr = 0u;
- HGraph* outer_graph = codegen_->GetGraph();
- if (target_method.dex_file == &outer_graph->GetDexFile() &&
- target_method.dex_method_index == outer_graph->GetMethodIdx()) {
+ if (invoke->GetResolvedMethod() == outer_graph->GetArtMethod()) {
+ DCHECK(outer_graph->GetArtMethod() != nullptr);
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRecursive;
code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallSelf;
} else {
- bool use_pc_relative_instructions =
- ((direct_method == 0u || direct_code == static_cast<uintptr_t>(-1))) &&
- ContainsElement(compiler_driver_->GetDexFilesForOatFile(), target_method.dex_file);
+ uintptr_t direct_code, direct_method;
+ {
+ ScopedObjectAccess soa(Thread::Current());
+ compiler_driver_->GetCodeAndMethodForDirectCall(
+ (compiling_method == nullptr) ? nullptr : compiling_method->GetDeclaringClass(),
+ invoke->GetResolvedMethod(),
+ &direct_code,
+ &direct_method);
+ }
if (direct_method != 0u) { // Should we use a direct pointer to the method?
// Note: For JIT, kDirectAddressWithFixup doesn't make sense at all and while
// kDirectAddress would be fine for image methods, we don't support it at the moment.
@@ -110,13 +94,12 @@ void HSharpening::ProcessInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kDirectAddressWithFixup;
}
} else { // Use dex cache.
- DCHECK_EQ(target_method.dex_file, &graph_->GetDexFile());
- if (use_pc_relative_instructions) { // Can we use PC-relative access to the dex cache arrays?
- DCHECK(!Runtime::Current()->UseJitCompilation());
+ if (!Runtime::Current()->UseJitCompilation()) {
+ // Use PC-relative access to the dex cache arrays.
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kDexCachePcRelative;
DexCacheArraysLayout layout(GetInstructionSetPointerSize(codegen_->GetInstructionSet()),
&graph_->GetDexFile());
- method_load_data = layout.MethodOffset(target_method.dex_method_index);
+ method_load_data = layout.MethodOffset(invoke->GetDexMethodIndex());
} else { // We must go through the ArtMethod's pointer to resolved methods.
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kDexCacheViaMethod;
}
@@ -125,10 +108,11 @@ void HSharpening::ProcessInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
// Note: For JIT, kCallPCRelative and kCallDirectWithFixup don't make sense at all and
// while kCallDirect would be fine for image methods, we don't support it at the moment.
DCHECK(!Runtime::Current()->UseJitCompilation());
+ const DexFile* dex_file_of_callee = invoke->GetTargetMethod().dex_file;
if (direct_code != static_cast<uintptr_t>(-1)) { // Is the code pointer known now?
code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallDirect;
direct_code_ptr = direct_code;
- } else if (use_pc_relative_instructions) {
+ } else if (ContainsElement(compiler_driver_->GetDexFilesForOatFile(), dex_file_of_callee)) {
// Use PC-relative calls for invokes within a multi-dex oat file.
code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallPCRelative;
} else { // The direct pointer will be known at link time.
@@ -151,8 +135,7 @@ void HSharpening::ProcessInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {
method_load_kind, code_ptr_location, method_load_data, direct_code_ptr
};
HInvokeStaticOrDirect::DispatchInfo dispatch_info =
- codegen_->GetSupportedInvokeStaticOrDirectDispatch(desired_dispatch_info,
- invoke->GetTargetMethod());
+ codegen_->GetSupportedInvokeStaticOrDirectDispatch(desired_dispatch_info, invoke);
invoke->SetDispatchInfo(dispatch_info);
}
diff --git a/test/555-checker-regression-x86const/build b/test/555-checker-regression-x86const/build
deleted file mode 100644
index 92ddfc9a58..0000000000
--- a/test/555-checker-regression-x86const/build
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Stop if something fails.
-set -e
-
-# We can't use src-ex testing infrastructure because src and src-ex are compiled
-# with javac independetely and can't share code (without reflection).
-
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-
-mkdir classes-ex
-mv classes/UnresolvedClass.class classes-ex
-
-if [ ${USE_JACK} = "true" ]; then
- jar cf classes.jill.jar -C classes .
- jar cf classes-ex.jill.jar -C classes-ex .
-
- ${JACK} --import classes.jill.jar --output-dex .
- zip $TEST_NAME.jar classes.dex
- ${JACK} --import classes-ex.jill.jar --output-dex .
- zip ${TEST_NAME}-ex.jar classes.dex
-else
- if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes
- zip $TEST_NAME.jar classes.dex
- ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 classes-ex
- zip ${TEST_NAME}-ex.jar classes.dex
- fi
-fi
diff --git a/test/555-checker-regression-x86const/expected.txt b/test/555-checker-regression-x86const/expected.txt
deleted file mode 100644
index e69de29bb2..0000000000
--- a/test/555-checker-regression-x86const/expected.txt
+++ /dev/null
diff --git a/test/555-checker-regression-x86const/info.txt b/test/555-checker-regression-x86const/info.txt
deleted file mode 100644
index c4037fa88f..0000000000
--- a/test/555-checker-regression-x86const/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Check that X86 FP constant-area handling handles intrinsics with CurrentMethod
-on the call.
diff --git a/test/555-checker-regression-x86const/run b/test/555-checker-regression-x86const/run
deleted file mode 100644
index 63fdb8c749..0000000000
--- a/test/555-checker-regression-x86const/run
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Use secondary switch to add secondary dex file to class path.
-exec ${RUN} "${@}" --secondary
diff --git a/test/555-checker-regression-x86const/src/Main.java b/test/555-checker-regression-x86const/src/Main.java
deleted file mode 100644
index 914cfde74f..0000000000
--- a/test/555-checker-regression-x86const/src/Main.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class Main extends UnresolvedClass {
-
- /// CHECK-START: float Main.callAbs(float) register (before)
- /// CHECK: <<CurrentMethod:[ij]\d+>> CurrentMethod
- /// CHECK: <<ParamValue:f\d+>> ParameterValue
- /// CHECK: InvokeStaticOrDirect [<<ParamValue>>,<<CurrentMethod>>] method_name:java.lang.Math.abs
- static public float callAbs(float f) {
- // An intrinsic invoke in a method that has unresolved references will still
- // have a CurrentMethod as an argument. The X86 pc_relative_fixups_x86 pass
- // must be able to handle Math.abs invokes that have a CurrentMethod, as both
- // the CurrentMethod and the HX86LoadFromConstantTable (for the bitmask)
- // expect to be in the 'SpecialInputIndex' input index.
- return Math.abs(f);
- }
-
- static public void main(String[] args) {
- expectEquals(callAbs(-6.5f), 6.5f);
- }
-
- public static void expectEquals(float expected, float result) {
- if (expected != result) {
- throw new Error("Expected: " + expected + ", found: " + result);
- }
- }
-}
diff --git a/test/555-checker-regression-x86const/src/Unresolved.java b/test/555-checker-regression-x86const/src/Unresolved.java
deleted file mode 100644
index e98bdbf8fb..0000000000
--- a/test/555-checker-regression-x86const/src/Unresolved.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class UnresolvedClass {
-}