LCOV - code coverage report
Current view: top level - src/snapshot - serializer-common.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 40 51 78.4 %
Date: 2019-04-17 Functions: 10 11 90.9 %

          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             : #include "src/objects/foreign-inl.h"
      10             : #include "src/objects/slots.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15      768617 : ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
      16             : #ifdef DEBUG
      17             :   api_references_ = isolate->api_external_references();
      18             :   if (api_references_ != nullptr) {
      19             :     for (uint32_t i = 0; api_references_[i] != 0; ++i) count_.push_back(0);
      20             :   }
      21             : #endif  // DEBUG
      22      768617 :   map_ = isolate->external_reference_map();
      23      768617 :   if (map_ != nullptr) return;
      24        1028 :   map_ = new AddressToIndexHashMap();
      25             :   isolate->set_external_reference_map(map_);
      26             :   // Add V8's external references.
      27             :   ExternalReferenceTable* table = isolate->external_reference_table();
      28      977114 :   for (uint32_t i = 0; i < ExternalReferenceTable::kSize; ++i) {
      29             :     Address addr = table->address(i);
      30             :     // Ignore duplicate references.
      31             :     // This can happen due to ICF. See http://crbug.com/726896.
      32      976600 :     if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, false));
      33             :     DCHECK(map_->Get(addr).IsJust());
      34             :   }
      35             :   // Add external references provided by the embedder.
      36             :   const intptr_t* api_references = isolate->api_external_references();
      37         514 :   if (api_references == nullptr) return;
      38         375 :   for (uint32_t i = 0; api_references[i] != 0; ++i) {
      39         175 :     Address addr = static_cast<Address>(api_references[i]);
      40             :     // Ignore duplicate references.
      41             :     // This can happen due to ICF. See http://crbug.com/726896.
      42         500 :     if (map_->Get(addr).IsNothing()) map_->Set(addr, Value::Encode(i, true));
      43             :     DCHECK(map_->Get(addr).IsJust());
      44             :   }
      45             : }
      46             : 
      47      768617 : ExternalReferenceEncoder::~ExternalReferenceEncoder() {
      48             : #ifdef DEBUG
      49             :   if (!i::FLAG_external_reference_stats) return;
      50             :   if (api_references_ == nullptr) return;
      51             :   for (uint32_t i = 0; api_references_[i] != 0; ++i) {
      52             :     Address addr = static_cast<Address>(api_references_[i]);
      53             :     DCHECK(map_->Get(addr).IsJust());
      54             :     v8::base::OS::Print(
      55             :         "index=%5d count=%5d  %-60s\n", i, count_[i],
      56             :         ExternalReferenceTable::ResolveSymbol(reinterpret_cast<void*>(addr)));
      57             :   }
      58             : #endif  // DEBUG
      59      768617 : }
      60             : 
      61          30 : Maybe<ExternalReferenceEncoder::Value> ExternalReferenceEncoder::TryEncode(
      62             :     Address address) {
      63          30 :   Maybe<uint32_t> maybe_index = map_->Get(address);
      64          30 :   if (maybe_index.IsNothing()) return Nothing<Value>();
      65             :   Value result(maybe_index.FromJust());
      66             : #ifdef DEBUG
      67             :   if (result.is_from_api()) count_[result.index()]++;
      68             : #endif  // DEBUG
      69             :   return Just<Value>(result);
      70             : }
      71             : 
      72      776306 : ExternalReferenceEncoder::Value ExternalReferenceEncoder::Encode(
      73             :     Address address) {
      74      776306 :   Maybe<uint32_t> maybe_index = map_->Get(address);
      75      776306 :   if (maybe_index.IsNothing()) {
      76           0 :     void* addr = reinterpret_cast<void*>(address);
      77           0 :     v8::base::OS::PrintError("Unknown external reference %p.\n", addr);
      78           0 :     v8::base::OS::PrintError("%s", ExternalReferenceTable::ResolveSymbol(addr));
      79           0 :     v8::base::OS::Abort();
      80             :   }
      81             :   Value result(maybe_index.FromJust());
      82             : #ifdef DEBUG
      83             :   if (result.is_from_api()) count_[result.index()]++;
      84             : #endif  // DEBUG
      85      776306 :   return result;
      86             : }
      87             : 
      88           0 : const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
      89             :                                                     Address address) const {
      90           0 :   Maybe<uint32_t> maybe_index = map_->Get(address);
      91           0 :   if (maybe_index.IsNothing()) return "<unknown>";
      92             :   Value value(maybe_index.FromJust());
      93           0 :   if (value.is_from_api()) return "<from api>";
      94           0 :   return isolate->external_reference_table()->name(value.index());
      95             : }
      96             : 
      97        1137 : void SerializedData::AllocateData(uint32_t size) {
      98             :   DCHECK(!owns_data_);
      99        1137 :   data_ = NewArray<byte>(size);
     100        1137 :   size_ = size;
     101        1137 :   owns_data_ = true;
     102             :   DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
     103        1137 : }
     104             : 
     105             : // static
     106             : constexpr uint32_t SerializedData::kMagicNumber;
     107             : 
     108             : // The partial snapshot cache is terminated by undefined. We visit the
     109             : // partial snapshot...
     110             : //  - during deserialization to populate it.
     111             : //  - during normal GC to keep its content alive.
     112             : //  - not during serialization. The partial serializer adds to it explicitly.
     113             : DISABLE_CFI_PERF
     114      290999 : void SerializerDeserializer::Iterate(Isolate* isolate, RootVisitor* visitor) {
     115             :   std::vector<Object>* cache = isolate->partial_snapshot_cache();
     116   436374884 :   for (size_t i = 0;; ++i) {
     117             :     // Extend the array ready to get a value when deserializing.
     118   436665883 :     if (cache->size() <= i) cache->push_back(Smi::kZero);
     119             :     // During deserialization, the visitor populates the partial snapshot cache
     120             :     // and eventually terminates the cache with undefined.
     121   436665884 :     visitor->VisitRootPointer(Root::kPartialSnapshotCache, nullptr,
     122   873331584 :                               FullObjectSlot(&cache->at(i)));
     123   436665884 :     if (cache->at(i)->IsUndefined(isolate)) break;
     124             :   }
     125      291000 : }
     126             : 
     127        3143 : bool SerializerDeserializer::CanBeDeferred(HeapObject o) {
     128        9429 :   return !o->IsString() && !o->IsScript() && !o->IsJSTypedArray();
     129             : }
     130             : 
     131       62631 : void SerializerDeserializer::RestoreExternalReferenceRedirectors(
     132             :     const std::vector<AccessorInfo>& accessor_infos) {
     133             :   // Restore wiped accessor infos.
     134       62631 :   for (AccessorInfo info : accessor_infos) {
     135             :     Foreign::cast(info->js_getter())
     136           0 :         ->set_foreign_address(info->redirected_getter());
     137             :   }
     138       62631 : }
     139             : 
     140       62631 : void SerializerDeserializer::RestoreExternalReferenceRedirectors(
     141             :     const std::vector<CallHandlerInfo>& call_handler_infos) {
     142       62631 :   for (CallHandlerInfo info : call_handler_infos) {
     143             :     Foreign::cast(info->js_callback())
     144           0 :         ->set_foreign_address(info->redirected_callback());
     145             :   }
     146       62631 : }
     147             : 
     148             : }  // namespace internal
     149      122004 : }  // namespace v8

Generated by: LCOV version 1.10