blob: cf85d1544808689907c2b9952b70924299e38f2e [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 Rogers1d54e732013-05-02 21:10:01 -070026
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027namespace mirror {
Ian Rogers1d54e732013-05-02 21:10:01 -070028 class Object;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029} // namespace mirror
Ian Rogers1d54e732013-05-02 21:10:01 -070030
31namespace gc {
32
33namespace space {
34 class ContinuousSpace;
35} // namespace space
36
Mathieu Chartier262e5ff2012-06-01 17:35:38 -070037class Heap;
Ian Rogers1d54e732013-05-02 21:10:01 -070038
39namespace accounting {
40
Mathieu Chartierb062fdd2012-07-03 09:51:48 -070041class SpaceBitmap;
Ian Rogers5d76c432011-10-31 21:42:49 -070042
Elliott Hughes2faa5f12012-01-30 14:42:07 -080043// Maintain a card table from the the write barrier. All writes of
44// non-NULL values to heap addresses should go through an entry in
45// WriteBarrier, and from there to here.
Ian Rogers5d76c432011-10-31 21:42:49 -070046class CardTable {
47 public:
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070048 static const size_t kCardShift = 7;
49 static const size_t kCardSize = (1 << kCardShift);
50 static const uint8_t kCardClean = 0x0;
51 static const uint8_t kCardDirty = 0x70;
52
Ian Rogers30fab402012-01-23 15:43:46 -080053 static CardTable* Create(const byte* heap_begin, size_t heap_capacity);
Ian Rogers5d76c432011-10-31 21:42:49 -070054
Ian Rogers30fab402012-01-23 15:43:46 -080055 // Set the card associated with the given address to GC_CARD_DIRTY.
Ian Rogers5d76c432011-10-31 21:42:49 -070056 void MarkCard(const void *addr) {
Elliott Hughes24edeb52012-06-18 15:29:46 -070057 byte* card_addr = CardFromAddr(addr);
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070058 *card_addr = kCardDirty;
Ian Rogers5d76c432011-10-31 21:42:49 -070059 }
60
Ian Rogers30fab402012-01-23 15:43:46 -080061 // Is the object on a dirty card?
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080062 bool IsDirty(const mirror::Object* obj) const {
Mathieu Chartier4da7f2f2012-11-13 12:51:01 -080063 return GetCard(obj) == kCardDirty;
64 }
65
66 // Return the state of the card at an address.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080067 byte GetCard(const mirror::Object* obj) const {
Mathieu Chartier4da7f2f2012-11-13 12:51:01 -080068 return *CardFromAddr(obj);
Ian Rogers5d76c432011-10-31 21:42:49 -070069 }
70
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070071 // Visit and clear cards within memory range, only visits dirty cards.
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070072 template <typename Visitor>
73 void VisitClear(const void* start, const void* end, const Visitor& visitor) {
74 byte* card_start = CardFromAddr(start);
75 byte* card_end = CardFromAddr(end);
Mathieu Chartier7469ebf2012-09-24 16:28:36 -070076 for (byte* it = card_start; it != card_end; ++it) {
77 if (*it == kCardDirty) {
78 *it = kCardClean;
79 visitor(it);
Mathieu Chartierb43b7d42012-06-19 13:15:09 -070080 }
81 }
82 }
83
Ian Rogers30fab402012-01-23 15:43:46 -080084 // Returns a value that when added to a heap address >> GC_CARD_SHIFT will address the appropriate
85 // card table byte. For convenience this value is cached in every Thread
86 byte* GetBiasedBegin() const {
87 return biased_begin_;
jeffhao39da0352011-11-04 14:58:55 -070088 }
89
Mathieu Chartierd22d5482012-11-06 17:14:12 -080090 /*
91 * Visitor is expected to take in a card and return the new value. When a value is modified, the
92 * modify visitor is called.
93 * visitor: The visitor which modifies the cards. Returns the new value for a card given an old
94 * value.
95 * modified: Whenever the visitor modifies a card, this visitor is called on the card. Enables
96 * us to know which cards got cleared.
97 */
98 template <typename Visitor, typename ModifiedVisitor>
99 void ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const Visitor& visitor,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 const ModifiedVisitor& modified);
Mathieu Chartierd22d5482012-11-06 17:14:12 -0800101
102 // For every dirty at least minumum age between begin and end invoke the visitor with the
103 // specified argument.
Mathieu Chartier357e9be2012-08-01 11:00:14 -0700104 template <typename Visitor, typename FingerVisitor>
105 void Scan(SpaceBitmap* bitmap, byte* scan_begin, byte* scan_end,
Mathieu Chartierd22d5482012-11-06 17:14:12 -0800106 const Visitor& visitor, const FingerVisitor& finger_visitor,
107 const byte minimum_age = kCardDirty) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700108 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800109 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers30fab402012-01-23 15:43:46 -0800110
Ian Rogers30fab402012-01-23 15:43:46 -0800111 // Assertion used to check the given address is covered by the card table
112 void CheckAddrIsInCardTable(const byte* addr) const;
113
Mathieu Chartier262e5ff2012-06-01 17:35:38 -0700114 // Resets all of the bytes in the card table to clean.
115 void ClearCardTable();
116
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700117 // Resets all of the bytes in the card table which do not map to the image space.
Ian Rogers1d54e732013-05-02 21:10:01 -0700118 void ClearSpaceCards(space::ContinuousSpace* space);
Ian Rogers5d76c432011-10-31 21:42:49 -0700119
Mathieu Chartierb43b7d42012-06-19 13:15:09 -0700120 // Returns the first address in the heap which maps to this card.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800121 void* AddrFromCard(const byte *card_addr) const;
Ian Rogers5d76c432011-10-31 21:42:49 -0700122
Ian Rogers30fab402012-01-23 15:43:46 -0800123 // Returns the address of the relevant byte in the card table, given an address on the heap.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800124 byte* CardFromAddr(const void *addr) const;
Ian Rogers5d76c432011-10-31 21:42:49 -0700125
Mathieu Chartier7469ebf2012-09-24 16:28:36 -0700126 bool AddrIsInCardTable(const void* addr) const;
127
Mathieu Chartiercc236d72012-07-20 10:29:05 -0700128 private:
129 CardTable(MemMap* begin, byte* biased_begin, size_t offset);
130
Ian Rogers30fab402012-01-23 15:43:46 -0800131 // Returns true iff the card table address is within the bounds of the card table.
Elliott Hughes24edeb52012-06-18 15:29:46 -0700132 bool IsValidCard(const byte* card_addr) const {
Ian Rogers30fab402012-01-23 15:43:46 -0800133 byte* begin = mem_map_->Begin() + offset_;
134 byte* end = mem_map_->End();
Elliott Hughes24edeb52012-06-18 15:29:46 -0700135 return card_addr >= begin && card_addr < end;
Ian Rogers5d76c432011-10-31 21:42:49 -0700136 }
137
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800138 void CheckCardValid(byte* card) const;
Mathieu Chartierd22d5482012-11-06 17:14:12 -0800139
Ian Rogers30fab402012-01-23 15:43:46 -0800140 // Verifies that all gray objects are on a dirty card.
Ian Rogers5d76c432011-10-31 21:42:49 -0700141 void VerifyCardTable();
142
Ian Rogers30fab402012-01-23 15:43:46 -0800143 // Mmapped pages for the card table
Ian Rogers5d76c432011-10-31 21:42:49 -0700144 UniquePtr<MemMap> mem_map_;
Ian Rogers30fab402012-01-23 15:43:46 -0800145 // Value used to compute card table addresses from object addresses, see GetBiasedBegin
146 byte* const biased_begin_;
147 // Card table doesn't begin at the beginning of the mem_map_, instead it is displaced by offset
148 // to allow the byte value of biased_begin_ to equal GC_CARD_DIRTY
149 const size_t offset_;
Ian Rogers5d76c432011-10-31 21:42:49 -0700150};
151
Ian Rogers1d54e732013-05-02 21:10:01 -0700152} // namespace accounting
153} // namespace gc
Ian Rogers5d76c432011-10-31 21:42:49 -0700154} // namespace art
Ian Rogers1d54e732013-05-02 21:10:01 -0700155
Mathieu Chartier858f1c52012-10-17 17:45:55 -0700156#endif // ART_SRC_GC_CARDTABLE_H_