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 // TODO(1605) select heuristic for flushing NumberString cache with | 905 FlushNumberStringCache(); |
906 // FlushNumberStringCache | |
907 if (FLAG_cleanup_code_caches_at_gc) { | 906 if (FLAG_cleanup_code_caches_at_gc) { |
908 polymorphic_code_cache()->set_cache(undefined_value()); | 907 polymorphic_code_cache()->set_cache(undefined_value()); |
909 } | 908 } |
910 | 909 |
911 ClearNormalizedMapCaches(); | 910 ClearNormalizedMapCaches(); |
912 } | 911 } |
913 | 912 |
914 | 913 |
915 Object* Heap::FindCodeObject(Address a) { | 914 Object* Heap::FindCodeObject(Address a) { |
916 return isolate()->inner_pointer_to_code_cache()-> | 915 return isolate()->inner_pointer_to_code_cache()-> |
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2505 // Allocate the dictionary of intrinsic function names. | 2504 // Allocate the dictionary of intrinsic function names. |
2506 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); | 2505 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); |
2507 if (!maybe_obj->ToObject(&obj)) return false; | 2506 if (!maybe_obj->ToObject(&obj)) return false; |
2508 } | 2507 } |
2509 { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this, | 2508 { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this, |
2510 obj); | 2509 obj); |
2511 if (!maybe_obj->ToObject(&obj)) return false; | 2510 if (!maybe_obj->ToObject(&obj)) return false; |
2512 } | 2511 } |
2513 set_intrinsic_function_names(StringDictionary::cast(obj)); | 2512 set_intrinsic_function_names(StringDictionary::cast(obj)); |
2514 | 2513 |
2515 if (InitializeNumberStringCache()->IsFailure()) return false; | 2514 { MaybeObject* maybe_obj = AllocateInitialNumberStringCache(); |
| 2515 if (!maybe_obj->ToObject(&obj)) return false; |
| 2516 } |
| 2517 set_number_string_cache(FixedArray::cast(obj)); |
2516 | 2518 |
2517 // Allocate cache for single character ASCII strings. | 2519 // Allocate cache for single character ASCII strings. |
2518 { MaybeObject* maybe_obj = | 2520 { MaybeObject* maybe_obj = |
2519 AllocateFixedArray(String::kMaxAsciiCharCode + 1, TENURED); | 2521 AllocateFixedArray(String::kMaxAsciiCharCode + 1, TENURED); |
2520 if (!maybe_obj->ToObject(&obj)) return false; | 2522 if (!maybe_obj->ToObject(&obj)) return false; |
2521 } | 2523 } |
2522 set_single_character_string_cache(FixedArray::cast(obj)); | 2524 set_single_character_string_cache(FixedArray::cast(obj)); |
2523 | 2525 |
2524 // Allocate cache for string split. | 2526 // Allocate cache for string split. |
2525 { MaybeObject* maybe_obj = | 2527 { MaybeObject* maybe_obj = |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2615 } | 2617 } |
2616 | 2618 |
2617 | 2619 |
2618 void StringSplitCache::Clear(FixedArray* cache) { | 2620 void StringSplitCache::Clear(FixedArray* cache) { |
2619 for (int i = 0; i < kStringSplitCacheSize; i++) { | 2621 for (int i = 0; i < kStringSplitCacheSize; i++) { |
2620 cache->set(i, Smi::FromInt(0)); | 2622 cache->set(i, Smi::FromInt(0)); |
2621 } | 2623 } |
2622 } | 2624 } |
2623 | 2625 |
2624 | 2626 |
2625 MaybeObject* Heap::InitializeNumberStringCache() { | 2627 MaybeObject* Heap::AllocateInitialNumberStringCache() { |
2626 // Compute the size of the number string cache based on the max heap size. | 2628 MaybeObject* maybe_obj = |
2627 // max_semispace_size_ == 512 KB => number_string_cache_size = 32. | 2629 AllocateFixedArray(kInitialNumberStringCacheSize * 2, TENURED); |
2628 // max_semispace_size_ == 8 MB => number_string_cache_size = 16KB. | 2630 return maybe_obj; |
| 2631 } |
| 2632 |
| 2633 |
| 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'. |
2629 int number_string_cache_size = max_semispace_size_ / 512; | 2638 int number_string_cache_size = max_semispace_size_ / 512; |
2630 number_string_cache_size = Max(32, Min(16*KB, number_string_cache_size)); | 2639 number_string_cache_size = Max(kInitialNumberStringCacheSize * 2, |
2631 Object* obj; | 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()); |
2632 MaybeObject* maybe_obj = | 2652 MaybeObject* maybe_obj = |
2633 AllocateFixedArray(number_string_cache_size * 2, TENURED); | 2653 AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED); |
2634 if (maybe_obj->ToObject(&obj)) set_number_string_cache(FixedArray::cast(obj)); | 2654 Object* new_cache; |
2635 return maybe_obj; | 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. |
2636 } | 2662 } |
2637 | 2663 |
2638 | 2664 |
2639 void Heap::FlushNumberStringCache() { | 2665 void Heap::FlushNumberStringCache() { |
2640 // Flush the number to string cache. | 2666 // Flush the number to string cache. |
2641 int len = number_string_cache()->length(); | 2667 int len = number_string_cache()->length(); |
2642 for (int i = 0; i < len; i++) { | 2668 for (int i = 0; i < len; i++) { |
2643 number_string_cache()->set_undefined(this, i); | 2669 number_string_cache()->set_undefined(this, i); |
2644 } | 2670 } |
2645 } | 2671 } |
(...skipping 28 matching lines...) Expand all Loading... |
2674 } | 2700 } |
2675 return undefined_value(); | 2701 return undefined_value(); |
2676 } | 2702 } |
2677 | 2703 |
2678 | 2704 |
2679 void Heap::SetNumberStringCache(Object* number, String* string) { | 2705 void Heap::SetNumberStringCache(Object* number, String* string) { |
2680 int hash; | 2706 int hash; |
2681 int mask = (number_string_cache()->length() >> 1) - 1; | 2707 int mask = (number_string_cache()->length() >> 1) - 1; |
2682 if (number->IsSmi()) { | 2708 if (number->IsSmi()) { |
2683 hash = smi_get_hash(Smi::cast(number)) & mask; | 2709 hash = smi_get_hash(Smi::cast(number)) & mask; |
2684 number_string_cache()->set(hash * 2, Smi::cast(number)); | |
2685 } else { | 2710 } else { |
2686 hash = double_get_hash(number->Number()) & mask; | 2711 hash = double_get_hash(number->Number()) & mask; |
2687 number_string_cache()->set(hash * 2, number); | |
2688 } | 2712 } |
| 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); |
2689 number_string_cache()->set(hash * 2 + 1, string); | 2721 number_string_cache()->set(hash * 2 + 1, string); |
2690 } | 2722 } |
2691 | 2723 |
2692 | 2724 |
2693 MaybeObject* Heap::NumberToString(Object* number, | 2725 MaybeObject* Heap::NumberToString(Object* number, |
2694 bool check_number_string_cache) { | 2726 bool check_number_string_cache) { |
2695 isolate_->counters()->number_to_string_runtime()->Increment(); | 2727 isolate_->counters()->number_to_string_runtime()->Increment(); |
2696 if (check_number_string_cache) { | 2728 if (check_number_string_cache) { |
2697 Object* cached = GetNumberStringCache(number); | 2729 Object* cached = GetNumberStringCache(number); |
2698 if (cached != undefined_value()) { | 2730 if (cached != undefined_value()) { |
(...skipping 4004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6703 isolate_->heap()->store_buffer()->Compact(); | 6735 isolate_->heap()->store_buffer()->Compact(); |
6704 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6736 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
6705 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6737 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
6706 next = chunk->next_chunk(); | 6738 next = chunk->next_chunk(); |
6707 isolate_->memory_allocator()->Free(chunk); | 6739 isolate_->memory_allocator()->Free(chunk); |
6708 } | 6740 } |
6709 chunks_queued_for_free_ = NULL; | 6741 chunks_queued_for_free_ = NULL; |
6710 } | 6742 } |
6711 | 6743 |
6712 } } // namespace v8::internal | 6744 } } // namespace v8::internal |
OLD | NEW |