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