| 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 |