diff options
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.cc | 24 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.h | 12 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_to_method_inliner_map.cc | 37 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_to_method_inliner_map.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/assemble_x86.cc | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/fp_x86.cc | 10 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/x86_lir.h | 2 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 8 | ||||
| -rw-r--r-- | runtime/arch/x86/entrypoints_init_x86.cc | 1 | ||||
| -rw-r--r-- | runtime/locks.h | 2 | ||||
| -rw-r--r-- | runtime/native/dalvik_system_Zygote.cc | 21 | ||||
| -rw-r--r-- | runtime/verifier/method_verifier.cc | 38 |
14 files changed, 102 insertions, 61 deletions
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc index b21e37e13d..ba98225024 100644 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ b/compiler/dex/quick/dex_file_method_inliner.cc @@ -16,6 +16,10 @@ #include <algorithm> #include "base/macros.h" +#include "base/mutex.h" +#include "base/mutex-inl.h" +#include "thread.h" +#include "thread-inl.h" #include "dex/mir_graph.h" #include "dex_file_method_inliner.h" @@ -228,7 +232,8 @@ const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods }; DexFileMethodInliner::DexFileMethodInliner() - : dex_file_(NULL) { + : lock_("DexFileMethodInliner lock", kDexFileMethodInlinerLock), + dex_file_(NULL) { COMPILE_ASSERT(kClassCacheFirst == 0, kClassCacheFirst_not_0); COMPILE_ASSERT(arraysize(kClassCacheNames) == kClassCacheLast, bad_arraysize_kClassCacheNames); COMPILE_ASSERT(kNameCacheFirst == 0, kNameCacheFirst_not_0); @@ -240,16 +245,21 @@ DexFileMethodInliner::DexFileMethodInliner() DexFileMethodInliner::~DexFileMethodInliner() { } -bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index) const { +bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index) { + ReaderMutexLock mu(Thread::Current(), lock_); return intrinsics_.find(method_index) != intrinsics_.end(); } -bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) const { - auto it = intrinsics_.find(info->index); - if (it == intrinsics_.end()) { - return false; +bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) { + Intrinsic intrinsic; + { + ReaderMutexLock mu(Thread::Current(), lock_); + auto it = intrinsics_.find(info->index); + if (it == intrinsics_.end()) { + return false; + } + intrinsic = it->second; } - const Intrinsic& intrinsic = it->second; switch (intrinsic.opcode) { case kIntrinsicDoubleCvt: return backend->GenInlinedDoubleCvt(info); diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h index 948f4bbe56..9198f2a29d 100644 --- a/compiler/dex/quick/dex_file_method_inliner.h +++ b/compiler/dex/quick/dex_file_method_inliner.h @@ -19,6 +19,9 @@ #include <stdint.h> #include <map> +#include "base/mutex.h" +#include "base/macros.h" +#include "locks.h" namespace art { @@ -95,12 +98,12 @@ class DexFileMethodInliner { /** * Check whether a particular method index corresponds to an intrinsic function. */ - bool IsIntrinsic(uint32_t method_index) const; + bool IsIntrinsic(uint32_t method_index) LOCKS_EXCLUDED(lock_); /** * Generate code for an intrinsic function invocation. */ - bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) const; + bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) LOCKS_EXCLUDED(lock_); private: /** @@ -300,14 +303,15 @@ class DexFileMethodInliner { * * Only DexFileToMethodInlinerMap may call this function to initialize the inliner. */ - void FindIntrinsics(const DexFile* dex_file); + void FindIntrinsics(const DexFile* dex_file) EXCLUSIVE_LOCKS_REQUIRED(lock_); friend class DexFileToMethodInlinerMap; + ReaderWriterMutex lock_; /* * Maps method indexes (for the particular DexFile) to Intrinsic defintions. */ - std::map<uint32_t, Intrinsic> intrinsics_; + std::map<uint32_t, Intrinsic> intrinsics_ GUARDED_BY(lock_); const DexFile* dex_file_; DISALLOW_COPY_AND_ASSIGN(DexFileMethodInliner); diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.cc b/compiler/dex/quick/dex_file_to_method_inliner_map.cc index 0107ed3ccb..2fec183289 100644 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.cc +++ b/compiler/dex/quick/dex_file_to_method_inliner_map.cc @@ -28,7 +28,7 @@ namespace art { DexFileToMethodInlinerMap::DexFileToMethodInlinerMap() - : lock_("inline_helper_mutex") { + : lock_("DexFileToMethodInlinerMap lock", kDexFileToMethodInlinerMapLock) { } DexFileToMethodInlinerMap::~DexFileToMethodInlinerMap() { @@ -37,26 +37,37 @@ DexFileToMethodInlinerMap::~DexFileToMethodInlinerMap() { } } -const DexFileMethodInliner& DexFileToMethodInlinerMap::GetMethodInliner(const DexFile* dex_file) { +DexFileMethodInliner* DexFileToMethodInlinerMap::GetMethodInliner(const DexFile* dex_file) { Thread* self = Thread::Current(); { - ReaderMutexLock lock(self, lock_); + ReaderMutexLock mu(self, lock_); auto it = inliners_.find(dex_file); if (it != inliners_.end()) { - return *it->second; + return it->second; } } - WriterMutexLock lock(self, lock_); - DexFileMethodInliner** inliner = &inliners_[dex_file]; // inserts new entry if not found - if (*inliner) { - return **inliner; + // We need to acquire our lock_ to modify inliners_ but we want to release it + // before we initialize the new inliner. However, we need to acquire the + // new inliner's lock_ before we release our lock_ to prevent another thread + // from using the uninitialized inliner. This requires explicit calls to + // ExclusiveLock()/ExclusiveUnlock() on one of the locks, the other one + // can use WriterMutexLock. + DexFileMethodInliner* locked_inliner; + { + WriterMutexLock mu(self, lock_); + DexFileMethodInliner** inliner = &inliners_[dex_file]; // inserts new entry if not found + if (*inliner) { + return *inliner; + } + *inliner = new DexFileMethodInliner; + DCHECK(*inliner != nullptr); + locked_inliner = *inliner; + locked_inliner->lock_.ExclusiveLock(self); // Acquire inliner's lock_ before releasing lock_. } - *inliner = new DexFileMethodInliner(); - DCHECK(*inliner != nullptr); - // TODO: per-dex file locking for the intrinsics container filling. - (*inliner)->FindIntrinsics(dex_file); - return **inliner; + locked_inliner->FindIntrinsics(dex_file); + locked_inliner->lock_.ExclusiveUnlock(self); + return locked_inliner; } } // namespace art diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.h b/compiler/dex/quick/dex_file_to_method_inliner_map.h index 476f002bb5..6d5b8893c5 100644 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.h +++ b/compiler/dex/quick/dex_file_to_method_inliner_map.h @@ -40,7 +40,7 @@ class DexFileToMethodInlinerMap { DexFileToMethodInlinerMap(); ~DexFileToMethodInlinerMap(); - const DexFileMethodInliner& GetMethodInliner(const DexFile* dex_file) LOCKS_EXCLUDED(lock_); + DexFileMethodInliner* GetMethodInliner(const DexFile* dex_file) LOCKS_EXCLUDED(lock_); private: ReaderWriterMutex lock_; diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index e66d4ea52c..ee6f9c8fe9 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -1242,7 +1242,7 @@ void Mir2Lir::GenInvoke(CallInfo* info) { if (inliner_ == nullptr) { QuickCompilerContext* context = reinterpret_cast<QuickCompilerContext*>( cu_->compiler_driver->GetCompilerContext()); - inliner_ = &context->GetInlinerMap()->GetMethodInliner(cu_->dex_file); + inliner_ = context->GetInlinerMap()->GetMethodInliner(cu_->dex_file); } if (inliner_->GenIntrinsic(this, info)) { return; diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 2a54eb32cc..8415cbfb6d 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -827,7 +827,7 @@ class Mir2Lir : public Backend { LIR* first_lir_insn_; LIR* last_lir_insn_; // Lazily retrieved method inliner for intrinsics. - const DexFileMethodInliner* inliner_; + DexFileMethodInliner* inliner_; }; // Class Mir2Lir } // namespace art diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc index 96dc6ee7d1..0ecc0915fa 100644 --- a/compiler/dex/quick/x86/assemble_x86.cc +++ b/compiler/dex/quick/x86/assemble_x86.cc @@ -288,6 +288,8 @@ ENCODING_MAP(Cmp, IS_LOAD, 0, 0, { kX86PsrlqRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x73, 0, 2, 0, 1 }, "PsrlqRI", "!0r,!1d" }, { kX86PsllqRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x73, 0, 6, 0, 1 }, "PsllqRI", "!0r,!1d" }, + { kX86SqrtsdRR, kRegReg, IS_BINARY_OP | REG_DEF0_USE1, { 0xF2, 0, 0x0F, 0x51, 0, 0, 0, 0 }, "SqrtsdRR", "!0r,!1r" }, + { kX86FstpdM, kMem, IS_STORE | IS_BINARY_OP | REG_USE0, { 0x0, 0, 0xDD, 0x00, 0, 3, 0, 0 }, "FstpdM", "[!0r,!1d]" }, EXT_0F_ENCODING_MAP(Movdxr, 0x66, 0x6E, REG_DEF0), { kX86MovdrxRR, kRegRegStore, IS_BINARY_OP | REG_DEF0 | REG_USE01, { 0x66, 0, 0x0F, 0x7E, 0, 0, 0, 0 }, "MovdrxRR", "!0r,!1r" }, diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc index c9d6bfc8cc..1731703a3f 100644 --- a/compiler/dex/quick/x86/fp_x86.cc +++ b/compiler/dex/quick/x86/fp_x86.cc @@ -369,8 +369,14 @@ void X86Mir2Lir::GenNegDouble(RegLocation rl_dest, RegLocation rl_src) { } bool X86Mir2Lir::GenInlinedSqrt(CallInfo* info) { - DCHECK_NE(cu_->instruction_set, kThumb2); - return false; + RegLocation rl_src = info->args[0]; + RegLocation rl_dest = InlineTargetWide(info); // double place for result + rl_src = LoadValueWide(rl_src, kFPReg); + RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true); + NewLIR2(kX86SqrtsdRR, S2d(rl_result.low_reg, rl_result.high_reg), + S2d(rl_src.low_reg, rl_src.high_reg)); + StoreValueWide(rl_dest, rl_result); + return true; } diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h index 5fe76fe2f9..a2d5c3e402 100644 --- a/compiler/dex/quick/x86/x86_lir.h +++ b/compiler/dex/quick/x86/x86_lir.h @@ -348,6 +348,8 @@ enum X86OpCode { Binary0fOpCode(kX86Divss), // float divide kX86PsrlqRI, // right shift of floating point registers kX86PsllqRI, // left shift of floating point registers + kX86SqrtsdRR, // sqrt of floating point register + kX86FstpdM, // Store and pop top x87 fp stack Binary0fOpCode(kX86Movdxr), // move into xmm from gpr kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR, // move into reg from xmm kX86Set8R, kX86Set8M, kX86Set8A, // set byte depending on condition operand diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 43ed28c762..af18c05fbb 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -284,10 +284,10 @@ class AOTCompilationStats { }; extern "C" void ArtInitCompilerContext(art::CompilerDriver& driver); -extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver& compiler); +extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver& driver); extern "C" void ArtUnInitCompilerContext(art::CompilerDriver& driver); -extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver& compiler); +extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver& driver); extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver, const art::DexFile::CodeItem* code_item, @@ -1384,11 +1384,9 @@ class ParallelCompilationManager { self->AssertNoPendingException(); CHECK_GT(work_units, 0U); - std::vector<ForAllClosure*> closures(work_units); index_ = begin; for (size_t i = 0; i < work_units; ++i) { - closures[i] = new ForAllClosure(this, end, callback); - thread_pool_->AddTask(self, closures[i]); + thread_pool_->AddTask(self, new ForAllClosure(this, end, callback)); } thread_pool_->StartWorkers(self); diff --git a/runtime/arch/x86/entrypoints_init_x86.cc b/runtime/arch/x86/entrypoints_init_x86.cc index 6a67079b6f..589c7d9dc9 100644 --- a/runtime/arch/x86/entrypoints_init_x86.cc +++ b/runtime/arch/x86/entrypoints_init_x86.cc @@ -176,6 +176,7 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, // points->pCmplDouble = NULL; // Not needed on x86. // points->pCmplFloat = NULL; // Not needed on x86. qpoints->pFmod = art_quick_fmod; + // qpoints->pSqrt = NULL; // Not needed on x86. qpoints->pL2d = art_quick_l2d; qpoints->pFmodf = art_quick_fmodf; qpoints->pL2f = art_quick_l2f; diff --git a/runtime/locks.h b/runtime/locks.h index 2308e951b0..72d4f652ff 100644 --- a/runtime/locks.h +++ b/runtime/locks.h @@ -41,6 +41,8 @@ enum LockLevel { kRosAllocBracketLock, kRosAllocBulkFreeLock, kAllocSpaceLock, + kDexFileMethodInlinerLock, + kDexFileToMethodInlinerMapLock, kMarkSweepMarkStackLock, kDefaultMutexLevel, kMarkSweepLargeObjectLock, diff --git a/runtime/native/dalvik_system_Zygote.cc b/runtime/native/dalvik_system_Zygote.cc index 2e3d6a6ab4..7fa9457eb3 100644 --- a/runtime/native/dalvik_system_Zygote.cc +++ b/runtime/native/dalvik_system_Zygote.cc @@ -351,13 +351,14 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode) { if (mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) { // Mount entire external storage tree for all users - if (mount(source, target, NULL, MS_BIND, NULL) == -1) { + if (TEMP_FAILURE_RETRY(mount(source, target, NULL, MS_BIND, NULL)) == -1) { PLOG(WARNING) << "Failed to mount " << source << " to " << target; return false; } } else { // Only mount user-specific external storage - if (mount(source_user.c_str(), target_user.c_str(), NULL, MS_BIND, NULL) == -1) { + if (TEMP_FAILURE_RETRY( + mount(source_user.c_str(), target_user.c_str(), NULL, MS_BIND, NULL)) == -1) { PLOG(WARNING) << "Failed to mount " << source_user << " to " << target_user; return false; } @@ -368,7 +369,8 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode) { } // Finally, mount user-specific path into place for legacy users - if (mount(target_user.c_str(), legacy, NULL, MS_BIND | MS_REC, NULL) == -1) { + if (TEMP_FAILURE_RETRY( + mount(target_user.c_str(), legacy, NULL, MS_BIND | MS_REC, NULL)) == -1) { PLOG(WARNING) << "Failed to mount " << target_user << " to " << legacy; return false; } @@ -407,7 +409,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, - jstring java_se_info, jstring java_se_name, bool is_system_server) { + jstring java_se_info, jstring java_se_name, + bool is_system_server) { Runtime* runtime = Runtime::Current(); CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote"; if (!runtime->PreZygoteFork()) { @@ -527,14 +530,16 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra } static jint Zygote_nativeForkAndSpecialize(JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, - jint debug_flags, jobjectArray rlimits, jint mount_external, - jstring se_info, jstring se_name) { - return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, 0, 0, mount_external, se_info, se_name, false); + jint debug_flags, jobjectArray rlimits, + jint mount_external, jstring se_info, jstring se_name) { + return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, 0, 0, mount_external, + se_info, se_name, false); } static jint Zygote_nativeForkSystemServer(JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, - jlong permittedCapabilities, jlong effectiveCapabilities) { + jlong permittedCapabilities, + jlong effectiveCapabilities) { pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 9183b5f53c..59ead892e1 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -90,28 +90,28 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const mirror::Class* kla if (klass->IsVerified()) { return kNoFailure; } - mirror::Class* super = klass->GetSuperClass(); - if (super == NULL && strcmp("Ljava/lang/Object;", ClassHelper(klass).GetDescriptor()) != 0) { - *error = "Verifier rejected class "; - *error += PrettyDescriptor(klass); - *error += " that has no super class"; - return kHardFailure; - } - if (super != NULL && super->IsFinal()) { - *error = "Verifier rejected class "; - *error += PrettyDescriptor(klass); - *error += " that attempts to sub-class final class "; - *error += PrettyDescriptor(super); - return kHardFailure; - } + bool early_failure = false; + std::string failure_message; ClassHelper kh(klass); const DexFile& dex_file = kh.GetDexFile(); const DexFile::ClassDef* class_def = kh.GetClassDef(); - if (class_def == NULL) { - *error = "Verifier rejected class "; - *error += PrettyDescriptor(klass); - *error += " that isn't present in dex file "; - *error += dex_file.GetLocation(); + mirror::Class* super = klass->GetSuperClass(); + if (super == NULL && strcmp("Ljava/lang/Object;", kh.GetDescriptor()) != 0) { + early_failure = true; + failure_message = " that has no super class"; + } else if (super != NULL && super->IsFinal()) { + early_failure = true; + failure_message = " that attempts to sub-class final class " + PrettyDescriptor(super); + } else if (class_def == NULL) { + early_failure = true; + failure_message = " that isn't present in dex file " + dex_file.GetLocation(); + } + if (early_failure) { + *error = "Verifier rejected class " + PrettyDescriptor(klass) + failure_message; + if (Runtime::Current()->IsCompiler()) { + ClassReference ref(&dex_file, klass->GetDexClassDefIndex()); + AddRejectedClass(ref); + } return kHardFailure; } Thread* self = Thread::Current(); |