Trigger OOM when zone is full.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 9 Sep 2011 12:41:58 +0000 (12:41 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 9 Sep 2011 12:41:58 +0000 (12:41 +0000)
Review URL: http://codereview.chromium.org/7859030

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9211 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/zone-inl.h
src/zone.cc

index 6e2d558..4870105 100644 (file)
@@ -55,7 +55,12 @@ inline void* Zone::New(int size) {
 
   // Check if the requested size is available without expanding.
   Address result = position_;
-  if ((position_ += size) > limit_) result = NewExpand(size);
+
+  if (size > limit_ - position_) {
+     result = NewExpand(size);
+  } else {
+     position_ += size;
+  }
 
   // Check that the result has the proper alignment and return it.
   ASSERT(IsAddressAligned(result, kAlignment, 0));
index 7574778..2d14d13 100644 (file)
@@ -168,7 +168,7 @@ Address Zone::NewExpand(int size) {
   // Make sure the requested size is already properly aligned and that
   // there isn't enough room in the Zone to satisfy the request.
   ASSERT(size == RoundDown(size, kAlignment));
-  ASSERT(position_ + size > limit_);
+  ASSERT(size > limit_ - position_);
 
   // Compute the new segment size. We use a 'high water mark'
   // strategy, where we increase the segment size every time we expand
@@ -177,7 +177,13 @@ Address Zone::NewExpand(int size) {
   Segment* head = segment_head_;
   int old_size = (head == NULL) ? 0 : head->size();
   static const int kSegmentOverhead = sizeof(Segment) + kAlignment;
-  int new_size = kSegmentOverhead + size + (old_size << 1);
+  int new_size_no_overhead = size + (old_size << 1);
+  int new_size = kSegmentOverhead + new_size_no_overhead;
+  // Guard against integer overflow.
+  if (new_size_no_overhead < size || new_size < kSegmentOverhead) {
+    V8::FatalProcessOutOfMemory("Zone");
+    return NULL;
+  }
   if (new_size < kMinimumSegmentSize) {
     new_size = kMinimumSegmentSize;
   } else if (new_size > kMaximumSegmentSize) {
@@ -196,6 +202,11 @@ Address Zone::NewExpand(int size) {
   // Recompute 'top' and 'limit' based on the new segment.
   Address result = RoundUp(segment->start(), kAlignment);
   position_ = result + size;
+  // Check for address overflow.
+  if (position_ < result) {
+    V8::FatalProcessOutOfMemory("Zone");
+    return NULL;
+  }
   limit_ = segment->end();
   ASSERT(position_ <= limit_);
   return result;