1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org#include <string.h> 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org#include "v8.h" 3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "zone-inl.h" 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 3471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Segments represent chunks of memory: They have starting address 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (encoded in the this pointer) and a size in bytes. Segments are 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// chained together forming a LIFO structure with the newest segment 40ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// available as segment_head_. Segments are allocated using malloc() 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and de-allocated using free(). 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Segment { 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 45b645116853c677aca8a316381b87441ba6004f67danno@chromium.org void Initialize(Segment* next, int size) { 46b645116853c677aca8a316381b87441ba6004f67danno@chromium.org next_ = next; 47b645116853c677aca8a316381b87441ba6004f67danno@chromium.org size_ = size; 48b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 49b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Segment* next() const { return next_; } 5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void clear_next() { next_ = NULL; } 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int size() const { return size_; } 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int capacity() const { return size_ - sizeof(Segment); } 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address start() const { return address(sizeof(Segment)); } 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address end() const { return address(size_); } 5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Computes the address of the nth byte in this segment. 6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address address(int n) const { 6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Address(this) + n; 6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Segment* next_; 6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int size_; 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 705a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.orgZone::Zone(Isolate* isolate) 711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org : allocation_size_(0), 72b645116853c677aca8a316381b87441ba6004f67danno@chromium.org segment_bytes_allocated_(0), 73b645116853c677aca8a316381b87441ba6004f67danno@chromium.org position_(0), 74b645116853c677aca8a316381b87441ba6004f67danno@chromium.org limit_(0), 755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org segment_head_(NULL), 765a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org isolate_(isolate) { 77b645116853c677aca8a316381b87441ba6004f67danno@chromium.org} 78b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgZone::~Zone() { 81c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org DeleteAll(); 82c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org DeleteKeptSegment(); 83c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 84c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ASSERT(segment_bytes_allocated_ == 0); 85c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 86c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 87c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 88c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid Zone::DeleteAll() { 891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#ifdef DEBUG 901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Constant byte value used for zapping dead memory in debug mode. 911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org static const unsigned char kZapDeadByte = 0xcd; 921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#endif 931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 94c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Find a segment with a suitable size to keep around. 95e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Segment* keep = NULL; 96c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Traverse the chained list of segments, zapping (in debug mode) 97c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // and freeing every segment except the one we wish to keep. 98c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org for (Segment* current = segment_head_; current != NULL; ) { 991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Segment* next = current->next(); 100e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (keep == NULL && current->size() <= kMaximumKeptSegmentSize) { 101c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Unlink the segment we wish to keep from the list. 102e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org keep = current; 103e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org keep->clear_next(); 104c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } else { 105c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org int size = current->size(); 1061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#ifdef DEBUG 107c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Zap the entire current segment (including the header). 108c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org memset(current, kZapDeadByte, size); 1091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#endif 110c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org DeleteSegment(current, size); 111c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 1121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org current = next; 1131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 1141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 115c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // If we have found a segment we want to keep, we must recompute the 116c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // variables 'position' and 'limit' to prepare for future allocate 117c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // attempts. Otherwise, we must clear the position and limit to 118c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // force a new segment to be allocated on demand. 119c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (keep != NULL) { 120c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Address start = keep->start(); 121c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org position_ = RoundUp(start, kAlignment); 122c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org limit_ = keep->end(); 123c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef DEBUG 124c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Zap the contents of the kept segment (but not the header). 125c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org memset(start, kZapDeadByte, keep->capacity()); 126c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif 127c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } else { 128c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org position_ = limit_ = 0; 129c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 130c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 131c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Update the head segment to be the kept segment (if any). 132c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org segment_head_ = keep; 133c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 134c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 135c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 136c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid Zone::DeleteKeptSegment() { 137c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef DEBUG 138c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Constant byte value used for zapping dead memory in debug mode. 139c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org static const unsigned char kZapDeadByte = 0xcd; 140c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif 141c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 142c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ASSERT(segment_head_ == NULL || segment_head_->next() == NULL); 143c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (segment_head_ != NULL) { 144c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org int size = segment_head_->size(); 145c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef DEBUG 146c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Zap the entire kept segment (including the header). 147c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org memset(segment_head_, kZapDeadByte, size); 148c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif 149c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org DeleteSegment(segment_head_, size); 150c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org segment_head_ = NULL; 151c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 1521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 153c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ASSERT(segment_bytes_allocated_ == 0); 154b645116853c677aca8a316381b87441ba6004f67danno@chromium.org} 155b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 156b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 157ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Creates a new segment, sets it size, and pushes it to the front 158ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// of the segment chain. Returns the new segment. 159ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgSegment* Zone::NewSegment(int size) { 160ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Segment* result = reinterpret_cast<Segment*>(Malloced::New(size)); 161ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org adjust_segment_bytes_allocated(size); 162ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (result != NULL) { 163b645116853c677aca8a316381b87441ba6004f67danno@chromium.org result->Initialize(segment_head_, size); 164ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org segment_head_ = result; 165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 166ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return result; 167ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 168ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 169ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 170ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Deletes the given segment. Does not touch the segment chain. 171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid Zone::DeleteSegment(Segment* segment, int size) { 172ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org adjust_segment_bytes_allocated(-size); 173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Malloced::Delete(segment); 174ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAddress Zone::NewExpand(int size) { 17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure the requested size is already properly aligned and that 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // there isn't enough room in the Zone to satisfy the request. 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(size == RoundDown(size, kAlignment)); 18183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ASSERT(size > limit_ - position_); 18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the new segment size. We use a 'high water mark' 18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // strategy, where we increase the segment size every time we expand 18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // except that we employ a maximum segment size when we delete. This 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is to avoid excessive malloc() and free() overhead. 187ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Segment* head = segment_head_; 18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int old_size = (head == NULL) ? 0 : head->size(); 1898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org static const int kSegmentOverhead = sizeof(Segment) + kAlignment; 19083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org int new_size_no_overhead = size + (old_size << 1); 19183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org int new_size = kSegmentOverhead + new_size_no_overhead; 19283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org // Guard against integer overflow. 19383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org if (new_size_no_overhead < size || new_size < kSegmentOverhead) { 19483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org V8::FatalProcessOutOfMemory("Zone"); 19583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org return NULL; 19683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org } 1978bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (new_size < kMinimumSegmentSize) { 1988bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org new_size = kMinimumSegmentSize; 1998bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } else if (new_size > kMaximumSegmentSize) { 2008bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Limit the size of new segments to avoid growing the segment size 2018bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // exponentially, thus putting pressure on contiguous virtual address space. 2028bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // All the while making sure to allocate a segment large enough to hold the 2038bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // requested size. 2048bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org new_size = Max(kSegmentOverhead + size, kMaximumSegmentSize); 2058bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Segment* segment = NewSegment(new_size); 207e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (segment == NULL) { 208e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org V8::FatalProcessOutOfMemory("Zone"); 209e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return NULL; 210e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Recompute 'top' and 'limit' based on the new segment. 21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address result = RoundUp(segment->start(), kAlignment); 21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen position_ = result + size; 21583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org // Check for address overflow. 21683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org if (position_ < result) { 21783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org V8::FatalProcessOutOfMemory("Zone"); 21883e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org return NULL; 21983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org } 22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen limit_ = segment->end(); 22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(position_ <= limit_); 22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 227