blob: b3a4205b3f6bc8b3837f0f38cbcd1bf874131a7b [file] [log] [blame]
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001// Copyright 2012 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
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000031#include <cmath>
ager@chromium.org18ad94b2009-09-02 08:22:29 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
rossberg@chromium.org79e79022013-06-03 15:43:46 +000034#include "assert-scope.h"
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000035#include "globals.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000036#include "incremental-marking.h"
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000037#include "list.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000038#include "mark-compact.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000039#include "objects-visiting.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000040#include "spaces.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000041#include "splay-tree-inl.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000042#include "store-buffer.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000043#include "v8-counters.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000044#include "v8globals.h"
ager@chromium.org18ad94b2009-09-02 08:22:29 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046namespace v8 {
47namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
49// Defines all the roots in Heap.
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000050#define STRONG_ROOT_LIST(V) \
ager@chromium.org3811b432009-10-28 14:53:37 +000051 V(Map, byte_array_map, ByteArrayMap) \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000052 V(Map, free_space_map, FreeSpaceMap) \
ager@chromium.org3811b432009-10-28 14:53:37 +000053 V(Map, one_pointer_filler_map, OnePointerFillerMap) \
54 V(Map, two_pointer_filler_map, TwoPointerFillerMap) \
55 /* Cluster the most popular ones in a few cache lines here at the top. */ \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000056 V(Smi, store_buffer_top, StoreBufferTop) \
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000057 V(Oddball, undefined_value, UndefinedValue) \
58 V(Oddball, the_hole_value, TheHoleValue) \
59 V(Oddball, null_value, NullValue) \
60 V(Oddball, true_value, TrueValue) \
61 V(Oddball, false_value, FalseValue) \
danno@chromium.org1fd77d52013-06-07 16:01:45 +000062 V(Oddball, uninitialized_value, UninitializedValue) \
danno@chromium.org41728482013-06-12 22:31:22 +000063 V(Map, cell_map, CellMap) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000064 V(Map, global_property_cell_map, GlobalPropertyCellMap) \
65 V(Map, shared_function_info_map, SharedFunctionInfoMap) \
66 V(Map, meta_map, MetaMap) \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +000067 V(Map, heap_number_map, HeapNumberMap) \
yangguo@chromium.org46839fb2012-08-28 09:06:19 +000068 V(Map, native_context_map, NativeContextMap) \
ager@chromium.org18ad94b2009-09-02 08:22:29 +000069 V(Map, fixed_array_map, FixedArrayMap) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070 V(Map, code_map, CodeMap) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000071 V(Map, scope_info_map, ScopeInfoMap) \
ricow@chromium.org0b9f8502010-08-18 07:45:01 +000072 V(Map, fixed_cow_array_map, FixedCOWArrayMap) \
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +000073 V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
ager@chromium.org18ad94b2009-09-02 08:22:29 +000074 V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel) \
ager@chromium.org18ad94b2009-09-02 08:22:29 +000075 V(Map, hash_table_map, HashTableMap) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000076 V(FixedArray, empty_fixed_array, EmptyFixedArray) \
77 V(ByteArray, empty_byte_array, EmptyByteArray) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000078 V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000079 V(Smi, stack_limit, StackLimit) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000080 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. */ \
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000084 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) \
jkummerow@chromium.org486075a2011-09-07 12:44:28 +000089 V(FixedArray, string_split_cache, StringSplitCache) \
jkummerow@chromium.org78502a92012-09-06 13:50:42 +000090 V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000091 V(Object, termination_exception, TerminationException) \
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +000092 V(Smi, hash_seed, HashSeed) \
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +000093 V(Map, symbol_map, SymbolMap) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +000094 V(Map, string_map, StringMap) \
95 V(Map, ascii_string_map, AsciiStringMap) \
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000096 V(Map, cons_string_map, ConsStringMap) \
97 V(Map, cons_ascii_string_map, ConsAsciiStringMap) \
ricow@chromium.org4668a2c2011-08-29 10:41:00 +000098 V(Map, sliced_string_map, SlicedStringMap) \
99 V(Map, sliced_ascii_string_map, SlicedAsciiStringMap) \
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000100 V(Map, external_string_map, ExternalStringMap) \
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000101 V(Map, \
102 external_string_with_one_byte_data_map, \
103 ExternalStringWithOneByteDataMap) \
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000104 V(Map, external_ascii_string_map, ExternalAsciiStringMap) \
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000105 V(Map, short_external_string_map, ShortExternalStringMap) \
106 V(Map, \
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000107 short_external_string_with_one_byte_data_map, \
108 ShortExternalStringWithOneByteDataMap) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000109 V(Map, internalized_string_map, InternalizedStringMap) \
110 V(Map, ascii_internalized_string_map, AsciiInternalizedStringMap) \
111 V(Map, cons_internalized_string_map, ConsInternalizedStringMap) \
112 V(Map, cons_ascii_internalized_string_map, ConsAsciiInternalizedStringMap) \
113 V(Map, \
114 external_internalized_string_map, \
115 ExternalInternalizedStringMap) \
116 V(Map, \
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000117 external_internalized_string_with_one_byte_data_map, \
118 ExternalInternalizedStringWithOneByteDataMap) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000119 V(Map, \
120 external_ascii_internalized_string_map, \
121 ExternalAsciiInternalizedStringMap) \
122 V(Map, \
123 short_external_internalized_string_map, \
124 ShortExternalInternalizedStringMap) \
125 V(Map, \
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000126 short_external_internalized_string_with_one_byte_data_map, \
127 ShortExternalInternalizedStringWithOneByteDataMap) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000128 V(Map, \
129 short_external_ascii_internalized_string_map, \
130 ShortExternalAsciiInternalizedStringMap) \
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000131 V(Map, short_external_ascii_string_map, ShortExternalAsciiStringMap) \
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000132 V(Map, undetectable_string_map, UndetectableStringMap) \
133 V(Map, undetectable_ascii_string_map, UndetectableAsciiStringMap) \
ager@chromium.org3811b432009-10-28 14:53:37 +0000134 V(Map, external_byte_array_map, ExternalByteArrayMap) \
135 V(Map, external_unsigned_byte_array_map, ExternalUnsignedByteArrayMap) \
136 V(Map, external_short_array_map, ExternalShortArrayMap) \
137 V(Map, external_unsigned_short_array_map, ExternalUnsignedShortArrayMap) \
138 V(Map, external_int_array_map, ExternalIntArrayMap) \
139 V(Map, external_unsigned_int_array_map, ExternalUnsignedIntArrayMap) \
140 V(Map, external_float_array_map, ExternalFloatArrayMap) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000141 V(Map, external_double_array_map, ExternalDoubleArrayMap) \
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000142 V(Map, external_pixel_array_map, ExternalPixelArrayMap) \
143 V(ExternalArray, empty_external_byte_array, \
144 EmptyExternalByteArray) \
145 V(ExternalArray, empty_external_unsigned_byte_array, \
146 EmptyExternalUnsignedByteArray) \
147 V(ExternalArray, empty_external_short_array, EmptyExternalShortArray) \
148 V(ExternalArray, empty_external_unsigned_short_array, \
149 EmptyExternalUnsignedShortArray) \
150 V(ExternalArray, empty_external_int_array, EmptyExternalIntArray) \
151 V(ExternalArray, empty_external_unsigned_int_array, \
152 EmptyExternalUnsignedIntArray) \
153 V(ExternalArray, empty_external_float_array, EmptyExternalFloatArray) \
154 V(ExternalArray, empty_external_double_array, EmptyExternalDoubleArray) \
155 V(ExternalArray, empty_external_pixel_array, \
156 EmptyExternalPixelArray) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000157 V(Map, non_strict_arguments_elements_map, NonStrictArgumentsElementsMap) \
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000158 V(Map, function_context_map, FunctionContextMap) \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000159 V(Map, catch_context_map, CatchContextMap) \
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000160 V(Map, with_context_map, WithContextMap) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000161 V(Map, block_context_map, BlockContextMap) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000162 V(Map, module_context_map, ModuleContextMap) \
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000163 V(Map, global_context_map, GlobalContextMap) \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000164 V(Map, oddball_map, OddballMap) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000165 V(Map, message_object_map, JSMessageObjectMap) \
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000166 V(Map, foreign_map, ForeignMap) \
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000167 V(HeapNumber, nan_value, NanValue) \
168 V(HeapNumber, infinity_value, InfinityValue) \
169 V(HeapNumber, minus_zero_value, MinusZeroValue) \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000170 V(Map, neander_map, NeanderMap) \
171 V(JSObject, message_listeners, MessageListeners) \
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000172 V(UnseededNumberDictionary, code_stubs, CodeStubs) \
173 V(UnseededNumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000174 V(PolymorphicCodeCache, polymorphic_code_cache, PolymorphicCodeCache) \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000175 V(Code, js_entry_code, JsEntryCode) \
176 V(Code, js_construct_entry_code, JsConstructEntryCode) \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000177 V(FixedArray, natives_source_cache, NativesSourceCache) \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000178 V(Smi, last_script_id, LastScriptId) \
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000179 V(Script, empty_script, EmptyScript) \
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000180 V(Smi, real_stack_limit, RealStackLimit) \
ulan@chromium.org750145a2013-03-07 15:14:13 +0000181 V(NameDictionary, intrinsic_function_names, IntrinsicFunctionNames) \
ulan@chromium.org967e2702012-02-28 09:49:15 +0000182 V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000183 V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +0000184 V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000185 V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) \
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000186 V(JSObject, observation_state, ObservationState) \
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000187 V(Map, external_map, ExternalMap) \
188 V(Symbol, frozen_symbol, FrozenSymbol) \
189 V(SeededNumberDictionary, empty_slow_element_dictionary, \
190 EmptySlowElementDictionary)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192#define ROOT_LIST(V) \
193 STRONG_ROOT_LIST(V) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000194 V(StringTable, string_table, StringTable)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000195
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000196#define INTERNALIZED_STRING_LIST(V) \
197 V(Array_string, "Array") \
198 V(Object_string, "Object") \
199 V(proto_string, "__proto__") \
200 V(StringImpl_string, "StringImpl") \
201 V(arguments_string, "arguments") \
202 V(Arguments_string, "Arguments") \
203 V(call_string, "call") \
204 V(apply_string, "apply") \
205 V(caller_string, "caller") \
206 V(boolean_string, "boolean") \
207 V(Boolean_string, "Boolean") \
208 V(callee_string, "callee") \
209 V(constructor_string, "constructor") \
210 V(code_string, ".code") \
211 V(result_string, ".result") \
212 V(dot_for_string, ".for.") \
213 V(catch_var_string, ".catch-var") \
214 V(empty_string, "") \
215 V(eval_string, "eval") \
216 V(function_string, "function") \
217 V(length_string, "length") \
218 V(module_string, "module") \
219 V(name_string, "name") \
220 V(native_string, "native") \
221 V(null_string, "null") \
222 V(number_string, "number") \
223 V(Number_string, "Number") \
224 V(nan_string, "NaN") \
225 V(RegExp_string, "RegExp") \
226 V(source_string, "source") \
227 V(global_string, "global") \
228 V(ignore_case_string, "ignoreCase") \
229 V(multiline_string, "multiline") \
230 V(input_string, "input") \
231 V(index_string, "index") \
232 V(last_index_string, "lastIndex") \
233 V(object_string, "object") \
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000234 V(payload_string, "payload") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000235 V(prototype_string, "prototype") \
236 V(string_string, "string") \
237 V(String_string, "String") \
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000238 V(unknown_field_string, "unknownField") \
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000239 V(symbol_string, "symbol") \
240 V(Symbol_string, "Symbol") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000241 V(Date_string, "Date") \
242 V(this_string, "this") \
243 V(to_string_string, "toString") \
244 V(char_at_string, "CharAt") \
245 V(undefined_string, "undefined") \
246 V(value_of_string, "valueOf") \
247 V(stack_string, "stack") \
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000248 V(toJSON_string, "toJSON") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000249 V(InitializeVarGlobal_string, "InitializeVarGlobal") \
250 V(InitializeConstGlobal_string, "InitializeConstGlobal") \
251 V(KeyedLoadElementMonomorphic_string, \
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000252 "KeyedLoadElementMonomorphic") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000253 V(KeyedStoreElementMonomorphic_string, \
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000254 "KeyedStoreElementMonomorphic") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000255 V(stack_overflow_string, "kStackOverflowBoilerplate") \
256 V(illegal_access_string, "illegal access") \
257 V(out_of_memory_string, "out-of-memory") \
258 V(illegal_execution_state_string, "illegal execution state") \
259 V(get_string, "get") \
260 V(set_string, "set") \
261 V(map_field_string, "%map") \
262 V(elements_field_string, "%elements") \
263 V(length_field_string, "%length") \
264 V(function_class_string, "Function") \
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000265 V(properties_field_symbol, "%properties") \
266 V(payload_field_symbol, "%payload") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000267 V(illegal_argument_string, "illegal argument") \
268 V(MakeReferenceError_string, "MakeReferenceError") \
269 V(MakeSyntaxError_string, "MakeSyntaxError") \
270 V(MakeTypeError_string, "MakeTypeError") \
271 V(invalid_lhs_in_assignment_string, "invalid_lhs_in_assignment") \
272 V(invalid_lhs_in_for_in_string, "invalid_lhs_in_for_in") \
273 V(invalid_lhs_in_postfix_op_string, "invalid_lhs_in_postfix_op") \
274 V(invalid_lhs_in_prefix_op_string, "invalid_lhs_in_prefix_op") \
275 V(illegal_return_string, "illegal_return") \
276 V(illegal_break_string, "illegal_break") \
277 V(illegal_continue_string, "illegal_continue") \
278 V(unknown_label_string, "unknown_label") \
279 V(redeclaration_string, "redeclaration") \
280 V(failure_string, "<failure>") \
281 V(space_string, " ") \
282 V(exec_string, "exec") \
283 V(zero_string, "0") \
284 V(global_eval_string, "GlobalEval") \
285 V(identity_hash_string, "v8::IdentityHash") \
286 V(closure_string, "(closure)") \
287 V(use_strict_string, "use strict") \
288 V(dot_string, ".") \
289 V(anonymous_function_string, "(anonymous function)") \
290 V(compare_ic_string, "==") \
291 V(strict_compare_ic_string, "===") \
292 V(infinity_string, "Infinity") \
293 V(minus_infinity_string, "-Infinity") \
294 V(hidden_stack_trace_string, "v8::hidden_stack_trace") \
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000295 V(query_colon_string, "(?:)") \
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000296 V(Generator_string, "Generator") \
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000297 V(throw_string, "throw") \
298 V(done_string, "done") \
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000299 V(value_string, "value") \
300 V(next_string, "next")
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000301
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000302// Forward declarations.
kasper.lund7276f142008-07-30 08:49:36 +0000303class GCTracer;
ager@chromium.org60121232009-12-03 11:25:37 +0000304class HeapStats;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000305class Isolate;
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000306class WeakObjectRetainer;
kasper.lund7276f142008-07-30 08:49:36 +0000307
308
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000309typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap,
310 Object** pointer);
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000311
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000312class StoreBufferRebuilder {
313 public:
314 explicit StoreBufferRebuilder(StoreBuffer* store_buffer)
315 : store_buffer_(store_buffer) {
316 }
317
318 void Callback(MemoryChunk* page, StoreBufferEvent event);
319
320 private:
321 StoreBuffer* store_buffer_;
322
323 // We record in this variable how full the store buffer was when we started
324 // iterating over the current page, finding pointers to new space. If the
325 // store buffer overflows again we can exempt the page from the store buffer
326 // by rewinding to this point instead of having to search the store buffer.
327 Object*** start_of_current_page_;
328 // The current page we are scanning in the store buffer iterator.
329 MemoryChunk* current_page_;
330};
331
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000332
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000333
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000334// A queue of objects promoted during scavenge. Each object is accompanied
335// by it's size to avoid dereferencing a map pointer for scanning.
336class PromotionQueue {
337 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +0000338 explicit PromotionQueue(Heap* heap)
339 : front_(NULL),
340 rear_(NULL),
341 limit_(NULL),
342 emergency_stack_(0),
343 heap_(heap) { }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000344
danno@chromium.orgc612e022011-11-10 11:38:15 +0000345 void Initialize();
346
347 void Destroy() {
348 ASSERT(is_empty());
349 delete emergency_stack_;
350 emergency_stack_ = NULL;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000351 }
352
danno@chromium.orgc612e022011-11-10 11:38:15 +0000353 inline void ActivateGuardIfOnTheSamePage();
354
355 Page* GetHeadPage() {
356 return Page::FromAllocationTop(reinterpret_cast<Address>(rear_));
357 }
358
359 void SetNewLimit(Address limit) {
360 if (!guard_) {
361 return;
362 }
363
364 ASSERT(GetHeadPage() == Page::FromAllocationTop(limit));
365 limit_ = reinterpret_cast<intptr_t*>(limit);
366
367 if (limit_ <= rear_) {
368 return;
369 }
370
371 RelocateQueueHead();
372 }
373
374 bool is_empty() {
375 return (front_ == rear_) &&
376 (emergency_stack_ == NULL || emergency_stack_->length() == 0);
377 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000378
379 inline void insert(HeapObject* target, int size);
380
381 void remove(HeapObject** target, int* size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000382 ASSERT(!is_empty());
danno@chromium.orgc612e022011-11-10 11:38:15 +0000383 if (front_ == rear_) {
384 Entry e = emergency_stack_->RemoveLast();
385 *target = e.obj_;
386 *size = e.size_;
387 return;
388 }
389
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000390 if (NewSpacePage::IsAtStart(reinterpret_cast<Address>(front_))) {
391 NewSpacePage* front_page =
392 NewSpacePage::FromAddress(reinterpret_cast<Address>(front_));
393 ASSERT(!front_page->prev_page()->is_anchor());
394 front_ =
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000395 reinterpret_cast<intptr_t*>(front_page->prev_page()->area_end());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000396 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000397 *target = reinterpret_cast<HeapObject*>(*(--front_));
398 *size = static_cast<int>(*(--front_));
399 // Assert no underflow.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000400 SemiSpace::AssertValidRange(reinterpret_cast<Address>(rear_),
401 reinterpret_cast<Address>(front_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000402 }
403
404 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000405 // The front of the queue is higher in the memory page chain than the rear.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000406 intptr_t* front_;
407 intptr_t* rear_;
danno@chromium.orgc612e022011-11-10 11:38:15 +0000408 intptr_t* limit_;
409
410 bool guard_;
411
412 static const int kEntrySizeInWords = 2;
413
414 struct Entry {
415 Entry(HeapObject* obj, int size) : obj_(obj), size_(size) { }
416
417 HeapObject* obj_;
418 int size_;
419 };
420 List<Entry>* emergency_stack_;
421
422 Heap* heap_;
423
424 void RelocateQueueHead();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000425
426 DISALLOW_COPY_AND_ASSIGN(PromotionQueue);
427};
428
429
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000430typedef void (*ScavengingCallback)(Map* map,
431 HeapObject** slot,
432 HeapObject* object);
433
434
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000435// External strings table is a place where all external strings are
436// registered. We need to keep track of such strings to properly
437// finalize them.
438class ExternalStringTable {
439 public:
440 // Registers an external string.
441 inline void AddString(String* string);
442
443 inline void Iterate(ObjectVisitor* v);
444
445 // Restores internal invariant and gets rid of collected strings.
446 // Must be called after each Iterate() that modified the strings.
447 void CleanUp();
448
449 // Destroys all allocated memory.
450 void TearDown();
451
452 private:
453 ExternalStringTable() { }
454
455 friend class Heap;
456
457 inline void Verify();
458
459 inline void AddOldString(String* string);
460
461 // Notifies the table that only a prefix of the new list is valid.
462 inline void ShrinkNewStrings(int position);
463
464 // To speed up scavenge collections new space string are kept
465 // separate from old space strings.
466 List<Object*> new_space_strings_;
467 List<Object*> old_space_strings_;
468
469 Heap* heap_;
470
471 DISALLOW_COPY_AND_ASSIGN(ExternalStringTable);
472};
473
474
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000475// The stack property of an error object is implemented as a getter that
476// formats the attached raw stack trace into a string. This raw stack trace
477// keeps code and function objects alive until the getter is called the first
478// time. To release those objects, we call the getter after each GC for
479// newly tenured error objects that are kept in a list.
480class ErrorObjectList {
481 public:
482 inline void Add(JSObject* object);
483
484 inline void Iterate(ObjectVisitor* v);
485
486 void TearDown();
487
488 void RemoveUnmarked(Heap* heap);
489
490 void DeferredFormatStackTrace(Isolate* isolate);
491
492 void UpdateReferences();
493
494 void UpdateReferencesInNewSpace(Heap* heap);
495
496 private:
497 static const int kBudgetPerGC = 16;
498
499 ErrorObjectList() : nested_(false) { }
500
501 friend class Heap;
502
503 List<Object*> list_;
504 bool nested_;
505
506 DISALLOW_COPY_AND_ASSIGN(ErrorObjectList);
507};
508
509
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000510enum ArrayStorageAllocationMode {
511 DONT_INITIALIZE_ARRAY_ELEMENTS,
512 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE
513};
514
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000515class Heap {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516 public:
517 // Configure heap size before setup. Return false if the heap has been
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000518 // set up already.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000519 bool ConfigureHeap(int max_semispace_size,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000520 intptr_t max_old_gen_size,
521 intptr_t max_executable_size);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000522 bool ConfigureHeapDefault();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000523
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000524 // Prepares the heap, setting up memory areas that are needed in the isolate
525 // without actually creating any objects.
526 bool SetUp();
527
528 // Bootstraps the object heap with the core set of objects required to run.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000529 // Returns whether it succeeded.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000530 bool CreateHeapObjects();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000531
532 // Destroys all memory allocated by the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000533 void TearDown();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000535 // Set the stack limit in the roots_ array. Some architectures generate
536 // code that looks here, because it is faster than loading from the static
537 // jslimit_/real_jslimit_ variable in the StackGuard.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000538 void SetStackLimits();
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000539
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000540 // Returns whether SetUp has been called.
541 bool HasBeenSetUp();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542
ager@chromium.org3811b432009-10-28 14:53:37 +0000543 // Returns the maximum amount of memory reserved for the heap. For
544 // the young generation, we reserve 4 times the amount needed for a
545 // semi space. The young generation consists of two semi spaces and
546 // we reserve twice the amount needed for those in order to ensure
547 // that new space can be aligned to its size.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000548 intptr_t MaxReserved() {
ager@chromium.org3811b432009-10-28 14:53:37 +0000549 return 4 * reserved_semispace_size_ + max_old_generation_size_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000551 int MaxSemiSpaceSize() { return max_semispace_size_; }
552 int ReservedSemiSpaceSize() { return reserved_semispace_size_; }
553 int InitialSemiSpaceSize() { return initial_semispace_size_; }
554 intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
555 intptr_t MaxExecutableSize() { return max_executable_size_; }
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000556 int MaxRegularSpaceAllocationSize() { return InitialSemiSpaceSize() * 3/4; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557
558 // Returns the capacity of the heap in bytes w/o growing. Heap grows when
559 // more spaces are needed until it reaches the limit.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000560 intptr_t Capacity();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000561
ager@chromium.org3811b432009-10-28 14:53:37 +0000562 // Returns the amount of memory currently committed for the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000563 intptr_t CommittedMemory();
ager@chromium.org3811b432009-10-28 14:53:37 +0000564
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000565 // Returns the amount of executable memory currently committed for the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000566 intptr_t CommittedMemoryExecutable();
ager@chromium.org01fe7df2010-11-10 11:59:11 +0000567
danno@chromium.org72204d52012-10-31 10:02:10 +0000568 // Returns the amount of phyical memory currently committed for the heap.
569 size_t CommittedPhysicalMemory();
570
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571 // Returns the available bytes in space w/o growing.
572 // Heap doesn't guarantee that it can allocate an object that requires
573 // all available bytes. Check MaxHeapObjectSize() instead.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000574 intptr_t Available();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576 // Returns of size of all objects residing in the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000577 intptr_t SizeOfObjects();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578
579 // Return the starting address and a mask for the new space. And-masking an
580 // address with the mask will result in the start address of the new space
581 // for all addresses in either semispace.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000582 Address NewSpaceStart() { return new_space_.start(); }
583 uintptr_t NewSpaceMask() { return new_space_.mask(); }
584 Address NewSpaceTop() { return new_space_.top(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000585
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000586 NewSpace* new_space() { return &new_space_; }
587 OldSpace* old_pointer_space() { return old_pointer_space_; }
588 OldSpace* old_data_space() { return old_data_space_; }
589 OldSpace* code_space() { return code_space_; }
590 MapSpace* map_space() { return map_space_; }
591 CellSpace* cell_space() { return cell_space_; }
danno@chromium.org41728482013-06-12 22:31:22 +0000592 PropertyCellSpace* property_cell_space() {
593 return property_cell_space_;
594 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000595 LargeObjectSpace* lo_space() { return lo_space_; }
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000596 PagedSpace* paged_space(int idx) {
597 switch (idx) {
598 case OLD_POINTER_SPACE:
599 return old_pointer_space();
600 case OLD_DATA_SPACE:
601 return old_data_space();
602 case MAP_SPACE:
603 return map_space();
604 case CELL_SPACE:
605 return cell_space();
danno@chromium.org41728482013-06-12 22:31:22 +0000606 case PROPERTY_CELL_SPACE:
607 return property_cell_space();
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000608 case CODE_SPACE:
609 return code_space();
610 case NEW_SPACE:
611 case LO_SPACE:
612 UNREACHABLE();
613 }
614 return NULL;
615 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000617 bool always_allocate() { return always_allocate_scope_depth_ != 0; }
618 Address always_allocate_scope_depth_address() {
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000619 return reinterpret_cast<Address>(&always_allocate_scope_depth_);
620 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000621 bool linear_allocation() {
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000622 return linear_allocation_scope_depth_ != 0;
ager@chromium.org3811b432009-10-28 14:53:37 +0000623 }
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000624
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000625 Address* NewSpaceAllocationTopAddress() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000626 return new_space_.allocation_top_address();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000628 Address* NewSpaceAllocationLimitAddress() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000629 return new_space_.allocation_limit_address();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630 }
631
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000632 Address* OldPointerSpaceAllocationTopAddress() {
633 return old_pointer_space_->allocation_top_address();
634 }
635 Address* OldPointerSpaceAllocationLimitAddress() {
636 return old_pointer_space_->allocation_limit_address();
637 }
638
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000639 Address* OldDataSpaceAllocationTopAddress() {
640 return old_data_space_->allocation_top_address();
641 }
642 Address* OldDataSpaceAllocationLimitAddress() {
643 return old_data_space_->allocation_limit_address();
644 }
645
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000646 // Uncommit unused semi space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000647 bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); }
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000648
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649 // Allocates and initializes a new JavaScript object based on a
650 // constructor.
651 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
652 // failed.
653 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000654 MUST_USE_RESULT MaybeObject* AllocateJSObject(
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000655 JSFunction* constructor,
656 PretenureFlag pretenure = NOT_TENURED);
657
658 MUST_USE_RESULT MaybeObject* AllocateJSObjectWithAllocationSite(
659 JSFunction* constructor,
660 Handle<Object> allocation_site_info_payload);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000661
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000662 MUST_USE_RESULT MaybeObject* AllocateJSGeneratorObject(
663 JSFunction* function);
664
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000665 MUST_USE_RESULT MaybeObject* AllocateJSModule(Context* context,
666 ScopeInfo* scope_info);
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000667
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000668 // Allocate a JSArray with no elements
669 MUST_USE_RESULT MaybeObject* AllocateEmptyJSArray(
670 ElementsKind elements_kind,
671 PretenureFlag pretenure = NOT_TENURED) {
672 return AllocateJSArrayAndStorage(elements_kind, 0, 0,
673 DONT_INITIALIZE_ARRAY_ELEMENTS,
674 pretenure);
675 }
676
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000677 inline MUST_USE_RESULT MaybeObject* AllocateEmptyJSArrayWithAllocationSite(
678 ElementsKind elements_kind,
679 Handle<Object> allocation_site_payload);
680
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000681 // Allocate a JSArray with a specified length but elements that are left
682 // uninitialized.
683 MUST_USE_RESULT MaybeObject* AllocateJSArrayAndStorage(
684 ElementsKind elements_kind,
685 int length,
686 int capacity,
687 ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
688 PretenureFlag pretenure = NOT_TENURED);
689
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000690 MUST_USE_RESULT MaybeObject* AllocateJSArrayAndStorageWithAllocationSite(
691 ElementsKind elements_kind,
692 int length,
693 int capacity,
694 Handle<Object> allocation_site_payload,
695 ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS);
696
697 MUST_USE_RESULT MaybeObject* AllocateJSArrayStorage(
698 JSArray* array,
699 int length,
700 int capacity,
701 ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS);
702
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000703 // Allocate a JSArray with no elements
704 MUST_USE_RESULT MaybeObject* AllocateJSArrayWithElements(
705 FixedArrayBase* array_base,
706 ElementsKind elements_kind,
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000707 int length,
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000708 PretenureFlag pretenure = NOT_TENURED);
709
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000710 // Allocates and initializes a new global object based on a constructor.
711 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
712 // failed.
713 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000714 MUST_USE_RESULT MaybeObject* AllocateGlobalObject(JSFunction* constructor);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000715
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000716 // Returns a deep copy of the JavaScript object.
717 // Properties and elements are copied too.
718 // Returns failure if allocation failed.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000719 MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source);
720
721 MUST_USE_RESULT MaybeObject* CopyJSObjectWithAllocationSite(JSObject* source);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000722
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000723 // Allocates the function prototype.
724 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
725 // failed.
726 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000727 MUST_USE_RESULT MaybeObject* AllocateFunctionPrototype(JSFunction* function);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000728
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000729 // Allocates a JS ArrayBuffer object.
730 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
731 // failed.
732 // Please note this does not perform a garbage collection.
733 MUST_USE_RESULT MaybeObject* AllocateJSArrayBuffer();
734
lrn@chromium.org34e60782011-09-15 07:25:40 +0000735 // Allocates a Harmony proxy or function proxy.
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000736 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
737 // failed.
738 // Please note this does not perform a garbage collection.
739 MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler,
740 Object* prototype);
741
lrn@chromium.org34e60782011-09-15 07:25:40 +0000742 MUST_USE_RESULT MaybeObject* AllocateJSFunctionProxy(Object* handler,
743 Object* call_trap,
744 Object* construct_trap,
745 Object* prototype);
746
747 // Reinitialize a JSReceiver into an (empty) JS object of respective type and
748 // size, but keeping the original prototype. The receiver must have at least
749 // the size of the new object. The object is reinitialized and behaves as an
750 // object that has been freshly allocated.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000751 // Returns failure if an error occured, otherwise object.
lrn@chromium.org34e60782011-09-15 07:25:40 +0000752 MUST_USE_RESULT MaybeObject* ReinitializeJSReceiver(JSReceiver* object,
753 InstanceType type,
754 int size);
rossberg@chromium.org717967f2011-07-20 13:44:42 +0000755
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000756 // Reinitialize an JSGlobalProxy based on a constructor. The object
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757 // must have the same size as objects allocated using the
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000758 // constructor. The object is reinitialized and behaves as an
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000759 // object that has been freshly allocated using the constructor.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000760 MUST_USE_RESULT MaybeObject* ReinitializeJSGlobalProxy(
761 JSFunction* constructor, JSGlobalProxy* global);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000762
763 // Allocates and initializes a new JavaScript object based on a map.
764 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
765 // failed.
766 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000767 MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMap(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000768 Map* map, PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000769
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000770 MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMapWithAllocationSite(
771 Map* map, Handle<Object> allocation_site_info_payload);
772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773 // Allocates a heap object based on the map.
774 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
775 // failed.
776 // Please note this function does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000777 MUST_USE_RESULT MaybeObject* Allocate(Map* map, AllocationSpace space);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000778
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000779 MUST_USE_RESULT MaybeObject* AllocateWithAllocationSite(Map* map,
780 AllocationSpace space, Handle<Object> allocation_site_info_payload);
781
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782 // Allocates a JS Map in the heap.
783 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
784 // failed.
785 // Please note this function does not perform a garbage collection.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000786 MUST_USE_RESULT MaybeObject* AllocateMap(
787 InstanceType instance_type,
788 int instance_size,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000789 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790
791 // Allocates a partial map for bootstrapping.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000792 MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
793 int instance_size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794
795 // Allocate a map for the specified function
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000796 MUST_USE_RESULT MaybeObject* AllocateInitialMap(JSFunction* fun);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000797
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000798 // Allocates an empty code cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000799 MUST_USE_RESULT MaybeObject* AllocateCodeCache();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000800
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000801 // Allocates a serialized scope info.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000802 MUST_USE_RESULT MaybeObject* AllocateScopeInfo(int length);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000803
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000804 // Allocates an External object for v8's external API.
805 MUST_USE_RESULT MaybeObject* AllocateExternal(void* value);
806
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000807 // Allocates an empty PolymorphicCodeCache.
808 MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
809
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000810 // Allocates a pre-tenured empty AccessorPair.
811 MUST_USE_RESULT MaybeObject* AllocateAccessorPair();
812
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000813 // Allocates an empty TypeFeedbackInfo.
814 MUST_USE_RESULT MaybeObject* AllocateTypeFeedbackInfo();
815
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000816 // Allocates an AliasedArgumentsEntry.
817 MUST_USE_RESULT MaybeObject* AllocateAliasedArgumentsEntry(int slot);
818
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000819 // Clear the Instanceof cache (used when a prototype changes).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000820 inline void ClearInstanceofCache();
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000821
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000822 // For use during bootup.
823 void RepairFreeListsAfterBoot();
824
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000825 // Allocates and fully initializes a String. There are two String
826 // encodings: ASCII and two byte. One should choose between the three string
827 // allocation functions based on the encoding of the string buffer used to
828 // initialized the string.
829 // - ...FromAscii initializes the string from a buffer that is ASCII
830 // encoded (it does not check that the buffer is ASCII encoded) and the
831 // result will be ASCII encoded.
832 // - ...FromUTF8 initializes the string from a buffer that is UTF-8
833 // encoded. If the characters are all single-byte characters, the
834 // result will be ASCII encoded, otherwise it will converted to two
835 // byte.
836 // - ...FromTwoByte initializes the string from a buffer that is two-byte
837 // encoded. If the characters are all single-byte characters, the
838 // result will be converted to ASCII, otherwise it will be left as
839 // two-byte.
840 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
841 // failed.
842 // Please note this does not perform a garbage collection.
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000843 MUST_USE_RESULT MaybeObject* AllocateStringFromOneByte(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000844 Vector<const uint8_t> str,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000845 PretenureFlag pretenure = NOT_TENURED);
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000846 // TODO(dcarney): remove this function.
847 MUST_USE_RESULT inline MaybeObject* AllocateStringFromOneByte(
848 Vector<const char> str,
849 PretenureFlag pretenure = NOT_TENURED) {
850 return AllocateStringFromOneByte(Vector<const uint8_t>::cast(str),
851 pretenure);
852 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000853 MUST_USE_RESULT inline MaybeObject* AllocateStringFromUtf8(
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000854 Vector<const char> str,
855 PretenureFlag pretenure = NOT_TENURED);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000856 MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000857 Vector<const char> str,
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000858 int non_ascii_start,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000859 PretenureFlag pretenure = NOT_TENURED);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000860 MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861 Vector<const uc16> str,
862 PretenureFlag pretenure = NOT_TENURED);
863
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000864 // Allocates an internalized string in old space based on the character
865 // stream. Returns Failure::RetryAfterGC(requested_bytes, space) if the
866 // allocation failed.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000867 // Please note this function does not perform a garbage collection.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000868 MUST_USE_RESULT inline MaybeObject* AllocateInternalizedStringFromUtf8(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000869 Vector<const char> str,
870 int chars,
871 uint32_t hash_field);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000872
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000873 MUST_USE_RESULT inline MaybeObject* AllocateOneByteInternalizedString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000874 Vector<const uint8_t> str,
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000875 uint32_t hash_field);
876
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000877 MUST_USE_RESULT inline MaybeObject* AllocateTwoByteInternalizedString(
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000878 Vector<const uc16> str,
879 uint32_t hash_field);
880
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000881 template<typename T>
882 static inline bool IsOneByte(T t, int chars);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000883
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000884 template<typename T>
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000885 MUST_USE_RESULT inline MaybeObject* AllocateInternalizedStringImpl(
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000886 T t, int chars, uint32_t hash_field);
887
888 template<bool is_one_byte, typename T>
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000889 MUST_USE_RESULT MaybeObject* AllocateInternalizedStringImpl(
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000890 T t, int chars, uint32_t hash_field);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000891
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892 // Allocates and partially initializes a String. There are two String
893 // encodings: ASCII and two byte. These functions allocate a string of the
894 // given length and set its map and length fields. The characters of the
895 // string are uninitialized.
896 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
897 // failed.
898 // Please note this does not perform a garbage collection.
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000899 MUST_USE_RESULT MaybeObject* AllocateRawOneByteString(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000900 int length,
901 PretenureFlag pretenure = NOT_TENURED);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000902 MUST_USE_RESULT MaybeObject* AllocateRawTwoByteString(
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903 int length,
904 PretenureFlag pretenure = NOT_TENURED);
905
906 // Computes a single character string where the character has code.
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000907 // A cache is used for ASCII codes.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000908 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
909 // failed. Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000910 MUST_USE_RESULT MaybeObject* LookupSingleCharacterStringFromCode(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000911 uint16_t code);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000912
913 // Allocate a byte array of the specified length
914 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
915 // failed.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000916 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000917 MUST_USE_RESULT MaybeObject* AllocateByteArray(int length,
918 PretenureFlag pretenure);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000919
920 // Allocate a non-tenured byte array of the specified length
921 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
922 // failed.
923 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000924 MUST_USE_RESULT MaybeObject* AllocateByteArray(int length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925
ager@chromium.org3811b432009-10-28 14:53:37 +0000926 // Allocates an external array of the specified length and type.
927 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
928 // failed.
929 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000930 MUST_USE_RESULT MaybeObject* AllocateExternalArray(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000931 int length,
932 ExternalArrayType array_type,
933 void* external_pointer,
934 PretenureFlag pretenure);
ager@chromium.org3811b432009-10-28 14:53:37 +0000935
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000936 // Allocate a symbol in old space.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000937 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
938 // failed.
939 // Please note this does not perform a garbage collection.
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000940 MUST_USE_RESULT MaybeObject* AllocateSymbol();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000941
danno@chromium.org41728482013-06-12 22:31:22 +0000942 // Allocate a tenured simple cell.
943 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
944 // failed.
945 // Please note this does not perform a garbage collection.
946 MUST_USE_RESULT MaybeObject* AllocateCell(Object* value);
947
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000948 // Allocate a tenured JS global property cell.
949 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
950 // failed.
951 // Please note this does not perform a garbage collection.
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000952 MUST_USE_RESULT MaybeObject* AllocatePropertyCell(Object* value);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000953
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000954 // Allocate Box.
955 MUST_USE_RESULT MaybeObject* AllocateBox(Object* value,
956 PretenureFlag pretenure);
957
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958 // Allocates a fixed array initialized with undefined values
959 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
960 // failed.
961 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000962 MUST_USE_RESULT MaybeObject* AllocateFixedArray(int length,
963 PretenureFlag pretenure);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000964 // Allocates a fixed array initialized with undefined values
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000965 MUST_USE_RESULT MaybeObject* AllocateFixedArray(int length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000967 // Allocates an uninitialized fixed array. It must be filled by the caller.
968 //
969 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
970 // failed.
971 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000972 MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedArray(int length);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000973
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000974 // Move len elements within a given array from src_index index to dst_index
975 // index.
976 void MoveElements(FixedArray* array, int dst_index, int src_index, int len);
977
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000978 // Make a copy of src and return it. Returns
979 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000980 MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src);
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000981
982 // Make a copy of src, set the map, and return the copy. Returns
983 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000984 MUST_USE_RESULT MaybeObject* CopyFixedArrayWithMap(FixedArray* src, Map* map);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000985
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000986 // Make a copy of src and return it. Returns
987 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
988 MUST_USE_RESULT inline MaybeObject* CopyFixedDoubleArray(
989 FixedDoubleArray* src);
990
991 // Make a copy of src, set the map, and return the copy. Returns
992 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
993 MUST_USE_RESULT MaybeObject* CopyFixedDoubleArrayWithMap(
994 FixedDoubleArray* src, Map* map);
995
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000996 // Allocates a fixed array initialized with the hole values.
997 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
998 // failed.
999 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001000 MUST_USE_RESULT MaybeObject* AllocateFixedArrayWithHoles(
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00001001 int length,
1002 PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001003
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001004 MUST_USE_RESULT MaybeObject* AllocateRawFixedDoubleArray(
1005 int length,
1006 PretenureFlag pretenure);
1007
1008 // Allocates a fixed double array with uninitialized values. Returns
1009 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
1010 // Please note this does not perform a garbage collection.
1011 MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedDoubleArray(
1012 int length,
1013 PretenureFlag pretenure = NOT_TENURED);
1014
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001015 // Allocates a fixed double array with hole values. Returns
1016 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
1017 // Please note this does not perform a garbage collection.
1018 MUST_USE_RESULT MaybeObject* AllocateFixedDoubleArrayWithHoles(
1019 int length,
1020 PretenureFlag pretenure = NOT_TENURED);
1021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001022 // AllocateHashTable is identical to AllocateFixedArray except
1023 // that the resulting object has hash_table_map as map.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001024 MUST_USE_RESULT MaybeObject* AllocateHashTable(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00001025 int length, PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001026
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001027 // Allocate a native (but otherwise uninitialized) context.
1028 MUST_USE_RESULT MaybeObject* AllocateNativeContext();
1029
1030 // Allocate a global context.
1031 MUST_USE_RESULT MaybeObject* AllocateGlobalContext(JSFunction* function,
1032 ScopeInfo* scope_info);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001034 // Allocate a module context.
danno@chromium.org81cac2b2012-07-10 11:28:27 +00001035 MUST_USE_RESULT MaybeObject* AllocateModuleContext(ScopeInfo* scope_info);
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037 // Allocate a function context.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001038 MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00001039 JSFunction* function);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001040
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001041 // Allocate a catch context.
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00001042 MUST_USE_RESULT MaybeObject* AllocateCatchContext(JSFunction* function,
1043 Context* previous,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001044 String* name,
1045 Object* thrown_object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001046 // Allocate a 'with' context.
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00001047 MUST_USE_RESULT MaybeObject* AllocateWithContext(JSFunction* function,
1048 Context* previous,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001049 JSObject* extension);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001050
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001051 // Allocate a block context.
1052 MUST_USE_RESULT MaybeObject* AllocateBlockContext(JSFunction* function,
1053 Context* previous,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001054 ScopeInfo* info);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001055
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056 // Allocates a new utility object in the old generation.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001057 MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001059 // Allocates a function initialized with a shared part.
1060 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1061 // failed.
1062 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001063 MUST_USE_RESULT MaybeObject* AllocateFunction(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00001064 Map* function_map,
1065 SharedFunctionInfo* shared,
1066 Object* prototype,
1067 PretenureFlag pretenure = TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001068
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001069 // Arguments object size.
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001070 static const int kArgumentsObjectSize =
1071 JSObject::kHeaderSize + 2 * kPointerSize;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001072 // Strict mode arguments has no callee so it is smaller.
1073 static const int kArgumentsObjectSizeStrict =
1074 JSObject::kHeaderSize + 1 * kPointerSize;
1075 // Indicies for direct access into argument objects.
1076 static const int kArgumentsLengthIndex = 0;
1077 // callee is only valid in non-strict mode.
1078 static const int kArgumentsCalleeIndex = 1;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001079
1080 // Allocates an arguments object - optionally with an elements array.
1081 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1082 // failed.
1083 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001084 MUST_USE_RESULT MaybeObject* AllocateArgumentsObject(
1085 Object* callee, int length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001087 // Same as NewNumberFromDouble, but may return a preallocated/immutable
1088 // number object (e.g., minus_zero_value_, nan_value_)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001089 MUST_USE_RESULT MaybeObject* NumberFromDouble(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00001090 double value, PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001091
1092 // Allocated a HeapNumber from value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001093 MUST_USE_RESULT MaybeObject* AllocateHeapNumber(
lrn@chromium.org303ada72010-10-27 09:33:13 +00001094 double value,
1095 PretenureFlag pretenure);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001096 // pretenure = NOT_TENURED
1097 MUST_USE_RESULT MaybeObject* AllocateHeapNumber(double value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098
1099 // Converts an int into either a Smi or a HeapNumber object.
1100 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1101 // failed.
1102 // Please note this does not perform a garbage collection.
erikcorry0ad885c2011-11-21 13:51:57 +00001103 MUST_USE_RESULT inline MaybeObject* NumberFromInt32(
1104 int32_t value, PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001105
1106 // Converts an int into either a Smi or a HeapNumber object.
1107 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1108 // failed.
1109 // Please note this does not perform a garbage collection.
erikcorry0ad885c2011-11-21 13:51:57 +00001110 MUST_USE_RESULT inline MaybeObject* NumberFromUint32(
1111 uint32_t value, PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001112
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001113 // Allocates a new foreign object.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1115 // failed.
1116 // Please note this does not perform a garbage collection.
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001117 MUST_USE_RESULT MaybeObject* AllocateForeign(
1118 Address address, PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001119
1120 // Allocates a new SharedFunctionInfo object.
1121 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1122 // failed.
1123 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001124 MUST_USE_RESULT MaybeObject* AllocateSharedFunctionInfo(Object* name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001126 // Allocates a new JSMessageObject object.
1127 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1128 // failed.
1129 // Please note that this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001130 MUST_USE_RESULT MaybeObject* AllocateJSMessageObject(
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001131 String* type,
1132 JSArray* arguments,
1133 int start_position,
1134 int end_position,
1135 Object* script,
1136 Object* stack_trace,
1137 Object* stack_frames);
1138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139 // Allocates a new cons string object.
1140 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1141 // failed.
1142 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001143 MUST_USE_RESULT MaybeObject* AllocateConsString(String* first,
1144 String* second);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001146 // Allocates a new sub string object which is a substring of an underlying
1147 // string buffer stretching from the index start (inclusive) to the index
1148 // end (exclusive).
1149 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1150 // failed.
1151 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001152 MUST_USE_RESULT MaybeObject* AllocateSubString(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00001153 String* buffer,
1154 int start,
1155 int end,
1156 PretenureFlag pretenure = NOT_TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001157
1158 // Allocate a new external string object, which is backed by a string
1159 // resource that resides outside the V8 heap.
1160 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1161 // failed.
1162 // Please note this does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001163 MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001164 const ExternalAsciiString::Resource* resource);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001165 MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001166 const ExternalTwoByteString::Resource* resource);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001167
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00001168 // Finalizes an external string by deleting the associated external
1169 // data and clearing the resource pointer.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001170 inline void FinalizeExternalString(String* string);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00001171
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001172 // Allocates an uninitialized object. The memory is non-executable if the
1173 // hardware and OS allow.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1175 // failed.
1176 // Please note this function does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001177 MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes,
1178 AllocationSpace space,
1179 AllocationSpace retry_space);
kasper.lund7276f142008-07-30 08:49:36 +00001180
ager@chromium.org6f10e412009-02-13 10:11:16 +00001181 // Initialize a filler object to keep the ability to iterate over the heap
1182 // when shortening objects.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001183 void CreateFillerObjectAt(Address addr, int size);
ager@chromium.org6f10e412009-02-13 10:11:16 +00001184
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001185 // Makes a new native code object
1186 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001187 // failed. On success, the pointer to the Code object is stored in the
1188 // self_reference. This allows generated code to reference its own Code
1189 // object by containing this pointer.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190 // Please note this function does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001191 MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc,
1192 Code::Flags flags,
1193 Handle<Object> self_reference,
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00001194 bool immovable = false,
1195 bool crankshafted = false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001196
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001197 MUST_USE_RESULT MaybeObject* CopyCode(Code* code);
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001198
1199 // Copy the code and scope info part of the code object, but insert
1200 // the provided data as the relocation information.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001201 MUST_USE_RESULT MaybeObject* CopyCode(Code* code, Vector<byte> reloc_info);
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001202
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001203 // Finds the internalized copy for string in the string table.
1204 // If not found, a new string is added to the table and returned.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001205 // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
1206 // failed.
1207 // Please note this function does not perform a garbage collection.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001208 MUST_USE_RESULT MaybeObject* InternalizeUtf8String(Vector<const char> str);
1209 MUST_USE_RESULT MaybeObject* InternalizeUtf8String(const char* str) {
1210 return InternalizeUtf8String(CStrVector(str));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211 }
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001212 MUST_USE_RESULT MaybeObject* InternalizeOneByteString(
1213 Vector<const uint8_t> str);
1214 MUST_USE_RESULT MaybeObject* InternalizeTwoByteString(Vector<const uc16> str);
1215 MUST_USE_RESULT MaybeObject* InternalizeString(String* str);
1216 MUST_USE_RESULT MaybeObject* InternalizeOneByteString(
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001217 Handle<SeqOneByteString> string, int from, int length);
danno@chromium.org40cb8782011-05-25 07:58:50 +00001218
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001219 bool InternalizeStringIfExists(String* str, String** result);
1220 bool InternalizeTwoCharsStringIfExists(String* str, String** result);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001221
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001222 // Compute the matching internalized string map for a string if possible.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001223 // NULL is returned if string is in new space or not flattened.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001224 Map* InternalizedStringMapForString(String* str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001225
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001226 // Tries to flatten a string before compare operation.
1227 //
1228 // Returns a failure in case it was decided that flattening was
1229 // necessary and failed. Note, if flattening is not necessary the
1230 // string might stay non-flat even when not a failure is returned.
1231 //
1232 // Please note this function does not perform a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001233 MUST_USE_RESULT inline MaybeObject* PrepareForCompare(String* str);
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001235 // Converts the given boolean condition to JavaScript boolean value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001236 inline Object* ToBoolean(bool condition);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237
1238 // Code that should be run before and after each GC. Includes some
1239 // reporting/verification activities when compiled with DEBUG set.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001240 void GarbageCollectionPrologue();
1241 void GarbageCollectionEpilogue();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001242
1243 // Performs garbage collection operation.
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001244 // Returns whether there is a chance that another major GC could
1245 // collect more garbage.
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001246 bool CollectGarbage(AllocationSpace space,
1247 GarbageCollector collector,
1248 const char* gc_reason,
1249 const char* collector_reason);
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001250
1251 // Performs garbage collection operation.
1252 // Returns whether there is a chance that another major GC could
1253 // collect more garbage.
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001254 inline bool CollectGarbage(AllocationSpace space,
1255 const char* gc_reason = NULL);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001256
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001257 static const int kNoGCFlags = 0;
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001258 static const int kSweepPreciselyMask = 1;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001259 static const int kReduceMemoryFootprintMask = 2;
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001260 static const int kAbortIncrementalMarkingMask = 4;
1261
1262 // Making the heap iterable requires us to sweep precisely and abort any
1263 // incremental marking as well.
1264 static const int kMakeHeapIterableMask =
1265 kSweepPreciselyMask | kAbortIncrementalMarkingMask;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001266
1267 // Performs a full garbage collection. If (flags & kMakeHeapIterableMask) is
1268 // non-zero, then the slower precise sweeper is used, which leaves the heap
1269 // in a state where we can iterate over the heap visiting all objects.
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001270 void CollectAllGarbage(int flags, const char* gc_reason = NULL);
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001271
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001272 // Last hope GC, should try to squeeze as much as possible.
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001273 void CollectAllAvailableGarbage(const char* gc_reason = NULL);
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00001274
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001275 // Check whether the heap is currently iterable.
1276 bool IsHeapIterable();
1277
1278 // Ensure that we have swept all spaces in such a way that we can iterate
1279 // over all objects. May cause a GC.
1280 void EnsureHeapIsIterable();
1281
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001282 // Notify the heap that a context has been disposed.
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001283 int NotifyContextDisposed() {
1284 flush_monomorphic_ics_ = true;
1285 return ++contexts_disposed_;
1286 }
kasperl@chromium.org061ef742009-02-27 12:16:20 +00001287
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001288 // Utility to invoke the scavenger. This is needed in test code to
1289 // ensure correct callback for weak global handles.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001290 void PerformScavenge();
1291
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001292 inline void increment_scan_on_scavenge_pages() {
1293 scan_on_scavenge_pages_++;
1294 if (FLAG_gc_verbose) {
1295 PrintF("Scan-on-scavenge pages: %d\n", scan_on_scavenge_pages_);
1296 }
1297 }
1298
1299 inline void decrement_scan_on_scavenge_pages() {
1300 scan_on_scavenge_pages_--;
1301 if (FLAG_gc_verbose) {
1302 PrintF("Scan-on-scavenge pages: %d\n", scan_on_scavenge_pages_);
1303 }
1304 }
1305
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001306 PromotionQueue* promotion_queue() { return &promotion_queue_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001308#ifdef DEBUG
1309 // Utility used with flag gc-greedy.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001310 void GarbageCollectionGreedyCheck();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001311#endif
1312
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001313 void AddGCPrologueCallback(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001314 GCPrologueCallback callback, GCType gc_type_filter);
1315 void RemoveGCPrologueCallback(GCPrologueCallback callback);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001316
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001317 void AddGCEpilogueCallback(
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001318 GCEpilogueCallback callback, GCType gc_type_filter);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001319 void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001320
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001321 void SetGlobalGCPrologueCallback(GCCallback callback) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001322 ASSERT((callback == NULL) ^ (global_gc_prologue_callback_ == NULL));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001323 global_gc_prologue_callback_ = callback;
1324 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001325 void SetGlobalGCEpilogueCallback(GCCallback callback) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001326 ASSERT((callback == NULL) ^ (global_gc_epilogue_callback_ == NULL));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327 global_gc_epilogue_callback_ = callback;
1328 }
1329
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001330 // Heap root getters. We have versions with and without type::cast() here.
1331 // You can't use type::cast during GC because the assert fails.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001332 // TODO(1490): Try removing the unchecked accessors, now that GC marking does
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001333 // not corrupt the map.
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001334#define ROOT_ACCESSOR(type, name, camel_name) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001335 type* name() { \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001336 return type::cast(roots_[k##camel_name##RootIndex]); \
1337 } \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001338 type* raw_unchecked_##name() { \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001339 return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \
1340 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001341 ROOT_LIST(ROOT_ACCESSOR)
1342#undef ROOT_ACCESSOR
1343
1344// Utility type maps
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001345#define STRUCT_MAP_ACCESSOR(NAME, Name, name) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001346 Map* name##_map() { \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001347 return Map::cast(roots_[k##Name##MapRootIndex]); \
1348 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001349 STRUCT_LIST(STRUCT_MAP_ACCESSOR)
1350#undef STRUCT_MAP_ACCESSOR
1351
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001352#define STRING_ACCESSOR(name, str) String* name() { \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001353 return String::cast(roots_[k##name##RootIndex]); \
1354 }
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001355 INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
1356#undef STRING_ACCESSOR
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001357
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001358 // The hidden_string is special because it is the empty string, but does
ager@chromium.org3b45ab52009-03-19 22:21:34 +00001359 // not match the empty string.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001360 String* hidden_string() { return hidden_string_; }
ager@chromium.org3b45ab52009-03-19 22:21:34 +00001361
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001362 void set_native_contexts_list(Object* object) {
1363 native_contexts_list_ = object;
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001364 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001365 Object* native_contexts_list() { return native_contexts_list_; }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001366
danno@chromium.org1fd77d52013-06-07 16:01:45 +00001367 void set_array_buffers_list(Object* object) {
1368 array_buffers_list_ = object;
1369 }
1370 Object* array_buffers_list() { return array_buffers_list_; }
1371
1372
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00001373 // Number of mark-sweeps.
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00001374 unsigned int ms_count() { return ms_count_; }
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +00001375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376 // Iterates over all roots in the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001377 void IterateRoots(ObjectVisitor* v, VisitMode mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378 // Iterates over all strong roots in the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001379 void IterateStrongRoots(ObjectVisitor* v, VisitMode mode);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001380 // Iterates over all the other roots in the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001381 void IterateWeakRoots(ObjectVisitor* v, VisitMode mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001382
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001383 // Iterate pointers to from semispace of new space found in memory interval
1384 // from start to end.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001385 void IterateAndMarkPointersToFromSpace(Address start,
1386 Address end,
1387 ObjectSlotCallback callback);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001388
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389 // Returns whether the object resides in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001390 inline bool InNewSpace(Object* object);
ulan@chromium.org750145a2013-03-07 15:14:13 +00001391 inline bool InNewSpace(Address address);
1392 inline bool InNewSpacePage(Address address);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001393 inline bool InFromSpace(Object* object);
1394 inline bool InToSpace(Object* object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395
ulan@chromium.org750145a2013-03-07 15:14:13 +00001396 // Returns whether the object resides in old pointer space.
1397 inline bool InOldPointerSpace(Address address);
1398 inline bool InOldPointerSpace(Object* object);
1399
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001400 // Returns whether the object resides in old data space.
1401 inline bool InOldDataSpace(Address address);
1402 inline bool InOldDataSpace(Object* object);
1403
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001404 // Checks whether an address/object in the heap (including auxiliary
1405 // area and unused area).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001406 bool Contains(Address addr);
1407 bool Contains(HeapObject* value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408
1409 // Checks whether an address/object in a space.
ager@chromium.org3811b432009-10-28 14:53:37 +00001410 // Currently used by tests, serialization and heap verification only.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001411 bool InSpace(Address addr, AllocationSpace space);
1412 bool InSpace(HeapObject* value, AllocationSpace space);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413
kasper.lund7276f142008-07-30 08:49:36 +00001414 // Finds out which space an object should get promoted to based on its type.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001415 inline OldSpace* TargetSpace(HeapObject* object);
1416 inline AllocationSpace TargetSpaceId(InstanceType type);
kasper.lund7276f142008-07-30 08:49:36 +00001417
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418 // Sets the stub_cache_ (only used when expanding the dictionary).
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001419 void public_set_code_stubs(UnseededNumberDictionary* value) {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001420 roots_[kCodeStubsRootIndex] = value;
1421 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00001423 // Support for computing object sizes for old objects during GCs. Returns
1424 // a function that is guaranteed to be safe for computing object sizes in
1425 // the current GC phase.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001426 HeapObjectCallback GcSafeSizeOfOldObjectFunction() {
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00001427 return gc_safe_size_of_old_object_;
1428 }
1429
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 // Sets the non_monomorphic_cache_ (only used when expanding the dictionary).
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001431 void public_set_non_monomorphic_cache(UnseededNumberDictionary* value) {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001432 roots_[kNonMonomorphicCacheRootIndex] = value;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001433 }
1434
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001435 void public_set_empty_script(Script* script) {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001436 roots_[kEmptyScriptRootIndex] = script;
1437 }
1438
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001439 void public_set_store_buffer_top(Address* top) {
1440 roots_[kStoreBufferTopRootIndex] = reinterpret_cast<Smi*>(top);
1441 }
1442
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001443 // Generated code can embed this address to get access to the roots.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001444 Object** roots_array_start() { return roots_; }
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001445
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001446 Address* store_buffer_top_address() {
1447 return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
1448 }
1449
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001450 // Get address of native contexts list for serialization support.
1451 Object** native_contexts_list_address() {
1452 return &native_contexts_list_;
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001453 }
1454
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001455#ifdef VERIFY_HEAP
1456 // Verify the heap is in its normal state before or after a GC.
1457 void Verify();
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00001458
1459
1460 bool weak_embedded_maps_verification_enabled() {
1461 return no_weak_embedded_maps_verification_scope_depth_ == 0;
1462 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001463#endif
1464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001465#ifdef DEBUG
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001466 void Print();
1467 void PrintHandles();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001469 void OldPointerSpaceCheckStoreBuffer();
1470 void MapSpaceCheckStoreBuffer();
1471 void LargeObjectSpaceCheckStoreBuffer();
1472
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 // Report heap statistics.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001474 void ReportHeapStatistics(const char* title);
1475 void ReportCodeStatistics(const char* title);
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001476#endif
1477
1478 // Zapping is needed for verify heap, and always done in debug builds.
1479 static inline bool ShouldZapGarbage() {
1480#ifdef DEBUG
1481 return true;
1482#else
1483#ifdef VERIFY_HEAP
1484 return FLAG_verify_heap;
1485#else
1486 return false;
1487#endif
1488#endif
1489 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001490
1491 // Fill in bogus values in from space
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001492 void ZapFromSpace();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001494 // Print short heap statistics.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001495 void PrintShortHeapStatistics();
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001496
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001497 // Makes a new internalized string object
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
1499 // failed.
1500 // Please note this function does not perform a garbage collection.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001501 MUST_USE_RESULT MaybeObject* CreateInternalizedString(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001502 const char* str, int length, int hash);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001503 MUST_USE_RESULT MaybeObject* CreateInternalizedString(String* str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001504
1505 // Write barrier support for address[offset] = o.
ulan@chromium.org2e04b582013-02-21 14:06:02 +00001506 INLINE(void RecordWrite(Address address, int offset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001508 // Write barrier support for address[start : start + len[ = o.
ulan@chromium.org2e04b582013-02-21 14:06:02 +00001509 INLINE(void RecordWrites(Address address, int start, int len));
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001510
kasper.lund7276f142008-07-30 08:49:36 +00001511 // Given an address occupied by a live code object, return that object.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001512 Object* FindCodeObject(Address a);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001514 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001515 inline HeapState gc_state() { return gc_state_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001516
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00001517 inline bool IsInGCPostProcessing() { return gc_post_processing_depth_ > 0; }
1518
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001519#ifdef DEBUG
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520 bool disallow_allocation_failure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 return disallow_allocation_failure_;
1522 }
1523
ulan@chromium.orgea52b5f2012-07-30 13:05:33 +00001524 void TracePathToObjectFrom(Object* target, Object* root);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001525 void TracePathToObject(Object* target);
1526 void TracePathToGlobal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001527#endif
1528
ager@chromium.org32912102009-01-16 10:38:43 +00001529 // Callback function passed to Heap::Iterate etc. Copies an object if
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001530 // necessary, the object might be promoted to an old space. The caller must
1531 // ensure the precondition that the object is (a) a heap object and (b) in
1532 // the heap's from space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001533 static inline void ScavengePointer(HeapObject** p);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001534 static inline void ScavengeObject(HeapObject** p, HeapObject* object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001535
ager@chromium.orgadd848f2009-08-13 12:44:13 +00001536 // Commits from space if it is uncommitted.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001537 void EnsureFromSpaceIsCommitted();
ager@chromium.orgadd848f2009-08-13 12:44:13 +00001538
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001539 // Support for partial snapshots. After calling this we have a linear
1540 // space to write objects in each space.
1541 void ReserveSpace(int *sizes, Address* addresses);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001542
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001543 //
1544 // Support for the API.
1545 //
1546
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001547 bool CreateApiObjects();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548
1549 // Attempt to find the number in a small cache. If we finds it, return
1550 // the string representation of the number. Otherwise return undefined.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001551 Object* GetNumberStringCache(Object* number);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001552
1553 // Update the cache with a new number-string pair.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001554 void SetNumberStringCache(Object* number, String* str);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001555
kasper.lund7276f142008-07-30 08:49:36 +00001556 // Adjusts the amount of registered external memory.
1557 // Returns the adjusted value.
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001558 inline intptr_t AdjustAmountOfExternalAllocatedMemory(
1559 intptr_t change_in_bytes);
kasper.lund7276f142008-07-30 08:49:36 +00001560
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00001561 // Allocate uninitialized fixed array.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001562 MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length);
1563 MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length,
1564 PretenureFlag pretenure);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001565
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001566 // Predicate that governs global pre-tenuring decisions based on observed
1567 // promotion rates of previous collections.
1568 inline bool ShouldGloballyPretenure() {
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001569 return FLAG_pretenuring && new_space_high_promotion_mode_active_;
1570 }
1571
1572 // This is only needed for testing high promotion mode.
1573 void SetNewSpaceHighPromotionModeActive(bool mode) {
1574 new_space_high_promotion_mode_active_ = mode;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001575 }
1576
ulan@chromium.org57ff8812013-05-10 08:16:55 +00001577 inline PretenureFlag GetPretenureMode() {
1578 return new_space_high_promotion_mode_active_ ? TENURED : NOT_TENURED;
1579 }
1580
1581 inline Address* NewSpaceHighPromotionModeActiveAddress() {
1582 return reinterpret_cast<Address*>(&new_space_high_promotion_mode_active_);
1583 }
1584
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001585 inline intptr_t PromotedTotalSize() {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00001586 return PromotedSpaceSizeOfObjects() + PromotedExternalMemorySize();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001587 }
1588
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001589 inline intptr_t OldGenerationSpaceAvailable() {
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001590 return old_generation_allocation_limit_ - PromotedTotalSize();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00001591 }
1592
erik.corry@gmail.combbceb572012-03-09 10:52:05 +00001593 inline intptr_t OldGenerationCapacityAvailable() {
1594 return max_old_generation_size_ - PromotedTotalSize();
1595 }
1596
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001597 static const intptr_t kMinimumOldGenerationAllocationLimit =
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001598 8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
1599
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001600 intptr_t OldGenerationAllocationLimit(intptr_t old_gen_size) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001601 const int divisor = FLAG_stress_compaction ? 10 :
1602 new_space_high_promotion_mode_active_ ? 1 : 3;
ulan@chromium.orgd9e468a2012-06-25 09:47:40 +00001603 intptr_t limit =
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001604 Max(old_gen_size + old_gen_size / divisor,
1605 kMinimumOldGenerationAllocationLimit);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001606 limit += new_space_.Capacity();
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001607 // TODO(hpayer): Can be removed when when pretenuring is supported for all
1608 // allocation sites.
1609 if (IsHighSurvivalRate() && IsStableOrIncreasingSurvivalTrend()) {
1610 limit *= 2;
1611 }
danno@chromium.orgc612e022011-11-10 11:38:15 +00001612 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
1613 return Min(limit, halfway_to_the_max);
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001614 }
1615
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00001616 // Implements the corresponding V8 API function.
1617 bool IdleNotification(int hint);
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001618
1619 // Declare all the root indices.
1620 enum RootListIndex {
1621#define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex,
1622 STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION)
1623#undef ROOT_INDEX_DECLARATION
1624
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001625#define STRING_INDEX_DECLARATION(name, str) k##name##RootIndex,
1626 INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION)
1627#undef STRING_DECLARATION
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001628
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001629 // Utility type maps
1630#define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
1631 STRUCT_LIST(DECLARE_STRUCT_MAP)
1632#undef DECLARE_STRUCT_MAP
1633
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001634 kStringTableRootIndex,
1635 kStrongRootListLength = kStringTableRootIndex,
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001636 kRootListLength
1637 };
1638
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001639 STATIC_CHECK(kUndefinedValueRootIndex == Internals::kUndefinedValueRootIndex);
1640 STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex);
1641 STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex);
1642 STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00001643 STATIC_CHECK(kempty_stringRootIndex == Internals::kEmptyStringRootIndex);
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001644
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00001645 // Generated code can embed direct references to non-writable roots if
1646 // they are in new space.
1647 static bool RootCanBeWrittenAfterInitialization(RootListIndex root_index);
1648
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001649 MUST_USE_RESULT MaybeObject* NumberToString(
ulan@chromium.org57ff8812013-05-10 08:16:55 +00001650 Object* number, bool check_number_string_cache = true,
1651 PretenureFlag pretenure = NOT_TENURED);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001652 MUST_USE_RESULT MaybeObject* Uint32ToString(
1653 uint32_t value, bool check_number_string_cache = true);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +00001654
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001655 Map* MapForExternalArrayType(ExternalArrayType array_type);
1656 RootListIndex RootIndexForExternalArrayType(
ager@chromium.org3811b432009-10-28 14:53:37 +00001657 ExternalArrayType array_type);
1658
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001659 RootListIndex RootIndexForEmptyExternalArray(ElementsKind kind);
1660 ExternalArray* EmptyExternalArrayForMap(Map* map);
1661
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001662 void RecordStats(HeapStats* stats, bool take_snapshot = false);
ager@chromium.org60121232009-12-03 11:25:37 +00001663
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001664 // Copy block of memory from src to dst. Size of block should be aligned
1665 // by pointer size.
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001666 static inline void CopyBlock(Address dst, Address src, int byte_size);
1667
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001668 // Optimized version of memmove for blocks with pointer size aligned sizes and
1669 // pointer size aligned addresses.
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001670 static inline void MoveBlock(Address dst, Address src, int byte_size);
1671
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001672 // Check new space expansion criteria and expand semispaces if it was hit.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001673 void CheckNewSpaceExpansionCriteria();
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001674
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001675 inline void IncrementYoungSurvivorsCounter(int survived) {
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001676 ASSERT(survived >= 0);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001677 young_survivors_after_last_gc_ = survived;
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001678 survived_since_last_expansion_ += survived;
1679 }
1680
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001681 inline bool NextGCIsLikelyToBeFull() {
1682 if (FLAG_gc_global) return true;
1683
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001684 if (FLAG_stress_compaction && (gc_count_ & 1) != 0) return true;
1685
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001686 intptr_t adjusted_allocation_limit =
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001687 old_generation_allocation_limit_ - new_space_.Capacity();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001688
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001689 if (PromotedTotalSize() >= adjusted_allocation_limit) return true;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001690
1691 return false;
1692 }
1693
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001694 void UpdateNewSpaceReferencesInExternalStringTable(
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001695 ExternalStringTableUpdaterCallback updater_func);
1696
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001697 void UpdateReferencesInExternalStringTable(
1698 ExternalStringTableUpdaterCallback updater_func);
1699
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001700 void ProcessWeakReferences(WeakObjectRetainer* retainer);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001701
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001702 void VisitExternalResources(v8::ExternalResourceVisitor* visitor);
1703
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001704 // Helper function that governs the promotion policy from new space to
1705 // old. If the object's old address lies below the new space's age
1706 // mark or if we've already filled the bottom 1/16th of the to space,
1707 // we try to promote this object.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001708 inline bool ShouldBePromoted(Address old_address, int object_size);
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00001709
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001710 int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; }
ager@chromium.orgb26c50a2010-03-26 09:27:16 +00001711
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001712 void ClearJSFunctionResultCaches();
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001713
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001714 void ClearNormalizedMapCaches();
ricow@chromium.org65fae842010-08-25 15:26:24 +00001715
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001716 GCTracer* tracer() { return tracer_; }
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001717
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001718 // Returns the size of objects residing in non new spaces.
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001719 intptr_t PromotedSpaceSizeOfObjects();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001720
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001721 double total_regexp_code_generated() { return total_regexp_code_generated_; }
1722 void IncreaseTotalRegexpCodeGenerated(int size) {
1723 total_regexp_code_generated_ += size;
1724 }
1725
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001726 // Returns maximum GC pause.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001727 double get_max_gc_pause() { return max_gc_pause_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001728
1729 // Returns maximum size of objects alive after GC.
1730 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; }
1731
1732 // Returns minimal interval between two subsequent collections.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00001733 double get_min_in_mutator() { return min_in_mutator_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001734
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001735 // TODO(hpayer): remove, should be handled by GCTracer
1736 void AddMarkingTime(double marking_time) {
1737 marking_time_ += marking_time;
1738 }
1739
1740 double marking_time() const {
1741 return marking_time_;
1742 }
1743
1744 // TODO(hpayer): remove, should be handled by GCTracer
1745 void AddSweepingTime(double sweeping_time) {
1746 sweeping_time_ += sweeping_time;
1747 }
1748
1749 double sweeping_time() const {
1750 return sweeping_time_;
1751 }
1752
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001753 MarkCompactCollector* mark_compact_collector() {
1754 return &mark_compact_collector_;
1755 }
1756
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001757 StoreBuffer* store_buffer() {
1758 return &store_buffer_;
1759 }
1760
1761 Marking* marking() {
1762 return &marking_;
1763 }
1764
1765 IncrementalMarking* incremental_marking() {
1766 return &incremental_marking_;
1767 }
1768
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00001769 bool IsSweepingComplete() {
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00001770 return !mark_compact_collector()->IsConcurrentSweepingInProgress() &&
1771 old_data_space()->IsLazySweepingComplete() &&
1772 old_pointer_space()->IsLazySweepingComplete();
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00001773 }
1774
1775 bool AdvanceSweepers(int step_size) {
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001776 ASSERT(!FLAG_parallel_sweeping && !FLAG_concurrent_sweeping);
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00001777 bool sweeping_complete = old_data_space()->AdvanceSweeper(step_size);
1778 sweeping_complete &= old_pointer_space()->AdvanceSweeper(step_size);
1779 return sweeping_complete;
1780 }
1781
ulan@chromium.org750145a2013-03-07 15:14:13 +00001782 bool EnsureSweepersProgressed(int step_size) {
1783 bool sweeping_complete = old_data_space()->EnsureSweeperProgress(step_size);
1784 sweeping_complete &= old_pointer_space()->EnsureSweeperProgress(step_size);
1785 return sweeping_complete;
1786 }
1787
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 ExternalStringTable* external_string_table() {
1789 return &external_string_table_;
1790 }
1791
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001792 ErrorObjectList* error_object_list() {
1793 return &error_object_list_;
1794 }
1795
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001796 // Returns the current sweep generation.
1797 int sweep_generation() {
1798 return sweep_generation_;
1799 }
1800
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001801 inline Isolate* isolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001803 void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001804 void CallGCEpilogueCallbacks(GCType gc_type);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00001805
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001806 inline bool OldGenerationAllocationLimitReached();
1807
1808 inline void DoScavengeObject(Map* map, HeapObject** slot, HeapObject* obj) {
1809 scavenging_visitors_table_.GetVisitor(map)(map, slot, obj);
1810 }
1811
1812 void QueueMemoryChunkForFree(MemoryChunk* chunk);
1813 void FreeQueuedChunks();
1814
1815 // Completely clear the Instanceof cache (to stop it keeping objects alive
1816 // around a GC).
1817 inline void CompletelyClearInstanceofCache();
1818
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001819 // The roots that have an index less than this are always in old space.
1820 static const int kOldSpaceRoots = 0x20;
1821
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001822 uint32_t HashSeed() {
1823 uint32_t seed = static_cast<uint32_t>(hash_seed()->value());
1824 ASSERT(FLAG_randomize_hashes || seed == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00001825 return seed;
1826 }
1827
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001828 void SetArgumentsAdaptorDeoptPCOffset(int pc_offset) {
1829 ASSERT(arguments_adaptor_deopt_pc_offset() == Smi::FromInt(0));
1830 set_arguments_adaptor_deopt_pc_offset(Smi::FromInt(pc_offset));
1831 }
1832
ulan@chromium.org967e2702012-02-28 09:49:15 +00001833 void SetConstructStubDeoptPCOffset(int pc_offset) {
1834 ASSERT(construct_stub_deopt_pc_offset() == Smi::FromInt(0));
1835 set_construct_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
1836 }
1837
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001838 void SetGetterStubDeoptPCOffset(int pc_offset) {
1839 ASSERT(getter_stub_deopt_pc_offset() == Smi::FromInt(0));
1840 set_getter_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
1841 }
1842
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001843 void SetSetterStubDeoptPCOffset(int pc_offset) {
1844 ASSERT(setter_stub_deopt_pc_offset() == Smi::FromInt(0));
1845 set_setter_stub_deopt_pc_offset(Smi::FromInt(pc_offset));
1846 }
1847
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00001848 // For post mortem debugging.
1849 void RememberUnmappedPage(Address page, bool compacted);
1850
danno@chromium.org88aa0582012-03-23 15:11:57 +00001851 // Global inline caching age: it is incremented on some GCs after context
1852 // disposal. We use it to flush inline caches.
1853 int global_ic_age() {
1854 return global_ic_age_;
1855 }
1856
1857 void AgeInlineCaches() {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001858 global_ic_age_ = (global_ic_age_ + 1) & SharedFunctionInfo::ICAgeBits::kMax;
danno@chromium.org88aa0582012-03-23 15:11:57 +00001859 }
1860
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001861 bool flush_monomorphic_ics() { return flush_monomorphic_ics_; }
1862
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001863 intptr_t amount_of_external_allocated_memory() {
1864 return amount_of_external_allocated_memory_;
1865 }
1866
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001867 // ObjectStats are kept in two arrays, counts and sizes. Related stats are
1868 // stored in a contiguous linear buffer. Stats groups are stored one after
1869 // another.
1870 enum {
1871 FIRST_CODE_KIND_SUB_TYPE = LAST_TYPE + 1,
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001872 FIRST_FIXED_ARRAY_SUB_TYPE =
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001873 FIRST_CODE_KIND_SUB_TYPE + Code::NUMBER_OF_KINDS,
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001874 OBJECT_STATS_COUNT =
1875 FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001876 };
1877
1878 void RecordObjectStats(InstanceType type, int sub_type, size_t size) {
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001879 ASSERT(type <= LAST_TYPE);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001880 if (sub_type < 0) {
1881 object_counts_[type]++;
1882 object_sizes_[type] += size;
1883 } else {
1884 if (type == CODE_TYPE) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001885 ASSERT(sub_type < Code::NUMBER_OF_KINDS);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001886 object_counts_[FIRST_CODE_KIND_SUB_TYPE + sub_type]++;
1887 object_sizes_[FIRST_CODE_KIND_SUB_TYPE + sub_type] += size;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001888 } else if (type == FIXED_ARRAY_TYPE) {
1889 ASSERT(sub_type <= LAST_FIXED_ARRAY_SUB_TYPE);
1890 object_counts_[FIRST_FIXED_ARRAY_SUB_TYPE + sub_type]++;
1891 object_sizes_[FIRST_FIXED_ARRAY_SUB_TYPE + sub_type] += size;
verwaest@chromium.org753aee42012-07-17 16:15:42 +00001892 }
1893 }
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001894 }
1895
1896 void CheckpointObjectStats();
1897
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001898 // We don't use a ScopedLock here since we want to lock the heap
1899 // only when FLAG_parallel_recompilation is true.
1900 class RelocationLock {
1901 public:
1902 explicit RelocationLock(Heap* heap);
1903
1904 ~RelocationLock() {
1905 if (FLAG_parallel_recompilation) {
1906#ifdef DEBUG
1907 heap_->relocation_mutex_locked_by_optimizer_thread_ = false;
1908#endif // DEBUG
1909 heap_->relocation_mutex_->Unlock();
1910 }
1911 }
1912
1913#ifdef DEBUG
1914 static bool IsLockedByOptimizerThread(Heap* heap) {
1915 return heap->relocation_mutex_locked_by_optimizer_thread_;
1916 }
1917#endif // DEBUG
1918
1919 private:
1920 Heap* heap_;
1921 };
1922
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001923 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001924 Heap();
1925
1926 // This can be calculated directly from a pointer to the heap; however, it is
1927 // more expedient to get at the isolate directly from within Heap methods.
1928 Isolate* isolate_;
1929
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001930 Object* roots_[kRootListLength];
1931
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001932 intptr_t code_range_size_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001933 int reserved_semispace_size_;
1934 int max_semispace_size_;
1935 int initial_semispace_size_;
1936 intptr_t max_old_generation_size_;
1937 intptr_t max_executable_size_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001938
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001939 // For keeping track of how much data has survived
1940 // scavenge since last new space expansion.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001941 int survived_since_last_expansion_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001943 // For keeping track on when to flush RegExp code.
1944 int sweep_generation_;
1945
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001946 int always_allocate_scope_depth_;
1947 int linear_allocation_scope_depth_;
kasperl@chromium.org8b2bb262010-03-01 09:46:28 +00001948
1949 // For keeping track of context disposals.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001950 int contexts_disposed_;
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001951
danno@chromium.org88aa0582012-03-23 15:11:57 +00001952 int global_ic_age_;
1953
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001954 bool flush_monomorphic_ics_;
1955
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001956 int scan_on_scavenge_pages_;
1957
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001958#if defined(V8_TARGET_ARCH_X64)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001959 static const int kMaxObjectSizeInNewSpace = 1024*KB;
lrn@chromium.org8541d772010-12-15 12:05:09 +00001960#else
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001961 static const int kMaxObjectSizeInNewSpace = 512*KB;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00001962#endif
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001963
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001964 NewSpace new_space_;
1965 OldSpace* old_pointer_space_;
1966 OldSpace* old_data_space_;
1967 OldSpace* code_space_;
1968 MapSpace* map_space_;
1969 CellSpace* cell_space_;
danno@chromium.org41728482013-06-12 22:31:22 +00001970 PropertyCellSpace* property_cell_space_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001971 LargeObjectSpace* lo_space_;
1972 HeapState gc_state_;
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00001973 int gc_post_processing_depth_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001974
kasper.lund7276f142008-07-30 08:49:36 +00001975 // Returns the amount of external memory registered since last global gc.
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001976 intptr_t PromotedExternalMemorySize();
kasper.lund7276f142008-07-30 08:49:36 +00001977
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00001978 unsigned int ms_count_; // how many mark-sweep collections happened
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001979 unsigned int gc_count_; // how many gc happened
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001980
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00001981 // For post mortem debugging.
1982 static const int kRememberedUnmappedPages = 128;
1983 int remembered_unmapped_pages_index_;
1984 Address remembered_unmapped_pages_[kRememberedUnmappedPages];
1985
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001986 // Total length of the strings we failed to flatten since the last GC.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001987 int unflattened_strings_length_;
fschneider@chromium.org086aac62010-03-17 13:18:24 +00001988
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001989#define ROOT_ACCESSOR(type, name, camel_name) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001990 inline void set_##name(type* value) { \
1991 /* The deserializer makes use of the fact that these common roots are */ \
1992 /* never in new space and never on a page that is being compacted. */ \
1993 ASSERT(k##camel_name##RootIndex >= kOldSpaceRoots || !InNewSpace(value)); \
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00001994 roots_[k##camel_name##RootIndex] = value; \
1995 }
1996 ROOT_LIST(ROOT_ACCESSOR)
1997#undef ROOT_ACCESSOR
1998
kasper.lund7276f142008-07-30 08:49:36 +00001999#ifdef DEBUG
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002000 // If the --gc-interval flag is set to a positive value, this
2001 // variable holds the value indicating the number of allocations
2002 // remain until the next failure and garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002003 int allocation_timeout_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002004
2005 // Do we expect to be able to handle allocation failure at this
2006 // time?
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002007 bool disallow_allocation_failure_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002008#endif // DEBUG
2009
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002010 // Indicates that the new space should be kept small due to high promotion
2011 // rates caused by the mutator allocating a lot of long-lived objects.
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002012 // TODO(hpayer): change to bool if no longer accessed from generated code
2013 intptr_t new_space_high_promotion_mode_active_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002014
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00002015 // Limit that triggers a global GC on the next (normally caused) GC. This
2016 // is checked when we have already decided to do a GC to help determine
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00002017 // which collector to invoke, before expanding a paged space in the old
2018 // generation and on every allocation in large object space.
2019 intptr_t old_generation_allocation_limit_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002020
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002021 // Used to adjust the limits that control the timing of the next GC.
2022 intptr_t size_of_old_gen_at_last_old_space_gc_;
2023
kasperl@chromium.orge959c182009-07-27 08:59:04 +00002024 // Limit on the amount of externally allocated memory allowed
2025 // between global GCs. If reached a global GC is forced.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002026 intptr_t external_allocation_limit_;
kasperl@chromium.orge959c182009-07-27 08:59:04 +00002027
kasper.lund7276f142008-07-30 08:49:36 +00002028 // The amount of external memory registered through the API kept alive
2029 // by global handles
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00002030 intptr_t amount_of_external_allocated_memory_;
kasper.lund7276f142008-07-30 08:49:36 +00002031
2032 // Caches the amount of external memory registered at the last global gc.
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00002033 intptr_t amount_of_external_allocated_memory_at_last_global_gc_;
kasper.lund7276f142008-07-30 08:49:36 +00002034
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035 // Indicates that an allocation has failed in the old generation since the
2036 // last GC.
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00002037 bool old_gen_exhausted_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002039 Object* native_contexts_list_;
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002040
danno@chromium.org1fd77d52013-06-07 16:01:45 +00002041 Object* array_buffers_list_;
2042
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002043 StoreBufferRebuilder store_buffer_rebuilder_;
2044
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00002045 struct StringTypeTable {
2046 InstanceType type;
2047 int size;
2048 RootListIndex index;
2049 };
2050
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002051 struct ConstantStringTable {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00002052 const char* contents;
2053 RootListIndex index;
2054 };
2055
2056 struct StructTable {
2057 InstanceType type;
2058 int size;
2059 RootListIndex index;
2060 };
2061
2062 static const StringTypeTable string_type_table[];
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002063 static const ConstantStringTable constant_string_table[];
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00002064 static const StructTable struct_table[];
2065
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002066 // The special hidden string which is an empty string, but does not match
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002067 // any string when looked up in properties.
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002068 String* hidden_string_;
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002069
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070 // GC callback function, called before and after mark-compact GC.
2071 // Allocations in the callback function are disallowed.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002072 struct GCPrologueCallbackPair {
2073 GCPrologueCallbackPair(GCPrologueCallback callback, GCType gc_type)
2074 : callback(callback), gc_type(gc_type) {
2075 }
2076 bool operator==(const GCPrologueCallbackPair& pair) const {
2077 return pair.callback == callback;
2078 }
2079 GCPrologueCallback callback;
2080 GCType gc_type;
2081 };
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002082 List<GCPrologueCallbackPair> gc_prologue_callbacks_;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002083
2084 struct GCEpilogueCallbackPair {
2085 GCEpilogueCallbackPair(GCEpilogueCallback callback, GCType gc_type)
2086 : callback(callback), gc_type(gc_type) {
2087 }
2088 bool operator==(const GCEpilogueCallbackPair& pair) const {
2089 return pair.callback == callback;
2090 }
2091 GCEpilogueCallback callback;
2092 GCType gc_type;
2093 };
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002094 List<GCEpilogueCallbackPair> gc_epilogue_callbacks_;
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002095
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002096 GCCallback global_gc_prologue_callback_;
2097 GCCallback global_gc_epilogue_callback_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002099 // Support for computing object sizes during GC.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002100 HeapObjectCallback gc_safe_size_of_old_object_;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002101 static int GcSafeSizeOfOldObject(HeapObject* object);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002102
2103 // Update the GC state. Called from the mark-compact collector.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002104 void MarkMapPointersAsEncoded(bool encoded) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002105 ASSERT(!encoded);
2106 gc_safe_size_of_old_object_ = &GcSafeSizeOfOldObject;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002107 }
2108
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109 // Checks whether a global GC is necessary
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002110 GarbageCollector SelectGarbageCollector(AllocationSpace space,
2111 const char** reason);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112
2113 // Performs garbage collection
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00002114 // Returns whether there is a chance another major GC could
2115 // collect more garbage.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002116 bool PerformGarbageCollection(GarbageCollector collector,
2117 GCTracer* tracer);
2118
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002119 inline void UpdateOldSpaceLimits();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002120
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002121 // Allocate an uninitialized object in map space. The behavior is identical
2122 // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't
2123 // have to test the allocation space argument and (b) can reduce code size
2124 // (since both AllocateRaw and AllocateRawMap are inlined).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002125 MUST_USE_RESULT inline MaybeObject* AllocateRawMap();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002126
danno@chromium.org41728482013-06-12 22:31:22 +00002127 // Allocate an uninitialized object in the simple cell space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002128 MUST_USE_RESULT inline MaybeObject* AllocateRawCell();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129
danno@chromium.org41728482013-06-12 22:31:22 +00002130 // Allocate an uninitialized object in the global property cell space.
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00002131 MUST_USE_RESULT inline MaybeObject* AllocateRawPropertyCell();
danno@chromium.org41728482013-06-12 22:31:22 +00002132
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133 // Initializes a JSObject based on its map.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002134 void InitializeJSObjectFromMap(JSObject* obj,
2135 FixedArray* properties,
2136 Map* map);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002138 bool CreateInitialMaps();
2139 bool CreateInitialObjects();
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002140
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002141 // These five Create*EntryStub functions are here and forced to not be inlined
sgjesse@chromium.org76ae6992010-08-05 15:54:25 +00002142 // because of a gcc-4.4 bug that assigns wrong vtable entries.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002143 NO_INLINE(void CreateJSEntryStub());
2144 NO_INLINE(void CreateJSConstructEntryStub());
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002145
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002146 void CreateFixedStubs();
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002147
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00002148 MUST_USE_RESULT MaybeObject* CreateOddball(const char* to_string,
2149 Object* to_number,
2150 byte kind);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002152 // Allocate a JSArray with no elements
2153 MUST_USE_RESULT MaybeObject* AllocateJSArray(
2154 ElementsKind elements_kind,
2155 PretenureFlag pretenure = NOT_TENURED);
2156
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002157 MUST_USE_RESULT MaybeObject* AllocateJSArrayWithAllocationSite(
2158 ElementsKind elements_kind,
2159 Handle<Object> allocation_site_info_payload);
2160
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161 // Allocate empty fixed array.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002162 MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002163
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00002164 // Allocate empty external array of given type.
2165 MUST_USE_RESULT MaybeObject* AllocateEmptyExternalArray(
2166 ExternalArrayType array_type);
2167
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002168 // Allocate empty fixed double array.
2169 MUST_USE_RESULT MaybeObject* AllocateEmptyFixedDoubleArray();
2170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171 // Performs a minor collection in new generation.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002172 void Scavenge();
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00002173
2174 static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002175 Heap* heap,
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +00002176 Object** pointer);
2177
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002178 Address DoScavenge(ObjectVisitor* scavenge_visitor, Address new_space_front);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002179 static void ScavengeStoreBufferCallback(Heap* heap,
2180 MemoryChunk* page,
2181 StoreBufferEvent event);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002182
2183 // Performs a major collection in the whole heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002184 void MarkCompact(GCTracer* tracer);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002185
2186 // Code to be run before and after mark-compact.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002187 void MarkCompactPrologue();
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00002188
danno@chromium.org1fd77d52013-06-07 16:01:45 +00002189 void ProcessNativeContexts(WeakObjectRetainer* retainer, bool record_slots);
2190 void ProcessArrayBuffers(WeakObjectRetainer* retainer, bool record_slots);
2191
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002192 // Called on heap tear-down.
2193 void TearDownArrayBuffers();
2194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195 // Record statistics before and after garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002196 void ReportStatisticsBeforeGC();
2197 void ReportStatisticsAfterGC();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002199 // Slow part of scavenge object.
2200 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
2201
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002202 // Initializes a function with a shared part and prototype.
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002203 // Note: this code was factored out of AllocateFunction such that
2204 // other parts of the VM could use it. Specifically, a function that creates
2205 // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
2206 // Please note this does not perform a garbage collection.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002207 inline void InitializeFunction(
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002208 JSFunction* function,
2209 SharedFunctionInfo* shared,
2210 Object* prototype);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002211
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002212 // Total RegExp code ever generated
2213 double total_regexp_code_generated_;
2214
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002215 GCTracer* tracer_;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002216
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002217 // Allocates a small number to string cache.
2218 MUST_USE_RESULT MaybeObject* AllocateInitialNumberStringCache();
2219 // Creates and installs the full-sized number string cache.
2220 void AllocateFullSizeNumberStringCache();
2221 // Get the length of the number to string cache based on the max semispace
2222 // size.
2223 int FullSizeNumberStringCacheLength();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002224 // Flush the number to string cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002225 void FlushNumberStringCache();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +00002226
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002227 void UpdateSurvivalRateTrend(int start_new_space_size);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002228
2229 enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING };
2230
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002231 static const int kYoungSurvivalRateHighThreshold = 90;
2232 static const int kYoungSurvivalRateLowThreshold = 10;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002233 static const int kYoungSurvivalRateAllowedDeviation = 15;
2234
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002235 int young_survivors_after_last_gc_;
2236 int high_survival_rate_period_length_;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002237 int low_survival_rate_period_length_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002238 double survival_rate_;
2239 SurvivalRateTrend previous_survival_rate_trend_;
2240 SurvivalRateTrend survival_rate_trend_;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002241
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002242 void set_survival_rate_trend(SurvivalRateTrend survival_rate_trend) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002243 ASSERT(survival_rate_trend != FLUCTUATING);
2244 previous_survival_rate_trend_ = survival_rate_trend_;
2245 survival_rate_trend_ = survival_rate_trend;
2246 }
2247
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002248 SurvivalRateTrend survival_rate_trend() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002249 if (survival_rate_trend_ == STABLE) {
2250 return STABLE;
2251 } else if (previous_survival_rate_trend_ == STABLE) {
2252 return survival_rate_trend_;
2253 } else if (survival_rate_trend_ != previous_survival_rate_trend_) {
2254 return FLUCTUATING;
2255 } else {
2256 return survival_rate_trend_;
2257 }
2258 }
2259
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002260 bool IsStableOrIncreasingSurvivalTrend() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002261 switch (survival_rate_trend()) {
2262 case STABLE:
2263 case INCREASING:
2264 return true;
2265 default:
2266 return false;
2267 }
2268 }
2269
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002270 bool IsStableOrDecreasingSurvivalTrend() {
2271 switch (survival_rate_trend()) {
2272 case STABLE:
2273 case DECREASING:
2274 return true;
2275 default:
2276 return false;
2277 }
2278 }
2279
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002280 bool IsIncreasingSurvivalTrend() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002281 return survival_rate_trend() == INCREASING;
2282 }
2283
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002284 bool IsHighSurvivalRate() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002285 return high_survival_rate_period_length_ > 0;
2286 }
2287
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002288 bool IsLowSurvivalRate() {
2289 return low_survival_rate_period_length_ > 0;
2290 }
2291
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002292 void SelectScavengingVisitorsTable();
2293
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00002294 void StartIdleRound() {
2295 mark_sweeps_since_idle_round_started_ = 0;
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00002296 }
2297
2298 void FinishIdleRound() {
2299 mark_sweeps_since_idle_round_started_ = kMaxMarkSweepsInIdleRound;
2300 scavenges_since_last_idle_round_ = 0;
2301 }
2302
2303 bool EnoughGarbageSinceLastIdleRound() {
2304 return (scavenges_since_last_idle_round_ >= kIdleScavengeThreshold);
2305 }
2306
ulan@chromium.org6ff65142012-03-21 09:52:17 +00002307 // Estimates how many milliseconds a Mark-Sweep would take to complete.
2308 // In idle notification handler we assume that this function will return:
2309 // - a number less than 10 for small heaps, which are less than 8Mb.
2310 // - a number greater than 10 for large heaps, which are greater than 32Mb.
2311 int TimeMarkSweepWouldTakeInMs() {
2312 // Rough estimate of how many megabytes of heap can be processed in 1 ms.
2313 static const int kMbPerMs = 2;
2314
2315 int heap_size_mb = static_cast<int>(SizeOfObjects() / MB);
2316 return heap_size_mb / kMbPerMs;
2317 }
2318
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00002319 // Returns true if no more GC work is left.
2320 bool IdleGlobalGC();
2321
ulan@chromium.org6ff65142012-03-21 09:52:17 +00002322 void AdvanceIdleIncrementalMarking(intptr_t step_size);
2323
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002324 void ClearObjectStats(bool clear_last_time_stats = false);
ulan@chromium.org6ff65142012-03-21 09:52:17 +00002325
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002326 static const int kInitialStringTableSize = 2048;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002327 static const int kInitialEvalCacheSize = 64;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002328 static const int kInitialNumberStringCacheSize = 256;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002329
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002330 // Object counts and used memory by InstanceType
verwaest@chromium.org753aee42012-07-17 16:15:42 +00002331 size_t object_counts_[OBJECT_STATS_COUNT];
2332 size_t object_counts_last_time_[OBJECT_STATS_COUNT];
2333 size_t object_sizes_[OBJECT_STATS_COUNT];
2334 size_t object_sizes_last_time_[OBJECT_STATS_COUNT];
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002335
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002336 // Maximum GC pause.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00002337 double max_gc_pause_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002338
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00002339 // Total time spent in GC.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00002340 double total_gc_time_ms_;
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00002341
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002342 // Maximum size of objects alive after GC.
2343 intptr_t max_alive_after_gc_;
2344
2345 // Minimal interval between two subsequent collections.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +00002346 double min_in_mutator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002347
2348 // Size of objects alive after last GC.
2349 intptr_t alive_after_last_gc_;
2350
2351 double last_gc_end_timestamp_;
2352
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00002353 // Cumulative GC time spent in marking
2354 double marking_time_;
2355
2356 // Cumulative GC time spent in sweeping
2357 double sweeping_time_;
2358
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002359 MarkCompactCollector mark_compact_collector_;
2360
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002361 StoreBuffer store_buffer_;
2362
2363 Marking marking_;
2364
2365 IncrementalMarking incremental_marking_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002366
2367 int number_idle_notifications_;
2368 unsigned int last_idle_notification_gc_count_;
2369 bool last_idle_notification_gc_count_init_;
2370
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00002371 int mark_sweeps_since_idle_round_started_;
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00002372 unsigned int gc_count_at_last_idle_gc_;
2373 int scavenges_since_last_idle_round_;
2374
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002375 // If the --deopt_every_n_garbage_collections flag is set to a positive value,
2376 // this variable holds the number of garbage collections since the last
2377 // deoptimization triggered by garbage collection.
2378 int gcs_since_last_deopt_;
2379
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00002380#ifdef VERIFY_HEAP
2381 int no_weak_embedded_maps_verification_scope_depth_;
2382#endif
2383
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +00002384 static const int kMaxMarkSweepsInIdleRound = 7;
2385 static const int kIdleScavengeThreshold = 5;
2386
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002387 // Shared state read by the scavenge collector and set by ScavengeObject.
2388 PromotionQueue promotion_queue_;
2389
2390 // Flag is set when the heap has been configured. The heap can be repeatedly
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002391 // configured through the API until it is set up.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002392 bool configured_;
2393
2394 ExternalStringTable external_string_table_;
2395
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00002396 ErrorObjectList error_object_list_;
2397
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002398 VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_;
2399
2400 MemoryChunk* chunks_queued_for_free_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002401
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002402 Mutex* relocation_mutex_;
2403#ifdef DEBUG
2404 bool relocation_mutex_locked_by_optimizer_thread_;
2405#endif // DEBUG;
2406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002407 friend class Factory;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002408 friend class GCTracer;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409 friend class DisallowAllocationFailure;
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00002410 friend class AlwaysAllocateScope;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002411 friend class Page;
2412 friend class Isolate;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002413 friend class MarkCompactCollector;
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00002414 friend class MarkCompactMarkingVisitor;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002415 friend class MapCompact;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00002416#ifdef VERIFY_HEAP
2417 friend class NoWeakEmbeddedMapsVerificationScope;
2418#endif
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002419
2420 DISALLOW_COPY_AND_ASSIGN(Heap);
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00002421};
2422
2423
ager@chromium.org67368652009-12-03 11:40:49 +00002424class HeapStats {
2425 public:
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002426 static const int kStartMarker = 0xDECADE00;
2427 static const int kEndMarker = 0xDECADE01;
2428
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +00002429 int* start_marker; // 0
2430 int* new_space_size; // 1
2431 int* new_space_capacity; // 2
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002432 intptr_t* old_pointer_space_size; // 3
2433 intptr_t* old_pointer_space_capacity; // 4
2434 intptr_t* old_data_space_size; // 5
2435 intptr_t* old_data_space_capacity; // 6
2436 intptr_t* code_space_size; // 7
2437 intptr_t* code_space_capacity; // 8
2438 intptr_t* map_space_size; // 9
2439 intptr_t* map_space_capacity; // 10
2440 intptr_t* cell_space_size; // 11
2441 intptr_t* cell_space_capacity; // 12
2442 intptr_t* lo_space_size; // 13
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +00002443 int* global_handle_count; // 14
2444 int* weak_global_handle_count; // 15
2445 int* pending_global_handle_count; // 16
2446 int* near_death_global_handle_count; // 17
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002447 int* free_global_handle_count; // 18
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002448 intptr_t* memory_allocator_size; // 19
2449 intptr_t* memory_allocator_capacity; // 20
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +00002450 int* objects_per_type; // 21
2451 int* size_per_type; // 22
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002452 int* os_error; // 23
2453 int* end_marker; // 24
danno@chromium.org41728482013-06-12 22:31:22 +00002454 intptr_t* property_cell_space_size; // 25
2455 intptr_t* property_cell_space_capacity; // 26
ager@chromium.org60121232009-12-03 11:25:37 +00002456};
2457
2458
jkummerow@chromium.org000f7fb2012-08-01 11:14:42 +00002459class DisallowAllocationFailure {
2460 public:
2461 inline DisallowAllocationFailure();
2462 inline ~DisallowAllocationFailure();
2463
2464#ifdef DEBUG
2465 private:
2466 bool old_state_;
2467#endif
2468};
2469
2470
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00002471class AlwaysAllocateScope {
2472 public:
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002473 inline AlwaysAllocateScope();
2474 inline ~AlwaysAllocateScope();
jkummerow@chromium.org000f7fb2012-08-01 11:14:42 +00002475
2476 private:
2477 // Implicitly disable artificial allocation failures.
2478 DisallowAllocationFailure disallow_allocation_failure_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002479};
2480
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00002481#ifdef VERIFY_HEAP
2482class NoWeakEmbeddedMapsVerificationScope {
2483 public:
2484 inline NoWeakEmbeddedMapsVerificationScope();
2485 inline ~NoWeakEmbeddedMapsVerificationScope();
2486};
2487#endif
2488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002489
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002490// Visitor class to verify interior pointers in spaces that do not contain
2491// or care about intergenerational references. All heap object pointers have to
2492// point into the heap to a location that has a map pointer at its first word.
2493// Caveat: Heap::Contains is an approximation because it can return true for
2494// objects in a heap space but above the allocation pointer.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002495class VerifyPointersVisitor: public ObjectVisitor {
2496 public:
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002497 inline void VisitPointers(Object** start, Object** end);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002498};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002499
2500
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002501// Space iterator for iterating over all spaces of the heap. Returns each space
2502// in turn, and null when it is done.
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002503class AllSpaces BASE_EMBEDDED {
2504 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002505 explicit AllSpaces(Heap* heap) : heap_(heap), counter_(FIRST_SPACE) {}
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002506 Space* next();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002507 private:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002508 Heap* heap_;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002509 int counter_;
2510};
2511
2512
2513// Space iterator for iterating over all old spaces of the heap: Old pointer
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002514// space, old data space and code space. Returns each space in turn, and null
2515// when it is done.
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002516class OldSpaces BASE_EMBEDDED {
2517 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002518 explicit OldSpaces(Heap* heap) : heap_(heap), counter_(OLD_POINTER_SPACE) {}
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002519 OldSpace* next();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002520 private:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002521 Heap* heap_;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002522 int counter_;
2523};
2524
2525
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002526// Space iterator for iterating over all the paged spaces of the heap: Map
2527// space, old pointer space, old data space, code space and cell space. Returns
2528// each space in turn, and null when it is done.
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002529class PagedSpaces BASE_EMBEDDED {
2530 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002531 explicit PagedSpaces(Heap* heap) : heap_(heap), counter_(OLD_POINTER_SPACE) {}
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002532 PagedSpace* next();
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002533 private:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002534 Heap* heap_;
ager@chromium.org9258b6b2008-09-11 09:11:10 +00002535 int counter_;
2536};
2537
2538
2539// Space iterator for iterating over all spaces of the heap.
kasper.lund7276f142008-07-30 08:49:36 +00002540// For each space an object iterator is provided. The deallocation of the
2541// returned object iterators is handled by the space iterator.
kasper.lund7276f142008-07-30 08:49:36 +00002542class SpaceIterator : public Malloced {
2543 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002544 explicit SpaceIterator(Heap* heap);
2545 SpaceIterator(Heap* heap, HeapObjectCallback size_func);
kasper.lund7276f142008-07-30 08:49:36 +00002546 virtual ~SpaceIterator();
2547
2548 bool has_next();
2549 ObjectIterator* next();
2550
2551 private:
2552 ObjectIterator* CreateIterator();
2553
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002554 Heap* heap_;
kasper.lund7276f142008-07-30 08:49:36 +00002555 int current_space_; // from enum AllocationSpace.
2556 ObjectIterator* iterator_; // object iterator for the current space.
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00002557 HeapObjectCallback size_func_;
kasper.lund7276f142008-07-30 08:49:36 +00002558};
2559
2560
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00002561// A HeapIterator provides iteration over the whole heap. It
2562// aggregates the specific iterators for the different spaces as
2563// these can only iterate over one space only.
2564//
2565// HeapIterator can skip free list nodes (that is, de-allocated heap
2566// objects that still remain in the heap). As implementation of free
2567// nodes filtering uses GC marks, it can't be used during MS/MC GC
2568// phases. Also, it is forbidden to interrupt iteration in this mode,
2569// as this will leave heap objects marked (and thus, unusable).
whesse@chromium.org023421e2010-12-21 12:19:12 +00002570class HeapObjectsFilter;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002571
2572class HeapIterator BASE_EMBEDDED {
2573 public:
whesse@chromium.org023421e2010-12-21 12:19:12 +00002574 enum HeapObjectsFiltering {
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00002575 kNoFiltering,
whesse@chromium.org023421e2010-12-21 12:19:12 +00002576 kFilterUnreachable
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00002577 };
2578
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002579 explicit HeapIterator(Heap* heap);
2580 HeapIterator(Heap* heap, HeapObjectsFiltering filtering);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00002581 ~HeapIterator();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002582
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002583 HeapObject* next();
2584 void reset();
2585
2586 private:
2587 // Perform the initialization.
2588 void Init();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589 // Perform all necessary shutdown (destruction) work.
2590 void Shutdown();
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00002591 HeapObject* NextObject();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002593 Heap* heap_;
whesse@chromium.org023421e2010-12-21 12:19:12 +00002594 HeapObjectsFiltering filtering_;
2595 HeapObjectsFilter* filter_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002596 // Space iterator for iterating all the spaces.
2597 SpaceIterator* space_iterator_;
2598 // Object iterator for the space currently being iterated.
2599 ObjectIterator* object_iterator_;
2600};
2601
2602
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002603// Cache for mapping (map, property name) into field offset.
2604// Cleared at startup and prior to mark sweep collection.
2605class KeyedLookupCache {
2606 public:
2607 // Lookup field offset for (map, name). If absent, -1 is returned.
ulan@chromium.org750145a2013-03-07 15:14:13 +00002608 int Lookup(Map* map, Name* name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002609
2610 // Update an element in the cache.
ulan@chromium.org750145a2013-03-07 15:14:13 +00002611 void Update(Map* map, Name* name, int field_offset);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002612
2613 // Clear the cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002614 void Clear();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002615
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002616 static const int kLength = 256;
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002617 static const int kCapacityMask = kLength - 1;
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002618 static const int kMapHashShift = 5;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002619 static const int kHashMask = -4; // Zero the last two bits.
2620 static const int kEntriesPerBucket = 4;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002621 static const int kNotFound = -1;
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002622
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00002623 // kEntriesPerBucket should be a power of 2.
2624 STATIC_ASSERT((kEntriesPerBucket & (kEntriesPerBucket - 1)) == 0);
2625 STATIC_ASSERT(kEntriesPerBucket == -kHashMask);
2626
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002627 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002628 KeyedLookupCache() {
2629 for (int i = 0; i < kLength; ++i) {
2630 keys_[i].map = NULL;
2631 keys_[i].name = NULL;
2632 field_offsets_[i] = kNotFound;
2633 }
2634 }
2635
ulan@chromium.org750145a2013-03-07 15:14:13 +00002636 static inline int Hash(Map* map, Name* name);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002637
2638 // Get the address of the keys and field_offsets arrays. Used in
2639 // generated code to perform cache lookups.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002640 Address keys_address() {
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002641 return reinterpret_cast<Address>(&keys_);
2642 }
2643
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002644 Address field_offsets_address() {
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002645 return reinterpret_cast<Address>(&field_offsets_);
2646 }
2647
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002648 struct Key {
2649 Map* map;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002650 Name* name;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002651 };
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002652
2653 Key keys_[kLength];
2654 int field_offsets_[kLength];
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002655
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002656 friend class ExternalReference;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002657 friend class Isolate;
2658 DISALLOW_COPY_AND_ASSIGN(KeyedLookupCache);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002659};
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002660
2661
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002662// Cache for mapping (map, property name) into descriptor index.
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002663// The cache contains both positive and negative results.
2664// Descriptor index equals kNotFound means the property is absent.
2665// Cleared at startup and prior to any gc.
2666class DescriptorLookupCache {
2667 public:
2668 // Lookup descriptor index for (map, name).
2669 // If absent, kAbsent is returned.
ulan@chromium.org750145a2013-03-07 15:14:13 +00002670 int Lookup(Map* source, Name* name) {
2671 if (!name->IsUniqueName()) return kAbsent;
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002672 int index = Hash(source, name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002673 Key& key = keys_[index];
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002674 if ((key.source == source) && (key.name == name)) return results_[index];
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002675 return kAbsent;
2676 }
2677
2678 // Update an element in the cache.
ulan@chromium.org750145a2013-03-07 15:14:13 +00002679 void Update(Map* source, Name* name, int result) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002680 ASSERT(result != kAbsent);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002681 if (name->IsUniqueName()) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002682 int index = Hash(source, name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002683 Key& key = keys_[index];
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002684 key.source = source;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002685 key.name = name;
2686 results_[index] = result;
2687 }
2688 }
2689
2690 // Clear the cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002691 void Clear();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002692
2693 static const int kAbsent = -2;
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002694
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002695 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002696 DescriptorLookupCache() {
2697 for (int i = 0; i < kLength; ++i) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002698 keys_[i].source = NULL;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002699 keys_[i].name = NULL;
2700 results_[i] = kAbsent;
2701 }
2702 }
2703
ulan@chromium.org750145a2013-03-07 15:14:13 +00002704 static int Hash(Object* source, Name* name) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002705 // Uses only lower 32 bits if pointers are larger.
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002706 uint32_t source_hash =
2707 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(source))
jkummerow@chromium.org000f7fb2012-08-01 11:14:42 +00002708 >> kPointerSizeLog2;
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +00002709 uint32_t name_hash =
jkummerow@chromium.org000f7fb2012-08-01 11:14:42 +00002710 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name))
2711 >> kPointerSizeLog2;
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002712 return (source_hash ^ name_hash) % kLength;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002713 }
2714
2715 static const int kLength = 64;
2716 struct Key {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002717 Map* source;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002718 Name* name;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002719 };
2720
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002721 Key keys_[kLength];
2722 int results_[kLength];
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002723
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002724 friend class Isolate;
2725 DISALLOW_COPY_AND_ASSIGN(DescriptorLookupCache);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726};
2727
2728
kasper.lund7276f142008-07-30 08:49:36 +00002729// GCTracer collects and prints ONE line after each garbage collector
2730// invocation IFF --trace_gc is used.
2731
2732class GCTracer BASE_EMBEDDED {
2733 public:
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002734 class Scope BASE_EMBEDDED {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002735 public:
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002736 enum ScopeId {
2737 EXTERNAL,
2738 MC_MARK,
2739 MC_SWEEP,
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002740 MC_SWEEP_NEWSPACE,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002741 MC_EVACUATE_PAGES,
2742 MC_UPDATE_NEW_TO_NEW_POINTERS,
2743 MC_UPDATE_ROOT_TO_NEW_POINTERS,
2744 MC_UPDATE_OLD_TO_NEW_POINTERS,
2745 MC_UPDATE_POINTERS_TO_EVACUATED,
2746 MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
2747 MC_UPDATE_MISC_POINTERS,
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00002748 MC_WEAKMAP_PROCESS,
2749 MC_WEAKMAP_CLEAR,
fschneider@chromium.orged78ffd2010-07-21 11:05:19 +00002750 MC_FLUSH_CODE,
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002751 kNumberOfScopes
2752 };
2753
2754 Scope(GCTracer* tracer, ScopeId scope)
2755 : tracer_(tracer),
2756 scope_(scope) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002757 start_time_ = OS::TimeCurrentMillis();
2758 }
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002759
2760 ~Scope() {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002761 ASSERT(scope_ < kNumberOfScopes); // scope_ is unsigned.
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002762 tracer_->scopes_[scope_] += OS::TimeCurrentMillis() - start_time_;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002763 }
kasper.lund7276f142008-07-30 08:49:36 +00002764
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002765 private:
2766 GCTracer* tracer_;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002767 ScopeId scope_;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002768 double start_time_;
2769 };
2770
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002771 explicit GCTracer(Heap* heap,
2772 const char* gc_reason,
2773 const char* collector_reason);
kasper.lund7276f142008-07-30 08:49:36 +00002774 ~GCTracer();
2775
2776 // Sets the collector.
2777 void set_collector(GarbageCollector collector) { collector_ = collector; }
2778
2779 // Sets the GC count.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002780 void set_gc_count(unsigned int count) { gc_count_ = count; }
kasper.lund7276f142008-07-30 08:49:36 +00002781
2782 // Sets the full GC count.
2783 void set_full_gc_count(int count) { full_gc_count_ = count; }
2784
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002785 void increment_promoted_objects_size(int object_size) {
2786 promoted_objects_size_ += object_size;
2787 }
2788
rossberg@chromium.orgcddc71f2012-12-07 12:40:13 +00002789 void increment_nodes_died_in_new_space() {
2790 nodes_died_in_new_space_++;
2791 }
2792
2793 void increment_nodes_copied_in_new_space() {
2794 nodes_copied_in_new_space_++;
2795 }
2796
2797 void increment_nodes_promoted() {
2798 nodes_promoted_++;
2799 }
2800
kasper.lund7276f142008-07-30 08:49:36 +00002801 private:
2802 // Returns a string matching the collector.
2803 const char* CollectorString();
2804
2805 // Returns size of object in heap (in MB).
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002806 inline double SizeOfHeapObjects();
kasper.lund7276f142008-07-30 08:49:36 +00002807
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +00002808 // Timestamp set in the constructor.
2809 double start_time_;
2810
2811 // Size of objects in heap set in constructor.
2812 intptr_t start_object_size_;
2813
2814 // Size of memory allocated from OS set in constructor.
2815 intptr_t start_memory_size_;
2816
2817 // Type of collector.
2818 GarbageCollector collector_;
kasper.lund7276f142008-07-30 08:49:36 +00002819
ulan@chromium.org2efb9002012-01-19 15:36:35 +00002820 // A count (including this one, e.g. the first collection is 1) of the
kasper.lund7276f142008-07-30 08:49:36 +00002821 // number of garbage collections.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002822 unsigned int gc_count_;
kasper.lund7276f142008-07-30 08:49:36 +00002823
2824 // A count (including this one) of the number of full garbage collections.
2825 int full_gc_count_;
2826
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002827 // Amounts of time spent in different scopes during GC.
2828 double scopes_[Scope::kNumberOfScopes];
2829
2830 // Total amount of space either wasted or contained in one of free lists
2831 // before the current GC.
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002832 intptr_t in_free_list_or_wasted_before_gc_;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002833
2834 // Difference between space used in the heap at the beginning of the current
2835 // collection and the end of the previous collection.
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002836 intptr_t allocated_since_last_gc_;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002837
2838 // Amount of time spent in mutator that is time elapsed between end of the
2839 // previous collection and the beginning of the current one.
2840 double spent_in_mutator_;
2841
2842 // Size of objects promoted during the current collection.
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +00002843 intptr_t promoted_objects_size_;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002844
rossberg@chromium.orgcddc71f2012-12-07 12:40:13 +00002845 // Number of died nodes in the new space.
2846 int nodes_died_in_new_space_;
2847
2848 // Number of copied nodes to the new space.
2849 int nodes_copied_in_new_space_;
2850
2851 // Number of promoted nodes to the old space.
2852 int nodes_promoted_;
2853
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002854 // Incremental marking steps counters.
2855 int steps_count_;
2856 double steps_took_;
2857 double longest_step_;
2858 int steps_count_since_last_gc_;
2859 double steps_took_since_last_gc_;
2860
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002861 Heap* heap_;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002862
2863 const char* gc_reason_;
2864 const char* collector_reason_;
kasper.lund7276f142008-07-30 08:49:36 +00002865};
2866
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002867
jkummerow@chromium.org78502a92012-09-06 13:50:42 +00002868class RegExpResultsCache {
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002869 public:
jkummerow@chromium.org78502a92012-09-06 13:50:42 +00002870 enum ResultsCacheType { REGEXP_MULTIPLE_INDICES, STRING_SPLIT_SUBSTRINGS };
2871
2872 // Attempt to retrieve a cached result. On failure, 0 is returned as a Smi.
2873 // On success, the returned result is guaranteed to be a COW-array.
2874 static Object* Lookup(Heap* heap,
2875 String* key_string,
2876 Object* key_pattern,
2877 ResultsCacheType type);
2878 // Attempt to add value_array to the cache specified by type. On success,
2879 // value_array is turned into a COW-array.
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002880 static void Enter(Heap* heap,
jkummerow@chromium.org78502a92012-09-06 13:50:42 +00002881 String* key_string,
2882 Object* key_pattern,
2883 FixedArray* value_array,
2884 ResultsCacheType type);
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002885 static void Clear(FixedArray* cache);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +00002886 static const int kRegExpResultsCacheSize = 0x100;
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002887
2888 private:
2889 static const int kArrayEntriesPerCacheEntry = 4;
2890 static const int kStringOffset = 0;
2891 static const int kPatternOffset = 1;
2892 static const int kArrayOffset = 2;
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002893};
2894
2895
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002896class TranscendentalCache {
2897 public:
2898 enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches};
whesse@chromium.org023421e2010-12-21 12:19:12 +00002899 static const int kTranscendentalTypeBits = 3;
2900 STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches);
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002901
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002902 // Returns a heap number with f(input), where f is a math function specified
2903 // by the 'type' argument.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002904 MUST_USE_RESULT inline MaybeObject* Get(Type type, double input);
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002905
2906 // The cache contains raw Object pointers. This method disposes of
2907 // them before a garbage collection.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002908 void Clear();
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002909
2910 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002911 class SubCache {
2912 static const int kCacheSize = 512;
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002913
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002914 explicit SubCache(Type t);
2915
2916 MUST_USE_RESULT inline MaybeObject* Get(double input);
2917
2918 inline double Calculate(double input);
2919
2920 struct Element {
2921 uint32_t in[2];
2922 Object* output;
2923 };
2924
2925 union Converter {
2926 double dbl;
2927 uint32_t integers[2];
2928 };
2929
2930 inline static int Hash(const Converter& c) {
2931 uint32_t hash = (c.integers[0] ^ c.integers[1]);
2932 hash ^= static_cast<int32_t>(hash) >> 16;
2933 hash ^= static_cast<int32_t>(hash) >> 8;
2934 return (hash & (kCacheSize - 1));
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002935 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002936
2937 Element elements_[kCacheSize];
2938 Type type_;
2939 Isolate* isolate_;
2940
2941 // Allow access to the caches_ array as an ExternalReference.
2942 friend class ExternalReference;
2943 // Inline implementation of the cache.
2944 friend class TranscendentalCacheStub;
2945 // For evaluating value.
2946 friend class TranscendentalCache;
2947
2948 DISALLOW_COPY_AND_ASSIGN(SubCache);
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002949 };
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002950
2951 TranscendentalCache() {
2952 for (int i = 0; i < kNumberOfCaches; ++i) caches_[i] = NULL;
ager@chromium.org18ad94b2009-09-02 08:22:29 +00002953 }
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002954
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002955 // Used to create an external reference.
2956 inline Address cache_array_address();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002957
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002958 // Instantiation
2959 friend class Isolate;
2960 // Inline implementation of the caching.
2961 friend class TranscendentalCacheStub;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002962 // Allow access to the caches_ array as an ExternalReference.
2963 friend class ExternalReference;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002964
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002965 SubCache* caches_[kNumberOfCaches];
2966 DISALLOW_COPY_AND_ASSIGN(TranscendentalCache);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +00002967};
2968
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002969
2970// Abstract base class for checking whether a weak object should be retained.
2971class WeakObjectRetainer {
2972 public:
2973 virtual ~WeakObjectRetainer() {}
2974
2975 // Return whether this object should be retained. If NULL is returned the
2976 // object has no references. Otherwise the address of the retained object
2977 // should be returned as in some GC situations the object has been moved.
2978 virtual Object* RetainAs(Object* object) = 0;
2979};
2980
2981
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002982// Intrusive object marking uses least significant bit of
2983// heap object's map word to mark objects.
2984// Normally all map words have least significant bit set
2985// because they contain tagged map pointer.
2986// If the bit is not set object is marked.
2987// All objects should be unmarked before resuming
2988// JavaScript execution.
2989class IntrusiveMarking {
2990 public:
2991 static bool IsMarked(HeapObject* object) {
2992 return (object->map_word().ToRawValue() & kNotMarkedBit) == 0;
2993 }
2994
2995 static void ClearMark(HeapObject* object) {
2996 uintptr_t map_word = object->map_word().ToRawValue();
2997 object->set_map_word(MapWord::FromRawValue(map_word | kNotMarkedBit));
2998 ASSERT(!IsMarked(object));
2999 }
3000
3001 static void SetMark(HeapObject* object) {
3002 uintptr_t map_word = object->map_word().ToRawValue();
3003 object->set_map_word(MapWord::FromRawValue(map_word & ~kNotMarkedBit));
3004 ASSERT(IsMarked(object));
3005 }
3006
3007 static Map* MapOfMarkedObject(HeapObject* object) {
3008 uintptr_t map_word = object->map_word().ToRawValue();
3009 return MapWord::FromRawValue(map_word | kNotMarkedBit).ToMap();
3010 }
3011
3012 static int SizeOfMarkedObject(HeapObject* object) {
3013 return object->SizeFromMap(MapOfMarkedObject(object));
3014 }
3015
3016 private:
3017 static const uintptr_t kNotMarkedBit = 0x1;
3018 STATIC_ASSERT((kHeapObjectTag & kNotMarkedBit) != 0);
3019};
3020
3021
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003022#ifdef DEBUG
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003023// Helper class for tracing paths to a search target Object from all roots.
3024// The TracePathFrom() method can be used to trace paths from a specific
3025// object to the search target object.
3026class PathTracer : public ObjectVisitor {
3027 public:
3028 enum WhatToFind {
3029 FIND_ALL, // Will find all matches.
3030 FIND_FIRST // Will stop the search after first match.
3031 };
3032
3033 // For the WhatToFind arg, if FIND_FIRST is specified, tracing will stop
3034 // after the first match. If FIND_ALL is specified, then tracing will be
3035 // done for all matches.
3036 PathTracer(Object* search_target,
3037 WhatToFind what_to_find,
3038 VisitMode visit_mode)
3039 : search_target_(search_target),
3040 found_target_(false),
3041 found_target_in_trace_(false),
3042 what_to_find_(what_to_find),
3043 visit_mode_(visit_mode),
3044 object_stack_(20),
rossberg@chromium.org79e79022013-06-03 15:43:46 +00003045 no_allocation() {}
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046
3047 virtual void VisitPointers(Object** start, Object** end);
3048
3049 void Reset();
3050 void TracePathFrom(Object** root);
3051
3052 bool found() const { return found_target_; }
3053
3054 static Object* const kAnyGlobalObject;
3055
3056 protected:
3057 class MarkVisitor;
3058 class UnmarkVisitor;
3059
3060 void MarkRecursively(Object** p, MarkVisitor* mark_visitor);
3061 void UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor);
3062 virtual void ProcessResults();
3063
3064 // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject.
3065 static const int kMarkTag = 2;
3066
3067 Object* search_target_;
3068 bool found_target_;
3069 bool found_target_in_trace_;
3070 WhatToFind what_to_find_;
3071 VisitMode visit_mode_;
3072 List<Object*> object_stack_;
3073
rossberg@chromium.org79e79022013-06-03 15:43:46 +00003074 DisallowHeapAllocation no_allocation; // i.e. no gc allowed.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003075
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00003076 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer);
3078};
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003079#endif // DEBUG
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081} } // namespace v8::internal
3082
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003083#endif // V8_HEAP_H_