diff options
Diffstat (limited to 'compiler/dex')
| -rw-r--r-- | compiler/dex/mir_analysis.cc | 4 | ||||
| -rw-r--r-- | compiler/dex/mir_graph.h | 5 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.cc | 87 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.h | 17 | ||||
| -rw-r--r-- | compiler/dex/quick/quick_compiler.cc | 8 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/assemble_x86.cc | 1 | ||||
| -rwxr-xr-x | compiler/dex/quick/x86/target_x86.cc | 32 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/x86_lir.h | 1 | ||||
| -rw-r--r-- | compiler/dex/quick_compiler_callbacks.cc | 12 | ||||
| -rw-r--r-- | compiler/dex/quick_compiler_callbacks.h | 2 | ||||
| -rw-r--r-- | compiler/dex/type_inference_test.cc | 2 | ||||
| -rw-r--r-- | compiler/dex/verification_results.cc | 9 | ||||
| -rw-r--r-- | compiler/dex/verification_results.h | 2 |
13 files changed, 142 insertions, 40 deletions
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc index 39f8ee8f7e..18ce563fc2 100644 --- a/compiler/dex/mir_analysis.cc +++ b/compiler/dex/mir_analysis.cc @@ -1430,8 +1430,4 @@ void MIRGraph::DoCacheMethodLoweringInfo() { method_lowering_infos_.data(), count); } -bool MIRGraph::SkipCompilationByName(const std::string& methodname) { - return cu_->compiler_driver->SkipCompilation(methodname); -} - } // namespace art diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index 2da8a98f00..3191fe9d57 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -564,11 +564,6 @@ class MIRGraph { bool SkipCompilation(std::string* skip_message); /* - * Should we skip the compilation of this method based on its name? - */ - bool SkipCompilationByName(const std::string& methodname); - - /* * Parse dex method and add MIR at current insert point. Returns id (which is * actually the index of the method in the m_units_ array). */ diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc index eaf2408763..f48947d537 100644 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ b/compiler/dex/quick/dex_file_method_inliner.cc @@ -50,6 +50,23 @@ static constexpr bool kIntrinsicIsStatic[] = { true, // kIntrinsicMinMaxLong true, // kIntrinsicMinMaxFloat true, // kIntrinsicMinMaxDouble + true, // kIntrinsicCos + true, // kIntrinsicSin + true, // kIntrinsicAcos + true, // kIntrinsicAsin + true, // kIntrinsicAtan + true, // kIntrinsicAtan2 + true, // kIntrinsicCbrt + true, // kIntrinsicCosh + true, // kIntrinsicExp + true, // kIntrinsicExpm1 + true, // kIntrinsicHypot + true, // kIntrinsicLog + true, // kIntrinsicLog10 + true, // kIntrinsicNextAfter + true, // kIntrinsicSinh + true, // kIntrinsicTan + true, // kIntrinsicTanh true, // kIntrinsicSqrt true, // kIntrinsicCeil true, // kIntrinsicFloor @@ -95,6 +112,23 @@ static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxInt], "MinMaxInt must be static static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxLong], "MinMaxLong_must_be_static"); static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], "MinMaxFloat_must_be_static"); static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], "MinMaxDouble_must_be_static"); +static_assert(kIntrinsicIsStatic[kIntrinsicCos], "Cos must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicSin], "Sin must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicAcos], "Acos must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicAsin], "Asin must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicAtan], "Atan must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicAtan2], "Atan2 must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicCbrt], "Cbrt must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicCosh], "Cosh must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicExp], "Exp must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicExpm1], "Expm1 must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicHypot], "Hypot must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicLog], "Log must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicLog10], "Log10 must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicNextAfter], "NextAfter must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicSinh], "Sinh must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicTan], "Tan must be static"); +static_assert(kIntrinsicIsStatic[kIntrinsicTanh], "Tanh must be static"); static_assert(kIntrinsicIsStatic[kIntrinsicSqrt], "Sqrt must be static"); static_assert(kIntrinsicIsStatic[kIntrinsicCeil], "Ceil must be static"); static_assert(kIntrinsicIsStatic[kIntrinsicFloor], "Floor must be static"); @@ -196,6 +230,23 @@ const char* const DexFileMethodInliner::kNameCacheNames[] = { "abs", // kNameCacheAbs "max", // kNameCacheMax "min", // kNameCacheMin + "cos", // kNameCacheCos + "sin", // kNameCacheSin + "acos", // kNameCacheAcos + "asin", // kNameCacheAsin + "atan", // kNameCacheAtan + "atan2", // kNameCacheAtan2 + "cbrt", // kNameCacheCbrt + "cosh", // kNameCacheCosh + "exp", // kNameCacheExp + "expm1", // kNameCacheExpm1 + "hypot", // kNameCacheHypot + "log", // kNameCacheLog + "log10", // kNameCacheLog10 + "nextAfter", // kNameCacheNextAfter + "sinh", // kNameCacheSinh + "tan", // kNameCacheTan + "tanh", // kNameCacheTanh "sqrt", // kNameCacheSqrt "ceil", // kNameCacheCeil "floor", // kNameCacheFloor @@ -425,6 +476,23 @@ const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods INTRINSIC(JavaLangMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax), INTRINSIC(JavaLangStrictMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax), + INTRINSIC(JavaLangMath, Cos, D_D, kIntrinsicCos, 0), + INTRINSIC(JavaLangMath, Sin, D_D, kIntrinsicSin, 0), + INTRINSIC(JavaLangMath, Acos, D_D, kIntrinsicAcos, 0), + INTRINSIC(JavaLangMath, Asin, D_D, kIntrinsicAsin, 0), + INTRINSIC(JavaLangMath, Atan, D_D, kIntrinsicAtan, 0), + INTRINSIC(JavaLangMath, Atan2, DD_D, kIntrinsicAtan2, 0), + INTRINSIC(JavaLangMath, Cbrt, D_D, kIntrinsicCbrt, 0), + INTRINSIC(JavaLangMath, Cosh, D_D, kIntrinsicCosh, 0), + INTRINSIC(JavaLangMath, Exp, D_D, kIntrinsicExp, 0), + INTRINSIC(JavaLangMath, Expm1, D_D, kIntrinsicExpm1, 0), + INTRINSIC(JavaLangMath, Hypot, DD_D, kIntrinsicHypot, 0), + INTRINSIC(JavaLangMath, Log, D_D, kIntrinsicLog, 0), + INTRINSIC(JavaLangMath, Log10, D_D, kIntrinsicLog10, 0), + INTRINSIC(JavaLangMath, NextAfter, DD_D, kIntrinsicNextAfter, 0), + INTRINSIC(JavaLangMath, Sinh, D_D, kIntrinsicSinh, 0), + INTRINSIC(JavaLangMath, Tan, D_D, kIntrinsicTan, 0), + INTRINSIC(JavaLangMath, Tanh, D_D, kIntrinsicTanh, 0), INTRINSIC(JavaLangMath, Sqrt, D_D, kIntrinsicSqrt, 0), INTRINSIC(JavaLangStrictMath, Sqrt, D_D, kIntrinsicSqrt, 0), @@ -603,6 +671,25 @@ bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) { return backend->GenInlinedMinMaxFP(info, intrinsic.d.data & kIntrinsicFlagMin, false /* is_double */); case kIntrinsicMinMaxDouble: return backend->GenInlinedMinMaxFP(info, intrinsic.d.data & kIntrinsicFlagMin, true /* is_double */); + case kIntrinsicCos: + case kIntrinsicSin: + case kIntrinsicAcos: + case kIntrinsicAsin: + case kIntrinsicAtan: + case kIntrinsicAtan2: + case kIntrinsicCbrt: + case kIntrinsicCosh: + case kIntrinsicExp: + case kIntrinsicExpm1: + case kIntrinsicHypot: + case kIntrinsicLog: + case kIntrinsicLog10: + case kIntrinsicNextAfter: + case kIntrinsicSinh: + case kIntrinsicTan: + case kIntrinsicTanh: + // Not implemented in Quick. + return false; case kIntrinsicSqrt: return backend->GenInlinedSqrt(info); case kIntrinsicCeil: diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h index 5ce110c120..ac70577b48 100644 --- a/compiler/dex/quick/dex_file_method_inliner.h +++ b/compiler/dex/quick/dex_file_method_inliner.h @@ -162,6 +162,23 @@ class DexFileMethodInliner { kNameCacheAbs, kNameCacheMax, kNameCacheMin, + kNameCacheCos, + kNameCacheSin, + kNameCacheAcos, + kNameCacheAsin, + kNameCacheAtan, + kNameCacheAtan2, + kNameCacheCbrt, + kNameCacheCosh, + kNameCacheExp, + kNameCacheExpm1, + kNameCacheHypot, + kNameCacheLog, + kNameCacheLog10, + kNameCacheNextAfter, + kNameCacheSinh, + kNameCacheTan, + kNameCacheTanh, kNameCacheSqrt, kNameCacheCeil, kNameCacheFloor, diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc index 05dde9f649..3260a7a050 100644 --- a/compiler/dex/quick/quick_compiler.cc +++ b/compiler/dex/quick/quick_compiler.cc @@ -780,14 +780,6 @@ CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item, PassDriverMEOpts pass_driver(GetPreOptPassManager(), GetPostOptPassManager(), &cu); pass_driver.Launch(); - /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */ - if (cu.compiler_driver->ProfilePresent() - && !cu.mir_graph->MethodIsLeaf() - && cu.mir_graph->SkipCompilationByName(PrettyMethod(method_idx, dex_file))) { - cu.EndTiming(); - return nullptr; - } - if (cu.enable_debug & (1 << kDebugDumpCheckStats)) { cu.mir_graph->DumpCheckStats(); } diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc index e5d3841b14..1c2a619020 100644 --- a/compiler/dex/quick/x86/assemble_x86.cc +++ b/compiler/dex/quick/x86/assemble_x86.cc @@ -508,6 +508,7 @@ ENCODING_MAP(Cmp, IS_LOAD, 0, 0, { kX86Lfence, kReg, NO_OPERAND, { 0, 0, 0x0F, 0xAE, 0, 5, 0, 0, false }, "Lfence", "" }, { kX86Mfence, kReg, NO_OPERAND, { 0, 0, 0x0F, 0xAE, 0, 6, 0, 0, false }, "Mfence", "" }, { kX86Sfence, kReg, NO_OPERAND, { 0, 0, 0x0F, 0xAE, 0, 7, 0, 0, false }, "Sfence", "" }, + { kX86LockAdd32MI8, kMemImm, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0xF0, 0, 0x83, 0x0, 0x0, 0, 0, 1, false }, "LockAdd32MI8", "[!0r+!1d],!2d" }, EXT_0F_ENCODING_MAP(Imul16, 0x66, 0xAF, REG_USE0 | REG_DEF0 | SETS_CCODES), EXT_0F_ENCODING_MAP(Imul32, 0x00, 0xAF, REG_USE0 | REG_DEF0 | SETS_CCODES), diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 75f3fef599..4ff79935d7 100755 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -20,7 +20,7 @@ #include <inttypes.h> #include <string> -#include "arch/instruction_set_features.h" +#include "arch/x86/instruction_set_features_x86.h" #include "art_method.h" #include "backend_x86.h" #include "base/logging.h" @@ -585,6 +585,8 @@ bool X86Mir2Lir::ProvidesFullMemoryBarrier(X86OpCode opcode) { case kX86LockCmpxchgAR: case kX86LockCmpxchg64M: case kX86LockCmpxchg64A: + case kX86LockCmpxchg64AR: + case kX86LockAdd32MI8: case kX86XchgMR: case kX86Mfence: // Atomic memory instructions provide full barrier. @@ -598,7 +600,9 @@ bool X86Mir2Lir::ProvidesFullMemoryBarrier(X86OpCode opcode) { } bool X86Mir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { - if (!cu_->compiler_driver->GetInstructionSetFeatures()->IsSmp()) { + const X86InstructionSetFeatures* features = + cu_->compiler_driver->GetInstructionSetFeatures()->AsX86InstructionSetFeatures(); + if (!features->IsSmp()) { return false; } // Start off with using the last LIR as the barrier. If it is not enough, then we will update it. @@ -610,20 +614,34 @@ bool X86Mir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { * All other barriers (LoadAny, AnyStore, StoreStore) are nops due to the x86 memory model. * For those cases, all we need to ensure is that there is a scheduling barrier in place. */ + const RegStorage rs_rSP = cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32; + bool use_locked_add = features->PrefersLockedAddSynchronization(); if (barrier_kind == kAnyAny) { - // If no LIR exists already that can be used a barrier, then generate an mfence. + // If no LIR exists already that can be used a barrier, then generate a barrier. if (mem_barrier == nullptr) { - mem_barrier = NewLIR0(kX86Mfence); + if (use_locked_add) { + mem_barrier = NewLIR3(kX86LockAdd32MI8, rs_rSP.GetReg(), 0, 0); + } else { + mem_barrier = NewLIR0(kX86Mfence); + } ret = true; } - // If last instruction does not provide full barrier, then insert an mfence. + // If last instruction does not provide full barrier, then insert a barrier. if (ProvidesFullMemoryBarrier(static_cast<X86OpCode>(mem_barrier->opcode)) == false) { - mem_barrier = NewLIR0(kX86Mfence); + if (use_locked_add) { + mem_barrier = NewLIR3(kX86LockAdd32MI8, rs_rSP.GetReg(), 0, 0); + } else { + mem_barrier = NewLIR0(kX86Mfence); + } ret = true; } } else if (barrier_kind == kNTStoreStore) { - mem_barrier = NewLIR0(kX86Sfence); + if (use_locked_add) { + mem_barrier = NewLIR3(kX86LockAdd32MI8, rs_rSP.GetReg(), 0, 0); + } else { + mem_barrier = NewLIR0(kX86Sfence); + } ret = true; } diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h index d6a6a60d3d..8cd6574443 100644 --- a/compiler/dex/quick/x86/x86_lir.h +++ b/compiler/dex/quick/x86/x86_lir.h @@ -606,6 +606,7 @@ enum X86OpCode { // load-from-memory and store-to-memory instructions kX86Sfence, // memory barrier to serialize all previous // store-to-memory instructions + kX86LockAdd32MI8, // locked add used to serialize memory instructions Binary0fOpCode(kX86Imul16), // 16bit multiply Binary0fOpCode(kX86Imul32), // 32bit multiply Binary0fOpCode(kX86Imul64), // 64bit multiply diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc index 03bda78498..2532bda632 100644 --- a/compiler/dex/quick_compiler_callbacks.cc +++ b/compiler/dex/quick_compiler_callbacks.cc @@ -22,14 +22,10 @@ namespace art { -bool QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) { - bool result = verification_results_->ProcessVerifiedMethod(verifier); - if (result) { - MethodReference ref = verifier->GetMethodReference(); - method_inliner_map_->GetMethodInliner(ref.dex_file) - ->AnalyseMethodCode(verifier); - } - return result; +void QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) { + verification_results_->ProcessVerifiedMethod(verifier); + MethodReference ref = verifier->GetMethodReference(); + method_inliner_map_->GetMethodInliner(ref.dex_file)->AnalyseMethodCode(verifier); } void QuickCompilerCallbacks::ClassRejected(ClassReference ref) { diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h index 03bf57bded..4f5ea766d8 100644 --- a/compiler/dex/quick_compiler_callbacks.h +++ b/compiler/dex/quick_compiler_callbacks.h @@ -37,7 +37,7 @@ class QuickCompilerCallbacks FINAL : public CompilerCallbacks { ~QuickCompilerCallbacks() { } - bool MethodVerified(verifier::MethodVerifier* verifier) + void MethodVerified(verifier::MethodVerifier* verifier) SHARED_REQUIRES(Locks::mutator_lock_) OVERRIDE; void ClassRejected(ClassReference ref) OVERRIDE; diff --git a/compiler/dex/type_inference_test.cc b/compiler/dex/type_inference_test.cc index 528a18cc99..e2c0d32f97 100644 --- a/compiler/dex/type_inference_test.cc +++ b/compiler/dex/type_inference_test.cc @@ -253,7 +253,7 @@ class TypeInferenceTest : public testing::Test { &cu_, cu_.class_loader, cu_.class_linker, *cu_.dex_file, nullptr /* code_item not used */, 0u /* class_def_idx not used */, 0u /* method_index not used */, cu_.access_flags, nullptr /* verified_method not used */, - NullHandle<mirror::DexCache>())); + ScopedNullHandle<mirror::DexCache>())); cu_.mir_graph->current_method_ = 0u; code_item_ = static_cast<DexFile::CodeItem*>( cu_.arena.Alloc(sizeof(DexFile::CodeItem), kArenaAllocMisc)); diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 65b0ad6400..dd24220e0e 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -44,14 +44,14 @@ VerificationResults::~VerificationResults() { } } -bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { +void VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) { DCHECK(method_verifier != nullptr); MethodReference ref = method_verifier->GetMethodReference(); bool compile = IsCandidateForCompilation(ref, method_verifier->GetAccessFlags()); const VerifiedMethod* verified_method = VerifiedMethod::Create(method_verifier, compile); if (verified_method == nullptr) { - // Do not report an error to the verifier. We'll just punt this later. - return true; + // We'll punt this later. + return; } WriterMutexLock mu(Thread::Current(), verified_methods_lock_); @@ -69,11 +69,10 @@ bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method // is unsafe to replace the existing one since the JIT may be using it to generate a // native GC map. delete verified_method; - return true; + return; } verified_methods_.Put(ref, verified_method); DCHECK(verified_methods_.find(ref) != verified_methods_.end()); - return true; } const VerifiedMethod* VerificationResults::GetVerifiedMethod(MethodReference ref) { diff --git a/compiler/dex/verification_results.h b/compiler/dex/verification_results.h index 9934f6b13b..da80bf07db 100644 --- a/compiler/dex/verification_results.h +++ b/compiler/dex/verification_results.h @@ -42,7 +42,7 @@ class VerificationResults { explicit VerificationResults(const CompilerOptions* compiler_options); ~VerificationResults(); - bool ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) + void ProcessVerifiedMethod(verifier::MethodVerifier* method_verifier) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!verified_methods_lock_); |