OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2721 space, kAllocationActionAllocate, size); | 2721 space, kAllocationActionAllocate, size); |
2722 | 2722 |
2723 LargeObjectChunk* chunk = reinterpret_cast<LargeObjectChunk*>(mem); | 2723 LargeObjectChunk* chunk = reinterpret_cast<LargeObjectChunk*>(mem); |
2724 chunk->size_ = size; | 2724 chunk->size_ = size; |
2725 chunk->GetPage()->heap_ = isolate->heap(); | 2725 chunk->GetPage()->heap_ = isolate->heap(); |
2726 return chunk; | 2726 return chunk; |
2727 } | 2727 } |
2728 | 2728 |
2729 | 2729 |
2730 void LargeObjectChunk::Free(Executability executable) { | 2730 void LargeObjectChunk::Free(Executability executable) { |
2731 size_t guard_size = (executable == EXECUTABLE) ? Page::kPageSize : 0; | |
2732 ObjectSpace space = | |
2733 (executable == EXECUTABLE) ? kObjectSpaceCodeSpace : kObjectSpaceLoSpace; | |
2734 // Do not access instance fields after FreeRawMemory! | |
2735 Address my_address = address(); | |
2736 size_t my_size = size(); | |
2731 Isolate* isolate = GetPage()->heap_->isolate(); | 2737 Isolate* isolate = GetPage()->heap_->isolate(); |
2732 isolate->memory_allocator()->FreeRawMemory(address(), size(), executable); | 2738 MemoryAllocator* a = isolate->memory_allocator(); |
2739 a->FreeRawMemory(my_address - guard_size, my_size + guard_size, executable); | |
2740 a->PerformAllocationCallback(space, kAllocationActionFree, my_size); | |
2741 LOG(isolate, DeleteEvent("LargeObjectChunk", my_address)); | |
2733 } | 2742 } |
2734 | 2743 |
2735 | 2744 |
2736 int LargeObjectChunk::ChunkSizeFor(int size_in_bytes) { | 2745 int LargeObjectChunk::ChunkSizeFor(int size_in_bytes) { |
2737 int os_alignment = static_cast<int>(OS::AllocateAlignment()); | 2746 int os_alignment = static_cast<int>(OS::AllocateAlignment()); |
2738 if (os_alignment < Page::kPageSize) { | 2747 if (os_alignment < Page::kPageSize) { |
2739 size_in_bytes += (Page::kPageSize - os_alignment); | 2748 size_in_bytes += (Page::kPageSize - os_alignment); |
2740 } | 2749 } |
2741 return size_in_bytes + Page::kObjectStartOffset; | 2750 return size_in_bytes + Page::kObjectStartOffset; |
2742 } | 2751 } |
(...skipping 15 matching lines...) Expand all Loading... | |
2758 page_count_ = 0; | 2767 page_count_ = 0; |
2759 objects_size_ = 0; | 2768 objects_size_ = 0; |
2760 return true; | 2769 return true; |
2761 } | 2770 } |
2762 | 2771 |
2763 | 2772 |
2764 void LargeObjectSpace::TearDown() { | 2773 void LargeObjectSpace::TearDown() { |
2765 while (first_chunk_ != NULL) { | 2774 while (first_chunk_ != NULL) { |
2766 LargeObjectChunk* chunk = first_chunk_; | 2775 LargeObjectChunk* chunk = first_chunk_; |
2767 first_chunk_ = first_chunk_->next(); | 2776 first_chunk_ = first_chunk_->next(); |
2768 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", chunk->address())); | 2777 chunk->Free(chunk->GetPage()->PageExecutability()); |
2769 Executability executable = chunk->GetPage()->PageExecutability(); | |
2770 ObjectSpace space = kObjectSpaceLoSpace; | |
2771 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; | |
2772 size_t size = chunk->size(); | |
2773 size_t guard_size = (executable == EXECUTABLE) ? Page::kPageSize : 0; | |
2774 heap()->isolate()->memory_allocator()->FreeRawMemory( | |
2775 chunk->address() - guard_size, | |
2776 size + guard_size, | |
2777 executable); | |
2778 heap()->isolate()->memory_allocator()->PerformAllocationCallback( | |
2779 space, kAllocationActionFree, size); | |
2780 } | 2778 } |
2781 | 2779 Setup(); |
Vyacheslav Egorov (Chromium)
2011/08/25 15:22:54
Calling Setup from TearDown is very confusing.
| |
2782 size_ = 0; | |
2783 page_count_ = 0; | |
2784 objects_size_ = 0; | |
2785 } | 2780 } |
2786 | 2781 |
2787 | 2782 |
2788 MaybeObject* LargeObjectSpace::AllocateRawInternal(int requested_size, | 2783 MaybeObject* LargeObjectSpace::AllocateRawInternal(int requested_size, |
2789 int object_size, | 2784 int object_size, |
2790 Executability executable) { | 2785 Executability executable) { |
2791 ASSERT(0 < object_size && object_size <= requested_size); | 2786 ASSERT(0 < object_size && object_size <= requested_size); |
2792 | 2787 |
2793 // Check if we want to force a GC before growing the old space further. | 2788 // Check if we want to force a GC before growing the old space further. |
2794 // If so, fail the allocation. | 2789 // If so, fail the allocation. |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2940 LargeObjectChunk* previous = NULL; | 2935 LargeObjectChunk* previous = NULL; |
2941 LargeObjectChunk* current = first_chunk_; | 2936 LargeObjectChunk* current = first_chunk_; |
2942 while (current != NULL) { | 2937 while (current != NULL) { |
2943 HeapObject* object = current->GetObject(); | 2938 HeapObject* object = current->GetObject(); |
2944 if (object->IsMarked()) { | 2939 if (object->IsMarked()) { |
2945 object->ClearMark(); | 2940 object->ClearMark(); |
2946 heap()->mark_compact_collector()->tracer()->decrement_marked_count(); | 2941 heap()->mark_compact_collector()->tracer()->decrement_marked_count(); |
2947 previous = current; | 2942 previous = current; |
2948 current = current->next(); | 2943 current = current->next(); |
2949 } else { | 2944 } else { |
2950 Executability executable = current->GetPage()->PageExecutability(); | |
2951 Address chunk_address = current->address(); | |
2952 size_t chunk_size = current->size(); | |
2953 | |
2954 // Cut the chunk out from the chunk list. | 2945 // Cut the chunk out from the chunk list. |
2946 LargeObjectChunk* current_chunk = current; | |
2955 current = current->next(); | 2947 current = current->next(); |
2956 if (previous == NULL) { | 2948 if (previous == NULL) { |
2957 first_chunk_ = current; | 2949 first_chunk_ = current; |
2958 } else { | 2950 } else { |
2959 previous->set_next(current); | 2951 previous->set_next(current); |
2960 } | 2952 } |
2961 | 2953 |
2962 // Free the chunk. | 2954 // Free the chunk. |
2963 heap()->mark_compact_collector()->ReportDeleteIfNeeded( | 2955 heap()->mark_compact_collector()->ReportDeleteIfNeeded( |
2964 object, heap()->isolate()); | 2956 object, heap()->isolate()); |
2965 LiveObjectList::ProcessNonLive(object); | 2957 LiveObjectList::ProcessNonLive(object); |
2966 | 2958 |
2967 size_ -= static_cast<int>(chunk_size); | 2959 size_ -= static_cast<int>(current_chunk->size()); |
2968 objects_size_ -= object->Size(); | 2960 objects_size_ -= object->Size(); |
2969 page_count_--; | 2961 page_count_--; |
2970 ObjectSpace space = kObjectSpaceLoSpace; | 2962 current_chunk->Free(current_chunk->GetPage()->PageExecutability()); |
2971 size_t guard_size = 0; | |
2972 if (executable == EXECUTABLE) { | |
2973 space = kObjectSpaceCodeSpace; | |
2974 guard_size = Page::kPageSize; | |
2975 } | |
2976 heap()->isolate()->memory_allocator()->FreeRawMemory( | |
2977 chunk_address - guard_size, | |
2978 chunk_size + guard_size, | |
2979 executable); | |
2980 heap()->isolate()->memory_allocator()->PerformAllocationCallback( | |
2981 space, kAllocationActionFree, size_); | |
2982 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", chunk_address)); | |
2983 } | 2963 } |
2984 } | 2964 } |
2985 } | 2965 } |
2986 | 2966 |
2987 | 2967 |
2988 bool LargeObjectSpace::Contains(HeapObject* object) { | 2968 bool LargeObjectSpace::Contains(HeapObject* object) { |
2989 Address address = object->address(); | 2969 Address address = object->address(); |
2990 if (heap()->new_space()->Contains(address)) { | 2970 if (heap()->new_space()->Contains(address)) { |
2991 return false; | 2971 return false; |
2992 } | 2972 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3089 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 3069 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
3090 if (obj->IsCode()) { | 3070 if (obj->IsCode()) { |
3091 Code* code = Code::cast(obj); | 3071 Code* code = Code::cast(obj); |
3092 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 3072 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
3093 } | 3073 } |
3094 } | 3074 } |
3095 } | 3075 } |
3096 #endif // DEBUG | 3076 #endif // DEBUG |
3097 | 3077 |
3098 } } // namespace v8::internal | 3078 } } // namespace v8::internal |
OLD | NEW |