1/* 2 * Copyright (c) 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20/* 21 WriteBarrier.h 22 Write Barrier for Generational GC 23 Copyright (c) 2004-2011 Apple Inc. All rights reserved. 24 */ 25 26#pragma once 27#ifndef __AUTO_WRITE_BARRIER__ 28#define __AUTO_WRITE_BARRIER__ 29 30#include "Configuration.h" 31#include "Definitions.h" 32#include "Range.h" 33 34 35namespace Auto { 36 37 38 // 39 // Forward declarations 40 // 41 class Zone; 42 43 44 //----- WriteBarrier -----// 45 46 class WriteBarrier : public Range { 47 48 private: 49 50 void *_base; // base address of managed range 51 usword_t _protect; // protected space to base of write barrier 52 53 public: 54 55 // 56 // card values 57 // 58 enum { 59 card_unmarked = 0, 60 card_marked_untouched = 0x1, 61 card_marked = 0x3 62 }; 63 64 65 // 66 // Constructor 67 // 68 // Set up cached allocation of use. 69 // 70 WriteBarrier(void *base, void *address, const usword_t size, const usword_t protect = 0) 71 : Range(address, size), _base(base), _protect(protect) 72 { 73 } 74 75 76 // 77 // bytes_needed 78 // 79 // Returns the number of write barrier bytes needed to represent 'n' actual bytes. 80 // 81 static inline const usword_t bytes_needed(usword_t n) { 82 return partition2(n, write_barrier_quantum_log2); 83 } 84 85 86 // 87 // card_index 88 // 89 // Return the write barrier card index for the specified address. 90 // 91 inline const usword_t card_index(void *address) const { 92 uintptr_t normalized = (uintptr_t)address - (uintptr_t)_base; 93 usword_t i = normalized >> write_barrier_quantum_log2; 94 ASSERTION(_protect <= i); 95 ASSERTION(i < size()); 96 return i; 97 } 98 99 // 100 // contains_card 101 // 102 // Returns true if the specified address is managed by this write-barrier. 103 // 104 inline bool contains_card(void *address) { 105 usword_t i = card_index(address); 106 return (_protect <= i && i < size()); 107 } 108 109 110 // 111 // card_address 112 // 113 // Return the base address of the range managed by the specified card index. 114 // 115 inline void *card_address(usword_t i) const { return displace(_base, i << write_barrier_quantum_log2); } 116 117 118 // 119 // is_card_marked 120 // 121 // Test to see if card i is marked. 122 // 123 inline bool is_card_marked(usword_t i) { return ((unsigned char *)address())[i] != card_unmarked; } 124 125 126 // 127 // mark_card 128 // 129 // Marks the card at index i. 130 // 131 inline void mark_card(usword_t i) { 132 ((unsigned char *)address())[i] = card_marked; 133 } 134 135 // 136 // mark_cards_untouched 137 // 138 // Used by the write-barrier repair algorithm. Transitions all cards that are currently marked from card_marked -> card_marked_untouched. 139 // 140 usword_t mark_cards_untouched(); 141 142 // 143 // clear_untouched_cards 144 // 145 // Used by the write-barrier repair algorithm. Uses compare and swap to effect the transition card_marked_untouched -> card_unmarked. 146 // 147 usword_t clear_untouched_cards(); 148 149 150 // 151 // is_card_marked 152 // 153 // Checks to see if the card corresponding to . 154 // 155 inline bool is_card_marked(void *address) { 156 usword_t i = card_index(address); 157 return is_card_marked(i); 158 } 159 160 161 // 162 // mark_card 163 // 164 // Mark the write barrier card for the specified address. 165 // 166 inline void mark_card(void *address) { 167 const usword_t i = card_index(address); 168 mark_card(i); 169 } 170 171 172 // 173 // mark_cards 174 // 175 // Mark the write barrier cards corresponding to the specified address range. 176 // 177 inline void mark_cards(void *address, const usword_t size) { 178 usword_t i = card_index(address); 179 const usword_t j = card_index(displace(address, size - 1)); 180 for ( ; i <= j; i++) mark_card(i); 181 } 182 183 184 // 185 // scan_marked_ranges 186 // 187 // Scan ranges in block that are marked in the write barrier. 188 // 189#ifdef __BLOCKS__ 190 typedef void (^write_barrier_scanner_t) (const Range&, WriteBarrier*); 191#else 192 class write_barrier_scanner { 193 public: 194 virtual void operator() (const Range &range, WriteBarrier *wb) = 0; 195 }; 196 typedef write_barrier_scanner &write_barrier_scanner_t; 197#endif 198 199 void scan_marked_ranges(void *address, const usword_t size, write_barrier_scanner_t scanner); 200 void scan_marked_ranges(void *address, const usword_t size, void (*scanner) (const Range&, WriteBarrier*, void*), void *arg); 201 202 203 // 204 // range_has_marked_cards 205 // 206 // Returns true if range intersects a range that has cards marked. 207 // 208 bool range_has_marked_cards(void *address, const usword_t size); 209 }; 210 211 212}; 213 214 215#endif // __AUTO_WRITE_BARRIER__ 216 217