OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 14 matching lines...) Expand all Loading... |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_HEAP_H_ | 28 #ifndef V8_HEAP_H_ |
29 #define V8_HEAP_H_ | 29 #define V8_HEAP_H_ |
30 | 30 |
31 #include <math.h> | 31 #include <math.h> |
32 | 32 |
33 #include "globals.h" | 33 #include "globals.h" |
34 #include "list.h" | 34 #include "list.h" |
| 35 #include "mark-compact.h" |
35 #include "spaces.h" | 36 #include "spaces.h" |
36 #include "splay-tree-inl.h" | 37 #include "splay-tree-inl.h" |
37 #include "v8-counters.h" | 38 #include "v8-counters.h" |
38 | 39 |
39 namespace v8 { | 40 namespace v8 { |
40 namespace internal { | 41 namespace internal { |
41 | 42 |
| 43 // TODO(isolates): remove HEAP here |
| 44 #define HEAP (_inline_get_heap_()) |
| 45 class Heap; |
| 46 inline Heap* _inline_get_heap_(); |
| 47 |
42 | 48 |
43 // Defines all the roots in Heap. | 49 // Defines all the roots in Heap. |
44 #define STRONG_ROOT_LIST(V) \ | 50 #define STRONG_ROOT_LIST(V) \ |
45 /* Put the byte array map early. We need it to be in place by the time */ \ | 51 /* Put the byte array map early. We need it to be in place by the time */ \ |
46 /* the deserializer hits the next page, since it wants to put a byte */ \ | 52 /* the deserializer hits the next page, since it wants to put a byte */ \ |
47 /* array in the unused space at the end of the page. */ \ | 53 /* array in the unused space at the end of the page. */ \ |
48 V(Map, byte_array_map, ByteArrayMap) \ | 54 V(Map, byte_array_map, ByteArrayMap) \ |
49 V(Map, one_pointer_filler_map, OnePointerFillerMap) \ | 55 V(Map, one_pointer_filler_map, OnePointerFillerMap) \ |
50 V(Map, two_pointer_filler_map, TwoPointerFillerMap) \ | 56 V(Map, two_pointer_filler_map, TwoPointerFillerMap) \ |
51 /* Cluster the most popular ones in a few cache lines here at the top. */ \ | 57 /* Cluster the most popular ones in a few cache lines here at the top. */ \ |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 "KeyedStoreExternalUnsignedShortArray") \ | 225 "KeyedStoreExternalUnsignedShortArray") \ |
220 V(KeyedStoreExternalIntArray_symbol, "KeyedStoreExternalIntArray") \ | 226 V(KeyedStoreExternalIntArray_symbol, "KeyedStoreExternalIntArray") \ |
221 V(KeyedStoreExternalUnsignedIntArray_symbol, \ | 227 V(KeyedStoreExternalUnsignedIntArray_symbol, \ |
222 "KeyedStoreExternalUnsignedIntArray") \ | 228 "KeyedStoreExternalUnsignedIntArray") \ |
223 V(KeyedStoreExternalFloatArray_symbol, "KeyedStoreExternalFloatArray") \ | 229 V(KeyedStoreExternalFloatArray_symbol, "KeyedStoreExternalFloatArray") \ |
224 V(KeyedStoreExternalPixelArray_symbol, "KeyedStoreExternalPixelArray") | 230 V(KeyedStoreExternalPixelArray_symbol, "KeyedStoreExternalPixelArray") |
225 | 231 |
226 // Forward declarations. | 232 // Forward declarations. |
227 class GCTracer; | 233 class GCTracer; |
228 class HeapStats; | 234 class HeapStats; |
| 235 class Isolate; |
229 class WeakObjectRetainer; | 236 class WeakObjectRetainer; |
230 | 237 |
231 | 238 |
232 typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer); | 239 typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap, |
| 240 Object** pointer); |
233 | 241 |
234 typedef bool (*DirtyRegionCallback)(Address start, | 242 typedef bool (*DirtyRegionCallback)(Heap* heap, |
| 243 Address start, |
235 Address end, | 244 Address end, |
236 ObjectSlotCallback copy_object_func); | 245 ObjectSlotCallback copy_object_func); |
237 | 246 |
238 | 247 |
239 // The all static Heap captures the interface to the global object heap. | 248 // The all static Heap captures the interface to the global object heap. |
240 // All JavaScript contexts by this process share the same object heap. | 249 // All JavaScript contexts by this process share the same object heap. |
241 | 250 |
242 class Heap : public AllStatic { | 251 #ifdef DEBUG |
| 252 class HeapDebugUtils; |
| 253 #endif |
| 254 |
| 255 |
| 256 // A queue of objects promoted during scavenge. Each object is accompanied |
| 257 // by it's size to avoid dereferencing a map pointer for scanning. |
| 258 class PromotionQueue { |
| 259 public: |
| 260 PromotionQueue() : front_(NULL), rear_(NULL) { } |
| 261 |
| 262 void Initialize(Address start_address) { |
| 263 front_ = rear_ = reinterpret_cast<intptr_t*>(start_address); |
| 264 } |
| 265 |
| 266 bool is_empty() { return front_ <= rear_; } |
| 267 |
| 268 inline void insert(HeapObject* target, int size); |
| 269 |
| 270 void remove(HeapObject** target, int* size) { |
| 271 *target = reinterpret_cast<HeapObject*>(*(--front_)); |
| 272 *size = static_cast<int>(*(--front_)); |
| 273 // Assert no underflow. |
| 274 ASSERT(front_ >= rear_); |
| 275 } |
| 276 |
| 277 private: |
| 278 // The front of the queue is higher in memory than the rear. |
| 279 intptr_t* front_; |
| 280 intptr_t* rear_; |
| 281 |
| 282 DISALLOW_COPY_AND_ASSIGN(PromotionQueue); |
| 283 }; |
| 284 |
| 285 |
| 286 // External strings table is a place where all external strings are |
| 287 // registered. We need to keep track of such strings to properly |
| 288 // finalize them. |
| 289 class ExternalStringTable { |
| 290 public: |
| 291 // Registers an external string. |
| 292 inline void AddString(String* string); |
| 293 |
| 294 inline void Iterate(ObjectVisitor* v); |
| 295 |
| 296 // Restores internal invariant and gets rid of collected strings. |
| 297 // Must be called after each Iterate() that modified the strings. |
| 298 void CleanUp(); |
| 299 |
| 300 // Destroys all allocated memory. |
| 301 void TearDown(); |
| 302 |
| 303 private: |
| 304 ExternalStringTable() { } |
| 305 |
| 306 friend class Heap; |
| 307 |
| 308 inline void Verify(); |
| 309 |
| 310 inline void AddOldString(String* string); |
| 311 |
| 312 // Notifies the table that only a prefix of the new list is valid. |
| 313 inline void ShrinkNewStrings(int position); |
| 314 |
| 315 // To speed up scavenge collections new space string are kept |
| 316 // separate from old space strings. |
| 317 List<Object*> new_space_strings_; |
| 318 List<Object*> old_space_strings_; |
| 319 |
| 320 Heap* heap_; |
| 321 |
| 322 DISALLOW_COPY_AND_ASSIGN(ExternalStringTable); |
| 323 }; |
| 324 |
| 325 |
| 326 class Heap { |
243 public: | 327 public: |
244 // Configure heap size before setup. Return false if the heap has been | 328 // Configure heap size before setup. Return false if the heap has been |
245 // setup already. | 329 // setup already. |
246 static bool ConfigureHeap(int max_semispace_size, | 330 bool ConfigureHeap(int max_semispace_size, |
247 int max_old_gen_size, | 331 int max_old_gen_size, |
248 int max_executable_size); | 332 int max_executable_size); |
249 static bool ConfigureHeapDefault(); | 333 bool ConfigureHeapDefault(); |
250 | 334 |
251 // Initializes the global object heap. If create_heap_objects is true, | 335 // Initializes the global object heap. If create_heap_objects is true, |
252 // also creates the basic non-mutable objects. | 336 // also creates the basic non-mutable objects. |
253 // Returns whether it succeeded. | 337 // Returns whether it succeeded. |
254 static bool Setup(bool create_heap_objects); | 338 bool Setup(bool create_heap_objects); |
255 | 339 |
256 // Destroys all memory allocated by the heap. | 340 // Destroys all memory allocated by the heap. |
257 static void TearDown(); | 341 void TearDown(); |
258 | 342 |
259 // Set the stack limit in the roots_ array. Some architectures generate | 343 // Set the stack limit in the roots_ array. Some architectures generate |
260 // code that looks here, because it is faster than loading from the static | 344 // code that looks here, because it is faster than loading from the static |
261 // jslimit_/real_jslimit_ variable in the StackGuard. | 345 // jslimit_/real_jslimit_ variable in the StackGuard. |
262 static void SetStackLimits(); | 346 void SetStackLimits(); |
263 | 347 |
264 // Returns whether Setup has been called. | 348 // Returns whether Setup has been called. |
265 static bool HasBeenSetup(); | 349 bool HasBeenSetup(); |
266 | 350 |
267 // Returns the maximum amount of memory reserved for the heap. For | 351 // Returns the maximum amount of memory reserved for the heap. For |
268 // the young generation, we reserve 4 times the amount needed for a | 352 // the young generation, we reserve 4 times the amount needed for a |
269 // semi space. The young generation consists of two semi spaces and | 353 // semi space. The young generation consists of two semi spaces and |
270 // we reserve twice the amount needed for those in order to ensure | 354 // we reserve twice the amount needed for those in order to ensure |
271 // that new space can be aligned to its size. | 355 // that new space can be aligned to its size. |
272 static intptr_t MaxReserved() { | 356 intptr_t MaxReserved() { |
273 return 4 * reserved_semispace_size_ + max_old_generation_size_; | 357 return 4 * reserved_semispace_size_ + max_old_generation_size_; |
274 } | 358 } |
275 static int MaxSemiSpaceSize() { return max_semispace_size_; } | 359 int MaxSemiSpaceSize() { return max_semispace_size_; } |
276 static int ReservedSemiSpaceSize() { return reserved_semispace_size_; } | 360 int ReservedSemiSpaceSize() { return reserved_semispace_size_; } |
277 static int InitialSemiSpaceSize() { return initial_semispace_size_; } | 361 int InitialSemiSpaceSize() { return initial_semispace_size_; } |
278 static intptr_t MaxOldGenerationSize() { return max_old_generation_size_; } | 362 intptr_t MaxOldGenerationSize() { return max_old_generation_size_; } |
279 static intptr_t MaxExecutableSize() { return max_executable_size_; } | 363 intptr_t MaxExecutableSize() { return max_executable_size_; } |
280 | 364 |
281 // Returns the capacity of the heap in bytes w/o growing. Heap grows when | 365 // Returns the capacity of the heap in bytes w/o growing. Heap grows when |
282 // more spaces are needed until it reaches the limit. | 366 // more spaces are needed until it reaches the limit. |
283 static intptr_t Capacity(); | 367 intptr_t Capacity(); |
284 | 368 |
285 // Returns the amount of memory currently committed for the heap. | 369 // Returns the amount of memory currently committed for the heap. |
286 static intptr_t CommittedMemory(); | 370 intptr_t CommittedMemory(); |
287 | 371 |
288 // Returns the amount of executable memory currently committed for the heap. | 372 // Returns the amount of executable memory currently committed for the heap. |
289 static intptr_t CommittedMemoryExecutable(); | 373 intptr_t CommittedMemoryExecutable(); |
290 | 374 |
291 // Returns the available bytes in space w/o growing. | 375 // Returns the available bytes in space w/o growing. |
292 // Heap doesn't guarantee that it can allocate an object that requires | 376 // Heap doesn't guarantee that it can allocate an object that requires |
293 // all available bytes. Check MaxHeapObjectSize() instead. | 377 // all available bytes. Check MaxHeapObjectSize() instead. |
294 static intptr_t Available(); | 378 intptr_t Available(); |
295 | 379 |
296 // Returns the maximum object size in paged space. | 380 // Returns the maximum object size in paged space. |
297 static inline int MaxObjectSizeInPagedSpace(); | 381 inline int MaxObjectSizeInPagedSpace(); |
298 | 382 |
299 // Returns of size of all objects residing in the heap. | 383 // Returns of size of all objects residing in the heap. |
300 static intptr_t SizeOfObjects(); | 384 intptr_t SizeOfObjects(); |
301 | 385 |
302 // Return the starting address and a mask for the new space. And-masking an | 386 // Return the starting address and a mask for the new space. And-masking an |
303 // address with the mask will result in the start address of the new space | 387 // address with the mask will result in the start address of the new space |
304 // for all addresses in either semispace. | 388 // for all addresses in either semispace. |
305 static Address NewSpaceStart() { return new_space_.start(); } | 389 Address NewSpaceStart() { return new_space_.start(); } |
306 static uintptr_t NewSpaceMask() { return new_space_.mask(); } | 390 uintptr_t NewSpaceMask() { return new_space_.mask(); } |
307 static Address NewSpaceTop() { return new_space_.top(); } | 391 Address NewSpaceTop() { return new_space_.top(); } |
308 | 392 |
309 static NewSpace* new_space() { return &new_space_; } | 393 NewSpace* new_space() { return &new_space_; } |
310 static OldSpace* old_pointer_space() { return old_pointer_space_; } | 394 OldSpace* old_pointer_space() { return old_pointer_space_; } |
311 static OldSpace* old_data_space() { return old_data_space_; } | 395 OldSpace* old_data_space() { return old_data_space_; } |
312 static OldSpace* code_space() { return code_space_; } | 396 OldSpace* code_space() { return code_space_; } |
313 static MapSpace* map_space() { return map_space_; } | 397 MapSpace* map_space() { return map_space_; } |
314 static CellSpace* cell_space() { return cell_space_; } | 398 CellSpace* cell_space() { return cell_space_; } |
315 static LargeObjectSpace* lo_space() { return lo_space_; } | 399 LargeObjectSpace* lo_space() { return lo_space_; } |
316 | 400 |
317 static bool always_allocate() { return always_allocate_scope_depth_ != 0; } | 401 bool always_allocate() { return always_allocate_scope_depth_ != 0; } |
318 static Address always_allocate_scope_depth_address() { | 402 Address always_allocate_scope_depth_address() { |
319 return reinterpret_cast<Address>(&always_allocate_scope_depth_); | 403 return reinterpret_cast<Address>(&always_allocate_scope_depth_); |
320 } | 404 } |
321 static bool linear_allocation() { | 405 bool linear_allocation() { |
322 return linear_allocation_scope_depth_ != 0; | 406 return linear_allocation_scope_depth_ != 0; |
323 } | 407 } |
324 | 408 |
325 static Address* NewSpaceAllocationTopAddress() { | 409 Address* NewSpaceAllocationTopAddress() { |
326 return new_space_.allocation_top_address(); | 410 return new_space_.allocation_top_address(); |
327 } | 411 } |
328 static Address* NewSpaceAllocationLimitAddress() { | 412 Address* NewSpaceAllocationLimitAddress() { |
329 return new_space_.allocation_limit_address(); | 413 return new_space_.allocation_limit_address(); |
330 } | 414 } |
331 | 415 |
332 // Uncommit unused semi space. | 416 // Uncommit unused semi space. |
333 static bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); } | 417 bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); } |
334 | 418 |
335 #ifdef ENABLE_HEAP_PROTECTION | 419 #ifdef ENABLE_HEAP_PROTECTION |
336 // Protect/unprotect the heap by marking all spaces read-only/writable. | 420 // Protect/unprotect the heap by marking all spaces read-only/writable. |
337 static void Protect(); | 421 void Protect(); |
338 static void Unprotect(); | 422 void Unprotect(); |
339 #endif | 423 #endif |
340 | 424 |
341 // Allocates and initializes a new JavaScript object based on a | 425 // Allocates and initializes a new JavaScript object based on a |
342 // constructor. | 426 // constructor. |
343 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 427 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
344 // failed. | 428 // failed. |
345 // Please note this does not perform a garbage collection. | 429 // Please note this does not perform a garbage collection. |
346 MUST_USE_RESULT static MaybeObject* AllocateJSObject( | 430 MUST_USE_RESULT MaybeObject* AllocateJSObject( |
347 JSFunction* constructor, PretenureFlag pretenure = NOT_TENURED); | 431 JSFunction* constructor, PretenureFlag pretenure = NOT_TENURED); |
348 | 432 |
349 // Allocates and initializes a new global object based on a constructor. | 433 // Allocates and initializes a new global object based on a constructor. |
350 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 434 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
351 // failed. | 435 // failed. |
352 // Please note this does not perform a garbage collection. | 436 // Please note this does not perform a garbage collection. |
353 MUST_USE_RESULT static MaybeObject* AllocateGlobalObject( | 437 MUST_USE_RESULT MaybeObject* AllocateGlobalObject(JSFunction* constructor); |
354 JSFunction* constructor); | |
355 | 438 |
356 // Returns a deep copy of the JavaScript object. | 439 // Returns a deep copy of the JavaScript object. |
357 // Properties and elements are copied too. | 440 // Properties and elements are copied too. |
358 // Returns failure if allocation failed. | 441 // Returns failure if allocation failed. |
359 MUST_USE_RESULT static MaybeObject* CopyJSObject(JSObject* source); | 442 MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source); |
360 | 443 |
361 // Allocates the function prototype. | 444 // Allocates the function prototype. |
362 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 445 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
363 // failed. | 446 // failed. |
364 // Please note this does not perform a garbage collection. | 447 // Please note this does not perform a garbage collection. |
365 MUST_USE_RESULT static MaybeObject* AllocateFunctionPrototype( | 448 MUST_USE_RESULT MaybeObject* AllocateFunctionPrototype(JSFunction* function); |
366 JSFunction* function); | |
367 | 449 |
368 // Reinitialize an JSGlobalProxy based on a constructor. The object | 450 // Reinitialize an JSGlobalProxy based on a constructor. The object |
369 // must have the same size as objects allocated using the | 451 // must have the same size as objects allocated using the |
370 // constructor. The object is reinitialized and behaves as an | 452 // constructor. The object is reinitialized and behaves as an |
371 // object that has been freshly allocated using the constructor. | 453 // object that has been freshly allocated using the constructor. |
372 MUST_USE_RESULT static MaybeObject* ReinitializeJSGlobalProxy( | 454 MUST_USE_RESULT MaybeObject* ReinitializeJSGlobalProxy( |
373 JSFunction* constructor, | 455 JSFunction* constructor, JSGlobalProxy* global); |
374 JSGlobalProxy* global); | |
375 | 456 |
376 // Allocates and initializes a new JavaScript object based on a map. | 457 // Allocates and initializes a new JavaScript object based on a map. |
377 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 458 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
378 // failed. | 459 // failed. |
379 // Please note this does not perform a garbage collection. | 460 // Please note this does not perform a garbage collection. |
380 MUST_USE_RESULT static MaybeObject* AllocateJSObjectFromMap( | 461 MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMap( |
381 Map* map, PretenureFlag pretenure = NOT_TENURED); | 462 Map* map, PretenureFlag pretenure = NOT_TENURED); |
382 | 463 |
383 // Allocates a heap object based on the map. | 464 // Allocates a heap object based on the map. |
384 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 465 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
385 // failed. | 466 // failed. |
386 // Please note this function does not perform a garbage collection. | 467 // Please note this function does not perform a garbage collection. |
387 MUST_USE_RESULT static MaybeObject* Allocate(Map* map, AllocationSpace space); | 468 MUST_USE_RESULT MaybeObject* Allocate(Map* map, AllocationSpace space); |
388 | 469 |
389 // Allocates a JS Map in the heap. | 470 // Allocates a JS Map in the heap. |
390 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 471 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
391 // failed. | 472 // failed. |
392 // Please note this function does not perform a garbage collection. | 473 // Please note this function does not perform a garbage collection. |
393 MUST_USE_RESULT static MaybeObject* AllocateMap(InstanceType instance_type, | 474 MUST_USE_RESULT MaybeObject* AllocateMap(InstanceType instance_type, |
394 int instance_size); | 475 int instance_size); |
395 | 476 |
396 // Allocates a partial map for bootstrapping. | 477 // Allocates a partial map for bootstrapping. |
397 MUST_USE_RESULT static MaybeObject* AllocatePartialMap( | 478 MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type, |
398 InstanceType instance_type, | 479 int instance_size); |
399 int instance_size); | |
400 | 480 |
401 // Allocate a map for the specified function | 481 // Allocate a map for the specified function |
402 MUST_USE_RESULT static MaybeObject* AllocateInitialMap(JSFunction* fun); | 482 MUST_USE_RESULT MaybeObject* AllocateInitialMap(JSFunction* fun); |
403 | 483 |
404 // Allocates an empty code cache. | 484 // Allocates an empty code cache. |
405 MUST_USE_RESULT static MaybeObject* AllocateCodeCache(); | 485 MUST_USE_RESULT MaybeObject* AllocateCodeCache(); |
406 | 486 |
407 // Clear the Instanceof cache (used when a prototype changes). | 487 // Clear the Instanceof cache (used when a prototype changes). |
408 static void ClearInstanceofCache() { | 488 inline void ClearInstanceofCache(); |
409 set_instanceof_cache_function(the_hole_value()); | |
410 } | |
411 | 489 |
412 // Allocates and fully initializes a String. There are two String | 490 // Allocates and fully initializes a String. There are two String |
413 // encodings: ASCII and two byte. One should choose between the three string | 491 // encodings: ASCII and two byte. One should choose between the three string |
414 // allocation functions based on the encoding of the string buffer used to | 492 // allocation functions based on the encoding of the string buffer used to |
415 // initialized the string. | 493 // initialized the string. |
416 // - ...FromAscii initializes the string from a buffer that is ASCII | 494 // - ...FromAscii initializes the string from a buffer that is ASCII |
417 // encoded (it does not check that the buffer is ASCII encoded) and the | 495 // encoded (it does not check that the buffer is ASCII encoded) and the |
418 // result will be ASCII encoded. | 496 // result will be ASCII encoded. |
419 // - ...FromUTF8 initializes the string from a buffer that is UTF-8 | 497 // - ...FromUTF8 initializes the string from a buffer that is UTF-8 |
420 // encoded. If the characters are all single-byte characters, the | 498 // encoded. If the characters are all single-byte characters, the |
421 // result will be ASCII encoded, otherwise it will converted to two | 499 // result will be ASCII encoded, otherwise it will converted to two |
422 // byte. | 500 // byte. |
423 // - ...FromTwoByte initializes the string from a buffer that is two-byte | 501 // - ...FromTwoByte initializes the string from a buffer that is two-byte |
424 // encoded. If the characters are all single-byte characters, the | 502 // encoded. If the characters are all single-byte characters, the |
425 // result will be converted to ASCII, otherwise it will be left as | 503 // result will be converted to ASCII, otherwise it will be left as |
426 // two-byte. | 504 // two-byte. |
427 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 505 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
428 // failed. | 506 // failed. |
429 // Please note this does not perform a garbage collection. | 507 // Please note this does not perform a garbage collection. |
430 MUST_USE_RESULT static MaybeObject* AllocateStringFromAscii( | 508 MUST_USE_RESULT MaybeObject* AllocateStringFromAscii( |
431 Vector<const char> str, | 509 Vector<const char> str, |
432 PretenureFlag pretenure = NOT_TENURED); | 510 PretenureFlag pretenure = NOT_TENURED); |
433 MUST_USE_RESULT static inline MaybeObject* AllocateStringFromUtf8( | 511 MUST_USE_RESULT inline MaybeObject* AllocateStringFromUtf8( |
434 Vector<const char> str, | 512 Vector<const char> str, |
435 PretenureFlag pretenure = NOT_TENURED); | 513 PretenureFlag pretenure = NOT_TENURED); |
436 MUST_USE_RESULT static MaybeObject* AllocateStringFromUtf8Slow( | 514 MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow( |
437 Vector<const char> str, | 515 Vector<const char> str, |
438 PretenureFlag pretenure = NOT_TENURED); | 516 PretenureFlag pretenure = NOT_TENURED); |
439 MUST_USE_RESULT static MaybeObject* AllocateStringFromTwoByte( | 517 MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte( |
440 Vector<const uc16> str, | 518 Vector<const uc16> str, |
441 PretenureFlag pretenure = NOT_TENURED); | 519 PretenureFlag pretenure = NOT_TENURED); |
442 | 520 |
443 // Allocates a symbol in old space based on the character stream. | 521 // Allocates a symbol in old space based on the character stream. |
444 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 522 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
445 // failed. | 523 // failed. |
446 // Please note this function does not perform a garbage collection. | 524 // Please note this function does not perform a garbage collection. |
447 MUST_USE_RESULT static inline MaybeObject* AllocateSymbol( | 525 MUST_USE_RESULT inline MaybeObject* AllocateSymbol(Vector<const char> str, |
448 Vector<const char> str, | 526 int chars, |
449 int chars, | 527 uint32_t hash_field); |
450 uint32_t hash_field); | |
451 | 528 |
452 MUST_USE_RESULT static inline MaybeObject* AllocateAsciiSymbol( | 529 MUST_USE_RESULT inline MaybeObject* AllocateAsciiSymbol( |
453 Vector<const char> str, | 530 Vector<const char> str, |
454 uint32_t hash_field); | 531 uint32_t hash_field); |
455 | 532 |
456 MUST_USE_RESULT static inline MaybeObject* AllocateTwoByteSymbol( | 533 MUST_USE_RESULT inline MaybeObject* AllocateTwoByteSymbol( |
457 Vector<const uc16> str, | 534 Vector<const uc16> str, |
458 uint32_t hash_field); | 535 uint32_t hash_field); |
459 | 536 |
460 MUST_USE_RESULT static MaybeObject* AllocateInternalSymbol( | 537 MUST_USE_RESULT MaybeObject* AllocateInternalSymbol( |
461 unibrow::CharacterStream* buffer, int chars, uint32_t hash_field); | 538 unibrow::CharacterStream* buffer, int chars, uint32_t hash_field); |
462 | 539 |
463 MUST_USE_RESULT static MaybeObject* AllocateExternalSymbol( | 540 MUST_USE_RESULT MaybeObject* AllocateExternalSymbol( |
464 Vector<const char> str, | 541 Vector<const char> str, |
465 int chars); | 542 int chars); |
466 | 543 |
467 | |
468 // Allocates and partially initializes a String. There are two String | 544 // Allocates and partially initializes a String. There are two String |
469 // encodings: ASCII and two byte. These functions allocate a string of the | 545 // encodings: ASCII and two byte. These functions allocate a string of the |
470 // given length and set its map and length fields. The characters of the | 546 // given length and set its map and length fields. The characters of the |
471 // string are uninitialized. | 547 // string are uninitialized. |
472 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 548 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
473 // failed. | 549 // failed. |
474 // Please note this does not perform a garbage collection. | 550 // Please note this does not perform a garbage collection. |
475 MUST_USE_RESULT static MaybeObject* AllocateRawAsciiString( | 551 MUST_USE_RESULT MaybeObject* AllocateRawAsciiString( |
476 int length, | 552 int length, |
477 PretenureFlag pretenure = NOT_TENURED); | 553 PretenureFlag pretenure = NOT_TENURED); |
478 MUST_USE_RESULT static MaybeObject* AllocateRawTwoByteString( | 554 MUST_USE_RESULT MaybeObject* AllocateRawTwoByteString( |
479 int length, | 555 int length, |
480 PretenureFlag pretenure = NOT_TENURED); | 556 PretenureFlag pretenure = NOT_TENURED); |
481 | 557 |
482 // Computes a single character string where the character has code. | 558 // Computes a single character string where the character has code. |
483 // A cache is used for ascii codes. | 559 // A cache is used for ascii codes. |
484 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 560 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
485 // failed. Please note this does not perform a garbage collection. | 561 // failed. Please note this does not perform a garbage collection. |
486 MUST_USE_RESULT static MaybeObject* LookupSingleCharacterStringFromCode( | 562 MUST_USE_RESULT MaybeObject* LookupSingleCharacterStringFromCode( |
487 uint16_t code); | 563 uint16_t code); |
488 | 564 |
489 // Allocate a byte array of the specified length | 565 // Allocate a byte array of the specified length |
490 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 566 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
491 // failed. | 567 // failed. |
492 // Please note this does not perform a garbage collection. | 568 // Please note this does not perform a garbage collection. |
493 MUST_USE_RESULT static MaybeObject* AllocateByteArray(int length, | 569 MUST_USE_RESULT MaybeObject* AllocateByteArray(int length, |
494 PretenureFlag pretenure); | 570 PretenureFlag pretenure); |
495 | 571 |
496 // Allocate a non-tenured byte array of the specified length | 572 // Allocate a non-tenured byte array of the specified length |
497 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 573 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
498 // failed. | 574 // failed. |
499 // Please note this does not perform a garbage collection. | 575 // Please note this does not perform a garbage collection. |
500 MUST_USE_RESULT static MaybeObject* AllocateByteArray(int length); | 576 MUST_USE_RESULT MaybeObject* AllocateByteArray(int length); |
501 | 577 |
502 // Allocates an external array of the specified length and type. | 578 // Allocates an external array of the specified length and type. |
503 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 579 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
504 // failed. | 580 // failed. |
505 // Please note this does not perform a garbage collection. | 581 // Please note this does not perform a garbage collection. |
506 MUST_USE_RESULT static MaybeObject* AllocateExternalArray( | 582 MUST_USE_RESULT MaybeObject* AllocateExternalArray( |
507 int length, | 583 int length, |
508 ExternalArrayType array_type, | 584 ExternalArrayType array_type, |
509 void* external_pointer, | 585 void* external_pointer, |
510 PretenureFlag pretenure); | 586 PretenureFlag pretenure); |
511 | 587 |
512 // Allocate a tenured JS global property cell. | 588 // Allocate a tenured JS global property cell. |
513 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 589 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
514 // failed. | 590 // failed. |
515 // Please note this does not perform a garbage collection. | 591 // Please note this does not perform a garbage collection. |
516 MUST_USE_RESULT static MaybeObject* AllocateJSGlobalPropertyCell( | 592 MUST_USE_RESULT MaybeObject* AllocateJSGlobalPropertyCell(Object* value); |
517 Object* value); | |
518 | 593 |
519 // Allocates a fixed array initialized with undefined values | 594 // Allocates a fixed array initialized with undefined values |
520 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 595 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
521 // failed. | 596 // failed. |
522 // Please note this does not perform a garbage collection. | 597 // Please note this does not perform a garbage collection. |
523 MUST_USE_RESULT static MaybeObject* AllocateFixedArray( | 598 MUST_USE_RESULT MaybeObject* AllocateFixedArray(int length, |
524 int length, | 599 PretenureFlag pretenure); |
525 PretenureFlag pretenure); | |
526 // Allocates a fixed array initialized with undefined values | 600 // Allocates a fixed array initialized with undefined values |
527 MUST_USE_RESULT static MaybeObject* AllocateFixedArray(int length); | 601 MUST_USE_RESULT MaybeObject* AllocateFixedArray(int length); |
528 | 602 |
529 // Allocates an uninitialized fixed array. It must be filled by the caller. | 603 // Allocates an uninitialized fixed array. It must be filled by the caller. |
530 // | 604 // |
531 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 605 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
532 // failed. | 606 // failed. |
533 // Please note this does not perform a garbage collection. | 607 // Please note this does not perform a garbage collection. |
534 MUST_USE_RESULT static MaybeObject* AllocateUninitializedFixedArray( | 608 MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedArray(int length); |
535 int length); | |
536 | 609 |
537 // Make a copy of src and return it. Returns | 610 // Make a copy of src and return it. Returns |
538 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed. | 611 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed. |
539 MUST_USE_RESULT static inline MaybeObject* CopyFixedArray(FixedArray* src); | 612 MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src); |
540 | 613 |
541 // Make a copy of src, set the map, and return the copy. Returns | 614 // Make a copy of src, set the map, and return the copy. Returns |
542 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed. | 615 // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed. |
543 MUST_USE_RESULT static MaybeObject* CopyFixedArrayWithMap(FixedArray* src, | 616 MUST_USE_RESULT MaybeObject* CopyFixedArrayWithMap(FixedArray* src, Map* map); |
544 Map* map); | |
545 | 617 |
546 // Allocates a fixed array initialized with the hole values. | 618 // Allocates a fixed array initialized with the hole values. |
547 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 619 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
548 // failed. | 620 // failed. |
549 // Please note this does not perform a garbage collection. | 621 // Please note this does not perform a garbage collection. |
550 MUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithHoles( | 622 MUST_USE_RESULT MaybeObject* AllocateFixedArrayWithHoles( |
551 int length, | 623 int length, |
552 PretenureFlag pretenure = NOT_TENURED); | 624 PretenureFlag pretenure = NOT_TENURED); |
553 | 625 |
554 // AllocateHashTable is identical to AllocateFixedArray except | 626 // AllocateHashTable is identical to AllocateFixedArray except |
555 // that the resulting object has hash_table_map as map. | 627 // that the resulting object has hash_table_map as map. |
556 MUST_USE_RESULT static MaybeObject* AllocateHashTable( | 628 MUST_USE_RESULT MaybeObject* AllocateHashTable( |
557 int length, PretenureFlag pretenure = NOT_TENURED); | 629 int length, PretenureFlag pretenure = NOT_TENURED); |
558 | 630 |
559 // Allocate a global (but otherwise uninitialized) context. | 631 // Allocate a global (but otherwise uninitialized) context. |
560 MUST_USE_RESULT static MaybeObject* AllocateGlobalContext(); | 632 MUST_USE_RESULT MaybeObject* AllocateGlobalContext(); |
561 | 633 |
562 // Allocate a function context. | 634 // Allocate a function context. |
563 MUST_USE_RESULT static MaybeObject* AllocateFunctionContext( | 635 MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length, |
564 int length, | 636 JSFunction* closure); |
565 JSFunction* closure); | |
566 | 637 |
567 // Allocate a 'with' context. | 638 // Allocate a 'with' context. |
568 MUST_USE_RESULT static MaybeObject* AllocateWithContext( | 639 MUST_USE_RESULT MaybeObject* AllocateWithContext(Context* previous, |
569 Context* previous, | 640 JSObject* extension, |
570 JSObject* extension, | 641 bool is_catch_context); |
571 bool is_catch_context); | |
572 | 642 |
573 // Allocates a new utility object in the old generation. | 643 // Allocates a new utility object in the old generation. |
574 MUST_USE_RESULT static MaybeObject* AllocateStruct(InstanceType type); | 644 MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type); |
575 | 645 |
576 // Allocates a function initialized with a shared part. | 646 // Allocates a function initialized with a shared part. |
577 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 647 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
578 // failed. | 648 // failed. |
579 // Please note this does not perform a garbage collection. | 649 // Please note this does not perform a garbage collection. |
580 MUST_USE_RESULT static MaybeObject* AllocateFunction( | 650 MUST_USE_RESULT MaybeObject* AllocateFunction( |
581 Map* function_map, | 651 Map* function_map, |
582 SharedFunctionInfo* shared, | 652 SharedFunctionInfo* shared, |
583 Object* prototype, | 653 Object* prototype, |
584 PretenureFlag pretenure = TENURED); | 654 PretenureFlag pretenure = TENURED); |
585 | 655 |
586 // Arguments object size. | 656 // Arguments object size. |
587 static const int kArgumentsObjectSize = | 657 static const int kArgumentsObjectSize = |
588 JSObject::kHeaderSize + 2 * kPointerSize; | 658 JSObject::kHeaderSize + 2 * kPointerSize; |
589 // Strict mode arguments has no callee so it is smaller. | 659 // Strict mode arguments has no callee so it is smaller. |
590 static const int kArgumentsObjectSizeStrict = | 660 static const int kArgumentsObjectSizeStrict = |
591 JSObject::kHeaderSize + 1 * kPointerSize; | 661 JSObject::kHeaderSize + 1 * kPointerSize; |
592 // Indicies for direct access into argument objects. | 662 // Indicies for direct access into argument objects. |
593 static const int kArgumentsLengthIndex = 0; | 663 static const int kArgumentsLengthIndex = 0; |
594 // callee is only valid in non-strict mode. | 664 // callee is only valid in non-strict mode. |
595 static const int kArgumentsCalleeIndex = 1; | 665 static const int kArgumentsCalleeIndex = 1; |
596 | 666 |
597 // Allocates an arguments object - optionally with an elements array. | 667 // Allocates an arguments object - optionally with an elements array. |
598 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 668 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
599 // failed. | 669 // failed. |
600 // Please note this does not perform a garbage collection. | 670 // Please note this does not perform a garbage collection. |
601 MUST_USE_RESULT static MaybeObject* AllocateArgumentsObject(Object* callee, | 671 MUST_USE_RESULT MaybeObject* AllocateArgumentsObject( |
602 int length); | 672 Object* callee, int length); |
603 | 673 |
604 // Same as NewNumberFromDouble, but may return a preallocated/immutable | 674 // Same as NewNumberFromDouble, but may return a preallocated/immutable |
605 // number object (e.g., minus_zero_value_, nan_value_) | 675 // number object (e.g., minus_zero_value_, nan_value_) |
606 MUST_USE_RESULT static MaybeObject* NumberFromDouble( | 676 MUST_USE_RESULT MaybeObject* NumberFromDouble( |
607 double value, PretenureFlag pretenure = NOT_TENURED); | 677 double value, PretenureFlag pretenure = NOT_TENURED); |
608 | 678 |
609 // Allocated a HeapNumber from value. | 679 // Allocated a HeapNumber from value. |
610 MUST_USE_RESULT static MaybeObject* AllocateHeapNumber( | 680 MUST_USE_RESULT MaybeObject* AllocateHeapNumber( |
611 double value, | 681 double value, |
612 PretenureFlag pretenure); | 682 PretenureFlag pretenure); |
613 // pretenure = NOT_TENURED. | 683 // pretenure = NOT_TENURED |
614 MUST_USE_RESULT static MaybeObject* AllocateHeapNumber(double value); | 684 MUST_USE_RESULT MaybeObject* AllocateHeapNumber(double value); |
615 | 685 |
616 // Converts an int into either a Smi or a HeapNumber object. | 686 // Converts an int into either a Smi or a HeapNumber object. |
617 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 687 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
618 // failed. | 688 // failed. |
619 // Please note this does not perform a garbage collection. | 689 // Please note this does not perform a garbage collection. |
620 MUST_USE_RESULT static inline MaybeObject* NumberFromInt32(int32_t value); | 690 MUST_USE_RESULT inline MaybeObject* NumberFromInt32(int32_t value); |
621 | 691 |
622 // Converts an int into either a Smi or a HeapNumber object. | 692 // Converts an int into either a Smi or a HeapNumber object. |
623 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 693 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
624 // failed. | 694 // failed. |
625 // Please note this does not perform a garbage collection. | 695 // Please note this does not perform a garbage collection. |
626 MUST_USE_RESULT static inline MaybeObject* NumberFromUint32(uint32_t value); | 696 MUST_USE_RESULT inline MaybeObject* NumberFromUint32(uint32_t value); |
627 | 697 |
628 // Allocates a new proxy object. | 698 // Allocates a new proxy object. |
629 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 699 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
630 // failed. | 700 // failed. |
631 // Please note this does not perform a garbage collection. | 701 // Please note this does not perform a garbage collection. |
632 MUST_USE_RESULT static MaybeObject* AllocateProxy( | 702 MUST_USE_RESULT MaybeObject* AllocateProxy( |
633 Address proxy, | 703 Address proxy, PretenureFlag pretenure = NOT_TENURED); |
634 PretenureFlag pretenure = NOT_TENURED); | |
635 | 704 |
636 // Allocates a new SharedFunctionInfo object. | 705 // Allocates a new SharedFunctionInfo object. |
637 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 706 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
638 // failed. | 707 // failed. |
639 // Please note this does not perform a garbage collection. | 708 // Please note this does not perform a garbage collection. |
640 MUST_USE_RESULT static MaybeObject* AllocateSharedFunctionInfo(Object* name); | 709 MUST_USE_RESULT MaybeObject* AllocateSharedFunctionInfo(Object* name); |
641 | 710 |
642 // Allocates a new JSMessageObject object. | 711 // Allocates a new JSMessageObject object. |
643 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 712 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
644 // failed. | 713 // failed. |
645 // Please note that this does not perform a garbage collection. | 714 // Please note that this does not perform a garbage collection. |
646 MUST_USE_RESULT static MaybeObject* AllocateJSMessageObject( | 715 MUST_USE_RESULT MaybeObject* AllocateJSMessageObject( |
647 String* type, | 716 String* type, |
648 JSArray* arguments, | 717 JSArray* arguments, |
649 int start_position, | 718 int start_position, |
650 int end_position, | 719 int end_position, |
651 Object* script, | 720 Object* script, |
652 Object* stack_trace, | 721 Object* stack_trace, |
653 Object* stack_frames); | 722 Object* stack_frames); |
654 | 723 |
655 // Allocates a new cons string object. | 724 // Allocates a new cons string object. |
656 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 725 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
657 // failed. | 726 // failed. |
658 // Please note this does not perform a garbage collection. | 727 // Please note this does not perform a garbage collection. |
659 MUST_USE_RESULT static MaybeObject* AllocateConsString(String* first, | 728 MUST_USE_RESULT MaybeObject* AllocateConsString(String* first, |
660 String* second); | 729 String* second); |
661 | 730 |
662 // Allocates a new sub string object which is a substring of an underlying | 731 // Allocates a new sub string object which is a substring of an underlying |
663 // string buffer stretching from the index start (inclusive) to the index | 732 // string buffer stretching from the index start (inclusive) to the index |
664 // end (exclusive). | 733 // end (exclusive). |
665 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 734 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
666 // failed. | 735 // failed. |
667 // Please note this does not perform a garbage collection. | 736 // Please note this does not perform a garbage collection. |
668 MUST_USE_RESULT static MaybeObject* AllocateSubString( | 737 MUST_USE_RESULT MaybeObject* AllocateSubString( |
669 String* buffer, | 738 String* buffer, |
670 int start, | 739 int start, |
671 int end, | 740 int end, |
672 PretenureFlag pretenure = NOT_TENURED); | 741 PretenureFlag pretenure = NOT_TENURED); |
673 | 742 |
674 // Allocate a new external string object, which is backed by a string | 743 // Allocate a new external string object, which is backed by a string |
675 // resource that resides outside the V8 heap. | 744 // resource that resides outside the V8 heap. |
676 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 745 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
677 // failed. | 746 // failed. |
678 // Please note this does not perform a garbage collection. | 747 // Please note this does not perform a garbage collection. |
679 MUST_USE_RESULT static MaybeObject* AllocateExternalStringFromAscii( | 748 MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii( |
680 ExternalAsciiString::Resource* resource); | 749 ExternalAsciiString::Resource* resource); |
681 MUST_USE_RESULT static MaybeObject* AllocateExternalStringFromTwoByte( | 750 MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte( |
682 ExternalTwoByteString::Resource* resource); | 751 ExternalTwoByteString::Resource* resource); |
683 | 752 |
684 // Finalizes an external string by deleting the associated external | 753 // Finalizes an external string by deleting the associated external |
685 // data and clearing the resource pointer. | 754 // data and clearing the resource pointer. |
686 static inline void FinalizeExternalString(String* string); | 755 inline void FinalizeExternalString(String* string); |
687 | 756 |
688 // Allocates an uninitialized object. The memory is non-executable if the | 757 // Allocates an uninitialized object. The memory is non-executable if the |
689 // hardware and OS allow. | 758 // hardware and OS allow. |
690 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 759 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
691 // failed. | 760 // failed. |
692 // Please note this function does not perform a garbage collection. | 761 // Please note this function does not perform a garbage collection. |
693 MUST_USE_RESULT static inline MaybeObject* AllocateRaw( | 762 MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes, |
694 int size_in_bytes, | 763 AllocationSpace space, |
695 AllocationSpace space, | 764 AllocationSpace retry_space); |
696 AllocationSpace retry_space); | |
697 | 765 |
698 // Initialize a filler object to keep the ability to iterate over the heap | 766 // Initialize a filler object to keep the ability to iterate over the heap |
699 // when shortening objects. | 767 // when shortening objects. |
700 static void CreateFillerObjectAt(Address addr, int size); | 768 void CreateFillerObjectAt(Address addr, int size); |
701 | 769 |
702 // Makes a new native code object | 770 // Makes a new native code object |
703 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 771 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
704 // failed. On success, the pointer to the Code object is stored in the | 772 // failed. On success, the pointer to the Code object is stored in the |
705 // self_reference. This allows generated code to reference its own Code | 773 // self_reference. This allows generated code to reference its own Code |
706 // object by containing this pointer. | 774 // object by containing this pointer. |
707 // Please note this function does not perform a garbage collection. | 775 // Please note this function does not perform a garbage collection. |
708 MUST_USE_RESULT static MaybeObject* CreateCode(const CodeDesc& desc, | 776 MUST_USE_RESULT MaybeObject* CreateCode(const CodeDesc& desc, |
709 Code::Flags flags, | 777 Code::Flags flags, |
710 Handle<Object> self_reference, | 778 Handle<Object> self_reference, |
711 bool immovable = false); | 779 bool immovable = false); |
712 | 780 |
713 MUST_USE_RESULT static MaybeObject* CopyCode(Code* code); | 781 MUST_USE_RESULT MaybeObject* CopyCode(Code* code); |
714 | 782 |
715 // Copy the code and scope info part of the code object, but insert | 783 // Copy the code and scope info part of the code object, but insert |
716 // the provided data as the relocation information. | 784 // the provided data as the relocation information. |
717 MUST_USE_RESULT static MaybeObject* CopyCode(Code* code, | 785 MUST_USE_RESULT MaybeObject* CopyCode(Code* code, Vector<byte> reloc_info); |
718 Vector<byte> reloc_info); | |
719 | 786 |
720 // Finds the symbol for string in the symbol table. | 787 // Finds the symbol for string in the symbol table. |
721 // If not found, a new symbol is added to the table and returned. | 788 // If not found, a new symbol is added to the table and returned. |
722 // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation | 789 // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation |
723 // failed. | 790 // failed. |
724 // Please note this function does not perform a garbage collection. | 791 // Please note this function does not perform a garbage collection. |
725 MUST_USE_RESULT static MaybeObject* LookupSymbol(Vector<const char> str); | 792 MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str); |
726 MUST_USE_RESULT static MaybeObject* LookupAsciiSymbol(Vector<const char> str); | 793 MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str); |
727 MUST_USE_RESULT static MaybeObject* LookupTwoByteSymbol( | 794 MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol( |
728 Vector<const uc16> str); | 795 Vector<const uc16> str); |
729 MUST_USE_RESULT static MaybeObject* LookupAsciiSymbol(const char* str) { | 796 MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(const char* str) { |
730 return LookupSymbol(CStrVector(str)); | 797 return LookupSymbol(CStrVector(str)); |
731 } | 798 } |
732 MUST_USE_RESULT static MaybeObject* LookupSymbol(String* str); | 799 MUST_USE_RESULT MaybeObject* LookupSymbol(String* str); |
733 static bool LookupSymbolIfExists(String* str, String** symbol); | 800 bool LookupSymbolIfExists(String* str, String** symbol); |
734 static bool LookupTwoCharsSymbolIfExists(String* str, String** symbol); | 801 bool LookupTwoCharsSymbolIfExists(String* str, String** symbol); |
735 | 802 |
736 // Compute the matching symbol map for a string if possible. | 803 // Compute the matching symbol map for a string if possible. |
737 // NULL is returned if string is in new space or not flattened. | 804 // NULL is returned if string is in new space or not flattened. |
738 static Map* SymbolMapForString(String* str); | 805 Map* SymbolMapForString(String* str); |
739 | 806 |
740 // Tries to flatten a string before compare operation. | 807 // Tries to flatten a string before compare operation. |
741 // | 808 // |
742 // Returns a failure in case it was decided that flattening was | 809 // Returns a failure in case it was decided that flattening was |
743 // necessary and failed. Note, if flattening is not necessary the | 810 // necessary and failed. Note, if flattening is not necessary the |
744 // string might stay non-flat even when not a failure is returned. | 811 // string might stay non-flat even when not a failure is returned. |
745 // | 812 // |
746 // Please note this function does not perform a garbage collection. | 813 // Please note this function does not perform a garbage collection. |
747 MUST_USE_RESULT static inline MaybeObject* PrepareForCompare(String* str); | 814 MUST_USE_RESULT inline MaybeObject* PrepareForCompare(String* str); |
748 | 815 |
749 // Converts the given boolean condition to JavaScript boolean value. | 816 // Converts the given boolean condition to JavaScript boolean value. |
750 static Object* ToBoolean(bool condition) { | 817 inline Object* ToBoolean(bool condition); |
751 return condition ? true_value() : false_value(); | |
752 } | |
753 | 818 |
754 // Code that should be run before and after each GC. Includes some | 819 // Code that should be run before and after each GC. Includes some |
755 // reporting/verification activities when compiled with DEBUG set. | 820 // reporting/verification activities when compiled with DEBUG set. |
756 static void GarbageCollectionPrologue(); | 821 void GarbageCollectionPrologue(); |
757 static void GarbageCollectionEpilogue(); | 822 void GarbageCollectionEpilogue(); |
758 | 823 |
759 // Performs garbage collection operation. | 824 // Performs garbage collection operation. |
760 // Returns whether there is a chance that another major GC could | 825 // Returns whether there is a chance that another major GC could |
761 // collect more garbage. | 826 // collect more garbage. |
762 static bool CollectGarbage(AllocationSpace space, GarbageCollector collector); | 827 bool CollectGarbage(AllocationSpace space, GarbageCollector collector); |
763 | 828 |
764 // Performs garbage collection operation. | 829 // Performs garbage collection operation. |
765 // Returns whether there is a chance that another major GC could | 830 // Returns whether there is a chance that another major GC could |
766 // collect more garbage. | 831 // collect more garbage. |
767 inline static bool CollectGarbage(AllocationSpace space); | 832 inline bool CollectGarbage(AllocationSpace space); |
768 | 833 |
769 // Performs a full garbage collection. Force compaction if the | 834 // Performs a full garbage collection. Force compaction if the |
770 // parameter is true. | 835 // parameter is true. |
771 static void CollectAllGarbage(bool force_compaction); | 836 void CollectAllGarbage(bool force_compaction); |
772 | 837 |
773 // Last hope GC, should try to squeeze as much as possible. | 838 // Last hope GC, should try to squeeze as much as possible. |
774 static void CollectAllAvailableGarbage(); | 839 void CollectAllAvailableGarbage(); |
775 | 840 |
776 // Notify the heap that a context has been disposed. | 841 // Notify the heap that a context has been disposed. |
777 static int NotifyContextDisposed() { return ++contexts_disposed_; } | 842 int NotifyContextDisposed() { return ++contexts_disposed_; } |
778 | 843 |
779 // Utility to invoke the scavenger. This is needed in test code to | 844 // Utility to invoke the scavenger. This is needed in test code to |
780 // ensure correct callback for weak global handles. | 845 // ensure correct callback for weak global handles. |
781 static void PerformScavenge(); | 846 void PerformScavenge(); |
| 847 |
| 848 PromotionQueue* promotion_queue() { return &promotion_queue_; } |
782 | 849 |
783 #ifdef DEBUG | 850 #ifdef DEBUG |
784 // Utility used with flag gc-greedy. | 851 // Utility used with flag gc-greedy. |
785 static void GarbageCollectionGreedyCheck(); | 852 void GarbageCollectionGreedyCheck(); |
786 #endif | 853 #endif |
787 | 854 |
788 static void AddGCPrologueCallback( | 855 void AddGCPrologueCallback( |
789 GCEpilogueCallback callback, GCType gc_type_filter); | 856 GCEpilogueCallback callback, GCType gc_type_filter); |
790 static void RemoveGCPrologueCallback(GCEpilogueCallback callback); | 857 void RemoveGCPrologueCallback(GCEpilogueCallback callback); |
791 | 858 |
792 static void AddGCEpilogueCallback( | 859 void AddGCEpilogueCallback( |
793 GCEpilogueCallback callback, GCType gc_type_filter); | 860 GCEpilogueCallback callback, GCType gc_type_filter); |
794 static void RemoveGCEpilogueCallback(GCEpilogueCallback callback); | 861 void RemoveGCEpilogueCallback(GCEpilogueCallback callback); |
795 | 862 |
796 static void SetGlobalGCPrologueCallback(GCCallback callback) { | 863 void SetGlobalGCPrologueCallback(GCCallback callback) { |
797 ASSERT((callback == NULL) ^ (global_gc_prologue_callback_ == NULL)); | 864 ASSERT((callback == NULL) ^ (global_gc_prologue_callback_ == NULL)); |
798 global_gc_prologue_callback_ = callback; | 865 global_gc_prologue_callback_ = callback; |
799 } | 866 } |
800 static void SetGlobalGCEpilogueCallback(GCCallback callback) { | 867 void SetGlobalGCEpilogueCallback(GCCallback callback) { |
801 ASSERT((callback == NULL) ^ (global_gc_epilogue_callback_ == NULL)); | 868 ASSERT((callback == NULL) ^ (global_gc_epilogue_callback_ == NULL)); |
802 global_gc_epilogue_callback_ = callback; | 869 global_gc_epilogue_callback_ = callback; |
803 } | 870 } |
804 | 871 |
805 // Heap root getters. We have versions with and without type::cast() here. | 872 // Heap root getters. We have versions with and without type::cast() here. |
806 // You can't use type::cast during GC because the assert fails. | 873 // You can't use type::cast during GC because the assert fails. |
807 #define ROOT_ACCESSOR(type, name, camel_name) \ | 874 #define ROOT_ACCESSOR(type, name, camel_name) \ |
808 static inline type* name() { \ | 875 type* name() { \ |
809 return type::cast(roots_[k##camel_name##RootIndex]); \ | 876 return type::cast(roots_[k##camel_name##RootIndex]); \ |
810 } \ | 877 } \ |
811 static inline type* raw_unchecked_##name() { \ | 878 type* raw_unchecked_##name() { \ |
812 return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \ | 879 return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \ |
813 } | 880 } |
814 ROOT_LIST(ROOT_ACCESSOR) | 881 ROOT_LIST(ROOT_ACCESSOR) |
815 #undef ROOT_ACCESSOR | 882 #undef ROOT_ACCESSOR |
816 | 883 |
817 // Utility type maps | 884 // Utility type maps |
818 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) \ | 885 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) \ |
819 static inline Map* name##_map() { \ | 886 Map* name##_map() { \ |
820 return Map::cast(roots_[k##Name##MapRootIndex]); \ | 887 return Map::cast(roots_[k##Name##MapRootIndex]); \ |
821 } | 888 } |
822 STRUCT_LIST(STRUCT_MAP_ACCESSOR) | 889 STRUCT_LIST(STRUCT_MAP_ACCESSOR) |
823 #undef STRUCT_MAP_ACCESSOR | 890 #undef STRUCT_MAP_ACCESSOR |
824 | 891 |
825 #define SYMBOL_ACCESSOR(name, str) static inline String* name() { \ | 892 #define SYMBOL_ACCESSOR(name, str) String* name() { \ |
826 return String::cast(roots_[k##name##RootIndex]); \ | 893 return String::cast(roots_[k##name##RootIndex]); \ |
827 } | 894 } |
828 SYMBOL_LIST(SYMBOL_ACCESSOR) | 895 SYMBOL_LIST(SYMBOL_ACCESSOR) |
829 #undef SYMBOL_ACCESSOR | 896 #undef SYMBOL_ACCESSOR |
830 | 897 |
831 // The hidden_symbol is special because it is the empty string, but does | 898 // The hidden_symbol is special because it is the empty string, but does |
832 // not match the empty string. | 899 // not match the empty string. |
833 static String* hidden_symbol() { return hidden_symbol_; } | 900 String* hidden_symbol() { return hidden_symbol_; } |
834 | 901 |
835 static void set_global_contexts_list(Object* object) { | 902 void set_global_contexts_list(Object* object) { |
836 global_contexts_list_ = object; | 903 global_contexts_list_ = object; |
837 } | 904 } |
838 static Object* global_contexts_list() { return global_contexts_list_; } | 905 Object* global_contexts_list() { return global_contexts_list_; } |
839 | 906 |
840 // Iterates over all roots in the heap. | 907 // Iterates over all roots in the heap. |
841 static void IterateRoots(ObjectVisitor* v, VisitMode mode); | 908 void IterateRoots(ObjectVisitor* v, VisitMode mode); |
842 // Iterates over all strong roots in the heap. | 909 // Iterates over all strong roots in the heap. |
843 static void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); | 910 void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); |
844 // Iterates over all the other roots in the heap. | 911 // Iterates over all the other roots in the heap. |
845 static void IterateWeakRoots(ObjectVisitor* v, VisitMode mode); | 912 void IterateWeakRoots(ObjectVisitor* v, VisitMode mode); |
846 | 913 |
847 enum ExpectedPageWatermarkState { | 914 enum ExpectedPageWatermarkState { |
848 WATERMARK_SHOULD_BE_VALID, | 915 WATERMARK_SHOULD_BE_VALID, |
849 WATERMARK_CAN_BE_INVALID | 916 WATERMARK_CAN_BE_INVALID |
850 }; | 917 }; |
851 | 918 |
852 // For each dirty region on a page in use from an old space call | 919 // For each dirty region on a page in use from an old space call |
853 // visit_dirty_region callback. | 920 // visit_dirty_region callback. |
854 // If either visit_dirty_region or callback can cause an allocation | 921 // If either visit_dirty_region or callback can cause an allocation |
855 // in old space and changes in allocation watermark then | 922 // in old space and changes in allocation watermark then |
856 // can_preallocate_during_iteration should be set to true. | 923 // can_preallocate_during_iteration should be set to true. |
857 // All pages will be marked as having invalid watermark upon | 924 // All pages will be marked as having invalid watermark upon |
858 // iteration completion. | 925 // iteration completion. |
859 static void IterateDirtyRegions( | 926 void IterateDirtyRegions( |
860 PagedSpace* space, | 927 PagedSpace* space, |
861 DirtyRegionCallback visit_dirty_region, | 928 DirtyRegionCallback visit_dirty_region, |
862 ObjectSlotCallback callback, | 929 ObjectSlotCallback callback, |
863 ExpectedPageWatermarkState expected_page_watermark_state); | 930 ExpectedPageWatermarkState expected_page_watermark_state); |
864 | 931 |
865 // Interpret marks as a bitvector of dirty marks for regions of size | 932 // Interpret marks as a bitvector of dirty marks for regions of size |
866 // Page::kRegionSize aligned by Page::kRegionAlignmentMask and covering | 933 // Page::kRegionSize aligned by Page::kRegionAlignmentMask and covering |
867 // memory interval from start to top. For each dirty region call a | 934 // memory interval from start to top. For each dirty region call a |
868 // visit_dirty_region callback. Return updated bitvector of dirty marks. | 935 // visit_dirty_region callback. Return updated bitvector of dirty marks. |
869 static uint32_t IterateDirtyRegions(uint32_t marks, | 936 uint32_t IterateDirtyRegions(uint32_t marks, |
870 Address start, | 937 Address start, |
871 Address end, | 938 Address end, |
872 DirtyRegionCallback visit_dirty_region, | 939 DirtyRegionCallback visit_dirty_region, |
873 ObjectSlotCallback callback); | 940 ObjectSlotCallback callback); |
874 | 941 |
875 // Iterate pointers to from semispace of new space found in memory interval | 942 // Iterate pointers to from semispace of new space found in memory interval |
876 // from start to end. | 943 // from start to end. |
877 // Update dirty marks for page containing start address. | 944 // Update dirty marks for page containing start address. |
878 static void IterateAndMarkPointersToFromSpace(Address start, | 945 void IterateAndMarkPointersToFromSpace(Address start, |
879 Address end, | 946 Address end, |
880 ObjectSlotCallback callback); | 947 ObjectSlotCallback callback); |
881 | 948 |
882 // Iterate pointers to new space found in memory interval from start to end. | 949 // Iterate pointers to new space found in memory interval from start to end. |
883 // Return true if pointers to new space was found. | 950 // Return true if pointers to new space was found. |
884 static bool IteratePointersInDirtyRegion(Address start, | 951 static bool IteratePointersInDirtyRegion(Heap* heap, |
| 952 Address start, |
885 Address end, | 953 Address end, |
886 ObjectSlotCallback callback); | 954 ObjectSlotCallback callback); |
887 | 955 |
888 | 956 |
889 // Iterate pointers to new space found in memory interval from start to end. | 957 // Iterate pointers to new space found in memory interval from start to end. |
890 // This interval is considered to belong to the map space. | 958 // This interval is considered to belong to the map space. |
891 // Return true if pointers to new space was found. | 959 // Return true if pointers to new space was found. |
892 static bool IteratePointersInDirtyMapsRegion(Address start, | 960 static bool IteratePointersInDirtyMapsRegion(Heap* heap, |
| 961 Address start, |
893 Address end, | 962 Address end, |
894 ObjectSlotCallback callback); | 963 ObjectSlotCallback callback); |
895 | 964 |
896 | 965 |
897 // Returns whether the object resides in new space. | 966 // Returns whether the object resides in new space. |
898 static inline bool InNewSpace(Object* object); | 967 inline bool InNewSpace(Object* object); |
899 static inline bool InFromSpace(Object* object); | 968 inline bool InFromSpace(Object* object); |
900 static inline bool InToSpace(Object* object); | 969 inline bool InToSpace(Object* object); |
901 | 970 |
902 // Checks whether an address/object in the heap (including auxiliary | 971 // Checks whether an address/object in the heap (including auxiliary |
903 // area and unused area). | 972 // area and unused area). |
904 static bool Contains(Address addr); | 973 bool Contains(Address addr); |
905 static bool Contains(HeapObject* value); | 974 bool Contains(HeapObject* value); |
906 | 975 |
907 // Checks whether an address/object in a space. | 976 // Checks whether an address/object in a space. |
908 // Currently used by tests, serialization and heap verification only. | 977 // Currently used by tests, serialization and heap verification only. |
909 static bool InSpace(Address addr, AllocationSpace space); | 978 bool InSpace(Address addr, AllocationSpace space); |
910 static bool InSpace(HeapObject* value, AllocationSpace space); | 979 bool InSpace(HeapObject* value, AllocationSpace space); |
911 | 980 |
912 // Finds out which space an object should get promoted to based on its type. | 981 // Finds out which space an object should get promoted to based on its type. |
913 static inline OldSpace* TargetSpace(HeapObject* object); | 982 inline OldSpace* TargetSpace(HeapObject* object); |
914 static inline AllocationSpace TargetSpaceId(InstanceType type); | 983 inline AllocationSpace TargetSpaceId(InstanceType type); |
915 | 984 |
916 // Sets the stub_cache_ (only used when expanding the dictionary). | 985 // Sets the stub_cache_ (only used when expanding the dictionary). |
917 static void public_set_code_stubs(NumberDictionary* value) { | 986 void public_set_code_stubs(NumberDictionary* value) { |
918 roots_[kCodeStubsRootIndex] = value; | 987 roots_[kCodeStubsRootIndex] = value; |
919 } | 988 } |
920 | 989 |
921 // Support for computing object sizes for old objects during GCs. Returns | 990 // Support for computing object sizes for old objects during GCs. Returns |
922 // a function that is guaranteed to be safe for computing object sizes in | 991 // a function that is guaranteed to be safe for computing object sizes in |
923 // the current GC phase. | 992 // the current GC phase. |
924 static HeapObjectCallback GcSafeSizeOfOldObjectFunction() { | 993 HeapObjectCallback GcSafeSizeOfOldObjectFunction() { |
925 return gc_safe_size_of_old_object_; | 994 return gc_safe_size_of_old_object_; |
926 } | 995 } |
927 | 996 |
928 // Sets the non_monomorphic_cache_ (only used when expanding the dictionary). | 997 // Sets the non_monomorphic_cache_ (only used when expanding the dictionary). |
929 static void public_set_non_monomorphic_cache(NumberDictionary* value) { | 998 void public_set_non_monomorphic_cache(NumberDictionary* value) { |
930 roots_[kNonMonomorphicCacheRootIndex] = value; | 999 roots_[kNonMonomorphicCacheRootIndex] = value; |
931 } | 1000 } |
932 | 1001 |
933 static void public_set_empty_script(Script* script) { | 1002 void public_set_empty_script(Script* script) { |
934 roots_[kEmptyScriptRootIndex] = script; | 1003 roots_[kEmptyScriptRootIndex] = script; |
935 } | 1004 } |
936 | 1005 |
937 // Update the next script id. | 1006 // Update the next script id. |
938 static inline void SetLastScriptId(Object* last_script_id); | 1007 inline void SetLastScriptId(Object* last_script_id); |
939 | 1008 |
940 // Generated code can embed this address to get access to the roots. | 1009 // Generated code can embed this address to get access to the roots. |
941 static Object** roots_address() { return roots_; } | 1010 Object** roots_address() { return roots_; } |
942 | 1011 |
943 // Get address of global contexts list for serialization support. | 1012 // Get address of global contexts list for serialization support. |
944 static Object** global_contexts_list_address() { | 1013 Object** global_contexts_list_address() { |
945 return &global_contexts_list_; | 1014 return &global_contexts_list_; |
946 } | 1015 } |
947 | 1016 |
948 #ifdef DEBUG | 1017 #ifdef DEBUG |
949 static void Print(); | 1018 void Print(); |
950 static void PrintHandles(); | 1019 void PrintHandles(); |
951 | 1020 |
952 // Verify the heap is in its normal state before or after a GC. | 1021 // Verify the heap is in its normal state before or after a GC. |
953 static void Verify(); | 1022 void Verify(); |
954 | 1023 |
955 // Report heap statistics. | 1024 // Report heap statistics. |
956 static void ReportHeapStatistics(const char* title); | 1025 void ReportHeapStatistics(const char* title); |
957 static void ReportCodeStatistics(const char* title); | 1026 void ReportCodeStatistics(const char* title); |
958 | 1027 |
959 // Fill in bogus values in from space | 1028 // Fill in bogus values in from space |
960 static void ZapFromSpace(); | 1029 void ZapFromSpace(); |
961 #endif | 1030 #endif |
962 | 1031 |
963 #if defined(ENABLE_LOGGING_AND_PROFILING) | 1032 #if defined(ENABLE_LOGGING_AND_PROFILING) |
964 // Print short heap statistics. | 1033 // Print short heap statistics. |
965 static void PrintShortHeapStatistics(); | 1034 void PrintShortHeapStatistics(); |
966 #endif | 1035 #endif |
967 | 1036 |
968 // Makes a new symbol object | 1037 // Makes a new symbol object |
969 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation | 1038 // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation |
970 // failed. | 1039 // failed. |
971 // Please note this function does not perform a garbage collection. | 1040 // Please note this function does not perform a garbage collection. |
972 MUST_USE_RESULT static MaybeObject* CreateSymbol(const char* str, | 1041 MUST_USE_RESULT MaybeObject* CreateSymbol( |
973 int length, | 1042 const char* str, int length, int hash); |
974 int hash); | 1043 MUST_USE_RESULT MaybeObject* CreateSymbol(String* str); |
975 MUST_USE_RESULT static MaybeObject* CreateSymbol(String* str); | |
976 | 1044 |
977 // Write barrier support for address[offset] = o. | 1045 // Write barrier support for address[offset] = o. |
978 static inline void RecordWrite(Address address, int offset); | 1046 inline void RecordWrite(Address address, int offset); |
979 | 1047 |
980 // Write barrier support for address[start : start + len[ = o. | 1048 // Write barrier support for address[start : start + len[ = o. |
981 static inline void RecordWrites(Address address, int start, int len); | 1049 inline void RecordWrites(Address address, int start, int len); |
982 | 1050 |
983 // Given an address occupied by a live code object, return that object. | 1051 // Given an address occupied by a live code object, return that object. |
984 static Object* FindCodeObject(Address a); | 1052 Object* FindCodeObject(Address a); |
985 | 1053 |
986 // Invoke Shrink on shrinkable spaces. | 1054 // Invoke Shrink on shrinkable spaces. |
987 static void Shrink(); | 1055 void Shrink(); |
988 | 1056 |
989 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT }; | 1057 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT }; |
990 static inline HeapState gc_state() { return gc_state_; } | 1058 inline HeapState gc_state() { return gc_state_; } |
991 | 1059 |
992 #ifdef DEBUG | 1060 #ifdef DEBUG |
993 static bool IsAllocationAllowed() { return allocation_allowed_; } | 1061 bool IsAllocationAllowed() { return allocation_allowed_; } |
994 static inline bool allow_allocation(bool enable); | 1062 inline bool allow_allocation(bool enable); |
995 | 1063 |
996 static bool disallow_allocation_failure() { | 1064 bool disallow_allocation_failure() { |
997 return disallow_allocation_failure_; | 1065 return disallow_allocation_failure_; |
998 } | 1066 } |
999 | 1067 |
1000 static void TracePathToObject(Object* target); | 1068 void TracePathToObject(Object* target); |
1001 static void TracePathToGlobal(); | 1069 void TracePathToGlobal(); |
1002 #endif | 1070 #endif |
1003 | 1071 |
1004 // Callback function passed to Heap::Iterate etc. Copies an object if | 1072 // Callback function passed to Heap::Iterate etc. Copies an object if |
1005 // necessary, the object might be promoted to an old space. The caller must | 1073 // necessary, the object might be promoted to an old space. The caller must |
1006 // ensure the precondition that the object is (a) a heap object and (b) in | 1074 // ensure the precondition that the object is (a) a heap object and (b) in |
1007 // the heap's from space. | 1075 // the heap's from space. |
1008 static void ScavengePointer(HeapObject** p); | 1076 static inline void ScavengePointer(HeapObject** p); |
1009 static inline void ScavengeObject(HeapObject** p, HeapObject* object); | 1077 static inline void ScavengeObject(HeapObject** p, HeapObject* object); |
1010 | 1078 |
1011 // Commits from space if it is uncommitted. | 1079 // Commits from space if it is uncommitted. |
1012 static void EnsureFromSpaceIsCommitted(); | 1080 void EnsureFromSpaceIsCommitted(); |
1013 | 1081 |
1014 // Support for partial snapshots. After calling this we can allocate a | 1082 // Support for partial snapshots. After calling this we can allocate a |
1015 // certain number of bytes using only linear allocation (with a | 1083 // certain number of bytes using only linear allocation (with a |
1016 // LinearAllocationScope and an AlwaysAllocateScope) without using freelists | 1084 // LinearAllocationScope and an AlwaysAllocateScope) without using freelists |
1017 // or causing a GC. It returns true of space was reserved or false if a GC is | 1085 // or causing a GC. It returns true of space was reserved or false if a GC is |
1018 // needed. For paged spaces the space requested must include the space wasted | 1086 // needed. For paged spaces the space requested must include the space wasted |
1019 // at the end of each page when allocating linearly. | 1087 // at the end of each page when allocating linearly. |
1020 static void ReserveSpace( | 1088 void ReserveSpace( |
1021 int new_space_size, | 1089 int new_space_size, |
1022 int pointer_space_size, | 1090 int pointer_space_size, |
1023 int data_space_size, | 1091 int data_space_size, |
1024 int code_space_size, | 1092 int code_space_size, |
1025 int map_space_size, | 1093 int map_space_size, |
1026 int cell_space_size, | 1094 int cell_space_size, |
1027 int large_object_size); | 1095 int large_object_size); |
1028 | 1096 |
1029 // | 1097 // |
1030 // Support for the API. | 1098 // Support for the API. |
1031 // | 1099 // |
1032 | 1100 |
1033 static bool CreateApiObjects(); | 1101 bool CreateApiObjects(); |
1034 | 1102 |
1035 // Attempt to find the number in a small cache. If we finds it, return | 1103 // Attempt to find the number in a small cache. If we finds it, return |
1036 // the string representation of the number. Otherwise return undefined. | 1104 // the string representation of the number. Otherwise return undefined. |
1037 static Object* GetNumberStringCache(Object* number); | 1105 Object* GetNumberStringCache(Object* number); |
1038 | 1106 |
1039 // Update the cache with a new number-string pair. | 1107 // Update the cache with a new number-string pair. |
1040 static void SetNumberStringCache(Object* number, String* str); | 1108 void SetNumberStringCache(Object* number, String* str); |
1041 | 1109 |
1042 // Adjusts the amount of registered external memory. | 1110 // Adjusts the amount of registered external memory. |
1043 // Returns the adjusted value. | 1111 // Returns the adjusted value. |
1044 static inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes); | 1112 inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes); |
1045 | 1113 |
1046 // Allocate uninitialized fixed array. | 1114 // Allocate uninitialized fixed array. |
1047 MUST_USE_RESULT static MaybeObject* AllocateRawFixedArray(int length); | 1115 MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length); |
1048 MUST_USE_RESULT static MaybeObject* AllocateRawFixedArray( | 1116 MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length, |
1049 int length, | 1117 PretenureFlag pretenure); |
1050 PretenureFlag pretenure); | |
1051 | 1118 |
1052 // True if we have reached the allocation limit in the old generation that | 1119 // True if we have reached the allocation limit in the old generation that |
1053 // should force the next GC (caused normally) to be a full one. | 1120 // should force the next GC (caused normally) to be a full one. |
1054 static bool OldGenerationPromotionLimitReached() { | 1121 bool OldGenerationPromotionLimitReached() { |
1055 return (PromotedSpaceSize() + PromotedExternalMemorySize()) | 1122 return (PromotedSpaceSize() + PromotedExternalMemorySize()) |
1056 > old_gen_promotion_limit_; | 1123 > old_gen_promotion_limit_; |
1057 } | 1124 } |
1058 | 1125 |
1059 static intptr_t OldGenerationSpaceAvailable() { | 1126 intptr_t OldGenerationSpaceAvailable() { |
1060 return old_gen_allocation_limit_ - | 1127 return old_gen_allocation_limit_ - |
1061 (PromotedSpaceSize() + PromotedExternalMemorySize()); | 1128 (PromotedSpaceSize() + PromotedExternalMemorySize()); |
1062 } | 1129 } |
1063 | 1130 |
1064 // True if we have reached the allocation limit in the old generation that | 1131 // True if we have reached the allocation limit in the old generation that |
1065 // should artificially cause a GC right now. | 1132 // should artificially cause a GC right now. |
1066 static bool OldGenerationAllocationLimitReached() { | 1133 bool OldGenerationAllocationLimitReached() { |
1067 return OldGenerationSpaceAvailable() < 0; | 1134 return OldGenerationSpaceAvailable() < 0; |
1068 } | 1135 } |
1069 | 1136 |
1070 // Can be called when the embedding application is idle. | 1137 // Can be called when the embedding application is idle. |
1071 static bool IdleNotification(); | 1138 bool IdleNotification(); |
1072 | 1139 |
1073 // Declare all the root indices. | 1140 // Declare all the root indices. |
1074 enum RootListIndex { | 1141 enum RootListIndex { |
1075 #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, | 1142 #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, |
1076 STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION) | 1143 STRONG_ROOT_LIST(ROOT_INDEX_DECLARATION) |
1077 #undef ROOT_INDEX_DECLARATION | 1144 #undef ROOT_INDEX_DECLARATION |
1078 | 1145 |
1079 // Utility type maps | 1146 // Utility type maps |
1080 #define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex, | 1147 #define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex, |
1081 STRUCT_LIST(DECLARE_STRUCT_MAP) | 1148 STRUCT_LIST(DECLARE_STRUCT_MAP) |
1082 #undef DECLARE_STRUCT_MAP | 1149 #undef DECLARE_STRUCT_MAP |
1083 | 1150 |
1084 #define SYMBOL_INDEX_DECLARATION(name, str) k##name##RootIndex, | 1151 #define SYMBOL_INDEX_DECLARATION(name, str) k##name##RootIndex, |
1085 SYMBOL_LIST(SYMBOL_INDEX_DECLARATION) | 1152 SYMBOL_LIST(SYMBOL_INDEX_DECLARATION) |
1086 #undef SYMBOL_DECLARATION | 1153 #undef SYMBOL_DECLARATION |
1087 | 1154 |
1088 kSymbolTableRootIndex, | 1155 kSymbolTableRootIndex, |
1089 kStrongRootListLength = kSymbolTableRootIndex, | 1156 kStrongRootListLength = kSymbolTableRootIndex, |
1090 kRootListLength | 1157 kRootListLength |
1091 }; | 1158 }; |
1092 | 1159 |
1093 MUST_USE_RESULT static MaybeObject* NumberToString( | 1160 MUST_USE_RESULT MaybeObject* NumberToString( |
1094 Object* number, | 1161 Object* number, bool check_number_string_cache = true); |
1095 bool check_number_string_cache = true); | |
1096 | 1162 |
1097 static Map* MapForExternalArrayType(ExternalArrayType array_type); | 1163 Map* MapForExternalArrayType(ExternalArrayType array_type); |
1098 static RootListIndex RootIndexForExternalArrayType( | 1164 RootListIndex RootIndexForExternalArrayType( |
1099 ExternalArrayType array_type); | 1165 ExternalArrayType array_type); |
1100 | 1166 |
1101 static void RecordStats(HeapStats* stats, bool take_snapshot = false); | 1167 void RecordStats(HeapStats* stats, bool take_snapshot = false); |
1102 | 1168 |
1103 // Copy block of memory from src to dst. Size of block should be aligned | 1169 // Copy block of memory from src to dst. Size of block should be aligned |
1104 // by pointer size. | 1170 // by pointer size. |
1105 static inline void CopyBlock(Address dst, Address src, int byte_size); | 1171 static inline void CopyBlock(Address dst, Address src, int byte_size); |
1106 | 1172 |
1107 static inline void CopyBlockToOldSpaceAndUpdateRegionMarks(Address dst, | 1173 inline void CopyBlockToOldSpaceAndUpdateRegionMarks(Address dst, |
1108 Address src, | 1174 Address src, |
1109 int byte_size); | 1175 int byte_size); |
1110 | 1176 |
1111 // Optimized version of memmove for blocks with pointer size aligned sizes and | 1177 // Optimized version of memmove for blocks with pointer size aligned sizes and |
1112 // pointer size aligned addresses. | 1178 // pointer size aligned addresses. |
1113 static inline void MoveBlock(Address dst, Address src, int byte_size); | 1179 static inline void MoveBlock(Address dst, Address src, int byte_size); |
1114 | 1180 |
1115 static inline void MoveBlockToOldSpaceAndUpdateRegionMarks(Address dst, | 1181 inline void MoveBlockToOldSpaceAndUpdateRegionMarks(Address dst, |
1116 Address src, | 1182 Address src, |
1117 int byte_size); | 1183 int byte_size); |
1118 | 1184 |
1119 // Check new space expansion criteria and expand semispaces if it was hit. | 1185 // Check new space expansion criteria and expand semispaces if it was hit. |
1120 static void CheckNewSpaceExpansionCriteria(); | 1186 void CheckNewSpaceExpansionCriteria(); |
1121 | 1187 |
1122 static inline void IncrementYoungSurvivorsCounter(int survived) { | 1188 inline void IncrementYoungSurvivorsCounter(int survived) { |
1123 young_survivors_after_last_gc_ = survived; | 1189 young_survivors_after_last_gc_ = survived; |
1124 survived_since_last_expansion_ += survived; | 1190 survived_since_last_expansion_ += survived; |
1125 } | 1191 } |
1126 | 1192 |
1127 static void UpdateNewSpaceReferencesInExternalStringTable( | 1193 void UpdateNewSpaceReferencesInExternalStringTable( |
1128 ExternalStringTableUpdaterCallback updater_func); | 1194 ExternalStringTableUpdaterCallback updater_func); |
1129 | 1195 |
1130 static void ProcessWeakReferences(WeakObjectRetainer* retainer); | 1196 void ProcessWeakReferences(WeakObjectRetainer* retainer); |
1131 | 1197 |
1132 // Helper function that governs the promotion policy from new space to | 1198 // Helper function that governs the promotion policy from new space to |
1133 // old. If the object's old address lies below the new space's age | 1199 // old. If the object's old address lies below the new space's age |
1134 // mark or if we've already filled the bottom 1/16th of the to space, | 1200 // mark or if we've already filled the bottom 1/16th of the to space, |
1135 // we try to promote this object. | 1201 // we try to promote this object. |
1136 static inline bool ShouldBePromoted(Address old_address, int object_size); | 1202 inline bool ShouldBePromoted(Address old_address, int object_size); |
1137 | 1203 |
1138 static int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; } | 1204 int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; } |
1139 | 1205 |
1140 static void ClearJSFunctionResultCaches(); | 1206 void ClearJSFunctionResultCaches(); |
1141 | 1207 |
1142 static void ClearNormalizedMapCaches(); | 1208 void ClearNormalizedMapCaches(); |
1143 | 1209 |
1144 static GCTracer* tracer() { return tracer_; } | 1210 GCTracer* tracer() { return tracer_; } |
1145 | 1211 |
1146 static void CallGlobalGCPrologueCallback() { | 1212 // Returns maximum GC pause. |
| 1213 int get_max_gc_pause() { return max_gc_pause_; } |
| 1214 |
| 1215 // Returns maximum size of objects alive after GC. |
| 1216 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } |
| 1217 |
| 1218 // Returns minimal interval between two subsequent collections. |
| 1219 int get_min_in_mutator() { return min_in_mutator_; } |
| 1220 |
| 1221 MarkCompactCollector* mark_compact_collector() { |
| 1222 return &mark_compact_collector_; |
| 1223 } |
| 1224 |
| 1225 ExternalStringTable* external_string_table() { |
| 1226 return &external_string_table_; |
| 1227 } |
| 1228 |
| 1229 inline Isolate* isolate(); |
| 1230 bool is_safe_to_read_maps() { return is_safe_to_read_maps_; } |
| 1231 |
| 1232 void CallGlobalGCPrologueCallback() { |
1147 if (global_gc_prologue_callback_ != NULL) global_gc_prologue_callback_(); | 1233 if (global_gc_prologue_callback_ != NULL) global_gc_prologue_callback_(); |
1148 } | 1234 } |
1149 | 1235 |
1150 static void CallGlobalGCEpilogueCallback() { | 1236 void CallGlobalGCEpilogueCallback() { |
1151 if (global_gc_epilogue_callback_ != NULL) global_gc_epilogue_callback_(); | 1237 if (global_gc_epilogue_callback_ != NULL) global_gc_epilogue_callback_(); |
1152 } | 1238 } |
1153 | 1239 |
1154 private: | 1240 private: |
1155 static int reserved_semispace_size_; | 1241 Heap(); |
1156 static int max_semispace_size_; | 1242 |
1157 static int initial_semispace_size_; | 1243 // This can be calculated directly from a pointer to the heap; however, it is |
1158 static intptr_t max_old_generation_size_; | 1244 // more expedient to get at the isolate directly from within Heap methods. |
1159 static intptr_t max_executable_size_; | 1245 Isolate* isolate_; |
1160 static intptr_t code_range_size_; | 1246 |
| 1247 int reserved_semispace_size_; |
| 1248 int max_semispace_size_; |
| 1249 int initial_semispace_size_; |
| 1250 intptr_t max_old_generation_size_; |
| 1251 intptr_t max_executable_size_; |
| 1252 intptr_t code_range_size_; |
1161 | 1253 |
1162 // For keeping track of how much data has survived | 1254 // For keeping track of how much data has survived |
1163 // scavenge since last new space expansion. | 1255 // scavenge since last new space expansion. |
1164 static int survived_since_last_expansion_; | 1256 int survived_since_last_expansion_; |
1165 | 1257 |
1166 static int always_allocate_scope_depth_; | 1258 int always_allocate_scope_depth_; |
1167 static int linear_allocation_scope_depth_; | 1259 int linear_allocation_scope_depth_; |
1168 | 1260 |
1169 // For keeping track of context disposals. | 1261 // For keeping track of context disposals. |
1170 static int contexts_disposed_; | 1262 int contexts_disposed_; |
1171 | 1263 |
1172 #if defined(V8_TARGET_ARCH_X64) | 1264 #if defined(V8_TARGET_ARCH_X64) |
1173 static const int kMaxObjectSizeInNewSpace = 1024*KB; | 1265 static const int kMaxObjectSizeInNewSpace = 1024*KB; |
1174 #else | 1266 #else |
1175 static const int kMaxObjectSizeInNewSpace = 512*KB; | 1267 static const int kMaxObjectSizeInNewSpace = 512*KB; |
1176 #endif | 1268 #endif |
1177 | 1269 |
1178 static NewSpace new_space_; | 1270 NewSpace new_space_; |
1179 static OldSpace* old_pointer_space_; | 1271 OldSpace* old_pointer_space_; |
1180 static OldSpace* old_data_space_; | 1272 OldSpace* old_data_space_; |
1181 static OldSpace* code_space_; | 1273 OldSpace* code_space_; |
1182 static MapSpace* map_space_; | 1274 MapSpace* map_space_; |
1183 static CellSpace* cell_space_; | 1275 CellSpace* cell_space_; |
1184 static LargeObjectSpace* lo_space_; | 1276 LargeObjectSpace* lo_space_; |
1185 static HeapState gc_state_; | 1277 HeapState gc_state_; |
1186 | 1278 |
1187 // Returns the size of object residing in non new spaces. | 1279 // Returns the size of object residing in non new spaces. |
1188 static intptr_t PromotedSpaceSize(); | 1280 intptr_t PromotedSpaceSize(); |
1189 | 1281 |
1190 // Returns the amount of external memory registered since last global gc. | 1282 // Returns the amount of external memory registered since last global gc. |
1191 static int PromotedExternalMemorySize(); | 1283 int PromotedExternalMemorySize(); |
1192 | 1284 |
1193 static int mc_count_; // how many mark-compact collections happened | 1285 int mc_count_; // how many mark-compact collections happened |
1194 static int ms_count_; // how many mark-sweep collections happened | 1286 int ms_count_; // how many mark-sweep collections happened |
1195 static unsigned int gc_count_; // how many gc happened | 1287 unsigned int gc_count_; // how many gc happened |
1196 | 1288 |
1197 // Total length of the strings we failed to flatten since the last GC. | 1289 // Total length of the strings we failed to flatten since the last GC. |
1198 static int unflattened_strings_length_; | 1290 int unflattened_strings_length_; |
1199 | 1291 |
1200 #define ROOT_ACCESSOR(type, name, camel_name) \ | 1292 #define ROOT_ACCESSOR(type, name, camel_name) \ |
1201 static inline void set_##name(type* value) { \ | 1293 inline void set_##name(type* value) { \ |
1202 roots_[k##camel_name##RootIndex] = value; \ | 1294 roots_[k##camel_name##RootIndex] = value; \ |
1203 } | 1295 } |
1204 ROOT_LIST(ROOT_ACCESSOR) | 1296 ROOT_LIST(ROOT_ACCESSOR) |
1205 #undef ROOT_ACCESSOR | 1297 #undef ROOT_ACCESSOR |
1206 | 1298 |
1207 #ifdef DEBUG | 1299 #ifdef DEBUG |
1208 static bool allocation_allowed_; | 1300 bool allocation_allowed_; |
1209 | 1301 |
1210 // If the --gc-interval flag is set to a positive value, this | 1302 // If the --gc-interval flag is set to a positive value, this |
1211 // variable holds the value indicating the number of allocations | 1303 // variable holds the value indicating the number of allocations |
1212 // remain until the next failure and garbage collection. | 1304 // remain until the next failure and garbage collection. |
1213 static int allocation_timeout_; | 1305 int allocation_timeout_; |
1214 | 1306 |
1215 // Do we expect to be able to handle allocation failure at this | 1307 // Do we expect to be able to handle allocation failure at this |
1216 // time? | 1308 // time? |
1217 static bool disallow_allocation_failure_; | 1309 bool disallow_allocation_failure_; |
| 1310 |
| 1311 HeapDebugUtils* debug_utils_; |
1218 #endif // DEBUG | 1312 #endif // DEBUG |
1219 | 1313 |
1220 // Limit that triggers a global GC on the next (normally caused) GC. This | 1314 // Limit that triggers a global GC on the next (normally caused) GC. This |
1221 // is checked when we have already decided to do a GC to help determine | 1315 // is checked when we have already decided to do a GC to help determine |
1222 // which collector to invoke. | 1316 // which collector to invoke. |
1223 static intptr_t old_gen_promotion_limit_; | 1317 intptr_t old_gen_promotion_limit_; |
1224 | 1318 |
1225 // Limit that triggers a global GC as soon as is reasonable. This is | 1319 // Limit that triggers a global GC as soon as is reasonable. This is |
1226 // checked before expanding a paged space in the old generation and on | 1320 // checked before expanding a paged space in the old generation and on |
1227 // every allocation in large object space. | 1321 // every allocation in large object space. |
1228 static intptr_t old_gen_allocation_limit_; | 1322 intptr_t old_gen_allocation_limit_; |
1229 | 1323 |
1230 // Limit on the amount of externally allocated memory allowed | 1324 // Limit on the amount of externally allocated memory allowed |
1231 // between global GCs. If reached a global GC is forced. | 1325 // between global GCs. If reached a global GC is forced. |
1232 static intptr_t external_allocation_limit_; | 1326 intptr_t external_allocation_limit_; |
1233 | 1327 |
1234 // The amount of external memory registered through the API kept alive | 1328 // The amount of external memory registered through the API kept alive |
1235 // by global handles | 1329 // by global handles |
1236 static int amount_of_external_allocated_memory_; | 1330 int amount_of_external_allocated_memory_; |
1237 | 1331 |
1238 // Caches the amount of external memory registered at the last global gc. | 1332 // Caches the amount of external memory registered at the last global gc. |
1239 static int amount_of_external_allocated_memory_at_last_global_gc_; | 1333 int amount_of_external_allocated_memory_at_last_global_gc_; |
1240 | 1334 |
1241 // Indicates that an allocation has failed in the old generation since the | 1335 // Indicates that an allocation has failed in the old generation since the |
1242 // last GC. | 1336 // last GC. |
1243 static int old_gen_exhausted_; | 1337 int old_gen_exhausted_; |
1244 | 1338 |
1245 static Object* roots_[kRootListLength]; | 1339 Object* roots_[kRootListLength]; |
1246 | 1340 |
1247 static Object* global_contexts_list_; | 1341 Object* global_contexts_list_; |
1248 | 1342 |
1249 struct StringTypeTable { | 1343 struct StringTypeTable { |
1250 InstanceType type; | 1344 InstanceType type; |
1251 int size; | 1345 int size; |
1252 RootListIndex index; | 1346 RootListIndex index; |
1253 }; | 1347 }; |
1254 | 1348 |
1255 struct ConstantSymbolTable { | 1349 struct ConstantSymbolTable { |
1256 const char* contents; | 1350 const char* contents; |
1257 RootListIndex index; | 1351 RootListIndex index; |
1258 }; | 1352 }; |
1259 | 1353 |
1260 struct StructTable { | 1354 struct StructTable { |
1261 InstanceType type; | 1355 InstanceType type; |
1262 int size; | 1356 int size; |
1263 RootListIndex index; | 1357 RootListIndex index; |
1264 }; | 1358 }; |
1265 | 1359 |
1266 static const StringTypeTable string_type_table[]; | 1360 static const StringTypeTable string_type_table[]; |
1267 static const ConstantSymbolTable constant_symbol_table[]; | 1361 static const ConstantSymbolTable constant_symbol_table[]; |
1268 static const StructTable struct_table[]; | 1362 static const StructTable struct_table[]; |
1269 | 1363 |
1270 // The special hidden symbol which is an empty string, but does not match | 1364 // The special hidden symbol which is an empty string, but does not match |
1271 // any string when looked up in properties. | 1365 // any string when looked up in properties. |
1272 static String* hidden_symbol_; | 1366 String* hidden_symbol_; |
1273 | 1367 |
1274 // GC callback function, called before and after mark-compact GC. | 1368 // GC callback function, called before and after mark-compact GC. |
1275 // Allocations in the callback function are disallowed. | 1369 // Allocations in the callback function are disallowed. |
1276 struct GCPrologueCallbackPair { | 1370 struct GCPrologueCallbackPair { |
1277 GCPrologueCallbackPair(GCPrologueCallback callback, GCType gc_type) | 1371 GCPrologueCallbackPair(GCPrologueCallback callback, GCType gc_type) |
1278 : callback(callback), gc_type(gc_type) { | 1372 : callback(callback), gc_type(gc_type) { |
1279 } | 1373 } |
1280 bool operator==(const GCPrologueCallbackPair& pair) const { | 1374 bool operator==(const GCPrologueCallbackPair& pair) const { |
1281 return pair.callback == callback; | 1375 return pair.callback == callback; |
1282 } | 1376 } |
1283 GCPrologueCallback callback; | 1377 GCPrologueCallback callback; |
1284 GCType gc_type; | 1378 GCType gc_type; |
1285 }; | 1379 }; |
1286 static List<GCPrologueCallbackPair> gc_prologue_callbacks_; | 1380 List<GCPrologueCallbackPair> gc_prologue_callbacks_; |
1287 | 1381 |
1288 struct GCEpilogueCallbackPair { | 1382 struct GCEpilogueCallbackPair { |
1289 GCEpilogueCallbackPair(GCEpilogueCallback callback, GCType gc_type) | 1383 GCEpilogueCallbackPair(GCEpilogueCallback callback, GCType gc_type) |
1290 : callback(callback), gc_type(gc_type) { | 1384 : callback(callback), gc_type(gc_type) { |
1291 } | 1385 } |
1292 bool operator==(const GCEpilogueCallbackPair& pair) const { | 1386 bool operator==(const GCEpilogueCallbackPair& pair) const { |
1293 return pair.callback == callback; | 1387 return pair.callback == callback; |
1294 } | 1388 } |
1295 GCEpilogueCallback callback; | 1389 GCEpilogueCallback callback; |
1296 GCType gc_type; | 1390 GCType gc_type; |
1297 }; | 1391 }; |
1298 static List<GCEpilogueCallbackPair> gc_epilogue_callbacks_; | 1392 List<GCEpilogueCallbackPair> gc_epilogue_callbacks_; |
1299 | 1393 |
1300 static GCCallback global_gc_prologue_callback_; | 1394 GCCallback global_gc_prologue_callback_; |
1301 static GCCallback global_gc_epilogue_callback_; | 1395 GCCallback global_gc_epilogue_callback_; |
1302 | 1396 |
1303 // Support for computing object sizes during GC. | 1397 // Support for computing object sizes during GC. |
1304 static HeapObjectCallback gc_safe_size_of_old_object_; | 1398 HeapObjectCallback gc_safe_size_of_old_object_; |
1305 static int GcSafeSizeOfOldObject(HeapObject* object); | 1399 static int GcSafeSizeOfOldObject(HeapObject* object); |
1306 static int GcSafeSizeOfOldObjectWithEncodedMap(HeapObject* object); | 1400 static int GcSafeSizeOfOldObjectWithEncodedMap(HeapObject* object); |
1307 | 1401 |
1308 // Update the GC state. Called from the mark-compact collector. | 1402 // Update the GC state. Called from the mark-compact collector. |
1309 static void MarkMapPointersAsEncoded(bool encoded) { | 1403 void MarkMapPointersAsEncoded(bool encoded) { |
1310 gc_safe_size_of_old_object_ = encoded | 1404 gc_safe_size_of_old_object_ = encoded |
1311 ? &GcSafeSizeOfOldObjectWithEncodedMap | 1405 ? &GcSafeSizeOfOldObjectWithEncodedMap |
1312 : &GcSafeSizeOfOldObject; | 1406 : &GcSafeSizeOfOldObject; |
1313 } | 1407 } |
1314 | 1408 |
1315 // Checks whether a global GC is necessary | 1409 // Checks whether a global GC is necessary |
1316 static GarbageCollector SelectGarbageCollector(AllocationSpace space); | 1410 GarbageCollector SelectGarbageCollector(AllocationSpace space); |
1317 | 1411 |
1318 // Performs garbage collection | 1412 // Performs garbage collection |
1319 // Returns whether there is a chance another major GC could | 1413 // Returns whether there is a chance another major GC could |
1320 // collect more garbage. | 1414 // collect more garbage. |
1321 static bool PerformGarbageCollection(GarbageCollector collector, | 1415 bool PerformGarbageCollection(GarbageCollector collector, |
1322 GCTracer* tracer); | 1416 GCTracer* tracer); |
| 1417 |
| 1418 static const intptr_t kMinimumPromotionLimit = 2 * MB; |
| 1419 static const intptr_t kMinimumAllocationLimit = 8 * MB; |
| 1420 |
| 1421 inline void UpdateOldSpaceLimits(); |
1323 | 1422 |
1324 // Allocate an uninitialized object in map space. The behavior is identical | 1423 // Allocate an uninitialized object in map space. The behavior is identical |
1325 // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't | 1424 // to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't |
1326 // have to test the allocation space argument and (b) can reduce code size | 1425 // have to test the allocation space argument and (b) can reduce code size |
1327 // (since both AllocateRaw and AllocateRawMap are inlined). | 1426 // (since both AllocateRaw and AllocateRawMap are inlined). |
1328 MUST_USE_RESULT static inline MaybeObject* AllocateRawMap(); | 1427 MUST_USE_RESULT inline MaybeObject* AllocateRawMap(); |
1329 | 1428 |
1330 // Allocate an uninitialized object in the global property cell space. | 1429 // Allocate an uninitialized object in the global property cell space. |
1331 MUST_USE_RESULT static inline MaybeObject* AllocateRawCell(); | 1430 MUST_USE_RESULT inline MaybeObject* AllocateRawCell(); |
1332 | 1431 |
1333 // Initializes a JSObject based on its map. | 1432 // Initializes a JSObject based on its map. |
1334 static void InitializeJSObjectFromMap(JSObject* obj, | 1433 void InitializeJSObjectFromMap(JSObject* obj, |
1335 FixedArray* properties, | 1434 FixedArray* properties, |
1336 Map* map); | 1435 Map* map); |
1337 | 1436 |
1338 static bool CreateInitialMaps(); | 1437 bool CreateInitialMaps(); |
1339 static bool CreateInitialObjects(); | 1438 bool CreateInitialObjects(); |
1340 | 1439 |
1341 // These two Create*EntryStub functions are here and forced to not be inlined | 1440 // These five Create*EntryStub functions are here and forced to not be inlined |
1342 // because of a gcc-4.4 bug that assigns wrong vtable entries. | 1441 // because of a gcc-4.4 bug that assigns wrong vtable entries. |
1343 NO_INLINE(static void CreateJSEntryStub()); | 1442 NO_INLINE(void CreateJSEntryStub()); |
1344 NO_INLINE(static void CreateJSConstructEntryStub()); | 1443 NO_INLINE(void CreateJSConstructEntryStub()); |
1345 | 1444 |
1346 static void CreateFixedStubs(); | 1445 void CreateFixedStubs(); |
1347 | 1446 |
1348 MUST_USE_RESULT static MaybeObject* CreateOddball(const char* to_string, | 1447 MaybeObject* CreateOddball(const char* to_string, |
1349 Object* to_number); | 1448 Object* to_number, |
| 1449 byte kind); |
1350 | 1450 |
1351 // Allocate empty fixed array. | 1451 // Allocate empty fixed array. |
1352 MUST_USE_RESULT static MaybeObject* AllocateEmptyFixedArray(); | 1452 MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray(); |
1353 | 1453 |
1354 // Performs a minor collection in new generation. | 1454 // Performs a minor collection in new generation. |
1355 static void Scavenge(); | 1455 void Scavenge(); |
1356 | 1456 |
1357 static String* UpdateNewSpaceReferenceInExternalStringTableEntry( | 1457 static String* UpdateNewSpaceReferenceInExternalStringTableEntry( |
| 1458 Heap* heap, |
1358 Object** pointer); | 1459 Object** pointer); |
1359 | 1460 |
1360 static Address DoScavenge(ObjectVisitor* scavenge_visitor, | 1461 Address DoScavenge(ObjectVisitor* scavenge_visitor, Address new_space_front); |
1361 Address new_space_front); | |
1362 | 1462 |
1363 // Performs a major collection in the whole heap. | 1463 // Performs a major collection in the whole heap. |
1364 static void MarkCompact(GCTracer* tracer); | 1464 void MarkCompact(GCTracer* tracer); |
1365 | 1465 |
1366 // Code to be run before and after mark-compact. | 1466 // Code to be run before and after mark-compact. |
1367 static void MarkCompactPrologue(bool is_compacting); | 1467 void MarkCompactPrologue(bool is_compacting); |
1368 | 1468 |
1369 // Completely clear the Instanceof cache (to stop it keeping objects alive | 1469 // Completely clear the Instanceof cache (to stop it keeping objects alive |
1370 // around a GC). | 1470 // around a GC). |
1371 static void CompletelyClearInstanceofCache() { | 1471 inline void CompletelyClearInstanceofCache(); |
1372 set_instanceof_cache_map(the_hole_value()); | |
1373 set_instanceof_cache_function(the_hole_value()); | |
1374 } | |
1375 | 1472 |
1376 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 1473 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
1377 // Record statistics before and after garbage collection. | 1474 // Record statistics before and after garbage collection. |
1378 static void ReportStatisticsBeforeGC(); | 1475 void ReportStatisticsBeforeGC(); |
1379 static void ReportStatisticsAfterGC(); | 1476 void ReportStatisticsAfterGC(); |
1380 #endif | 1477 #endif |
1381 | 1478 |
1382 // Slow part of scavenge object. | 1479 // Slow part of scavenge object. |
1383 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object); | 1480 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object); |
1384 | 1481 |
1385 // Initializes a function with a shared part and prototype. | 1482 // Initializes a function with a shared part and prototype. |
1386 // Returns the function. | 1483 // Returns the function. |
1387 // Note: this code was factored out of AllocateFunction such that | 1484 // Note: this code was factored out of AllocateFunction such that |
1388 // other parts of the VM could use it. Specifically, a function that creates | 1485 // other parts of the VM could use it. Specifically, a function that creates |
1389 // instances of type JS_FUNCTION_TYPE benefit from the use of this function. | 1486 // instances of type JS_FUNCTION_TYPE benefit from the use of this function. |
1390 // Please note this does not perform a garbage collection. | 1487 // Please note this does not perform a garbage collection. |
1391 MUST_USE_RESULT static inline MaybeObject* InitializeFunction( | 1488 MUST_USE_RESULT inline MaybeObject* InitializeFunction( |
1392 JSFunction* function, | 1489 JSFunction* function, |
1393 SharedFunctionInfo* shared, | 1490 SharedFunctionInfo* shared, |
1394 Object* prototype); | 1491 Object* prototype); |
1395 | 1492 |
1396 static GCTracer* tracer_; | 1493 GCTracer* tracer_; |
1397 | 1494 |
1398 | 1495 |
1399 // Initializes the number to string cache based on the max semispace size. | 1496 // Initializes the number to string cache based on the max semispace size. |
1400 MUST_USE_RESULT static MaybeObject* InitializeNumberStringCache(); | 1497 MUST_USE_RESULT MaybeObject* InitializeNumberStringCache(); |
1401 // Flush the number to string cache. | 1498 // Flush the number to string cache. |
1402 static void FlushNumberStringCache(); | 1499 void FlushNumberStringCache(); |
1403 | 1500 |
1404 static void UpdateSurvivalRateTrend(int start_new_space_size); | 1501 void UpdateSurvivalRateTrend(int start_new_space_size); |
1405 | 1502 |
1406 enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING }; | 1503 enum SurvivalRateTrend { INCREASING, STABLE, DECREASING, FLUCTUATING }; |
1407 | 1504 |
1408 static const int kYoungSurvivalRateThreshold = 90; | 1505 static const int kYoungSurvivalRateThreshold = 90; |
1409 static const int kYoungSurvivalRateAllowedDeviation = 15; | 1506 static const int kYoungSurvivalRateAllowedDeviation = 15; |
1410 | 1507 |
1411 static int young_survivors_after_last_gc_; | 1508 int young_survivors_after_last_gc_; |
1412 static int high_survival_rate_period_length_; | 1509 int high_survival_rate_period_length_; |
1413 static double survival_rate_; | 1510 double survival_rate_; |
1414 static SurvivalRateTrend previous_survival_rate_trend_; | 1511 SurvivalRateTrend previous_survival_rate_trend_; |
1415 static SurvivalRateTrend survival_rate_trend_; | 1512 SurvivalRateTrend survival_rate_trend_; |
1416 | 1513 |
1417 static void set_survival_rate_trend(SurvivalRateTrend survival_rate_trend) { | 1514 void set_survival_rate_trend(SurvivalRateTrend survival_rate_trend) { |
1418 ASSERT(survival_rate_trend != FLUCTUATING); | 1515 ASSERT(survival_rate_trend != FLUCTUATING); |
1419 previous_survival_rate_trend_ = survival_rate_trend_; | 1516 previous_survival_rate_trend_ = survival_rate_trend_; |
1420 survival_rate_trend_ = survival_rate_trend; | 1517 survival_rate_trend_ = survival_rate_trend; |
1421 } | 1518 } |
1422 | 1519 |
1423 static SurvivalRateTrend survival_rate_trend() { | 1520 SurvivalRateTrend survival_rate_trend() { |
1424 if (survival_rate_trend_ == STABLE) { | 1521 if (survival_rate_trend_ == STABLE) { |
1425 return STABLE; | 1522 return STABLE; |
1426 } else if (previous_survival_rate_trend_ == STABLE) { | 1523 } else if (previous_survival_rate_trend_ == STABLE) { |
1427 return survival_rate_trend_; | 1524 return survival_rate_trend_; |
1428 } else if (survival_rate_trend_ != previous_survival_rate_trend_) { | 1525 } else if (survival_rate_trend_ != previous_survival_rate_trend_) { |
1429 return FLUCTUATING; | 1526 return FLUCTUATING; |
1430 } else { | 1527 } else { |
1431 return survival_rate_trend_; | 1528 return survival_rate_trend_; |
1432 } | 1529 } |
1433 } | 1530 } |
1434 | 1531 |
1435 static bool IsStableOrIncreasingSurvivalTrend() { | 1532 bool IsStableOrIncreasingSurvivalTrend() { |
1436 switch (survival_rate_trend()) { | 1533 switch (survival_rate_trend()) { |
1437 case STABLE: | 1534 case STABLE: |
1438 case INCREASING: | 1535 case INCREASING: |
1439 return true; | 1536 return true; |
1440 default: | 1537 default: |
1441 return false; | 1538 return false; |
1442 } | 1539 } |
1443 } | 1540 } |
1444 | 1541 |
1445 static bool IsIncreasingSurvivalTrend() { | 1542 bool IsIncreasingSurvivalTrend() { |
1446 return survival_rate_trend() == INCREASING; | 1543 return survival_rate_trend() == INCREASING; |
1447 } | 1544 } |
1448 | 1545 |
1449 static bool IsHighSurvivalRate() { | 1546 bool IsHighSurvivalRate() { |
1450 return high_survival_rate_period_length_ > 0; | 1547 return high_survival_rate_period_length_ > 0; |
1451 } | 1548 } |
1452 | 1549 |
1453 static const int kInitialSymbolTableSize = 2048; | 1550 static const int kInitialSymbolTableSize = 2048; |
1454 static const int kInitialEvalCacheSize = 64; | 1551 static const int kInitialEvalCacheSize = 64; |
1455 | 1552 |
| 1553 // Maximum GC pause. |
| 1554 int max_gc_pause_; |
| 1555 |
| 1556 // Maximum size of objects alive after GC. |
| 1557 intptr_t max_alive_after_gc_; |
| 1558 |
| 1559 // Minimal interval between two subsequent collections. |
| 1560 int min_in_mutator_; |
| 1561 |
| 1562 // Size of objects alive after last GC. |
| 1563 intptr_t alive_after_last_gc_; |
| 1564 |
| 1565 double last_gc_end_timestamp_; |
| 1566 |
| 1567 MarkCompactCollector mark_compact_collector_; |
| 1568 |
| 1569 // This field contains the meaning of the WATERMARK_INVALIDATED flag. |
| 1570 // Instead of clearing this flag from all pages we just flip |
| 1571 // its meaning at the beginning of a scavenge. |
| 1572 intptr_t page_watermark_invalidated_mark_; |
| 1573 |
| 1574 int number_idle_notifications_; |
| 1575 unsigned int last_idle_notification_gc_count_; |
| 1576 bool last_idle_notification_gc_count_init_; |
| 1577 |
| 1578 // Shared state read by the scavenge collector and set by ScavengeObject. |
| 1579 PromotionQueue promotion_queue_; |
| 1580 |
| 1581 // Flag is set when the heap has been configured. The heap can be repeatedly |
| 1582 // configured through the API until it is setup. |
| 1583 bool configured_; |
| 1584 |
| 1585 ExternalStringTable external_string_table_; |
| 1586 |
| 1587 bool is_safe_to_read_maps_; |
| 1588 |
1456 friend class Factory; | 1589 friend class Factory; |
| 1590 friend class GCTracer; |
1457 friend class DisallowAllocationFailure; | 1591 friend class DisallowAllocationFailure; |
1458 friend class AlwaysAllocateScope; | 1592 friend class AlwaysAllocateScope; |
1459 friend class LinearAllocationScope; | 1593 friend class LinearAllocationScope; |
| 1594 friend class Page; |
| 1595 friend class Isolate; |
1460 friend class MarkCompactCollector; | 1596 friend class MarkCompactCollector; |
| 1597 friend class MapCompact; |
| 1598 |
| 1599 DISALLOW_COPY_AND_ASSIGN(Heap); |
1461 }; | 1600 }; |
1462 | 1601 |
1463 | 1602 |
1464 class HeapStats { | 1603 class HeapStats { |
1465 public: | 1604 public: |
1466 static const int kStartMarker = 0xDECADE00; | 1605 static const int kStartMarker = 0xDECADE00; |
1467 static const int kEndMarker = 0xDECADE01; | 1606 static const int kEndMarker = 0xDECADE01; |
1468 | 1607 |
1469 int* start_marker; // 0 | 1608 int* start_marker; // 0 |
1470 int* new_space_size; // 1 | 1609 int* new_space_size; // 1 |
(...skipping 23 matching lines...) Expand all Loading... |
1494 }; | 1633 }; |
1495 | 1634 |
1496 | 1635 |
1497 class AlwaysAllocateScope { | 1636 class AlwaysAllocateScope { |
1498 public: | 1637 public: |
1499 AlwaysAllocateScope() { | 1638 AlwaysAllocateScope() { |
1500 // We shouldn't hit any nested scopes, because that requires | 1639 // We shouldn't hit any nested scopes, because that requires |
1501 // non-handle code to call handle code. The code still works but | 1640 // non-handle code to call handle code. The code still works but |
1502 // performance will degrade, so we want to catch this situation | 1641 // performance will degrade, so we want to catch this situation |
1503 // in debug mode. | 1642 // in debug mode. |
1504 ASSERT(Heap::always_allocate_scope_depth_ == 0); | 1643 ASSERT(HEAP->always_allocate_scope_depth_ == 0); |
1505 Heap::always_allocate_scope_depth_++; | 1644 HEAP->always_allocate_scope_depth_++; |
1506 } | 1645 } |
1507 | 1646 |
1508 ~AlwaysAllocateScope() { | 1647 ~AlwaysAllocateScope() { |
1509 Heap::always_allocate_scope_depth_--; | 1648 HEAP->always_allocate_scope_depth_--; |
1510 ASSERT(Heap::always_allocate_scope_depth_ == 0); | 1649 ASSERT(HEAP->always_allocate_scope_depth_ == 0); |
1511 } | 1650 } |
1512 }; | 1651 }; |
1513 | 1652 |
1514 | 1653 |
1515 class LinearAllocationScope { | 1654 class LinearAllocationScope { |
1516 public: | 1655 public: |
1517 LinearAllocationScope() { | 1656 LinearAllocationScope() { |
1518 Heap::linear_allocation_scope_depth_++; | 1657 HEAP->linear_allocation_scope_depth_++; |
1519 } | 1658 } |
1520 | 1659 |
1521 ~LinearAllocationScope() { | 1660 ~LinearAllocationScope() { |
1522 Heap::linear_allocation_scope_depth_--; | 1661 HEAP->linear_allocation_scope_depth_--; |
1523 ASSERT(Heap::linear_allocation_scope_depth_ >= 0); | 1662 ASSERT(HEAP->linear_allocation_scope_depth_ >= 0); |
1524 } | 1663 } |
1525 }; | 1664 }; |
1526 | 1665 |
1527 | 1666 |
1528 #ifdef DEBUG | 1667 #ifdef DEBUG |
1529 // Visitor class to verify interior pointers in spaces that do not contain | 1668 // Visitor class to verify interior pointers in spaces that do not contain |
1530 // or care about intergenerational references. All heap object pointers have to | 1669 // or care about intergenerational references. All heap object pointers have to |
1531 // point into the heap to a location that has a map pointer at its first word. | 1670 // point into the heap to a location that has a map pointer at its first word. |
1532 // Caveat: Heap::Contains is an approximation because it can return true for | 1671 // Caveat: Heap::Contains is an approximation because it can return true for |
1533 // objects in a heap space but above the allocation pointer. | 1672 // objects in a heap space but above the allocation pointer. |
1534 class VerifyPointersVisitor: public ObjectVisitor { | 1673 class VerifyPointersVisitor: public ObjectVisitor { |
1535 public: | 1674 public: |
1536 void VisitPointers(Object** start, Object** end) { | 1675 void VisitPointers(Object** start, Object** end) { |
1537 for (Object** current = start; current < end; current++) { | 1676 for (Object** current = start; current < end; current++) { |
1538 if ((*current)->IsHeapObject()) { | 1677 if ((*current)->IsHeapObject()) { |
1539 HeapObject* object = HeapObject::cast(*current); | 1678 HeapObject* object = HeapObject::cast(*current); |
1540 ASSERT(Heap::Contains(object)); | 1679 ASSERT(HEAP->Contains(object)); |
1541 ASSERT(object->map()->IsMap()); | 1680 ASSERT(object->map()->IsMap()); |
1542 } | 1681 } |
1543 } | 1682 } |
1544 } | 1683 } |
1545 }; | 1684 }; |
1546 | 1685 |
1547 | 1686 |
1548 // Visitor class to verify interior pointers in spaces that use region marks | 1687 // Visitor class to verify interior pointers in spaces that use region marks |
1549 // to keep track of intergenerational references. | 1688 // to keep track of intergenerational references. |
1550 // As VerifyPointersVisitor but also checks that dirty marks are set | 1689 // As VerifyPointersVisitor but also checks that dirty marks are set |
1551 // for regions covering intergenerational references. | 1690 // for regions covering intergenerational references. |
1552 class VerifyPointersAndDirtyRegionsVisitor: public ObjectVisitor { | 1691 class VerifyPointersAndDirtyRegionsVisitor: public ObjectVisitor { |
1553 public: | 1692 public: |
1554 void VisitPointers(Object** start, Object** end) { | 1693 void VisitPointers(Object** start, Object** end) { |
1555 for (Object** current = start; current < end; current++) { | 1694 for (Object** current = start; current < end; current++) { |
1556 if ((*current)->IsHeapObject()) { | 1695 if ((*current)->IsHeapObject()) { |
1557 HeapObject* object = HeapObject::cast(*current); | 1696 HeapObject* object = HeapObject::cast(*current); |
1558 ASSERT(Heap::Contains(object)); | 1697 ASSERT(HEAP->Contains(object)); |
1559 ASSERT(object->map()->IsMap()); | 1698 ASSERT(object->map()->IsMap()); |
1560 if (Heap::InNewSpace(object)) { | 1699 if (HEAP->InNewSpace(object)) { |
1561 ASSERT(Heap::InToSpace(object)); | 1700 ASSERT(HEAP->InToSpace(object)); |
1562 Address addr = reinterpret_cast<Address>(current); | 1701 Address addr = reinterpret_cast<Address>(current); |
1563 ASSERT(Page::FromAddress(addr)->IsRegionDirty(addr)); | 1702 ASSERT(Page::FromAddress(addr)->IsRegionDirty(addr)); |
1564 } | 1703 } |
1565 } | 1704 } |
1566 } | 1705 } |
1567 } | 1706 } |
1568 }; | 1707 }; |
1569 #endif | 1708 #endif |
1570 | 1709 |
1571 | 1710 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 // Object iterator for the space currently being iterated. | 1804 // Object iterator for the space currently being iterated. |
1666 ObjectIterator* object_iterator_; | 1805 ObjectIterator* object_iterator_; |
1667 }; | 1806 }; |
1668 | 1807 |
1669 | 1808 |
1670 // Cache for mapping (map, property name) into field offset. | 1809 // Cache for mapping (map, property name) into field offset. |
1671 // Cleared at startup and prior to mark sweep collection. | 1810 // Cleared at startup and prior to mark sweep collection. |
1672 class KeyedLookupCache { | 1811 class KeyedLookupCache { |
1673 public: | 1812 public: |
1674 // Lookup field offset for (map, name). If absent, -1 is returned. | 1813 // Lookup field offset for (map, name). If absent, -1 is returned. |
1675 static int Lookup(Map* map, String* name); | 1814 int Lookup(Map* map, String* name); |
1676 | 1815 |
1677 // Update an element in the cache. | 1816 // Update an element in the cache. |
1678 static void Update(Map* map, String* name, int field_offset); | 1817 void Update(Map* map, String* name, int field_offset); |
1679 | 1818 |
1680 // Clear the cache. | 1819 // Clear the cache. |
1681 static void Clear(); | 1820 void Clear(); |
1682 | 1821 |
1683 static const int kLength = 64; | 1822 static const int kLength = 64; |
1684 static const int kCapacityMask = kLength - 1; | 1823 static const int kCapacityMask = kLength - 1; |
1685 static const int kMapHashShift = 2; | 1824 static const int kMapHashShift = 2; |
| 1825 static const int kNotFound = -1; |
1686 | 1826 |
1687 private: | 1827 private: |
| 1828 KeyedLookupCache() { |
| 1829 for (int i = 0; i < kLength; ++i) { |
| 1830 keys_[i].map = NULL; |
| 1831 keys_[i].name = NULL; |
| 1832 field_offsets_[i] = kNotFound; |
| 1833 } |
| 1834 } |
| 1835 |
1688 static inline int Hash(Map* map, String* name); | 1836 static inline int Hash(Map* map, String* name); |
1689 | 1837 |
1690 // Get the address of the keys and field_offsets arrays. Used in | 1838 // Get the address of the keys and field_offsets arrays. Used in |
1691 // generated code to perform cache lookups. | 1839 // generated code to perform cache lookups. |
1692 static Address keys_address() { | 1840 Address keys_address() { |
1693 return reinterpret_cast<Address>(&keys_); | 1841 return reinterpret_cast<Address>(&keys_); |
1694 } | 1842 } |
1695 | 1843 |
1696 static Address field_offsets_address() { | 1844 Address field_offsets_address() { |
1697 return reinterpret_cast<Address>(&field_offsets_); | 1845 return reinterpret_cast<Address>(&field_offsets_); |
1698 } | 1846 } |
1699 | 1847 |
1700 struct Key { | 1848 struct Key { |
1701 Map* map; | 1849 Map* map; |
1702 String* name; | 1850 String* name; |
1703 }; | 1851 }; |
1704 static Key keys_[kLength]; | 1852 |
1705 static int field_offsets_[kLength]; | 1853 Key keys_[kLength]; |
| 1854 int field_offsets_[kLength]; |
1706 | 1855 |
1707 friend class ExternalReference; | 1856 friend class ExternalReference; |
| 1857 friend class Isolate; |
| 1858 DISALLOW_COPY_AND_ASSIGN(KeyedLookupCache); |
1708 }; | 1859 }; |
1709 | 1860 |
1710 | 1861 |
1711 // Cache for mapping (array, property name) into descriptor index. | 1862 // Cache for mapping (array, property name) into descriptor index. |
1712 // The cache contains both positive and negative results. | 1863 // The cache contains both positive and negative results. |
1713 // Descriptor index equals kNotFound means the property is absent. | 1864 // Descriptor index equals kNotFound means the property is absent. |
1714 // Cleared at startup and prior to any gc. | 1865 // Cleared at startup and prior to any gc. |
1715 class DescriptorLookupCache { | 1866 class DescriptorLookupCache { |
1716 public: | 1867 public: |
1717 // Lookup descriptor index for (map, name). | 1868 // Lookup descriptor index for (map, name). |
1718 // If absent, kAbsent is returned. | 1869 // If absent, kAbsent is returned. |
1719 static int Lookup(DescriptorArray* array, String* name) { | 1870 int Lookup(DescriptorArray* array, String* name) { |
1720 if (!StringShape(name).IsSymbol()) return kAbsent; | 1871 if (!StringShape(name).IsSymbol()) return kAbsent; |
1721 int index = Hash(array, name); | 1872 int index = Hash(array, name); |
1722 Key& key = keys_[index]; | 1873 Key& key = keys_[index]; |
1723 if ((key.array == array) && (key.name == name)) return results_[index]; | 1874 if ((key.array == array) && (key.name == name)) return results_[index]; |
1724 return kAbsent; | 1875 return kAbsent; |
1725 } | 1876 } |
1726 | 1877 |
1727 // Update an element in the cache. | 1878 // Update an element in the cache. |
1728 static void Update(DescriptorArray* array, String* name, int result) { | 1879 void Update(DescriptorArray* array, String* name, int result) { |
1729 ASSERT(result != kAbsent); | 1880 ASSERT(result != kAbsent); |
1730 if (StringShape(name).IsSymbol()) { | 1881 if (StringShape(name).IsSymbol()) { |
1731 int index = Hash(array, name); | 1882 int index = Hash(array, name); |
1732 Key& key = keys_[index]; | 1883 Key& key = keys_[index]; |
1733 key.array = array; | 1884 key.array = array; |
1734 key.name = name; | 1885 key.name = name; |
1735 results_[index] = result; | 1886 results_[index] = result; |
1736 } | 1887 } |
1737 } | 1888 } |
1738 | 1889 |
1739 // Clear the cache. | 1890 // Clear the cache. |
1740 static void Clear(); | 1891 void Clear(); |
1741 | 1892 |
1742 static const int kAbsent = -2; | 1893 static const int kAbsent = -2; |
1743 private: | 1894 private: |
| 1895 DescriptorLookupCache() { |
| 1896 for (int i = 0; i < kLength; ++i) { |
| 1897 keys_[i].array = NULL; |
| 1898 keys_[i].name = NULL; |
| 1899 results_[i] = kAbsent; |
| 1900 } |
| 1901 } |
| 1902 |
1744 static int Hash(DescriptorArray* array, String* name) { | 1903 static int Hash(DescriptorArray* array, String* name) { |
1745 // Uses only lower 32 bits if pointers are larger. | 1904 // Uses only lower 32 bits if pointers are larger. |
1746 uint32_t array_hash = | 1905 uint32_t array_hash = |
1747 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2; | 1906 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(array)) >> 2; |
1748 uint32_t name_hash = | 1907 uint32_t name_hash = |
1749 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2; | 1908 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >> 2; |
1750 return (array_hash ^ name_hash) % kLength; | 1909 return (array_hash ^ name_hash) % kLength; |
1751 } | 1910 } |
1752 | 1911 |
1753 static const int kLength = 64; | 1912 static const int kLength = 64; |
1754 struct Key { | 1913 struct Key { |
1755 DescriptorArray* array; | 1914 DescriptorArray* array; |
1756 String* name; | 1915 String* name; |
1757 }; | 1916 }; |
1758 | 1917 |
1759 static Key keys_[kLength]; | 1918 Key keys_[kLength]; |
1760 static int results_[kLength]; | 1919 int results_[kLength]; |
| 1920 |
| 1921 friend class Isolate; |
| 1922 DISALLOW_COPY_AND_ASSIGN(DescriptorLookupCache); |
1761 }; | 1923 }; |
1762 | 1924 |
1763 | 1925 |
1764 // ---------------------------------------------------------------------------- | |
1765 // Marking stack for tracing live objects. | |
1766 | |
1767 class MarkingStack { | |
1768 public: | |
1769 void Initialize(Address low, Address high) { | |
1770 top_ = low_ = reinterpret_cast<HeapObject**>(low); | |
1771 high_ = reinterpret_cast<HeapObject**>(high); | |
1772 overflowed_ = false; | |
1773 } | |
1774 | |
1775 bool is_full() { return top_ >= high_; } | |
1776 | |
1777 bool is_empty() { return top_ <= low_; } | |
1778 | |
1779 bool overflowed() { return overflowed_; } | |
1780 | |
1781 void clear_overflowed() { overflowed_ = false; } | |
1782 | |
1783 // Push the (marked) object on the marking stack if there is room, | |
1784 // otherwise mark the object as overflowed and wait for a rescan of the | |
1785 // heap. | |
1786 void Push(HeapObject* object) { | |
1787 CHECK(object->IsHeapObject()); | |
1788 if (is_full()) { | |
1789 object->SetOverflow(); | |
1790 overflowed_ = true; | |
1791 } else { | |
1792 *(top_++) = object; | |
1793 } | |
1794 } | |
1795 | |
1796 HeapObject* Pop() { | |
1797 ASSERT(!is_empty()); | |
1798 HeapObject* object = *(--top_); | |
1799 CHECK(object->IsHeapObject()); | |
1800 return object; | |
1801 } | |
1802 | |
1803 private: | |
1804 HeapObject** low_; | |
1805 HeapObject** top_; | |
1806 HeapObject** high_; | |
1807 bool overflowed_; | |
1808 }; | |
1809 | |
1810 | |
1811 // A helper class to document/test C++ scopes where we do not | 1926 // A helper class to document/test C++ scopes where we do not |
1812 // expect a GC. Usage: | 1927 // expect a GC. Usage: |
1813 // | 1928 // |
1814 // /* Allocation not allowed: we cannot handle a GC in this scope. */ | 1929 // /* Allocation not allowed: we cannot handle a GC in this scope. */ |
1815 // { AssertNoAllocation nogc; | 1930 // { AssertNoAllocation nogc; |
1816 // ... | 1931 // ... |
1817 // } | 1932 // } |
1818 | 1933 |
1819 #ifdef DEBUG | 1934 #ifdef DEBUG |
1820 | 1935 |
1821 class DisallowAllocationFailure { | 1936 class DisallowAllocationFailure { |
1822 public: | 1937 public: |
1823 DisallowAllocationFailure() { | 1938 DisallowAllocationFailure() { |
1824 old_state_ = Heap::disallow_allocation_failure_; | 1939 old_state_ = HEAP->disallow_allocation_failure_; |
1825 Heap::disallow_allocation_failure_ = true; | 1940 HEAP->disallow_allocation_failure_ = true; |
1826 } | 1941 } |
1827 ~DisallowAllocationFailure() { | 1942 ~DisallowAllocationFailure() { |
1828 Heap::disallow_allocation_failure_ = old_state_; | 1943 HEAP->disallow_allocation_failure_ = old_state_; |
1829 } | 1944 } |
1830 private: | 1945 private: |
1831 bool old_state_; | 1946 bool old_state_; |
1832 }; | 1947 }; |
1833 | 1948 |
1834 class AssertNoAllocation { | 1949 class AssertNoAllocation { |
1835 public: | 1950 public: |
1836 AssertNoAllocation() { | 1951 AssertNoAllocation() { |
1837 old_state_ = Heap::allow_allocation(false); | 1952 old_state_ = HEAP->allow_allocation(false); |
1838 } | 1953 } |
1839 | 1954 |
1840 ~AssertNoAllocation() { | 1955 ~AssertNoAllocation() { |
1841 Heap::allow_allocation(old_state_); | 1956 HEAP->allow_allocation(old_state_); |
1842 } | 1957 } |
1843 | 1958 |
1844 private: | 1959 private: |
1845 bool old_state_; | 1960 bool old_state_; |
1846 }; | 1961 }; |
1847 | 1962 |
1848 class DisableAssertNoAllocation { | 1963 class DisableAssertNoAllocation { |
1849 public: | 1964 public: |
1850 DisableAssertNoAllocation() { | 1965 DisableAssertNoAllocation() { |
1851 old_state_ = Heap::allow_allocation(true); | 1966 old_state_ = HEAP->allow_allocation(true); |
1852 } | 1967 } |
1853 | 1968 |
1854 ~DisableAssertNoAllocation() { | 1969 ~DisableAssertNoAllocation() { |
1855 Heap::allow_allocation(old_state_); | 1970 HEAP->allow_allocation(old_state_); |
1856 } | 1971 } |
1857 | 1972 |
1858 private: | 1973 private: |
1859 bool old_state_; | 1974 bool old_state_; |
1860 }; | 1975 }; |
1861 | 1976 |
1862 #else // ndef DEBUG | 1977 #else // ndef DEBUG |
1863 | 1978 |
1864 class AssertNoAllocation { | 1979 class AssertNoAllocation { |
1865 public: | 1980 public: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1902 ASSERT(scope_ < kNumberOfScopes); // scope_ is unsigned. | 2017 ASSERT(scope_ < kNumberOfScopes); // scope_ is unsigned. |
1903 tracer_->scopes_[scope_] += OS::TimeCurrentMillis() - start_time_; | 2018 tracer_->scopes_[scope_] += OS::TimeCurrentMillis() - start_time_; |
1904 } | 2019 } |
1905 | 2020 |
1906 private: | 2021 private: |
1907 GCTracer* tracer_; | 2022 GCTracer* tracer_; |
1908 ScopeId scope_; | 2023 ScopeId scope_; |
1909 double start_time_; | 2024 double start_time_; |
1910 }; | 2025 }; |
1911 | 2026 |
1912 GCTracer(); | 2027 explicit GCTracer(Heap* heap); |
1913 ~GCTracer(); | 2028 ~GCTracer(); |
1914 | 2029 |
1915 // Sets the collector. | 2030 // Sets the collector. |
1916 void set_collector(GarbageCollector collector) { collector_ = collector; } | 2031 void set_collector(GarbageCollector collector) { collector_ = collector; } |
1917 | 2032 |
1918 // Sets the GC count. | 2033 // Sets the GC count. |
1919 void set_gc_count(unsigned int count) { gc_count_ = count; } | 2034 void set_gc_count(unsigned int count) { gc_count_ = count; } |
1920 | 2035 |
1921 // Sets the full GC count. | 2036 // Sets the full GC count. |
1922 void set_full_gc_count(int count) { full_gc_count_ = count; } | 2037 void set_full_gc_count(int count) { full_gc_count_ = count; } |
1923 | 2038 |
1924 // Sets the flag that this is a compacting full GC. | 2039 // Sets the flag that this is a compacting full GC. |
1925 void set_is_compacting() { is_compacting_ = true; } | 2040 void set_is_compacting() { is_compacting_ = true; } |
1926 bool is_compacting() const { return is_compacting_; } | 2041 bool is_compacting() const { return is_compacting_; } |
1927 | 2042 |
1928 // Increment and decrement the count of marked objects. | 2043 // Increment and decrement the count of marked objects. |
1929 void increment_marked_count() { ++marked_count_; } | 2044 void increment_marked_count() { ++marked_count_; } |
1930 void decrement_marked_count() { --marked_count_; } | 2045 void decrement_marked_count() { --marked_count_; } |
1931 | 2046 |
1932 int marked_count() { return marked_count_; } | 2047 int marked_count() { return marked_count_; } |
1933 | 2048 |
1934 void increment_promoted_objects_size(int object_size) { | 2049 void increment_promoted_objects_size(int object_size) { |
1935 promoted_objects_size_ += object_size; | 2050 promoted_objects_size_ += object_size; |
1936 } | 2051 } |
1937 | 2052 |
1938 // Returns maximum GC pause. | |
1939 static int get_max_gc_pause() { return max_gc_pause_; } | |
1940 | |
1941 // Returns maximum size of objects alive after GC. | |
1942 static intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } | |
1943 | |
1944 // Returns minimal interval between two subsequent collections. | |
1945 static int get_min_in_mutator() { return min_in_mutator_; } | |
1946 | |
1947 private: | 2053 private: |
1948 // Returns a string matching the collector. | 2054 // Returns a string matching the collector. |
1949 const char* CollectorString(); | 2055 const char* CollectorString(); |
1950 | 2056 |
1951 // Returns size of object in heap (in MB). | 2057 // Returns size of object in heap (in MB). |
1952 double SizeOfHeapObjects() { | 2058 double SizeOfHeapObjects() { |
1953 return (static_cast<double>(Heap::SizeOfObjects())) / MB; | 2059 return (static_cast<double>(HEAP->SizeOfObjects())) / MB; |
1954 } | 2060 } |
1955 | 2061 |
1956 double start_time_; // Timestamp set in the constructor. | 2062 double start_time_; // Timestamp set in the constructor. |
1957 intptr_t start_size_; // Size of objects in heap set in constructor. | 2063 intptr_t start_size_; // Size of objects in heap set in constructor. |
1958 GarbageCollector collector_; // Type of collector. | 2064 GarbageCollector collector_; // Type of collector. |
1959 | 2065 |
1960 // A count (including this one, eg, the first collection is 1) of the | 2066 // A count (including this one, eg, the first collection is 1) of the |
1961 // number of garbage collections. | 2067 // number of garbage collections. |
1962 unsigned int gc_count_; | 2068 unsigned int gc_count_; |
1963 | 2069 |
(...skipping 28 matching lines...) Expand all Loading... |
1992 // collection and the end of the previous collection. | 2098 // collection and the end of the previous collection. |
1993 intptr_t allocated_since_last_gc_; | 2099 intptr_t allocated_since_last_gc_; |
1994 | 2100 |
1995 // Amount of time spent in mutator that is time elapsed between end of the | 2101 // Amount of time spent in mutator that is time elapsed between end of the |
1996 // previous collection and the beginning of the current one. | 2102 // previous collection and the beginning of the current one. |
1997 double spent_in_mutator_; | 2103 double spent_in_mutator_; |
1998 | 2104 |
1999 // Size of objects promoted during the current collection. | 2105 // Size of objects promoted during the current collection. |
2000 intptr_t promoted_objects_size_; | 2106 intptr_t promoted_objects_size_; |
2001 | 2107 |
2002 // Maximum GC pause. | 2108 Heap* heap_; |
2003 static int max_gc_pause_; | |
2004 | |
2005 // Maximum size of objects alive after GC. | |
2006 static intptr_t max_alive_after_gc_; | |
2007 | |
2008 // Minimal interval between two subsequent collections. | |
2009 static int min_in_mutator_; | |
2010 | |
2011 // Size of objects alive after last GC. | |
2012 static intptr_t alive_after_last_gc_; | |
2013 | |
2014 static double last_gc_end_timestamp_; | |
2015 }; | 2109 }; |
2016 | 2110 |
2017 | 2111 |
2018 class TranscendentalCache { | 2112 class TranscendentalCache { |
2019 public: | 2113 public: |
2020 enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches}; | 2114 enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches}; |
2021 static const int kTranscendentalTypeBits = 3; | 2115 static const int kTranscendentalTypeBits = 3; |
2022 STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches); | 2116 STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches); |
2023 | 2117 |
2024 explicit TranscendentalCache(Type t); | |
2025 | |
2026 // Returns a heap number with f(input), where f is a math function specified | 2118 // Returns a heap number with f(input), where f is a math function specified |
2027 // by the 'type' argument. | 2119 // by the 'type' argument. |
2028 MUST_USE_RESULT static inline MaybeObject* Get(Type type, double input) { | 2120 MUST_USE_RESULT inline MaybeObject* Get(Type type, double input); |
2029 TranscendentalCache* cache = caches_[type]; | |
2030 if (cache == NULL) { | |
2031 caches_[type] = cache = new TranscendentalCache(type); | |
2032 } | |
2033 return cache->Get(input); | |
2034 } | |
2035 | 2121 |
2036 // The cache contains raw Object pointers. This method disposes of | 2122 // The cache contains raw Object pointers. This method disposes of |
2037 // them before a garbage collection. | 2123 // them before a garbage collection. |
2038 static void Clear(); | 2124 void Clear(); |
2039 | 2125 |
2040 private: | 2126 private: |
2041 MUST_USE_RESULT inline MaybeObject* Get(double input) { | 2127 class SubCache { |
2042 Converter c; | 2128 static const int kCacheSize = 512; |
2043 c.dbl = input; | 2129 |
2044 int hash = Hash(c); | 2130 explicit SubCache(Type t); |
2045 Element e = elements_[hash]; | 2131 |
2046 if (e.in[0] == c.integers[0] && | 2132 MUST_USE_RESULT inline MaybeObject* Get(double input); |
2047 e.in[1] == c.integers[1]) { | 2133 |
2048 ASSERT(e.output != NULL); | 2134 inline double Calculate(double input); |
2049 Counters::transcendental_cache_hit.Increment(); | 2135 |
2050 return e.output; | 2136 struct Element { |
| 2137 uint32_t in[2]; |
| 2138 Object* output; |
| 2139 }; |
| 2140 |
| 2141 union Converter { |
| 2142 double dbl; |
| 2143 uint32_t integers[2]; |
| 2144 }; |
| 2145 |
| 2146 inline static int Hash(const Converter& c) { |
| 2147 uint32_t hash = (c.integers[0] ^ c.integers[1]); |
| 2148 hash ^= static_cast<int32_t>(hash) >> 16; |
| 2149 hash ^= static_cast<int32_t>(hash) >> 8; |
| 2150 return (hash & (kCacheSize - 1)); |
2051 } | 2151 } |
2052 double answer = Calculate(input); | 2152 |
2053 Counters::transcendental_cache_miss.Increment(); | 2153 Element elements_[kCacheSize]; |
2054 Object* heap_number; | 2154 Type type_; |
2055 { MaybeObject* maybe_heap_number = Heap::AllocateHeapNumber(answer); | 2155 Isolate* isolate_; |
2056 if (!maybe_heap_number->ToObject(&heap_number)) return maybe_heap_number; | 2156 |
2057 } | 2157 // Allow access to the caches_ array as an ExternalReference. |
2058 elements_[hash].in[0] = c.integers[0]; | 2158 friend class ExternalReference; |
2059 elements_[hash].in[1] = c.integers[1]; | 2159 // Inline implementation of the cache. |
2060 elements_[hash].output = heap_number; | 2160 friend class TranscendentalCacheStub; |
2061 return heap_number; | 2161 // For evaluating value. |
| 2162 friend class TranscendentalCache; |
| 2163 |
| 2164 DISALLOW_COPY_AND_ASSIGN(SubCache); |
| 2165 }; |
| 2166 |
| 2167 TranscendentalCache() { |
| 2168 for (int i = 0; i < kNumberOfCaches; ++i) caches_[i] = NULL; |
2062 } | 2169 } |
2063 | 2170 |
2064 inline double Calculate(double input) { | 2171 // Used to create an external reference. |
2065 switch (type_) { | 2172 inline Address cache_array_address(); |
2066 case ACOS: | |
2067 return acos(input); | |
2068 case ASIN: | |
2069 return asin(input); | |
2070 case ATAN: | |
2071 return atan(input); | |
2072 case COS: | |
2073 return cos(input); | |
2074 case EXP: | |
2075 return exp(input); | |
2076 case LOG: | |
2077 return log(input); | |
2078 case SIN: | |
2079 return sin(input); | |
2080 case TAN: | |
2081 return tan(input); | |
2082 default: | |
2083 return 0.0; // Never happens. | |
2084 } | |
2085 } | |
2086 static const int kCacheSize = 512; | |
2087 struct Element { | |
2088 uint32_t in[2]; | |
2089 Object* output; | |
2090 }; | |
2091 union Converter { | |
2092 double dbl; | |
2093 uint32_t integers[2]; | |
2094 }; | |
2095 inline static int Hash(const Converter& c) { | |
2096 uint32_t hash = (c.integers[0] ^ c.integers[1]); | |
2097 hash ^= static_cast<int32_t>(hash) >> 16; | |
2098 hash ^= static_cast<int32_t>(hash) >> 8; | |
2099 return (hash & (kCacheSize - 1)); | |
2100 } | |
2101 | 2173 |
2102 static Address cache_array_address() { | 2174 // Instantiation |
2103 // Used to create an external reference. | 2175 friend class Isolate; |
2104 return reinterpret_cast<Address>(caches_); | 2176 // Inline implementation of the caching. |
2105 } | 2177 friend class TranscendentalCacheStub; |
2106 | |
2107 // Allow access to the caches_ array as an ExternalReference. | 2178 // Allow access to the caches_ array as an ExternalReference. |
2108 friend class ExternalReference; | 2179 friend class ExternalReference; |
2109 // Inline implementation of the cache. | |
2110 friend class TranscendentalCacheStub; | |
2111 | 2180 |
2112 static TranscendentalCache* caches_[kNumberOfCaches]; | 2181 SubCache* caches_[kNumberOfCaches]; |
2113 Element elements_[kCacheSize]; | 2182 DISALLOW_COPY_AND_ASSIGN(TranscendentalCache); |
2114 Type type_; | |
2115 }; | 2183 }; |
2116 | 2184 |
2117 | 2185 |
2118 // External strings table is a place where all external strings are | |
2119 // registered. We need to keep track of such strings to properly | |
2120 // finalize them. | |
2121 class ExternalStringTable : public AllStatic { | |
2122 public: | |
2123 // Registers an external string. | |
2124 inline static void AddString(String* string); | |
2125 | |
2126 inline static void Iterate(ObjectVisitor* v); | |
2127 | |
2128 // Restores internal invariant and gets rid of collected strings. | |
2129 // Must be called after each Iterate() that modified the strings. | |
2130 static void CleanUp(); | |
2131 | |
2132 // Destroys all allocated memory. | |
2133 static void TearDown(); | |
2134 | |
2135 private: | |
2136 friend class Heap; | |
2137 | |
2138 inline static void Verify(); | |
2139 | |
2140 inline static void AddOldString(String* string); | |
2141 | |
2142 // Notifies the table that only a prefix of the new list is valid. | |
2143 inline static void ShrinkNewStrings(int position); | |
2144 | |
2145 // To speed up scavenge collections new space string are kept | |
2146 // separate from old space strings. | |
2147 static List<Object*> new_space_strings_; | |
2148 static List<Object*> old_space_strings_; | |
2149 }; | |
2150 | |
2151 | |
2152 // Abstract base class for checking whether a weak object should be retained. | 2186 // Abstract base class for checking whether a weak object should be retained. |
2153 class WeakObjectRetainer { | 2187 class WeakObjectRetainer { |
2154 public: | 2188 public: |
2155 virtual ~WeakObjectRetainer() {} | 2189 virtual ~WeakObjectRetainer() {} |
2156 | 2190 |
2157 // Return whether this object should be retained. If NULL is returned the | 2191 // Return whether this object should be retained. If NULL is returned the |
2158 // object has no references. Otherwise the address of the retained object | 2192 // object has no references. Otherwise the address of the retained object |
2159 // should be returned as in some GC situations the object has been moved. | 2193 // should be returned as in some GC situations the object has been moved. |
2160 virtual Object* RetainAs(Object* object) = 0; | 2194 virtual Object* RetainAs(Object* object) = 0; |
2161 }; | 2195 }; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2215 | 2249 |
2216 AssertNoAllocation no_alloc; // i.e. no gc allowed. | 2250 AssertNoAllocation no_alloc; // i.e. no gc allowed. |
2217 | 2251 |
2218 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2252 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
2219 }; | 2253 }; |
2220 #endif // DEBUG || LIVE_OBJECT_LIST | 2254 #endif // DEBUG || LIVE_OBJECT_LIST |
2221 | 2255 |
2222 | 2256 |
2223 } } // namespace v8::internal | 2257 } } // namespace v8::internal |
2224 | 2258 |
| 2259 #undef HEAP |
| 2260 |
2225 #endif // V8_HEAP_H_ | 2261 #endif // V8_HEAP_H_ |
OLD | NEW |