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

Side by Side Diff: src/heap-inl.h

Issue 8700: As discussed on the phone, I'd like your thoughts on the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years, 1 month 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 21 matching lines...) Expand all
32 #include "v8-counters.h" 32 #include "v8-counters.h"
33 33
34 namespace v8 { namespace internal { 34 namespace v8 { namespace internal {
35 35
36 int Heap::MaxHeapObjectSize() { 36 int Heap::MaxHeapObjectSize() {
37 return Page::kMaxHeapObjectSize; 37 return Page::kMaxHeapObjectSize;
38 } 38 }
39 39
40 40
41 Object* Heap::AllocateRaw(int size_in_bytes, 41 Object* Heap::AllocateRaw(int size_in_bytes,
42 AllocationSpace space) { 42 AllocationSpace space,
43 AllocationSpace retry_space) {
Erik Corry 2008/10/30 09:08:43 This is fine for now. In the long run I think we
43 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); 44 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
45 ASSERT(space != NEW_SPACE ||
46 retry_space == OLD_POINTER_SPACE ||
47 retry_space == OLD_DATA_SPACE);
44 #ifdef DEBUG 48 #ifdef DEBUG
45 if (FLAG_gc_interval >= 0 && 49 if (FLAG_gc_interval >= 0 &&
46 !disallow_allocation_failure_ && 50 !disallow_allocation_failure_ &&
47 Heap::allocation_timeout_-- <= 0) { 51 Heap::allocation_timeout_-- <= 0) {
48 return Failure::RetryAfterGC(size_in_bytes, space); 52 return Failure::RetryAfterGC(size_in_bytes, space);
49 } 53 }
50 Counters::objs_since_last_full.Increment(); 54 Counters::objs_since_last_full.Increment();
51 Counters::objs_since_last_young.Increment(); 55 Counters::objs_since_last_young.Increment();
52 #endif 56 #endif
57 Object* result;
53 if (NEW_SPACE == space) { 58 if (NEW_SPACE == space) {
54 return new_space_.AllocateRaw(size_in_bytes); 59 result = new_space_.AllocateRaw(size_in_bytes);
60 if (!always_allocate() || !result->IsFailure()) return result;
Mads Ager (chromium) 2008/10/30 08:48:14 Normally, I like these bail-outs instead of if-els
61 space = retry_space;
55 } 62 }
56 63
57 Object* result;
58 if (OLD_POINTER_SPACE == space) { 64 if (OLD_POINTER_SPACE == space) {
59 result = old_pointer_space_->AllocateRaw(size_in_bytes); 65 result = old_pointer_space_->AllocateRaw(size_in_bytes);
60 } else if (OLD_DATA_SPACE == space) { 66 } else if (OLD_DATA_SPACE == space) {
61 result = old_data_space_->AllocateRaw(size_in_bytes); 67 result = old_data_space_->AllocateRaw(size_in_bytes);
62 } else if (CODE_SPACE == space) { 68 } else if (CODE_SPACE == space) {
63 result = code_space_->AllocateRaw(size_in_bytes); 69 result = code_space_->AllocateRaw(size_in_bytes);
64 } else if (LO_SPACE == space) { 70 } else if (LO_SPACE == space) {
65 result = lo_space_->AllocateRaw(size_in_bytes); 71 result = lo_space_->AllocateRaw(size_in_bytes);
66 } else { 72 } else {
67 ASSERT(MAP_SPACE == space); 73 ASSERT(MAP_SPACE == space);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 131
126 void Heap::RecordWrite(Address address, int offset) { 132 void Heap::RecordWrite(Address address, int offset) {
127 if (new_space_.Contains(address)) return; 133 if (new_space_.Contains(address)) return;
128 ASSERT(!new_space_.FromSpaceContains(address)); 134 ASSERT(!new_space_.FromSpaceContains(address));
129 SLOW_ASSERT(Contains(address + offset)); 135 SLOW_ASSERT(Contains(address + offset));
130 Page::SetRSet(address, offset); 136 Page::SetRSet(address, offset);
131 } 137 }
132 138
133 139
134 OldSpace* Heap::TargetSpace(HeapObject* object) { 140 OldSpace* Heap::TargetSpace(HeapObject* object) {
141 InstanceType type = object->map()->instance_type();
142 AllocationSpace space = TargetSpaceId(type);
143 return (space == OLD_POINTER_SPACE)
144 ? old_pointer_space_
145 : old_data_space_;
146 }
147
148
149 AllocationSpace Heap::TargetSpaceId(InstanceType type) {
135 // Heap numbers and sequential strings are promoted to old data space, all 150 // Heap numbers and sequential strings are promoted to old data space, all
136 // other object types are promoted to old pointer space. We do not use 151 // other object types are promoted to old pointer space. We do not use
137 // object->IsHeapNumber() and object->IsSeqString() because we already 152 // object->IsHeapNumber() and object->IsSeqString() because we already
138 // know that object has the heap object tag. 153 // know that object has the heap object tag.
139 InstanceType type = object->map()->instance_type();
140 ASSERT((type != CODE_TYPE) && (type != MAP_TYPE)); 154 ASSERT((type != CODE_TYPE) && (type != MAP_TYPE));
141 bool has_pointers = 155 bool has_pointers =
142 type != HEAP_NUMBER_TYPE && 156 type != HEAP_NUMBER_TYPE &&
143 (type >= FIRST_NONSTRING_TYPE || 157 (type >= FIRST_NONSTRING_TYPE ||
144 String::cast(object)->representation_tag() != kSeqStringTag); 158 (type & kStringRepresentationMask) != kSeqStringTag);
145 return has_pointers ? old_pointer_space_ : old_data_space_; 159 return has_pointers ? OLD_POINTER_SPACE : OLD_DATA_SPACE;
146 } 160 }
147 161
148 162
149 void Heap::CopyBlock(Object** dst, Object** src, int byte_size) { 163 void Heap::CopyBlock(Object** dst, Object** src, int byte_size) {
150 ASSERT(IsAligned(byte_size, kPointerSize)); 164 ASSERT(IsAligned(byte_size, kPointerSize));
151 165
152 // Use block copying memcpy if the segment we're copying is 166 // Use block copying memcpy if the segment we're copying is
153 // enough to justify the extra call/setup overhead. 167 // enough to justify the extra call/setup overhead.
154 static const int kBlockCopyLimit = 16 * kPointerSize; 168 static const int kBlockCopyLimit = 16 * kPointerSize;
155 169
(...skipping 25 matching lines...) Expand all
181 195
182 196
183 void Heap::ClearKeyedLookupCache() { 197 void Heap::ClearKeyedLookupCache() {
184 keyed_lookup_cache_ = undefined_value(); 198 keyed_lookup_cache_ = undefined_value();
185 } 199 }
186 200
187 201
188 #define GC_GREEDY_CHECK() \ 202 #define GC_GREEDY_CHECK() \
189 ASSERT(!FLAG_gc_greedy || v8::internal::Heap::GarbageCollectionGreedyCheck()) 203 ASSERT(!FLAG_gc_greedy || v8::internal::Heap::GarbageCollectionGreedyCheck())
190 204
191 // Do not use the identifier __object__ in a call to this macro. 205
192 // 206 // Calls the FUNCTION_CALL function and retries it up to three times
193 // Call the function FUNCTION_CALL. If it fails with a RetryAfterGC 207 // to guarantee that any allocations performed during the call will
194 // failure, call the garbage collector and retry the function. If the 208 // succeed if there's enough memory.
195 // garbage collector cannot reclaim the required space or the second 209
196 // call fails with a RetryAfterGC failure, fail with out of memory. 210 // Warning: Do not use the identifiers __object__ or __scope__ in a
Erik Corry 2008/10/30 09:08:43 I don't really feel we need this warning, but if w
197 // If there is any other failure, return a null handle. If either 211 // call to this macro.
198 // call succeeds, return a handle to the functions return value. 212
199 // 213 #define CALL_AND_RETRY(FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \
200 // Note that this macro always returns or raises a fatal error. 214 do { \
201 #define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \ 215 GC_GREEDY_CHECK(); \
202 do { \ 216 Object* __object__ = FUNCTION_CALL; \
203 GC_GREEDY_CHECK(); \ 217 if (!__object__->IsFailure()) return RETURN_VALUE; \
204 Object* __object__ = FUNCTION_CALL; \ 218 if (__object__->IsOutOfMemoryFailure()) { \
205 if (__object__->IsFailure()) { \ 219 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0"); \
Erik Corry 2008/10/30 09:08:43 Is there a subtle fall-through here? Comment need
206 if (__object__->IsRetryAfterGC()) { \ 220 } \
207 if (!Heap::CollectGarbage( \ 221 if (!__object__->IsRetryAfterGC()) return RETURN_EMPTY; \
208 Failure::cast(__object__)->requested(), \ 222 if (!Heap::CollectGarbage( \
209 Failure::cast(__object__)->allocation_space())) { \ 223 Failure::cast(__object__)->requested(), \
210 /* TODO(1181417): Fix this. */ \ 224 Failure::cast(__object__)->allocation_space())) { \
211 v8::internal::V8::FatalProcessOutOfMemory("CALL_HEAP_FUNCTION"); \ 225 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1"); \
212 } \ 226 } \
213 __object__ = FUNCTION_CALL; \ 227 __object__ = FUNCTION_CALL; \
214 if (__object__->IsFailure()) { \ 228 if (!__object__->IsFailure()) return RETURN_VALUE; \
215 if (__object__->IsRetryAfterGC()) { \ 229 if (__object__->IsOutOfMemoryFailure()) { \
216 /* TODO(1181417): Fix this. */ \ 230 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2"); \
217 v8::internal::V8::FatalProcessOutOfMemory("CALL_HEAP_FUNCTION"); \ 231 } \
218 } \ 232 if (!__object__->IsRetryAfterGC()) return RETURN_EMPTY; \
219 return Handle<TYPE>(); \ 233 Counters::gc_last_resort_from_handles.Increment(); \
220 } \ 234 Heap::CollectAllGarbage(); \
221 } else { \ 235 { \
222 if (__object__->IsOutOfMemoryFailure()) { \ 236 AlwaysAllocateScope __scope__; \
223 v8::internal::V8::FatalProcessOutOfMemory("CALL_HEAP_FUNCTION"); \ 237 __object__ = FUNCTION_CALL; \
224 } \ 238 } \
225 return Handle<TYPE>(); \ 239 if (!__object__->IsFailure()) return RETURN_VALUE; \
226 } \ 240 if (__object__->IsOutOfMemoryFailure()) { \
227 } \ 241 /* TODO(1181417): Fix this. */ \
228 return Handle<TYPE>(TYPE::cast(__object__)); \ 242 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_3"); \
243 } \
244 ASSERT(!__object__->IsRetryAfterGC()); \
245 return RETURN_EMPTY; \
229 } while (false) 246 } while (false)
230 247
231 248
232 // Don't use the following names: __object__, __failure__. 249 #define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \
233 #define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL) \ 250 CALL_AND_RETRY(FUNCTION_CALL, \
234 GC_GREEDY_CHECK(); \ 251 Handle<TYPE>(TYPE::cast(__object__)), \
235 Object* __object__ = FUNCTION_CALL; \ 252 Handle<TYPE>())
236 if (__object__->IsFailure()) { \ 253
237 if (__object__->IsRetryAfterGC()) { \ 254
238 Failure* __failure__ = Failure::cast(__object__); \ 255 #define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL) \
239 if (!Heap::CollectGarbage(__failure__->requested(), \ 256 CALL_AND_RETRY(FUNCTION_CALL,,)
240 __failure__->allocation_space())) { \
241 /* TODO(1181417): Fix this. */ \
242 V8::FatalProcessOutOfMemory("Handles"); \
243 } \
244 __object__ = FUNCTION_CALL; \
245 if (__object__->IsFailure()) { \
246 if (__object__->IsRetryAfterGC()) { \
247 /* TODO(1181417): Fix this. */ \
248 V8::FatalProcessOutOfMemory("Handles"); \
249 } \
250 return; \
251 } \
252 } else { \
253 if (__object__->IsOutOfMemoryFailure()) { \
254 V8::FatalProcessOutOfMemory("Handles"); \
255 } \
256 UNREACHABLE(); \
257 } \
258 }
259 257
260 258
261 #ifdef DEBUG 259 #ifdef DEBUG
262 260
263 inline bool Heap::allow_allocation(bool new_state) { 261 inline bool Heap::allow_allocation(bool new_state) {
264 bool old = allocation_allowed_; 262 bool old = allocation_allowed_;
265 allocation_allowed_ = new_state; 263 allocation_allowed_ = new_state;
266 return old; 264 return old;
267 } 265 }
268 266
269 #endif 267 #endif
270 268
271 269
272 } } // namespace v8::internal 270 } } // namespace v8::internal
273 271
274 #endif // V8_HEAP_INL_H_ 272 #endif // V8_HEAP_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698