OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 if (Heap::InNewSpace(target)) { | 797 if (Heap::InNewSpace(target)) { |
798 // String is still in new space. Update the table entry. | 798 // String is still in new space. Update the table entry. |
799 *last = target; | 799 *last = target; |
800 ++last; | 800 ++last; |
801 } else { | 801 } else { |
802 // String got promoted. Move it to the old string list. | 802 // String got promoted. Move it to the old string list. |
803 ExternalStringTable::AddOldString(target); | 803 ExternalStringTable::AddOldString(target); |
804 } | 804 } |
805 } | 805 } |
806 | 806 |
807 ExternalStringTable::ShrinkNewStrings(last - start); | 807 ASSERT(last <= end); |
| 808 ExternalStringTable::ShrinkNewStrings(static_cast<int>(last - start)); |
808 } | 809 } |
809 | 810 |
810 | 811 |
811 Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor, | 812 Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor, |
812 Address new_space_front) { | 813 Address new_space_front) { |
813 do { | 814 do { |
814 ASSERT(new_space_front <= new_space_.top()); | 815 ASSERT(new_space_front <= new_space_.top()); |
815 | 816 |
816 // The addresses new_space_front and new_space_.top() define a | 817 // The addresses new_space_front and new_space_.top() define a |
817 // queue of unprocessed copied objects. Process them until the | 818 // queue of unprocessed copied objects. Process them until the |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2011 | 2012 |
2012 Object* result = Heap::AllocateRawTwoByteString(1); | 2013 Object* result = Heap::AllocateRawTwoByteString(1); |
2013 if (result->IsFailure()) return result; | 2014 if (result->IsFailure()) return result; |
2014 String* answer = String::cast(result); | 2015 String* answer = String::cast(result); |
2015 answer->Set(0, code); | 2016 answer->Set(0, code); |
2016 return answer; | 2017 return answer; |
2017 } | 2018 } |
2018 | 2019 |
2019 | 2020 |
2020 Object* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { | 2021 Object* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { |
| 2022 if (length < 0 || length > ByteArray::kMaxLength) { |
| 2023 return Failure::OutOfMemoryException(); |
| 2024 } |
2021 if (pretenure == NOT_TENURED) { | 2025 if (pretenure == NOT_TENURED) { |
2022 return AllocateByteArray(length); | 2026 return AllocateByteArray(length); |
2023 } | 2027 } |
2024 int size = ByteArray::SizeFor(length); | 2028 int size = ByteArray::SizeFor(length); |
2025 Object* result = (size <= MaxObjectSizeInPagedSpace()) | 2029 Object* result = (size <= MaxObjectSizeInPagedSpace()) |
2026 ? old_data_space_->AllocateRaw(size) | 2030 ? old_data_space_->AllocateRaw(size) |
2027 : lo_space_->AllocateRaw(size); | 2031 : lo_space_->AllocateRaw(size); |
2028 if (result->IsFailure()) return result; | 2032 if (result->IsFailure()) return result; |
2029 | 2033 |
2030 reinterpret_cast<Array*>(result)->set_map(byte_array_map()); | 2034 reinterpret_cast<Array*>(result)->set_map(byte_array_map()); |
2031 reinterpret_cast<Array*>(result)->set_length(length); | 2035 reinterpret_cast<Array*>(result)->set_length(length); |
2032 return result; | 2036 return result; |
2033 } | 2037 } |
2034 | 2038 |
2035 | 2039 |
2036 Object* Heap::AllocateByteArray(int length) { | 2040 Object* Heap::AllocateByteArray(int length) { |
| 2041 if (length < 0 || length > ByteArray::kMaxLength) { |
| 2042 return Failure::OutOfMemoryException(); |
| 2043 } |
2037 int size = ByteArray::SizeFor(length); | 2044 int size = ByteArray::SizeFor(length); |
2038 AllocationSpace space = | 2045 AllocationSpace space = |
2039 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : NEW_SPACE; | 2046 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : NEW_SPACE; |
2040 Object* result = AllocateRaw(size, space, OLD_DATA_SPACE); | 2047 Object* result = AllocateRaw(size, space, OLD_DATA_SPACE); |
2041 if (result->IsFailure()) return result; | 2048 if (result->IsFailure()) return result; |
2042 | 2049 |
2043 reinterpret_cast<Array*>(result)->set_map(byte_array_map()); | 2050 reinterpret_cast<Array*>(result)->set_map(byte_array_map()); |
2044 reinterpret_cast<Array*>(result)->set_length(length); | 2051 reinterpret_cast<Array*>(result)->set_length(length); |
2045 return result; | 2052 return result; |
2046 } | 2053 } |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 if (map == external_ascii_string_map()) return external_ascii_symbol_map(); | 2636 if (map == external_ascii_string_map()) return external_ascii_symbol_map(); |
2630 | 2637 |
2631 // No match found. | 2638 // No match found. |
2632 return NULL; | 2639 return NULL; |
2633 } | 2640 } |
2634 | 2641 |
2635 | 2642 |
2636 Object* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer, | 2643 Object* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer, |
2637 int chars, | 2644 int chars, |
2638 uint32_t hash_field) { | 2645 uint32_t hash_field) { |
| 2646 ASSERT(chars >= 0); |
2639 // Ensure the chars matches the number of characters in the buffer. | 2647 // Ensure the chars matches the number of characters in the buffer. |
2640 ASSERT(static_cast<unsigned>(chars) == buffer->Length()); | 2648 ASSERT(static_cast<unsigned>(chars) == buffer->Length()); |
2641 // Determine whether the string is ascii. | 2649 // Determine whether the string is ascii. |
2642 bool is_ascii = true; | 2650 bool is_ascii = true; |
2643 while (buffer->has_more() && is_ascii) { | 2651 while (buffer->has_more()) { |
2644 if (buffer->GetNext() > unibrow::Utf8::kMaxOneByteChar) is_ascii = false; | 2652 if (buffer->GetNext() > unibrow::Utf8::kMaxOneByteChar) { |
| 2653 is_ascii = false; |
| 2654 break; |
| 2655 } |
2645 } | 2656 } |
2646 buffer->Rewind(); | 2657 buffer->Rewind(); |
2647 | 2658 |
2648 // Compute map and object size. | 2659 // Compute map and object size. |
2649 int size; | 2660 int size; |
2650 Map* map; | 2661 Map* map; |
2651 | 2662 |
2652 if (is_ascii) { | 2663 if (is_ascii) { |
| 2664 if (chars > SeqAsciiString::kMaxLength) { |
| 2665 return Failure::OutOfMemoryException(); |
| 2666 } |
2653 map = ascii_symbol_map(); | 2667 map = ascii_symbol_map(); |
2654 size = SeqAsciiString::SizeFor(chars); | 2668 size = SeqAsciiString::SizeFor(chars); |
2655 } else { | 2669 } else { |
| 2670 if (chars > SeqTwoByteString::kMaxLength) { |
| 2671 return Failure::OutOfMemoryException(); |
| 2672 } |
2656 map = symbol_map(); | 2673 map = symbol_map(); |
2657 size = SeqTwoByteString::SizeFor(chars); | 2674 size = SeqTwoByteString::SizeFor(chars); |
2658 } | 2675 } |
2659 | 2676 |
2660 // Allocate string. | 2677 // Allocate string. |
2661 Object* result = (size > MaxObjectSizeInPagedSpace()) | 2678 Object* result = (size > MaxObjectSizeInPagedSpace()) |
2662 ? lo_space_->AllocateRaw(size) | 2679 ? lo_space_->AllocateRaw(size) |
2663 : old_data_space_->AllocateRaw(size); | 2680 : old_data_space_->AllocateRaw(size); |
2664 if (result->IsFailure()) return result; | 2681 if (result->IsFailure()) return result; |
2665 | 2682 |
2666 reinterpret_cast<HeapObject*>(result)->set_map(map); | 2683 reinterpret_cast<HeapObject*>(result)->set_map(map); |
2667 // Set length and hash fields of the allocated string. | 2684 // Set length and hash fields of the allocated string. |
2668 String* answer = String::cast(result); | 2685 String* answer = String::cast(result); |
2669 answer->set_length(chars); | 2686 answer->set_length(chars); |
2670 answer->set_hash_field(hash_field); | 2687 answer->set_hash_field(hash_field); |
2671 | 2688 |
2672 ASSERT_EQ(size, answer->Size()); | 2689 ASSERT_EQ(size, answer->Size()); |
2673 | 2690 |
2674 // Fill in the characters. | 2691 // Fill in the characters. |
2675 for (int i = 0; i < chars; i++) { | 2692 for (int i = 0; i < chars; i++) { |
2676 answer->Set(i, buffer->GetNext()); | 2693 answer->Set(i, buffer->GetNext()); |
2677 } | 2694 } |
2678 return answer; | 2695 return answer; |
2679 } | 2696 } |
2680 | 2697 |
2681 | 2698 |
2682 Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { | 2699 Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { |
| 2700 if (length < 0 || length > SeqAsciiString::kMaxLength) { |
| 2701 return Failure::OutOfMemoryException(); |
| 2702 } |
| 2703 |
2683 int size = SeqAsciiString::SizeFor(length); | 2704 int size = SeqAsciiString::SizeFor(length); |
| 2705 ASSERT(size <= SeqAsciiString::kMaxSize); |
| 2706 |
2684 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2707 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
2685 AllocationSpace retry_space = OLD_DATA_SPACE; | 2708 AllocationSpace retry_space = OLD_DATA_SPACE; |
2686 | 2709 |
2687 if (space == NEW_SPACE) { | 2710 if (space == NEW_SPACE) { |
2688 if (size > kMaxObjectSizeInNewSpace) { | 2711 if (size > kMaxObjectSizeInNewSpace) { |
2689 // Allocate in large object space, retry space will be ignored. | 2712 // Allocate in large object space, retry space will be ignored. |
2690 space = LO_SPACE; | 2713 space = LO_SPACE; |
2691 } else if (size > MaxObjectSizeInPagedSpace()) { | 2714 } else if (size > MaxObjectSizeInPagedSpace()) { |
2692 // Allocate in new space, retry in large object space. | 2715 // Allocate in new space, retry in large object space. |
2693 retry_space = LO_SPACE; | 2716 retry_space = LO_SPACE; |
2694 } | 2717 } |
2695 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { | 2718 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { |
2696 space = LO_SPACE; | 2719 space = LO_SPACE; |
2697 } | 2720 } |
2698 Object* result = AllocateRaw(size, space, retry_space); | 2721 Object* result = AllocateRaw(size, space, retry_space); |
2699 if (result->IsFailure()) return result; | 2722 if (result->IsFailure()) return result; |
2700 | 2723 |
2701 // Partially initialize the object. | 2724 // Partially initialize the object. |
2702 HeapObject::cast(result)->set_map(ascii_string_map()); | 2725 HeapObject::cast(result)->set_map(ascii_string_map()); |
2703 String::cast(result)->set_length(length); | 2726 String::cast(result)->set_length(length); |
2704 String::cast(result)->set_hash_field(String::kEmptyHashField); | 2727 String::cast(result)->set_hash_field(String::kEmptyHashField); |
2705 ASSERT_EQ(size, HeapObject::cast(result)->Size()); | 2728 ASSERT_EQ(size, HeapObject::cast(result)->Size()); |
2706 return result; | 2729 return result; |
2707 } | 2730 } |
2708 | 2731 |
2709 | 2732 |
2710 Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) { | 2733 Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) { |
| 2734 if (length < 0 || length > SeqTwoByteString::kMaxLength) { |
| 2735 return Failure::OutOfMemoryException(); |
| 2736 } |
2711 int size = SeqTwoByteString::SizeFor(length); | 2737 int size = SeqTwoByteString::SizeFor(length); |
| 2738 ASSERT(size <= SeqTwoByteString::kMaxSize); |
2712 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2739 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
2713 AllocationSpace retry_space = OLD_DATA_SPACE; | 2740 AllocationSpace retry_space = OLD_DATA_SPACE; |
2714 | 2741 |
2715 if (space == NEW_SPACE) { | 2742 if (space == NEW_SPACE) { |
2716 if (size > kMaxObjectSizeInNewSpace) { | 2743 if (size > kMaxObjectSizeInNewSpace) { |
2717 // Allocate in large object space, retry space will be ignored. | 2744 // Allocate in large object space, retry space will be ignored. |
2718 space = LO_SPACE; | 2745 space = LO_SPACE; |
2719 } else if (size > MaxObjectSizeInPagedSpace()) { | 2746 } else if (size > MaxObjectSizeInPagedSpace()) { |
2720 // Allocate in new space, retry in large object space. | 2747 // Allocate in new space, retry in large object space. |
2721 retry_space = LO_SPACE; | 2748 retry_space = LO_SPACE; |
(...skipping 18 matching lines...) Expand all Loading... |
2740 Object* result = AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); | 2767 Object* result = AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); |
2741 if (result->IsFailure()) return result; | 2768 if (result->IsFailure()) return result; |
2742 // Initialize the object. | 2769 // Initialize the object. |
2743 reinterpret_cast<Array*>(result)->set_map(fixed_array_map()); | 2770 reinterpret_cast<Array*>(result)->set_map(fixed_array_map()); |
2744 reinterpret_cast<Array*>(result)->set_length(0); | 2771 reinterpret_cast<Array*>(result)->set_length(0); |
2745 return result; | 2772 return result; |
2746 } | 2773 } |
2747 | 2774 |
2748 | 2775 |
2749 Object* Heap::AllocateRawFixedArray(int length) { | 2776 Object* Heap::AllocateRawFixedArray(int length) { |
| 2777 if (length < 0 || length > FixedArray::kMaxLength) { |
| 2778 return Failure::OutOfMemoryException(); |
| 2779 } |
2750 // Use the general function if we're forced to always allocate. | 2780 // Use the general function if we're forced to always allocate. |
2751 if (always_allocate()) return AllocateFixedArray(length, TENURED); | 2781 if (always_allocate()) return AllocateFixedArray(length, TENURED); |
2752 // Allocate the raw data for a fixed array. | 2782 // Allocate the raw data for a fixed array. |
2753 int size = FixedArray::SizeFor(length); | 2783 int size = FixedArray::SizeFor(length); |
2754 return size <= kMaxObjectSizeInNewSpace | 2784 return size <= kMaxObjectSizeInNewSpace |
2755 ? new_space_.AllocateRaw(size) | 2785 ? new_space_.AllocateRaw(size) |
2756 : lo_space_->AllocateRawFixedArray(size); | 2786 : lo_space_->AllocateRawFixedArray(size); |
2757 } | 2787 } |
2758 | 2788 |
2759 | 2789 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2791 // Initialize body. | 2821 // Initialize body. |
2792 for (int index = 0; index < length; index++) { | 2822 for (int index = 0; index < length; index++) { |
2793 array->set(index, value, SKIP_WRITE_BARRIER); | 2823 array->set(index, value, SKIP_WRITE_BARRIER); |
2794 } | 2824 } |
2795 } | 2825 } |
2796 return result; | 2826 return result; |
2797 } | 2827 } |
2798 | 2828 |
2799 | 2829 |
2800 Object* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { | 2830 Object* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) { |
| 2831 ASSERT(length >= 0); |
2801 ASSERT(empty_fixed_array()->IsFixedArray()); | 2832 ASSERT(empty_fixed_array()->IsFixedArray()); |
| 2833 if (length < 0 || length > FixedArray::kMaxLength) { |
| 2834 return Failure::OutOfMemoryException(); |
| 2835 } |
2802 if (length == 0) return empty_fixed_array(); | 2836 if (length == 0) return empty_fixed_array(); |
2803 | 2837 |
2804 AllocationSpace space = | 2838 AllocationSpace space = |
2805 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; | 2839 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; |
2806 int size = FixedArray::SizeFor(length); | 2840 int size = FixedArray::SizeFor(length); |
2807 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { | 2841 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { |
2808 // Too big for new space. | 2842 // Too big for new space. |
2809 space = LO_SPACE; | 2843 space = LO_SPACE; |
2810 } else if (space == OLD_POINTER_SPACE && | 2844 } else if (space == OLD_POINTER_SPACE && |
2811 size > MaxObjectSizeInPagedSpace()) { | 2845 size > MaxObjectSizeInPagedSpace()) { |
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4081 void ExternalStringTable::TearDown() { | 4115 void ExternalStringTable::TearDown() { |
4082 new_space_strings_.Free(); | 4116 new_space_strings_.Free(); |
4083 old_space_strings_.Free(); | 4117 old_space_strings_.Free(); |
4084 } | 4118 } |
4085 | 4119 |
4086 | 4120 |
4087 List<Object*> ExternalStringTable::new_space_strings_; | 4121 List<Object*> ExternalStringTable::new_space_strings_; |
4088 List<Object*> ExternalStringTable::old_space_strings_; | 4122 List<Object*> ExternalStringTable::old_space_strings_; |
4089 | 4123 |
4090 } } // namespace v8::internal | 4124 } } // namespace v8::internal |
OLD | NEW |