LCOV - code coverage report
Current view: top level - src/heap - heap-write-barrier-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 70 75 93.3 %
Date: 2019-02-19 Functions: 24 24 100.0 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
       6             : #define V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
       7             : 
       8             : // Clients of this interface shouldn't depend on lots of heap internals.
       9             : // Do not include anything from src/heap here!
      10             : 
      11             : #include "src/heap/heap-write-barrier.h"
      12             : 
      13             : #include "src/globals.h"
      14             : // TODO(jkummerow): Get rid of this by moving GetIsolateFromWritableObject
      15             : // elsewhere.
      16             : #include "src/isolate.h"
      17             : #include "src/objects/code.h"
      18             : #include "src/objects/fixed-array.h"
      19             : #include "src/objects/heap-object.h"
      20             : #include "src/objects/maybe-object-inl.h"
      21             : #include "src/objects/slots.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26             : // Defined in heap.cc.
      27             : V8_EXPORT_PRIVATE bool Heap_PageFlagsAreConsistent(HeapObject object);
      28             : V8_EXPORT_PRIVATE void Heap_GenerationalBarrierSlow(HeapObject object,
      29             :                                                     Address slot,
      30             :                                                     HeapObject value);
      31             : V8_EXPORT_PRIVATE void Heap_MarkingBarrierSlow(HeapObject object, Address slot,
      32             :                                                HeapObject value);
      33             : V8_EXPORT_PRIVATE void Heap_WriteBarrierForCodeSlow(Code host);
      34             : V8_EXPORT_PRIVATE void Heap_GenerationalBarrierForCodeSlow(Code host,
      35             :                                                            RelocInfo* rinfo,
      36             :                                                            HeapObject object);
      37             : V8_EXPORT_PRIVATE void Heap_MarkingBarrierForCodeSlow(Code host,
      38             :                                                       RelocInfo* rinfo,
      39             :                                                       HeapObject object);
      40             : V8_EXPORT_PRIVATE void Heap_GenerationalBarrierForElementsSlow(Heap* heap,
      41             :                                                                FixedArray array,
      42             :                                                                int offset,
      43             :                                                                int length);
      44             : V8_EXPORT_PRIVATE void Heap_MarkingBarrierForElementsSlow(Heap* heap,
      45             :                                                           HeapObject object);
      46             : V8_EXPORT_PRIVATE void Heap_MarkingBarrierForDescriptorArraySlow(
      47             :     Heap* heap, HeapObject host, HeapObject descriptor_array,
      48             :     int number_of_own_descriptors);
      49             : 
      50             : // Do not use these internal details anywhere outside of this file. These
      51             : // internals are only intended to shortcut write barrier checks.
      52             : namespace heap_internals {
      53             : 
      54             : struct Space {
      55             :   static constexpr uintptr_t kIdOffset = 9 * kSystemPointerSize;
      56             :   V8_INLINE AllocationSpace identity() {
      57       75905 :     return *reinterpret_cast<AllocationSpace*>(reinterpret_cast<Address>(this) +
      58       75905 :                                                kIdOffset);
      59             :   }
      60             : };
      61             : 
      62             : struct MemoryChunk {
      63             :   static constexpr uintptr_t kFlagsOffset = sizeof(size_t);
      64             :   static constexpr uintptr_t kHeapOffset =
      65             :       kFlagsOffset + kUIntptrSize + 4 * kSystemPointerSize;
      66             :   static constexpr uintptr_t kOwnerOffset =
      67             :       kHeapOffset + 2 * kSystemPointerSize;
      68             :   static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 18;
      69             :   static constexpr uintptr_t kFromPageBit = uintptr_t{1} << 3;
      70             :   static constexpr uintptr_t kToPageBit = uintptr_t{1} << 4;
      71             : 
      72             :   V8_INLINE static heap_internals::MemoryChunk* FromHeapObject(
      73             :       HeapObject object) {
      74  5582826408 :     return reinterpret_cast<MemoryChunk*>(object->ptr() & ~kPageAlignmentMask);
      75             :   }
      76             : 
      77  2189269652 :   V8_INLINE bool IsMarking() const { return GetFlags() & kMarkingBit; }
      78             : 
      79             :   V8_INLINE bool InYoungGeneration() const {
      80           0 :     constexpr uintptr_t kYoungGenerationMask = kFromPageBit | kToPageBit;
      81  2194874859 :     return GetFlags() & kYoungGenerationMask;
      82             :   }
      83             : 
      84             :   V8_INLINE uintptr_t GetFlags() const {
      85  4348134906 :     return *reinterpret_cast<const uintptr_t*>(reinterpret_cast<Address>(this) +
      86  4348134912 :                                                kFlagsOffset);
      87             :   }
      88             : 
      89             :   V8_INLINE Heap* GetHeap() {
      90  1410992095 :     Heap* heap = *reinterpret_cast<Heap**>(reinterpret_cast<Address>(this) +
      91  1410992095 :                                            kHeapOffset);
      92             :     SLOW_DCHECK(heap != nullptr);
      93    50130860 :     return heap;
      94             :   }
      95             : 
      96             :   V8_INLINE Space* GetOwner() {
      97       75905 :     return *reinterpret_cast<Space**>(reinterpret_cast<Address>(this) +
      98       75905 :                                       kOwnerOffset);
      99             :   }
     100             : };
     101             : 
     102  1962039738 : inline void GenerationalBarrierInternal(HeapObject object, Address slot,
     103             :                                         HeapObject value) {
     104             :   DCHECK(Heap_PageFlagsAreConsistent(object));
     105             :   heap_internals::MemoryChunk* value_chunk =
     106           0 :       heap_internals::MemoryChunk::FromHeapObject(value);
     107             :   heap_internals::MemoryChunk* object_chunk =
     108           0 :       heap_internals::MemoryChunk::FromHeapObject(object);
     109             : 
     110  2138400775 :   if (!value_chunk->InYoungGeneration() || object_chunk->InYoungGeneration()) {
     111  1962039069 :     return;
     112             :   }
     113             : 
     114   111939479 :   Heap_GenerationalBarrierSlow(object, slot, value);
     115             : }
     116             : 
     117  2059873600 : inline void MarkingBarrierInternal(HeapObject object, Address slot,
     118             :                                    HeapObject value) {
     119             :   DCHECK(Heap_PageFlagsAreConsistent(object));
     120             :   heap_internals::MemoryChunk* value_chunk =
     121          70 :       heap_internals::MemoryChunk::FromHeapObject(value);
     122             : 
     123  4119747107 :   if (!value_chunk->IsMarking()) return;
     124             : 
     125   285502283 :   Heap_MarkingBarrierSlow(object, slot, value);
     126             : }
     127             : 
     128             : }  // namespace heap_internals
     129             : 
     130     6249697 : inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value) {
     131             :   DCHECK(!HasWeakHeapObjectTag(value));
     132     6249697 :   if (!value->IsHeapObject()) return;
     133     6249697 :   HeapObject object = HeapObject::cast(value);
     134     6249697 :   GenerationalBarrierForCode(host, rinfo, object);
     135     6249696 :   MarkingBarrierForCode(host, rinfo, object);
     136             : }
     137             : 
     138             : inline void WriteBarrierForCode(Code host) {
     139          40 :   Heap_WriteBarrierForCodeSlow(host);
     140             : }
     141             : 
     142  2050050267 : inline void GenerationalBarrier(HeapObject object, ObjectSlot slot,
     143             :                                 Object value) {
     144             :   DCHECK(!HasWeakHeapObjectTag(*slot));
     145             :   DCHECK(!HasWeakHeapObjectTag(value));
     146  4100098918 :   if (!value->IsHeapObject()) return;
     147             :   heap_internals::GenerationalBarrierInternal(object, slot.address(),
     148  1726148193 :                                               HeapObject::cast(value));
     149             : }
     150             : 
     151  1376453665 : inline void GenerationalBarrier(HeapObject object, MaybeObjectSlot slot,
     152             :                                 MaybeObject value) {
     153  1376453665 :   HeapObject value_heap_object;
     154  2517167971 :   if (!value->GetHeapObject(&value_heap_object)) return;
     155             :   heap_internals::GenerationalBarrierInternal(object, slot.address(),
     156   235891610 :                                               value_heap_object);
     157             : }
     158             : 
     159        9234 : inline void GenerationalBarrierForElements(Heap* heap, FixedArray array,
     160             :                                            int offset, int length) {
     161             :   heap_internals::MemoryChunk* array_chunk =
     162             :       heap_internals::MemoryChunk::FromHeapObject(array);
     163       18468 :   if (array_chunk->InYoungGeneration()) return;
     164             : 
     165         963 :   Heap_GenerationalBarrierForElementsSlow(heap, array, offset, length);
     166             : }
     167             : 
     168     6305567 : inline void GenerationalBarrierForCode(Code host, RelocInfo* rinfo,
     169             :                                        HeapObject object) {
     170             :   heap_internals::MemoryChunk* object_chunk =
     171           0 :       heap_internals::MemoryChunk::FromHeapObject(object);
     172    12611134 :   if (!object_chunk->InYoungGeneration()) return;
     173      217505 :   Heap_GenerationalBarrierForCodeSlow(host, rinfo, object);
     174             : }
     175             : 
     176  2148154599 : inline void MarkingBarrier(HeapObject object, ObjectSlot slot, Object value) {
     177             :   DCHECK_IMPLIES(slot.address() != kNullAddress, !HasWeakHeapObjectTag(*slot));
     178             :   DCHECK(!HasWeakHeapObjectTag(value));
     179  4296309422 :   if (!value->IsHeapObject()) return;
     180             :   heap_internals::MarkingBarrierInternal(object, slot.address(),
     181  1824251931 :                                          HeapObject::cast(value));
     182             : }
     183             : 
     184  1376183794 : inline void MarkingBarrier(HeapObject object, MaybeObjectSlot slot,
     185             :                            MaybeObject value) {
     186  1376183794 :   HeapObject value_heap_object;
     187  2516746339 :   if (!value->GetHeapObject(&value_heap_object)) return;
     188             :   heap_internals::MarkingBarrierInternal(object, slot.address(),
     189   235621707 :                                          value_heap_object);
     190             : }
     191             : 
     192        9234 : inline void MarkingBarrierForElements(Heap* heap, HeapObject object) {
     193             :   heap_internals::MemoryChunk* object_chunk =
     194             :       heap_internals::MemoryChunk::FromHeapObject(object);
     195       18468 :   if (!object_chunk->IsMarking()) return;
     196             : 
     197         423 :   Heap_MarkingBarrierForElementsSlow(heap, object);
     198             : }
     199             : 
     200     7638405 : inline void MarkingBarrierForCode(Code host, RelocInfo* rinfo,
     201             :                                   HeapObject object) {
     202             :   DCHECK(!HasWeakHeapObjectTag(object.ptr()));
     203             :   heap_internals::MemoryChunk* object_chunk =
     204           0 :       heap_internals::MemoryChunk::FromHeapObject(object);
     205    15276808 :   if (!object_chunk->IsMarking()) return;
     206      291888 :   Heap_MarkingBarrierForCodeSlow(host, rinfo, object);
     207             : }
     208             : 
     209    81523072 : inline void MarkingBarrierForDescriptorArray(Heap* heap, HeapObject host,
     210             :                                              HeapObject descriptor_array,
     211             :                                              int number_of_own_descriptors) {
     212             :   heap_internals::MemoryChunk* chunk =
     213             :       heap_internals::MemoryChunk::FromHeapObject(descriptor_array);
     214   163046145 :   if (!chunk->IsMarking()) return;
     215             : 
     216             :   Heap_MarkingBarrierForDescriptorArraySlow(heap, host, descriptor_array,
     217     9252428 :                                             number_of_own_descriptors);
     218             : }
     219             : 
     220    40225374 : inline WriteBarrierMode GetWriteBarrierModeForObject(
     221             :     HeapObject object, const DisallowHeapAllocation* promise) {
     222             :   DCHECK(Heap_PageFlagsAreConsistent(object));
     223             :   heap_internals::MemoryChunk* chunk =
     224             :       heap_internals::MemoryChunk::FromHeapObject(object);
     225    40225387 :   if (chunk->IsMarking()) return UPDATE_WRITE_BARRIER;
     226    36009599 :   if (chunk->InYoungGeneration()) return SKIP_WRITE_BARRIER;
     227             :   return UPDATE_WRITE_BARRIER;
     228             : }
     229             : 
     230    14150756 : inline bool ObjectInYoungGeneration(const Object object) {
     231    14150756 :   if (object.IsSmi()) return false;
     232             :   return heap_internals::MemoryChunk::FromHeapObject(HeapObject::cast(object))
     233    14149678 :       ->InYoungGeneration();
     234             : }
     235             : 
     236  1410976599 : inline Heap* GetHeapFromWritableObject(const HeapObject object) {
     237             :   heap_internals::MemoryChunk* chunk =
     238    50130860 :       heap_internals::MemoryChunk::FromHeapObject(object);
     239  1410976398 :   return chunk->GetHeap();
     240             : }
     241             : 
     242       75905 : inline bool GetIsolateFromWritableObject(HeapObject obj, Isolate** isolate) {
     243             :   heap_internals::MemoryChunk* chunk =
     244             :       heap_internals::MemoryChunk::FromHeapObject(obj);
     245       75905 :   if (chunk->GetOwner()->identity() == RO_SPACE) {
     246       60208 :     *isolate = nullptr;
     247       60208 :     return false;
     248             :   }
     249       15697 :   *isolate = Isolate::FromHeap(chunk->GetHeap());
     250       15697 :   return true;
     251             : }
     252             : 
     253             : }  // namespace internal
     254             : }  // namespace v8
     255             : 
     256             : #endif  // V8_HEAP_HEAP_WRITE_BARRIER_INL_H_

Generated by: LCOV version 1.10