LCOV - code coverage report
Current view: top level - src/snapshot - serializer-allocator.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 38 51 74.5 %
Date: 2019-04-19 Functions: 8 10 80.0 %

          Line data    Source code
       1             : // Copyright 2017 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             : #include "src/snapshot/serializer-allocator.h"
       6             : 
       7             : #include "src/heap/heap-inl.h"  // crbug.com/v8/8499
       8             : #include "src/snapshot/references.h"
       9             : #include "src/snapshot/serializer.h"
      10             : #include "src/snapshot/snapshot-source-sink.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15        1137 : SerializerAllocator::SerializerAllocator(Serializer* serializer)
      16        5685 :     : serializer_(serializer) {
      17       10233 :   for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
      18        4548 :     pending_chunk_[i] = 0;
      19             :   }
      20        1137 : }
      21             : 
      22         615 : void SerializerAllocator::UseCustomChunkSize(uint32_t chunk_size) {
      23         615 :   custom_chunk_size_ = chunk_size;
      24         615 : }
      25             : 
      26             : static uint32_t PageSizeOfSpace(int space) {
      27             :   return static_cast<uint32_t>(
      28     1346820 :       MemoryChunkLayout::AllocatableMemoryInMemoryChunk(
      29     1346820 :           static_cast<AllocationSpace>(space)));
      30             : }
      31             : 
      32           0 : uint32_t SerializerAllocator::TargetChunkSize(int space) {
      33     1867348 :   if (custom_chunk_size_ == 0) return PageSizeOfSpace(space);
      34             :   DCHECK_LE(custom_chunk_size_, PageSizeOfSpace(space));
      35             :   return custom_chunk_size_;
      36             : }
      37             : 
      38     1867348 : SerializerReference SerializerAllocator::Allocate(AllocationSpace space,
      39             :                                                   uint32_t size) {
      40             :   DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
      41             :   DCHECK(size > 0 && size <= PageSizeOfSpace(space));
      42             : 
      43             :   // Maps are allocated through AllocateMap.
      44             :   DCHECK_NE(MAP_SPACE, space);
      45             :   // We tenure large object allocations.
      46             :   DCHECK_NE(NEW_LO_SPACE, space);
      47             : 
      48     1867348 :   uint32_t old_chunk_size = pending_chunk_[space];
      49     1867348 :   uint32_t new_chunk_size = old_chunk_size + size;
      50             :   // Start a new chunk if the new size exceeds the target chunk size.
      51             :   // We may exceed the target chunk size if the single object size does.
      52     1867348 :   if (new_chunk_size > TargetChunkSize(space) && old_chunk_size != 0) {
      53       10109 :     serializer_->PutNextChunk(space);
      54       10109 :     completed_chunks_[space].push_back(pending_chunk_[space]);
      55       10109 :     pending_chunk_[space] = 0;
      56             :     new_chunk_size = size;
      57             :   }
      58     1867348 :   uint32_t offset = pending_chunk_[space];
      59     1867348 :   pending_chunk_[space] = new_chunk_size;
      60             :   return SerializerReference::BackReference(
      61     5602044 :       space, static_cast<uint32_t>(completed_chunks_[space].size()), offset);
      62             : }
      63             : 
      64       60811 : SerializerReference SerializerAllocator::AllocateMap() {
      65             :   // Maps are allocated one-by-one when deserializing.
      66       60811 :   return SerializerReference::MapReference(num_maps_++);
      67             : }
      68             : 
      69          60 : SerializerReference SerializerAllocator::AllocateLargeObject(uint32_t size) {
      70             :   // Large objects are allocated one-by-one when deserializing. We do not
      71             :   // have to keep track of multiple chunks.
      72          60 :   large_objects_total_size_ += size;
      73          60 :   return SerializerReference::LargeObjectReference(seen_large_objects_index_++);
      74             : }
      75             : 
      76          35 : SerializerReference SerializerAllocator::AllocateOffHeapBackingStore() {
      77             :   DCHECK_NE(0, seen_backing_stores_index_);
      78             :   return SerializerReference::OffHeapBackingStoreReference(
      79          35 :       seen_backing_stores_index_++);
      80             : }
      81             : 
      82             : #ifdef DEBUG
      83             : bool SerializerAllocator::BackReferenceIsAlreadyAllocated(
      84             :     SerializerReference reference) const {
      85             :   DCHECK(reference.is_back_reference());
      86             :   AllocationSpace space = reference.space();
      87             :   if (space == LO_SPACE) {
      88             :     return reference.large_object_index() < seen_large_objects_index_;
      89             :   } else if (space == MAP_SPACE) {
      90             :     return reference.map_index() < num_maps_;
      91             :   } else if (space == RO_SPACE &&
      92             :              serializer_->isolate()->heap()->deserialization_complete()) {
      93             :     // If not deserializing the isolate itself, then we create BackReferences
      94             :     // for all RO_SPACE objects without ever allocating.
      95             :     return true;
      96             :   } else {
      97             :     size_t chunk_index = reference.chunk_index();
      98             :     if (chunk_index == completed_chunks_[space].size()) {
      99             :       return reference.chunk_offset() < pending_chunk_[space];
     100             :     } else {
     101             :       return chunk_index < completed_chunks_[space].size() &&
     102             :              reference.chunk_offset() < completed_chunks_[space][chunk_index];
     103             :     }
     104             :   }
     105             : }
     106             : #endif
     107             : 
     108             : std::vector<SerializedData::Reservation>
     109        1137 : SerializerAllocator::EncodeReservations() const {
     110             :   std::vector<SerializedData::Reservation> out;
     111             : 
     112       10233 :   for (int i = FIRST_SPACE; i < kNumberOfPreallocatedSpaces; i++) {
     113       39423 :     for (size_t j = 0; j < completed_chunks_[i].size(); j++) {
     114       10109 :       out.emplace_back(completed_chunks_[i][j]);
     115             :     }
     116             : 
     117        4548 :     if (pending_chunk_[i] > 0 || completed_chunks_[i].size() == 0) {
     118        4548 :       out.emplace_back(pending_chunk_[i]);
     119             :     }
     120             :     out.back().mark_as_last();
     121             :   }
     122             : 
     123             :   STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
     124        1137 :   out.emplace_back(num_maps_ * Map::kSize);
     125             :   out.back().mark_as_last();
     126             : 
     127             :   STATIC_ASSERT(LO_SPACE == MAP_SPACE + 1);
     128        1137 :   out.emplace_back(large_objects_total_size_);
     129             :   out.back().mark_as_last();
     130             : 
     131        1137 :   return out;
     132             : }
     133             : 
     134           0 : void SerializerAllocator::OutputStatistics() {
     135             :   DCHECK(FLAG_serialization_statistics);
     136             : 
     137           0 :   PrintF("  Spaces (bytes):\n");
     138             : 
     139           0 :   for (int space = FIRST_SPACE; space < kNumberOfSpaces; space++) {
     140           0 :     PrintF("%16s", Heap::GetSpaceName(static_cast<AllocationSpace>(space)));
     141             :   }
     142           0 :   PrintF("\n");
     143             : 
     144           0 :   for (int space = FIRST_SPACE; space < kNumberOfPreallocatedSpaces; space++) {
     145           0 :     size_t s = pending_chunk_[space];
     146           0 :     for (uint32_t chunk_size : completed_chunks_[space]) s += chunk_size;
     147           0 :     PrintF("%16" PRIuS, s);
     148             :   }
     149             : 
     150             :   STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
     151           0 :   PrintF("%16d", num_maps_ * Map::kSize);
     152             : 
     153             :   STATIC_ASSERT(LO_SPACE == MAP_SPACE + 1);
     154           0 :   PrintF("%16d\n", large_objects_total_size_);
     155           0 : }
     156             : 
     157             : }  // namespace internal
     158      122036 : }  // namespace v8

Generated by: LCOV version 1.10