immune_spaces.cc revision 66a55394b0489b30576f90499f24b792a400a2d2
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