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

Unified 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, 2 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 side-by-side diff with in-line comments
Download patch
Index: src/heap-inl.h
===================================================================
--- src/heap-inl.h (revision 645)
+++ src/heap-inl.h (working copy)
@@ -39,8 +39,12 @@
Object* Heap::AllocateRaw(int size_in_bytes,
- AllocationSpace space) {
+ AllocationSpace space,
+ AllocationSpace retry_space) {
Erik Corry 2008/10/30 09:08:43 This is fine for now. In the long run I think we
ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
+ ASSERT(space != NEW_SPACE ||
+ retry_space == OLD_POINTER_SPACE ||
+ retry_space == OLD_DATA_SPACE);
#ifdef DEBUG
if (FLAG_gc_interval >= 0 &&
!disallow_allocation_failure_ &&
@@ -50,11 +54,13 @@
Counters::objs_since_last_full.Increment();
Counters::objs_since_last_young.Increment();
#endif
+ Object* result;
if (NEW_SPACE == space) {
- return new_space_.AllocateRaw(size_in_bytes);
+ result = new_space_.AllocateRaw(size_in_bytes);
+ 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
+ space = retry_space;
}
- Object* result;
if (OLD_POINTER_SPACE == space) {
result = old_pointer_space_->AllocateRaw(size_in_bytes);
} else if (OLD_DATA_SPACE == space) {
@@ -132,17 +138,25 @@
OldSpace* Heap::TargetSpace(HeapObject* object) {
+ InstanceType type = object->map()->instance_type();
+ AllocationSpace space = TargetSpaceId(type);
+ return (space == OLD_POINTER_SPACE)
+ ? old_pointer_space_
+ : old_data_space_;
+}
+
+
+AllocationSpace Heap::TargetSpaceId(InstanceType type) {
// Heap numbers and sequential strings are promoted to old data space, all
// other object types are promoted to old pointer space. We do not use
// object->IsHeapNumber() and object->IsSeqString() because we already
// know that object has the heap object tag.
- InstanceType type = object->map()->instance_type();
ASSERT((type != CODE_TYPE) && (type != MAP_TYPE));
bool has_pointers =
type != HEAP_NUMBER_TYPE &&
(type >= FIRST_NONSTRING_TYPE ||
- String::cast(object)->representation_tag() != kSeqStringTag);
- return has_pointers ? old_pointer_space_ : old_data_space_;
+ (type & kStringRepresentationMask) != kSeqStringTag);
+ return has_pointers ? OLD_POINTER_SPACE : OLD_DATA_SPACE;
}
@@ -188,76 +202,60 @@
#define GC_GREEDY_CHECK() \
ASSERT(!FLAG_gc_greedy || v8::internal::Heap::GarbageCollectionGreedyCheck())
-// Do not use the identifier __object__ in a call to this macro.
-//
-// Call the function FUNCTION_CALL. If it fails with a RetryAfterGC
-// failure, call the garbage collector and retry the function. If the
-// garbage collector cannot reclaim the required space or the second
-// call fails with a RetryAfterGC failure, fail with out of memory.
-// If there is any other failure, return a null handle. If either
-// call succeeds, return a handle to the functions return value.
-//
-// Note that this macro always returns or raises a fatal error.
-#define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \
- do { \
- GC_GREEDY_CHECK(); \
- Object* __object__ = FUNCTION_CALL; \
- if (__object__->IsFailure()) { \
- if (__object__->IsRetryAfterGC()) { \
- if (!Heap::CollectGarbage( \
- Failure::cast(__object__)->requested(), \
- Failure::cast(__object__)->allocation_space())) { \
- /* TODO(1181417): Fix this. */ \
- v8::internal::V8::FatalProcessOutOfMemory("CALL_HEAP_FUNCTION"); \
- } \
- __object__ = FUNCTION_CALL; \
- if (__object__->IsFailure()) { \
- if (__object__->IsRetryAfterGC()) { \
- /* TODO(1181417): Fix this. */ \
- v8::internal::V8::FatalProcessOutOfMemory("CALL_HEAP_FUNCTION"); \
- } \
- return Handle<TYPE>(); \
- } \
- } else { \
- if (__object__->IsOutOfMemoryFailure()) { \
- v8::internal::V8::FatalProcessOutOfMemory("CALL_HEAP_FUNCTION"); \
- } \
- return Handle<TYPE>(); \
- } \
- } \
- return Handle<TYPE>(TYPE::cast(__object__)); \
+
+// Calls the FUNCTION_CALL function and retries it up to three times
+// to guarantee that any allocations performed during the call will
+// succeed if there's enough memory.
+
+// 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
+// call to this macro.
+
+#define CALL_AND_RETRY(FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \
+ do { \
+ GC_GREEDY_CHECK(); \
+ Object* __object__ = FUNCTION_CALL; \
+ if (!__object__->IsFailure()) return RETURN_VALUE; \
+ if (__object__->IsOutOfMemoryFailure()) { \
+ 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
+ } \
+ if (!__object__->IsRetryAfterGC()) return RETURN_EMPTY; \
+ if (!Heap::CollectGarbage( \
+ Failure::cast(__object__)->requested(), \
+ Failure::cast(__object__)->allocation_space())) { \
+ v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1"); \
+ } \
+ __object__ = FUNCTION_CALL; \
+ if (!__object__->IsFailure()) return RETURN_VALUE; \
+ if (__object__->IsOutOfMemoryFailure()) { \
+ v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2"); \
+ } \
+ if (!__object__->IsRetryAfterGC()) return RETURN_EMPTY; \
+ Counters::gc_last_resort_from_handles.Increment(); \
+ Heap::CollectAllGarbage(); \
+ { \
+ AlwaysAllocateScope __scope__; \
+ __object__ = FUNCTION_CALL; \
+ } \
+ if (!__object__->IsFailure()) return RETURN_VALUE; \
+ if (__object__->IsOutOfMemoryFailure()) { \
+ /* TODO(1181417): Fix this. */ \
+ v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_3"); \
+ } \
+ ASSERT(!__object__->IsRetryAfterGC()); \
+ return RETURN_EMPTY; \
} while (false)
-// Don't use the following names: __object__, __failure__.
-#define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL) \
- GC_GREEDY_CHECK(); \
- Object* __object__ = FUNCTION_CALL; \
- if (__object__->IsFailure()) { \
- if (__object__->IsRetryAfterGC()) { \
- Failure* __failure__ = Failure::cast(__object__); \
- if (!Heap::CollectGarbage(__failure__->requested(), \
- __failure__->allocation_space())) { \
- /* TODO(1181417): Fix this. */ \
- V8::FatalProcessOutOfMemory("Handles"); \
- } \
- __object__ = FUNCTION_CALL; \
- if (__object__->IsFailure()) { \
- if (__object__->IsRetryAfterGC()) { \
- /* TODO(1181417): Fix this. */ \
- V8::FatalProcessOutOfMemory("Handles"); \
- } \
- return; \
- } \
- } else { \
- if (__object__->IsOutOfMemoryFailure()) { \
- V8::FatalProcessOutOfMemory("Handles"); \
- } \
- UNREACHABLE(); \
- } \
- }
+#define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \
+ CALL_AND_RETRY(FUNCTION_CALL, \
+ Handle<TYPE>(TYPE::cast(__object__)), \
+ Handle<TYPE>())
+#define CALL_HEAP_FUNCTION_VOID(FUNCTION_CALL) \
+ CALL_AND_RETRY(FUNCTION_CALL,,)
+
+
#ifdef DEBUG
inline bool Heap::allow_allocation(bool new_state) {

Powered by Google App Engine
This is Rietveld 408576698