| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 delete virtual_memory_; | 89 delete virtual_memory_; |
| 90 delete[] hash_map_1_; | 90 delete[] hash_map_1_; |
| 91 delete[] hash_map_2_; | 91 delete[] hash_map_2_; |
| 92 delete[] old_start_; | 92 delete[] old_start_; |
| 93 old_start_ = old_top_ = old_limit_ = NULL; | 93 old_start_ = old_top_ = old_limit_ = NULL; |
| 94 start_ = limit_ = NULL; | 94 start_ = limit_ = NULL; |
| 95 Heap::public_set_store_buffer_top(start_); | 95 Heap::public_set_store_buffer_top(start_); |
| 96 } | 96 } |
| 97 | 97 |
| 98 | 98 |
| 99 | |
| 100 #if V8_TARGET_ARCH_X64 | 99 #if V8_TARGET_ARCH_X64 |
| 101 static int CompareAddresses(const void* void_a, const void* void_b) { | 100 static int CompareAddresses(const void* void_a, const void* void_b) { |
| 102 intptr_t a = | 101 intptr_t a = |
| 103 reinterpret_cast<intptr_t>(*reinterpret_cast<const Address*>(void_a)); | 102 reinterpret_cast<intptr_t>(*reinterpret_cast<const Address*>(void_a)); |
| 104 intptr_t b = | 103 intptr_t b = |
| 105 reinterpret_cast<intptr_t>(*reinterpret_cast<const Address*>(void_b)); | 104 reinterpret_cast<intptr_t>(*reinterpret_cast<const Address*>(void_b)); |
| 106 // Unfortunately if int is smaller than intptr_t there is no branch-free | 105 // Unfortunately if int is smaller than intptr_t there is no branch-free |
| 107 // way to return a number with the same sign as the difference between the | 106 // way to return a number with the same sign as the difference between the |
| 108 // pointers. | 107 // pointers. |
| 109 if (a == b) return 0; | 108 if (a == b) return 0; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 qsort(reinterpret_cast<void*>(old_start_), | 153 qsort(reinterpret_cast<void*>(old_start_), |
| 155 old_top_ - old_start_, | 154 old_top_ - old_start_, |
| 156 sizeof(*old_top_), | 155 sizeof(*old_top_), |
| 157 &CompareAddresses); | 156 &CompareAddresses); |
| 158 Uniq(); | 157 Uniq(); |
| 159 | 158 |
| 160 old_buffer_is_sorted_ = true; | 159 old_buffer_is_sorted_ = true; |
| 161 } | 160 } |
| 162 | 161 |
| 163 | 162 |
| 163 void StoreBuffer::PrepareForIteration() { |
| 164 Compact(); |
| 165 if (store_buffer_mode() == kStoreBufferDisabled) { |
| 166 old_top_ = old_start_; |
| 167 return; |
| 168 } |
| 169 ZapHashTables(); |
| 170 } |
| 171 |
| 172 |
| 164 #ifdef DEBUG | 173 #ifdef DEBUG |
| 165 void StoreBuffer::Clean() { | 174 void StoreBuffer::Clean() { |
| 166 if (store_buffer_mode() == kStoreBufferDisabled) { | 175 if (store_buffer_mode() == kStoreBufferDisabled) { |
| 167 old_top_ = old_start_; // Just clear the cache. | 176 old_top_ = old_start_; // Just clear the cache. |
| 168 return; | 177 return; |
| 169 } | 178 } |
| 170 ZapHashTables(); | 179 ZapHashTables(); |
| 171 Uniq(); // Also removes things that no longer point to new space. | 180 Uniq(); // Also removes things that no longer point to new space. |
| 172 CheckForFullBuffer(); | 181 CheckForFullBuffer(); |
| 173 } | 182 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 during_gc_ = false; | 258 during_gc_ = false; |
| 250 if (store_buffer_mode() == kStoreBufferBeingRebuilt) { | 259 if (store_buffer_mode() == kStoreBufferBeingRebuilt) { |
| 251 set_store_buffer_mode(kStoreBufferFunctional); | 260 set_store_buffer_mode(kStoreBufferFunctional); |
| 252 } | 261 } |
| 253 Verify(); | 262 Verify(); |
| 254 } | 263 } |
| 255 | 264 |
| 256 | 265 |
| 257 void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback callback) { | 266 void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback callback) { |
| 258 if (store_buffer_mode() == kStoreBufferFunctional) { | 267 if (store_buffer_mode() == kStoreBufferFunctional) { |
| 259 SortUniq(); | 268 // We do not sort or remove duplicated entries from the store buffer because |
| 269 // we expect that callback will rebuild the store buffer thus removing |
| 270 // all duplicates and pointers to old space. |
| 271 PrepareForIteration(); |
| 260 } | 272 } |
| 261 if (store_buffer_mode() != kStoreBufferFunctional) { | 273 if (store_buffer_mode() != kStoreBufferFunctional) { |
| 262 old_top_ = old_start_; | 274 old_top_ = old_start_; |
| 263 ZapHashTables(); | 275 ZapHashTables(); |
| 264 Heap::public_set_store_buffer_top(start_); | 276 Heap::public_set_store_buffer_top(start_); |
| 265 set_store_buffer_mode(kStoreBufferBeingRebuilt); | 277 set_store_buffer_mode(kStoreBufferBeingRebuilt); |
| 266 Heap::IteratePointers(Heap::old_pointer_space(), | 278 Heap::IteratePointers(Heap::old_pointer_space(), |
| 267 &Heap::IteratePointersToNewSpace, | 279 &Heap::IteratePointersToNewSpace, |
| 268 callback, | 280 callback, |
| 269 Heap::WATERMARK_SHOULD_BE_VALID); | 281 Heap::WATERMARK_SHOULD_BE_VALID); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 280 { | 292 { |
| 281 DontMoveStoreBufferEntriesScope scope; | 293 DontMoveStoreBufferEntriesScope scope; |
| 282 for (Address* current = old_start_; current < limit; current++) { | 294 for (Address* current = old_start_; current < limit; current++) { |
| 283 #ifdef DEBUG | 295 #ifdef DEBUG |
| 284 Address* saved_top = old_top_; | 296 Address* saved_top = old_top_; |
| 285 #endif | 297 #endif |
| 286 Object** cell = reinterpret_cast<Object**>(*current); | 298 Object** cell = reinterpret_cast<Object**>(*current); |
| 287 Object* object = *cell; | 299 Object* object = *cell; |
| 288 // May be invalid if object is not in new space. | 300 // May be invalid if object is not in new space. |
| 289 HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); | 301 HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); |
| 290 if (Heap::InNewSpace(object)) { | 302 if (Heap::InFromSpace(object)) { |
| 291 callback(reinterpret_cast<HeapObject**>(cell), heap_object); | 303 callback(reinterpret_cast<HeapObject**>(cell), heap_object); |
| 292 } | 304 } |
| 293 ASSERT(old_top_ == saved_top + 1 || old_top_ == saved_top); | 305 ASSERT(old_top_ == saved_top + 1 || old_top_ == saved_top); |
| 294 ASSERT((old_top_ == saved_top + 1) == | |
| 295 (Heap::InNewSpace(*cell) && | |
| 296 !Heap::InNewSpace(reinterpret_cast<Address>(cell)) && | |
| 297 Memory::Address_at(heap_object->address()) != NULL)); | |
| 298 } | 306 } |
| 299 } | 307 } |
| 300 } | 308 } |
| 301 } | 309 } |
| 302 | 310 |
| 303 | 311 |
| 304 void StoreBuffer::Compact() { | 312 void StoreBuffer::Compact() { |
| 305 Address* top = reinterpret_cast<Address*>(Heap::store_buffer_top()); | 313 Address* top = reinterpret_cast<Address*>(Heap::store_buffer_top()); |
| 306 | 314 |
| 307 if (top == start_) return; | 315 if (top == start_) return; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 // TODO(gc): Make the disabling of the store buffer dependendent on | 375 // TODO(gc): Make the disabling of the store buffer dependendent on |
| 368 // those two measures failing: | 376 // those two measures failing: |
| 369 // After compression not enough space was freed up in the store buffer. We | 377 // After compression not enough space was freed up in the store buffer. We |
| 370 // might as well stop sorting and trying to eliminate duplicates. | 378 // might as well stop sorting and trying to eliminate duplicates. |
| 371 Counters::store_buffer_overflows.Increment(); | 379 Counters::store_buffer_overflows.Increment(); |
| 372 set_store_buffer_mode(kStoreBufferDisabled); | 380 set_store_buffer_mode(kStoreBufferDisabled); |
| 373 } | 381 } |
| 374 } | 382 } |
| 375 | 383 |
| 376 } } // namespace v8::internal | 384 } } // namespace v8::internal |
| OLD | NEW |