1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_HEAP_H_ 29 #define V8_HEAP_H_ 30 31 #include <math.h> 32 33 #include "zone-inl.h" 34 35 36 namespace v8 { 37 namespace internal { 38 39 // Defines all the roots in Heap. 40 #define UNCONDITIONAL_STRONG_ROOT_LIST(V) \ 41 /* Put the byte array map early. We need it to be in place by the time */ \ 42 /* the deserializer hits the next page, since it wants to put a byte */ \ 43 /* array in the unused space at the end of the page. */ \ 44 V(Map, byte_array_map, ByteArrayMap) \ 45 V(Map, one_pointer_filler_map, OnePointerFillerMap) \ 46 V(Map, two_pointer_filler_map, TwoPointerFillerMap) \ 47 /* Cluster the most popular ones in a few cache lines here at the top. */ \ 48 V(Smi, stack_limit, StackLimit) \ 49 V(Object, undefined_value, UndefinedValue) \ 50 V(Object, the_hole_value, TheHoleValue) \ 51 V(Object, null_value, NullValue) \ 52 V(Object, true_value, TrueValue) \ 53 V(Object, false_value, FalseValue) \ 54 V(Map, heap_number_map, HeapNumberMap) \ 55 V(Map, global_context_map, GlobalContextMap) \ 56 V(Map, fixed_array_map, FixedArrayMap) \ 57 V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel) \ 58 V(Map, meta_map, MetaMap) \ 59 V(Object, termination_exception, TerminationException) \ 60 V(Map, hash_table_map, HashTableMap) \ 61 V(FixedArray, empty_fixed_array, EmptyFixedArray) \ 62 V(Map, string_map, StringMap) \ 63 V(Map, ascii_string_map, AsciiStringMap) \ 64 V(Map, symbol_map, SymbolMap) \ 65 V(Map, ascii_symbol_map, AsciiSymbolMap) \ 66 V(Map, cons_symbol_map, ConsSymbolMap) \ 67 V(Map, cons_ascii_symbol_map, ConsAsciiSymbolMap) \ 68 V(Map, external_symbol_map, ExternalSymbolMap) \ 69 V(Map, external_ascii_symbol_map, ExternalAsciiSymbolMap) \ 70 V(Map, cons_string_map, ConsStringMap) \ 71 V(Map, cons_ascii_string_map, ConsAsciiStringMap) \ 72 V(Map, external_string_map, ExternalStringMap) \ 73 V(Map, external_ascii_string_map, ExternalAsciiStringMap) \ 74 V(Map, undetectable_string_map, UndetectableStringMap) \ 75 V(Map, undetectable_ascii_string_map, UndetectableAsciiStringMap) \ 76 V(Map, pixel_array_map, PixelArrayMap) \ 77 V(Map, external_byte_array_map, ExternalByteArrayMap) \ 78 V(Map, external_unsigned_byte_array_map, ExternalUnsignedByteArrayMap) \ 79 V(Map, external_short_array_map, ExternalShortArrayMap) \ 80 V(Map, external_unsigned_short_array_map, ExternalUnsignedShortArrayMap) \ 81 V(Map, external_int_array_map, ExternalIntArrayMap) \ 82 V(Map, external_unsigned_int_array_map, ExternalUnsignedIntArrayMap) \ 83 V(Map, external_float_array_map, ExternalFloatArrayMap) \ 84 V(Map, context_map, ContextMap) \ 85 V(Map, catch_context_map, CatchContextMap) \ 86 V(Map, code_map, CodeMap) \ 87 V(Map, oddball_map, OddballMap) \ 88 V(Map, global_property_cell_map, GlobalPropertyCellMap) \ 89 V(Map, boilerplate_function_map, BoilerplateFunctionMap) \ 90 V(Map, shared_function_info_map, SharedFunctionInfoMap) \ 91 V(Map, proxy_map, ProxyMap) \ 92 V(Object, nan_value, NanValue) \ 93 V(Object, minus_zero_value, MinusZeroValue) \ 94 V(String, empty_string, EmptyString) \ 95 V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \ 96 V(Map, neander_map, NeanderMap) \ 97 V(JSObject, message_listeners, MessageListeners) \ 98 V(Proxy, prototype_accessors, PrototypeAccessors) \ 99 V(NumberDictionary, code_stubs, CodeStubs) \ 100 V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \ 101 V(Code, js_entry_code, JsEntryCode) \ 102 V(Code, js_construct_entry_code, JsConstructEntryCode) \ 103 V(Code, c_entry_code, CEntryCode) \ 104 V(FixedArray, number_string_cache, NumberStringCache) \ 105 V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ 106 V(FixedArray, natives_source_cache, NativesSourceCache) \ 107 V(Object, last_script_id, LastScriptId) \ 108 V(Script, empty_script, EmptyScript) \ 109 V(Smi, real_stack_limit, RealStackLimit) \ 110 111 #if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP 112 #define STRONG_ROOT_LIST(V) \ 113 UNCONDITIONAL_STRONG_ROOT_LIST(V) \ 114 V(Code, re_c_entry_code, RegExpCEntryCode) 115 #else 116 #define STRONG_ROOT_LIST(V) UNCONDITIONAL_STRONG_ROOT_LIST(V) 117 #endif 118 119 #define ROOT_LIST(V) \ 120 STRONG_ROOT_LIST(V) \ 121 V(SymbolTable, symbol_table, SymbolTable) 122 123 #define SYMBOL_LIST(V) \ 124 V(Array_symbol, "Array") \ 125 V(Object_symbol, "Object") \ 126 V(Proto_symbol, "__proto__") \ 127 V(StringImpl_symbol, "StringImpl") \ 128 V(arguments_symbol, "arguments") \ 129 V(Arguments_symbol, "Arguments") \ 130 V(arguments_shadow_symbol, ".arguments") \ 131 V(call_symbol, "call") \ 132 V(apply_symbol, "apply") \ 133 V(caller_symbol, "caller") \ 134 V(boolean_symbol, "boolean") \ 135 V(Boolean_symbol, "Boolean") \ 136 V(callee_symbol, "callee") \ 137 V(constructor_symbol, "constructor") \ 138 V(code_symbol, ".code") \ 139 V(result_symbol, ".result") \ 140 V(catch_var_symbol, ".catch-var") \ 141 V(empty_symbol, "") \ 142 V(eval_symbol, "eval") \ 143 V(function_symbol, "function") \ 144 V(length_symbol, "length") \ 145 V(name_symbol, "name") \ 146 V(number_symbol, "number") \ 147 V(Number_symbol, "Number") \ 148 V(RegExp_symbol, "RegExp") \ 149 V(object_symbol, "object") \ 150 V(prototype_symbol, "prototype") \ 151 V(string_symbol, "string") \ 152 V(String_symbol, "String") \ 153 V(Date_symbol, "Date") \ 154 V(this_symbol, "this") \ 155 V(to_string_symbol, "toString") \ 156 V(char_at_symbol, "CharAt") \ 157 V(undefined_symbol, "undefined") \ 158 V(value_of_symbol, "valueOf") \ 159 V(InitializeVarGlobal_symbol, "InitializeVarGlobal") \ 160 V(InitializeConstGlobal_symbol, "InitializeConstGlobal") \ 161 V(stack_overflow_symbol, "kStackOverflowBoilerplate") \ 162 V(illegal_access_symbol, "illegal access") \ 163 V(out_of_memory_symbol, "out-of-memory") \ 164 V(illegal_execution_state_symbol, "illegal execution state") \ 165 V(get_symbol, "get") \ 166 V(set_symbol, "set") \ 167 V(function_class_symbol, "Function") \ 168 V(illegal_argument_symbol, "illegal argument") \ 169 V(MakeReferenceError_symbol, "MakeReferenceError") \ 170 V(MakeSyntaxError_symbol, "MakeSyntaxError") \ 171 V(MakeTypeError_symbol, "MakeTypeError") \ 172 V(invalid_lhs_in_assignment_symbol, "invalid_lhs_in_assignment") \ 173 V(invalid_lhs_in_for_in_symbol, "invalid_lhs_in_for_in") \ 174 V(invalid_lhs_in_postfix_op_symbol, "invalid_lhs_in_postfix_op") \ 175 V(invalid_lhs_in_prefix_op_symbol, "invalid_lhs_in_prefix_op") \ 176 V(illegal_return_symbol, "illegal_return") \ 177 V(illegal_break_symbol, "illegal_break") \ 178 V(illegal_continue_symbol, "illegal_continue") \ 179 V(unknown_label_symbol, "unknown_label") \ 180 V(redeclaration_symbol, "redeclaration") \ 181 V(failure_symbol, "<failure>") \ 182 V(space_symbol, " ") \ 183 V(exec_symbol, "exec") \ 184 V(zero_symbol, "0") \ 185 V(global_eval_symbol, "GlobalEval") \ 186 V(identity_hash_symbol, "v8::IdentityHash") \ 187 V(closure_symbol, "(closure)") 188 189 190 // Forward declaration of the GCTracer class. 191 class GCTracer; 192 class HeapStats; 193 194 195 // The all static Heap captures the interface to the global object heap. 196 // All JavaScript contexts by this process share the same object heap. 197 198 class Heap : public AllStatic { 199 public: 200 // Configure heap size before setup. Return false if the heap has been 201 // setup already. 202 static bool ConfigureHeap(int max_semispace_size, int max_old_gen_size); 203 static bool ConfigureHeapDefault(); 204 205 // Initializes the global object heap. If create_heap_objects is true, 206 // also creates the basic non-mutable objects. 207 // Returns whether it succeeded. 208 static bool Setup(bool create_heap_objects); 209 210 // Destroys all memory allocated by the heap. 211 static void TearDown(); 212 213 // Set the stack limit in the roots_ array. Some architectures generate 214 // code that looks here, because it is faster than loading from the static 215 // jslimit_/real_jslimit_ variable in the StackGuard. 216 static void SetStackLimits(); 217 218 // Returns whether Setup has been called. 219 static bool HasBeenSetup(); 220 221 // Returns the maximum amount of memory reserved for the heap. For 222 // the young generation, we reserve 4 times the amount needed for a 223 // semi space. The young generation consists of two semi spaces and 224 // we reserve twice the amount needed for those in order to ensure 225 // that new space can be aligned to its size. MaxReserved()226 static int MaxReserved() { 227 return 4 * reserved_semispace_size_ + max_old_generation_size_; 228 } MaxSemiSpaceSize()229 static int MaxSemiSpaceSize() { return max_semispace_size_; } ReservedSemiSpaceSize()230 static int ReservedSemiSpaceSize() { return reserved_semispace_size_; } InitialSemiSpaceSize()231 static int InitialSemiSpaceSize() { return initial_semispace_size_; } MaxOldGenerationSize()232 static int MaxOldGenerationSize() { return max_old_generation_size_; } 233 234 // Returns the capacity of the heap in bytes w/o growing. Heap grows when 235 // more spaces are needed until it reaches the limit. 236 static int Capacity(); 237 238 // Returns the amount of memory currently committed for the heap. 239 static int CommittedMemory(); 240 241 // Returns the available bytes in space w/o growing. 242 // Heap doesn't guarantee that it can allocate an object that requires 243 // all available bytes. Check MaxHeapObjectSize() instead. 244 static int Available(); 245 246 // Returns the maximum object size in paged space. 247 static inline int MaxObjectSizeInPagedSpace(); 248 249 // Returns of size of all objects residing in the heap. 250 static int SizeOfObjects(); 251 252 // Return the starting address and a mask for the new space. And-masking an 253 // address with the mask will result in the start address of the new space 254 // for all addresses in either semispace. NewSpaceStart()255 static Address NewSpaceStart() { return new_space_.start(); } NewSpaceMask()256 static uintptr_t NewSpaceMask() { return new_space_.mask(); } NewSpaceTop()257 static Address NewSpaceTop() { return new_space_.top(); } 258 new_space()259 static NewSpace* new_space() { return &new_space_; } old_pointer_space()260 static OldSpace* old_pointer_space() { return old_pointer_space_; } old_data_space()261 static OldSpace* old_data_space() { return old_data_space_; } code_space()262 static OldSpace* code_space() { return code_space_; } map_space()263 static MapSpace* map_space() { return map_space_; } cell_space()264 static CellSpace* cell_space() { return cell_space_; } lo_space()265 static LargeObjectSpace* lo_space() { return lo_space_; } 266 always_allocate()267 static bool always_allocate() { return always_allocate_scope_depth_ != 0; } always_allocate_scope_depth_address()268 static Address always_allocate_scope_depth_address() { 269 return reinterpret_cast<Address>(&always_allocate_scope_depth_); 270 } linear_allocation()271 static bool linear_allocation() { 272 return linear_allocation_scope_depth_ != 0; 273 } 274 NewSpaceAllocationTopAddress()275 static Address* NewSpaceAllocationTopAddress() { 276 return new_space_.allocation_top_address(); 277 } NewSpaceAllocationLimitAddress()278 static Address* NewSpaceAllocationLimitAddress() { 279 return new_space_.allocation_limit_address(); 280 } 281 282 // Uncommit unused semi space. UncommitFromSpace()283 static bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); } 284 285 #ifdef ENABLE_HEAP_PROTECTION 286 // Protect/unprotect the heap by marking all spaces read-only/writable. 287 static void Protect(); 288 static void Unprotect(); 289 #endif 290 291 // Allocates and initializes a new JavaScript object based on a 292 // constructor. 293 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 294 // failed. 295 // Please note this does not perform a garbage collection. 296 static Object* AllocateJSObject(JSFunction* constructor, 297 PretenureFlag pretenure = NOT_TENURED); 298 299 // Allocates and initializes a new global object based on a constructor. 300 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 301 // failed. 302 // Please note this does not perform a garbage collection. 303 static Object* AllocateGlobalObject(JSFunction* constructor); 304 305 // Returns a deep copy of the JavaScript object. 306 // Properties and elements are copied too. 307 // Returns failure if allocation failed. 308 static Object* CopyJSObject(JSObject* source); 309 310 // Allocates the function prototype. 311 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 312 // failed. 313 // Please note this does not perform a garbage collection. 314 static Object* AllocateFunctionPrototype(JSFunction* function); 315 316 // Reinitialize an JSGlobalProxy based on a constructor. The object 317 // must have the same size as objects allocated using the 318 // constructor. The object is reinitialized and behaves as an 319 // object that has been freshly allocated using the constructor. 320 static Object* ReinitializeJSGlobalProxy(JSFunction* constructor, 321 JSGlobalProxy* global); 322 323 // Allocates and initializes a new JavaScript object based on a map. 324 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 325 // failed. 326 // Please note this does not perform a garbage collection. 327 static Object* AllocateJSObjectFromMap(Map* map, 328 PretenureFlag pretenure = NOT_TENURED); 329 330 // Allocates a heap object based on the map. 331 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 332 // failed. 333 // Please note this function does not perform a garbage collection. 334 static Object* Allocate(Map* map, AllocationSpace space); 335 336 // Allocates a JS Map in the heap. 337 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 338 // failed. 339 // Please note this function does not perform a garbage collection. 340 static Object* AllocateMap(InstanceType instance_type, int instance_size); 341 342 // Allocates a partial map for bootstrapping. 343 static Object* AllocatePartialMap(InstanceType instance_type, 344 int instance_size); 345 346 // Allocate a map for the specified function 347 static Object* AllocateInitialMap(JSFunction* fun); 348 349 // Allocates and fully initializes a String. There are two String 350 // encodings: ASCII and two byte. One should choose between the three string 351 // allocation functions based on the encoding of the string buffer used to 352 // initialized the string. 353 // - ...FromAscii initializes the string from a buffer that is ASCII 354 // encoded (it does not check that the buffer is ASCII encoded) and the 355 // result will be ASCII encoded. 356 // - ...FromUTF8 initializes the string from a buffer that is UTF-8 357 // encoded. If the characters are all single-byte characters, the 358 // result will be ASCII encoded, otherwise it will converted to two 359 // byte. 360 // - ...FromTwoByte initializes the string from a buffer that is two-byte 361 // encoded. If the characters are all single-byte characters, the 362 // result will be converted to ASCII, otherwise it will be left as 363 // two-byte. 364 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 365 // failed. 366 // Please note this does not perform a garbage collection. 367 static Object* AllocateStringFromAscii( 368 Vector<const char> str, 369 PretenureFlag pretenure = NOT_TENURED); 370 static Object* AllocateStringFromUtf8( 371 Vector<const char> str, 372 PretenureFlag pretenure = NOT_TENURED); 373 static Object* AllocateStringFromTwoByte( 374 Vector<const uc16> str, 375 PretenureFlag pretenure = NOT_TENURED); 376 377 // Allocates a symbol in old space based on the character stream. 378 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 379 // failed. 380 // Please note this function does not perform a garbage collection. 381 static inline Object* AllocateSymbol(Vector<const char> str, 382 int chars, 383 uint32_t hash_field); 384 385 static Object* AllocateInternalSymbol(unibrow::CharacterStream* buffer, 386 int chars, 387 uint32_t hash_field); 388 389 static Object* AllocateExternalSymbol(Vector<const char> str, 390 int chars); 391 392 393 // Allocates and partially initializes a String. There are two String 394 // encodings: ASCII and two byte. These functions allocate a string of the 395 // given length and set its map and length fields. The characters of the 396 // string are uninitialized. 397 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 398 // failed. 399 // Please note this does not perform a garbage collection. 400 static Object* AllocateRawAsciiString( 401 int length, 402 PretenureFlag pretenure = NOT_TENURED); 403 static Object* AllocateRawTwoByteString( 404 int length, 405 PretenureFlag pretenure = NOT_TENURED); 406 407 // Computes a single character string where the character has code. 408 // A cache is used for ascii codes. 409 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 410 // failed. Please note this does not perform a garbage collection. 411 static Object* LookupSingleCharacterStringFromCode(uint16_t code); 412 413 // Allocate a byte array of the specified length 414 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 415 // failed. 416 // Please note this does not perform a garbage collection. 417 static Object* AllocateByteArray(int length, PretenureFlag pretenure); 418 419 // Allocate a non-tenured byte array of the specified length 420 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 421 // failed. 422 // Please note this does not perform a garbage collection. 423 static Object* AllocateByteArray(int length); 424 425 // Allocate a pixel array of the specified length 426 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 427 // failed. 428 // Please note this does not perform a garbage collection. 429 static Object* AllocatePixelArray(int length, 430 uint8_t* external_pointer, 431 PretenureFlag pretenure); 432 433 // Allocates an external array of the specified length and type. 434 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 435 // failed. 436 // Please note this does not perform a garbage collection. 437 static Object* AllocateExternalArray(int length, 438 ExternalArrayType array_type, 439 void* external_pointer, 440 PretenureFlag pretenure); 441 442 // Allocate a tenured JS global property cell. 443 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 444 // failed. 445 // Please note this does not perform a garbage collection. 446 static Object* AllocateJSGlobalPropertyCell(Object* value); 447 448 // Allocates a fixed array initialized with undefined values 449 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 450 // failed. 451 // Please note this does not perform a garbage collection. 452 static Object* AllocateFixedArray(int length, PretenureFlag pretenure); 453 // Allocate uninitialized, non-tenured fixed array with length elements. 454 static Object* AllocateFixedArray(int length); 455 456 // Make a copy of src and return it. Returns 457 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed. 458 static Object* CopyFixedArray(FixedArray* src); 459 460 // Allocates a fixed array initialized with the hole values. 461 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 462 // failed. 463 // Please note this does not perform a garbage collection. 464 static Object* AllocateFixedArrayWithHoles(int length); 465 466 // AllocateHashTable is identical to AllocateFixedArray except 467 // that the resulting object has hash_table_map as map. 468 static Object* AllocateHashTable(int length); 469 470 // Allocate a global (but otherwise uninitialized) context. 471 static Object* AllocateGlobalContext(); 472 473 // Allocate a function context. 474 static Object* AllocateFunctionContext(int length, JSFunction* closure); 475 476 // Allocate a 'with' context. 477 static Object* AllocateWithContext(Context* previous, 478 JSObject* extension, 479 bool is_catch_context); 480 481 // Allocates a new utility object in the old generation. 482 static Object* AllocateStruct(InstanceType type); 483 484 // Allocates a function initialized with a shared part. 485 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 486 // failed. 487 // Please note this does not perform a garbage collection. 488 static Object* AllocateFunction(Map* function_map, 489 SharedFunctionInfo* shared, 490 Object* prototype, 491 PretenureFlag pretenure = TENURED); 492 493 // Indicies for direct access into argument objects. 494 static const int kArgumentsObjectSize = 495 JSObject::kHeaderSize + 2 * kPointerSize; 496 static const int arguments_callee_index = 0; 497 static const int arguments_length_index = 1; 498 499 // Allocates an arguments object - optionally with an elements array. 500 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 501 // failed. 502 // Please note this does not perform a garbage collection. 503 static Object* AllocateArgumentsObject(Object* callee, int length); 504 505 // Converts a double into either a Smi or a HeapNumber object. 506 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 507 // failed. 508 // Please note this does not perform a garbage collection. 509 static Object* NewNumberFromDouble(double value, 510 PretenureFlag pretenure = NOT_TENURED); 511 512 // Same as NewNumberFromDouble, but may return a preallocated/immutable 513 // number object (e.g., minus_zero_value_, nan_value_) 514 static Object* NumberFromDouble(double value, 515 PretenureFlag pretenure = NOT_TENURED); 516 517 // Allocated a HeapNumber from value. 518 static Object* AllocateHeapNumber(double value, PretenureFlag pretenure); 519 static Object* AllocateHeapNumber(double value); // pretenure = NOT_TENURED 520 521 // Converts an int into either a Smi or a HeapNumber object. 522 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 523 // failed. 524 // Please note this does not perform a garbage collection. 525 static inline Object* NumberFromInt32(int32_t value); 526 527 // Converts an int into either a Smi or a HeapNumber object. 528 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 529 // failed. 530 // Please note this does not perform a garbage collection. 531 static inline Object* NumberFromUint32(uint32_t value); 532 533 // Allocates a new proxy object. 534 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 535 // failed. 536 // Please note this does not perform a garbage collection. 537 static Object* AllocateProxy(Address proxy, 538 PretenureFlag pretenure = NOT_TENURED); 539 540 // Allocates a new SharedFunctionInfo object. 541 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 542 // failed. 543 // Please note this does not perform a garbage collection. 544 static Object* AllocateSharedFunctionInfo(Object* name); 545 546 // Allocates a new cons string object. 547 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 548 // failed. 549 // Please note this does not perform a garbage collection. 550 static Object* AllocateConsString(String* first, String* second); 551 552 // Allocates a new sub string object which is a substring of an underlying 553 // string buffer stretching from the index start (inclusive) to the index 554 // end (exclusive). 555 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 556 // failed. 557 // Please note this does not perform a garbage collection. 558 static Object* AllocateSubString(String* buffer, 559 int start, 560 int end); 561 562 // Allocate a new external string object, which is backed by a string 563 // resource that resides outside the V8 heap. 564 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 565 // failed. 566 // Please note this does not perform a garbage collection. 567 static Object* AllocateExternalStringFromAscii( 568 ExternalAsciiString::Resource* resource); 569 static Object* AllocateExternalStringFromTwoByte( 570 ExternalTwoByteString::Resource* resource); 571 572 // Finalizes an external string by deleting the associated external 573 // data and clearing the resource pointer. 574 static inline void FinalizeExternalString(String* string); 575 576 // Allocates an uninitialized object. The memory is non-executable if the 577 // hardware and OS allow. 578 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 579 // failed. 580 // Please note this function does not perform a garbage collection. 581 static inline Object* AllocateRaw(int size_in_bytes, 582 AllocationSpace space, 583 AllocationSpace retry_space); 584 585 // Initialize a filler object to keep the ability to iterate over the heap 586 // when shortening objects. 587 static void CreateFillerObjectAt(Address addr, int size); 588 589 // Makes a new native code object 590 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 591 // failed. On success, the pointer to the Code object is stored in the 592 // self_reference. This allows generated code to reference its own Code 593 // object by containing this pointer. 594 // Please note this function does not perform a garbage collection. 595 static Object* CreateCode(const CodeDesc& desc, 596 ZoneScopeInfo* sinfo, 597 Code::Flags flags, 598 Handle<Object> self_reference); 599 600 static Object* CopyCode(Code* code); 601 // Finds the symbol for string in the symbol table. 602 // If not found, a new symbol is added to the table and returned. 603 // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation 604 // failed. 605 // Please note this function does not perform a garbage collection. 606 static Object* LookupSymbol(Vector<const char> str); LookupAsciiSymbol(const char * str)607 static Object* LookupAsciiSymbol(const char* str) { 608 return LookupSymbol(CStrVector(str)); 609 } 610 static Object* LookupSymbol(String* str); 611 static bool LookupSymbolIfExists(String* str, String** symbol); 612 static bool LookupTwoCharsSymbolIfExists(String* str, String** symbol); 613 614 // Compute the matching symbol map for a string if possible. 615 // NULL is returned if string is in new space or not flattened. 616 static Map* SymbolMapForString(String* str); 617 618 // Converts the given boolean condition to JavaScript boolean value. ToBoolean(bool condition)619 static Object* ToBoolean(bool condition) { 620 return condition ? true_value() : false_value(); 621 } 622 623 // Code that should be run before and after each GC. Includes some 624 // reporting/verification activities when compiled with DEBUG set. 625 static void GarbageCollectionPrologue(); 626 static void GarbageCollectionEpilogue(); 627 628 // Performs garbage collection operation. 629 // Returns whether required_space bytes are available after the collection. 630 static bool CollectGarbage(int required_space, AllocationSpace space); 631 632 // Performs a full garbage collection. Force compaction if the 633 // parameter is true. 634 static void CollectAllGarbage(bool force_compaction); 635 636 // Performs a full garbage collection if a context has been disposed 637 // since the last time the check was performed. 638 static void CollectAllGarbageIfContextDisposed(); 639 640 // Notify the heap that a context has been disposed. 641 static void NotifyContextDisposed(); 642 643 // Utility to invoke the scavenger. This is needed in test code to 644 // ensure correct callback for weak global handles. 645 static void PerformScavenge(); 646 647 #ifdef DEBUG 648 // Utility used with flag gc-greedy. 649 static bool GarbageCollectionGreedyCheck(); 650 #endif 651 SetGlobalGCPrologueCallback(GCCallback callback)652 static void SetGlobalGCPrologueCallback(GCCallback callback) { 653 global_gc_prologue_callback_ = callback; 654 } SetGlobalGCEpilogueCallback(GCCallback callback)655 static void SetGlobalGCEpilogueCallback(GCCallback callback) { 656 global_gc_epilogue_callback_ = callback; 657 } 658 659 // Heap root getters. We have versions with and without type::cast() here. 660 // You can't use type::cast during GC because the assert fails. 661 #define ROOT_ACCESSOR(type, name, camel_name) \ 662 static inline type* name() { \ 663 return type::cast(roots_[k##camel_name##RootIndex]); \ 664 } \ 665 static inline type* raw_unchecked_##name() { \ 666 return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \ 667 } 668 ROOT_LIST(ROOT_ACCESSOR) 669 #undef ROOT_ACCESSOR 670 671 // Utility type maps 672 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) \ 673 static inline Map* name##_map() { \ 674 return Map::cast(roots_[k##Name##MapRootIndex]); \ 675 } STRUCT_LIST(STRUCT_MAP_ACCESSOR)676 STRUCT_LIST(STRUCT_MAP_ACCESSOR) 677 #undef STRUCT_MAP_ACCESSOR 678 679 #define SYMBOL_ACCESSOR(name, str) static inline String* name() { \ 680 return String::cast(roots_[k##name##RootIndex]); \ 681 } 682 SYMBOL_LIST(SYMBOL_ACCESSOR) 683 #undef SYMBOL_ACCESSOR 684 685 // The hidden_symbol is special because it is the empty string, but does 686 // not match the empty string. 687 static String* hidden_symbol() { return hidden_symbol_; } 688 689 // Iterates over all roots in the heap. 690 static void IterateRoots(ObjectVisitor* v, VisitMode mode); 691 // Iterates over all strong roots in the heap. 692 static void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); 693 // Iterates over all the other roots in the heap. 694 static void IterateWeakRoots(ObjectVisitor* v, VisitMode mode); 695 696 // Iterates remembered set of an old space. 697 static void IterateRSet(PagedSpace* space, ObjectSlotCallback callback); 698 699 // Iterates a range of remembered set addresses starting with rset_start 700 // corresponding to the range of allocated pointers 701 // [object_start, object_end). 702 // Returns the number of bits that were set. 703 static int IterateRSetRange(Address object_start, 704 Address object_end, 705 Address rset_start, 706 ObjectSlotCallback copy_object_func); 707 708 // Returns whether the object resides in new space. 709 static inline bool InNewSpace(Object* object); 710 static inline bool InFromSpace(Object* object); 711 static inline bool InToSpace(Object* object); 712 713 // Checks whether an address/object in the heap (including auxiliary 714 // area and unused area). 715 static bool Contains(Address addr); 716 static bool Contains(HeapObject* value); 717 718 // Checks whether an address/object in a space. 719 // Currently used by tests, serialization and heap verification only. 720 static bool InSpace(Address addr, AllocationSpace space); 721 static bool InSpace(HeapObject* value, AllocationSpace space); 722 723 // Finds out which space an object should get promoted to based on its type. 724 static inline OldSpace* TargetSpace(HeapObject* object); 725 static inline AllocationSpace TargetSpaceId(InstanceType type); 726 727 // Sets the stub_cache_ (only used when expanding the dictionary). public_set_code_stubs(NumberDictionary * value)728 static void public_set_code_stubs(NumberDictionary* value) { 729 roots_[kCodeStubsRootIndex] = value; 730 } 731 732 // Sets the non_monomorphic_cache_ (only used when expanding the dictionary). public_set_non_monomorphic_cache(NumberDictionary * value)733 static void public_set_non_monomorphic_cache(NumberDictionary* value) { 734 roots_[kNonMonomorphicCacheRootIndex] = value; 735 } 736 public_set_empty_script(Script * script)737 static void public_set_empty_script(Script* script) { 738 roots_[kEmptyScriptRootIndex] = script; 739 } 740 741 // Update the next script id. 742 static inline void SetLastScriptId(Object* last_script_id); 743 744 // Generated code can embed this address to get access to the roots. roots_address()745 static Object** roots_address() { return roots_; } 746 747 #ifdef DEBUG 748 static void Print(); 749 static void PrintHandles(); 750 751 // Verify the heap is in its normal state before or after a GC. 752 static void Verify(); 753 754 // Report heap statistics. 755 static void ReportHeapStatistics(const char* title); 756 static void ReportCodeStatistics(const char* title); 757 758 // Fill in bogus values in from space 759 static void ZapFromSpace(); 760 #endif 761 762 #if defined(ENABLE_LOGGING_AND_PROFILING) 763 // Print short heap statistics. 764 static void PrintShortHeapStatistics(); 765 #endif 766 767 // Makes a new symbol object 768 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation 769 // failed. 770 // Please note this function does not perform a garbage collection. 771 static Object* CreateSymbol(const char* str, int length, int hash); 772 static Object* CreateSymbol(String* str); 773 774 // Write barrier support for address[offset] = o. 775 static inline void RecordWrite(Address address, int offset); 776 777 // Given an address occupied by a live code object, return that object. 778 static Object* FindCodeObject(Address a); 779 780 // Invoke Shrink on shrinkable spaces. 781 static void Shrink(); 782 783 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT }; gc_state()784 static inline HeapState gc_state() { return gc_state_; } 785 786 #ifdef DEBUG IsAllocationAllowed()787 static bool IsAllocationAllowed() { return allocation_allowed_; } 788 static inline bool allow_allocation(bool enable); 789 disallow_allocation_failure()790 static bool disallow_allocation_failure() { 791 return disallow_allocation_failure_; 792 } 793 794 static void TracePathToObject(Object* target); 795 static void TracePathToGlobal(); 796 #endif 797 798 // Callback function passed to Heap::Iterate etc. Copies an object if 799 // necessary, the object might be promoted to an old space. The caller must 800 // ensure the precondition that the object is (a) a heap object and (b) in 801 // the heap's from space. 802 static void ScavengePointer(HeapObject** p); 803 static inline void ScavengeObject(HeapObject** p, HeapObject* object); 804 805 // Clear a range of remembered set addresses corresponding to the object 806 // area address 'start' with size 'size_in_bytes', eg, when adding blocks 807 // to the free list. 808 static void ClearRSetRange(Address start, int size_in_bytes); 809 810 // Rebuild remembered set in old and map spaces. 811 static void RebuildRSets(); 812 813 // Update an old object's remembered set 814 static int UpdateRSet(HeapObject* obj); 815 816 // Commits from space if it is uncommitted. 817 static void EnsureFromSpaceIsCommitted(); 818 819 // Support for partial snapshots. After calling this we can allocate a 820 // certain number of bytes using only linear allocation (with a 821 // LinearAllocationScope and an AlwaysAllocateScope) without using freelists 822 // or causing a GC. It returns true of space was reserved or false if a GC is 823 // needed. For paged spaces the space requested must include the space wasted 824 // at the end of each page when allocating linearly. 825 static void ReserveSpace( 826 int new_space_size, 827 int pointer_space_size, 828 int data_space_size, 829 int code_space_size, 830 int map_space_size, 831 int cell_space_size, 832 int large_object_size); 833 834 // 835 // Support for the API. 836 // 837 838 static bool CreateApiObjects(); 839 840 // Attempt to find the number in a small cache. If we finds it, return 841 // the string representation of the number. Otherwise return undefined. 842 static Object* GetNumberStringCache(Object* number); 843 844 // Update the cache with a new number-string pair. 845 static void SetNumberStringCache(Object* number, String* str); 846 847 // Adjusts the amount of registered external memory. 848 // Returns the adjusted value. 849 static inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes); 850 851 // Allocate unitialized fixed array (pretenure == NON_TENURE). 852 static Object* AllocateRawFixedArray(int length); 853 854 // True if we have reached the allocation limit in the old generation that 855 // should force the next GC (caused normally) to be a full one. OldGenerationPromotionLimitReached()856 static bool OldGenerationPromotionLimitReached() { 857 return (PromotedSpaceSize() + PromotedExternalMemorySize()) 858 > old_gen_promotion_limit_; 859 } 860 OldGenerationSpaceAvailable()861 static intptr_t OldGenerationSpaceAvailable() { 862 return old_gen_allocation_limit_ - 863 (PromotedSpaceSize() + PromotedExternalMemorySize()); 864 } 865 866 // True if we have reached the allocation limit in the old generation that 867 // should artificially cause a GC right now. OldGenerationAllocationLimitReached()868 static bool OldGenerationAllocationLimitReached() { 869 return OldGenerationSpaceAvailable() < 0; 870 } 871 872 // Can be called when the embedding application is idle. 873 static bool IdleNotification(); 874 875 // Declare all the root indices. 876 enum RootListIndex { 877 #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, 878 STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION) 879 #undef ROOT_INDEX_DECLARATION 880 881 // Utility type maps 882 #define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex, 883 STRUCT_LIST(DECLARE_STRUCT_MAP) 884 #undef DECLARE_STRUCT_MAP 885 886 #define SYMBOL_INDEX_DECLARATION(name, str) k##name##RootIndex, 887 SYMBOL_LIST(SYMBOL_INDEX_DECLARATION) 888 #undef SYMBOL_DECLARATION 889 890 kSymbolTableRootIndex, 891 kStrongRootListLength = kSymbolTableRootIndex, 892 kRootListLength 893 }; 894 895 static Object* NumberToString(Object* number); 896 897 static Map* MapForExternalArrayType(ExternalArrayType array_type); 898 static RootListIndex RootIndexForExternalArrayType( 899 ExternalArrayType array_type); 900 901 static void RecordStats(HeapStats* stats); 902 903 private: 904 static int reserved_semispace_size_; 905 static int max_semispace_size_; 906 static int initial_semispace_size_; 907 static int max_old_generation_size_; 908 static size_t code_range_size_; 909 910 // For keeping track of how much data has survived 911 // scavenge since last new space expansion. 912 static int survived_since_last_expansion_; 913 914 static int always_allocate_scope_depth_; 915 static int linear_allocation_scope_depth_; 916 static bool context_disposed_pending_; 917 918 #if defined(V8_TARGET_ARCH_X64) 919 static const int kMaxObjectSizeInNewSpace = 512*KB; 920 #else 921 static const int kMaxObjectSizeInNewSpace = 256*KB; 922 #endif 923 924 static NewSpace new_space_; 925 static OldSpace* old_pointer_space_; 926 static OldSpace* old_data_space_; 927 static OldSpace* code_space_; 928 static MapSpace* map_space_; 929 static CellSpace* cell_space_; 930 static LargeObjectSpace* lo_space_; 931 static HeapState gc_state_; 932 933 // Returns the size of object residing in non new spaces. 934 static int PromotedSpaceSize(); 935 936 // Returns the amount of external memory registered since last global gc. 937 static int PromotedExternalMemorySize(); 938 939 static int mc_count_; // how many mark-compact collections happened 940 static int gc_count_; // how many gc happened 941 942 #define ROOT_ACCESSOR(type, name, camel_name) \ 943 static inline void set_##name(type* value) { \ 944 roots_[k##camel_name##RootIndex] = value; \ 945 } 946 ROOT_LIST(ROOT_ACCESSOR) 947 #undef ROOT_ACCESSOR 948 949 #ifdef DEBUG 950 static bool allocation_allowed_; 951 952 // If the --gc-interval flag is set to a positive value, this 953 // variable holds the value indicating the number of allocations 954 // remain until the next failure and garbage collection. 955 static int allocation_timeout_; 956 957 // Do we expect to be able to handle allocation failure at this 958 // time? 959 static bool disallow_allocation_failure_; 960 #endif // DEBUG 961 962 // Limit that triggers a global GC on the next (normally caused) GC. This 963 // is checked when we have already decided to do a GC to help determine 964 // which collector to invoke. 965 static int old_gen_promotion_limit_; 966 967 // Limit that triggers a global GC as soon as is reasonable. This is 968 // checked before expanding a paged space in the old generation and on 969 // every allocation in large object space. 970 static int old_gen_allocation_limit_; 971 972 // Limit on the amount of externally allocated memory allowed 973 // between global GCs. If reached a global GC is forced. 974 static int external_allocation_limit_; 975 976 // The amount of external memory registered through the API kept alive 977 // by global handles 978 static int amount_of_external_allocated_memory_; 979 980 // Caches the amount of external memory registered at the last global gc. 981 static int amount_of_external_allocated_memory_at_last_global_gc_; 982 983 // Indicates that an allocation has failed in the old generation since the 984 // last GC. 985 static int old_gen_exhausted_; 986 987 static Object* roots_[kRootListLength]; 988 989 struct StringTypeTable { 990 InstanceType type; 991 int size; 992 RootListIndex index; 993 }; 994 995 struct ConstantSymbolTable { 996 const char* contents; 997 RootListIndex index; 998 }; 999 1000 struct StructTable { 1001 InstanceType type; 1002 int size; 1003 RootListIndex index; 1004 }; 1005 1006 static const StringTypeTable string_type_table[]; 1007 static const ConstantSymbolTable constant_symbol_table[]; 1008 static const StructTable struct_table[]; 1009 1010 // The special hidden symbol which is an empty string, but does not match 1011 // any string when looked up in properties. 1012 static String* hidden_symbol_; 1013 1014 // GC callback function, called before and after mark-compact GC. 1015 // Allocations in the callback function are disallowed. 1016 static GCCallback global_gc_prologue_callback_; 1017 static GCCallback global_gc_epilogue_callback_; 1018 1019 // Checks whether a global GC is necessary 1020 static GarbageCollector SelectGarbageCollector(AllocationSpace space); 1021 1022 // Performs garbage collection 1023 static void PerformGarbageCollection(AllocationSpace space, 1024 GarbageCollector collector, 1025 GCTracer* tracer); 1026 1027 // Returns either a Smi or a Number object from 'value'. If 'new_object' 1028 // is false, it may return a preallocated immutable object. 1029 static Object* SmiOrNumberFromDouble(double value, 1030 bool new_object, 1031 PretenureFlag pretenure = NOT_TENURED); 1032 1033 // Allocate an uninitialized object in map space. The behavior is identical 1034 // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't 1035 // have to test the allocation space argument and (b) can reduce code size 1036 // (since both AllocateRaw and AllocateRawMap are inlined). 1037 static inline Object* AllocateRawMap(); 1038 1039 // Allocate an uninitialized object in the global property cell space. 1040 static inline Object* AllocateRawCell(); 1041 1042 // Initializes a JSObject based on its map. 1043 static void InitializeJSObjectFromMap(JSObject* obj, 1044 FixedArray* properties, 1045 Map* map); 1046 1047 static bool CreateInitialMaps(); 1048 static bool CreateInitialObjects(); 1049 1050 // These four Create*EntryStub functions are here because of a gcc-4.4 bug 1051 // that assigns wrong vtable entries. 1052 static void CreateCEntryStub(); 1053 static void CreateJSEntryStub(); 1054 static void CreateJSConstructEntryStub(); 1055 static void CreateRegExpCEntryStub(); 1056 1057 static void CreateFixedStubs(); 1058 1059 static Object* CreateOddball(Map* map, 1060 const char* to_string, 1061 Object* to_number); 1062 1063 // Allocate empty fixed array. 1064 static Object* AllocateEmptyFixedArray(); 1065 1066 // Performs a minor collection in new generation. 1067 static void Scavenge(); 1068 static void ScavengeExternalStringTable(); 1069 static Address DoScavenge(ObjectVisitor* scavenge_visitor, 1070 Address new_space_front); 1071 1072 // Performs a major collection in the whole heap. 1073 static void MarkCompact(GCTracer* tracer); 1074 1075 // Code to be run before and after mark-compact. 1076 static void MarkCompactPrologue(bool is_compacting); 1077 static void MarkCompactEpilogue(bool is_compacting); 1078 1079 // Helper function used by CopyObject to copy a source object to an 1080 // allocated target object and update the forwarding pointer in the source 1081 // object. Returns the target object. 1082 static inline HeapObject* MigrateObject(HeapObject* source, 1083 HeapObject* target, 1084 int size); 1085 1086 // Helper function that governs the promotion policy from new space to 1087 // old. If the object's old address lies below the new space's age 1088 // mark or if we've already filled the bottom 1/16th of the to space, 1089 // we try to promote this object. 1090 static inline bool ShouldBePromoted(Address old_address, int object_size); 1091 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) 1092 // Record the copy of an object in the NewSpace's statistics. 1093 static void RecordCopiedObject(HeapObject* obj); 1094 1095 // Record statistics before and after garbage collection. 1096 static void ReportStatisticsBeforeGC(); 1097 static void ReportStatisticsAfterGC(); 1098 #endif 1099 1100 // Rebuild remembered set in an old space. 1101 static void RebuildRSets(PagedSpace* space); 1102 1103 // Rebuild remembered set in the large object space. 1104 static void RebuildRSets(LargeObjectSpace* space); 1105 1106 // Slow part of scavenge object. 1107 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object); 1108 1109 // Copy memory from src to dst. 1110 static inline void CopyBlock(Object** dst, Object** src, int byte_size); 1111 1112 // Initializes a function with a shared part and prototype. 1113 // Returns the function. 1114 // Note: this code was factored out of AllocateFunction such that 1115 // other parts of the VM could use it. Specifically, a function that creates 1116 // instances of type JS_FUNCTION_TYPE benefit from the use of this function. 1117 // Please note this does not perform a garbage collection. 1118 static inline Object* InitializeFunction(JSFunction* function, 1119 SharedFunctionInfo* shared, 1120 Object* prototype); 1121 1122 1123 // Initializes the number to string cache based on the max semispace size. 1124 static Object* InitializeNumberStringCache(); 1125 // Flush the number to string cache. 1126 static void FlushNumberStringCache(); 1127 1128 static const int kInitialSymbolTableSize = 2048; 1129 static const int kInitialEvalCacheSize = 64; 1130 1131 friend class Factory; 1132 friend class DisallowAllocationFailure; 1133 friend class AlwaysAllocateScope; 1134 friend class LinearAllocationScope; 1135 }; 1136 1137 1138 class HeapStats { 1139 public: 1140 int *start_marker; 1141 int *new_space_size; 1142 int *new_space_capacity; 1143 int *old_pointer_space_size; 1144 int *old_pointer_space_capacity; 1145 int *old_data_space_size; 1146 int *old_data_space_capacity; 1147 int *code_space_size; 1148 int *code_space_capacity; 1149 int *map_space_size; 1150 int *map_space_capacity; 1151 int *cell_space_size; 1152 int *cell_space_capacity; 1153 int *lo_space_size; 1154 int *global_handle_count; 1155 int *weak_global_handle_count; 1156 int *pending_global_handle_count; 1157 int *near_death_global_handle_count; 1158 int *destroyed_global_handle_count; 1159 int *end_marker; 1160 }; 1161 1162 1163 class AlwaysAllocateScope { 1164 public: AlwaysAllocateScope()1165 AlwaysAllocateScope() { 1166 // We shouldn't hit any nested scopes, because that requires 1167 // non-handle code to call handle code. The code still works but 1168 // performance will degrade, so we want to catch this situation 1169 // in debug mode. 1170 ASSERT(Heap::always_allocate_scope_depth_ == 0); 1171 Heap::always_allocate_scope_depth_++; 1172 } 1173 ~AlwaysAllocateScope()1174 ~AlwaysAllocateScope() { 1175 Heap::always_allocate_scope_depth_--; 1176 ASSERT(Heap::always_allocate_scope_depth_ == 0); 1177 } 1178 }; 1179 1180 1181 class LinearAllocationScope { 1182 public: LinearAllocationScope()1183 LinearAllocationScope() { 1184 Heap::linear_allocation_scope_depth_++; 1185 } 1186 ~LinearAllocationScope()1187 ~LinearAllocationScope() { 1188 Heap::linear_allocation_scope_depth_--; 1189 ASSERT(Heap::linear_allocation_scope_depth_ >= 0); 1190 } 1191 }; 1192 1193 1194 #ifdef DEBUG 1195 // Visitor class to verify interior pointers that do not have remembered set 1196 // bits. All heap object pointers have to point into the heap to a location 1197 // that has a map pointer at its first word. Caveat: Heap::Contains is an 1198 // approximation because it can return true for objects in a heap space but 1199 // above the allocation pointer. 1200 class VerifyPointersVisitor: public ObjectVisitor { 1201 public: VisitPointers(Object ** start,Object ** end)1202 void VisitPointers(Object** start, Object** end) { 1203 for (Object** current = start; current < end; current++) { 1204 if ((*current)->IsHeapObject()) { 1205 HeapObject* object = HeapObject::cast(*current); 1206 ASSERT(Heap::Contains(object)); 1207 ASSERT(object->map()->IsMap()); 1208 } 1209 } 1210 } 1211 }; 1212 1213 1214 // Visitor class to verify interior pointers that have remembered set bits. 1215 // As VerifyPointersVisitor but also checks that remembered set bits are 1216 // always set for pointers into new space. 1217 class VerifyPointersAndRSetVisitor: public ObjectVisitor { 1218 public: VisitPointers(Object ** start,Object ** end)1219 void VisitPointers(Object** start, Object** end) { 1220 for (Object** current = start; current < end; current++) { 1221 if ((*current)->IsHeapObject()) { 1222 HeapObject* object = HeapObject::cast(*current); 1223 ASSERT(Heap::Contains(object)); 1224 ASSERT(object->map()->IsMap()); 1225 if (Heap::InNewSpace(object)) { 1226 ASSERT(Page::IsRSetSet(reinterpret_cast<Address>(current), 0)); 1227 } 1228 } 1229 } 1230 } 1231 }; 1232 #endif 1233 1234 1235 // Space iterator for iterating over all spaces of the heap. 1236 // Returns each space in turn, and null when it is done. 1237 class AllSpaces BASE_EMBEDDED { 1238 public: 1239 Space* next(); AllSpaces()1240 AllSpaces() { counter_ = FIRST_SPACE; } 1241 private: 1242 int counter_; 1243 }; 1244 1245 1246 // Space iterator for iterating over all old spaces of the heap: Old pointer 1247 // space, old data space and code space. 1248 // Returns each space in turn, and null when it is done. 1249 class OldSpaces BASE_EMBEDDED { 1250 public: 1251 OldSpace* next(); OldSpaces()1252 OldSpaces() { counter_ = OLD_POINTER_SPACE; } 1253 private: 1254 int counter_; 1255 }; 1256 1257 1258 // Space iterator for iterating over all the paged spaces of the heap: 1259 // Map space, old pointer space, old data space, code space and cell space. 1260 // Returns each space in turn, and null when it is done. 1261 class PagedSpaces BASE_EMBEDDED { 1262 public: 1263 PagedSpace* next(); PagedSpaces()1264 PagedSpaces() { counter_ = OLD_POINTER_SPACE; } 1265 private: 1266 int counter_; 1267 }; 1268 1269 1270 // Space iterator for iterating over all spaces of the heap. 1271 // For each space an object iterator is provided. The deallocation of the 1272 // returned object iterators is handled by the space iterator. 1273 class SpaceIterator : public Malloced { 1274 public: 1275 SpaceIterator(); 1276 virtual ~SpaceIterator(); 1277 1278 bool has_next(); 1279 ObjectIterator* next(); 1280 1281 private: 1282 ObjectIterator* CreateIterator(); 1283 1284 int current_space_; // from enum AllocationSpace. 1285 ObjectIterator* iterator_; // object iterator for the current space. 1286 }; 1287 1288 1289 // A HeapIterator provides iteration over the whole heap It aggregates a the 1290 // specific iterators for the different spaces as these can only iterate over 1291 // one space only. 1292 1293 class HeapIterator BASE_EMBEDDED { 1294 public: 1295 explicit HeapIterator(); 1296 virtual ~HeapIterator(); 1297 1298 HeapObject* next(); 1299 void reset(); 1300 1301 private: 1302 // Perform the initialization. 1303 void Init(); 1304 1305 // Perform all necessary shutdown (destruction) work. 1306 void Shutdown(); 1307 1308 // Space iterator for iterating all the spaces. 1309 SpaceIterator* space_iterator_; 1310 // Object iterator for the space currently being iterated. 1311 ObjectIterator* object_iterator_; 1312 }; 1313 1314 1315 // Cache for mapping (map, property name) into field offset. 1316 // Cleared at startup and prior to mark sweep collection. 1317 class KeyedLookupCache { 1318 public: 1319 // Lookup field offset for (map, name). If absent, -1 is returned. 1320 static int Lookup(Map* map, String* name); 1321 1322 // Update an element in the cache. 1323 static void Update(Map* map, String* name, int field_offset); 1324 1325 // Clear the cache. 1326 static void Clear(); 1327 1328 static const int kLength = 64; 1329 static const int kCapacityMask = kLength - 1; 1330 static const int kMapHashShift = 2; 1331 1332 private: 1333 static inline int Hash(Map* map, String* name); 1334 1335 // Get the address of the keys and field_offsets arrays. Used in 1336 // generated code to perform cache lookups. keys_address()1337 static Address keys_address() { 1338 return reinterpret_cast<Address>(&keys_); 1339 } 1340 field_offsets_address()1341 static Address field_offsets_address() { 1342 return reinterpret_cast<Address>(&field_offsets_); 1343 } 1344 1345 struct Key { 1346 Map* map; 1347 String* name; 1348 }; 1349 static Key keys_[kLength]; 1350 static int field_offsets_[kLength]; 1351 1352 friend class ExternalReference; 1353 }; 1354 1355 1356 // Cache for mapping (array, property name) into descriptor index. 1357 // The cache contains both positive and negative results. 1358 // Descriptor index equals kNotFound means the property is absent. 1359 // Cleared at startup and prior to any gc. 1360 class DescriptorLookupCache { 1361 public: 1362 // Lookup descriptor index for (map, name). 1363 // If absent, kAbsent is returned. Lookup(DescriptorArray * array,String * name)1364 static int Lookup(DescriptorArray* array, String* name) { 1365 if (!StringShape(name).IsSymbol()) return kAbsent; 1366 int index = Hash(array, name); 1367 Key& key = keys_[index]; 1368 if ((key.array == array) && (key.name == name)) return results_[index]; 1369 return kAbsent; 1370 } 1371 1372 // Update an element in the cache. Update(DescriptorArray * array,String * name,int result)1373 static void Update(DescriptorArray* array, String* name, int result) { 1374 ASSERT(result != kAbsent); 1375 if (StringShape(name).IsSymbol()) { 1376 int index = Hash(array, name); 1377 Key& key = keys_[index]; 1378 key.array = array; 1379 key.name = name; 1380 results_[index] = result; 1381 } 1382 } 1383 1384 // Clear the cache. 1385 static void Clear(); 1386 1387 static const int kAbsent = -2; 1388 private: Hash(DescriptorArray * array,String * name)1389 static int Hash(DescriptorArray* array, String* name) { 1390 // Uses only lower 32 bits if pointers are larger. 1391 uint32_t array_hash = 1392 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2; 1393 uint32_t name_hash = 1394 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2; 1395 return (array_hash ^ name_hash) % kLength; 1396 } 1397 1398 static const int kLength = 64; 1399 struct Key { 1400 DescriptorArray* array; 1401 String* name; 1402 }; 1403 1404 static Key keys_[kLength]; 1405 static int results_[kLength]; 1406 }; 1407 1408 1409 // ---------------------------------------------------------------------------- 1410 // Marking stack for tracing live objects. 1411 1412 class MarkingStack { 1413 public: Initialize(Address low,Address high)1414 void Initialize(Address low, Address high) { 1415 top_ = low_ = reinterpret_cast<HeapObject**>(low); 1416 high_ = reinterpret_cast<HeapObject**>(high); 1417 overflowed_ = false; 1418 } 1419 is_full()1420 bool is_full() { return top_ >= high_; } 1421 is_empty()1422 bool is_empty() { return top_ <= low_; } 1423 overflowed()1424 bool overflowed() { return overflowed_; } 1425 clear_overflowed()1426 void clear_overflowed() { overflowed_ = false; } 1427 1428 // Push the (marked) object on the marking stack if there is room, 1429 // otherwise mark the object as overflowed and wait for a rescan of the 1430 // heap. Push(HeapObject * object)1431 void Push(HeapObject* object) { 1432 CHECK(object->IsHeapObject()); 1433 if (is_full()) { 1434 object->SetOverflow(); 1435 overflowed_ = true; 1436 } else { 1437 *(top_++) = object; 1438 } 1439 } 1440 Pop()1441 HeapObject* Pop() { 1442 ASSERT(!is_empty()); 1443 HeapObject* object = *(--top_); 1444 CHECK(object->IsHeapObject()); 1445 return object; 1446 } 1447 1448 private: 1449 HeapObject** low_; 1450 HeapObject** top_; 1451 HeapObject** high_; 1452 bool overflowed_; 1453 }; 1454 1455 1456 // A helper class to document/test C++ scopes where we do not 1457 // expect a GC. Usage: 1458 // 1459 // /* Allocation not allowed: we cannot handle a GC in this scope. */ 1460 // { AssertNoAllocation nogc; 1461 // ... 1462 // } 1463 1464 #ifdef DEBUG 1465 1466 class DisallowAllocationFailure { 1467 public: DisallowAllocationFailure()1468 DisallowAllocationFailure() { 1469 old_state_ = Heap::disallow_allocation_failure_; 1470 Heap::disallow_allocation_failure_ = true; 1471 } ~DisallowAllocationFailure()1472 ~DisallowAllocationFailure() { 1473 Heap::disallow_allocation_failure_ = old_state_; 1474 } 1475 private: 1476 bool old_state_; 1477 }; 1478 1479 class AssertNoAllocation { 1480 public: AssertNoAllocation()1481 AssertNoAllocation() { 1482 old_state_ = Heap::allow_allocation(false); 1483 } 1484 ~AssertNoAllocation()1485 ~AssertNoAllocation() { 1486 Heap::allow_allocation(old_state_); 1487 } 1488 1489 private: 1490 bool old_state_; 1491 }; 1492 1493 class DisableAssertNoAllocation { 1494 public: DisableAssertNoAllocation()1495 DisableAssertNoAllocation() { 1496 old_state_ = Heap::allow_allocation(true); 1497 } 1498 ~DisableAssertNoAllocation()1499 ~DisableAssertNoAllocation() { 1500 Heap::allow_allocation(old_state_); 1501 } 1502 1503 private: 1504 bool old_state_; 1505 }; 1506 1507 #else // ndef DEBUG 1508 1509 class AssertNoAllocation { 1510 public: AssertNoAllocation()1511 AssertNoAllocation() { } ~AssertNoAllocation()1512 ~AssertNoAllocation() { } 1513 }; 1514 1515 class DisableAssertNoAllocation { 1516 public: DisableAssertNoAllocation()1517 DisableAssertNoAllocation() { } ~DisableAssertNoAllocation()1518 ~DisableAssertNoAllocation() { } 1519 }; 1520 1521 #endif 1522 1523 // GCTracer collects and prints ONE line after each garbage collector 1524 // invocation IFF --trace_gc is used. 1525 1526 class GCTracer BASE_EMBEDDED { 1527 public: 1528 GCTracer(); 1529 1530 ~GCTracer(); 1531 1532 // Sets the collector. set_collector(GarbageCollector collector)1533 void set_collector(GarbageCollector collector) { collector_ = collector; } 1534 1535 // Sets the GC count. set_gc_count(int count)1536 void set_gc_count(int count) { gc_count_ = count; } 1537 1538 // Sets the full GC count. set_full_gc_count(int count)1539 void set_full_gc_count(int count) { full_gc_count_ = count; } 1540 1541 // Sets the flag that this is a compacting full GC. set_is_compacting()1542 void set_is_compacting() { is_compacting_ = true; } 1543 1544 // Increment and decrement the count of marked objects. increment_marked_count()1545 void increment_marked_count() { ++marked_count_; } decrement_marked_count()1546 void decrement_marked_count() { --marked_count_; } 1547 marked_count()1548 int marked_count() { return marked_count_; } 1549 1550 private: 1551 // Returns a string matching the collector. 1552 const char* CollectorString(); 1553 1554 // Returns size of object in heap (in MB). SizeOfHeapObjects()1555 double SizeOfHeapObjects() { 1556 return (static_cast<double>(Heap::SizeOfObjects())) / MB; 1557 } 1558 1559 double start_time_; // Timestamp set in the constructor. 1560 double start_size_; // Size of objects in heap set in constructor. 1561 GarbageCollector collector_; // Type of collector. 1562 1563 // A count (including this one, eg, the first collection is 1) of the 1564 // number of garbage collections. 1565 int gc_count_; 1566 1567 // A count (including this one) of the number of full garbage collections. 1568 int full_gc_count_; 1569 1570 // True if the current GC is a compacting full collection, false 1571 // otherwise. 1572 bool is_compacting_; 1573 1574 // True if the *previous* full GC cwas a compacting collection (will be 1575 // false if there has not been a previous full GC). 1576 bool previous_has_compacted_; 1577 1578 // On a full GC, a count of the number of marked objects. Incremented 1579 // when an object is marked and decremented when an object's mark bit is 1580 // cleared. Will be zero on a scavenge collection. 1581 int marked_count_; 1582 1583 // The count from the end of the previous full GC. Will be zero if there 1584 // was no previous full GC. 1585 int previous_marked_count_; 1586 }; 1587 1588 1589 class TranscendentalCache { 1590 public: 1591 enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches}; 1592 1593 explicit TranscendentalCache(Type t); 1594 1595 // Returns a heap number with f(input), where f is a math function specified 1596 // by the 'type' argument. Get(Type type,double input)1597 static inline Object* Get(Type type, double input) { 1598 TranscendentalCache* cache = caches_[type]; 1599 if (cache == NULL) { 1600 caches_[type] = cache = new TranscendentalCache(type); 1601 } 1602 return cache->Get(input); 1603 } 1604 1605 // The cache contains raw Object pointers. This method disposes of 1606 // them before a garbage collection. 1607 static void Clear(); 1608 1609 private: Get(double input)1610 inline Object* Get(double input) { 1611 Converter c; 1612 c.dbl = input; 1613 int hash = Hash(c); 1614 Element e = elements_[hash]; 1615 if (e.in[0] == c.integers[0] && 1616 e.in[1] == c.integers[1]) { 1617 ASSERT(e.output != NULL); 1618 Counters::transcendental_cache_hit.Increment(); 1619 return e.output; 1620 } 1621 double answer = Calculate(input); 1622 Object* heap_number = Heap::AllocateHeapNumber(answer); 1623 if (!heap_number->IsFailure()) { 1624 elements_[hash].in[0] = c.integers[0]; 1625 elements_[hash].in[1] = c.integers[1]; 1626 elements_[hash].output = heap_number; 1627 } 1628 Counters::transcendental_cache_miss.Increment(); 1629 return heap_number; 1630 } 1631 Calculate(double input)1632 inline double Calculate(double input) { 1633 switch (type_) { 1634 case ACOS: 1635 return acos(input); 1636 case ASIN: 1637 return asin(input); 1638 case ATAN: 1639 return atan(input); 1640 case COS: 1641 return cos(input); 1642 case EXP: 1643 return exp(input); 1644 case LOG: 1645 return log(input); 1646 case SIN: 1647 return sin(input); 1648 case TAN: 1649 return tan(input); 1650 default: 1651 return 0.0; // Never happens. 1652 } 1653 } 1654 static const int kCacheSize = 512; 1655 struct Element { 1656 uint32_t in[2]; 1657 Object* output; 1658 }; 1659 union Converter { 1660 double dbl; 1661 uint32_t integers[2]; 1662 }; Hash(const Converter & c)1663 inline static int Hash(const Converter& c) { 1664 uint32_t hash = (c.integers[0] ^ c.integers[1]); 1665 hash ^= hash >> 16; 1666 hash ^= hash >> 8; 1667 return (hash & (kCacheSize - 1)); 1668 } 1669 cache_array_address()1670 static Address cache_array_address() { 1671 // Used to create an external reference. 1672 return reinterpret_cast<Address>(caches_); 1673 } 1674 1675 // Allow access to the caches_ array as an ExternalReference. 1676 friend class ExternalReference; 1677 // Inline implementation of the caching. 1678 friend class TranscendentalCacheStub; 1679 1680 static TranscendentalCache* caches_[kNumberOfCaches]; 1681 Element elements_[kCacheSize]; 1682 Type type_; 1683 }; 1684 1685 1686 // External strings table is a place where all external strings are 1687 // registered. We need to keep track of such strings to properly 1688 // finalize them. 1689 class ExternalStringTable : public AllStatic { 1690 public: 1691 // Registers an external string. 1692 inline static void AddString(String* string); 1693 1694 inline static void Iterate(ObjectVisitor* v); 1695 1696 // Restores internal invariant and gets rid of collected strings. 1697 // Must be called after each Iterate() that modified the strings. 1698 static void CleanUp(); 1699 1700 // Destroys all allocated memory. 1701 static void TearDown(); 1702 1703 private: 1704 friend class Heap; 1705 1706 inline static void Verify(); 1707 1708 inline static void AddOldString(String* string); 1709 1710 // Notifies the table that only a prefix of the new list is valid. 1711 inline static void ShrinkNewStrings(int position); 1712 1713 // To speed up scavenge collections new space string are kept 1714 // separate from old space strings. 1715 static List<Object*> new_space_strings_; 1716 static List<Object*> old_space_strings_; 1717 }; 1718 1719 } } // namespace v8::internal 1720 1721 #endif // V8_HEAP_H_ 1722