1c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Copyright 2011 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/store-buffer.h" 6ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 7ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#include <algorithm> 8ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 101e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org 111e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/atomicops.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/counters.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/store-buffer-inl.h" 14c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 15c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comnamespace v8 { 16c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comnamespace internal { 17c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 18c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comStoreBuffer::StoreBuffer(Heap* heap) 19c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : heap_(heap), 20c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com start_(NULL), 21c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com limit_(NULL), 22c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_start_(NULL), 23c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_limit_(NULL), 24c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_top_(NULL), 2564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_reserved_limit_(NULL), 26c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_sorted_(false), 27c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_filtered_(false), 28c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com during_gc_(false), 29c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com store_buffer_rebuilding_enabled_(false), 30c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com callback_(NULL), 31c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com may_move_store_buffer_entries_(true), 32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual_memory_(NULL), 33b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_1_(NULL), 34b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_2_(NULL), 35b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_sets_are_empty_(true) { 36c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 37c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 38c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 39f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid StoreBuffer::SetUp() { 40c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual_memory_ = new VirtualMemory(kStoreBufferSize * 3); 41c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uintptr_t start_as_int = 42c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<uintptr_t>(virtual_memory_->address()); 43c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com start_ = 44c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize * 2)); 4564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org limit_ = start_ + (kStoreBufferSize / kPointerSize); 4664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 4764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_virtual_memory_ = 4864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org new VirtualMemory(kOldStoreBufferLength * kPointerSize); 4964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_top_ = old_start_ = 5064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org reinterpret_cast<Address*>(old_virtual_memory_->address()); 5164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Don't know the alignment requirements of the OS, but it is certainly not 5264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // less than 0xfff. 5364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT((reinterpret_cast<uintptr_t>(old_start_) & 0xfff) == 0); 5464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org int initial_length = static_cast<int>(OS::CommitPageSize() / kPointerSize); 5564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(initial_length > 0); 5664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(initial_length <= kOldStoreBufferLength); 5764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_limit_ = old_start_ + initial_length; 5864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_reserved_limit_ = old_start_ + kOldStoreBufferLength; 5964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 6064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org CHECK(old_virtual_memory_->Commit( 6164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org reinterpret_cast<void*>(old_start_), 6264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org (old_limit_ - old_start_) * kPointerSize, 6364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org false)); 64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(reinterpret_cast<Address>(start_) >= virtual_memory_->address()); 66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(reinterpret_cast<Address>(limit_) >= virtual_memory_->address()); 67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* vm_limit = reinterpret_cast<Address*>( 68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<char*>(virtual_memory_->address()) + 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual_memory_->size()); 70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(start_ <= vm_limit); 71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(limit_ <= vm_limit); 72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(vm_limit); 73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((reinterpret_cast<uintptr_t>(limit_) & kStoreBufferOverflowBit) != 0); 74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((reinterpret_cast<uintptr_t>(limit_ - 1) & kStoreBufferOverflowBit) == 75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 0); 76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 7764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org CHECK(virtual_memory_->Commit(reinterpret_cast<Address>(start_), 7864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org kStoreBufferSize, 7964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org false)); // Not executable. 80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->public_set_store_buffer_top(start_); 81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 82b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_1_ = new uintptr_t[kHashSetLength]; 83b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_2_ = new uintptr_t[kHashSetLength]; 84b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_sets_are_empty_ = false; 85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 86b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org ClearFilteringHashSets(); 87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 88c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 89c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 90c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::TearDown() { 91c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com delete virtual_memory_; 9264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org delete old_virtual_memory_; 93b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org delete[] hash_set_1_; 94b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org delete[] hash_set_2_; 9564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_start_ = old_top_ = old_limit_ = old_reserved_limit_ = NULL; 96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com start_ = limit_ = NULL; 97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->public_set_store_buffer_top(start_); 98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::StoreBufferOverflow(Isolate* isolate) { 102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate->heap()->store_buffer()->Compact(); 1031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org isolate->counters()->store_buffer_overflows()->Increment(); 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::Uniq() { 108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Remove adjacent duplicates and cells that do not point at new space. 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address previous = NULL; 110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* write = old_start_; 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(may_move_store_buffer_entries_); 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* read = old_start_; read < old_top_; read++) { 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address current = *read; 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (current != previous) { 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (heap_->InNewSpace(*reinterpret_cast<Object**>(current))) { 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *write++ = current; 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com previous = current; 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_top_ = write; 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 12541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgbool StoreBuffer::SpaceAvailable(intptr_t space_needed) { 12641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return old_limit_ - old_top_ >= space_needed; 12741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org} 12841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 12941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 13064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid StoreBuffer::EnsureSpace(intptr_t space_needed) { 13164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org while (old_limit_ - old_top_ < space_needed && 13264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_limit_ < old_reserved_limit_) { 13364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org size_t grow = old_limit_ - old_start_; // Double size. 13464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_), 13564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org grow * kPointerSize, 13664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org false)); 13764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org old_limit_ += grow; 13864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 13964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 14041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (SpaceAvailable(space_needed)) return; 14164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (old_buffer_is_filtered_) return; 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(may_move_store_buffer_entries_); 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Compact(); 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_filtered_ = true; 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool page_has_scan_on_scavenge_flag = false; 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointerChunkIterator it(heap_); 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* chunk; 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while ((chunk = it.next()) != NULL) { 152639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (chunk->scan_on_scavenge()) { 153639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org page_has_scan_on_scavenge_flag = true; 154639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org break; 155639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (page_has_scan_on_scavenge_flag) { 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Filter(MemoryChunk::SCAN_ON_SCAVENGE); 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 16241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (SpaceAvailable(space_needed)) return; 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sample 1 entry in 97 and filter out the pages where we estimate that more 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // than 1 in 8 pointers are to new space. 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kSampleFinenesses = 5; 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const struct Samples { 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int prime_sample_step; 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int threshold; 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } samples[kSampleFinenesses] = { 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 97, ((Page::kPageSize / kPointerSize) / 97) / 8 }, 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 23, ((Page::kPageSize / kPointerSize) / 23) / 16 }, 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 7, ((Page::kPageSize / kPointerSize) / 7) / 32 }, 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 3, ((Page::kPageSize / kPointerSize) / 3) / 256 }, 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1, 0} 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 1778a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org for (int i = 0; i < kSampleFinenesses; i++) { 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExemptPopularPages(samples[i].prime_sample_step, samples[i].threshold); 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // As a last resort we mark all pages as being exempt from the store buffer. 1808a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org ASSERT(i != (kSampleFinenesses - 1) || old_top_ == old_start_); 18141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (SpaceAvailable(space_needed)) return; 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Sample the store buffer to see if some pages are taking up a lot of space 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// in the store buffer. 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::ExemptPopularPages(int prime_sample_step, int threshold) { 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointerChunkIterator it(heap_); 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* chunk; 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while ((chunk = it.next()) != NULL) { 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com chunk->set_store_buffer_counter(0); 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool created_new_scan_on_scavenge_pages = false; 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* previous_chunk = NULL; 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* p = old_start_; p < old_top_; p += prime_sample_step) { 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address addr = *p; 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* containing_chunk = NULL; 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (previous_chunk != NULL && previous_chunk->Contains(addr)) { 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com containing_chunk = previous_chunk; 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 203c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org containing_chunk = MemoryChunk::FromAnyPointerAddress(heap_, addr); 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int old_counter = containing_chunk->store_buffer_counter(); 2069cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if (old_counter >= threshold) { 207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com containing_chunk->set_scan_on_scavenge(true); 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com created_new_scan_on_scavenge_pages = true; 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com containing_chunk->set_store_buffer_counter(old_counter + 1); 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com previous_chunk = containing_chunk; 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (created_new_scan_on_scavenge_pages) { 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Filter(MemoryChunk::SCAN_ON_SCAVENGE); 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_filtered_ = true; 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::Filter(int flag) { 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* new_top = old_start_; 222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* previous_chunk = NULL; 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* p = old_start_; p < old_top_; p++) { 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address addr = *p; 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* containing_chunk = NULL; 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (previous_chunk != NULL && previous_chunk->Contains(addr)) { 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com containing_chunk = previous_chunk; 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 229c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org containing_chunk = MemoryChunk::FromAnyPointerAddress(heap_, addr); 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com previous_chunk = containing_chunk; 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!containing_chunk->IsFlagSet(flag)) { 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *new_top++ = addr; 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_top_ = new_top; 237b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org 238b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // Filtering hash sets are inconsistent with the store buffer after this 239b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // operation. 240b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org ClearFilteringHashSets(); 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::SortUniq() { 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Compact(); 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (old_buffer_is_sorted_) return; 247ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org std::sort(old_start_, old_top_); 248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Uniq(); 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_sorted_ = true; 251b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org 252b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // Filtering hash sets are inconsistent with the store buffer after this 253b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // operation. 254b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org ClearFilteringHashSets(); 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool StoreBuffer::PrepareForIteration() { 259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Compact(); 260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointerChunkIterator it(heap_); 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* chunk; 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool page_has_scan_on_scavenge_flag = false; 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while ((chunk = it.next()) != NULL) { 264639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (chunk->scan_on_scavenge()) { 265639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org page_has_scan_on_scavenge_flag = true; 266639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org break; 267639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (page_has_scan_on_scavenge_flag) { 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Filter(MemoryChunk::SCAN_ON_SCAVENGE); 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 273b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org 274b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // Filtering hash sets are inconsistent with the store buffer after 275b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // iteration. 276b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org ClearFilteringHashSets(); 277b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return page_has_scan_on_scavenge_flag; 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::Clean() { 284b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org ClearFilteringHashSets(); 285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Uniq(); // Also removes things that no longer point to new space. 28641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org EnsureSpace(kStoreBufferSize / 2); 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic Address* in_store_buffer_1_element_cache = NULL; 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool StoreBuffer::CellIsInStoreBuffer(Address cell_address) { 294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!FLAG_enable_slow_asserts) return true; 295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (in_store_buffer_1_element_cache != NULL && 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *in_store_buffer_1_element_cache == cell_address) { 297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top()); 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* current = top - 1; current >= start_; current--) { 301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (*current == cell_address) { 302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com in_store_buffer_1_element_cache = current; 303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* current = old_top_ - 1; current >= old_start_; current--) { 307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (*current == cell_address) { 308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com in_store_buffer_1_element_cache = current; 309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 317b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.orgvoid StoreBuffer::ClearFilteringHashSets() { 318b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org if (!hash_sets_are_empty_) { 319b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org memset(reinterpret_cast<void*>(hash_set_1_), 320b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org 0, 321b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org sizeof(uintptr_t) * kHashSetLength); 322b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org memset(reinterpret_cast<void*>(hash_set_2_), 323b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org 0, 324b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org sizeof(uintptr_t) * kHashSetLength); 325b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_sets_are_empty_ = true; 326b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org } 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::GCPrologue() { 331b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org ClearFilteringHashSets(); 332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com during_gc_ = true; 333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 336c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::VerifyPointers(LargeObjectSpace* space) { 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargeObjectIterator it(space); 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (object->IsFixedArray()) { 341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address slot_address = object->address(); 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address end = object->address() + object->Size(); 343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (slot_address < end) { 345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject** slot = reinterpret_cast<HeapObject**>(slot_address); 346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // When we are not in GC the Heap::InNewSpace() predicate 347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // checks that pointers which satisfy predicate point into 348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the active semispace. 3499e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Object* object = reinterpret_cast<Object*>( 3501e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); 3519e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org heap_->InNewSpace(object); 352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slot_address += kPointerSize; 353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::Verify() { 361c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyPointers(heap_->lo_space()); 363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::GCEpilogue() { 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com during_gc_ = false; 369c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (FLAG_verify_heap) { 371394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Verify(); 372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 373c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::FindPointersToNewSpaceInRegion( 378169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Address start, 379169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Address end, 380169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ObjectSlotCallback slot_callback, 381169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool clear_maps) { 382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address slot_address = start; 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slot_address < end; 384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slot_address += kPointerSize) { 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object** slot = reinterpret_cast<Object**>(slot_address); 3869e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Object* object = reinterpret_cast<Object*>( 3871e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); 3889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org if (heap_->InNewSpace(object)) { 3899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); 3909e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org ASSERT(heap_object->IsHeapObject()); 391169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // The new space object was not promoted if it still contains a map 392169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // pointer. Clear the map field now lazily. 3939e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org if (clear_maps) ClearDeadObject(heap_object); 3949e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object); 3959e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org object = reinterpret_cast<Object*>( 3961e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); 3979e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org if (heap_->InNewSpace(object)) { 398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EnterDirectlyIntoStoreBuffer(slot_address); 399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Compute start address of the first map following given addr. 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline Address MapStartAlign(Address addr) { 407ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address page = Page::FromAddress(addr)->area_start(); 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return page + (((addr - page) + (Map::kSize - 1)) / Map::kSize * Map::kSize); 409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Compute end address of the first map preceding given addr. 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline Address MapEndAlign(Address addr) { 414ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address page = Page::FromAllocationTop(addr)->area_start(); 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return page + ((addr - page) / Map::kSize * Map::kSize); 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::FindPointersToNewSpaceInMaps( 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address start, 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address end, 422169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ObjectSlotCallback slot_callback, 423169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool clear_maps) { 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MapStartAlign(start) == start); 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MapEndAlign(end) == end); 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address map_address = start; 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (map_address < end) { 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!heap_->InNewSpace(Memory::Object_at(map_address))); 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(Memory::Object_at(map_address)->IsMap()); 431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address pointer_fields_start = map_address + Map::kPointerFieldsBeginOffset; 433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address pointer_fields_end = map_address + Map::kPointerFieldsEndOffset; 434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FindPointersToNewSpaceInRegion(pointer_fields_start, 436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pointer_fields_end, 437169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org slot_callback, 438169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org clear_maps); 439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com map_address += Map::kSize; 440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::FindPointersToNewSpaceInMapsRegion( 445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address start, 446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address end, 447169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ObjectSlotCallback slot_callback, 448169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool clear_maps) { 449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address map_aligned_start = MapStartAlign(start); 450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address map_aligned_end = MapEndAlign(end); 451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(map_aligned_start == start); 453e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(map_aligned_start <= map_aligned_end && map_aligned_end <= end); 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FindPointersToNewSpaceInMaps(map_aligned_start, 456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com map_aligned_end, 457169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org slot_callback, 458169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org clear_maps); 459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::IteratePointersInStoreBuffer( 463169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ObjectSlotCallback slot_callback, 464169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool clear_maps) { 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* limit = old_top_; 466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_top_ = old_start_; 467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DontMoveStoreBufferEntriesScope scope(this); 469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* current = old_start_; current < limit; current++) { 470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* saved_top = old_top_; 472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object** slot = reinterpret_cast<Object**>(*current); 4749e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Object* object = reinterpret_cast<Object*>( 4751e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); 476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (heap_->InFromSpace(object)) { 477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); 478169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // The new space object was not promoted if it still contains a map 479169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // pointer. Clear the map field now lazily. 480169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (clear_maps) ClearDeadObject(heap_object); 481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object); 4829e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org object = reinterpret_cast<Object*>( 4831e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot))); 4849e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org if (heap_->InNewSpace(object)) { 485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot)); 486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(old_top_ == saved_top + 1 || old_top_ == saved_top); 489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { 495169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org IteratePointersToNewSpace(slot_callback, false); 496169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 497169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 498169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 499169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid StoreBuffer::IteratePointersToNewSpaceAndClearMaps( 500169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ObjectSlotCallback slot_callback) { 501169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org IteratePointersToNewSpace(slot_callback, true); 502169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 503169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 504169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 505169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, 506169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org bool clear_maps) { 507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We do not sort or remove duplicated entries from the store buffer because 508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // we expect that callback will rebuild the store buffer thus removing 509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // all duplicates and pointers to old space. 510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool some_pages_to_scan = PrepareForIteration(); 511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // TODO(gc): we want to skip slots on evacuation candidates 513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // but we can't simply figure that out from slot address 514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // because slot can belong to a large object. 515169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org IteratePointersInStoreBuffer(slot_callback, clear_maps); 516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We are done scanning all the pointers that were in the store buffer, but 518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // there may be some pages marked scan_on_scavenge that have pointers to new 519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // space that are not in the store buffer. We must scan them now. As we 520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // scan, the surviving pointers to new space will be added to the store 521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // buffer. If there are still a lot of pointers to new space then we will 522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // keep the scan_on_scavenge flag on the page and discard the pointers that 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // were added to the store buffer. If there are not many pointers to new 524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // space left on the page we will keep the pointers in the store buffer and 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // remove the flag from the page. 526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (some_pages_to_scan) { 527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (callback_ != NULL) { 528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (*callback_)(heap_, NULL, kStoreBufferStartScanningPagesEvent); 529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointerChunkIterator it(heap_); 531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* chunk; 532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while ((chunk = it.next()) != NULL) { 533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (chunk->scan_on_scavenge()) { 534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com chunk->set_scan_on_scavenge(false); 535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (callback_ != NULL) { 536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (*callback_)(heap_, chunk, kStoreBufferScanningPageEvent); 537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (chunk->owner() == heap_->lo_space()) { 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargePage* large_page = reinterpret_cast<LargePage*>(chunk); 540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* array = large_page->GetObject(); 541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(array->IsFixedArray()); 542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address start = array->address(); 543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address end = start + array->Size(); 544169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps); 545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* page = reinterpret_cast<Page*>(chunk); 547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); 548aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org Address start = page->area_start(); 549aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org Address end = page->area_end(); 550aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org if (owner == heap_->map_space()) { 551aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org FindPointersToNewSpaceInMapsRegion( 552aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org start, end, slot_callback, clear_maps); 553aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org } else { 554aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org FindPointersToNewSpaceInRegion( 555aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org start, end, slot_callback, clear_maps); 556aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org } 557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (callback_ != NULL) { 561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent); 562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid StoreBuffer::Compact() { 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top()); 569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (top == start_) return; 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // There's no check of the limit in the loop below so we check here for 573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the worst case (compaction doesn't eliminate any pointers). 574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(top <= limit_); 575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->public_set_store_buffer_top(start_); 57664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org EnsureSpace(top - start_); 577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(may_move_store_buffer_entries_); 578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Goes through the addresses in the store buffer attempting to remove 579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // duplicates. In the interest of speed this is a lossy operation. Some 580b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org // duplicates will remain. We have two hash sets with different hash 581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // functions to reduce the number of unnecessary clashes. 582b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_sets_are_empty_ = false; // Hash sets are in use. 583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address* current = start_; current < top; current++) { 584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!heap_->cell_space()->Contains(*current)); 585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!heap_->code_space()->Contains(*current)); 586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!heap_->old_data_space()->Contains(*current)); 587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uintptr_t int_addr = reinterpret_cast<uintptr_t>(*current); 588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Shift out the last bits including any tags. 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int_addr >>= kPointerSizeLog2; 590a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // The upper part of an address is basically random because of ASLR and OS 591a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // non-determinism, so we use only the bits within a page for hashing to 592a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // make v8's behavior (more) deterministic. 593a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org uintptr_t hash_addr = 594a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int_addr & (Page::kPageAlignmentMask >> kPointerSizeLog2); 595a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int hash1 = ((hash_addr ^ (hash_addr >> kHashSetLengthLog2)) & 596a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org (kHashSetLength - 1)); 597b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org if (hash_set_1_[hash1] == int_addr) continue; 598a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org uintptr_t hash2 = (hash_addr - (hash_addr >> kHashSetLengthLog2)); 599b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash2 ^= hash2 >> (kHashSetLengthLog2 * 2); 600fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org hash2 &= (kHashSetLength - 1); 601b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org if (hash_set_2_[hash2] == int_addr) continue; 602b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org if (hash_set_1_[hash1] == 0) { 603b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_1_[hash1] = int_addr; 604b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org } else if (hash_set_2_[hash2] == 0) { 605b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_2_[hash2] = int_addr; 606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Rather than slowing down we just throw away some entries. This will 608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // cause some duplicates to remain undetected. 609b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_1_[hash1] = int_addr; 610b295776b8c02617720d03b6dbcf2f912dfd2c4e7vegorov@chromium.org hash_set_2_[hash2] = 0; 611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_sorted_ = false; 613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_buffer_is_filtered_ = false; 614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2); 615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(old_top_ <= old_limit_); 616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->isolate()->counters()->store_buffer_compactions()->Increment(); 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} } // namespace v8::internal 621