immune_spaces.cc revision 07dbbca0b42cb8da1811de8209b4a7d4becfc7b2
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "immune_spaces.h" 18 19#include "gc/space/space-inl.h" 20#include "mirror/object.h" 21#include "oat_file.h" 22 23namespace art { 24namespace gc { 25namespace collector { 26 27void ImmuneSpaces::Reset() { 28 spaces_.clear(); 29 largest_immune_region_.Reset(); 30} 31 32void ImmuneSpaces::CreateLargestImmuneRegion() { 33 uintptr_t best_begin = 0u; 34 uintptr_t best_end = 0u; 35 uintptr_t cur_begin = 0u; 36 uintptr_t cur_end = 0u; 37 // TODO: If the last space is an image space, we may include its oat file in the immune region. 38 // This could potentially hide heap corruption bugs if there is invalid pointers that point into 39 // the boot oat code 40 for (space::ContinuousSpace* space : GetSpaces()) { 41 uintptr_t space_begin = reinterpret_cast<uintptr_t>(space->Begin()); 42 uintptr_t space_end = reinterpret_cast<uintptr_t>(space->Limit()); 43 if (space->IsImageSpace()) { 44 // For the boot image, the boot oat file is always directly after. For app images it may not 45 // be if the app image was mapped at a random address. 46 space::ImageSpace* image_space = space->AsImageSpace(); 47 // Update the end to include the other non-heap sections. 48 space_end = RoundUp(reinterpret_cast<uintptr_t>(image_space->GetImageEnd()), kPageSize); 49 // For the app image case, GetOatFileBegin is where the oat file was mapped during image 50 // creation, the actual oat file could be somewhere else. 51 const OatFile* const image_oat_file = image_space->GetOatFile(); 52 if (image_oat_file != nullptr) { 53 uintptr_t oat_begin = reinterpret_cast<uintptr_t>(image_oat_file->Begin()); 54 uintptr_t oat_end = reinterpret_cast<uintptr_t>(image_oat_file->End()); 55 if (space_end == oat_begin) { 56 DCHECK_GE(oat_end, oat_begin); 57 space_end = oat_end; 58 } 59 } 60 } 61 if (cur_begin == 0u) { 62 cur_begin = space_begin; 63 cur_end = space_end; 64 } else if (cur_end == space_begin) { 65 // Extend current region. 66 cur_end = space_end; 67 } else { 68 // Reset. 69 cur_begin = 0; 70 cur_end = 0; 71 } 72 if (cur_end - cur_begin > best_end - best_begin) { 73 // Improvement, update the best range. 74 best_begin = cur_begin; 75 best_end = cur_end; 76 } 77 } 78 largest_immune_region_.SetBegin(reinterpret_cast<mirror::Object*>(best_begin)); 79 largest_immune_region_.SetEnd(reinterpret_cast<mirror::Object*>(best_end)); 80 VLOG(collector) << "Immune region " << largest_immune_region_.Begin() << "-" 81 << largest_immune_region_.End(); 82} 83 84void ImmuneSpaces::AddSpace(space::ContinuousSpace* space) { 85 DCHECK(spaces_.find(space) == spaces_.end()) << *space; 86 // Bind live to mark bitmap if necessary. 87 if (space->GetLiveBitmap() != space->GetMarkBitmap()) { 88 CHECK(space->IsContinuousMemMapAllocSpace()); 89 space->AsContinuousMemMapAllocSpace()->BindLiveToMarkBitmap(); 90 } 91 spaces_.insert(space); 92 CreateLargestImmuneRegion(); 93} 94 95bool ImmuneSpaces::CompareByBegin::operator()(space::ContinuousSpace* a, space::ContinuousSpace* b) 96 const { 97 return a->Begin() < b->Begin(); 98} 99 100bool ImmuneSpaces::ContainsSpace(space::ContinuousSpace* space) const { 101 return spaces_.find(space) != spaces_.end(); 102} 103 104} // namespace collector 105} // namespace gc 106} // namespace art 107