Start addressing massive arrays on the stack. There is hardly ever
authoriposva@chromium.org <iposva@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 16 Apr 2009 21:01:05 +0000 (21:01 +0000)
committeriposva@chromium.org <iposva@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 16 Apr 2009 21:01:05 +0000 (21:01 +0000)
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

src/platform-freebsd.cc
src/platform-linux.cc
src/platform-macos.cc
src/platform-nullos.cc
src/platform-win32.cc
src/platform.h
src/runtime.cc
src/string-stream.cc
src/string-stream.h
src/top.cc
src/utils.h

index 92099907bc982ff49c2ee450d724d85601641921..3d223174ce2c9a05ab75b3eda138cf144f38085d 100644 (file)
@@ -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);
 
   int frames_count = backtrace(addresses, frames_size);
index f9a5deacb2caf1c7a6202a672b273d089bb1ad83..3b5351f036bbac17394f807acdc6a8f0af14409b 100644 (file)
@@ -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.
 #ifdef __GLIBC__
+  int frames_size = frames.length();
   void** addresses = NewArray<void*>(frames_size);
 
   int frames_count = backtrace(addresses, frames_size);
index b13122fae669c46bf532fce085636b181d92dff1..79515434e61656f2f3667b46beb74c1536ad2940 100644 (file)
@@ -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
   return 0;
 #else
+  int frames_size = frames.length();
   void** addresses = NewArray<void*>(frames_size);
   int frames_count = backtrace(addresses, frames_size);
 
index 3a50b9ddda38bbcdf8ade16904732a97225f9f5a..42583f17f6ed50c2c2c07ffd4988747817d25b34 100644 (file)
@@ -215,7 +215,7 @@ void OS::LogSharedLibraryAddresses() {
 }
 
 
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
   UNIMPLEMENTED();
   return 0;
 }
index 7177870223b6cd9850162e7f62a5ecef4aac53f1..597a21716b2b655e4962b7b55b6ccb76d57ecc15 100644 (file)
@@ -1161,7 +1161,7 @@ void OS::LogSharedLibraryAddresses() {
 // it is triggered by the use of inline assembler.
 #pragma warning(push)
 #pragma warning(disable : 4748)
-int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
   BOOL ok;
 
   // Load the required functions from DLL's.
@@ -1201,6 +1201,7 @@ int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
   int frames_count = 0;
 
   // Collect stack frames.
+  int frames_size = frames.length();
   while (frames_count < frames_size) {
     ok = _StackWalk64(
         IMAGE_FILE_MACHINE_I386,    // MachineType
@@ -1284,7 +1285,7 @@ int OS::StackWalk(OS::StackFrame* frames, int frames_size) {
 
 #else  // __MINGW32__
 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__
 
 
index db4f2fdabdbffc07d182a9c7f2acdad644dd8ffc..b70095b12024f3dc63c27c8de87c28872ee4470f 100644 (file)
@@ -207,7 +207,7 @@ class OS {
     char text[kStackWalkMaxTextLen];
   };
 
-  static int StackWalk(StackFrame* frames, int frames_size);
+  static int StackWalk(Vector<StackFrame> frames);
 
   // Factory method for creating platform dependent Mutex.
   // Please use delete to reclaim the storage for the returned Mutex.
index 8fbcdcec968af7499ea5fde9a92073b97e563ba1..1e41b0f16c4bc9f801c56986f1fd51cb77b97243 100644 (file)
@@ -5929,8 +5929,8 @@ static Object* Runtime_GetCFrames(Arguments args) {
   if (result->IsFailure()) return result;
 
   static const int kMaxCFramesSize = 200;
-  OS::StackFrame frames[kMaxCFramesSize];
-  int frames_count = OS::StackWalk(frames, kMaxCFramesSize);
+  ScopedVector<OS::StackFrame> frames(kMaxCFramesSize);
+  int frames_count = OS::StackWalk(frames);
   if (frames_count == OS::kStackWalkError) {
     return Heap::undefined_value();
   }
index f311e20bdeb69d1da6815a99745da7face22d89a..2e0912fbdb82d9eb84a88775c024e437c6eab05b 100644 (file)
@@ -57,19 +57,26 @@ NoAllocationStringAllocator::NoAllocationStringAllocator(char* memory,
 
 
 bool StringStream::Put(char c) {
-  if (space() == 0) return false;
-  if (length_ >= capacity_ - 1) {
+  if (full()) return false;
+  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_;
     char* new_buffer = allocator_->grow(&new_capacity);
     if (new_capacity > capacity_) {
       capacity_ = new_capacity;
       buffer_ = new_buffer;
     } else {
-      // Indicate truncation with dots.
-      memset(cursor(), '.', space());
-      length_ = capacity_;
-      buffer_[length_ - 2] = '\n';
-      buffer_[length_ - 1] = '\0';
+      // Reached the end of the available buffer.
+      ASSERT(capacity_ >= 5);
+      length_ = capacity_ - 1;  // Indicate fullness of the stream.
+      buffer_[length_ - 4] = '.';
+      buffer_[length_ - 3] = '.';
+      buffer_[length_ - 2] = '.';
+      buffer_[length_ - 1] = '\n';
+      buffer_[length_] = '\0';
       return false;
     }
   }
@@ -95,8 +102,7 @@ static bool IsControlChar(char c) {
 
 void StringStream::Add(Vector<const char> format, Vector<FmtElm> elms) {
   // If we already ran out of space then return immediately.
-  if (space() == 0)
-    return;
+  if (full()) return;
   int offset = 0;
   int elm = 0;
   while (offset < format.length()) {
@@ -564,12 +570,10 @@ char* HeapStringAllocator::grow(unsigned* bytes) {
 }
 
 
+// Only grow once to the maximum allowable size.
 char* NoAllocationStringAllocator::grow(unsigned* bytes) {
-  unsigned new_bytes = *bytes * 2;
-  if (new_bytes > size_) {
-    new_bytes = size_;
-  }
-  *bytes = new_bytes;
+  ASSERT(size_ >= *bytes);
+  *bytes = size_;
   return space_;
 }
 
index 37ae93e2c6f6582dc008263754a3acd61f5955f8..901f376a5aff5b735c7e498575c3b374b4f92da1 100644 (file)
@@ -162,8 +162,8 @@ class StringStream {
   unsigned length_;  // does not include terminating 0-character
   char* buffer_;
 
+  bool full() const { return (capacity_ - length_) == 1; }
   int space() const { return capacity_ - length_; }
-  char* cursor() const { return buffer_ + length_; }
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
 };
index a99e9fff8add6c42576598ec101837cbd8a312dc..82221c120216debe350c3f961390f0b41f1ff6a6 100644 (file)
@@ -116,7 +116,7 @@ class PreallocatedMemoryThread: public Thread {
   // 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.
   void Run() {
-    EmbeddedVector<char, 32 * 1024> local_buffer;
+    EmbeddedVector<char, 15 * 1024> local_buffer;
 
     // Initialize the buffer with a known good value.
     OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
index f62b47a54f55844bfafd58968b448a446ebb5a9f..e008c85f59a7799db75e73b1d5adc15886fe8db8 100644 (file)
@@ -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) {
   return Vector<const char>(data, strlen(data));
 }