LCOV - code coverage report
Current view: top level - src/snapshot - builtin-deserializer-allocator.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 36 38 94.7 %
Date: 2017-10-20 Functions: 6 8 75.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/builtin-deserializer-allocator.h"
       6             : 
       7             : #include "src/heap/heap-inl.h"
       8             : #include "src/snapshot/builtin-deserializer.h"
       9             : #include "src/snapshot/deserializer.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14      155730 : BuiltinDeserializerAllocator::BuiltinDeserializerAllocator(
      15             :     Deserializer<BuiltinDeserializerAllocator>* deserializer)
      16      155730 :     : deserializer_(deserializer) {}
      17             : 
      18    25042057 : Address BuiltinDeserializerAllocator::Allocate(AllocationSpace space,
      19             :                                                int size) {
      20    25042057 :   const int builtin_id = deserializer()->CurrentBuiltinId();
      21             :   DCHECK_EQ(CODE_SPACE, space);
      22             :   DCHECK_EQ(deserializer()->ExtractBuiltinSize(builtin_id), size);
      23             : #ifdef DEBUG
      24             :   RegisterBuiltinAllocation(builtin_id);
      25             : #endif
      26             :   Object* obj = isolate()->builtins()->builtin(builtin_id);
      27             :   DCHECK(Internals::HasHeapObjectTag(obj));
      28    25042057 :   return HeapObject::cast(obj)->address();
      29             : }
      30             : 
      31             : Heap::Reservation
      32       54968 : BuiltinDeserializerAllocator::CreateReservationsForEagerBuiltins() {
      33             :   Heap::Reservation result;
      34             : 
      35             :   // DeserializeLazy is always the first reservation (to simplify logic in
      36             :   // InitializeBuiltinsTable).
      37             :   {
      38             :     DCHECK(!Builtins::IsLazy(Builtins::kDeserializeLazy));
      39             :     uint32_t builtin_size =
      40       54968 :         deserializer()->ExtractBuiltinSize(Builtins::kDeserializeLazy);
      41             :     DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
      42      109947 :     result.push_back({builtin_size, nullptr, nullptr});
      43             :   }
      44             : 
      45    38587156 :   for (int i = 0; i < Builtins::builtin_count; i++) {
      46    38532188 :     if (i == Builtins::kDeserializeLazy) continue;
      47             : 
      48             :     // Skip lazy builtins. These will be replaced by the DeserializeLazy code
      49             :     // object in InitializeBuiltinsTable and thus require no reserved space.
      50    38477240 :     if (deserializer()->IsLazyDeserializationEnabled() && Builtins::IsLazy(i)) {
      51             :       continue;
      52             :     }
      53             : 
      54    24886338 :     uint32_t builtin_size = deserializer()->ExtractBuiltinSize(i);
      55             :     DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
      56    49772659 :     result.push_back({builtin_size, nullptr, nullptr});
      57             :   }
      58             : 
      59       54968 :   return result;
      60             : }
      61             : 
      62    24941077 : void BuiltinDeserializerAllocator::InitializeBuiltinFromReservation(
      63             :     const Heap::Chunk& chunk, int builtin_id) {
      64             :   DCHECK_EQ(deserializer()->ExtractBuiltinSize(builtin_id), chunk.size);
      65             :   DCHECK_EQ(chunk.size, chunk.end - chunk.start);
      66             : 
      67    24941077 :   SkipList::Update(chunk.start, chunk.size);
      68             :   isolate()->builtins()->set_builtin(builtin_id,
      69    49882332 :                                      HeapObject::FromAddress(chunk.start));
      70             : 
      71             : #ifdef DEBUG
      72             :   RegisterBuiltinReservation(builtin_id);
      73             : #endif
      74    24941034 : }
      75             : 
      76       54968 : void BuiltinDeserializerAllocator::InitializeBuiltinsTable(
      77    24941046 :     const Heap::Reservation& reservation) {
      78             :   DCHECK(!AllowHeapAllocation::IsAllowed());
      79             : 
      80       54968 :   Builtins* builtins = isolate()->builtins();
      81             :   int reservation_index = 0;
      82             : 
      83             :   // Other builtins can be replaced by DeserializeLazy so it may not be lazy.
      84             :   // It always occupies the first reservation slot.
      85             :   {
      86             :     DCHECK(!Builtins::IsLazy(Builtins::kDeserializeLazy));
      87             :     InitializeBuiltinFromReservation(reservation[reservation_index],
      88       54968 :                                      Builtins::kDeserializeLazy);
      89             :     reservation_index++;
      90             :   }
      91             : 
      92             :   Code* deserialize_lazy = builtins->builtin(Builtins::kDeserializeLazy);
      93             : 
      94    38586689 :   for (int i = 0; i < Builtins::builtin_count; i++) {
      95    38531721 :     if (i == Builtins::kDeserializeLazy) continue;
      96             : 
      97    38476732 :     if (deserializer()->IsLazyDeserializationEnabled() && Builtins::IsLazy(i)) {
      98    13591086 :       builtins->set_builtin(i, deserialize_lazy);
      99             :     } else {
     100    49772156 :       InitializeBuiltinFromReservation(reservation[reservation_index], i);
     101    24886083 :       reservation_index++;
     102             :     }
     103             :   }
     104             : 
     105             :   DCHECK_EQ(reservation.size(), reservation_index);
     106       54968 : }
     107             : 
     108      100762 : void BuiltinDeserializerAllocator::ReserveAndInitializeBuiltinsTableForBuiltin(
     109             :     int builtin_id) {
     110             :   DCHECK(AllowHeapAllocation::IsAllowed());
     111             :   DCHECK(isolate()->builtins()->is_initialized());
     112             :   DCHECK(Builtins::IsBuiltinId(builtin_id));
     113             :   DCHECK_NE(Builtins::kDeserializeLazy, builtin_id);
     114             :   DCHECK_EQ(Builtins::kDeserializeLazy,
     115             :             isolate()->builtins()->builtin(builtin_id)->builtin_index());
     116             : 
     117      100762 :   const uint32_t builtin_size = deserializer()->ExtractBuiltinSize(builtin_id);
     118             :   DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
     119             : 
     120             :   Handle<HeapObject> o =
     121      100762 :       isolate()->factory()->NewCodeForDeserialization(builtin_size);
     122             : 
     123             :   // Note: After this point and until deserialization finishes, heap allocation
     124             :   // is disallowed. We currently can't safely assert this since we'd need to
     125             :   // pass the DisallowHeapAllocation scope out of this function.
     126             : 
     127             :   // Write the allocated filler object into the builtins table. It will be
     128             :   // returned by our custom Allocate method below once needed.
     129             : 
     130      100762 :   isolate()->builtins()->set_builtin(builtin_id, *o);
     131             : 
     132             : #ifdef DEBUG
     133             :   RegisterBuiltinReservation(builtin_id);
     134             : #endif
     135      100762 : }
     136             : 
     137             : #ifdef DEBUG
     138             : void BuiltinDeserializerAllocator::RegisterBuiltinReservation(int builtin_id) {
     139             :   const auto result = unused_reservations_.emplace(builtin_id);
     140             :   CHECK(result.second);  // False, iff builtin_id was already present in set.
     141             : }
     142             : 
     143             : void BuiltinDeserializerAllocator::RegisterBuiltinAllocation(int builtin_id) {
     144             :   const size_t removed_elems = unused_reservations_.erase(builtin_id);
     145             :   CHECK_EQ(removed_elems, 1);
     146             : }
     147             : 
     148             : bool BuiltinDeserializerAllocator::ReservationsAreFullyUsed() const {
     149             :   // Not 100% precise but should be good enough.
     150             :   return unused_reservations_.empty();
     151             : }
     152             : #endif  // DEBUG
     153             : 
     154           0 : Isolate* BuiltinDeserializerAllocator::isolate() const {
     155    50239715 :   return deserializer()->isolate();
     156             : }
     157             : 
     158           0 : BuiltinDeserializer* BuiltinDeserializerAllocator::deserializer() const {
     159   152235755 :   return static_cast<BuiltinDeserializer*>(deserializer_);
     160             : }
     161             : 
     162             : }  // namespace internal
     163             : }  // namespace v8

Generated by: LCOV version 1.10