diff options
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 4 | ||||
-rw-r--r-- | compiler/image_writer.cc | 6 | ||||
-rw-r--r-- | runtime/barrier_test.cc | 4 | ||||
-rw-r--r-- | runtime/base/logging.cc | 25 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 2 | ||||
-rw-r--r-- | runtime/gc/space/dlmalloc_space.cc | 1 | ||||
-rw-r--r-- | runtime/mem_map.cc | 7 | ||||
-rw-r--r-- | runtime/thread_pool.cc | 20 | ||||
-rw-r--r-- | runtime/thread_pool.h | 11 | ||||
-rw-r--r-- | runtime/thread_pool_test.cc | 6 |
11 files changed, 51 insertions, 36 deletions
@@ -18,6 +18,7 @@ LOCAL_PATH := $(call my-dir) art_path := $(LOCAL_PATH) art_build_path := $(art_path)/build +include $(art_build_path)/Android.common.mk ######################################################################## # clean-oat targets diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 4af492b..d74383e 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -505,7 +505,7 @@ void CompilerDriver::CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, base::TimingLogger& timings) { DCHECK(!Runtime::Current()->IsStarted()); - UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_ - 1)); + UniquePtr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", thread_count_ - 1)); PreCompile(class_loader, dex_files, *thread_pool.get(), timings); Compile(class_loader, dex_files, *thread_pool.get(), timings); if (dump_stats_) { @@ -568,7 +568,7 @@ void CompilerDriver::CompileOne(const mirror::ArtMethod* method, base::TimingLog std::vector<const DexFile*> dex_files; dex_files.push_back(dex_file); - UniquePtr<ThreadPool> thread_pool(new ThreadPool(0U)); + UniquePtr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", 0U)); PreCompile(jclass_loader, dex_files, *thread_pool.get(), timings); uint32_t method_idx = method->GetDexMethodIndex(); diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index c22f8d6..d2d7c0a 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -520,11 +520,13 @@ void ImageWriter::CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_d // Return to write header at start of image with future location of image_roots. At this point, // image_end_ is the size of the image (excluding bitmaps). + const size_t heap_bytes_per_bitmap_byte = 8 * gc::accounting::SpaceBitmap::kAlignment; + const size_t bitmap_bytes = RoundUp(image_end_, heap_bytes_per_bitmap_byte) / + heap_bytes_per_bitmap_byte; ImageHeader image_header(reinterpret_cast<uint32_t>(image_begin_), static_cast<uint32_t>(image_end_), RoundUp(image_end_, kPageSize), - RoundUp(image_end_ / gc::accounting::SpaceBitmap::kAlignment, - sizeof(size_t)), + RoundUp(bitmap_bytes, kPageSize), reinterpret_cast<uint32_t>(GetImageAddress(image_roots.get())), oat_file_->GetOatHeader().GetChecksum(), reinterpret_cast<uint32_t>(oat_file_begin), diff --git a/runtime/barrier_test.cc b/runtime/barrier_test.cc index 298ae56..91fc143 100644 --- a/runtime/barrier_test.cc +++ b/runtime/barrier_test.cc @@ -66,7 +66,7 @@ int32_t BarrierTest::num_threads = 4; // Check that barrier wait and barrier increment work. TEST_F(BarrierTest, CheckWait) { Thread* self = Thread::Current(); - ThreadPool thread_pool(num_threads); + ThreadPool thread_pool("Barrier test thread pool", num_threads); Barrier barrier(0); AtomicInteger count1(0); AtomicInteger count2(0); @@ -121,7 +121,7 @@ class CheckPassTask : public Task { // Check that barrier pass through works. TEST_F(BarrierTest, CheckPass) { Thread* self = Thread::Current(); - ThreadPool thread_pool(num_threads); + ThreadPool thread_pool("Barrier test thread pool", num_threads); Barrier barrier(0); AtomicInteger count(0); const int32_t num_tasks = num_threads * 4; diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc index 3d842a0..3aabc8d 100644 --- a/runtime/base/logging.cc +++ b/runtime/base/logging.cc @@ -19,6 +19,7 @@ #include "base/mutex.h" #include "runtime.h" #include "thread-inl.h" +#include "UniquePtr.h" #include "utils.h" namespace art { @@ -28,20 +29,21 @@ LogVerbosity gLogVerbosity; unsigned int gAborting = 0; static LogSeverity gMinimumLogSeverity = INFO; -static std::string* gCmdLine = NULL; -static std::string* gProgramInvocationName = NULL; -static std::string* gProgramInvocationShortName = NULL; +static UniquePtr<std::string> gCmdLine; +static UniquePtr<std::string> gProgramInvocationName; +static UniquePtr<std::string> gProgramInvocationShortName; const char* GetCmdLine() { - return (gCmdLine != NULL) ? gCmdLine->c_str() : NULL; + return (gCmdLine.get() != nullptr) ? gCmdLine->c_str() : nullptr; } const char* ProgramInvocationName() { - return (gProgramInvocationName != NULL) ? gProgramInvocationName->c_str() : "art"; + return (gProgramInvocationName.get() != nullptr) ? gProgramInvocationName->c_str() : "art"; } const char* ProgramInvocationShortName() { - return (gProgramInvocationShortName != NULL) ? gProgramInvocationShortName->c_str() : "art"; + return (gProgramInvocationShortName.get() != nullptr) ? gProgramInvocationShortName->c_str() + : "art"; } // Configure logging based on ANDROID_LOG_TAGS environment variable. @@ -53,7 +55,7 @@ const char* ProgramInvocationShortName() { // and a letter indicating the minimum priority level we're expected to log. // This can be used to reveal or conceal logs with specific tags. void InitLogging(char* argv[]) { - if (gCmdLine != NULL) { + if (gCmdLine.get() != nullptr) { return; } // TODO: Move this to a more obvious InitART... @@ -63,17 +65,18 @@ void InitLogging(char* argv[]) { // but we don't have that luxury on the Mac, and there are a couple of argv[0] variants that are // commonly used. if (argv != NULL) { - gCmdLine = new std::string(argv[0]); + gCmdLine.reset(new std::string(argv[0])); for (size_t i = 1; argv[i] != NULL; ++i) { gCmdLine->append(" "); gCmdLine->append(argv[i]); } - gProgramInvocationName = new std::string(argv[0]); + gProgramInvocationName.reset(new std::string(argv[0])); const char* last_slash = strrchr(argv[0], '/'); - gProgramInvocationShortName = new std::string((last_slash != NULL) ? last_slash + 1 : argv[0]); + gProgramInvocationShortName.reset(new std::string((last_slash != NULL) ? last_slash + 1 + : argv[0])); } else { // TODO: fall back to /proc/self/cmdline when argv is NULL on Linux - gCmdLine = new std::string("<unset>"); + gCmdLine.reset(new std::string("<unset>")); } const char* tags = getenv("ANDROID_LOG_TAGS"); if (tags == NULL) { diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 69ca620..70df3d3 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -309,7 +309,7 @@ void Heap::DecrementDisableGC(Thread* self) { void Heap::CreateThreadPool() { const size_t num_threads = std::max(parallel_gc_threads_, conc_gc_threads_); if (num_threads != 0) { - thread_pool_.reset(new ThreadPool(num_threads)); + thread_pool_.reset(new ThreadPool("Heap thread pool", num_threads)); } } diff --git a/runtime/gc/space/dlmalloc_space.cc b/runtime/gc/space/dlmalloc_space.cc index 8a5e33a..1c7aa22 100644 --- a/runtime/gc/space/dlmalloc_space.cc +++ b/runtime/gc/space/dlmalloc_space.cc @@ -318,6 +318,7 @@ DlMallocSpace* DlMallocSpace::CreateZygoteSpace(const char* alloc_space_name) { DlMallocSpace* alloc_space = new DlMallocSpace(alloc_space_name, mem_map.release(), mspace, end_, end, limit_, growth_limit); + SetLimit(End()); live_bitmap_->SetHeapLimit(reinterpret_cast<uintptr_t>(End())); CHECK_EQ(live_bitmap_->HeapLimit(), reinterpret_cast<uintptr_t>(End())); mark_bitmap_->SetHeapLimit(reinterpret_cast<uintptr_t>(End())); diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index 3afb606..39e838f 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -133,12 +133,13 @@ MemMap* MemMap::MapFileAtAddress(byte* addr, size_t byte_count, int prot, int fl fd, page_aligned_offset)); if (actual == MAP_FAILED) { + std::string strerr(strerror(errno)); std::string maps; ReadFileToString("/proc/self/maps", &maps); - *error_msg = StringPrintf("mmap(%p, %zd, %x, %x, %d, %lld) of file '%s' failed\n%s", + *error_msg = StringPrintf("mmap(%p, %zd, %x, %x, %d, %lld) of file '%s' failed: %s\n%s", page_aligned_addr, page_aligned_byte_count, prot, flags, fd, - static_cast<int64_t>(page_aligned_offset), - filename, maps.c_str()); + static_cast<int64_t>(page_aligned_offset), filename, strerr.c_str(), + maps.c_str()); return NULL; } return new MemMap("file", actual + page_offset, byte_count, actual, page_aligned_byte_count, diff --git a/runtime/thread_pool.cc b/runtime/thread_pool.cc index bb6c475..aca0561 100644 --- a/runtime/thread_pool.cc +++ b/runtime/thread_pool.cc @@ -28,12 +28,15 @@ static constexpr bool kMeasureWaitTime = false; ThreadPoolWorker::ThreadPoolWorker(ThreadPool* thread_pool, const std::string& name, size_t stack_size) : thread_pool_(thread_pool), - name_(name), - stack_size_(stack_size) { + name_(name) { + std::string error_msg; + stack_.reset(MemMap::MapAnonymous(name.c_str(), nullptr, stack_size, PROT_READ | PROT_WRITE, + &error_msg)); + CHECK(stack_.get() != nullptr) << error_msg; const char* reason = "new thread pool worker thread"; pthread_attr_t attr; CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason); - CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), reason); + CHECK_PTHREAD_CALL(pthread_attr_setstack, (&attr, stack_->Begin(), stack_->Size()), reason); CHECK_PTHREAD_CALL(pthread_create, (&pthread_, &attr, &Callback, this), reason); CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason); } @@ -71,8 +74,9 @@ void ThreadPool::AddTask(Thread* self, Task* task) { } } -ThreadPool::ThreadPool(size_t num_threads) - : task_queue_lock_("task queue lock"), +ThreadPool::ThreadPool(const char* name, size_t num_threads) + : name_(name), + task_queue_lock_("task queue lock"), task_queue_condition_("task queue condition", task_queue_lock_), completion_condition_("task completion condition", task_queue_lock_), started_(false), @@ -85,7 +89,7 @@ ThreadPool::ThreadPool(size_t num_threads) max_active_workers_(num_threads) { Thread* self = Thread::Current(); while (GetThreadCount() < num_threads) { - const std::string name = StringPrintf("Thread pool worker %zu", GetThreadCount()); + const std::string name = StringPrintf("%s worker thread %zu", name_.c_str(), GetThreadCount()); threads_.push_back(new ThreadPoolWorker(this, name, ThreadPoolWorker::kDefaultStackSize)); } // Wait for all of the threads to attach. @@ -270,8 +274,8 @@ void WorkStealingWorker::Run() { WorkStealingWorker::~WorkStealingWorker() {} -WorkStealingThreadPool::WorkStealingThreadPool(size_t num_threads) - : ThreadPool(0), +WorkStealingThreadPool::WorkStealingThreadPool(const char* name, size_t num_threads) + : ThreadPool(name, 0), work_steal_lock_("work stealing lock"), steal_index_(0) { while (GetThreadCount() < num_threads) { diff --git a/runtime/thread_pool.h b/runtime/thread_pool.h index b9a97a1..e8f9afe 100644 --- a/runtime/thread_pool.h +++ b/runtime/thread_pool.h @@ -24,6 +24,7 @@ #include "base/mutex.h" #include "closure.h" #include "locks.h" +#include "mem_map.h" namespace art { @@ -40,7 +41,8 @@ class ThreadPoolWorker { static const size_t kDefaultStackSize = 1 * MB; size_t GetStackSize() const { - return stack_size_; + DCHECK(stack_.get() != nullptr); + return stack_->Size(); } virtual ~ThreadPoolWorker(); @@ -52,7 +54,7 @@ class ThreadPoolWorker { ThreadPool* const thread_pool_; const std::string name_; - const size_t stack_size_; + UniquePtr<MemMap> stack_; pthread_t pthread_; private: @@ -77,7 +79,7 @@ class ThreadPool { // after running it, it is the caller's responsibility. void AddTask(Thread* self, Task* task); - explicit ThreadPool(size_t num_threads); + explicit ThreadPool(const char* name, size_t num_threads); virtual ~ThreadPool(); // Wait for all tasks currently on queue to get completed. @@ -107,6 +109,7 @@ class ThreadPool { return shutting_down_; } + const std::string name_; Mutex task_queue_lock_; ConditionVariable task_queue_condition_ GUARDED_BY(task_queue_lock_); ConditionVariable completion_condition_ GUARDED_BY(task_queue_lock_); @@ -167,7 +170,7 @@ class WorkStealingWorker : public ThreadPoolWorker { class WorkStealingThreadPool : public ThreadPool { public: - explicit WorkStealingThreadPool(size_t num_threads); + explicit WorkStealingThreadPool(const char* name, size_t num_threads); virtual ~WorkStealingThreadPool(); private: diff --git a/runtime/thread_pool_test.cc b/runtime/thread_pool_test.cc index 9b789d2..1b22361 100644 --- a/runtime/thread_pool_test.cc +++ b/runtime/thread_pool_test.cc @@ -59,7 +59,7 @@ int32_t ThreadPoolTest::num_threads = 4; // Check that the thread pool actually runs tasks that you assign it. TEST_F(ThreadPoolTest, CheckRun) { Thread* self = Thread::Current(); - ThreadPool thread_pool(num_threads); + ThreadPool thread_pool("Thread pool test thread pool", num_threads); AtomicInteger count(0); static const int32_t num_tasks = num_threads * 4; for (int32_t i = 0; i < num_tasks; ++i) { @@ -74,7 +74,7 @@ TEST_F(ThreadPoolTest, CheckRun) { TEST_F(ThreadPoolTest, StopStart) { Thread* self = Thread::Current(); - ThreadPool thread_pool(num_threads); + ThreadPool thread_pool("Thread pool test thread pool", num_threads); AtomicInteger count(0); static const int32_t num_tasks = num_threads * 4; for (int32_t i = 0; i < num_tasks; ++i) { @@ -129,7 +129,7 @@ class TreeTask : public Task { // Test that adding new tasks from within a task works. TEST_F(ThreadPoolTest, RecursiveTest) { Thread* self = Thread::Current(); - ThreadPool thread_pool(num_threads); + ThreadPool thread_pool("Thread pool test thread pool", num_threads); AtomicInteger count(0); static const int depth = 8; thread_pool.AddTask(self, new TreeTask(&thread_pool, &count, depth)); |