Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: src/heap/mark-compact.h

Issue 1343043002: [heap] Move slots buffer into a separate file. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/mark-compact.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HEAP_MARK_COMPACT_H_ 5 #ifndef V8_HEAP_MARK_COMPACT_H_
6 #define V8_HEAP_MARK_COMPACT_H_ 6 #define V8_HEAP_MARK_COMPACT_H_
7 7
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/heap/spaces.h" 9 #include "src/heap/spaces.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 // Callback function, returns whether an object is alive. The heap size 14 // Callback function, returns whether an object is alive. The heap size
15 // of the object is returned in size. It optionally updates the offset 15 // of the object is returned in size. It optionally updates the offset
16 // to the first live object in the page (only used for old and map objects). 16 // to the first live object in the page (only used for old and map objects).
17 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); 17 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset);
18 18
19 // Callback function to mark an object in a given heap. 19 // Callback function to mark an object in a given heap.
20 typedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object); 20 typedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object);
21 21
22 // Forward declarations. 22 // Forward declarations.
23 class CodeFlusher; 23 class CodeFlusher;
24 class MarkCompactCollector; 24 class MarkCompactCollector;
25 class MarkingVisitor; 25 class MarkingVisitor;
26 class RootMarkingVisitor; 26 class RootMarkingVisitor;
27 class SlotsBuffer;
28 class SlotsBufferAllocator;
27 29
28 30
29 class Marking : public AllStatic { 31 class Marking : public AllStatic {
30 public: 32 public:
31 INLINE(static MarkBit MarkBitFrom(Address addr)) { 33 INLINE(static MarkBit MarkBitFrom(Address addr)) {
32 MemoryChunk* p = MemoryChunk::FromAddress(addr); 34 MemoryChunk* p = MemoryChunk::FromAddress(addr);
33 return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(addr)); 35 return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(addr));
34 } 36 }
35 37
36 INLINE(static MarkBit MarkBitFrom(HeapObject* obj)) { 38 INLINE(static MarkBit MarkBitFrom(HeapObject* obj)) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 int top_; 253 int top_;
252 int bottom_; 254 int bottom_;
253 int mask_; 255 int mask_;
254 bool overflowed_; 256 bool overflowed_;
255 bool in_use_; 257 bool in_use_;
256 258
257 DISALLOW_COPY_AND_ASSIGN(MarkingDeque); 259 DISALLOW_COPY_AND_ASSIGN(MarkingDeque);
258 }; 260 };
259 261
260 262
261 class SlotsBufferAllocator {
262 public:
263 SlotsBuffer* AllocateBuffer(SlotsBuffer* next_buffer);
264 void DeallocateBuffer(SlotsBuffer* buffer);
265
266 void DeallocateChain(SlotsBuffer** buffer_address);
267 };
268
269
270 // SlotsBuffer records a sequence of slots that has to be updated
271 // after live objects were relocated from evacuation candidates.
272 // All slots are either untyped or typed:
273 // - Untyped slots are expected to contain a tagged object pointer.
274 // They are recorded by an address.
275 // - Typed slots are expected to contain an encoded pointer to a heap
276 // object where the way of encoding depends on the type of the slot.
277 // They are recorded as a pair (SlotType, slot address).
278 // We assume that zero-page is never mapped this allows us to distinguish
279 // untyped slots from typed slots during iteration by a simple comparison:
280 // if element of slots buffer is less than NUMBER_OF_SLOT_TYPES then it
281 // is the first element of typed slot's pair.
282 class SlotsBuffer {
283 public:
284 typedef Object** ObjectSlot;
285
286 explicit SlotsBuffer(SlotsBuffer* next_buffer)
287 : idx_(0), chain_length_(1), next_(next_buffer) {
288 if (next_ != NULL) {
289 chain_length_ = next_->chain_length_ + 1;
290 }
291 }
292
293 ~SlotsBuffer() {}
294
295 void Add(ObjectSlot slot) {
296 DCHECK(0 <= idx_ && idx_ < kNumberOfElements);
297 #ifdef DEBUG
298 if (slot >= reinterpret_cast<ObjectSlot>(NUMBER_OF_SLOT_TYPES)) {
299 DCHECK_NOT_NULL(*slot);
300 }
301 #endif
302 slots_[idx_++] = slot;
303 }
304
305 // Should be used for testing only.
306 ObjectSlot Get(intptr_t i) {
307 DCHECK(i >= 0 && i < kNumberOfElements);
308 return slots_[i];
309 }
310
311 enum SlotType {
312 EMBEDDED_OBJECT_SLOT,
313 OBJECT_SLOT,
314 RELOCATED_CODE_OBJECT,
315 CELL_TARGET_SLOT,
316 CODE_TARGET_SLOT,
317 CODE_ENTRY_SLOT,
318 DEBUG_TARGET_SLOT,
319 NUMBER_OF_SLOT_TYPES
320 };
321
322 static const char* SlotTypeToString(SlotType type) {
323 switch (type) {
324 case EMBEDDED_OBJECT_SLOT:
325 return "EMBEDDED_OBJECT_SLOT";
326 case OBJECT_SLOT:
327 return "OBJECT_SLOT";
328 case RELOCATED_CODE_OBJECT:
329 return "RELOCATED_CODE_OBJECT";
330 case CELL_TARGET_SLOT:
331 return "CELL_TARGET_SLOT";
332 case CODE_TARGET_SLOT:
333 return "CODE_TARGET_SLOT";
334 case CODE_ENTRY_SLOT:
335 return "CODE_ENTRY_SLOT";
336 case DEBUG_TARGET_SLOT:
337 return "DEBUG_TARGET_SLOT";
338 case NUMBER_OF_SLOT_TYPES:
339 return "NUMBER_OF_SLOT_TYPES";
340 }
341 return "UNKNOWN SlotType";
342 }
343
344 void UpdateSlots(Heap* heap);
345
346 void UpdateSlotsWithFilter(Heap* heap);
347
348 SlotsBuffer* next() { return next_; }
349
350 static int SizeOfChain(SlotsBuffer* buffer) {
351 if (buffer == NULL) return 0;
352 return static_cast<int>(buffer->idx_ +
353 (buffer->chain_length_ - 1) * kNumberOfElements);
354 }
355
356 inline bool IsFull() { return idx_ == kNumberOfElements; }
357
358 inline bool HasSpaceForTypedSlot() { return idx_ < kNumberOfElements - 1; }
359
360 static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer) {
361 while (buffer != NULL) {
362 buffer->UpdateSlots(heap);
363 buffer = buffer->next();
364 }
365 }
366
367 enum AdditionMode { FAIL_ON_OVERFLOW, IGNORE_OVERFLOW };
368
369 static bool ChainLengthThresholdReached(SlotsBuffer* buffer) {
370 return buffer != NULL && buffer->chain_length_ >= kChainLengthThreshold;
371 }
372
373 INLINE(static bool AddToSynchronized(SlotsBufferAllocator* allocator,
374 SlotsBuffer** buffer_address,
375 base::Mutex* buffer_mutex,
376 ObjectSlot slot, AdditionMode mode)) {
377 base::LockGuard<base::Mutex> lock_guard(buffer_mutex);
378 return AddTo(allocator, buffer_address, slot, mode);
379 }
380
381 INLINE(static bool AddTo(SlotsBufferAllocator* allocator,
382 SlotsBuffer** buffer_address, ObjectSlot slot,
383 AdditionMode mode)) {
384 SlotsBuffer* buffer = *buffer_address;
385 if (buffer == NULL || buffer->IsFull()) {
386 if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) {
387 allocator->DeallocateChain(buffer_address);
388 return false;
389 }
390 buffer = allocator->AllocateBuffer(buffer);
391 *buffer_address = buffer;
392 }
393 buffer->Add(slot);
394 return true;
395 }
396
397 static bool IsTypedSlot(ObjectSlot slot);
398
399 static bool AddToSynchronized(SlotsBufferAllocator* allocator,
400 SlotsBuffer** buffer_address,
401 base::Mutex* buffer_mutex, SlotType type,
402 Address addr, AdditionMode mode);
403
404 static bool AddTo(SlotsBufferAllocator* allocator,
405 SlotsBuffer** buffer_address, SlotType type, Address addr,
406 AdditionMode mode);
407
408 // Eliminates all stale entries from the slots buffer, i.e., slots that
409 // are not part of live objects anymore. This method must be called after
410 // marking, when the whole transitive closure is known and must be called
411 // before sweeping when mark bits are still intact.
412 static void RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer);
413
414 // Eliminate all slots that are within the given address range.
415 static void RemoveObjectSlots(Heap* heap, SlotsBuffer* buffer,
416 Address start_slot, Address end_slot);
417
418 // Ensures that there are no invalid slots in the chain of slots buffers.
419 static void VerifySlots(Heap* heap, SlotsBuffer* buffer);
420
421 static const int kNumberOfElements = 1021;
422
423 private:
424 static const int kChainLengthThreshold = 15;
425
426 intptr_t idx_;
427 intptr_t chain_length_;
428 SlotsBuffer* next_;
429 ObjectSlot slots_[kNumberOfElements];
430 };
431
432
433 // CodeFlusher collects candidates for code flushing during marking and 263 // CodeFlusher collects candidates for code flushing during marking and
434 // processes those candidates after marking has completed in order to 264 // processes those candidates after marking has completed in order to
435 // reset those functions referencing code objects that would otherwise 265 // reset those functions referencing code objects that would otherwise
436 // be unreachable. Code objects can be referenced in three ways: 266 // be unreachable. Code objects can be referenced in three ways:
437 // - SharedFunctionInfo references unoptimized code. 267 // - SharedFunctionInfo references unoptimized code.
438 // - JSFunction references either unoptimized or optimized code. 268 // - JSFunction references either unoptimized or optimized code.
439 // - OptimizedCodeMap references optimized code. 269 // - OptimizedCodeMap references optimized code.
440 // We are not allowed to flush unoptimized code for functions that got 270 // We are not allowed to flush unoptimized code for functions that got
441 // optimized or inlined into optimized code, because we might bailout 271 // optimized or inlined into optimized code, because we might bailout
442 // into the unoptimized code again during deoptimization. 272 // into the unoptimized code again during deoptimization.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 } 412 }
583 413
584 INLINE(static bool IsOnEvacuationCandidate(Object* obj)) { 414 INLINE(static bool IsOnEvacuationCandidate(Object* obj)) {
585 return Page::FromAddress(reinterpret_cast<Address>(obj)) 415 return Page::FromAddress(reinterpret_cast<Address>(obj))
586 ->IsEvacuationCandidate(); 416 ->IsEvacuationCandidate();
587 } 417 }
588 418
589 void RecordRelocSlot(RelocInfo* rinfo, Object* target); 419 void RecordRelocSlot(RelocInfo* rinfo, Object* target);
590 void RecordCodeEntrySlot(HeapObject* object, Address slot, Code* target); 420 void RecordCodeEntrySlot(HeapObject* object, Address slot, Code* target);
591 void RecordCodeTargetPatch(Address pc, Code* target); 421 void RecordCodeTargetPatch(Address pc, Code* target);
422 void RecordSlot(HeapObject* object, Object** slot, Object* target);
423 void ForceRecordSlot(HeapObject* object, Object** slot, Object* target);
592 424
593 INLINE(void RecordSlot( 425 void UpdateSlots(SlotsBuffer* buffer);
594 HeapObject* object, Object** slot, Object* target, 426 void UpdateSlotsRecordedIn(SlotsBuffer* buffer);
595 SlotsBuffer::AdditionMode mode = SlotsBuffer::FAIL_ON_OVERFLOW));
596 427
597 void MigrateObject(HeapObject* dst, HeapObject* src, int size, 428 void MigrateObject(HeapObject* dst, HeapObject* src, int size,
598 AllocationSpace to_old_space); 429 AllocationSpace to_old_space);
599 430
600 void MigrateObjectTagged(HeapObject* dst, HeapObject* src, int size); 431 void MigrateObjectTagged(HeapObject* dst, HeapObject* src, int size);
601 void MigrateObjectMixed(HeapObject* dst, HeapObject* src, int size); 432 void MigrateObjectMixed(HeapObject* dst, HeapObject* src, int size);
602 void MigrateObjectRaw(HeapObject* dst, HeapObject* src, int size); 433 void MigrateObjectRaw(HeapObject* dst, HeapObject* src, int size);
603 434
604 bool TryPromoteObject(HeapObject* object, int object_size); 435 bool TryPromoteObject(HeapObject* object, int object_size);
605 436
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 bool parallel_compaction_in_progress_; 551 bool parallel_compaction_in_progress_;
721 552
722 // Synchronize sweeper threads. 553 // Synchronize sweeper threads.
723 base::Semaphore pending_sweeper_jobs_semaphore_; 554 base::Semaphore pending_sweeper_jobs_semaphore_;
724 555
725 // Synchronize compaction threads. 556 // Synchronize compaction threads.
726 base::Semaphore pending_compaction_jobs_semaphore_; 557 base::Semaphore pending_compaction_jobs_semaphore_;
727 558
728 bool evacuation_; 559 bool evacuation_;
729 560
730 SlotsBufferAllocator slots_buffer_allocator_; 561 SlotsBufferAllocator* slots_buffer_allocator_;
731 562
732 SlotsBuffer* migration_slots_buffer_; 563 SlotsBuffer* migration_slots_buffer_;
733 564
734 base::Mutex migration_slots_buffer_mutex_; 565 base::Mutex migration_slots_buffer_mutex_;
735 566
736 // Finishes GC, performs heap verification if enabled. 567 // Finishes GC, performs heap verification if enabled.
737 void Finish(); 568 void Finish();
738 569
739 // ----------------------------------------------------------------------- 570 // -----------------------------------------------------------------------
740 // Phase 1: Marking live objects. 571 // Phase 1: Marking live objects.
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 private: 823 private:
993 MarkCompactCollector* collector_; 824 MarkCompactCollector* collector_;
994 }; 825 };
995 826
996 827
997 const char* AllocationSpaceName(AllocationSpace space); 828 const char* AllocationSpaceName(AllocationSpace space);
998 } 829 }
999 } // namespace v8::internal 830 } // namespace v8::internal
1000 831
1001 #endif // V8_HEAP_MARK_COMPACT_H_ 832 #endif // V8_HEAP_MARK_COMPACT_H_
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/mark-compact.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698