Commit e05c2e36 authored by iposva@chromium.org's avatar iposva@chromium.org

Start addressing massive arrays on the stack. There is hardly ever

a reason to stack allocate large chunks of stack space.
- Runtime_GetCFrames used to allocate a frame size of 52040 bytes.
- PreallocatedMemoryThread::Run used to allocate 32784 bytes.
- Fixed StringStream overflow conditions.

Review URL: http://codereview.chromium.org/67197

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1729 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4ff39b7a
...@@ -262,7 +262,8 @@ void OS::LogSharedLibraryAddresses() { ...@@ -262,7 +262,8 @@ void OS::LogSharedLibraryAddresses() {
} }
int OS::StackWalk(OS::StackFrame* frames, int frames_size) { int OS::StackWalk(Vector<OS::StackFrame> frames) {
int frames_size = frames.length();
void** addresses = NewArray<void*>(frames_size); void** addresses = NewArray<void*>(frames_size);
int frames_count = backtrace(addresses, frames_size); int frames_count = backtrace(addresses, frames_size);
......
...@@ -262,9 +262,10 @@ void OS::LogSharedLibraryAddresses() { ...@@ -262,9 +262,10 @@ void OS::LogSharedLibraryAddresses() {
} }
int OS::StackWalk(OS::StackFrame* frames, int frames_size) { int OS::StackWalk(Vector<OS::StackFrame> frames) {
// backtrace is a glibc extension. // backtrace is a glibc extension.
#ifdef __GLIBC__ #ifdef __GLIBC__
int frames_size = frames.length();
void** addresses = NewArray<void*>(frames_size); void** addresses = NewArray<void*>(frames_size);
int frames_count = backtrace(addresses, frames_size); int frames_count = backtrace(addresses, frames_size);
......
...@@ -212,10 +212,11 @@ int OS::ActivationFrameAlignment() { ...@@ -212,10 +212,11 @@ int OS::ActivationFrameAlignment() {
} }
int OS::StackWalk(StackFrame* frames, int frames_size) { int OS::StackWalk(Vector<StackFrame> frames) {
#ifndef MAC_OS_X_VERSION_10_5 #ifndef MAC_OS_X_VERSION_10_5
return 0; return 0;
#else #else
int frames_size = frames.length();
void** addresses = NewArray<void*>(frames_size); void** addresses = NewArray<void*>(frames_size);
int frames_count = backtrace(addresses, frames_size); int frames_count = backtrace(addresses, frames_size);
......
...@@ -215,7 +215,7 @@ void OS::LogSharedLibraryAddresses() { ...@@ -215,7 +215,7 @@ void OS::LogSharedLibraryAddresses() {
} }
int OS::StackWalk(OS::StackFrame* frames, int frames_size) { int OS::StackWalk(Vector<OS::StackFrame> frames) {
UNIMPLEMENTED(); UNIMPLEMENTED();
return 0; return 0;
} }
......
...@@ -1161,7 +1161,7 @@ void OS::LogSharedLibraryAddresses() { ...@@ -1161,7 +1161,7 @@ void OS::LogSharedLibraryAddresses() {
// it is triggered by the use of inline assembler. // it is triggered by the use of inline assembler.
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4748) #pragma warning(disable : 4748)
int OS::StackWalk(OS::StackFrame* frames, int frames_size) { int OS::StackWalk(Vector<OS::StackFrame> frames) {
BOOL ok; BOOL ok;
// Load the required functions from DLL's. // Load the required functions from DLL's.
...@@ -1201,6 +1201,7 @@ int OS::StackWalk(OS::StackFrame* frames, int frames_size) { ...@@ -1201,6 +1201,7 @@ int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
int frames_count = 0; int frames_count = 0;
// Collect stack frames. // Collect stack frames.
int frames_size = frames.length();
while (frames_count < frames_size) { while (frames_count < frames_size) {
ok = _StackWalk64( ok = _StackWalk64(
IMAGE_FILE_MACHINE_I386, // MachineType IMAGE_FILE_MACHINE_I386, // MachineType
...@@ -1284,7 +1285,7 @@ int OS::StackWalk(OS::StackFrame* frames, int frames_size) { ...@@ -1284,7 +1285,7 @@ int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
#else // __MINGW32__ #else // __MINGW32__
void OS::LogSharedLibraryAddresses() { } void OS::LogSharedLibraryAddresses() { }
int OS::StackWalk(OS::StackFrame* frames, int frames_size) { return 0; } int OS::StackWalk(Vector<OS::StackFrame> frames) { return 0; }
#endif // __MINGW32__ #endif // __MINGW32__
......
...@@ -207,7 +207,7 @@ class OS { ...@@ -207,7 +207,7 @@ class OS {
char text[kStackWalkMaxTextLen]; char text[kStackWalkMaxTextLen];
}; };
static int StackWalk(StackFrame* frames, int frames_size); static int StackWalk(Vector<StackFrame> frames);
// Factory method for creating platform dependent Mutex. // Factory method for creating platform dependent Mutex.
// Please use delete to reclaim the storage for the returned Mutex. // Please use delete to reclaim the storage for the returned Mutex.
......
...@@ -5929,8 +5929,8 @@ static Object* Runtime_GetCFrames(Arguments args) { ...@@ -5929,8 +5929,8 @@ static Object* Runtime_GetCFrames(Arguments args) {
if (result->IsFailure()) return result; if (result->IsFailure()) return result;
static const int kMaxCFramesSize = 200; static const int kMaxCFramesSize = 200;
OS::StackFrame frames[kMaxCFramesSize]; ScopedVector<OS::StackFrame> frames(kMaxCFramesSize);
int frames_count = OS::StackWalk(frames, kMaxCFramesSize); int frames_count = OS::StackWalk(frames);
if (frames_count == OS::kStackWalkError) { if (frames_count == OS::kStackWalkError) {
return Heap::undefined_value(); return Heap::undefined_value();
} }
......
...@@ -57,19 +57,26 @@ NoAllocationStringAllocator::NoAllocationStringAllocator(char* memory, ...@@ -57,19 +57,26 @@ NoAllocationStringAllocator::NoAllocationStringAllocator(char* memory,
bool StringStream::Put(char c) { bool StringStream::Put(char c) {
if (space() == 0) return false; if (full()) return false;
if (length_ >= capacity_ - 1) { ASSERT(length_ < capacity_);
// Since the trailing '\0' is not accounted for in length_ fullness is
// indicated by a difference of 1 between length_ and capacity_. Thus when
// reaching a difference of 2 we need to grow the buffer.
if (length_ == capacity_ - 2) {
unsigned new_capacity = capacity_; unsigned new_capacity = capacity_;
char* new_buffer = allocator_->grow(&new_capacity); char* new_buffer = allocator_->grow(&new_capacity);
if (new_capacity > capacity_) { if (new_capacity > capacity_) {
capacity_ = new_capacity; capacity_ = new_capacity;
buffer_ = new_buffer; buffer_ = new_buffer;
} else { } else {
// Indicate truncation with dots. // Reached the end of the available buffer.
memset(cursor(), '.', space()); ASSERT(capacity_ >= 5);
length_ = capacity_; length_ = capacity_ - 1; // Indicate fullness of the stream.
buffer_[length_ - 2] = '\n'; buffer_[length_ - 4] = '.';
buffer_[length_ - 1] = '\0'; buffer_[length_ - 3] = '.';
buffer_[length_ - 2] = '.';
buffer_[length_ - 1] = '\n';
buffer_[length_] = '\0';
return false; return false;
} }
} }
...@@ -95,8 +102,7 @@ static bool IsControlChar(char c) { ...@@ -95,8 +102,7 @@ static bool IsControlChar(char c) {
void StringStream::Add(Vector<const char> format, Vector<FmtElm> elms) { void StringStream::Add(Vector<const char> format, Vector<FmtElm> elms) {
// If we already ran out of space then return immediately. // If we already ran out of space then return immediately.
if (space() == 0) if (full()) return;
return;
int offset = 0; int offset = 0;
int elm = 0; int elm = 0;
while (offset < format.length()) { while (offset < format.length()) {
...@@ -564,12 +570,10 @@ char* HeapStringAllocator::grow(unsigned* bytes) { ...@@ -564,12 +570,10 @@ char* HeapStringAllocator::grow(unsigned* bytes) {
} }
// Only grow once to the maximum allowable size.
char* NoAllocationStringAllocator::grow(unsigned* bytes) { char* NoAllocationStringAllocator::grow(unsigned* bytes) {
unsigned new_bytes = *bytes * 2; ASSERT(size_ >= *bytes);
if (new_bytes > size_) { *bytes = size_;
new_bytes = size_;
}
*bytes = new_bytes;
return space_; return space_;
} }
......
...@@ -162,8 +162,8 @@ class StringStream { ...@@ -162,8 +162,8 @@ class StringStream {
unsigned length_; // does not include terminating 0-character unsigned length_; // does not include terminating 0-character
char* buffer_; char* buffer_;
bool full() const { return (capacity_ - length_) == 1; }
int space() const { return capacity_ - length_; } int space() const { return capacity_ - length_; }
char* cursor() const { return buffer_ + length_; }
DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream); DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
}; };
......
...@@ -116,7 +116,7 @@ class PreallocatedMemoryThread: public Thread { ...@@ -116,7 +116,7 @@ class PreallocatedMemoryThread: public Thread {
// When the thread starts running it will allocate a fixed number of bytes // When the thread starts running it will allocate a fixed number of bytes
// on the stack and publish the location of this memory for others to use. // on the stack and publish the location of this memory for others to use.
void Run() { void Run() {
EmbeddedVector<char, 32 * 1024> local_buffer; EmbeddedVector<char, 15 * 1024> local_buffer;
// Initialize the buffer with a known good value. // Initialize the buffer with a known good value.
OS::StrNCpy(local_buffer, "Trace data was not generated.\n", OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
......
...@@ -406,6 +406,16 @@ class EmbeddedVector : public Vector<T> { ...@@ -406,6 +406,16 @@ class EmbeddedVector : public Vector<T> {
}; };
template <typename T>
class ScopedVector : public Vector<T> {
public:
explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { }
~ScopedVector() {
DeleteArray(this->start());
}
};
inline Vector<const char> CStrVector(const char* data) { inline Vector<const char> CStrVector(const char* data) {
return Vector<const char>(data, strlen(data)); return Vector<const char>(data, strlen(data));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment