Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: src/zone.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/zone.h ('k') | src/zone-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 16 matching lines...) Expand all
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "zone-inl.h" 30 #include "zone-inl.h"
31 #include "splay-tree-inl.h" 31 #include "splay-tree-inl.h"
32 32
33 namespace v8 { 33 namespace v8 {
34 namespace internal { 34 namespace internal {
35 35
36 36
37 Address Zone::position_ = 0; 37 Zone::Zone()
38 Address Zone::limit_ = 0; 38 : zone_excess_limit_(256 * MB),
39 int Zone::zone_excess_limit_ = 256 * MB; 39 segment_bytes_allocated_(0),
40 int Zone::segment_bytes_allocated_ = 0; 40 position_(0),
41 limit_(0),
42 scope_nesting_(0),
43 segment_head_(NULL) {
44 }
41 unsigned Zone::allocation_size_ = 0; 45 unsigned Zone::allocation_size_ = 0;
42 46
43 bool AssertNoZoneAllocation::allow_allocation_ = true;
44 47
45 int ZoneScope::nesting_ = 0; 48 ZoneScope::~ZoneScope() {
49 ASSERT_EQ(Isolate::Current(), isolate_);
50 if (ShouldDeleteOnExit()) isolate_->zone()->DeleteAll();
51 isolate_->zone()->scope_nesting_--;
52 }
53
46 54
47 // Segments represent chunks of memory: They have starting address 55 // Segments represent chunks of memory: They have starting address
48 // (encoded in the this pointer) and a size in bytes. Segments are 56 // (encoded in the this pointer) and a size in bytes. Segments are
49 // chained together forming a LIFO structure with the newest segment 57 // chained together forming a LIFO structure with the newest segment
50 // available as Segment::head(). Segments are allocated using malloc() 58 // available as segment_head_. Segments are allocated using malloc()
51 // and de-allocated using free(). 59 // and de-allocated using free().
52 60
53 class Segment { 61 class Segment {
54 public: 62 public:
55 Segment* next() const { return next_; } 63 Segment* next() const { return next_; }
56 void clear_next() { next_ = NULL; } 64 void clear_next() { next_ = NULL; }
57 65
58 int size() const { return size_; } 66 int size() const { return size_; }
59 int capacity() const { return size_ - sizeof(Segment); } 67 int capacity() const { return size_ - sizeof(Segment); }
60 68
61 Address start() const { return address(sizeof(Segment)); } 69 Address start() const { return address(sizeof(Segment)); }
62 Address end() const { return address(size_); } 70 Address end() const { return address(size_); }
63 71
64 static Segment* head() { return head_; }
65 static void set_head(Segment* head) { head_ = head; }
66
67 // Creates a new segment, sets it size, and pushes it to the front
68 // of the segment chain. Returns the new segment.
69 static Segment* New(int size) {
70 Segment* result = reinterpret_cast<Segment*>(Malloced::New(size));
71 Zone::adjust_segment_bytes_allocated(size);
72 if (result != NULL) {
73 result->next_ = head_;
74 result->size_ = size;
75 head_ = result;
76 }
77 return result;
78 }
79
80 // Deletes the given segment. Does not touch the segment chain.
81 static void Delete(Segment* segment, int size) {
82 Zone::adjust_segment_bytes_allocated(-size);
83 Malloced::Delete(segment);
84 }
85
86 static int bytes_allocated() { return bytes_allocated_; }
87
88 private: 72 private:
89 // Computes the address of the nth byte in this segment. 73 // Computes the address of the nth byte in this segment.
90 Address address(int n) const { 74 Address address(int n) const {
91 return Address(this) + n; 75 return Address(this) + n;
92 } 76 }
93 77
94 static Segment* head_;
95 static int bytes_allocated_;
96 Segment* next_; 78 Segment* next_;
97 int size_; 79 int size_;
80
81 friend class Zone;
98 }; 82 };
99 83
100 84
101 Segment* Segment::head_ = NULL; 85 // Creates a new segment, sets it size, and pushes it to the front
102 int Segment::bytes_allocated_ = 0; 86 // of the segment chain. Returns the new segment.
87 Segment* Zone::NewSegment(int size) {
88 Segment* result = reinterpret_cast<Segment*>(Malloced::New(size));
89 adjust_segment_bytes_allocated(size);
90 if (result != NULL) {
91 result->next_ = segment_head_;
92 result->size_ = size;
93 segment_head_ = result;
94 }
95 return result;
96 }
97
98
99 // Deletes the given segment. Does not touch the segment chain.
100 void Zone::DeleteSegment(Segment* segment, int size) {
101 adjust_segment_bytes_allocated(-size);
102 Malloced::Delete(segment);
103 }
103 104
104 105
105 void Zone::DeleteAll() { 106 void Zone::DeleteAll() {
106 #ifdef DEBUG 107 #ifdef DEBUG
107 // Constant byte value used for zapping dead memory in debug mode. 108 // Constant byte value used for zapping dead memory in debug mode.
108 static const unsigned char kZapDeadByte = 0xcd; 109 static const unsigned char kZapDeadByte = 0xcd;
109 #endif 110 #endif
110 111
111 // Find a segment with a suitable size to keep around. 112 // Find a segment with a suitable size to keep around.
112 Segment* keep = Segment::head(); 113 Segment* keep = segment_head_;
113 while (keep != NULL && keep->size() > kMaximumKeptSegmentSize) { 114 while (keep != NULL && keep->size() > kMaximumKeptSegmentSize) {
114 keep = keep->next(); 115 keep = keep->next();
115 } 116 }
116 117
117 // Traverse the chained list of segments, zapping (in debug mode) 118 // Traverse the chained list of segments, zapping (in debug mode)
118 // and freeing every segment except the one we wish to keep. 119 // and freeing every segment except the one we wish to keep.
119 Segment* current = Segment::head(); 120 Segment* current = segment_head_;
120 while (current != NULL) { 121 while (current != NULL) {
121 Segment* next = current->next(); 122 Segment* next = current->next();
122 if (current == keep) { 123 if (current == keep) {
123 // Unlink the segment we wish to keep from the list. 124 // Unlink the segment we wish to keep from the list.
124 current->clear_next(); 125 current->clear_next();
125 } else { 126 } else {
126 int size = current->size(); 127 int size = current->size();
127 #ifdef DEBUG 128 #ifdef DEBUG
128 // Zap the entire current segment (including the header). 129 // Zap the entire current segment (including the header).
129 memset(current, kZapDeadByte, size); 130 memset(current, kZapDeadByte, size);
130 #endif 131 #endif
131 Segment::Delete(current, size); 132 DeleteSegment(current, size);
132 } 133 }
133 current = next; 134 current = next;
134 } 135 }
135 136
136 // If we have found a segment we want to keep, we must recompute the 137 // If we have found a segment we want to keep, we must recompute the
137 // variables 'position' and 'limit' to prepare for future allocate 138 // variables 'position' and 'limit' to prepare for future allocate
138 // attempts. Otherwise, we must clear the position and limit to 139 // attempts. Otherwise, we must clear the position and limit to
139 // force a new segment to be allocated on demand. 140 // force a new segment to be allocated on demand.
140 if (keep != NULL) { 141 if (keep != NULL) {
141 Address start = keep->start(); 142 Address start = keep->start();
142 position_ = RoundUp(start, kAlignment); 143 position_ = RoundUp(start, kAlignment);
143 limit_ = keep->end(); 144 limit_ = keep->end();
144 #ifdef DEBUG 145 #ifdef DEBUG
145 // Zap the contents of the kept segment (but not the header). 146 // Zap the contents of the kept segment (but not the header).
146 memset(start, kZapDeadByte, keep->capacity()); 147 memset(start, kZapDeadByte, keep->capacity());
147 #endif 148 #endif
148 } else { 149 } else {
149 position_ = limit_ = 0; 150 position_ = limit_ = 0;
150 } 151 }
151 152
152 // Update the head segment to be the kept segment (if any). 153 // Update the head segment to be the kept segment (if any).
153 Segment::set_head(keep); 154 segment_head_ = keep;
154 } 155 }
155 156
156 157
157 Address Zone::NewExpand(int size) { 158 Address Zone::NewExpand(int size) {
158 // Make sure the requested size is already properly aligned and that 159 // Make sure the requested size is already properly aligned and that
159 // there isn't enough room in the Zone to satisfy the request. 160 // there isn't enough room in the Zone to satisfy the request.
160 ASSERT(size == RoundDown(size, kAlignment)); 161 ASSERT(size == RoundDown(size, kAlignment));
161 ASSERT(position_ + size > limit_); 162 ASSERT(position_ + size > limit_);
162 163
163 // Compute the new segment size. We use a 'high water mark' 164 // Compute the new segment size. We use a 'high water mark'
164 // strategy, where we increase the segment size every time we expand 165 // strategy, where we increase the segment size every time we expand
165 // except that we employ a maximum segment size when we delete. This 166 // except that we employ a maximum segment size when we delete. This
166 // is to avoid excessive malloc() and free() overhead. 167 // is to avoid excessive malloc() and free() overhead.
167 Segment* head = Segment::head(); 168 Segment* head = segment_head_;
168 int old_size = (head == NULL) ? 0 : head->size(); 169 int old_size = (head == NULL) ? 0 : head->size();
169 static const int kSegmentOverhead = sizeof(Segment) + kAlignment; 170 static const int kSegmentOverhead = sizeof(Segment) + kAlignment;
170 int new_size = kSegmentOverhead + size + (old_size << 1); 171 int new_size = kSegmentOverhead + size + (old_size << 1);
171 if (new_size < kMinimumSegmentSize) { 172 if (new_size < kMinimumSegmentSize) {
172 new_size = kMinimumSegmentSize; 173 new_size = kMinimumSegmentSize;
173 } else if (new_size > kMaximumSegmentSize) { 174 } else if (new_size > kMaximumSegmentSize) {
174 // Limit the size of new segments to avoid growing the segment size 175 // Limit the size of new segments to avoid growing the segment size
175 // exponentially, thus putting pressure on contiguous virtual address space. 176 // exponentially, thus putting pressure on contiguous virtual address space.
176 // All the while making sure to allocate a segment large enough to hold the 177 // All the while making sure to allocate a segment large enough to hold the
177 // requested size. 178 // requested size.
178 new_size = Max(kSegmentOverhead + size, kMaximumSegmentSize); 179 new_size = Max(kSegmentOverhead + size, kMaximumSegmentSize);
179 } 180 }
180 Segment* segment = Segment::New(new_size); 181 Segment* segment = NewSegment(new_size);
181 if (segment == NULL) { 182 if (segment == NULL) {
182 V8::FatalProcessOutOfMemory("Zone"); 183 V8::FatalProcessOutOfMemory("Zone");
183 return NULL; 184 return NULL;
184 } 185 }
185 186
186 // Recompute 'top' and 'limit' based on the new segment. 187 // Recompute 'top' and 'limit' based on the new segment.
187 Address result = RoundUp(segment->start(), kAlignment); 188 Address result = RoundUp(segment->start(), kAlignment);
188 position_ = result + size; 189 position_ = result + size;
189 limit_ = segment->end(); 190 limit_ = segment->end();
190 ASSERT(position_ <= limit_); 191 ASSERT(position_ <= limit_);
191 return result; 192 return result;
192 } 193 }
193 194
194 195
195 } } // namespace v8::internal 196 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/zone.h ('k') | src/zone-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698