blob: 26da4ca5a9d18793d9c3cd7912e86388e63333f8 [file] [log] [blame]
Mathieu Chartier763a31e2015-11-16 16:05:55 -08001/*
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"
Mathieu Chartier5351da02016-02-17 16:19:53 -080021#include "oat_file.h"
Mathieu Chartier763a31e2015-11-16 16:05:55 -080022
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);
Mathieu Chartier5351da02016-02-17 16:19:53 -080049 // 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 }
Mathieu Chartier763a31e2015-11-16 16:05:55 -080059 }
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));
Mathieu Chartier66a55392016-02-19 10:25:39 -080080 VLOG(collector) << "Immune region " << largest_immune_region_.Begin() << "-"
81 << largest_immune_region_.End();
Mathieu Chartier763a31e2015-11-16 16:05:55 -080082}
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