Alloc stack using MemMap and -Xss
Change-Id: Ib6d52e41e62bf9cd111b2f03257ead53673d3e81
diff --git a/src/mem_map.h b/src/mem_map.h
index 9357b9b..8645f44 100644
--- a/src/mem_map.h
+++ b/src/mem_map.h
@@ -91,6 +91,10 @@
return length_;
}
+ byte* GetLimit() const {
+ return addr_ + length_;
+ }
+
private:
MemMap(byte* addr, size_t length, void* base_addr, size_t base_length)
: addr_(addr), length_(length), base_addr_(base_addr), base_length_(base_length) {
diff --git a/src/runtime.cc b/src/runtime.cc
index de76bb3..6108fe8 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -326,6 +326,7 @@
exit_ = options->hook_exit_;
abort_ = options->hook_abort_;
+ stack_size_ = options->stack_size_;
thread_list_ = ThreadList::Create();
Heap::Init(options->heap_initial_size_,
diff --git a/src/runtime.h b/src/runtime.h
index 0aa0cb5..4a5063c 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -75,7 +75,11 @@
~Runtime();
- ClassLinker* GetClassLinker() {
+ size_t GetStackSize() const {
+ return stack_size_;
+ }
+
+ ClassLinker* GetClassLinker() const {
return class_linker_;
}
@@ -86,11 +90,14 @@
private:
static void PlatformAbort(const char*, int);
- Runtime() : thread_list_(NULL), class_linker_(NULL) {}
+ Runtime() : stack_size_(0), thread_list_(NULL), class_linker_(NULL) {}
// Initializes a new uninitialized runtime.
bool Init(const Options& options, bool ignore_unrecognized);
+ // The default stack size for managed threads created by the runtime.
+ size_t stack_size_;
+
ThreadList* thread_list_;
ClassLinker* class_linker_;
diff --git a/src/thread.cc b/src/thread.cc
index 71cd877..aa3fe95 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -53,20 +53,21 @@
return NULL;
}
-Thread* Thread::Create(size_t stack_size) {
- int prot = PROT_READ | PROT_WRITE;
- // TODO: require the stack size to be page aligned?
- size_t length = RoundUp(stack_size, kPageSize);
- void* stack_limit = mmap(NULL, length, prot, MAP_PRIVATE, -1, 0);
- if (stack_limit == MAP_FAILED) {
- LOG(FATAL) << "mmap";
- return false;
+Thread* Thread::Create(const Runtime* runtime) {
+ size_t stack_size = runtime->GetStackSize();
+ scoped_ptr<MemMap> stack(MemMap::Map(stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE));
+ if (stack == NULL) {
+ LOG(FATAL) << "failed to allocate thread stack";
+ // notreached
+ return NULL;
}
Thread* new_thread = new Thread;
new_thread->InitCpu();
- new_thread->stack_limit_ = static_cast<byte*>(stack_limit);
- new_thread->stack_base_ = new_thread->stack_limit_ + length;
+ new_thread->stack_.reset(stack.release());
+ // Since stacks are assumed to grown downward the base is the limit and the limit is the base.
+ new_thread->stack_limit_ = stack->GetAddress();
+ new_thread->stack_base_ = stack->GetLimit();
pthread_attr_t attr;
int result = pthread_attr_init(&attr);
diff --git a/src/thread.h b/src/thread.h
index de5893e..4264a1a 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -10,6 +10,7 @@
#include "jni_internal.h"
#include "logging.h"
#include "macros.h"
+#include "mem_map.h"
#include "offsets.h"
#include "runtime.h"
@@ -115,7 +116,7 @@
static const size_t kDefaultStackSize = 64 * KB;
// Creates a new thread.
- static Thread* Create(size_t stack_size);
+ static Thread* Create(const Runtime* runtime);
// Creates a new thread from the calling thread.
static Thread* Attach(const Runtime* runtime);
@@ -292,6 +293,9 @@
// at the next poll.
int suspend_count_;
+ // The memory mapping of the stack for non-attached threads.
+ scoped_ptr<MemMap> stack_;
+
// The inclusive base of the control stack.
byte* stack_base_;