OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 // maps. | 895 // maps. |
896 isolate_->keyed_lookup_cache()->Clear(); | 896 isolate_->keyed_lookup_cache()->Clear(); |
897 isolate_->context_slot_cache()->Clear(); | 897 isolate_->context_slot_cache()->Clear(); |
898 isolate_->descriptor_lookup_cache()->Clear(); | 898 isolate_->descriptor_lookup_cache()->Clear(); |
899 StringSplitCache::Clear(string_split_cache()); | 899 StringSplitCache::Clear(string_split_cache()); |
900 | 900 |
901 isolate_->compilation_cache()->MarkCompactPrologue(); | 901 isolate_->compilation_cache()->MarkCompactPrologue(); |
902 | 902 |
903 CompletelyClearInstanceofCache(); | 903 CompletelyClearInstanceofCache(); |
904 | 904 |
905 FlushNumberStringCache(); | 905 // TODO(1605) select heuristic for flushing NumberString cache with |
| 906 // FlushNumberStringCache |
906 if (FLAG_cleanup_code_caches_at_gc) { | 907 if (FLAG_cleanup_code_caches_at_gc) { |
907 polymorphic_code_cache()->set_cache(undefined_value()); | 908 polymorphic_code_cache()->set_cache(undefined_value()); |
908 } | 909 } |
909 | 910 |
910 ClearNormalizedMapCaches(); | 911 ClearNormalizedMapCaches(); |
911 } | 912 } |
912 | 913 |
913 | 914 |
914 Object* Heap::FindCodeObject(Address a) { | 915 Object* Heap::FindCodeObject(Address a) { |
915 return isolate()->inner_pointer_to_code_cache()-> | 916 return isolate()->inner_pointer_to_code_cache()-> |
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 // Allocate the dictionary of intrinsic function names. | 2505 // Allocate the dictionary of intrinsic function names. |
2505 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); | 2506 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); |
2506 if (!maybe_obj->ToObject(&obj)) return false; | 2507 if (!maybe_obj->ToObject(&obj)) return false; |
2507 } | 2508 } |
2508 { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this, | 2509 { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this, |
2509 obj); | 2510 obj); |
2510 if (!maybe_obj->ToObject(&obj)) return false; | 2511 if (!maybe_obj->ToObject(&obj)) return false; |
2511 } | 2512 } |
2512 set_intrinsic_function_names(StringDictionary::cast(obj)); | 2513 set_intrinsic_function_names(StringDictionary::cast(obj)); |
2513 | 2514 |
2514 { MaybeObject* maybe_obj = AllocateInitialNumberStringCache(); | 2515 if (InitializeNumberStringCache()->IsFailure()) return false; |
2515 if (!maybe_obj->ToObject(&obj)) return false; | |
2516 } | |
2517 set_number_string_cache(FixedArray::cast(obj)); | |
2518 | 2516 |
2519 // Allocate cache for single character ASCII strings. | 2517 // Allocate cache for single character ASCII strings. |
2520 { MaybeObject* maybe_obj = | 2518 { MaybeObject* maybe_obj = |
2521 AllocateFixedArray(String::kMaxAsciiCharCode + 1, TENURED); | 2519 AllocateFixedArray(String::kMaxAsciiCharCode + 1, TENURED); |
2522 if (!maybe_obj->ToObject(&obj)) return false; | 2520 if (!maybe_obj->ToObject(&obj)) return false; |
2523 } | 2521 } |
2524 set_single_character_string_cache(FixedArray::cast(obj)); | 2522 set_single_character_string_cache(FixedArray::cast(obj)); |
2525 | 2523 |
2526 // Allocate cache for string split. | 2524 // Allocate cache for string split. |
2527 { MaybeObject* maybe_obj = | 2525 { MaybeObject* maybe_obj = |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2617 } | 2615 } |
2618 | 2616 |
2619 | 2617 |
2620 void StringSplitCache::Clear(FixedArray* cache) { | 2618 void StringSplitCache::Clear(FixedArray* cache) { |
2621 for (int i = 0; i < kStringSplitCacheSize; i++) { | 2619 for (int i = 0; i < kStringSplitCacheSize; i++) { |
2622 cache->set(i, Smi::FromInt(0)); | 2620 cache->set(i, Smi::FromInt(0)); |
2623 } | 2621 } |
2624 } | 2622 } |
2625 | 2623 |
2626 | 2624 |
2627 MaybeObject* Heap::AllocateInitialNumberStringCache() { | 2625 MaybeObject* Heap::InitializeNumberStringCache() { |
| 2626 // Compute the size of the number string cache based on the max heap size. |
| 2627 // max_semispace_size_ == 512 KB => number_string_cache_size = 32. |
| 2628 // max_semispace_size_ == 8 MB => number_string_cache_size = 16KB. |
| 2629 int number_string_cache_size = max_semispace_size_ / 512; |
| 2630 number_string_cache_size = Max(32, Min(16*KB, number_string_cache_size)); |
| 2631 Object* obj; |
2628 MaybeObject* maybe_obj = | 2632 MaybeObject* maybe_obj = |
2629 AllocateFixedArray(kInitialNumberStringCacheSize * 2, TENURED); | 2633 AllocateFixedArray(number_string_cache_size * 2, TENURED); |
| 2634 if (maybe_obj->ToObject(&obj)) set_number_string_cache(FixedArray::cast(obj)); |
2630 return maybe_obj; | 2635 return maybe_obj; |
2631 } | 2636 } |
2632 | 2637 |
2633 | 2638 |
2634 int Heap::FullSizeNumberStringCacheLength() { | |
2635 // Compute the size of the number string cache based on the max newspace size. | |
2636 // The number string cache has a minimum size based on twice the initial cache | |
2637 // size to ensure that it is bigger after being made 'full size'. | |
2638 int number_string_cache_size = max_semispace_size_ / 512; | |
2639 number_string_cache_size = Max(kInitialNumberStringCacheSize * 2, | |
2640 Min(0x4000, number_string_cache_size)); | |
2641 // There is a string and a number per entry so the length is twice the number | |
2642 // of entries. | |
2643 return number_string_cache_size * 2; | |
2644 } | |
2645 | |
2646 | |
2647 void Heap::AllocateFullSizeNumberStringCache() { | |
2648 // The idea is to have a small number string cache in the snapshot to keep | |
2649 // boot-time memory usage down. If we expand the number string cache already | |
2650 // while creating the snapshot then that didn't work out. | |
2651 ASSERT(!Serializer::enabled()); | |
2652 MaybeObject* maybe_obj = | |
2653 AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED); | |
2654 Object* new_cache; | |
2655 if (maybe_obj->ToObject(&new_cache)) { | |
2656 // We don't bother to repopulate the cache with entries from the old cache. | |
2657 // It will be repopulated soon enough with new strings. | |
2658 set_number_string_cache(FixedArray::cast(new_cache)); | |
2659 } | |
2660 // If allocation fails then we just return without doing anything. It is only | |
2661 // a cache, so best effort is OK here. | |
2662 } | |
2663 | |
2664 | |
2665 void Heap::FlushNumberStringCache() { | 2639 void Heap::FlushNumberStringCache() { |
2666 // Flush the number to string cache. | 2640 // Flush the number to string cache. |
2667 int len = number_string_cache()->length(); | 2641 int len = number_string_cache()->length(); |
2668 for (int i = 0; i < len; i++) { | 2642 for (int i = 0; i < len; i++) { |
2669 number_string_cache()->set_undefined(this, i); | 2643 number_string_cache()->set_undefined(this, i); |
2670 } | 2644 } |
2671 } | 2645 } |
2672 | 2646 |
2673 | 2647 |
2674 static inline int double_get_hash(double d) { | 2648 static inline int double_get_hash(double d) { |
(...skipping 25 matching lines...) Expand all Loading... |
2700 } | 2674 } |
2701 return undefined_value(); | 2675 return undefined_value(); |
2702 } | 2676 } |
2703 | 2677 |
2704 | 2678 |
2705 void Heap::SetNumberStringCache(Object* number, String* string) { | 2679 void Heap::SetNumberStringCache(Object* number, String* string) { |
2706 int hash; | 2680 int hash; |
2707 int mask = (number_string_cache()->length() >> 1) - 1; | 2681 int mask = (number_string_cache()->length() >> 1) - 1; |
2708 if (number->IsSmi()) { | 2682 if (number->IsSmi()) { |
2709 hash = smi_get_hash(Smi::cast(number)) & mask; | 2683 hash = smi_get_hash(Smi::cast(number)) & mask; |
| 2684 number_string_cache()->set(hash * 2, Smi::cast(number)); |
2710 } else { | 2685 } else { |
2711 hash = double_get_hash(number->Number()) & mask; | 2686 hash = double_get_hash(number->Number()) & mask; |
| 2687 number_string_cache()->set(hash * 2, number); |
2712 } | 2688 } |
2713 if (number_string_cache()->get(hash * 2) != undefined_value() && | |
2714 number_string_cache()->length() != FullSizeNumberStringCacheLength()) { | |
2715 // The first time we have a hash collision, we move to the full sized | |
2716 // number string cache. | |
2717 AllocateFullSizeNumberStringCache(); | |
2718 return; | |
2719 } | |
2720 number_string_cache()->set(hash * 2, number); | |
2721 number_string_cache()->set(hash * 2 + 1, string); | 2689 number_string_cache()->set(hash * 2 + 1, string); |
2722 } | 2690 } |
2723 | 2691 |
2724 | 2692 |
2725 MaybeObject* Heap::NumberToString(Object* number, | 2693 MaybeObject* Heap::NumberToString(Object* number, |
2726 bool check_number_string_cache) { | 2694 bool check_number_string_cache) { |
2727 isolate_->counters()->number_to_string_runtime()->Increment(); | 2695 isolate_->counters()->number_to_string_runtime()->Increment(); |
2728 if (check_number_string_cache) { | 2696 if (check_number_string_cache) { |
2729 Object* cached = GetNumberStringCache(number); | 2697 Object* cached = GetNumberStringCache(number); |
2730 if (cached != undefined_value()) { | 2698 if (cached != undefined_value()) { |
(...skipping 4004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6735 isolate_->heap()->store_buffer()->Compact(); | 6703 isolate_->heap()->store_buffer()->Compact(); |
6736 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6704 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
6737 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6705 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
6738 next = chunk->next_chunk(); | 6706 next = chunk->next_chunk(); |
6739 isolate_->memory_allocator()->Free(chunk); | 6707 isolate_->memory_allocator()->Free(chunk); |
6740 } | 6708 } |
6741 chunks_queued_for_free_ = NULL; | 6709 chunks_queued_for_free_ = NULL; |
6742 } | 6710 } |
6743 | 6711 |
6744 } } // namespace v8::internal | 6712 } } // namespace v8::internal |
OLD | NEW |