blob: f17a091340c1b4f6a0f7c8548388a8c00b56fc46 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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
31namespace v8 { namespace internal {
32
33// Defines all the roots in Heap.
34#define STRONG_ROOT_LIST(V) \
35 V(Map, meta_map) \
36 V(Map, heap_number_map) \
37 V(Map, short_string_map) \
38 V(Map, medium_string_map) \
39 V(Map, long_string_map) \
40 V(Map, short_ascii_string_map) \
41 V(Map, medium_ascii_string_map) \
42 V(Map, long_ascii_string_map) \
43 V(Map, short_symbol_map) \
44 V(Map, medium_symbol_map) \
45 V(Map, long_symbol_map) \
46 V(Map, short_ascii_symbol_map) \
47 V(Map, medium_ascii_symbol_map) \
48 V(Map, long_ascii_symbol_map) \
49 V(Map, short_cons_symbol_map) \
50 V(Map, medium_cons_symbol_map) \
51 V(Map, long_cons_symbol_map) \
52 V(Map, short_cons_ascii_symbol_map) \
53 V(Map, medium_cons_ascii_symbol_map) \
54 V(Map, long_cons_ascii_symbol_map) \
55 V(Map, short_sliced_symbol_map) \
56 V(Map, medium_sliced_symbol_map) \
57 V(Map, long_sliced_symbol_map) \
58 V(Map, short_sliced_ascii_symbol_map) \
59 V(Map, medium_sliced_ascii_symbol_map) \
60 V(Map, long_sliced_ascii_symbol_map) \
61 V(Map, short_external_symbol_map) \
62 V(Map, medium_external_symbol_map) \
63 V(Map, long_external_symbol_map) \
64 V(Map, short_external_ascii_symbol_map) \
65 V(Map, medium_external_ascii_symbol_map) \
66 V(Map, long_external_ascii_symbol_map) \
67 V(Map, short_cons_string_map) \
68 V(Map, medium_cons_string_map) \
69 V(Map, long_cons_string_map) \
70 V(Map, short_cons_ascii_string_map) \
71 V(Map, medium_cons_ascii_string_map) \
72 V(Map, long_cons_ascii_string_map) \
73 V(Map, short_sliced_string_map) \
74 V(Map, medium_sliced_string_map) \
75 V(Map, long_sliced_string_map) \
76 V(Map, short_sliced_ascii_string_map) \
77 V(Map, medium_sliced_ascii_string_map) \
78 V(Map, long_sliced_ascii_string_map) \
79 V(Map, short_external_string_map) \
80 V(Map, medium_external_string_map) \
81 V(Map, long_external_string_map) \
82 V(Map, short_external_ascii_string_map) \
83 V(Map, medium_external_ascii_string_map) \
84 V(Map, long_external_ascii_string_map) \
85 V(Map, undetectable_short_string_map) \
86 V(Map, undetectable_medium_string_map) \
87 V(Map, undetectable_long_string_map) \
88 V(Map, undetectable_short_ascii_string_map) \
89 V(Map, undetectable_medium_ascii_string_map) \
90 V(Map, undetectable_long_ascii_string_map) \
91 V(Map, byte_array_map) \
92 V(Map, fixed_array_map) \
93 V(Map, hash_table_map) \
94 V(Map, context_map) \
95 V(Map, global_context_map) \
96 V(Map, code_map) \
97 V(Map, oddball_map) \
98 V(Map, boilerplate_function_map) \
99 V(Map, shared_function_info_map) \
100 V(Map, proxy_map) \
101 V(Map, one_word_filler_map) \
102 V(Map, two_word_filler_map) \
103 V(Object, nan_value) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000104 V(Object, undefined_value) \
105 V(Object, minus_zero_value) \
106 V(Object, null_value) \
107 V(Object, true_value) \
108 V(Object, false_value) \
109 V(String, empty_string) \
110 V(FixedArray, empty_fixed_array) \
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000111 V(DescriptorArray, empty_descriptor_array) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112 V(Object, the_hole_value) \
113 V(Map, neander_map) \
114 V(JSObject, message_listeners) \
115 V(Proxy, prototype_accessors) \
116 V(JSObject, debug_event_listeners) \
117 V(Dictionary, code_stubs) \
118 V(Dictionary, non_monomorphic_cache) \
119 V(Code, js_entry_code) \
120 V(Code, js_construct_entry_code) \
121 V(Code, c_entry_code) \
122 V(Code, c_entry_debug_break_code) \
123 V(FixedArray, number_string_cache) \
124 V(FixedArray, single_character_string_cache) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000125 V(FixedArray, natives_source_cache) \
126 V(Object, keyed_lookup_cache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128
129#define ROOT_LIST(V) \
130 STRONG_ROOT_LIST(V) \
131 V(Object, symbol_table)
132
133#define SYMBOL_LIST(V) \
134 V(Array_symbol, "Array") \
135 V(Object_symbol, "Object") \
136 V(Proto_symbol, "__proto__") \
137 V(StringImpl_symbol, "StringImpl") \
138 V(arguments_symbol, "arguments") \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000139 V(Arguments_symbol, "Arguments") \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140 V(arguments_shadow_symbol, ".arguments") \
141 V(call_symbol, "call") \
142 V(apply_symbol, "apply") \
143 V(caller_symbol, "caller") \
144 V(boolean_symbol, "boolean") \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000145 V(Boolean_symbol, "Boolean") \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146 V(callee_symbol, "callee") \
147 V(constructor_symbol, "constructor") \
148 V(code_symbol, ".code") \
149 V(result_symbol, ".result") \
150 V(catch_var_symbol, ".catch-var") \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000151 V(empty_symbol, "") \
152 V(eval_symbol, "eval") \
153 V(function_symbol, "function") \
154 V(length_symbol, "length") \
155 V(name_symbol, "name") \
156 V(number_symbol, "number") \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000157 V(Number_symbol, "Number") \
158 V(RegExp_symbol, "RegExp") \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159 V(object_symbol, "object") \
160 V(prototype_symbol, "prototype") \
161 V(string_symbol, "string") \
ager@chromium.org7c537e22008-10-16 08:43:32 +0000162 V(String_symbol, "String") \
163 V(Date_symbol, "Date") \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164 V(this_symbol, "this") \
165 V(to_string_symbol, "toString") \
166 V(char_at_symbol, "CharAt") \
167 V(undefined_symbol, "undefined") \
168 V(value_of_symbol, "valueOf") \
169 V(CreateObjectLiteralBoilerplate_symbol, "CreateObjectLiteralBoilerplate") \
170 V(CreateArrayLiteral_symbol, "CreateArrayLiteral") \
171 V(InitializeVarGlobal_symbol, "InitializeVarGlobal") \
172 V(InitializeConstGlobal_symbol, "InitializeConstGlobal") \
173 V(stack_overflow_symbol, "kStackOverflowBoilerplate") \
174 V(illegal_access_symbol, "illegal access") \
175 V(out_of_memory_symbol, "out-of-memory") \
176 V(illegal_execution_state_symbol, "illegal execution state") \
177 V(get_symbol, "get") \
178 V(set_symbol, "set") \
179 V(function_class_symbol, "Function") \
180 V(illegal_argument_symbol, "illegal argument") \
181 V(MakeReferenceError_symbol, "MakeReferenceError") \
182 V(MakeSyntaxError_symbol, "MakeSyntaxError") \
183 V(MakeTypeError_symbol, "MakeTypeError") \
184 V(invalid_lhs_in_assignment_symbol, "invalid_lhs_in_assignment") \
185 V(invalid_lhs_in_for_in_symbol, "invalid_lhs_in_for_in") \
186 V(invalid_lhs_in_postfix_op_symbol, "invalid_lhs_in_postfix_op") \
187 V(invalid_lhs_in_prefix_op_symbol, "invalid_lhs_in_prefix_op") \
188 V(illegal_return_symbol, "illegal_return") \
189 V(illegal_break_symbol, "illegal_break") \
190 V(illegal_continue_symbol, "illegal_continue") \
191 V(unknown_label_symbol, "unknown_label") \
192 V(redeclaration_symbol, "redeclaration") \
193 V(failure_symbol, "<failure>") \
194 V(space_symbol, " ") \
195 V(exec_symbol, "exec") \
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000196 V(zero_symbol, "0") \
197 V(global_eval_symbol, "GlobalEval")
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198
199
kasper.lund7276f142008-07-30 08:49:36 +0000200// Forward declaration of the GCTracer class.
201class GCTracer;
202
203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204// The all static Heap captures the interface to the global object heap.
205// All JavaScript contexts by this process share the same object heap.
206
207class Heap : public AllStatic {
208 public:
209 // Configure heap size before setup. Return false if the heap has been
210 // setup already.
211 static bool ConfigureHeap(int semispace_size, int old_gen_size);
kasper.lund7276f142008-07-30 08:49:36 +0000212 static bool ConfigureHeapDefault();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000213
214 // Initializes the global object heap. If create_heap_objects is true,
215 // also creates the basic non-mutable objects.
216 // Returns whether it succeeded.
217 static bool Setup(bool create_heap_objects);
218
219 // Destroys all memory allocated by the heap.
220 static void TearDown();
221
222 // Returns whether Setup has been called.
223 static bool HasBeenSetup();
224
225 // Returns the maximum heap capacity.
226 static int MaxCapacity() {
227 return young_generation_size_ + old_generation_size_;
228 }
229 static int SemiSpaceSize() { return semispace_size_; }
230 static int InitialSemiSpaceSize() { return initial_semispace_size_; }
231 static int YoungGenerationSize() { return young_generation_size_; }
232 static int OldGenerationSize() { return old_generation_size_; }
233
234 // Returns the capacity of the heap in bytes w/o growing. Heap grows when
235 // more spaces are needed until it reaches the limit.
236 static int Capacity();
237
238 // Returns the available bytes in space w/o growing.
239 // Heap doesn't guarantee that it can allocate an object that requires
240 // all available bytes. Check MaxHeapObjectSize() instead.
241 static int Available();
242
243 // Returns the maximum object size that heap supports. Objects larger than
244 // the maximum heap object size are allocated in a large object space.
245 static inline int MaxHeapObjectSize();
246
247 // Returns of size of all objects residing in the heap.
248 static int SizeOfObjects();
249
250 // Return the starting address and a mask for the new space. And-masking an
251 // address with the mask will result in the start address of the new space
252 // for all addresses in either semispace.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000253 static Address NewSpaceStart() { return new_space_.start(); }
254 static uint32_t NewSpaceMask() { return new_space_.mask(); }
255 static Address NewSpaceTop() { return new_space_.top(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000256
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000257 static NewSpace* new_space() { return &new_space_; }
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000258 static OldSpace* old_pointer_space() { return old_pointer_space_; }
259 static OldSpace* old_data_space() { return old_data_space_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000260 static OldSpace* code_space() { return code_space_; }
261 static MapSpace* map_space() { return map_space_; }
262 static LargeObjectSpace* lo_space() { return lo_space_; }
263
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000264 static bool always_allocate() { return always_allocate_scope_depth_ != 0; }
265 static Address always_allocate_scope_depth_address() {
266 return reinterpret_cast<Address>(&always_allocate_scope_depth_);
267 }
268
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000269 static Address* NewSpaceAllocationTopAddress() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000270 return new_space_.allocation_top_address();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000271 }
272 static Address* NewSpaceAllocationLimitAddress() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000273 return new_space_.allocation_limit_address();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000274 }
275
276 // Allocates and initializes a new JavaScript object based on a
277 // constructor.
278 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
279 // failed.
280 // Please note this does not perform a garbage collection.
281 static Object* AllocateJSObject(JSFunction* constructor,
282 PretenureFlag pretenure = NOT_TENURED);
283
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000284 // Returns a deep copy of the JavaScript object.
285 // Properties and elements are copied too.
286 // Returns failure if allocation failed.
287 static Object* CopyJSObject(JSObject* source);
288
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000289 // Allocates the function prototype.
290 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
291 // failed.
292 // Please note this does not perform a garbage collection.
293 static Object* AllocateFunctionPrototype(JSFunction* function);
294
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000295 // Reinitialize an JSGlobalProxy based on a constructor. The object
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000296 // must have the same size as objects allocated using the
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000297 // constructor. The object is reinitialized and behaves as an
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000298 // object that has been freshly allocated using the constructor.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000299 static Object* ReinitializeJSGlobalProxy(JSFunction* constructor,
300 JSGlobalProxy* global);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000301
302 // Allocates and initializes a new JavaScript object based on a map.
303 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
304 // failed.
305 // Please note this does not perform a garbage collection.
306 static Object* AllocateJSObjectFromMap(Map* map,
307 PretenureFlag pretenure = NOT_TENURED);
308
309 // Allocates a heap object based on the map.
310 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
311 // failed.
312 // Please note this function does not perform a garbage collection.
313 static Object* Allocate(Map* map, AllocationSpace space);
314
315 // Allocates a JS Map in the heap.
316 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
317 // failed.
318 // Please note this function does not perform a garbage collection.
319 static Object* AllocateMap(InstanceType instance_type, int instance_size);
320
321 // Allocates a partial map for bootstrapping.
322 static Object* AllocatePartialMap(InstanceType instance_type,
323 int instance_size);
324
325 // Allocate a map for the specified function
326 static Object* AllocateInitialMap(JSFunction* fun);
327
328 // Allocates and fully initializes a String. There are two String
329 // encodings: ASCII and two byte. One should choose between the three string
330 // allocation functions based on the encoding of the string buffer used to
331 // initialized the string.
332 // - ...FromAscii initializes the string from a buffer that is ASCII
333 // encoded (it does not check that the buffer is ASCII encoded) and the
334 // result will be ASCII encoded.
335 // - ...FromUTF8 initializes the string from a buffer that is UTF-8
336 // encoded. If the characters are all single-byte characters, the
337 // result will be ASCII encoded, otherwise it will converted to two
338 // byte.
339 // - ...FromTwoByte initializes the string from a buffer that is two-byte
340 // encoded. If the characters are all single-byte characters, the
341 // result will be converted to ASCII, otherwise it will be left as
342 // two-byte.
343 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
344 // failed.
345 // Please note this does not perform a garbage collection.
346 static Object* AllocateStringFromAscii(
347 Vector<const char> str,
348 PretenureFlag pretenure = NOT_TENURED);
349 static Object* AllocateStringFromUtf8(
350 Vector<const char> str,
351 PretenureFlag pretenure = NOT_TENURED);
352 static Object* AllocateStringFromTwoByte(
353 Vector<const uc16> str,
354 PretenureFlag pretenure = NOT_TENURED);
355
356 // Allocates a symbol in old space based on the character stream.
357 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
358 // failed.
359 // Please note this function does not perform a garbage collection.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000360 static inline Object* AllocateSymbol(Vector<const char> str,
361 int chars,
362 uint32_t length_field);
363
364 static Object* AllocateInternalSymbol(unibrow::CharacterStream* buffer,
365 int chars,
366 uint32_t length_field);
367
368 static Object* AllocateExternalSymbol(Vector<const char> str,
369 int chars);
370
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000371
372 // Allocates and partially initializes a String. There are two String
373 // encodings: ASCII and two byte. These functions allocate a string of the
374 // given length and set its map and length fields. The characters of the
375 // string are uninitialized.
376 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
377 // failed.
378 // Please note this does not perform a garbage collection.
379 static Object* AllocateRawAsciiString(
380 int length,
381 PretenureFlag pretenure = NOT_TENURED);
382 static Object* AllocateRawTwoByteString(
383 int length,
384 PretenureFlag pretenure = NOT_TENURED);
385
386 // Computes a single character string where the character has code.
387 // A cache is used for ascii codes.
388 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
389 // failed. Please note this does not perform a garbage collection.
390 static Object* LookupSingleCharacterStringFromCode(uint16_t code);
391
392 // Allocate a byte array of the specified length
393 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
394 // failed.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000395 // Please note this does not perform a garbage collection.
396 static Object* AllocateByteArray(int length, PretenureFlag pretenure);
397
398 // Allocate a non-tenured byte array of the specified length
399 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
400 // failed.
401 // Please note this does not perform a garbage collection.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000402 static Object* AllocateByteArray(int length);
403
404 // Allocates a fixed array initialized with undefined values
405 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
406 // failed.
407 // Please note this does not perform a garbage collection.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000408 static Object* AllocateFixedArray(int length, PretenureFlag pretenure);
409 // Allocate uninitialized, non-tenured fixed array with length elements.
410 static Object* AllocateFixedArray(int length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000411
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000412 // Make a copy of src and return it. Returns
413 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
414 static Object* CopyFixedArray(FixedArray* src);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415
416 // Allocates a fixed array initialized with the hole values.
417 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
418 // failed.
419 // Please note this does not perform a garbage collection.
420 static Object* AllocateFixedArrayWithHoles(int length);
421
422 // AllocateHashTable is identical to AllocateFixedArray except
423 // that the resulting object has hash_table_map as map.
424 static Object* AllocateHashTable(int length);
425
426 // Allocate a global (but otherwise uninitialized) context.
427 static Object* AllocateGlobalContext();
428
429 // Allocate a function context.
430 static Object* AllocateFunctionContext(int length, JSFunction* closure);
431
432 // Allocate a 'with' context.
433 static Object* AllocateWithContext(Context* previous, JSObject* extension);
434
435 // Allocates a new utility object in the old generation.
436 static Object* AllocateStruct(InstanceType type);
437
438
439 // Initializes a function with a shared part and prototype.
440 // Returns the function.
441 // Note: this code was factored out of AllocateFunction such that
442 // other parts of the VM could use it. Specifically, a function that creates
443 // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
444 // Please note this does not perform a garbage collection.
445 static Object* InitializeFunction(JSFunction* function,
446 SharedFunctionInfo* shared,
447 Object* prototype);
448
449 // Allocates a function initialized with a shared part.
450 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
451 // failed.
452 // Please note this does not perform a garbage collection.
453 static Object* AllocateFunction(Map* function_map,
454 SharedFunctionInfo* shared,
455 Object* prototype);
456
457 // Indicies for direct access into argument objects.
458 static const int arguments_callee_index = 0;
459 static const int arguments_length_index = 1;
460
461 // Allocates an arguments object - optionally with an elements array.
462 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
463 // failed.
464 // Please note this does not perform a garbage collection.
465 static Object* AllocateArgumentsObject(Object* callee, int length);
466
467 // Converts a double into either a Smi or a HeapNumber object.
468 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
469 // failed.
470 // Please note this does not perform a garbage collection.
471 static Object* NewNumberFromDouble(double value,
472 PretenureFlag pretenure = NOT_TENURED);
473
474 // Same as NewNumberFromDouble, but may return a preallocated/immutable
475 // number object (e.g., minus_zero_value_, nan_value_)
476 static Object* NumberFromDouble(double value,
477 PretenureFlag pretenure = NOT_TENURED);
478
479 // Allocated a HeapNumber from value.
480 static Object* AllocateHeapNumber(double value, PretenureFlag pretenure);
481 static Object* AllocateHeapNumber(double value); // pretenure = NOT_TENURED
482
483 // Converts an int into either a Smi or a HeapNumber object.
484 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
485 // failed.
486 // Please note this does not perform a garbage collection.
487 static inline Object* NumberFromInt32(int32_t value);
488
489 // Converts an int into either a Smi or a HeapNumber object.
490 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
491 // failed.
492 // Please note this does not perform a garbage collection.
493 static inline Object* NumberFromUint32(uint32_t value);
494
495 // Allocates a new proxy object.
496 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
497 // failed.
498 // Please note this does not perform a garbage collection.
499 static Object* AllocateProxy(Address proxy,
500 PretenureFlag pretenure = NOT_TENURED);
501
502 // Allocates a new SharedFunctionInfo object.
503 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
504 // failed.
505 // Please note this does not perform a garbage collection.
506 static Object* AllocateSharedFunctionInfo(Object* name);
507
508 // Allocates a new cons string object.
509 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
510 // failed.
511 // Please note this does not perform a garbage collection.
ager@chromium.org870a0b62008-11-04 11:43:05 +0000512 static Object* AllocateConsString(String* first,
ager@chromium.orgc3e50d82008-11-05 11:53:10 +0000513 String* second);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514
515 // Allocates a new sliced string object which is a slice of an underlying
516 // string buffer stretching from the index start (inclusive) to the index
517 // end (exclusive).
518 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
519 // failed.
520 // Please note this does not perform a garbage collection.
ager@chromium.org870a0b62008-11-04 11:43:05 +0000521 static Object* AllocateSlicedString(String* buffer,
ager@chromium.org870a0b62008-11-04 11:43:05 +0000522 int start,
523 int end);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524
525 // Allocates a new sub string object which is a substring of an underlying
526 // string buffer stretching from the index start (inclusive) to the index
527 // end (exclusive).
528 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
529 // failed.
530 // Please note this does not perform a garbage collection.
ager@chromium.org870a0b62008-11-04 11:43:05 +0000531 static Object* AllocateSubString(String* buffer,
532 StringShape buffer_shape,
533 int start,
534 int end);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535
536 // Allocate a new external string object, which is backed by a string
537 // resource that resides outside the V8 heap.
538 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
539 // failed.
540 // Please note this does not perform a garbage collection.
541 static Object* AllocateExternalStringFromAscii(
542 ExternalAsciiString::Resource* resource);
543 static Object* AllocateExternalStringFromTwoByte(
544 ExternalTwoByteString::Resource* resource);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000545 static Object* AllocateExternalSymbolFromTwoByte(
546 ExternalTwoByteString::Resource* resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000547
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000548 // Allocates an uninitialized object. The memory is non-executable if the
549 // hardware and OS allow.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
551 // failed.
552 // Please note this function does not perform a garbage collection.
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000553 static inline Object* AllocateRaw(int size_in_bytes,
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000554 AllocationSpace space,
555 AllocationSpace retry_space);
kasper.lund7276f142008-07-30 08:49:36 +0000556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557 // Makes a new native code object
558 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000559 // failed. On success, the pointer to the Code object is stored in the
560 // self_reference. This allows generated code to reference its own Code
561 // object by containing this pointer.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000562 // Please note this function does not perform a garbage collection.
563 static Object* CreateCode(const CodeDesc& desc,
564 ScopeInfo<>* sinfo,
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000565 Code::Flags flags,
566 Code** self_reference = NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567
568 static Object* CopyCode(Code* code);
569 // Finds the symbol for string in the symbol table.
570 // If not found, a new symbol is added to the table and returned.
571 // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
572 // failed.
573 // Please note this function does not perform a garbage collection.
574 static Object* LookupSymbol(Vector<const char> str);
575 static Object* LookupAsciiSymbol(const char* str) {
576 return LookupSymbol(CStrVector(str));
577 }
578 static Object* LookupSymbol(String* str);
ager@chromium.org7c537e22008-10-16 08:43:32 +0000579 static bool LookupSymbolIfExists(String* str, String** symbol);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580
581 // Compute the matching symbol map for a string if possible.
582 // NULL is returned if string is in new space or not flattened.
583 static Map* SymbolMapForString(String* str);
584
585 // Converts the given boolean condition to JavaScript boolean value.
586 static Object* ToBoolean(bool condition) {
587 return condition ? true_value() : false_value();
588 }
589
590 // Code that should be run before and after each GC. Includes some
591 // reporting/verification activities when compiled with DEBUG set.
592 static void GarbageCollectionPrologue();
593 static void GarbageCollectionEpilogue();
594
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000595 // Code that should be executed after the garbage collection proper.
596 static void PostGarbageCollectionProcessing();
597
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000598 // Performs garbage collection operation.
599 // Returns whether required_space bytes are available after the collection.
600 static bool CollectGarbage(int required_space, AllocationSpace space);
601
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000602 // Performs a full garbage collection.
603 static void CollectAllGarbage();
604
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605 // Utility to invoke the scavenger. This is needed in test code to
606 // ensure correct callback for weak global handles.
kasper.lund7276f142008-07-30 08:49:36 +0000607 static void PerformScavenge();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000609#ifdef DEBUG
610 // Utility used with flag gc-greedy.
611 static bool GarbageCollectionGreedyCheck();
612#endif
613
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000614 static void SetGlobalGCPrologueCallback(GCCallback callback) {
615 global_gc_prologue_callback_ = callback;
616 }
617 static void SetGlobalGCEpilogueCallback(GCCallback callback) {
618 global_gc_epilogue_callback_ = callback;
619 }
620
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000621 static void SetExternalSymbolCallback(ExternalSymbolCallback callback) {
622 global_external_symbol_callback_ = callback;
623 }
624
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000625 // Heap roots
626#define ROOT_ACCESSOR(type, name) static type* name() { return name##_; }
627 ROOT_LIST(ROOT_ACCESSOR)
628#undef ROOT_ACCESSOR
629
630// Utility type maps
631#define STRUCT_MAP_ACCESSOR(NAME, Name, name) \
632 static Map* name##_map() { return name##_map_; }
633 STRUCT_LIST(STRUCT_MAP_ACCESSOR)
634#undef STRUCT_MAP_ACCESSOR
635
636#define SYMBOL_ACCESSOR(name, str) static String* name() { return name##_; }
637 SYMBOL_LIST(SYMBOL_ACCESSOR)
638#undef SYMBOL_ACCESSOR
639
640 // Iterates over all roots in the heap.
641 static void IterateRoots(ObjectVisitor* v);
642 // Iterates over all strong roots in the heap.
643 static void IterateStrongRoots(ObjectVisitor* v);
644
645 // Iterates remembered set of an old space.
646 static void IterateRSet(PagedSpace* space, ObjectSlotCallback callback);
647
648 // Iterates a range of remembered set addresses starting with rset_start
649 // corresponding to the range of allocated pointers
650 // [object_start, object_end).
651 static void IterateRSetRange(Address object_start,
652 Address object_end,
653 Address rset_start,
654 ObjectSlotCallback copy_object_func);
655
656 // Returns whether the object resides in new space.
657 static inline bool InNewSpace(Object* object);
658 static inline bool InFromSpace(Object* object);
659 static inline bool InToSpace(Object* object);
660
661 // Checks whether an address/object in the heap (including auxiliary
662 // area and unused area).
663 static bool Contains(Address addr);
664 static bool Contains(HeapObject* value);
665
666 // Checks whether an address/object in a space.
667 // Currently used by tests and heap verification only.
668 static bool InSpace(Address addr, AllocationSpace space);
669 static bool InSpace(HeapObject* value, AllocationSpace space);
670
kasper.lund7276f142008-07-30 08:49:36 +0000671 // Finds out which space an object should get promoted to based on its type.
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000672 static inline OldSpace* TargetSpace(HeapObject* object);
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000673 static inline AllocationSpace TargetSpaceId(InstanceType type);
kasper.lund7276f142008-07-30 08:49:36 +0000674
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000675 // Sets the stub_cache_ (only used when expanding the dictionary).
676 static void set_code_stubs(Dictionary* value) { code_stubs_ = value; }
677
678 // Sets the non_monomorphic_cache_ (only used when expanding the dictionary).
679 static void set_non_monomorphic_cache(Dictionary* value) {
680 non_monomorphic_cache_ = value;
681 }
682
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000683 // Gets, sets and clears the lookup cache used for keyed access.
684 static inline Object* GetKeyedLookupCache();
685 static inline void SetKeyedLookupCache(LookupCache* cache);
686 static inline void ClearKeyedLookupCache();
687
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000688#ifdef DEBUG
689 static void Print();
690 static void PrintHandles();
691
692 // Verify the heap is in its normal state before or after a GC.
693 static void Verify();
694
695 // Report heap statistics.
696 static void ReportHeapStatistics(const char* title);
697 static void ReportCodeStatistics(const char* title);
698
699 // Fill in bogus values in from space
700 static void ZapFromSpace();
701#endif
702
703 // Makes a new symbol object
704 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
705 // failed.
706 // Please note this function does not perform a garbage collection.
707 static Object* CreateSymbol(const char* str, int length, int hash);
708 static Object* CreateSymbol(String* str);
709
710 // Write barrier support for address[offset] = o.
711 inline static void RecordWrite(Address address, int offset);
712
kasper.lund7276f142008-07-30 08:49:36 +0000713 // Given an address occupied by a live code object, return that object.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000714 static Object* FindCodeObject(Address a);
715
716 // Invoke Shrink on shrinkable spaces.
717 static void Shrink();
718
719 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
720 static inline HeapState gc_state() { return gc_state_; }
721
722#ifdef DEBUG
723 static bool IsAllocationAllowed() { return allocation_allowed_; }
724 static inline bool allow_allocation(bool enable);
725
726 static bool disallow_allocation_failure() {
727 return disallow_allocation_failure_;
728 }
729
730 static void TracePathToObject();
731 static void TracePathToGlobal();
732#endif
733
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000734 // Callback function pased to Heap::Iterate etc. Copies an object if
735 // necessary, the object might be promoted to an old space. The caller must
736 // ensure the precondition that the object is (a) a heap object and (b) in
737 // the heap's from space.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738 static void ScavengePointer(HeapObject** p);
739 static inline void ScavengeObject(HeapObject** p, HeapObject* object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000740
741 // Clear a range of remembered set addresses corresponding to the object
742 // area address 'start' with size 'size_in_bytes', eg, when adding blocks
743 // to the free list.
744 static void ClearRSetRange(Address start, int size_in_bytes);
745
746 // Rebuild remembered set in old and map spaces.
747 static void RebuildRSets();
748
749 //
750 // Support for the API.
751 //
752
753 static bool CreateApiObjects();
754
755 // Attempt to find the number in a small cache. If we finds it, return
756 // the string representation of the number. Otherwise return undefined.
757 static Object* GetNumberStringCache(Object* number);
758
759 // Update the cache with a new number-string pair.
760 static void SetNumberStringCache(Object* number, String* str);
761
762 // Entries in the cache. Must be a power of 2.
763 static const int kNumberStringCacheSize = 64;
764
kasper.lund7276f142008-07-30 08:49:36 +0000765 // Adjusts the amount of registered external memory.
766 // Returns the adjusted value.
767 static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
768 int amount = amount_of_external_allocated_memory_ + change_in_bytes;
769 if (change_in_bytes >= 0) {
770 // Avoid overflow.
771 if (amount > amount_of_external_allocated_memory_) {
772 amount_of_external_allocated_memory_ = amount;
773 }
774 } else {
775 // Avoid underflow.
776 if (amount >= 0) {
777 amount_of_external_allocated_memory_ = amount;
778 }
779 }
780 ASSERT(amount_of_external_allocated_memory_ >= 0);
781 return amount_of_external_allocated_memory_;
782 }
783
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000784 // Allocate unitialized fixed array (pretenure == NON_TENURE).
785 static Object* AllocateRawFixedArray(int length);
786
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000787 // True if we have reached the allocation limit in the old generation that
788 // should force the next GC (caused normally) to be a full one.
789 static bool OldGenerationPromotionLimitReached() {
790 return (PromotedSpaceSize() + PromotedExternalMemorySize())
791 > old_gen_promotion_limit_;
792 }
793
794 // True if we have reached the allocation limit in the old generation that
795 // should artificially cause a GC right now.
796 static bool OldGenerationAllocationLimitReached() {
797 return (PromotedSpaceSize() + PromotedExternalMemorySize())
798 > old_gen_allocation_limit_;
799 }
800
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801 private:
802 static int semispace_size_;
803 static int initial_semispace_size_;
804 static int young_generation_size_;
805 static int old_generation_size_;
806
807 static int new_space_growth_limit_;
808 static int scavenge_count_;
809
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000810 static int always_allocate_scope_depth_;
811
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812 static const int kMaxMapSpaceSize = 8*MB;
813
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000814 static NewSpace new_space_;
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000815 static OldSpace* old_pointer_space_;
816 static OldSpace* old_data_space_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817 static OldSpace* code_space_;
818 static MapSpace* map_space_;
819 static LargeObjectSpace* lo_space_;
820 static HeapState gc_state_;
821
822 // Returns the size of object residing in non new spaces.
823 static int PromotedSpaceSize();
824
kasper.lund7276f142008-07-30 08:49:36 +0000825 // Returns the amount of external memory registered since last global gc.
826 static int PromotedExternalMemorySize();
827
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 static int mc_count_; // how many mark-compact collections happened
829 static int gc_count_; // how many gc happened
830
kasper.lund7276f142008-07-30 08:49:36 +0000831#ifdef DEBUG
832 static bool allocation_allowed_;
833
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000834 // If the --gc-interval flag is set to a positive value, this
835 // variable holds the value indicating the number of allocations
836 // remain until the next failure and garbage collection.
837 static int allocation_timeout_;
838
839 // Do we expect to be able to handle allocation failure at this
840 // time?
841 static bool disallow_allocation_failure_;
842#endif // DEBUG
843
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000844 // Limit that triggers a global GC on the next (normally caused) GC. This
845 // is checked when we have already decided to do a GC to help determine
846 // which collector to invoke.
847 static int old_gen_promotion_limit_;
848
849 // Limit that triggers a global GC as soon as is reasonable. This is
850 // checked before expanding a paged space in the old generation and on
851 // every allocation in large object space.
852 static int old_gen_allocation_limit_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000853
kasper.lund7276f142008-07-30 08:49:36 +0000854 // The amount of external memory registered through the API kept alive
855 // by global handles
856 static int amount_of_external_allocated_memory_;
857
858 // Caches the amount of external memory registered at the last global gc.
859 static int amount_of_external_allocated_memory_at_last_global_gc_;
860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861 // Indicates that an allocation has failed in the old generation since the
862 // last GC.
863 static int old_gen_exhausted_;
864
865 // Declare all the roots
866#define ROOT_DECLARATION(type, name) static type* name##_;
867 ROOT_LIST(ROOT_DECLARATION)
868#undef ROOT_DECLARATION
869
870// Utility type maps
871#define DECLARE_STRUCT_MAP(NAME, Name, name) static Map* name##_map_;
872 STRUCT_LIST(DECLARE_STRUCT_MAP)
873#undef DECLARE_STRUCT_MAP
874
875#define SYMBOL_DECLARATION(name, str) static String* name##_;
876 SYMBOL_LIST(SYMBOL_DECLARATION)
877#undef SYMBOL_DECLARATION
878
879 // GC callback function, called before and after mark-compact GC.
880 // Allocations in the callback function are disallowed.
881 static GCCallback global_gc_prologue_callback_;
882 static GCCallback global_gc_epilogue_callback_;
883
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000884 // Callback function used for allocating external symbols.
885 static ExternalSymbolCallback global_external_symbol_callback_;
886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887 // Checks whether a global GC is necessary
888 static GarbageCollector SelectGarbageCollector(AllocationSpace space);
889
890 // Performs garbage collection
891 static void PerformGarbageCollection(AllocationSpace space,
kasper.lund7276f142008-07-30 08:49:36 +0000892 GarbageCollector collector,
893 GCTracer* tracer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000894
895 // Returns either a Smi or a Number object from 'value'. If 'new_object'
896 // is false, it may return a preallocated immutable object.
897 static Object* SmiOrNumberFromDouble(double value,
898 bool new_object,
899 PretenureFlag pretenure = NOT_TENURED);
900
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000901 // Allocate an uninitialized object in map space. The behavior is identical
902 // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't
903 // have to test the allocation space argument and (b) can reduce code size
904 // (since both AllocateRaw and AllocateRawMap are inlined).
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000905 static inline Object* AllocateRawMap(int size_in_bytes);
906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000907 // Initializes a JSObject based on its map.
908 static void InitializeJSObjectFromMap(JSObject* obj,
909 FixedArray* properties,
910 Map* map);
911
912 static bool CreateInitialMaps();
913 static bool CreateInitialObjects();
914 static void CreateFixedStubs();
915 static Object* CreateOddball(Map* map,
916 const char* to_string,
917 Object* to_number);
918
919 // Allocate empty fixed array.
920 static Object* AllocateEmptyFixedArray();
921
922 // Performs a minor collection in new generation.
923 static void Scavenge();
924
925 // Performs a major collection in the whole heap.
kasper.lund7276f142008-07-30 08:49:36 +0000926 static void MarkCompact(GCTracer* tracer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000927
928 // Code to be run before and after mark-compact.
929 static void MarkCompactPrologue();
930 static void MarkCompactEpilogue();
931
932 // Helper function used by CopyObject to copy a source object to an
933 // allocated target object and update the forwarding pointer in the source
934 // object. Returns the target object.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000935 static HeapObject* MigrateObject(HeapObject* source,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000936 HeapObject* target,
937 int size);
938
939 // Helper function that governs the promotion policy from new space to
940 // old. If the object's old address lies below the new space's age
941 // mark or if we've already filled the bottom 1/16th of the to space,
942 // we try to promote this object.
943 static inline bool ShouldBePromoted(Address old_address, int object_size);
944#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
945 // Record the copy of an object in the NewSpace's statistics.
946 static void RecordCopiedObject(HeapObject* obj);
947
948 // Record statistics before and after garbage collection.
949 static void ReportStatisticsBeforeGC();
950 static void ReportStatisticsAfterGC();
951#endif
952
953 // Update an old object's remembered set
954 static int UpdateRSet(HeapObject* obj);
955
956 // Rebuild remembered set in an old space.
957 static void RebuildRSets(PagedSpace* space);
958
959 // Rebuild remembered set in the large object space.
960 static void RebuildRSets(LargeObjectSpace* space);
961
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000962 // Slow part of scavenge object.
963 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
964
965 // Copy memory from src to dst.
966 inline static void CopyBlock(Object** dst, Object** src, int byte_size);
967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000968 static const int kInitialSymbolTableSize = 2048;
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000969 static const int kInitialEvalCacheSize = 64;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970
971 friend class Factory;
972 friend class DisallowAllocationFailure;
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000973 friend class AlwaysAllocateScope;
974};
975
976
977class AlwaysAllocateScope {
978 public:
979 AlwaysAllocateScope() {
980 // We shouldn't hit any nested scopes, because that requires
981 // non-handle code to call handle code. The code still works but
982 // performance will degrade, so we want to catch this situation
983 // in debug mode.
984 ASSERT(Heap::always_allocate_scope_depth_ == 0);
985 Heap::always_allocate_scope_depth_++;
986 }
987
988 ~AlwaysAllocateScope() {
989 Heap::always_allocate_scope_depth_--;
990 ASSERT(Heap::always_allocate_scope_depth_ == 0);
991 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000992};
993
994
995#ifdef DEBUG
996// Visitor class to verify interior pointers that do not have remembered set
997// bits. All heap object pointers have to point into the heap to a location
998// that has a map pointer at its first word. Caveat: Heap::Contains is an
999// approximation because it can return true for objects in a heap space but
1000// above the allocation pointer.
1001class VerifyPointersVisitor: public ObjectVisitor {
1002 public:
1003 void VisitPointers(Object** start, Object** end) {
1004 for (Object** current = start; current < end; current++) {
1005 if ((*current)->IsHeapObject()) {
1006 HeapObject* object = HeapObject::cast(*current);
1007 ASSERT(Heap::Contains(object));
1008 ASSERT(object->map()->IsMap());
1009 }
1010 }
1011 }
1012};
1013
1014
1015// Visitor class to verify interior pointers that have remembered set bits.
1016// As VerifyPointersVisitor but also checks that remembered set bits are
1017// always set for pointers into new space.
1018class VerifyPointersAndRSetVisitor: public ObjectVisitor {
1019 public:
1020 void VisitPointers(Object** start, Object** end) {
1021 for (Object** current = start; current < end; current++) {
1022 if ((*current)->IsHeapObject()) {
1023 HeapObject* object = HeapObject::cast(*current);
1024 ASSERT(Heap::Contains(object));
1025 ASSERT(object->map()->IsMap());
1026 if (Heap::InNewSpace(object)) {
1027 ASSERT(Page::IsRSetSet(reinterpret_cast<Address>(current), 0));
1028 }
1029 }
1030 }
1031 }
1032};
1033#endif
1034
1035
kasper.lund7276f142008-07-30 08:49:36 +00001036// Space iterator for iterating over all spaces of the heap.
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001037// Returns each space in turn, and null when it is done.
1038class AllSpaces BASE_EMBEDDED {
1039 public:
1040 Space* next();
1041 AllSpaces() { counter_ = FIRST_SPACE; }
1042 private:
1043 int counter_;
1044};
1045
1046
1047// Space iterator for iterating over all old spaces of the heap: Old pointer
1048// space, old data space and code space.
1049// Returns each space in turn, and null when it is done.
1050class OldSpaces BASE_EMBEDDED {
1051 public:
1052 OldSpace* next();
1053 OldSpaces() { counter_ = OLD_POINTER_SPACE; }
1054 private:
1055 int counter_;
1056};
1057
1058
1059// Space iterator for iterating over all the paged spaces of the heap:
1060// Map space, old pointer space, old data space and code space.
1061// Returns each space in turn, and null when it is done.
1062class PagedSpaces BASE_EMBEDDED {
1063 public:
1064 PagedSpace* next();
1065 PagedSpaces() { counter_ = OLD_POINTER_SPACE; }
1066 private:
1067 int counter_;
1068};
1069
1070
1071// Space iterator for iterating over all spaces of the heap.
kasper.lund7276f142008-07-30 08:49:36 +00001072// For each space an object iterator is provided. The deallocation of the
1073// returned object iterators is handled by the space iterator.
kasper.lund7276f142008-07-30 08:49:36 +00001074class SpaceIterator : public Malloced {
1075 public:
1076 SpaceIterator();
1077 virtual ~SpaceIterator();
1078
1079 bool has_next();
1080 ObjectIterator* next();
1081
1082 private:
1083 ObjectIterator* CreateIterator();
1084
1085 int current_space_; // from enum AllocationSpace.
1086 ObjectIterator* iterator_; // object iterator for the current space.
1087};
1088
1089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090// A HeapIterator provides iteration over the whole heap It aggregates a the
1091// specific iterators for the different spaces as these can only iterate over
1092// one space only.
1093
1094class HeapIterator BASE_EMBEDDED {
1095 public:
1096 explicit HeapIterator();
1097 virtual ~HeapIterator();
1098
1099 bool has_next();
1100 HeapObject* next();
1101 void reset();
1102
1103 private:
1104 // Perform the initialization.
1105 void Init();
1106
1107 // Perform all necessary shutdown (destruction) work.
1108 void Shutdown();
1109
1110 // Space iterator for iterating all the spaces.
1111 SpaceIterator* space_iterator_;
1112 // Object iterator for the space currently being iterated.
1113 ObjectIterator* object_iterator_;
1114};
1115
1116
1117// ----------------------------------------------------------------------------
1118// Marking stack for tracing live objects.
1119
1120class MarkingStack {
1121 public:
1122 void Initialize(Address low, Address high) {
1123 top_ = low_ = reinterpret_cast<HeapObject**>(low);
1124 high_ = reinterpret_cast<HeapObject**>(high);
1125 overflowed_ = false;
1126 }
1127
1128 bool is_full() { return top_ >= high_; }
1129
1130 bool is_empty() { return top_ <= low_; }
1131
1132 bool overflowed() { return overflowed_; }
1133
1134 void clear_overflowed() { overflowed_ = false; }
1135
mads.s.ager31e71382008-08-13 09:32:07 +00001136 // Push the (marked) object on the marking stack if there is room,
1137 // otherwise mark the object as overflowed and wait for a rescan of the
1138 // heap.
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001139 void Push(HeapObject* object) {
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001140 CHECK(object->IsHeapObject());
mads.s.ager31e71382008-08-13 09:32:07 +00001141 if (is_full()) {
1142 object->SetOverflow();
1143 overflowed_ = true;
1144 } else {
1145 *(top_++) = object;
1146 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001147 }
1148
1149 HeapObject* Pop() {
1150 ASSERT(!is_empty());
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001151 HeapObject* object = *(--top_);
1152 CHECK(object->IsHeapObject());
1153 return object;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001154 }
1155
1156 private:
1157 HeapObject** low_;
1158 HeapObject** top_;
1159 HeapObject** high_;
1160 bool overflowed_;
1161};
1162
1163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164// A helper class to document/test C++ scopes where we do not
1165// expect a GC. Usage:
1166//
1167// /* Allocation not allowed: we cannot handle a GC in this scope. */
1168// { AssertNoAllocation nogc;
1169// ...
1170// }
1171
1172#ifdef DEBUG
1173
1174class DisallowAllocationFailure {
1175 public:
1176 DisallowAllocationFailure() {
1177 old_state_ = Heap::disallow_allocation_failure_;
1178 Heap::disallow_allocation_failure_ = true;
1179 }
1180 ~DisallowAllocationFailure() {
1181 Heap::disallow_allocation_failure_ = old_state_;
1182 }
1183 private:
1184 bool old_state_;
1185};
1186
1187class AssertNoAllocation {
1188 public:
1189 AssertNoAllocation() {
1190 old_state_ = Heap::allow_allocation(false);
1191 }
1192
1193 ~AssertNoAllocation() {
1194 Heap::allow_allocation(old_state_);
1195 }
1196
1197 private:
1198 bool old_state_;
1199};
1200
1201#else // ndef DEBUG
1202
1203class AssertNoAllocation {
1204 public:
1205 AssertNoAllocation() { }
1206 ~AssertNoAllocation() { }
1207};
1208
1209#endif
1210
1211#ifdef ENABLE_LOGGING_AND_PROFILING
1212// The HeapProfiler writes data to the log files, which can be postprocessed
1213// to generate .hp files for use by the GHC/Valgrind tool hp2ps.
1214class HeapProfiler {
1215 public:
1216 // Write a single heap sample to the log file.
1217 static void WriteSample();
1218
1219 private:
1220 // Update the array info with stats from obj.
1221 static void CollectStats(HeapObject* obj, HistogramInfo* info);
1222};
1223#endif
1224
kasper.lund7276f142008-07-30 08:49:36 +00001225// GCTracer collects and prints ONE line after each garbage collector
1226// invocation IFF --trace_gc is used.
1227
1228class GCTracer BASE_EMBEDDED {
1229 public:
1230 GCTracer();
1231
1232 ~GCTracer();
1233
1234 // Sets the collector.
1235 void set_collector(GarbageCollector collector) { collector_ = collector; }
1236
1237 // Sets the GC count.
1238 void set_gc_count(int count) { gc_count_ = count; }
1239
1240 // Sets the full GC count.
1241 void set_full_gc_count(int count) { full_gc_count_ = count; }
1242
1243 // Sets the flag that this is a compacting full GC.
1244 void set_is_compacting() { is_compacting_ = true; }
1245
1246 // Increment and decrement the count of marked objects.
1247 void increment_marked_count() { ++marked_count_; }
1248 void decrement_marked_count() { --marked_count_; }
1249
1250 int marked_count() { return marked_count_; }
1251
1252 private:
1253 // Returns a string matching the collector.
1254 const char* CollectorString();
1255
1256 // Returns size of object in heap (in MB).
1257 double SizeOfHeapObjects() {
1258 return (static_cast<double>(Heap::SizeOfObjects())) / MB;
1259 }
1260
1261 double start_time_; // Timestamp set in the constructor.
1262 double start_size_; // Size of objects in heap set in constructor.
1263 GarbageCollector collector_; // Type of collector.
1264
1265 // A count (including this one, eg, the first collection is 1) of the
1266 // number of garbage collections.
1267 int gc_count_;
1268
1269 // A count (including this one) of the number of full garbage collections.
1270 int full_gc_count_;
1271
1272 // True if the current GC is a compacting full collection, false
1273 // otherwise.
1274 bool is_compacting_;
1275
1276 // True if the *previous* full GC cwas a compacting collection (will be
1277 // false if there has not been a previous full GC).
1278 bool previous_has_compacted_;
1279
1280 // On a full GC, a count of the number of marked objects. Incremented
1281 // when an object is marked and decremented when an object's mark bit is
1282 // cleared. Will be zero on a scavenge collection.
1283 int marked_count_;
1284
1285 // The count from the end of the previous full GC. Will be zero if there
1286 // was no previous full GC.
1287 int previous_marked_count_;
1288};
1289
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001290} } // namespace v8::internal
1291
1292#endif // V8_HEAP_H_