blob: 842fcc3aa286286834e25f3823ccf5e71e3a5511 [file] [log] [blame]
Ian Rogers5d76c432011-10-31 21:42:49 -07001/*
Elliott Hughes2faa5f12012-01-30 14:42:07 -08002 * Copyright (C) 2011 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.
Ian Rogers5d76c432011-10-31 21:42:49 -070015 */
16
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070017#ifndef ART_SRC_GC_CARDTABLE_H_
18#define ART_SRC_GC_CARDTABLE_H_
Ian Rogers5d76c432011-10-31 21:42:49 -070019
20#include "globals.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080021#include "locks.h"
Ian Rogers5d76c432011-10-31 21:42:49 -070022#include "mem_map.h"
23#include "UniquePtr.h"
24
25namespace art {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080026namespace mirror {
27class Object;
28} // namespace mirror
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070029class Heap;
Mathieu Chartier2fde5332012-09-14 14:51:54 -070030class ContinuousSpace;
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070031class SpaceBitmap;
Ian Rogers5d76c432011-10-31 21:42:49 -070032
Elliott Hughes2faa5f12012-01-30 14:42:07 -080033// Maintain a card table from the the write barrier. All writes of
34// non-NULL values to heap addresses should go through an entry in
35// WriteBarrier, and from there to here.
Ian Rogers5d76c432011-10-31 21:42:49 -070036class CardTable {
37 public:
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070038 static const size_t kCardShift = 7;
39 static const size_t kCardSize = (1 << kCardShift);
40 static const uint8_t kCardClean = 0x0;
41 static const uint8_t kCardDirty = 0x70;
42
Ian Rogers30fab402012-01-23 15:43:46 -080043 static CardTable* Create(const byte* heap_begin, size_t heap_capacity);
Ian Rogers5d76c432011-10-31 21:42:49 -070044
Ian Rogers30fab402012-01-23 15:43:46 -080045 // Set the card associated with the given address to GC_CARD_DIRTY.
Ian Rogers5d76c432011-10-31 21:42:49 -070046 void MarkCard(const void *addr) {
Elliott Hughes24edeb52012-06-18 15:29:46 -070047 byte* card_addr = CardFromAddr(addr);
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070048 *card_addr = kCardDirty;
Ian Rogers5d76c432011-10-31 21:42:49 -070049 }
50
Ian Rogers30fab402012-01-23 15:43:46 -080051 // Is the object on a dirty card?
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052 bool IsDirty(const mirror::Object* obj) const {
Mathieu Chartier4da7f2f2012-11-13 12:51:01 -080053 return GetCard(obj) == kCardDirty;
54 }
55
56 // Return the state of the card at an address.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080057 byte GetCard(const mirror::Object* obj) const {
Mathieu Chartier4da7f2f2012-11-13 12:51:01 -080058 return *CardFromAddr(obj);
Ian Rogers5d76c432011-10-31 21:42:49 -070059 }
60
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070061 // Visit and clear cards within memory range, only visits dirty cards.
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070062 template <typename Visitor>
63 void VisitClear(const void* start, const void* end, const Visitor& visitor) {
64 byte* card_start = CardFromAddr(start);
65 byte* card_end = CardFromAddr(end);
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070066 for (byte* it = card_start; it != card_end; ++it) {
67 if (*it == kCardDirty) {
68 *it = kCardClean;
69 visitor(it);
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070070 }
71 }
72 }
73
Ian Rogers30fab402012-01-23 15:43:46 -080074 // Returns a value that when added to a heap address >> GC_CARD_SHIFT will address the appropriate
75 // card table byte. For convenience this value is cached in every Thread
76 byte* GetBiasedBegin() const {
77 return biased_begin_;
jeffhao39da0352011-11-04 14:58:55 -070078 }
79
Mathieu Chartierd22d5482012-11-06 17:14:12 -080080 /*
81 * Visitor is expected to take in a card and return the new value. When a value is modified, the
82 * modify visitor is called.
83 * visitor: The visitor which modifies the cards. Returns the new value for a card given an old
84 * value.
85 * modified: Whenever the visitor modifies a card, this visitor is called on the card. Enables
86 * us to know which cards got cleared.
87 */
88 template <typename Visitor, typename ModifiedVisitor>
89 void ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const Visitor& visitor,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080090 const ModifiedVisitor& modified);
Mathieu Chartierd22d5482012-11-06 17:14:12 -080091
92 // For every dirty at least minumum age between begin and end invoke the visitor with the
93 // specified argument.
Mathieu Chartier357e9be2012-08-01 11:00:14 -070094 template <typename Visitor, typename FingerVisitor>
95 void Scan(SpaceBitmap* bitmap, byte* scan_begin, byte* scan_end,
Mathieu Chartierd22d5482012-11-06 17:14:12 -080096 const Visitor& visitor, const FingerVisitor& finger_visitor,
97 const byte minimum_age = kCardDirty) const
Ian Rogersb726dcb2012-09-05 08:57:23 -070098 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080099 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers30fab402012-01-23 15:43:46 -0800100
Ian Rogers30fab402012-01-23 15:43:46 -0800101 // Assertion used to check the given address is covered by the card table
102 void CheckAddrIsInCardTable(const byte* addr) const;
103
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700104 // Resets all of the bytes in the card table to clean.
105 void ClearCardTable();
106
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700107 // Resets all of the bytes in the card table which do not map to the image space.
Mathieu Chartier2fde5332012-09-14 14:51:54 -0700108 void ClearSpaceCards(ContinuousSpace* space);
Ian Rogers5d76c432011-10-31 21:42:49 -0700109
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700110 // Returns the first address in the heap which maps to this card.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800111 void* AddrFromCard(const byte *card_addr) const;
Ian Rogers5d76c432011-10-31 21:42:49 -0700112
Ian Rogers30fab402012-01-23 15:43:46 -0800113 // Returns the address of the relevant byte in the card table, given an address on the heap.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800114 byte* CardFromAddr(const void *addr) const;
Ian Rogers5d76c432011-10-31 21:42:49 -0700115
Mathieu Chartier7469ebf2012-09-24 16:28:36 -0700116 bool AddrIsInCardTable(const void* addr) const;
117
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700118 private:
119 CardTable(MemMap* begin, byte* biased_begin, size_t offset);
120
Ian Rogers30fab402012-01-23 15:43:46 -0800121 // Returns true iff the card table address is within the bounds of the card table.
Elliott Hughes24edeb52012-06-18 15:29:46 -0700122 bool IsValidCard(const byte* card_addr) const {
Ian Rogers30fab402012-01-23 15:43:46 -0800123 byte* begin = mem_map_->Begin() + offset_;
124 byte* end = mem_map_->End();
Elliott Hughes24edeb52012-06-18 15:29:46 -0700125 return card_addr >= begin && card_addr < end;
Ian Rogers5d76c432011-10-31 21:42:49 -0700126 }
127
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128 void CheckCardValid(byte* card) const;
Mathieu Chartierd22d5482012-11-06 17:14:12 -0800129
Ian Rogers30fab402012-01-23 15:43:46 -0800130 // Verifies that all gray objects are on a dirty card.
Ian Rogers5d76c432011-10-31 21:42:49 -0700131 void VerifyCardTable();
132
Ian Rogers30fab402012-01-23 15:43:46 -0800133 // Mmapped pages for the card table
Ian Rogers5d76c432011-10-31 21:42:49 -0700134 UniquePtr<MemMap> mem_map_;
Ian Rogers30fab402012-01-23 15:43:46 -0800135 // Value used to compute card table addresses from object addresses, see GetBiasedBegin
136 byte* const biased_begin_;
137 // Card table doesn't begin at the beginning of the mem_map_, instead it is displaced by offset
138 // to allow the byte value of biased_begin_ to equal GC_CARD_DIRTY
139 const size_t offset_;
Ian Rogers5d76c432011-10-31 21:42:49 -0700140};
141
142} // namespace art
Mathieu Chartier858f1c52012-10-17 17:45:55 -0700143#endif // ART_SRC_GC_CARDTABLE_H_