LCOV - code coverage report
Current view: top level - src/snapshot - serializer-common.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 35 43 81.4 %
Date: 2017-10-20 Functions: 7 8 87.5 %

          Line data    Source code
       1             : // Copyright 2016 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-common.h"
       6             : 
       7             : #include "src/external-reference-table.h"
       8             : #include "src/objects-inl.h"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : 
      13        1409 : ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
      14             : #ifdef DEBUG
      15             :   api_references_ = isolate->api_external_references();
      16             :   if (api_references_ != nullptr) {
      17             :     for (uint32_t i = 0; api_references_[i] != 0; ++i) count_.push_back(0);
      18             :   }
      19             : #endif  // DEBUG
      20         891 :   map_ = isolate->external_reference_map();
      21         891 :   if (map_ != nullptr) return;
      22        1036 :   map_ = new AddressToIndexHashMap();
      23             :   isolate->set_external_reference_map(map_);
      24             :   // Add V8's external references.
      25         518 :   ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
      26     1005956 :   for (uint32_t i = 0; i < table->size(); ++i) {
      27             :     Address addr = table->address(i);
      28             :     // Ignore duplicate references.
      29             :     // This can happen due to ICF. See http://crbug.com/726896.
      30      502460 :     if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, false));
      31             :     DCHECK(map_->Get(addr).IsJust());
      32             :   }
      33             :   // Add external references provided by the embedder.
      34             :   const intptr_t* api_references = isolate->api_external_references();
      35         518 :   if (api_references == nullptr) return;
      36         120 :   for (uint32_t i = 0; api_references[i] != 0; ++i) {
      37         120 :     Address addr = reinterpret_cast<Address>(api_references[i]);
      38             :     // Ignore duplicate references.
      39             :     // This can happen due to ICF. See http://crbug.com/726896.
      40         220 :     if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, true));
      41             :     DCHECK(map_->Get(addr).IsJust());
      42             :   }
      43             : }
      44             : 
      45         891 : ExternalReferenceEncoder::~ExternalReferenceEncoder() {
      46             : #ifdef DEBUG
      47             :   if (!i::FLAG_external_reference_stats) return;
      48             :   if (api_references_ == nullptr) return;
      49             :   for (uint32_t i = 0; api_references_[i] != 0; ++i) {
      50             :     Address addr = reinterpret_cast<Address>(api_references_[i]);
      51             :     DCHECK(map_->Get(addr).IsJust());
      52             :     v8::base::OS::Print("index=%5d count=%5d  %-60s\n", i, count_[i],
      53             :                         ExternalReferenceTable::ResolveSymbol(addr));
      54             :   }
      55             : #endif  // DEBUG
      56         891 : }
      57             : 
      58      845893 : ExternalReferenceEncoder::Value ExternalReferenceEncoder::Encode(
      59             :     Address address) {
      60      845893 :   Maybe<uint32_t> maybe_index = map_->Get(address);
      61      845893 :   if (maybe_index.IsNothing()) {
      62             :     void* addr = address;
      63           0 :     v8::base::OS::PrintError("Unknown external reference %p.\n", addr);
      64           0 :     v8::base::OS::PrintError("%s", ExternalReferenceTable::ResolveSymbol(addr));
      65           0 :     v8::base::OS::Abort();
      66             :   }
      67             :   Value result(maybe_index.FromJust());
      68             : #ifdef DEBUG
      69             :   if (result.is_from_api()) count_[result.index()]++;
      70             : #endif  // DEBUG
      71      845893 :   return result;
      72             : }
      73             : 
      74           0 : const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
      75             :                                                     Address address) const {
      76           0 :   Maybe<uint32_t> maybe_index = map_->Get(address);
      77           0 :   if (maybe_index.IsNothing()) return "<unknown>";
      78             :   return ExternalReferenceTable::instance(isolate)->name(
      79           0 :       maybe_index.FromJust());
      80             : }
      81             : 
      82         891 : void SerializedData::AllocateData(uint32_t size) {
      83             :   DCHECK(!owns_data_);
      84         891 :   data_ = NewArray<byte>(size);
      85         891 :   size_ = size;
      86         891 :   owns_data_ = true;
      87             :   DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
      88         891 : }
      89             : 
      90             : // The partial snapshot cache is terminated by undefined. We visit the
      91             : // partial snapshot...
      92             : //  - during deserialization to populate it.
      93             : //  - during normal GC to keep its content alive.
      94             : //  - not during serialization. The partial serializer adds to it explicitly.
      95             : DISABLE_CFI_PERF
      96      232096 : void SerializerDeserializer::Iterate(Isolate* isolate, RootVisitor* visitor) {
      97      232096 :   std::vector<Object*>* cache = isolate->partial_snapshot_cache();
      98   503217601 :   for (size_t i = 0;; ++i) {
      99             :     // Extend the array ready to get a value when deserializing.
     100   622698608 :     if (cache->size() <= i) cache->push_back(Smi::kZero);
     101             :     // During deserialization, the visitor populates the partial snapshot cache
     102             :     // and eventually terminates the cache with undefined.
     103  1006899156 :     visitor->VisitRootPointer(Root::kPartialSnapshotCache, &cache->at(i));
     104  1006899522 :     if (cache->at(i)->IsUndefined(isolate)) break;
     105   503217601 :   }
     106      232262 : }
     107             : 
     108        3145 : bool SerializerDeserializer::CanBeDeferred(HeapObject* o) {
     109        6290 :   return !o->IsString() && !o->IsScript();
     110             : }
     111             : 
     112       55129 : void SerializerDeserializer::RestoreExternalReferenceRedirectors(
     113             :     const std::vector<AccessorInfo*>& accessor_infos) {
     114             :   // Restore wiped accessor infos.
     115      110258 :   for (AccessorInfo* info : accessor_infos) {
     116             :     Foreign::cast(info->js_getter())
     117           0 :         ->set_foreign_address(info->redirected_getter());
     118             :   }
     119       55129 : }
     120             : 
     121             : }  // namespace internal
     122             : }  // namespace v8

Generated by: LCOV version 1.10