1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "bitmap-inl.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <sys/mman.h> // For the PROT_* and MAP_* constants.
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/mem_map.h"
23*795d594fSAndroid Build Coastguard Worker #include "card_table.h"
24*795d594fSAndroid Build Coastguard Worker #include "gc/collector/mark_compact.h"
25*795d594fSAndroid Build Coastguard Worker #include "jit/jit_memory_region.h"
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
28*795d594fSAndroid Build Coastguard Worker namespace gc {
29*795d594fSAndroid Build Coastguard Worker namespace accounting {
30*795d594fSAndroid Build Coastguard Worker
CreateFromMemMap(MemMap && mem_map,size_t num_bits)31*795d594fSAndroid Build Coastguard Worker Bitmap* Bitmap::CreateFromMemMap(MemMap&& mem_map, size_t num_bits) {
32*795d594fSAndroid Build Coastguard Worker CHECK(mem_map.IsValid());
33*795d594fSAndroid Build Coastguard Worker return new Bitmap(std::move(mem_map), num_bits);
34*795d594fSAndroid Build Coastguard Worker }
35*795d594fSAndroid Build Coastguard Worker
Bitmap(MemMap && mem_map,size_t num_bits)36*795d594fSAndroid Build Coastguard Worker Bitmap::Bitmap(MemMap&& mem_map, size_t num_bits)
37*795d594fSAndroid Build Coastguard Worker : mem_map_(std::move(mem_map)),
38*795d594fSAndroid Build Coastguard Worker bitmap_begin_(reinterpret_cast<uintptr_t*>(mem_map_.Begin())),
39*795d594fSAndroid Build Coastguard Worker bitmap_numbits_(num_bits) {
40*795d594fSAndroid Build Coastguard Worker CHECK(bitmap_begin_ != nullptr);
41*795d594fSAndroid Build Coastguard Worker CHECK_NE(num_bits, 0U);
42*795d594fSAndroid Build Coastguard Worker }
43*795d594fSAndroid Build Coastguard Worker
~Bitmap()44*795d594fSAndroid Build Coastguard Worker Bitmap::~Bitmap() {
45*795d594fSAndroid Build Coastguard Worker // Destroys member MemMap.
46*795d594fSAndroid Build Coastguard Worker }
47*795d594fSAndroid Build Coastguard Worker
AllocateMemMap(const std::string & name,size_t num_bits)48*795d594fSAndroid Build Coastguard Worker MemMap Bitmap::AllocateMemMap(const std::string& name, size_t num_bits) {
49*795d594fSAndroid Build Coastguard Worker const size_t bitmap_size = RoundUp(
50*795d594fSAndroid Build Coastguard Worker RoundUp(num_bits, kBitsPerBitmapWord) / kBitsPerBitmapWord * sizeof(uintptr_t), gPageSize);
51*795d594fSAndroid Build Coastguard Worker std::string error_msg;
52*795d594fSAndroid Build Coastguard Worker MemMap mem_map = MemMap::MapAnonymous(name.c_str(),
53*795d594fSAndroid Build Coastguard Worker bitmap_size,
54*795d594fSAndroid Build Coastguard Worker PROT_READ | PROT_WRITE,
55*795d594fSAndroid Build Coastguard Worker /*low_4gb=*/ false,
56*795d594fSAndroid Build Coastguard Worker &error_msg);
57*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!mem_map.IsValid())) {
58*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Failed to allocate bitmap " << name << ": " << error_msg;
59*795d594fSAndroid Build Coastguard Worker }
60*795d594fSAndroid Build Coastguard Worker return mem_map;
61*795d594fSAndroid Build Coastguard Worker }
62*795d594fSAndroid Build Coastguard Worker
Create(const std::string & name,size_t num_bits)63*795d594fSAndroid Build Coastguard Worker Bitmap* Bitmap::Create(const std::string& name, size_t num_bits) {
64*795d594fSAndroid Build Coastguard Worker MemMap mem_map = AllocateMemMap(name, num_bits);
65*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!mem_map.IsValid())) {
66*795d594fSAndroid Build Coastguard Worker return nullptr;
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker return CreateFromMemMap(std::move(mem_map), num_bits);
69*795d594fSAndroid Build Coastguard Worker }
70*795d594fSAndroid Build Coastguard Worker
Clear()71*795d594fSAndroid Build Coastguard Worker void Bitmap::Clear() {
72*795d594fSAndroid Build Coastguard Worker if (bitmap_begin_ != nullptr) {
73*795d594fSAndroid Build Coastguard Worker mem_map_.MadviseDontNeedAndZero();
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker
CopyFrom(Bitmap * source_bitmap)77*795d594fSAndroid Build Coastguard Worker void Bitmap::CopyFrom(Bitmap* source_bitmap) {
78*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(BitmapSize(), source_bitmap->BitmapSize());
79*795d594fSAndroid Build Coastguard Worker std::copy(source_bitmap->Begin(),
80*795d594fSAndroid Build Coastguard Worker source_bitmap->Begin() + BitmapSize() / kBitsPerBitmapWord, Begin());
81*795d594fSAndroid Build Coastguard Worker }
82*795d594fSAndroid Build Coastguard Worker
83*795d594fSAndroid Build Coastguard Worker template<size_t kAlignment>
Create(const std::string & name,uintptr_t cover_begin,uintptr_t cover_end)84*795d594fSAndroid Build Coastguard Worker MemoryRangeBitmap<kAlignment>* MemoryRangeBitmap<kAlignment>::Create(
85*795d594fSAndroid Build Coastguard Worker const std::string& name, uintptr_t cover_begin, uintptr_t cover_end) {
86*795d594fSAndroid Build Coastguard Worker CHECK_ALIGNED(cover_begin, kAlignment);
87*795d594fSAndroid Build Coastguard Worker CHECK_ALIGNED(cover_end, kAlignment);
88*795d594fSAndroid Build Coastguard Worker const size_t num_bits = (cover_end - cover_begin) / kAlignment;
89*795d594fSAndroid Build Coastguard Worker MemMap mem_map = Bitmap::AllocateMemMap(name, num_bits);
90*795d594fSAndroid Build Coastguard Worker CHECK(mem_map.IsValid());
91*795d594fSAndroid Build Coastguard Worker return CreateFromMemMap(std::move(mem_map), cover_begin, num_bits);
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker
94*795d594fSAndroid Build Coastguard Worker template<size_t kAlignment>
CreateFromMemMap(MemMap && mem_map,uintptr_t begin,size_t num_bits)95*795d594fSAndroid Build Coastguard Worker MemoryRangeBitmap<kAlignment>* MemoryRangeBitmap<kAlignment>::CreateFromMemMap(
96*795d594fSAndroid Build Coastguard Worker MemMap&& mem_map, uintptr_t begin, size_t num_bits) {
97*795d594fSAndroid Build Coastguard Worker return new MemoryRangeBitmap(std::move(mem_map), begin, num_bits);
98*795d594fSAndroid Build Coastguard Worker }
99*795d594fSAndroid Build Coastguard Worker
100*795d594fSAndroid Build Coastguard Worker template class MemoryRangeBitmap<CardTable::kCardSize>;
101*795d594fSAndroid Build Coastguard Worker template class MemoryRangeBitmap<jit::kJitCodeAccountingBytes>;
102*795d594fSAndroid Build Coastguard Worker template class MemoryRangeBitmap<collector::MarkCompact::kAlignment>;
103*795d594fSAndroid Build Coastguard Worker
104*795d594fSAndroid Build Coastguard Worker } // namespace accounting
105*795d594fSAndroid Build Coastguard Worker } // namespace gc
106*795d594fSAndroid Build Coastguard Worker } // namespace art
107*795d594fSAndroid Build Coastguard Worker
108