immune_spaces.cc revision 763a31ed7a2bfad22a9cb07f5301a71c0f97ca49
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" 21763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 22763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiernamespace art { 23763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiernamespace gc { 24763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiernamespace collector { 25763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 26763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiervoid ImmuneSpaces::Reset() { 27763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier spaces_.clear(); 28763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier largest_immune_region_.Reset(); 29763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 30763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 31763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiervoid ImmuneSpaces::CreateLargestImmuneRegion() { 32763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t best_begin = 0u; 33763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t best_end = 0u; 34763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t cur_begin = 0u; 35763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t cur_end = 0u; 36763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // TODO: If the last space is an image space, we may include its oat file in the immune region. 37763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // This could potentially hide heap corruption bugs if there is invalid pointers that point into 38763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // the boot oat code 39763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier for (space::ContinuousSpace* space : GetSpaces()) { 40763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t space_begin = reinterpret_cast<uintptr_t>(space->Begin()); 41763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t space_end = reinterpret_cast<uintptr_t>(space->Limit()); 42763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (space->IsImageSpace()) { 43763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // For the boot image, the boot oat file is always directly after. For app images it may not 44763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // be if the app image was mapped at a random address. 45763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space::ImageSpace* image_space = space->AsImageSpace(); 46763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Update the end to include the other non-heap sections. 47763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space_end = RoundUp(reinterpret_cast<uintptr_t>(image_space->GetImageEnd()), kPageSize); 48763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t oat_begin = reinterpret_cast<uintptr_t>(image_space->GetOatFileBegin()); 49763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uintptr_t oat_end = reinterpret_cast<uintptr_t>(image_space->GetOatFileEnd()); 50763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (space_end == oat_begin) { 51763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier DCHECK_GE(oat_end, oat_begin); 52763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space_end = oat_end; 53763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 54763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 55763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (cur_begin == 0u) { 56763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_begin = space_begin; 57763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_end = space_end; 58763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } else if (cur_end == space_begin) { 59763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Extend current region. 60763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_end = space_end; 61763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } else { 62763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Reset. 63763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_begin = 0; 64763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier cur_end = 0; 65763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 66763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (cur_end - cur_begin > best_end - best_begin) { 67763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Improvement, update the best range. 68763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier best_begin = cur_begin; 69763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier best_end = cur_end; 70763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 71763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 72763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier largest_immune_region_.SetBegin(reinterpret_cast<mirror::Object*>(best_begin)); 73763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier largest_immune_region_.SetEnd(reinterpret_cast<mirror::Object*>(best_end)); 74763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 75763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 76763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartiervoid ImmuneSpaces::AddSpace(space::ContinuousSpace* space) { 77763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier DCHECK(spaces_.find(space) == spaces_.end()) << *space; 78763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Bind live to mark bitmap if necessary. 79763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier if (space->GetLiveBitmap() != space->GetMarkBitmap()) { 80763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier CHECK(space->IsContinuousMemMapAllocSpace()); 81763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier space->AsContinuousMemMapAllocSpace()->BindLiveToMarkBitmap(); 82763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 83763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier spaces_.insert(space); 84763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier CreateLargestImmuneRegion(); 85763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 86763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 87763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartierbool ImmuneSpaces::CompareByBegin::operator()(space::ContinuousSpace* a, space::ContinuousSpace* b) 88763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier const { 89763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return a->Begin() < b->Begin(); 90763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 91763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 92763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartierbool ImmuneSpaces::ContainsSpace(space::ContinuousSpace* space) const { 93763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return spaces_.find(space) != spaces_.end(); 94763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} 95763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 96763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} // namespace collector 97763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} // namespace gc 98763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier} // namespace art 99