Trigger OOM when zone is full.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9211 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2011-09-09 12:41:58 +00:00
parent 2a92165101
commit 37e39ce3f9
2 changed files with 19 additions and 3 deletions

View File

@ -55,7 +55,12 @@ inline void* Zone::New(int size) {
// Check if the requested size is available without expanding. // Check if the requested size is available without expanding.
Address result = position_; 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. // Check that the result has the proper alignment and return it.
ASSERT(IsAddressAligned(result, kAlignment, 0)); ASSERT(IsAddressAligned(result, kAlignment, 0));

View File

@ -168,7 +168,7 @@ Address Zone::NewExpand(int size) {
// Make sure the requested size is already properly aligned and that // Make sure the requested size is already properly aligned and that
// there isn't enough room in the Zone to satisfy the request. // there isn't enough room in the Zone to satisfy the request.
ASSERT(size == RoundDown(size, kAlignment)); ASSERT(size == RoundDown(size, kAlignment));
ASSERT(position_ + size > limit_); ASSERT(size > limit_ - position_);
// Compute the new segment size. We use a 'high water mark' // Compute the new segment size. We use a 'high water mark'
// strategy, where we increase the segment size every time we expand // strategy, where we increase the segment size every time we expand
@ -177,7 +177,13 @@ Address Zone::NewExpand(int size) {
Segment* head = segment_head_; Segment* head = segment_head_;
int old_size = (head == NULL) ? 0 : head->size(); int old_size = (head == NULL) ? 0 : head->size();
static const int kSegmentOverhead = sizeof(Segment) + kAlignment; 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) { if (new_size < kMinimumSegmentSize) {
new_size = kMinimumSegmentSize; new_size = kMinimumSegmentSize;
} else if (new_size > kMaximumSegmentSize) { } else if (new_size > kMaximumSegmentSize) {
@ -196,6 +202,11 @@ Address Zone::NewExpand(int size) {
// Recompute 'top' and 'limit' based on the new segment. // Recompute 'top' and 'limit' based on the new segment.
Address result = RoundUp(segment->start(), kAlignment); Address result = RoundUp(segment->start(), kAlignment);
position_ = result + size; position_ = result + size;
// Check for address overflow.
if (position_ < result) {
V8::FatalProcessOutOfMemory("Zone");
return NULL;
}
limit_ = segment->end(); limit_ = segment->end();
ASSERT(position_ <= limit_); ASSERT(position_ <= limit_);
return result; return result;