Update to 5.0.0-beta1
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / heap.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_HEAP_H_
29 #define V8_HEAP_H_
30
31 #include <math.h>
32
33 #include "allocation.h"
34 #include "globals.h"
35 #include "incremental-marking.h"
36 #include "list.h"
37 #include "mark-compact.h"
38 #include "objects-visiting.h"
39 #include "spaces.h"
40 #include "splay-tree-inl.h"
41 #include "store-buffer.h"
42 #include "v8-counters.h"
43 #include "v8globals.h"
44
45 namespace v8 {
46 namespace internal {
47
48 // Defines all the roots in Heap.
49 #define STRONG_ROOT_LIST(V)                                                    \
50   V(Map, byte_array_map, ByteArrayMap)                                         \
51   V(Map, free_space_map, FreeSpaceMap)                                         \
52   V(Map, one_pointer_filler_map, OnePointerFillerMap)                          \
53   V(Map, two_pointer_filler_map, TwoPointerFillerMap)                          \
54   /* Cluster the most popular ones in a few cache lines here at the top.    */ \
55   V(Smi, store_buffer_top, StoreBufferTop)                                     \
56   V(Oddball, undefined_value, UndefinedValue)                                  \
57   V(Oddball, the_hole_value, TheHoleValue)                                     \
58   V(Oddball, null_value, NullValue)                                            \
59   V(Oddball, true_value, TrueValue)                                            \
60   V(Oddball, false_value, FalseValue)                                          \
61   V(Map, global_property_cell_map, GlobalPropertyCellMap)                      \
62   V(Map, shared_function_info_map, SharedFunctionInfoMap)                      \
63   V(Map, meta_map, MetaMap)                                                    \
64   V(Map, ascii_symbol_map, AsciiSymbolMap)                                     \
65   V(Map, ascii_string_map, AsciiStringMap)                                     \
66   V(Map, heap_number_map, HeapNumberMap)                                       \
67   V(Map, global_context_map, GlobalContextMap)                                 \
68   V(Map, fixed_array_map, FixedArrayMap)                                       \
69   V(Map, code_map, CodeMap)                                                    \
70   V(Map, scope_info_map, ScopeInfoMap)                                         \
71   V(Map, fixed_cow_array_map, FixedCOWArrayMap)                                \
72   V(Map, fixed_double_array_map, FixedDoubleArrayMap)                          \
73   V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel)       \
74   V(Map, hash_table_map, HashTableMap)                                         \
75   V(FixedArray, empty_fixed_array, EmptyFixedArray)                            \
76   V(ByteArray, empty_byte_array, EmptyByteArray)                               \
77   V(String, empty_string, EmptyString)                                         \
78   V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray)             \
79   V(Smi, stack_limit, StackLimit)                                              \
80   V(Oddball, arguments_marker, ArgumentsMarker)                                \
81   /* The first 32 roots above this line should be boring from a GC point of */ \
82   /* view.  This means they are never in new space and never on a page that */ \
83   /* is being compacted.                                                    */ \
84   V(FixedArray, number_string_cache, NumberStringCache)                        \
85   V(Object, instanceof_cache_function, InstanceofCacheFunction)                \
86   V(Object, instanceof_cache_map, InstanceofCacheMap)                          \
87   V(Object, instanceof_cache_answer, InstanceofCacheAnswer)                    \
88   V(FixedArray, single_character_string_cache, SingleCharacterStringCache)     \
89   V(FixedArray, string_split_cache, StringSplitCache)                          \
90   V(Object, termination_exception, TerminationException)                       \
91   V(Smi, hash_seed, HashSeed)                                                  \
92   V(Map, string_map, StringMap)                                                \
93   V(Map, symbol_map, SymbolMap)                                                \
94   V(Map, cons_string_map, ConsStringMap)                                       \
95   V(Map, cons_ascii_string_map, ConsAsciiStringMap)                            \
96   V(Map, sliced_string_map, SlicedStringMap)                                   \
97   V(Map, sliced_ascii_string_map, SlicedAsciiStringMap)                        \
98   V(Map, cons_symbol_map, ConsSymbolMap)                                       \
99   V(Map, cons_ascii_symbol_map, ConsAsciiSymbolMap)                            \
100   V(Map, external_symbol_map, ExternalSymbolMap)                               \
101   V(Map, external_symbol_with_ascii_data_map, ExternalSymbolWithAsciiDataMap)  \
102   V(Map, external_ascii_symbol_map, ExternalAsciiSymbolMap)                    \
103   V(Map, external_string_map, ExternalStringMap)                               \
104   V(Map, external_string_with_ascii_data_map, ExternalStringWithAsciiDataMap)  \
105   V(Map, external_ascii_string_map, ExternalAsciiStringMap)                    \
106   V(Map, short_external_symbol_map, ShortExternalSymbolMap)                    \
107   V(Map,                                                                       \
108     short_external_symbol_with_ascii_data_map,                                 \
109     ShortExternalSymbolWithAsciiDataMap)                                       \
110   V(Map, short_external_ascii_symbol_map, ShortExternalAsciiSymbolMap)         \
111   V(Map, short_external_string_map, ShortExternalStringMap)                    \
112   V(Map,                                                                       \
113     short_external_string_with_ascii_data_map,                                 \
114     ShortExternalStringWithAsciiDataMap)                                       \
115   V(Map, short_external_ascii_string_map, ShortExternalAsciiStringMap)         \
116   V(Map, undetectable_string_map, UndetectableStringMap)                       \
117   V(Map, undetectable_ascii_string_map, UndetectableAsciiStringMap)            \
118   V(Map, external_pixel_array_map, ExternalPixelArrayMap)                      \
119   V(Map, external_byte_array_map, ExternalByteArrayMap)                        \
120   V(Map, external_unsigned_byte_array_map, ExternalUnsignedByteArrayMap)       \
121   V(Map, external_short_array_map, ExternalShortArrayMap)                      \
122   V(Map, external_unsigned_short_array_map, ExternalUnsignedShortArrayMap)     \
123   V(Map, external_int_array_map, ExternalIntArrayMap)                          \
124   V(Map, external_unsigned_int_array_map, ExternalUnsignedIntArrayMap)         \
125   V(Map, external_float_array_map, ExternalFloatArrayMap)                      \
126   V(Map, external_double_array_map, ExternalDoubleArrayMap)                    \
127   V(Map, non_strict_arguments_elements_map, NonStrictArgumentsElementsMap)     \
128   V(Map, function_context_map, FunctionContextMap)                             \
129   V(Map, catch_context_map, CatchContextMap)                                   \
130   V(Map, with_context_map, WithContextMap)                                     \
131   V(Map, block_context_map, BlockContextMap)                                   \
132   V(Map, module_context_map, ModuleContextMap)                                 \
133   V(Map, oddball_map, OddballMap)                                              \
134   V(Map, message_object_map, JSMessageObjectMap)                               \
135   V(Map, foreign_map, ForeignMap)                                              \
136   V(HeapNumber, nan_value, NanValue)                                           \
137   V(HeapNumber, infinity_value, InfinityValue)                                 \
138   V(HeapNumber, minus_zero_value, MinusZeroValue)                              \
139   V(Map, neander_map, NeanderMap)                                              \
140   V(JSObject, message_listeners, MessageListeners)                             \
141   V(Foreign, prototype_accessors, PrototypeAccessors)                          \
142   V(UnseededNumberDictionary, code_stubs, CodeStubs)                           \
143   V(UnseededNumberDictionary, non_monomorphic_cache, NonMonomorphicCache)      \
144   V(PolymorphicCodeCache, polymorphic_code_cache, PolymorphicCodeCache)        \
145   V(Code, js_entry_code, JsEntryCode)                                          \
146   V(Code, js_construct_entry_code, JsConstructEntryCode)                       \
147   V(FixedArray, natives_source_cache, NativesSourceCache)                      \
148   V(Object, last_script_id, LastScriptId)                                      \
149   V(Script, empty_script, EmptyScript)                                         \
150   V(Smi, real_stack_limit, RealStackLimit)                                     \
151   V(StringDictionary, intrinsic_function_names, IntrinsicFunctionNames)        \
152   V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset)     \
153   V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset)
154
155 #define ROOT_LIST(V)                                  \
156   STRONG_ROOT_LIST(V)                                 \
157   V(SymbolTable, symbol_table, SymbolTable)
158
159 #define SYMBOL_LIST(V)                                                   \
160   V(Array_symbol, "Array")                                               \
161   V(Object_symbol, "Object")                                             \
162   V(Proto_symbol, "__proto__")                                           \
163   V(StringImpl_symbol, "StringImpl")                                     \
164   V(arguments_symbol, "arguments")                                       \
165   V(Arguments_symbol, "Arguments")                                       \
166   V(call_symbol, "call")                                                 \
167   V(apply_symbol, "apply")                                               \
168   V(caller_symbol, "caller")                                             \
169   V(boolean_symbol, "boolean")                                           \
170   V(Boolean_symbol, "Boolean")                                           \
171   V(callee_symbol, "callee")                                             \
172   V(constructor_symbol, "constructor")                                   \
173   V(code_symbol, ".code")                                                \
174   V(result_symbol, ".result")                                            \
175   V(catch_var_symbol, ".catch-var")                                      \
176   V(empty_symbol, "")                                                    \
177   V(eval_symbol, "eval")                                                 \
178   V(function_symbol, "function")                                         \
179   V(length_symbol, "length")                                             \
180   V(module_symbol, "module")                                             \
181   V(name_symbol, "name")                                                 \
182   V(native_symbol, "native")                                             \
183   V(null_symbol, "null")                                                 \
184   V(number_symbol, "number")                                             \
185   V(Number_symbol, "Number")                                             \
186   V(nan_symbol, "NaN")                                                   \
187   V(RegExp_symbol, "RegExp")                                             \
188   V(source_symbol, "source")                                             \
189   V(global_symbol, "global")                                             \
190   V(ignore_case_symbol, "ignoreCase")                                    \
191   V(multiline_symbol, "multiline")                                       \
192   V(input_symbol, "input")                                               \
193   V(index_symbol, "index")                                               \
194   V(last_index_symbol, "lastIndex")                                      \
195   V(object_symbol, "object")                                             \
196   V(prototype_symbol, "prototype")                                       \
197   V(string_symbol, "string")                                             \
198   V(String_symbol, "String")                                             \
199   V(Date_symbol, "Date")                                                 \
200   V(Error_symbol, "Error")                                               \
201   V(this_symbol, "this")                                                 \
202   V(to_string_symbol, "toString")                                        \
203   V(char_at_symbol, "CharAt")                                            \
204   V(undefined_symbol, "undefined")                                       \
205   V(value_of_symbol, "valueOf")                                          \
206   V(InitializeVarGlobal_symbol, "InitializeVarGlobal")                   \
207   V(InitializeConstGlobal_symbol, "InitializeConstGlobal")               \
208   V(KeyedLoadElementMonomorphic_symbol,                                  \
209     "KeyedLoadElementMonomorphic")                                       \
210   V(KeyedStoreElementMonomorphic_symbol,                                 \
211     "KeyedStoreElementMonomorphic")                                      \
212   V(KeyedStoreAndGrowElementMonomorphic_symbol,                          \
213     "KeyedStoreAndGrowElementMonomorphic")                               \
214   V(stack_overflow_symbol, "kStackOverflowBoilerplate")                  \
215   V(illegal_access_symbol, "illegal access")                             \
216   V(out_of_memory_symbol, "out-of-memory")                               \
217   V(illegal_execution_state_symbol, "illegal execution state")           \
218   V(get_symbol, "get")                                                   \
219   V(set_symbol, "set")                                                   \
220   V(function_class_symbol, "Function")                                   \
221   V(illegal_argument_symbol, "illegal argument")                         \
222   V(MakeReferenceError_symbol, "MakeReferenceError")                     \
223   V(MakeSyntaxError_symbol, "MakeSyntaxError")                           \
224   V(MakeTypeError_symbol, "MakeTypeError")                               \
225   V(invalid_lhs_in_assignment_symbol, "invalid_lhs_in_assignment")       \
226   V(invalid_lhs_in_for_in_symbol, "invalid_lhs_in_for_in")               \
227   V(invalid_lhs_in_postfix_op_symbol, "invalid_lhs_in_postfix_op")       \
228   V(invalid_lhs_in_prefix_op_symbol, "invalid_lhs_in_prefix_op")         \
229   V(illegal_return_symbol, "illegal_return")                             \
230   V(illegal_break_symbol, "illegal_break")                               \
231   V(illegal_continue_symbol, "illegal_continue")                         \
232   V(unknown_label_symbol, "unknown_label")                               \
233   V(redeclaration_symbol, "redeclaration")                               \
234   V(failure_symbol, "<failure>")                                         \
235   V(space_symbol, " ")                                                   \
236   V(exec_symbol, "exec")                                                 \
237   V(zero_symbol, "0")                                                    \
238   V(global_eval_symbol, "GlobalEval")                                    \
239   V(identity_hash_symbol, "v8::IdentityHash")                            \
240   V(closure_symbol, "(closure)")                                         \
241   V(use_strict, "use strict")                                            \
242   V(dot_symbol, ".")                                                     \
243   V(anonymous_function_symbol, "(anonymous function)")                   \
244   V(compare_ic_symbol, ".compare_ic")                                    \
245   V(infinity_symbol, "Infinity")                                         \
246   V(minus_infinity_symbol, "-Infinity")                                  \
247   V(hidden_stack_trace_symbol, "v8::hidden_stack_trace")                 \
248   V(query_colon_symbol, "(?:)")
249
250 // Forward declarations.
251 class GCTracer;
252 class HeapStats;
253 class Isolate;
254 class WeakObjectRetainer;
255
256
257 typedef HeapObject* (*ExternalStringTableUpdaterCallback)(Heap* heap,
258                                                           Object** pointer);
259
260 class StoreBufferRebuilder {
261  public:
262   explicit StoreBufferRebuilder(StoreBuffer* store_buffer)
263       : store_buffer_(store_buffer) {
264   }
265
266   void Callback(MemoryChunk* page, StoreBufferEvent event);
267
268  private:
269   StoreBuffer* store_buffer_;
270
271   // We record in this variable how full the store buffer was when we started
272   // iterating over the current page, finding pointers to new space.  If the
273   // store buffer overflows again we can exempt the page from the store buffer
274   // by rewinding to this point instead of having to search the store buffer.
275   Object*** start_of_current_page_;
276   // The current page we are scanning in the store buffer iterator.
277   MemoryChunk* current_page_;
278 };
279
280
281
282 // The all static Heap captures the interface to the global object heap.
283 // All JavaScript contexts by this process share the same object heap.
284
285 #ifdef DEBUG
286 class HeapDebugUtils;
287 #endif
288
289
290 // A queue of objects promoted during scavenge. Each object is accompanied
291 // by it's size to avoid dereferencing a map pointer for scanning.
292 class PromotionQueue {
293  public:
294   explicit PromotionQueue(Heap* heap)
295       : front_(NULL),
296         rear_(NULL),
297         limit_(NULL),
298         emergency_stack_(0),
299         heap_(heap) { }
300
301   void Initialize();
302
303   void Destroy() {
304     ASSERT(is_empty());
305     delete emergency_stack_;
306     emergency_stack_ = NULL;
307   }
308
309   inline void ActivateGuardIfOnTheSamePage();
310
311   Page* GetHeadPage() {
312     return Page::FromAllocationTop(reinterpret_cast<Address>(rear_));
313   }
314
315   void SetNewLimit(Address limit) {
316     if (!guard_) {
317       return;
318     }
319
320     ASSERT(GetHeadPage() == Page::FromAllocationTop(limit));
321     limit_ = reinterpret_cast<intptr_t*>(limit);
322
323     if (limit_ <= rear_) {
324       return;
325     }
326
327     RelocateQueueHead();
328   }
329
330   bool is_empty() {
331     return (front_ == rear_) &&
332         (emergency_stack_ == NULL || emergency_stack_->length() == 0);
333   }
334
335   inline void insert(HeapObject* target, int size);
336
337   void remove(HeapObject** target, int* size) {
338     ASSERT(!is_empty());
339     if (front_ == rear_) {
340       Entry e = emergency_stack_->RemoveLast();
341       *target = e.obj_;
342       *size = e.size_;
343       return;
344     }
345
346     if (NewSpacePage::IsAtStart(reinterpret_cast<Address>(front_))) {
347       NewSpacePage* front_page =
348           NewSpacePage::FromAddress(reinterpret_cast<Address>(front_));
349       ASSERT(!front_page->prev_page()->is_anchor());
350       front_ =
351           reinterpret_cast<intptr_t*>(front_page->prev_page()->area_end());
352     }
353     *target = reinterpret_cast<HeapObject*>(*(--front_));
354     *size = static_cast<int>(*(--front_));
355     // Assert no underflow.
356     SemiSpace::AssertValidRange(reinterpret_cast<Address>(rear_),
357                                 reinterpret_cast<Address>(front_));
358   }
359
360  private:
361   // The front of the queue is higher in the memory page chain than the rear.
362   intptr_t* front_;
363   intptr_t* rear_;
364   intptr_t* limit_;
365
366   bool guard_;
367
368   static const int kEntrySizeInWords = 2;
369
370   struct Entry {
371     Entry(HeapObject* obj, int size) : obj_(obj), size_(size) { }
372
373     HeapObject* obj_;
374     int size_;
375   };
376   List<Entry>* emergency_stack_;
377
378   Heap* heap_;
379
380   void RelocateQueueHead();
381
382   DISALLOW_COPY_AND_ASSIGN(PromotionQueue);
383 };
384
385
386 typedef void (*ScavengingCallback)(Map* map,
387                                    HeapObject** slot,
388                                    HeapObject* object);
389
390
391 // External strings table is a place where all external strings are
392 // registered.  We need to keep track of such strings to properly
393 // finalize them.
394 // The ExternalStringTable can contain both strings and objects with
395 // external resources.  It was not renamed to make the patch simpler.
396 class ExternalStringTable {
397  public:
398   // Registers an external string.
399   inline void AddString(String* string);
400   // Registers an external object.
401   inline void AddObject(HeapObject* string);
402
403   inline void Iterate(ObjectVisitor* v);
404
405   // Restores internal invariant and gets rid of collected strings.
406   // Must be called after each Iterate() that modified the strings.
407   void CleanUp();
408
409   // Destroys all allocated memory.
410   void TearDown();
411
412  private:
413   ExternalStringTable() { }
414
415   friend class Heap;
416
417   inline void Verify();
418
419   inline void AddOldObject(HeapObject* string);
420
421   // Notifies the table that only a prefix of the new list is valid.
422   inline void ShrinkNewObjects(int position);
423
424   // To speed up scavenge collections new space string are kept
425   // separate from old space strings.
426   List<Object*> new_space_strings_;
427   List<Object*> old_space_strings_;
428
429   Heap* heap_;
430
431   DISALLOW_COPY_AND_ASSIGN(ExternalStringTable);
432 };
433
434
435 enum ArrayStorageAllocationMode {
436   DONT_INITIALIZE_ARRAY_ELEMENTS,
437   INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE
438 };
439
440 class Heap {
441  public:
442   // Configure heap size before setup. Return false if the heap has been
443   // set up already.
444   bool ConfigureHeap(int max_semispace_size,
445                      intptr_t max_old_gen_size,
446                      intptr_t max_executable_size);
447   bool ConfigureHeapDefault();
448
449   // Initializes the global object heap. If create_heap_objects is true,
450   // also creates the basic non-mutable objects.
451   // Returns whether it succeeded.
452   bool SetUp(bool create_heap_objects);
453
454   // Destroys all memory allocated by the heap.
455   void TearDown();
456
457   // Set the stack limit in the roots_ array.  Some architectures generate
458   // code that looks here, because it is faster than loading from the static
459   // jslimit_/real_jslimit_ variable in the StackGuard.
460   void SetStackLimits();
461
462   // Returns whether SetUp has been called.
463   bool HasBeenSetUp();
464
465   // Returns the maximum amount of memory reserved for the heap.  For
466   // the young generation, we reserve 4 times the amount needed for a
467   // semi space.  The young generation consists of two semi spaces and
468   // we reserve twice the amount needed for those in order to ensure
469   // that new space can be aligned to its size.
470   intptr_t MaxReserved() {
471     return 4 * reserved_semispace_size_ + max_old_generation_size_;
472   }
473   int MaxSemiSpaceSize() { return max_semispace_size_; }
474   int ReservedSemiSpaceSize() { return reserved_semispace_size_; }
475   int InitialSemiSpaceSize() { return initial_semispace_size_; }
476   intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
477   intptr_t MaxExecutableSize() { return max_executable_size_; }
478
479   // Returns the capacity of the heap in bytes w/o growing. Heap grows when
480   // more spaces are needed until it reaches the limit.
481   intptr_t Capacity();
482
483   // Returns the amount of memory currently committed for the heap.
484   intptr_t CommittedMemory();
485
486   // Returns the amount of executable memory currently committed for the heap.
487   intptr_t CommittedMemoryExecutable();
488
489   // Returns the available bytes in space w/o growing.
490   // Heap doesn't guarantee that it can allocate an object that requires
491   // all available bytes. Check MaxHeapObjectSize() instead.
492   intptr_t Available();
493
494   // Returns of size of all objects residing in the heap.
495   intptr_t SizeOfObjects();
496
497   // Return the starting address and a mask for the new space.  And-masking an
498   // address with the mask will result in the start address of the new space
499   // for all addresses in either semispace.
500   Address NewSpaceStart() { return new_space_.start(); }
501   uintptr_t NewSpaceMask() { return new_space_.mask(); }
502   Address NewSpaceTop() { return new_space_.top(); }
503
504   NewSpace* new_space() { return &new_space_; }
505   OldSpace* old_pointer_space() { return old_pointer_space_; }
506   OldSpace* old_data_space() { return old_data_space_; }
507   OldSpace* code_space() { return code_space_; }
508   MapSpace* map_space() { return map_space_; }
509   CellSpace* cell_space() { return cell_space_; }
510   LargeObjectSpace* lo_space() { return lo_space_; }
511
512   bool always_allocate() { return always_allocate_scope_depth_ != 0; }
513   Address always_allocate_scope_depth_address() {
514     return reinterpret_cast<Address>(&always_allocate_scope_depth_);
515   }
516   bool linear_allocation() {
517     return linear_allocation_scope_depth_ != 0;
518   }
519
520   Address* NewSpaceAllocationTopAddress() {
521     return new_space_.allocation_top_address();
522   }
523   Address* NewSpaceAllocationLimitAddress() {
524     return new_space_.allocation_limit_address();
525   }
526
527   // Uncommit unused semi space.
528   bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); }
529
530   // Allocates and initializes a new JavaScript object based on a
531   // constructor.
532   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
533   // failed.
534   // Please note this does not perform a garbage collection.
535   MUST_USE_RESULT MaybeObject* AllocateJSObject(
536       JSFunction* constructor, PretenureFlag pretenure = NOT_TENURED);
537
538   MUST_USE_RESULT MaybeObject* AllocateJSModule();
539
540   // Allocate a JSArray with no elements
541   MUST_USE_RESULT MaybeObject* AllocateEmptyJSArray(
542       ElementsKind elements_kind,
543       PretenureFlag pretenure = NOT_TENURED) {
544     return AllocateJSArrayAndStorage(elements_kind, 0, 0,
545                                      DONT_INITIALIZE_ARRAY_ELEMENTS,
546                                      pretenure);
547   }
548
549   // Allocate a JSArray with a specified length but elements that are left
550   // uninitialized.
551   MUST_USE_RESULT MaybeObject* AllocateJSArrayAndStorage(
552       ElementsKind elements_kind,
553       int length,
554       int capacity,
555       ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
556       PretenureFlag pretenure = NOT_TENURED);
557
558   // Allocate a JSArray with no elements
559   MUST_USE_RESULT MaybeObject* AllocateJSArrayWithElements(
560       FixedArrayBase* array_base,
561       ElementsKind elements_kind,
562       PretenureFlag pretenure = NOT_TENURED);
563
564   // Allocates and initializes a new global object based on a constructor.
565   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
566   // failed.
567   // Please note this does not perform a garbage collection.
568   MUST_USE_RESULT MaybeObject* AllocateGlobalObject(JSFunction* constructor);
569
570   // Returns a deep copy of the JavaScript object.
571   // Properties and elements are copied too.
572   // Returns failure if allocation failed.
573   MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source);
574
575   // Allocates the function prototype.
576   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
577   // failed.
578   // Please note this does not perform a garbage collection.
579   MUST_USE_RESULT MaybeObject* AllocateFunctionPrototype(JSFunction* function);
580
581   // Allocates a Harmony proxy or function proxy.
582   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
583   // failed.
584   // Please note this does not perform a garbage collection.
585   MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler,
586                                                Object* prototype);
587
588   MUST_USE_RESULT MaybeObject* AllocateJSFunctionProxy(Object* handler,
589                                                        Object* call_trap,
590                                                        Object* construct_trap,
591                                                        Object* prototype);
592
593   // Reinitialize a JSReceiver into an (empty) JS object of respective type and
594   // size, but keeping the original prototype.  The receiver must have at least
595   // the size of the new object.  The object is reinitialized and behaves as an
596   // object that has been freshly allocated.
597   // Returns failure if an error occured, otherwise object.
598   MUST_USE_RESULT MaybeObject* ReinitializeJSReceiver(JSReceiver* object,
599                                                       InstanceType type,
600                                                       int size);
601
602   // Reinitialize an JSGlobalProxy based on a constructor.  The object
603   // must have the same size as objects allocated using the
604   // constructor.  The object is reinitialized and behaves as an
605   // object that has been freshly allocated using the constructor.
606   MUST_USE_RESULT MaybeObject* ReinitializeJSGlobalProxy(
607       JSFunction* constructor, JSGlobalProxy* global);
608
609   // Allocates and initializes a new JavaScript object based on a map.
610   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
611   // failed.
612   // Please note this does not perform a garbage collection.
613   MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMap(
614       Map* map, PretenureFlag pretenure = NOT_TENURED);
615
616   // Allocates a heap object based on the map.
617   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
618   // failed.
619   // Please note this function does not perform a garbage collection.
620   MUST_USE_RESULT MaybeObject* Allocate(Map* map, AllocationSpace space);
621
622   // Allocates a JS Map in the heap.
623   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
624   // failed.
625   // Please note this function does not perform a garbage collection.
626   MUST_USE_RESULT MaybeObject* AllocateMap(
627       InstanceType instance_type,
628       int instance_size,
629       ElementsKind elements_kind = FAST_ELEMENTS);
630
631   // Allocates a partial map for bootstrapping.
632   MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
633                                                   int instance_size);
634
635   // Allocate a map for the specified function
636   MUST_USE_RESULT MaybeObject* AllocateInitialMap(JSFunction* fun);
637
638   // Allocates an empty code cache.
639   MUST_USE_RESULT MaybeObject* AllocateCodeCache();
640
641   // Allocates a serialized scope info.
642   MUST_USE_RESULT MaybeObject* AllocateScopeInfo(int length);
643
644   // Allocates an empty PolymorphicCodeCache.
645   MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
646
647   // Allocates a pre-tenured empty AccessorPair.
648   MUST_USE_RESULT MaybeObject* AllocateAccessorPair();
649
650   // Allocates an empty TypeFeedbackInfo.
651   MUST_USE_RESULT MaybeObject* AllocateTypeFeedbackInfo();
652
653   // Allocates an AliasedArgumentsEntry.
654   MUST_USE_RESULT MaybeObject* AllocateAliasedArgumentsEntry(int slot);
655
656   // Clear the Instanceof cache (used when a prototype changes).
657   inline void ClearInstanceofCache();
658
659   // Allocates and fully initializes a String.  There are two String
660   // encodings: ASCII and two byte. One should choose between the three string
661   // allocation functions based on the encoding of the string buffer used to
662   // initialized the string.
663   //   - ...FromAscii initializes the string from a buffer that is ASCII
664   //     encoded (it does not check that the buffer is ASCII encoded) and the
665   //     result will be ASCII encoded.
666   //   - ...FromUTF8 initializes the string from a buffer that is UTF-8
667   //     encoded.  If the characters are all single-byte characters, the
668   //     result will be ASCII encoded, otherwise it will converted to two
669   //     byte.
670   //   - ...FromTwoByte initializes the string from a buffer that is two-byte
671   //     encoded.  If the characters are all single-byte characters, the
672   //     result will be converted to ASCII, otherwise it will be left as
673   //     two-byte.
674   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
675   // failed.
676   // Please note this does not perform a garbage collection.
677   MUST_USE_RESULT MaybeObject* AllocateStringFromAscii(
678       Vector<const char> str,
679       PretenureFlag pretenure = NOT_TENURED);
680   MUST_USE_RESULT inline MaybeObject* AllocateStringFromUtf8(
681       Vector<const char> str,
682       PretenureFlag pretenure = NOT_TENURED);
683   MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
684       Vector<const char> str,
685       PretenureFlag pretenure = NOT_TENURED);
686   MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte(
687       Vector<const uc16> str,
688       PretenureFlag pretenure = NOT_TENURED);
689
690   // Allocates a symbol in old space based on the character stream.
691   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
692   // failed.
693   // Please note this function does not perform a garbage collection.
694   MUST_USE_RESULT inline MaybeObject* AllocateSymbol(Vector<const char> str,
695                                                      int chars,
696                                                      uint32_t hash_field);
697
698   MUST_USE_RESULT inline MaybeObject* AllocateAsciiSymbol(
699         Vector<const char> str,
700         uint32_t hash_field);
701
702   MUST_USE_RESULT inline MaybeObject* AllocateTwoByteSymbol(
703         Vector<const uc16> str,
704         uint32_t hash_field);
705
706   MUST_USE_RESULT MaybeObject* AllocateInternalSymbol(
707       unibrow::CharacterStream* buffer, int chars, uint32_t hash_field);
708
709   MUST_USE_RESULT MaybeObject* AllocateExternalSymbol(
710       Vector<const char> str,
711       int chars);
712
713   // Allocates and partially initializes a String.  There are two String
714   // encodings: ASCII and two byte.  These functions allocate a string of the
715   // given length and set its map and length fields.  The characters of the
716   // string are uninitialized.
717   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
718   // failed.
719   // Please note this does not perform a garbage collection.
720   MUST_USE_RESULT MaybeObject* AllocateRawAsciiString(
721       int length,
722       PretenureFlag pretenure = NOT_TENURED);
723   MUST_USE_RESULT MaybeObject* AllocateRawTwoByteString(
724       int length,
725       PretenureFlag pretenure = NOT_TENURED);
726
727   // Computes a single character string where the character has code.
728   // A cache is used for ASCII codes.
729   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
730   // failed. Please note this does not perform a garbage collection.
731   MUST_USE_RESULT MaybeObject* LookupSingleCharacterStringFromCode(
732       uint16_t code);
733
734   // Allocate a byte array of the specified length
735   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
736   // failed.
737   // Please note this does not perform a garbage collection.
738   MUST_USE_RESULT MaybeObject* AllocateByteArray(int length,
739                                                  PretenureFlag pretenure);
740
741   // Allocate a non-tenured byte array of the specified length
742   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
743   // failed.
744   // Please note this does not perform a garbage collection.
745   MUST_USE_RESULT MaybeObject* AllocateByteArray(int length);
746
747   // Allocates an external array of the specified length and type.
748   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
749   // failed.
750   // Please note this does not perform a garbage collection.
751   MUST_USE_RESULT MaybeObject* AllocateExternalArray(
752       int length,
753       ExternalArrayType array_type,
754       void* external_pointer,
755       PretenureFlag pretenure);
756
757   // Allocate a tenured JS global property cell.
758   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
759   // failed.
760   // Please note this does not perform a garbage collection.
761   MUST_USE_RESULT MaybeObject* AllocateJSGlobalPropertyCell(Object* value);
762
763   // Allocates a fixed array initialized with undefined values
764   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
765   // failed.
766   // Please note this does not perform a garbage collection.
767   MUST_USE_RESULT MaybeObject* AllocateFixedArray(int length,
768                                                   PretenureFlag pretenure);
769   // Allocates a fixed array initialized with undefined values
770   MUST_USE_RESULT MaybeObject* AllocateFixedArray(int length);
771
772   // Allocates an uninitialized fixed array. It must be filled by the caller.
773   //
774   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
775   // failed.
776   // Please note this does not perform a garbage collection.
777   MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedArray(int length);
778
779   // Make a copy of src and return it. Returns
780   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
781   MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src);
782
783   // Make a copy of src, set the map, and return the copy. Returns
784   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
785   MUST_USE_RESULT MaybeObject* CopyFixedArrayWithMap(FixedArray* src, Map* map);
786
787   // Make a copy of src and return it. Returns
788   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
789   MUST_USE_RESULT inline MaybeObject* CopyFixedDoubleArray(
790       FixedDoubleArray* src);
791
792   // Make a copy of src, set the map, and return the copy. Returns
793   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
794   MUST_USE_RESULT MaybeObject* CopyFixedDoubleArrayWithMap(
795       FixedDoubleArray* src, Map* map);
796
797   // Allocates a fixed array initialized with the hole values.
798   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
799   // failed.
800   // Please note this does not perform a garbage collection.
801   MUST_USE_RESULT MaybeObject* AllocateFixedArrayWithHoles(
802       int length,
803       PretenureFlag pretenure = NOT_TENURED);
804
805   MUST_USE_RESULT MaybeObject* AllocateRawFixedDoubleArray(
806       int length,
807       PretenureFlag pretenure);
808
809   // Allocates a fixed double array with uninitialized values. Returns
810   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
811   // Please note this does not perform a garbage collection.
812   MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedDoubleArray(
813       int length,
814       PretenureFlag pretenure = NOT_TENURED);
815
816   // Allocates a fixed double array with hole values. Returns
817   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
818   // Please note this does not perform a garbage collection.
819   MUST_USE_RESULT MaybeObject* AllocateFixedDoubleArrayWithHoles(
820       int length,
821       PretenureFlag pretenure = NOT_TENURED);
822
823   // AllocateHashTable is identical to AllocateFixedArray except
824   // that the resulting object has hash_table_map as map.
825   MUST_USE_RESULT MaybeObject* AllocateHashTable(
826       int length, PretenureFlag pretenure = NOT_TENURED);
827
828   // Allocate a global (but otherwise uninitialized) context.
829   MUST_USE_RESULT MaybeObject* AllocateGlobalContext();
830
831   // Allocate a module context.
832   MUST_USE_RESULT MaybeObject* AllocateModuleContext(Context* previous,
833                                                      ScopeInfo* scope_info);
834
835   // Allocate a function context.
836   MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
837                                                        JSFunction* function);
838
839   // Allocate a catch context.
840   MUST_USE_RESULT MaybeObject* AllocateCatchContext(JSFunction* function,
841                                                     Context* previous,
842                                                     String* name,
843                                                     Object* thrown_object);
844   // Allocate a 'with' context.
845   MUST_USE_RESULT MaybeObject* AllocateWithContext(JSFunction* function,
846                                                    Context* previous,
847                                                    JSObject* extension);
848
849   // Allocate a block context.
850   MUST_USE_RESULT MaybeObject* AllocateBlockContext(JSFunction* function,
851                                                     Context* previous,
852                                                     ScopeInfo* info);
853
854   // Allocates a new utility object in the old generation.
855   MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
856
857   // Allocates a function initialized with a shared part.
858   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
859   // failed.
860   // Please note this does not perform a garbage collection.
861   MUST_USE_RESULT MaybeObject* AllocateFunction(
862       Map* function_map,
863       SharedFunctionInfo* shared,
864       Object* prototype,
865       PretenureFlag pretenure = TENURED);
866
867   // Arguments object size.
868   static const int kArgumentsObjectSize =
869       JSObject::kHeaderSize + 2 * kPointerSize;
870   // Strict mode arguments has no callee so it is smaller.
871   static const int kArgumentsObjectSizeStrict =
872       JSObject::kHeaderSize + 1 * kPointerSize;
873   // Indicies for direct access into argument objects.
874   static const int kArgumentsLengthIndex = 0;
875   // callee is only valid in non-strict mode.
876   static const int kArgumentsCalleeIndex = 1;
877
878   // Allocates an arguments object - optionally with an elements array.
879   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
880   // failed.
881   // Please note this does not perform a garbage collection.
882   MUST_USE_RESULT MaybeObject* AllocateArgumentsObject(
883       Object* callee, int length);
884
885   // Same as NewNumberFromDouble, but may return a preallocated/immutable
886   // number object (e.g., minus_zero_value_, nan_value_)
887   MUST_USE_RESULT MaybeObject* NumberFromDouble(
888       double value, PretenureFlag pretenure = NOT_TENURED);
889
890   // Allocated a HeapNumber from value.
891   MUST_USE_RESULT MaybeObject* AllocateHeapNumber(
892       double value,
893       PretenureFlag pretenure);
894   // pretenure = NOT_TENURED
895   MUST_USE_RESULT MaybeObject* AllocateHeapNumber(double value);
896
897   // Converts an int into either a Smi or a HeapNumber object.
898   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
899   // failed.
900   // Please note this does not perform a garbage collection.
901   MUST_USE_RESULT inline MaybeObject* NumberFromInt32(
902       int32_t value, PretenureFlag pretenure = NOT_TENURED);
903
904   // Converts an int into either a Smi or a HeapNumber object.
905   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
906   // failed.
907   // Please note this does not perform a garbage collection.
908   MUST_USE_RESULT inline MaybeObject* NumberFromUint32(
909       uint32_t value, PretenureFlag pretenure = NOT_TENURED);
910
911   // Allocates a new foreign object.
912   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
913   // failed.
914   // Please note this does not perform a garbage collection.
915   MUST_USE_RESULT MaybeObject* AllocateForeign(
916       Address address, PretenureFlag pretenure = NOT_TENURED);
917
918   // Allocates a new SharedFunctionInfo object.
919   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
920   // failed.
921   // Please note this does not perform a garbage collection.
922   MUST_USE_RESULT MaybeObject* AllocateSharedFunctionInfo(Object* name);
923
924   // Allocates a new JSMessageObject object.
925   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
926   // failed.
927   // Please note that this does not perform a garbage collection.
928   MUST_USE_RESULT MaybeObject* AllocateJSMessageObject(
929       String* type,
930       JSArray* arguments,
931       int start_position,
932       int end_position,
933       Object* script,
934       Object* stack_trace,
935       Object* stack_frames);
936
937   // Allocates a new cons string object.
938   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
939   // failed.
940   // Please note this does not perform a garbage collection.
941   MUST_USE_RESULT MaybeObject* AllocateConsString(String* first,
942                                                   String* second);
943
944   // Allocates a new sub string object which is a substring of an underlying
945   // string buffer stretching from the index start (inclusive) to the index
946   // end (exclusive).
947   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
948   // failed.
949   // Please note this does not perform a garbage collection.
950   MUST_USE_RESULT MaybeObject* AllocateSubString(
951       String* buffer,
952       int start,
953       int end,
954       PretenureFlag pretenure = NOT_TENURED);
955
956   // Allocate a new external string object, which is backed by a string
957   // resource that resides outside the V8 heap.
958   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
959   // failed.
960   // Please note this does not perform a garbage collection.
961   MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii(
962       const ExternalAsciiString::Resource* resource);
963   MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte(
964       const ExternalTwoByteString::Resource* resource);
965
966   // Finalizes an external string by deleting the associated external
967   // data and clearing the resource pointer.
968   inline void FinalizeExternalString(HeapObject* string);
969
970   // Allocates an uninitialized object.  The memory is non-executable if the
971   // hardware and OS allow.
972   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
973   // failed.
974   // Please note this function does not perform a garbage collection.
975   MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes,
976                                                   AllocationSpace space,
977                                                   AllocationSpace retry_space);
978
979   // Initialize a filler object to keep the ability to iterate over the heap
980   // when shortening objects.
981   void CreateFillerObjectAt(Address addr, int size);
982
983   // Makes a new native code object
984   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
985   // failed. On success, the pointer to the Code object is stored in the
986   // self_reference. This allows generated code to reference its own Code
987   // object by containing this pointer.
988   // Please note this function does not perform a garbage collection.
989   MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc,
990                                           Code::Flags flags,
991                                           Handle<Object> self_reference,
992                                           bool immovable = false);
993
994   MUST_USE_RESULT MaybeObject* CopyCode(Code* code);
995
996   // Copy the code and scope info part of the code object, but insert
997   // the provided data as the relocation information.
998   MUST_USE_RESULT MaybeObject* CopyCode(Code* code, Vector<byte> reloc_info);
999
1000   // Finds the symbol for string in the symbol table.
1001   // If not found, a new symbol is added to the table and returned.
1002   // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
1003   // failed.
1004   // Please note this function does not perform a garbage collection.
1005   MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str);
1006   MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str);
1007   MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str);
1008   MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(const char* str) {
1009     return LookupSymbol(CStrVector(str));
1010   }
1011   MUST_USE_RESULT MaybeObject* LookupSymbol(String* str);
1012   MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Handle<SeqAsciiString> string,
1013                                                  int from,
1014                                                  int length);
1015
1016   bool LookupSymbolIfExists(String* str, String** symbol);
1017   bool LookupTwoCharsSymbolIfExists(String* str, String** symbol);
1018
1019   // Compute the matching symbol map for a string if possible.
1020   // NULL is returned if string is in new space or not flattened.
1021   Map* SymbolMapForString(String* str);
1022
1023   // Tries to flatten a string before compare operation.
1024   //
1025   // Returns a failure in case it was decided that flattening was
1026   // necessary and failed.  Note, if flattening is not necessary the
1027   // string might stay non-flat even when not a failure is returned.
1028   //
1029   // Please note this function does not perform a garbage collection.
1030   MUST_USE_RESULT inline MaybeObject* PrepareForCompare(String* str);
1031
1032   // Converts the given boolean condition to JavaScript boolean value.
1033   inline Object* ToBoolean(bool condition);
1034
1035   // Code that should be run before and after each GC.  Includes some
1036   // reporting/verification activities when compiled with DEBUG set.
1037   void GarbageCollectionPrologue();
1038   void GarbageCollectionEpilogue();
1039
1040   // Performs garbage collection operation.
1041   // Returns whether there is a chance that another major GC could
1042   // collect more garbage.
1043   bool CollectGarbage(AllocationSpace space,
1044                       GarbageCollector collector,
1045                       const char* gc_reason,
1046                       const char* collector_reason);
1047
1048   // Performs garbage collection operation.
1049   // Returns whether there is a chance that another major GC could
1050   // collect more garbage.
1051   inline bool CollectGarbage(AllocationSpace space,
1052                              const char* gc_reason = NULL);
1053
1054   static const int kNoGCFlags = 0;
1055   static const int kSweepPreciselyMask = 1;
1056   static const int kReduceMemoryFootprintMask = 2;
1057   static const int kAbortIncrementalMarkingMask = 4;
1058
1059   // Making the heap iterable requires us to sweep precisely and abort any
1060   // incremental marking as well.
1061   static const int kMakeHeapIterableMask =
1062       kSweepPreciselyMask | kAbortIncrementalMarkingMask;
1063
1064   // Performs a full garbage collection.  If (flags & kMakeHeapIterableMask) is
1065   // non-zero, then the slower precise sweeper is used, which leaves the heap
1066   // in a state where we can iterate over the heap visiting all objects.
1067   void CollectAllGarbage(int flags, const char* gc_reason = NULL);
1068
1069   // Last hope GC, should try to squeeze as much as possible.
1070   void CollectAllAvailableGarbage(const char* gc_reason = NULL);
1071
1072   // Check whether the heap is currently iterable.
1073   bool IsHeapIterable();
1074
1075   // Ensure that we have swept all spaces in such a way that we can iterate
1076   // over all objects.  May cause a GC.
1077   void EnsureHeapIsIterable();
1078
1079   // Notify the heap that a context has been disposed.
1080   int NotifyContextDisposed() { return ++contexts_disposed_; }
1081
1082   // Utility to invoke the scavenger. This is needed in test code to
1083   // ensure correct callback for weak global handles.
1084   void PerformScavenge();
1085
1086   inline void increment_scan_on_scavenge_pages() {
1087     scan_on_scavenge_pages_++;
1088     if (FLAG_gc_verbose) {
1089       PrintF("Scan-on-scavenge pages: %d\n", scan_on_scavenge_pages_);
1090     }
1091   }
1092
1093   inline void decrement_scan_on_scavenge_pages() {
1094     scan_on_scavenge_pages_--;
1095     if (FLAG_gc_verbose) {
1096       PrintF("Scan-on-scavenge pages: %d\n", scan_on_scavenge_pages_);
1097     }
1098   }
1099
1100   PromotionQueue* promotion_queue() { return &promotion_queue_; }
1101
1102 #ifdef DEBUG
1103   // Utility used with flag gc-greedy.
1104   void GarbageCollectionGreedyCheck();
1105 #endif
1106
1107   void AddGCPrologueCallback(
1108       GCEpilogueCallback callback, GCType gc_type_filter);
1109   void RemoveGCPrologueCallback(GCEpilogueCallback callback);
1110
1111   void AddGCEpilogueCallback(
1112       GCEpilogueCallback callback, GCType gc_type_filter);
1113   void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
1114
1115   void SetGlobalGCPrologueCallback(GCCallback callback) {
1116     ASSERT((callback == NULL) ^ (global_gc_prologue_callback_ == NULL));
1117     global_gc_prologue_callback_ = callback;
1118   }
1119   void SetGlobalGCEpilogueCallback(GCCallback callback) {
1120     ASSERT((callback == NULL) ^ (global_gc_epilogue_callback_ == NULL));
1121     global_gc_epilogue_callback_ = callback;
1122   }
1123
1124   // Heap root getters.  We have versions with and without type::cast() here.
1125   // You can't use type::cast during GC because the assert fails.
1126   // TODO(1490): Try removing the unchecked accessors, now that GC marking does
1127   // not corrupt the map.
1128 #define ROOT_ACCESSOR(type, name, camel_name)                                  \
1129   type* name() {                                                               \
1130     return type::cast(roots_[k##camel_name##RootIndex]);                       \
1131   }                                                                            \
1132   type* raw_unchecked_##name() {                                               \
1133     return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]);          \
1134   }
1135   ROOT_LIST(ROOT_ACCESSOR)
1136 #undef ROOT_ACCESSOR
1137
1138 // Utility type maps
1139 #define STRUCT_MAP_ACCESSOR(NAME, Name, name)                                  \
1140     Map* name##_map() {                                                        \
1141       return Map::cast(roots_[k##Name##MapRootIndex]);                         \
1142     }
1143   STRUCT_LIST(STRUCT_MAP_ACCESSOR)
1144 #undef STRUCT_MAP_ACCESSOR
1145
1146 #define SYMBOL_ACCESSOR(name, str) String* name() {                            \
1147     return String::cast(roots_[k##name##RootIndex]);                           \
1148   }
1149   SYMBOL_LIST(SYMBOL_ACCESSOR)
1150 #undef SYMBOL_ACCESSOR
1151
1152   // The hidden_symbol is special because it is the empty string, but does
1153   // not match the empty string.
1154   String* hidden_symbol() { return hidden_symbol_; }
1155
1156   void set_global_contexts_list(Object* object) {
1157     global_contexts_list_ = object;
1158   }
1159   Object* global_contexts_list() { return global_contexts_list_; }
1160
1161   // Number of mark-sweeps.
1162   int ms_count() { return ms_count_; }
1163
1164   // Iterates over all roots in the heap.
1165   void IterateRoots(ObjectVisitor* v, VisitMode mode);
1166   // Iterates over all strong roots in the heap.
1167   void IterateStrongRoots(ObjectVisitor* v, VisitMode mode);
1168   // Iterates over all the other roots in the heap.
1169   void IterateWeakRoots(ObjectVisitor* v, VisitMode mode);
1170
1171   // Iterate pointers to from semispace of new space found in memory interval
1172   // from start to end.
1173   void IterateAndMarkPointersToFromSpace(Address start,
1174                                          Address end,
1175                                          ObjectSlotCallback callback);
1176
1177   // Returns whether the object resides in new space.
1178   inline bool InNewSpace(Object* object);
1179   inline bool InNewSpace(Address addr);
1180   inline bool InNewSpacePage(Address addr);
1181   inline bool InFromSpace(Object* object);
1182   inline bool InToSpace(Object* object);
1183
1184   // Checks whether an address/object in the heap (including auxiliary
1185   // area and unused area).
1186   bool Contains(Address addr);
1187   bool Contains(HeapObject* value);
1188
1189   // Checks whether an address/object in a space.
1190   // Currently used by tests, serialization and heap verification only.
1191   bool InSpace(Address addr, AllocationSpace space);
1192   bool InSpace(HeapObject* value, AllocationSpace space);
1193
1194   // Finds out which space an object should get promoted to based on its type.
1195   inline OldSpace* TargetSpace(HeapObject* object);
1196   inline AllocationSpace TargetSpaceId(InstanceType type);
1197
1198   // Sets the stub_cache_ (only used when expanding the dictionary).
1199   void public_set_code_stubs(UnseededNumberDictionary* value) {
1200     roots_[kCodeStubsRootIndex] = value;
1201   }
1202
1203   // Support for computing object sizes for old objects during GCs. Returns
1204   // a function that is guaranteed to be safe for computing object sizes in
1205   // the current GC phase.
1206   HeapObjectCallback GcSafeSizeOfOldObjectFunction() {
1207     return gc_safe_size_of_old_object_;
1208   }
1209
1210   // Sets the non_monomorphic_cache_ (only used when expanding the dictionary).
1211   void public_set_non_monomorphic_cache(UnseededNumberDictionary* value) {
1212     roots_[kNonMonomorphicCacheRootIndex] = value;
1213   }
1214
1215   void public_set_empty_script(Script* script) {
1216     roots_[kEmptyScriptRootIndex] = script;
1217   }
1218
1219   void public_set_store_buffer_top(Address* top) {
1220     roots_[kStoreBufferTopRootIndex] = reinterpret_cast<Smi*>(top);
1221   }
1222
1223   // Update the next script id.
1224   inline void SetLastScriptId(Object* last_script_id);
1225
1226   // Generated code can embed this address to get access to the roots.
1227   Object** roots_array_start() { return roots_; }
1228
1229   Address* store_buffer_top_address() {
1230     return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
1231   }
1232
1233   // Get address of global contexts list for serialization support.
1234   Object** global_contexts_list_address() {
1235     return &global_contexts_list_;
1236   }
1237
1238 #ifdef DEBUG
1239   void Print();
1240   void PrintHandles();
1241
1242   // Verify the heap is in its normal state before or after a GC.
1243   void Verify();
1244
1245   // Verify that AccessorPairs are not shared, i.e. make sure that they have
1246   // exactly one pointer to them.
1247   void VerifyNoAccessorPairSharing();
1248
1249   void OldPointerSpaceCheckStoreBuffer();
1250   void MapSpaceCheckStoreBuffer();
1251   void LargeObjectSpaceCheckStoreBuffer();
1252
1253   // Report heap statistics.
1254   void ReportHeapStatistics(const char* title);
1255   void ReportCodeStatistics(const char* title);
1256
1257   // Fill in bogus values in from space
1258   void ZapFromSpace();
1259 #endif
1260
1261   // Print short heap statistics.
1262   void PrintShortHeapStatistics();
1263
1264   // Makes a new symbol object
1265   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1266   // failed.
1267   // Please note this function does not perform a garbage collection.
1268   MUST_USE_RESULT MaybeObject* CreateSymbol(
1269       const char* str, int length, int hash);
1270   MUST_USE_RESULT MaybeObject* CreateSymbol(String* str);
1271
1272   // Write barrier support for address[offset] = o.
1273   inline void RecordWrite(Address address, int offset);
1274
1275   // Write barrier support for address[start : start + len[ = o.
1276   inline void RecordWrites(Address address, int start, int len);
1277
1278   // Given an address occupied by a live code object, return that object.
1279   Object* FindCodeObject(Address a);
1280
1281   // Invoke Shrink on shrinkable spaces.
1282   void Shrink();
1283
1284   enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
1285   inline HeapState gc_state() { return gc_state_; }
1286
1287   inline bool IsInGCPostProcessing() { return gc_post_processing_depth_ > 0; }
1288
1289 #ifdef DEBUG
1290   bool IsAllocationAllowed() { return allocation_allowed_; }
1291   inline bool allow_allocation(bool enable);
1292
1293   bool disallow_allocation_failure() {
1294     return disallow_allocation_failure_;
1295   }
1296
1297   void TracePathToObject(Object* target);
1298   void TracePathToGlobal();
1299 #endif
1300
1301   // Callback function passed to Heap::Iterate etc.  Copies an object if
1302   // necessary, the object might be promoted to an old space.  The caller must
1303   // ensure the precondition that the object is (a) a heap object and (b) in
1304   // the heap's from space.
1305   static inline void ScavengePointer(HeapObject** p);
1306   static inline void ScavengeObject(HeapObject** p, HeapObject* object);
1307
1308   // Commits from space if it is uncommitted.
1309   void EnsureFromSpaceIsCommitted();
1310
1311   // Support for partial snapshots.  After calling this we can allocate a
1312   // certain number of bytes using only linear allocation (with a
1313   // LinearAllocationScope and an AlwaysAllocateScope) without using freelists
1314   // or causing a GC.  It returns true of space was reserved or false if a GC is
1315   // needed.  For paged spaces the space requested must include the space wasted
1316   // at the end of each page when allocating linearly.
1317   void ReserveSpace(
1318     int new_space_size,
1319     int pointer_space_size,
1320     int data_space_size,
1321     int code_space_size,
1322     int map_space_size,
1323     int cell_space_size,
1324     int large_object_size);
1325
1326   //
1327   // Support for the API.
1328   //
1329
1330   bool CreateApiObjects();
1331
1332   // Attempt to find the number in a small cache.  If we finds it, return
1333   // the string representation of the number.  Otherwise return undefined.
1334   Object* GetNumberStringCache(Object* number);
1335
1336   // Update the cache with a new number-string pair.
1337   void SetNumberStringCache(Object* number, String* str);
1338
1339   // Adjusts the amount of registered external memory.
1340   // Returns the adjusted value.
1341   inline intptr_t AdjustAmountOfExternalAllocatedMemory(
1342       intptr_t change_in_bytes);
1343
1344   // Allocate uninitialized fixed array.
1345   MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length);
1346   MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length,
1347                                                      PretenureFlag pretenure);
1348
1349   inline intptr_t PromotedTotalSize() {
1350     return PromotedSpaceSizeOfObjects() + PromotedExternalMemorySize();
1351   }
1352
1353   // True if we have reached the allocation limit in the old generation that
1354   // should force the next GC (caused normally) to be a full one.
1355   inline bool OldGenerationPromotionLimitReached() {
1356     return PromotedTotalSize() > old_gen_promotion_limit_;
1357   }
1358
1359   inline intptr_t OldGenerationSpaceAvailable() {
1360     return old_gen_allocation_limit_ - PromotedTotalSize();
1361   }
1362
1363   inline intptr_t OldGenerationCapacityAvailable() {
1364     return max_old_generation_size_ - PromotedTotalSize();
1365   }
1366
1367   static const intptr_t kMinimumPromotionLimit = 5 * Page::kPageSize;
1368   static const intptr_t kMinimumAllocationLimit =
1369       8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
1370
1371   intptr_t OldGenPromotionLimit(intptr_t old_gen_size) {
1372     const int divisor = FLAG_stress_compaction ? 10 : 3;
1373     intptr_t limit =
1374         Max(old_gen_size + old_gen_size / divisor, kMinimumPromotionLimit);
1375     limit += new_space_.Capacity();
1376     limit *= old_gen_limit_factor_;
1377     intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
1378     return Min(limit, halfway_to_the_max);
1379   }
1380
1381   intptr_t OldGenAllocationLimit(intptr_t old_gen_size) {
1382     const int divisor = FLAG_stress_compaction ? 8 : 2;
1383     intptr_t limit =
1384         Max(old_gen_size + old_gen_size / divisor, kMinimumAllocationLimit);
1385     limit += new_space_.Capacity();
1386     limit *= old_gen_limit_factor_;
1387     intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
1388     return Min(limit, halfway_to_the_max);
1389   }
1390
1391   // Implements the corresponding V8 API function.
1392   bool IdleNotification(int hint);
1393
1394   // Declare all the root indices.
1395   enum RootListIndex {
1396 #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex,
1397     STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION)
1398 #undef ROOT_INDEX_DECLARATION
1399
1400 // Utility type maps
1401 #define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
1402   STRUCT_LIST(DECLARE_STRUCT_MAP)
1403 #undef DECLARE_STRUCT_MAP
1404
1405 #define SYMBOL_INDEX_DECLARATION(name, str) k##name##RootIndex,
1406     SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
1407 #undef SYMBOL_DECLARATION
1408
1409     kSymbolTableRootIndex,
1410     kStrongRootListLength = kSymbolTableRootIndex,
1411     kRootListLength
1412   };
1413
1414   STATIC_CHECK(kUndefinedValueRootIndex == Internals::kUndefinedValueRootIndex);
1415   STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex);
1416   STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex);
1417   STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex);
1418   STATIC_CHECK(kempty_symbolRootIndex == Internals::kEmptySymbolRootIndex);
1419
1420   MUST_USE_RESULT MaybeObject* NumberToString(
1421       Object* number, bool check_number_string_cache = true);
1422   MUST_USE_RESULT MaybeObject* Uint32ToString(
1423       uint32_t value, bool check_number_string_cache = true);
1424
1425   Map* MapForExternalArrayType(ExternalArrayType array_type);
1426   RootListIndex RootIndexForExternalArrayType(
1427       ExternalArrayType array_type);
1428
1429   void RecordStats(HeapStats* stats, bool take_snapshot = false);
1430
1431   // Copy block of memory from src to dst. Size of block should be aligned
1432   // by pointer size.
1433   static inline void CopyBlock(Address dst, Address src, int byte_size);
1434
1435   // Optimized version of memmove for blocks with pointer size aligned sizes and
1436   // pointer size aligned addresses.
1437   static inline void MoveBlock(Address dst, Address src, int byte_size);
1438
1439   // Check new space expansion criteria and expand semispaces if it was hit.
1440   void CheckNewSpaceExpansionCriteria();
1441
1442   inline void IncrementYoungSurvivorsCounter(int survived) {
1443     ASSERT(survived >= 0);
1444     young_survivors_after_last_gc_ = survived;
1445     survived_since_last_expansion_ += survived;
1446   }
1447
1448   inline bool NextGCIsLikelyToBeFull() {
1449     if (FLAG_gc_global) return true;
1450
1451     if (FLAG_stress_compaction && (gc_count_ & 1) != 0) return true;
1452
1453     intptr_t total_promoted = PromotedTotalSize();
1454
1455     intptr_t adjusted_promotion_limit =
1456         old_gen_promotion_limit_ - new_space_.Capacity();
1457
1458     if (total_promoted >= adjusted_promotion_limit) return true;
1459
1460     intptr_t adjusted_allocation_limit =
1461         old_gen_allocation_limit_ - new_space_.Capacity() / 5;
1462
1463     if (PromotedSpaceSizeOfObjects() >= adjusted_allocation_limit) return true;
1464
1465     return false;
1466   }
1467
1468
1469   void UpdateNewSpaceReferencesInExternalStringTable(
1470       ExternalStringTableUpdaterCallback updater_func);
1471
1472   void UpdateReferencesInExternalStringTable(
1473       ExternalStringTableUpdaterCallback updater_func);
1474
1475   void ProcessWeakReferences(WeakObjectRetainer* retainer);
1476
1477   void VisitExternalResources(v8::ExternalResourceVisitor* visitor);
1478
1479   // Helper function that governs the promotion policy from new space to
1480   // old.  If the object's old address lies below the new space's age
1481   // mark or if we've already filled the bottom 1/16th of the to space,
1482   // we try to promote this object.
1483   inline bool ShouldBePromoted(Address old_address, int object_size);
1484
1485   int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; }
1486
1487   void ClearJSFunctionResultCaches();
1488
1489   void ClearNormalizedMapCaches();
1490
1491   // Clears the cache of ICs related to this map.
1492   void ClearCacheOnMap(Map* map) {
1493     if (FLAG_cleanup_code_caches_at_gc) {
1494       map->ClearCodeCache(this);
1495     }
1496   }
1497
1498   GCTracer* tracer() { return tracer_; }
1499
1500   // Returns the size of objects residing in non new spaces.
1501   intptr_t PromotedSpaceSizeOfObjects();
1502
1503   double total_regexp_code_generated() { return total_regexp_code_generated_; }
1504   void IncreaseTotalRegexpCodeGenerated(int size) {
1505     total_regexp_code_generated_ += size;
1506   }
1507
1508   // Returns maximum GC pause.
1509   int get_max_gc_pause() { return max_gc_pause_; }
1510
1511   // Returns maximum size of objects alive after GC.
1512   intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; }
1513
1514   // Returns minimal interval between two subsequent collections.
1515   int get_min_in_mutator() { return min_in_mutator_; }
1516
1517   MarkCompactCollector* mark_compact_collector() {
1518     return &mark_compact_collector_;
1519   }
1520
1521   StoreBuffer* store_buffer() {
1522     return &store_buffer_;
1523   }
1524
1525   Marking* marking() {
1526     return &marking_;
1527   }
1528
1529   IncrementalMarking* incremental_marking() {
1530     return &incremental_marking_;
1531   }
1532
1533   bool IsSweepingComplete() {
1534     return old_data_space()->IsSweepingComplete() &&
1535            old_pointer_space()->IsSweepingComplete();
1536   }
1537
1538   bool AdvanceSweepers(int step_size) {
1539     bool sweeping_complete = old_data_space()->AdvanceSweeper(step_size);
1540     sweeping_complete &= old_pointer_space()->AdvanceSweeper(step_size);
1541     return sweeping_complete;
1542   }
1543
1544   ExternalStringTable* external_string_table() {
1545     return &external_string_table_;
1546   }
1547
1548   // Returns the current sweep generation.
1549   int sweep_generation() {
1550     return sweep_generation_;
1551   }
1552
1553   inline Isolate* isolate();
1554
1555   inline void CallGlobalGCPrologueCallback() {
1556     if (global_gc_prologue_callback_ != NULL) global_gc_prologue_callback_();
1557   }
1558
1559   inline void CallGlobalGCEpilogueCallback() {
1560     if (global_gc_epilogue_callback_ != NULL) global_gc_epilogue_callback_();
1561   }
1562
1563   inline bool OldGenerationAllocationLimitReached();
1564
1565   inline void DoScavengeObject(Map* map, HeapObject** slot, HeapObject* obj) {
1566     scavenging_visitors_table_.GetVisitor(map)(map, slot, obj);
1567   }
1568
1569   void QueueMemoryChunkForFree(MemoryChunk* chunk);
1570   void FreeQueuedChunks();
1571
1572   // Completely clear the Instanceof cache (to stop it keeping objects alive
1573   // around a GC).
1574   inline void CompletelyClearInstanceofCache();
1575
1576   // The roots that have an index less than this are always in old space.
1577   static const int kOldSpaceRoots = 0x20;
1578
1579   uint32_t HashSeed() {
1580     uint32_t seed = static_cast<uint32_t>(hash_seed()->value());
1581     ASSERT(FLAG_randomize_hashes || seed == 0);
1582     return seed;
1583   }
1584
1585   void SetArgumentsAdaptorDeoptPCOffset(int pc_offset) {
1586     ASSERT(arguments_adaptor_deopt_pc_offset() == Smi::FromInt(0));
1587     set_arguments_adaptor_deopt_pc_offset(Smi::FromInt(pc_offset));
1588   }
1589
1590   void SetConstructStubDeoptPCOffset(int pc_offset) {
1591     ASSERT(construct_stub_deopt_pc_offset() == Smi::FromInt(0));
1592     set_construct_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
1593   }
1594
1595   // For post mortem debugging.
1596   void RememberUnmappedPage(Address page, bool compacted);
1597
1598   // Global inline caching age: it is incremented on some GCs after context
1599   // disposal. We use it to flush inline caches.
1600   int global_ic_age() {
1601     return global_ic_age_;
1602   }
1603
1604   void AgeInlineCaches() {
1605     ++global_ic_age_;
1606   }
1607
1608  private:
1609   Heap();
1610
1611   // This can be calculated directly from a pointer to the heap; however, it is
1612   // more expedient to get at the isolate directly from within Heap methods.
1613   Isolate* isolate_;
1614
1615   Object* roots_[kRootListLength];
1616
1617   intptr_t code_range_size_;
1618   int reserved_semispace_size_;
1619   int max_semispace_size_;
1620   int initial_semispace_size_;
1621   intptr_t max_old_generation_size_;
1622   intptr_t max_executable_size_;
1623
1624   // For keeping track of how much data has survived
1625   // scavenge since last new space expansion.
1626   int survived_since_last_expansion_;
1627
1628   // For keeping track on when to flush RegExp code.
1629   int sweep_generation_;
1630
1631   int always_allocate_scope_depth_;
1632   int linear_allocation_scope_depth_;
1633
1634   // For keeping track of context disposals.
1635   int contexts_disposed_;
1636
1637   int global_ic_age_;
1638
1639   int scan_on_scavenge_pages_;
1640
1641 #if defined(V8_TARGET_ARCH_X64)
1642   static const int kMaxObjectSizeInNewSpace = 1024*KB;
1643 #else
1644   static const int kMaxObjectSizeInNewSpace = 512*KB;
1645 #endif
1646
1647   NewSpace new_space_;
1648   OldSpace* old_pointer_space_;
1649   OldSpace* old_data_space_;
1650   OldSpace* code_space_;
1651   MapSpace* map_space_;
1652   CellSpace* cell_space_;
1653   LargeObjectSpace* lo_space_;
1654   HeapState gc_state_;
1655   int gc_post_processing_depth_;
1656
1657   // Returns the amount of external memory registered since last global gc.
1658   intptr_t PromotedExternalMemorySize();
1659
1660   int ms_count_;  // how many mark-sweep collections happened
1661   unsigned int gc_count_;  // how many gc happened
1662
1663   // For post mortem debugging.
1664   static const int kRememberedUnmappedPages = 128;
1665   int remembered_unmapped_pages_index_;
1666   Address remembered_unmapped_pages_[kRememberedUnmappedPages];
1667
1668   // Total length of the strings we failed to flatten since the last GC.
1669   int unflattened_strings_length_;
1670
1671 #define ROOT_ACCESSOR(type, name, camel_name)                                  \
1672   inline void set_##name(type* value) {                                        \
1673     /* The deserializer makes use of the fact that these common roots are */   \
1674     /* never in new space and never on a page that is being compacted.    */   \
1675     ASSERT(k##camel_name##RootIndex >= kOldSpaceRoots || !InNewSpace(value));  \
1676     roots_[k##camel_name##RootIndex] = value;                                  \
1677   }
1678   ROOT_LIST(ROOT_ACCESSOR)
1679 #undef ROOT_ACCESSOR
1680
1681 #ifdef DEBUG
1682   bool allocation_allowed_;
1683
1684   // If the --gc-interval flag is set to a positive value, this
1685   // variable holds the value indicating the number of allocations
1686   // remain until the next failure and garbage collection.
1687   int allocation_timeout_;
1688
1689   // Do we expect to be able to handle allocation failure at this
1690   // time?
1691   bool disallow_allocation_failure_;
1692
1693   HeapDebugUtils* debug_utils_;
1694 #endif  // DEBUG
1695
1696   // Indicates that the new space should be kept small due to high promotion
1697   // rates caused by the mutator allocating a lot of long-lived objects.
1698   bool new_space_high_promotion_mode_active_;
1699
1700   // Limit that triggers a global GC on the next (normally caused) GC.  This
1701   // is checked when we have already decided to do a GC to help determine
1702   // which collector to invoke.
1703   intptr_t old_gen_promotion_limit_;
1704
1705   // Limit that triggers a global GC as soon as is reasonable.  This is
1706   // checked before expanding a paged space in the old generation and on
1707   // every allocation in large object space.
1708   intptr_t old_gen_allocation_limit_;
1709
1710   // Sometimes the heuristics dictate that those limits are increased.  This
1711   // variable records that fact.
1712   int old_gen_limit_factor_;
1713
1714   // Used to adjust the limits that control the timing of the next GC.
1715   intptr_t size_of_old_gen_at_last_old_space_gc_;
1716
1717   // Limit on the amount of externally allocated memory allowed
1718   // between global GCs. If reached a global GC is forced.
1719   intptr_t external_allocation_limit_;
1720
1721   // The amount of external memory registered through the API kept alive
1722   // by global handles
1723   intptr_t amount_of_external_allocated_memory_;
1724
1725   // Caches the amount of external memory registered at the last global gc.
1726   intptr_t amount_of_external_allocated_memory_at_last_global_gc_;
1727
1728   // Indicates that an allocation has failed in the old generation since the
1729   // last GC.
1730   int old_gen_exhausted_;
1731
1732   Object* global_contexts_list_;
1733
1734   StoreBufferRebuilder store_buffer_rebuilder_;
1735
1736   struct StringTypeTable {
1737     InstanceType type;
1738     int size;
1739     RootListIndex index;
1740   };
1741
1742   struct ConstantSymbolTable {
1743     const char* contents;
1744     RootListIndex index;
1745   };
1746
1747   struct StructTable {
1748     InstanceType type;
1749     int size;
1750     RootListIndex index;
1751   };
1752
1753   static const StringTypeTable string_type_table[];
1754   static const ConstantSymbolTable constant_symbol_table[];
1755   static const StructTable struct_table[];
1756
1757   // The special hidden symbol which is an empty string, but does not match
1758   // any string when looked up in properties.
1759   String* hidden_symbol_;
1760
1761   // GC callback function, called before and after mark-compact GC.
1762   // Allocations in the callback function are disallowed.
1763   struct GCPrologueCallbackPair {
1764     GCPrologueCallbackPair(GCPrologueCallback callback, GCType gc_type)
1765         : callback(callback), gc_type(gc_type) {
1766     }
1767     bool operator==(const GCPrologueCallbackPair& pair) const {
1768       return pair.callback == callback;
1769     }
1770     GCPrologueCallback callback;
1771     GCType gc_type;
1772   };
1773   List<GCPrologueCallbackPair> gc_prologue_callbacks_;
1774
1775   struct GCEpilogueCallbackPair {
1776     GCEpilogueCallbackPair(GCEpilogueCallback callback, GCType gc_type)
1777         : callback(callback), gc_type(gc_type) {
1778     }
1779     bool operator==(const GCEpilogueCallbackPair& pair) const {
1780       return pair.callback == callback;
1781     }
1782     GCEpilogueCallback callback;
1783     GCType gc_type;
1784   };
1785   List<GCEpilogueCallbackPair> gc_epilogue_callbacks_;
1786
1787   GCCallback global_gc_prologue_callback_;
1788   GCCallback global_gc_epilogue_callback_;
1789
1790   // Support for computing object sizes during GC.
1791   HeapObjectCallback gc_safe_size_of_old_object_;
1792   static int GcSafeSizeOfOldObject(HeapObject* object);
1793
1794   // Update the GC state. Called from the mark-compact collector.
1795   void MarkMapPointersAsEncoded(bool encoded) {
1796     ASSERT(!encoded);
1797     gc_safe_size_of_old_object_ = &GcSafeSizeOfOldObject;
1798   }
1799
1800   // Checks whether a global GC is necessary
1801   GarbageCollector SelectGarbageCollector(AllocationSpace space,
1802                                           const char** reason);
1803
1804   // Performs garbage collection
1805   // Returns whether there is a chance another major GC could
1806   // collect more garbage.
1807   bool PerformGarbageCollection(GarbageCollector collector,
1808                                 GCTracer* tracer);
1809
1810
1811   inline void UpdateOldSpaceLimits();
1812
1813   // Allocate an uninitialized object in map space.  The behavior is identical
1814   // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't
1815   // have to test the allocation space argument and (b) can reduce code size
1816   // (since both AllocateRaw and AllocateRawMap are inlined).
1817   MUST_USE_RESULT inline MaybeObject* AllocateRawMap();
1818
1819   // Allocate an uninitialized object in the global property cell space.
1820   MUST_USE_RESULT inline MaybeObject* AllocateRawCell();
1821
1822   // Initializes a JSObject based on its map.
1823   void InitializeJSObjectFromMap(JSObject* obj,
1824                                  FixedArray* properties,
1825                                  Map* map);
1826
1827   bool CreateInitialMaps();
1828   bool CreateInitialObjects();
1829
1830   // These five Create*EntryStub functions are here and forced to not be inlined
1831   // because of a gcc-4.4 bug that assigns wrong vtable entries.
1832   NO_INLINE(void CreateJSEntryStub());
1833   NO_INLINE(void CreateJSConstructEntryStub());
1834
1835   void CreateFixedStubs();
1836
1837   MaybeObject* CreateOddball(const char* to_string,
1838                              Object* to_number,
1839                              byte kind);
1840
1841   // Allocate a JSArray with no elements
1842   MUST_USE_RESULT MaybeObject* AllocateJSArray(
1843       ElementsKind elements_kind,
1844       PretenureFlag pretenure = NOT_TENURED);
1845
1846   // Allocate empty fixed array.
1847   MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray();
1848
1849   // Allocate empty fixed double array.
1850   MUST_USE_RESULT MaybeObject* AllocateEmptyFixedDoubleArray();
1851
1852   // Performs a minor collection in new generation.
1853   void Scavenge();
1854
1855   static HeapObject* UpdateNewSpaceReferenceInExternalStringTableEntry(
1856       Heap* heap,
1857       Object** pointer);
1858
1859   Address DoScavenge(ObjectVisitor* scavenge_visitor, Address new_space_front);
1860   static void ScavengeStoreBufferCallback(Heap* heap,
1861                                           MemoryChunk* page,
1862                                           StoreBufferEvent event);
1863
1864   // Performs a major collection in the whole heap.
1865   void MarkCompact(GCTracer* tracer);
1866
1867   // Code to be run before and after mark-compact.
1868   void MarkCompactPrologue();
1869
1870   // Record statistics before and after garbage collection.
1871   void ReportStatisticsBeforeGC();
1872   void ReportStatisticsAfterGC();
1873
1874   // Slow part of scavenge object.
1875   static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
1876
1877   // Initializes a function with a shared part and prototype.
1878   // Note: this code was factored out of AllocateFunction such that
1879   // other parts of the VM could use it. Specifically, a function that creates
1880   // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
1881   // Please note this does not perform a garbage collection.
1882   inline void InitializeFunction(
1883       JSFunction* function,
1884       SharedFunctionInfo* shared,
1885       Object* prototype);
1886
1887   // Total RegExp code ever generated
1888   double total_regexp_code_generated_;
1889
1890   GCTracer* tracer_;
1891
1892
1893   // Allocates a small number to string cache.
1894   MUST_USE_RESULT MaybeObject* AllocateInitialNumberStringCache();
1895   // Creates and installs the full-sized number string cache.
1896   void AllocateFullSizeNumberStringCache();
1897   // Get the length of the number to string cache based on the max semispace
1898   // size.
1899   int FullSizeNumberStringCacheLength();
1900   // Flush the number to string cache.
1901   void FlushNumberStringCache();
1902
1903   void UpdateSurvivalRateTrend(int start_new_space_size);
1904
1905   enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING };
1906
1907   static const int kYoungSurvivalRateHighThreshold = 90;
1908   static const int kYoungSurvivalRateLowThreshold = 10;
1909   static const int kYoungSurvivalRateAllowedDeviation = 15;
1910
1911   int young_survivors_after_last_gc_;
1912   int high_survival_rate_period_length_;
1913   int low_survival_rate_period_length_;
1914   double survival_rate_;
1915   SurvivalRateTrend previous_survival_rate_trend_;
1916   SurvivalRateTrend survival_rate_trend_;
1917
1918   void set_survival_rate_trend(SurvivalRateTrend survival_rate_trend) {
1919     ASSERT(survival_rate_trend != FLUCTUATING);
1920     previous_survival_rate_trend_ = survival_rate_trend_;
1921     survival_rate_trend_ = survival_rate_trend;
1922   }
1923
1924   SurvivalRateTrend survival_rate_trend() {
1925     if (survival_rate_trend_ == STABLE) {
1926       return STABLE;
1927     } else if (previous_survival_rate_trend_ == STABLE) {
1928       return survival_rate_trend_;
1929     } else if (survival_rate_trend_ != previous_survival_rate_trend_) {
1930       return FLUCTUATING;
1931     } else {
1932       return survival_rate_trend_;
1933     }
1934   }
1935
1936   bool IsStableOrIncreasingSurvivalTrend() {
1937     switch (survival_rate_trend()) {
1938       case STABLE:
1939       case INCREASING:
1940         return true;
1941       default:
1942         return false;
1943     }
1944   }
1945
1946   bool IsStableOrDecreasingSurvivalTrend() {
1947     switch (survival_rate_trend()) {
1948       case STABLE:
1949       case DECREASING:
1950         return true;
1951       default:
1952         return false;
1953     }
1954   }
1955
1956   bool IsIncreasingSurvivalTrend() {
1957     return survival_rate_trend() == INCREASING;
1958   }
1959
1960   bool IsHighSurvivalRate() {
1961     return high_survival_rate_period_length_ > 0;
1962   }
1963
1964   bool IsLowSurvivalRate() {
1965     return low_survival_rate_period_length_ > 0;
1966   }
1967
1968   void SelectScavengingVisitorsTable();
1969
1970   void StartIdleRound() {
1971     mark_sweeps_since_idle_round_started_ = 0;
1972     ms_count_at_last_idle_notification_ = ms_count_;
1973   }
1974
1975   void FinishIdleRound() {
1976     mark_sweeps_since_idle_round_started_ = kMaxMarkSweepsInIdleRound;
1977     scavenges_since_last_idle_round_ = 0;
1978   }
1979
1980   bool EnoughGarbageSinceLastIdleRound() {
1981     return (scavenges_since_last_idle_round_ >= kIdleScavengeThreshold);
1982   }
1983
1984   // Estimates how many milliseconds a Mark-Sweep would take to complete.
1985   // In idle notification handler we assume that this function will return:
1986   // - a number less than 10 for small heaps, which are less than 8Mb.
1987   // - a number greater than 10 for large heaps, which are greater than 32Mb.
1988   int TimeMarkSweepWouldTakeInMs() {
1989     // Rough estimate of how many megabytes of heap can be processed in 1 ms.
1990     static const int kMbPerMs = 2;
1991
1992     int heap_size_mb = static_cast<int>(SizeOfObjects() / MB);
1993     return heap_size_mb / kMbPerMs;
1994   }
1995
1996   // Returns true if no more GC work is left.
1997   bool IdleGlobalGC();
1998
1999   void AdvanceIdleIncrementalMarking(intptr_t step_size);
2000
2001
2002   static const int kInitialSymbolTableSize = 2048;
2003   static const int kInitialEvalCacheSize = 64;
2004   static const int kInitialNumberStringCacheSize = 256;
2005
2006   // Maximum GC pause.
2007   int max_gc_pause_;
2008
2009   // Maximum size of objects alive after GC.
2010   intptr_t max_alive_after_gc_;
2011
2012   // Minimal interval between two subsequent collections.
2013   int min_in_mutator_;
2014
2015   // Size of objects alive after last GC.
2016   intptr_t alive_after_last_gc_;
2017
2018   double last_gc_end_timestamp_;
2019
2020   MarkCompactCollector mark_compact_collector_;
2021
2022   StoreBuffer store_buffer_;
2023
2024   Marking marking_;
2025
2026   IncrementalMarking incremental_marking_;
2027
2028   int number_idle_notifications_;
2029   unsigned int last_idle_notification_gc_count_;
2030   bool last_idle_notification_gc_count_init_;
2031
2032   int mark_sweeps_since_idle_round_started_;
2033   int ms_count_at_last_idle_notification_;
2034   unsigned int gc_count_at_last_idle_gc_;
2035   int scavenges_since_last_idle_round_;
2036
2037   static const int kMaxMarkSweepsInIdleRound = 7;
2038   static const int kIdleScavengeThreshold = 5;
2039
2040   // Shared state read by the scavenge collector and set by ScavengeObject.
2041   PromotionQueue promotion_queue_;
2042
2043   // Flag is set when the heap has been configured.  The heap can be repeatedly
2044   // configured through the API until it is set up.
2045   bool configured_;
2046
2047   ExternalStringTable external_string_table_;
2048
2049   VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_;
2050
2051   MemoryChunk* chunks_queued_for_free_;
2052
2053   friend class Factory;
2054   friend class GCTracer;
2055   friend class DisallowAllocationFailure;
2056   friend class AlwaysAllocateScope;
2057   friend class LinearAllocationScope;
2058   friend class Page;
2059   friend class Isolate;
2060   friend class MarkCompactCollector;
2061   friend class StaticMarkingVisitor;
2062   friend class MapCompact;
2063
2064   DISALLOW_COPY_AND_ASSIGN(Heap);
2065 };
2066
2067
2068 class HeapStats {
2069  public:
2070   static const int kStartMarker = 0xDECADE00;
2071   static const int kEndMarker = 0xDECADE01;
2072
2073   int* start_marker;                    //  0
2074   int* new_space_size;                  //  1
2075   int* new_space_capacity;              //  2
2076   intptr_t* old_pointer_space_size;          //  3
2077   intptr_t* old_pointer_space_capacity;      //  4
2078   intptr_t* old_data_space_size;             //  5
2079   intptr_t* old_data_space_capacity;         //  6
2080   intptr_t* code_space_size;                 //  7
2081   intptr_t* code_space_capacity;             //  8
2082   intptr_t* map_space_size;                  //  9
2083   intptr_t* map_space_capacity;              // 10
2084   intptr_t* cell_space_size;                 // 11
2085   intptr_t* cell_space_capacity;             // 12
2086   intptr_t* lo_space_size;                   // 13
2087   int* global_handle_count;             // 14
2088   int* weak_global_handle_count;        // 15
2089   int* pending_global_handle_count;     // 16
2090   int* near_death_global_handle_count;  // 17
2091   int* free_global_handle_count;        // 18
2092   intptr_t* memory_allocator_size;           // 19
2093   intptr_t* memory_allocator_capacity;       // 20
2094   int* objects_per_type;                // 21
2095   int* size_per_type;                   // 22
2096   int* os_error;                        // 23
2097   int* end_marker;                      // 24
2098 };
2099
2100
2101 class AlwaysAllocateScope {
2102  public:
2103   inline AlwaysAllocateScope();
2104   inline ~AlwaysAllocateScope();
2105 };
2106
2107
2108 class LinearAllocationScope {
2109  public:
2110   inline LinearAllocationScope();
2111   inline ~LinearAllocationScope();
2112 };
2113
2114
2115 #ifdef DEBUG
2116 // Visitor class to verify interior pointers in spaces that do not contain
2117 // or care about intergenerational references. All heap object pointers have to
2118 // point into the heap to a location that has a map pointer at its first word.
2119 // Caveat: Heap::Contains is an approximation because it can return true for
2120 // objects in a heap space but above the allocation pointer.
2121 class VerifyPointersVisitor: public ObjectVisitor {
2122  public:
2123   inline void VisitPointers(Object** start, Object** end);
2124 };
2125 #endif
2126
2127
2128 // Space iterator for iterating over all spaces of the heap.
2129 // Returns each space in turn, and null when it is done.
2130 class AllSpaces BASE_EMBEDDED {
2131  public:
2132   Space* next();
2133   AllSpaces() { counter_ = FIRST_SPACE; }
2134  private:
2135   int counter_;
2136 };
2137
2138
2139 // Space iterator for iterating over all old spaces of the heap: Old pointer
2140 // space, old data space and code space.
2141 // Returns each space in turn, and null when it is done.
2142 class OldSpaces BASE_EMBEDDED {
2143  public:
2144   OldSpace* next();
2145   OldSpaces() { counter_ = OLD_POINTER_SPACE; }
2146  private:
2147   int counter_;
2148 };
2149
2150
2151 // Space iterator for iterating over all the paged spaces of the heap:
2152 // Map space, old pointer space, old data space, code space and cell space.
2153 // Returns each space in turn, and null when it is done.
2154 class PagedSpaces BASE_EMBEDDED {
2155  public:
2156   PagedSpace* next();
2157   PagedSpaces() { counter_ = OLD_POINTER_SPACE; }
2158  private:
2159   int counter_;
2160 };
2161
2162
2163 // Space iterator for iterating over all spaces of the heap.
2164 // For each space an object iterator is provided. The deallocation of the
2165 // returned object iterators is handled by the space iterator.
2166 class SpaceIterator : public Malloced {
2167  public:
2168   SpaceIterator();
2169   explicit SpaceIterator(HeapObjectCallback size_func);
2170   virtual ~SpaceIterator();
2171
2172   bool has_next();
2173   ObjectIterator* next();
2174
2175  private:
2176   ObjectIterator* CreateIterator();
2177
2178   int current_space_;  // from enum AllocationSpace.
2179   ObjectIterator* iterator_;  // object iterator for the current space.
2180   HeapObjectCallback size_func_;
2181 };
2182
2183
2184 // A HeapIterator provides iteration over the whole heap. It
2185 // aggregates the specific iterators for the different spaces as
2186 // these can only iterate over one space only.
2187 //
2188 // HeapIterator can skip free list nodes (that is, de-allocated heap
2189 // objects that still remain in the heap). As implementation of free
2190 // nodes filtering uses GC marks, it can't be used during MS/MC GC
2191 // phases. Also, it is forbidden to interrupt iteration in this mode,
2192 // as this will leave heap objects marked (and thus, unusable).
2193 class HeapObjectsFilter;
2194
2195 class HeapIterator BASE_EMBEDDED {
2196  public:
2197   enum HeapObjectsFiltering {
2198     kNoFiltering,
2199     kFilterUnreachable
2200   };
2201
2202   HeapIterator();
2203   explicit HeapIterator(HeapObjectsFiltering filtering);
2204   ~HeapIterator();
2205
2206   HeapObject* next();
2207   void reset();
2208
2209  private:
2210   // Perform the initialization.
2211   void Init();
2212   // Perform all necessary shutdown (destruction) work.
2213   void Shutdown();
2214   HeapObject* NextObject();
2215
2216   HeapObjectsFiltering filtering_;
2217   HeapObjectsFilter* filter_;
2218   // Space iterator for iterating all the spaces.
2219   SpaceIterator* space_iterator_;
2220   // Object iterator for the space currently being iterated.
2221   ObjectIterator* object_iterator_;
2222 };
2223
2224
2225 // Cache for mapping (map, property name) into field offset.
2226 // Cleared at startup and prior to mark sweep collection.
2227 class KeyedLookupCache {
2228  public:
2229   // Lookup field offset for (map, name). If absent, -1 is returned.
2230   int Lookup(Map* map, String* name);
2231
2232   // Update an element in the cache.
2233   void Update(Map* map, String* name, int field_offset);
2234
2235   // Clear the cache.
2236   void Clear();
2237
2238   static const int kLength = 256;
2239   static const int kCapacityMask = kLength - 1;
2240   static const int kMapHashShift = 5;
2241   static const int kHashMask = -4;  // Zero the last two bits.
2242   static const int kEntriesPerBucket = 4;
2243   static const int kNotFound = -1;
2244
2245   // kEntriesPerBucket should be a power of 2.
2246   STATIC_ASSERT((kEntriesPerBucket & (kEntriesPerBucket - 1)) == 0);
2247   STATIC_ASSERT(kEntriesPerBucket == -kHashMask);
2248
2249  private:
2250   KeyedLookupCache() {
2251     for (int i = 0; i < kLength; ++i) {
2252       keys_[i].map = NULL;
2253       keys_[i].name = NULL;
2254       field_offsets_[i] = kNotFound;
2255     }
2256   }
2257
2258   static inline int Hash(Map* map, String* name);
2259
2260   // Get the address of the keys and field_offsets arrays.  Used in
2261   // generated code to perform cache lookups.
2262   Address keys_address() {
2263     return reinterpret_cast<Address>(&keys_);
2264   }
2265
2266   Address field_offsets_address() {
2267     return reinterpret_cast<Address>(&field_offsets_);
2268   }
2269
2270   struct Key {
2271     Map* map;
2272     String* name;
2273   };
2274
2275   Key keys_[kLength];
2276   int field_offsets_[kLength];
2277
2278   friend class ExternalReference;
2279   friend class Isolate;
2280   DISALLOW_COPY_AND_ASSIGN(KeyedLookupCache);
2281 };
2282
2283
2284 // Cache for mapping (array, property name) into descriptor index.
2285 // The cache contains both positive and negative results.
2286 // Descriptor index equals kNotFound means the property is absent.
2287 // Cleared at startup and prior to any gc.
2288 class DescriptorLookupCache {
2289  public:
2290   // Lookup descriptor index for (map, name).
2291   // If absent, kAbsent is returned.
2292   int Lookup(DescriptorArray* array, String* name) {
2293     if (!StringShape(name).IsSymbol()) return kAbsent;
2294     int index = Hash(array, name);
2295     Key& key = keys_[index];
2296     if ((key.array == array) && (key.name == name)) return results_[index];
2297     return kAbsent;
2298   }
2299
2300   // Update an element in the cache.
2301   void Update(DescriptorArray* array, String* name, int result) {
2302     ASSERT(result != kAbsent);
2303     if (StringShape(name).IsSymbol()) {
2304       int index = Hash(array, name);
2305       Key& key = keys_[index];
2306       key.array = array;
2307       key.name = name;
2308       results_[index] = result;
2309     }
2310   }
2311
2312   // Clear the cache.
2313   void Clear();
2314
2315   static const int kAbsent = -2;
2316
2317  private:
2318   DescriptorLookupCache() {
2319     for (int i = 0; i < kLength; ++i) {
2320       keys_[i].array = NULL;
2321       keys_[i].name = NULL;
2322       results_[i] = kAbsent;
2323     }
2324   }
2325
2326   static int Hash(DescriptorArray* array, String* name) {
2327     // Uses only lower 32 bits if pointers are larger.
2328     uint32_t array_hash =
2329         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2;
2330     uint32_t name_hash =
2331         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2;
2332     return (array_hash ^ name_hash) % kLength;
2333   }
2334
2335   static const int kLength = 64;
2336   struct Key {
2337     DescriptorArray* array;
2338     String* name;
2339   };
2340
2341   Key keys_[kLength];
2342   int results_[kLength];
2343
2344   friend class Isolate;
2345   DISALLOW_COPY_AND_ASSIGN(DescriptorLookupCache);
2346 };
2347
2348
2349 #ifdef DEBUG
2350 class DisallowAllocationFailure {
2351  public:
2352   inline DisallowAllocationFailure();
2353   inline ~DisallowAllocationFailure();
2354
2355  private:
2356   bool old_state_;
2357 };
2358 #endif
2359
2360
2361 // A helper class to document/test C++ scopes where we do not
2362 // expect a GC. Usage:
2363 //
2364 // /* Allocation not allowed: we cannot handle a GC in this scope. */
2365 // { AssertNoAllocation nogc;
2366 //   ...
2367 // }
2368 class AssertNoAllocation {
2369  public:
2370   inline AssertNoAllocation();
2371   inline ~AssertNoAllocation();
2372
2373 #ifdef DEBUG
2374  private:
2375   bool old_state_;
2376 #endif
2377 };
2378
2379
2380 class DisableAssertNoAllocation {
2381  public:
2382   inline DisableAssertNoAllocation();
2383   inline ~DisableAssertNoAllocation();
2384
2385 #ifdef DEBUG
2386  private:
2387   bool old_state_;
2388 #endif
2389 };
2390
2391 // GCTracer collects and prints ONE line after each garbage collector
2392 // invocation IFF --trace_gc is used.
2393
2394 class GCTracer BASE_EMBEDDED {
2395  public:
2396   class Scope BASE_EMBEDDED {
2397    public:
2398     enum ScopeId {
2399       EXTERNAL,
2400       MC_MARK,
2401       MC_SWEEP,
2402       MC_SWEEP_NEWSPACE,
2403       MC_EVACUATE_PAGES,
2404       MC_UPDATE_NEW_TO_NEW_POINTERS,
2405       MC_UPDATE_ROOT_TO_NEW_POINTERS,
2406       MC_UPDATE_OLD_TO_NEW_POINTERS,
2407       MC_UPDATE_POINTERS_TO_EVACUATED,
2408       MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
2409       MC_UPDATE_MISC_POINTERS,
2410       MC_FLUSH_CODE,
2411       kNumberOfScopes
2412     };
2413
2414     Scope(GCTracer* tracer, ScopeId scope)
2415         : tracer_(tracer),
2416         scope_(scope) {
2417       start_time_ = OS::TimeCurrentMillis();
2418     }
2419
2420     ~Scope() {
2421       ASSERT(scope_ < kNumberOfScopes);  // scope_ is unsigned.
2422       tracer_->scopes_[scope_] += OS::TimeCurrentMillis() - start_time_;
2423     }
2424
2425    private:
2426     GCTracer* tracer_;
2427     ScopeId scope_;
2428     double start_time_;
2429   };
2430
2431   explicit GCTracer(Heap* heap,
2432                     const char* gc_reason,
2433                     const char* collector_reason);
2434   ~GCTracer();
2435
2436   // Sets the collector.
2437   void set_collector(GarbageCollector collector) { collector_ = collector; }
2438
2439   // Sets the GC count.
2440   void set_gc_count(unsigned int count) { gc_count_ = count; }
2441
2442   // Sets the full GC count.
2443   void set_full_gc_count(int count) { full_gc_count_ = count; }
2444
2445   void increment_promoted_objects_size(int object_size) {
2446     promoted_objects_size_ += object_size;
2447   }
2448
2449  private:
2450   // Returns a string matching the collector.
2451   const char* CollectorString();
2452
2453   // Returns size of object in heap (in MB).
2454   inline double SizeOfHeapObjects();
2455
2456   // Timestamp set in the constructor.
2457   double start_time_;
2458
2459   // Size of objects in heap set in constructor.
2460   intptr_t start_object_size_;
2461
2462   // Size of memory allocated from OS set in constructor.
2463   intptr_t start_memory_size_;
2464
2465   // Type of collector.
2466   GarbageCollector collector_;
2467
2468   // A count (including this one, e.g. the first collection is 1) of the
2469   // number of garbage collections.
2470   unsigned int gc_count_;
2471
2472   // A count (including this one) of the number of full garbage collections.
2473   int full_gc_count_;
2474
2475   // Amounts of time spent in different scopes during GC.
2476   double scopes_[Scope::kNumberOfScopes];
2477
2478   // Total amount of space either wasted or contained in one of free lists
2479   // before the current GC.
2480   intptr_t in_free_list_or_wasted_before_gc_;
2481
2482   // Difference between space used in the heap at the beginning of the current
2483   // collection and the end of the previous collection.
2484   intptr_t allocated_since_last_gc_;
2485
2486   // Amount of time spent in mutator that is time elapsed between end of the
2487   // previous collection and the beginning of the current one.
2488   double spent_in_mutator_;
2489
2490   // Size of objects promoted during the current collection.
2491   intptr_t promoted_objects_size_;
2492
2493   // Incremental marking steps counters.
2494   int steps_count_;
2495   double steps_took_;
2496   double longest_step_;
2497   int steps_count_since_last_gc_;
2498   double steps_took_since_last_gc_;
2499
2500   Heap* heap_;
2501
2502   const char* gc_reason_;
2503   const char* collector_reason_;
2504 };
2505
2506
2507 class StringSplitCache {
2508  public:
2509   static Object* Lookup(FixedArray* cache, String* string, String* pattern);
2510   static void Enter(Heap* heap,
2511                     FixedArray* cache,
2512                     String* string,
2513                     String* pattern,
2514                     FixedArray* array);
2515   static void Clear(FixedArray* cache);
2516   static const int kStringSplitCacheSize = 0x100;
2517
2518  private:
2519   static const int kArrayEntriesPerCacheEntry = 4;
2520   static const int kStringOffset = 0;
2521   static const int kPatternOffset = 1;
2522   static const int kArrayOffset = 2;
2523
2524   static MaybeObject* WrapFixedArrayInJSArray(Object* fixed_array);
2525 };
2526
2527
2528 class TranscendentalCache {
2529  public:
2530   enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches};
2531   static const int kTranscendentalTypeBits = 3;
2532   STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches);
2533
2534   // Returns a heap number with f(input), where f is a math function specified
2535   // by the 'type' argument.
2536   MUST_USE_RESULT inline MaybeObject* Get(Type type, double input);
2537
2538   // The cache contains raw Object pointers.  This method disposes of
2539   // them before a garbage collection.
2540   void Clear();
2541
2542  private:
2543   class SubCache {
2544     static const int kCacheSize = 512;
2545
2546     explicit SubCache(Type t);
2547
2548     MUST_USE_RESULT inline MaybeObject* Get(double input);
2549
2550     inline double Calculate(double input);
2551
2552     struct Element {
2553       uint32_t in[2];
2554       Object* output;
2555     };
2556
2557     union Converter {
2558       double dbl;
2559       uint32_t integers[2];
2560     };
2561
2562     inline static int Hash(const Converter& c) {
2563       uint32_t hash = (c.integers[0] ^ c.integers[1]);
2564       hash ^= static_cast<int32_t>(hash) >> 16;
2565       hash ^= static_cast<int32_t>(hash) >> 8;
2566       return (hash & (kCacheSize - 1));
2567     }
2568
2569     Element elements_[kCacheSize];
2570     Type type_;
2571     Isolate* isolate_;
2572
2573     // Allow access to the caches_ array as an ExternalReference.
2574     friend class ExternalReference;
2575     // Inline implementation of the cache.
2576     friend class TranscendentalCacheStub;
2577     // For evaluating value.
2578     friend class TranscendentalCache;
2579
2580     DISALLOW_COPY_AND_ASSIGN(SubCache);
2581   };
2582
2583   TranscendentalCache() {
2584     for (int i = 0; i < kNumberOfCaches; ++i) caches_[i] = NULL;
2585   }
2586
2587   // Used to create an external reference.
2588   inline Address cache_array_address();
2589
2590   // Instantiation
2591   friend class Isolate;
2592   // Inline implementation of the caching.
2593   friend class TranscendentalCacheStub;
2594   // Allow access to the caches_ array as an ExternalReference.
2595   friend class ExternalReference;
2596
2597   SubCache* caches_[kNumberOfCaches];
2598   DISALLOW_COPY_AND_ASSIGN(TranscendentalCache);
2599 };
2600
2601
2602 // Abstract base class for checking whether a weak object should be retained.
2603 class WeakObjectRetainer {
2604  public:
2605   virtual ~WeakObjectRetainer() {}
2606
2607   // Return whether this object should be retained. If NULL is returned the
2608   // object has no references. Otherwise the address of the retained object
2609   // should be returned as in some GC situations the object has been moved.
2610   virtual Object* RetainAs(Object* object) = 0;
2611 };
2612
2613
2614 // Intrusive object marking uses least significant bit of
2615 // heap object's map word to mark objects.
2616 // Normally all map words have least significant bit set
2617 // because they contain tagged map pointer.
2618 // If the bit is not set object is marked.
2619 // All objects should be unmarked before resuming
2620 // JavaScript execution.
2621 class IntrusiveMarking {
2622  public:
2623   static bool IsMarked(HeapObject* object) {
2624     return (object->map_word().ToRawValue() & kNotMarkedBit) == 0;
2625   }
2626
2627   static void ClearMark(HeapObject* object) {
2628     uintptr_t map_word = object->map_word().ToRawValue();
2629     object->set_map_word(MapWord::FromRawValue(map_word | kNotMarkedBit));
2630     ASSERT(!IsMarked(object));
2631   }
2632
2633   static void SetMark(HeapObject* object) {
2634     uintptr_t map_word = object->map_word().ToRawValue();
2635     object->set_map_word(MapWord::FromRawValue(map_word & ~kNotMarkedBit));
2636     ASSERT(IsMarked(object));
2637   }
2638
2639   static Map* MapOfMarkedObject(HeapObject* object) {
2640     uintptr_t map_word = object->map_word().ToRawValue();
2641     return MapWord::FromRawValue(map_word | kNotMarkedBit).ToMap();
2642   }
2643
2644   static int SizeOfMarkedObject(HeapObject* object) {
2645     return object->SizeFromMap(MapOfMarkedObject(object));
2646   }
2647
2648  private:
2649   static const uintptr_t kNotMarkedBit = 0x1;
2650   STATIC_ASSERT((kHeapObjectTag & kNotMarkedBit) != 0);
2651 };
2652
2653
2654 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
2655 // Helper class for tracing paths to a search target Object from all roots.
2656 // The TracePathFrom() method can be used to trace paths from a specific
2657 // object to the search target object.
2658 class PathTracer : public ObjectVisitor {
2659  public:
2660   enum WhatToFind {
2661     FIND_ALL,   // Will find all matches.
2662     FIND_FIRST  // Will stop the search after first match.
2663   };
2664
2665   // For the WhatToFind arg, if FIND_FIRST is specified, tracing will stop
2666   // after the first match.  If FIND_ALL is specified, then tracing will be
2667   // done for all matches.
2668   PathTracer(Object* search_target,
2669              WhatToFind what_to_find,
2670              VisitMode visit_mode)
2671       : search_target_(search_target),
2672         found_target_(false),
2673         found_target_in_trace_(false),
2674         what_to_find_(what_to_find),
2675         visit_mode_(visit_mode),
2676         object_stack_(20),
2677         no_alloc() {}
2678
2679   virtual void VisitPointers(Object** start, Object** end);
2680
2681   void Reset();
2682   void TracePathFrom(Object** root);
2683
2684   bool found() const { return found_target_; }
2685
2686   static Object* const kAnyGlobalObject;
2687
2688  protected:
2689   class MarkVisitor;
2690   class UnmarkVisitor;
2691
2692   void MarkRecursively(Object** p, MarkVisitor* mark_visitor);
2693   void UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor);
2694   virtual void ProcessResults();
2695
2696   // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject.
2697   static const int kMarkTag = 2;
2698
2699   Object* search_target_;
2700   bool found_target_;
2701   bool found_target_in_trace_;
2702   WhatToFind what_to_find_;
2703   VisitMode visit_mode_;
2704   List<Object*> object_stack_;
2705
2706   AssertNoAllocation no_alloc;  // i.e. no gc allowed.
2707
2708  private:
2709   DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer);
2710 };
2711 #endif  // DEBUG || LIVE_OBJECT_LIST
2712
2713 } }  // namespace v8::internal
2714
2715 #endif  // V8_HEAP_H_