Merge "Use the asm-generic ucontext.h for arm."
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index b21e37e..ba98225 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 @@
};
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() {
}
-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 948f4bb..9198f2a 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 @@
/**
* 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 @@
*
* 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 0107ed3..2fec183 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 @@
}
}
-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 476f002..6d5b889 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 @@
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 e66d4ea..ee6f9c8 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1242,7 +1242,7 @@
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 2a54eb3..8415cbf 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -827,7 +827,7 @@
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 96dc6ee..0ecc091 100644
--- a/compiler/dex/quick/x86/assemble_x86.cc
+++ b/compiler/dex/quick/x86/assemble_x86.cc
@@ -288,6 +288,8 @@
{ 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 c9d6bfc..1731703 100644
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -369,8 +369,14 @@
}
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 5fe76fe..a2d5c3e 100644
--- a/compiler/dex/quick/x86/x86_lir.h
+++ b/compiler/dex/quick/x86/x86_lir.h
@@ -348,6 +348,8 @@
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 43ed28c..af18c05 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -284,10 +284,10 @@
};
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 @@
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 6a67079..589c7d9 100644
--- a/runtime/arch/x86/entrypoints_init_x86.cc
+++ b/runtime/arch/x86/entrypoints_init_x86.cc
@@ -176,6 +176,7 @@
// 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 2308e95..72d4f65 100644
--- a/runtime/locks.h
+++ b/runtime/locks.h
@@ -41,6 +41,8 @@
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 2e3d6a6..7fa9457 100644
--- a/runtime/native/dalvik_system_Zygote.cc
+++ b/runtime/native/dalvik_system_Zygote.cc
@@ -351,13 +351,14 @@
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 @@
}
// 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 @@
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 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 9183b5f..59ead89 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -90,28 +90,28 @@
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();