OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/factory.h" | 5 #include "src/factory.h" |
6 | 6 |
7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
11 #include "src/isolate-inl.h" | 11 #include "src/isolate-inl.h" |
12 #include "src/macro-assembler.h" | 12 #include "src/macro-assembler.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 | 16 |
17 | 17 |
| 18 // Calls the FUNCTION_CALL function and retries it up to three times |
| 19 // to guarantee that any allocations performed during the call will |
| 20 // succeed if there's enough memory. |
| 21 // |
| 22 // Warning: Do not use the identifiers __object__, __maybe_object__, |
| 23 // __allocation__ or __scope__ in a call to this macro. |
| 24 |
| 25 #define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ |
| 26 if (__allocation__.To(&__object__)) { \ |
| 27 DCHECK(__object__ != (ISOLATE)->heap()->exception()); \ |
| 28 return Handle<TYPE>(TYPE::cast(__object__), ISOLATE); \ |
| 29 } |
| 30 |
| 31 #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ |
| 32 do { \ |
| 33 AllocationResult __allocation__ = FUNCTION_CALL; \ |
| 34 Object* __object__ = NULL; \ |
| 35 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ |
| 36 /* Two GCs before panicking. In newspace will almost always succeed. */ \ |
| 37 for (int __i__ = 0; __i__ < 2; __i__++) { \ |
| 38 (ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \ |
| 39 "allocation failure"); \ |
| 40 __allocation__ = FUNCTION_CALL; \ |
| 41 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ |
| 42 } \ |
| 43 (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \ |
| 44 (ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \ |
| 45 { \ |
| 46 AlwaysAllocateScope __scope__(ISOLATE); \ |
| 47 __allocation__ = FUNCTION_CALL; \ |
| 48 } \ |
| 49 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ |
| 50 /* TODO(1181417): Fix this. */ \ |
| 51 v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \ |
| 52 return Handle<TYPE>(); \ |
| 53 } while (false) |
| 54 |
| 55 |
18 template<typename T> | 56 template<typename T> |
19 Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) { | 57 Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) { |
20 CALL_HEAP_FUNCTION( | 58 CALL_HEAP_FUNCTION( |
21 isolate(), | 59 isolate(), |
22 isolate()->heap()->Allocate(*map, space), | 60 isolate()->heap()->Allocate(*map, space), |
23 T); | 61 T); |
24 } | 62 } |
25 | 63 |
26 | 64 |
27 template<typename T> | 65 template<typename T> |
(...skipping 2346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2374 } | 2412 } |
2375 | 2413 |
2376 | 2414 |
2377 Handle<Object> Factory::ToBoolean(bool value) { | 2415 Handle<Object> Factory::ToBoolean(bool value) { |
2378 return value ? true_value() : false_value(); | 2416 return value ? true_value() : false_value(); |
2379 } | 2417 } |
2380 | 2418 |
2381 | 2419 |
2382 } // namespace internal | 2420 } // namespace internal |
2383 } // namespace v8 | 2421 } // namespace v8 |
OLD | NEW |