immune_spaces.cc revision a6e1c126299586932ecd3c1133a55a6f8e1107fc
1763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier/* 2763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * Copyright (C) 2015 The Android Open Source Project 3763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * 4763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 5763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * you may not use this file except in compliance with the License. 6763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * You may obtain a copy of the License at 7763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * 8763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 9763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * 10763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * Unless required by applicable law or agreed to in writing, software 11763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 12763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * See the License for the specific language governing permissions and 14763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier * limitations under the License. 15763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier */ 16763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 17763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier#include "immune_spaces.h" 18763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 19763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier#include "gc/space/space-inl.h" 20763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier#include "mirror/object.h" 21df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier#include "oat_file.h" 22763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 23763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiernamespace art { 24763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiernamespace gc { 25763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiernamespace collector { 26763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 27763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiervoid ImmuneSpaces::Reset() { 28763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier spaces_.clear(); 29763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier largest_immune_region_.Reset(); 30763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 31763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 32763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiervoid ImmuneSpaces::CreateLargestImmuneRegion() { 33763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t best_begin = 0u; 34763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t best_end = 0u; 35763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t cur_begin = 0u; 36763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t cur_end = 0u; 37763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // TODO: If the last space is an image space, we may include its oat file in the immune region. 38763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // This could potentially hide heap corruption bugs if there is invalid pointers that point into 39763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // the boot oat code 40763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier for (space::ContinuousSpace* space : GetSpaces()) { 41763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t space_begin = reinterpret_cast<uintptr_t>(space->Begin()); 42763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t space_end = reinterpret_cast<uintptr_t>(space->Limit()); 43763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (space->IsImageSpace()) { 44763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // For the boot image, the boot oat file is always directly after. For app images it may not 45763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // be if the app image was mapped at a random address. 46763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space::ImageSpace* image_space = space->AsImageSpace(); 47763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Update the end to include the other non-heap sections. 48763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space_end = RoundUp(reinterpret_cast<uintptr_t>(image_space->GetImageEnd()), kPageSize); 49df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier // For the app image case, GetOatFileBegin is where the oat file was mapped during image 50df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier // creation, the actual oat file could be somewhere else. 51df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier const OatFile* const image_oat_file = image_space->GetOatFile(); 52df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier if (image_oat_file != nullptr) { 53df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier uintptr_t oat_begin = reinterpret_cast<uintptr_t>(image_oat_file->Begin()); 54df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier uintptr_t oat_end = reinterpret_cast<uintptr_t>(image_oat_file->End()); 55df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier if (space_end == oat_begin) { 56df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier DCHECK_GE(oat_end, oat_begin); 57df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier space_end = oat_end; 58df0a8275abadc96a6363b59f31c64981571d6ed9Mathieu Chartier } 59763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 60763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 61763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (cur_begin == 0u) { 62763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_begin = space_begin; 63763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_end = space_end; 64763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } else if (cur_end == space_begin) { 65763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Extend current region. 66763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_end = space_end; 67763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } else { 68763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Reset. 69763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_begin = 0; 70763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_end = 0; 71763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 72763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (cur_end - cur_begin > best_end - best_begin) { 73763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Improvement, update the best range. 74763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier best_begin = cur_begin; 75763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier best_end = cur_end; 76763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 77763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 78763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier largest_immune_region_.SetBegin(reinterpret_cast<mirror::Object*>(best_begin)); 79763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier largest_immune_region_.SetEnd(reinterpret_cast<mirror::Object*>(best_end)); 80a6e1c126299586932ecd3c1133a55a6f8e1107fcMathieu Chartier VLOG(collector) << "Immune region " << largest_immune_region_.Begin() << "-" 81a6e1c126299586932ecd3c1133a55a6f8e1107fcMathieu Chartier << largest_immune_region_.End(); 82763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 83763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 84763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiervoid ImmuneSpaces::AddSpace(space::ContinuousSpace* space) { 85763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier DCHECK(spaces_.find(space) == spaces_.end()) << *space; 86763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Bind live to mark bitmap if necessary. 87763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (space->GetLiveBitmap() != space->GetMarkBitmap()) { 88763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier CHECK(space->IsContinuousMemMapAllocSpace()); 89763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space->AsContinuousMemMapAllocSpace()->BindLiveToMarkBitmap(); 90763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 91763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier spaces_.insert(space); 92763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier CreateLargestImmuneRegion(); 93763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 94763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 95763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartierbool ImmuneSpaces::CompareByBegin::operator()(space::ContinuousSpace* a, space::ContinuousSpace* b) 96763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier const { 97763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return a->Begin() < b->Begin(); 98763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 99763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 100763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartierbool ImmuneSpaces::ContainsSpace(space::ContinuousSpace* space) const { 101763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return spaces_.find(space) != spaces_.end(); 102763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 103763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 104763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} // namespace collector 105763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} // namespace gc 106763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} // namespace art 107