summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--compiler/driver/compiler_driver.cc4
-rw-r--r--compiler/image_writer.cc6
-rw-r--r--runtime/barrier_test.cc4
-rw-r--r--runtime/base/logging.cc25
-rw-r--r--runtime/gc/heap.cc2
-rw-r--r--runtime/gc/space/dlmalloc_space.cc1
-rw-r--r--runtime/mem_map.cc7
-rw-r--r--runtime/thread_pool.cc20
-rw-r--r--runtime/thread_pool.h11
-rw-r--r--runtime/thread_pool_test.cc6
11 files changed, 51 insertions, 36 deletions
diff --git a/Android.mk b/Android.mk
index bf2eb9a..76fb411 100644
--- a/Android.mk
+++ b/Android.mk
@@ -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));