LCOV - code coverage report
Current view: top level - src/snapshot - serializer.h (source / functions) Hit Total Coverage
Test: app.info Lines: 35 70 50.0 %
Date: 2019-04-17 Functions: 6 16 37.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             : #ifndef V8_SNAPSHOT_SERIALIZER_H_
       6             : #define V8_SNAPSHOT_SERIALIZER_H_
       7             : 
       8             : #include <map>
       9             : 
      10             : #include "src/isolate.h"
      11             : #include "src/log.h"
      12             : #include "src/objects.h"
      13             : #include "src/snapshot/embedded-data.h"
      14             : #include "src/snapshot/serializer-allocator.h"
      15             : #include "src/snapshot/serializer-common.h"
      16             : #include "src/snapshot/snapshot-source-sink.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : 
      21             : class CodeAddressMap : public CodeEventLogger {
      22             :  public:
      23         502 :   explicit CodeAddressMap(Isolate* isolate) : CodeEventLogger(isolate) {
      24         502 :     isolate->logger()->AddCodeEventListener(this);
      25         502 :   }
      26             : 
      27        1506 :   ~CodeAddressMap() override {
      28         502 :     isolate_->logger()->RemoveCodeEventListener(this);
      29        1004 :   }
      30             : 
      31           0 :   void CodeMoveEvent(AbstractCode from, AbstractCode to) override {
      32           0 :     address_to_name_map_.Move(from->address(), to->address());
      33           0 :   }
      34             : 
      35           0 :   void CodeDisableOptEvent(AbstractCode code,
      36           0 :                            SharedFunctionInfo shared) override {}
      37             : 
      38             :   const char* Lookup(Address address) {
      39     1692088 :     return address_to_name_map_.Lookup(address);
      40             :   }
      41             : 
      42             :  private:
      43             :   class NameMap {
      44             :    public:
      45             :     NameMap() : impl_() {}
      46             : 
      47        1004 :     ~NameMap() {
      48         502 :       for (base::HashMap::Entry* p = impl_.Start(); p != nullptr;
      49             :            p = impl_.Next(p)) {
      50           0 :         DeleteArray(static_cast<const char*>(p->value));
      51             :       }
      52         502 :     }
      53             : 
      54           0 :     void Insert(Address code_address, const char* name, int name_size) {
      55           0 :       base::HashMap::Entry* entry = FindOrCreateEntry(code_address);
      56           0 :       if (entry->value == nullptr) {
      57           0 :         entry->value = CopyName(name, name_size);
      58             :       }
      59           0 :     }
      60             : 
      61             :     const char* Lookup(Address code_address) {
      62     1692088 :       base::HashMap::Entry* entry = FindEntry(code_address);
      63             :       return (entry != nullptr) ? static_cast<const char*>(entry->value)
      64     1692088 :                                 : nullptr;
      65             :     }
      66             : 
      67             :     void Remove(Address code_address) {
      68             :       base::HashMap::Entry* entry = FindEntry(code_address);
      69             :       if (entry != nullptr) {
      70             :         DeleteArray(static_cast<char*>(entry->value));
      71             :         RemoveEntry(entry);
      72             :       }
      73             :     }
      74             : 
      75           0 :     void Move(Address from, Address to) {
      76           0 :       if (from == to) return;
      77           0 :       base::HashMap::Entry* from_entry = FindEntry(from);
      78             :       DCHECK_NOT_NULL(from_entry);
      79           0 :       void* value = from_entry->value;
      80             :       RemoveEntry(from_entry);
      81           0 :       base::HashMap::Entry* to_entry = FindOrCreateEntry(to);
      82             :       DCHECK_NULL(to_entry->value);
      83           0 :       to_entry->value = value;
      84             :     }
      85             : 
      86             :    private:
      87           0 :     static char* CopyName(const char* name, int name_size) {
      88           0 :       char* result = NewArray<char>(name_size + 1);
      89           0 :       for (int i = 0; i < name_size; ++i) {
      90           0 :         char c = name[i];
      91           0 :         if (c == '\0') c = ' ';
      92           0 :         result[i] = c;
      93             :       }
      94           0 :       result[name_size] = '\0';
      95           0 :       return result;
      96             :     }
      97             : 
      98           0 :     base::HashMap::Entry* FindOrCreateEntry(Address code_address) {
      99           0 :       return impl_.LookupOrInsert(reinterpret_cast<void*>(code_address),
     100           0 :                                   ComputeAddressHash(code_address));
     101             :     }
     102             : 
     103     1692088 :     base::HashMap::Entry* FindEntry(Address code_address) {
     104     1692088 :       return impl_.Lookup(reinterpret_cast<void*>(code_address),
     105     1692088 :                           ComputeAddressHash(code_address));
     106             :     }
     107             : 
     108             :     void RemoveEntry(base::HashMap::Entry* entry) {
     109           0 :       impl_.Remove(entry->key, entry->hash);
     110             :     }
     111             : 
     112             :     base::HashMap impl_;
     113             : 
     114             :     DISALLOW_COPY_AND_ASSIGN(NameMap);
     115             :   };
     116             : 
     117           0 :   void LogRecordedBuffer(AbstractCode code, SharedFunctionInfo,
     118             :                          const char* name, int length) override {
     119           0 :     address_to_name_map_.Insert(code->address(), name, length);
     120           0 :   }
     121             : 
     122           0 :   void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
     123             :                          int length) override {
     124           0 :     UNREACHABLE();
     125             :   }
     126             : 
     127             :   NameMap address_to_name_map_;
     128             : };
     129             : 
     130         522 : class ObjectCacheIndexMap {
     131             :  public:
     132        1044 :   ObjectCacheIndexMap() : map_(), next_index_(0) {}
     133             : 
     134             :   // If |obj| is in the map, immediately return true.  Otherwise add it to the
     135             :   // map and return false. In either case set |*index_out| to the index
     136             :   // associated with the map.
     137      621700 :   bool LookupOrInsert(HeapObject obj, int* index_out) {
     138      621700 :     Maybe<uint32_t> maybe_index = map_.Get(obj);
     139      621700 :     if (maybe_index.IsJust()) {
     140      202965 :       *index_out = maybe_index.FromJust();
     141      202965 :       return true;
     142             :     }
     143      418735 :     *index_out = next_index_;
     144      418735 :     map_.Set(obj, next_index_++);
     145      418735 :     return false;
     146             :   }
     147             : 
     148             :  private:
     149             :   DisallowHeapAllocation no_allocation_;
     150             : 
     151             :   HeapObjectToIndexHashMap map_;
     152             :   int next_index_;
     153             : 
     154             :   DISALLOW_COPY_AND_ASSIGN(ObjectCacheIndexMap);
     155             : };
     156             : 
     157             : class Serializer : public SerializerDeserializer {
     158             :  public:
     159             :   explicit Serializer(Isolate* isolate);
     160             :   ~Serializer() override;
     161             : 
     162             :   std::vector<SerializedData::Reservation> EncodeReservations() const {
     163        1137 :     return allocator_.EncodeReservations();
     164             :   }
     165             : 
     166             :   const std::vector<byte>* Payload() const { return sink_.data(); }
     167             : 
     168             :   bool ReferenceMapContains(HeapObject o) {
     169             :     return reference_map()
     170             :         ->LookupReference(reinterpret_cast<void*>(o->ptr()))
     171             :         .is_valid();
     172             :   }
     173             : 
     174             :   Isolate* isolate() const { return isolate_; }
     175             : 
     176             :  protected:
     177             :   class ObjectSerializer;
     178             :   class RecursionScope {
     179             :    public:
     180             :     explicit RecursionScope(Serializer* serializer) : serializer_(serializer) {
     181     1927938 :       serializer_->recursion_depth_++;
     182             :     }
     183     1927938 :     ~RecursionScope() { serializer_->recursion_depth_--; }
     184             :     bool ExceedsMaximum() {
     185             :       return serializer_->recursion_depth_ >= kMaxRecursionDepth;
     186             :     }
     187             : 
     188             :    private:
     189             :     static const int kMaxRecursionDepth = 32;
     190             :     Serializer* serializer_;
     191             :   };
     192             : 
     193             :   void SerializeDeferredObjects();
     194             :   virtual void SerializeObject(HeapObject o) = 0;
     195             : 
     196             :   virtual bool MustBeDeferred(HeapObject object);
     197             : 
     198             :   void VisitRootPointers(Root root, const char* description,
     199             :                          FullObjectSlot start, FullObjectSlot end) override;
     200             :   void SerializeRootObject(Object object);
     201             : 
     202             :   void PutRoot(RootIndex root_index, HeapObject object);
     203             :   void PutSmi(Smi smi);
     204             :   void PutBackReference(HeapObject object, SerializerReference reference);
     205             :   void PutAttachedReference(SerializerReference reference);
     206             :   // Emit alignment prefix if necessary, return required padding space in bytes.
     207             :   int PutAlignmentPrefix(HeapObject object);
     208             :   void PutNextChunk(int space);
     209             :   void PutRepeat(int repeat_count);
     210             : 
     211             :   // Returns true if the object was successfully serialized as a root.
     212             :   bool SerializeRoot(HeapObject obj);
     213             : 
     214             :   // Returns true if the object was successfully serialized as hot object.
     215             :   bool SerializeHotObject(HeapObject obj);
     216             : 
     217             :   // Returns true if the object was successfully serialized as back reference.
     218             :   bool SerializeBackReference(HeapObject obj);
     219             : 
     220             :   // Returns true if the given heap object is a bytecode handler code object.
     221             :   bool ObjectIsBytecodeHandler(HeapObject obj) const;
     222             : 
     223             :   ExternalReferenceEncoder::Value EncodeExternalReference(Address addr) {
     224        8826 :     return external_reference_encoder_.Encode(addr);
     225             :   }
     226             : 
     227             :   // GetInt reads 4 bytes at once, requiring padding at the end.
     228             :   // Use padding_offset to specify the space you want to use after padding.
     229             :   void Pad(int padding_offset = 0);
     230             : 
     231             :   // We may not need the code address map for logging for every instance
     232             :   // of the serializer.  Initialize it on demand.
     233             :   void InitializeCodeAddressMap();
     234             : 
     235             :   Code CopyCode(Code code);
     236             : 
     237             :   void QueueDeferredObject(HeapObject obj) {
     238             :     DCHECK(reference_map_.LookupReference(reinterpret_cast<void*>(obj->ptr()))
     239             :                .is_back_reference());
     240        3926 :     deferred_objects_.push_back(obj);
     241             :   }
     242             : 
     243             :   void OutputStatistics(const char* name);
     244             : 
     245             : #ifdef OBJECT_PRINT
     246             :   void CountInstanceType(Map map, int size, AllocationSpace space);
     247             : #endif  // OBJECT_PRINT
     248             : 
     249             : #ifdef DEBUG
     250             :   void PushStack(HeapObject o) { stack_.push_back(o); }
     251             :   void PopStack() { stack_.pop_back(); }
     252             :   void PrintStack();
     253             : #endif  // DEBUG
     254             : 
     255        4422 :   SerializerReferenceMap* reference_map() { return &reference_map_; }
     256    13697504 :   const RootIndexMap* root_index_map() const { return &root_index_map_; }
     257     1928234 :   SerializerAllocator* allocator() { return &allocator_; }
     258             : 
     259             :   SnapshotByteSink sink_;  // Used directly by subclasses.
     260             : 
     261             :  private:
     262             :   Isolate* isolate_;
     263             :   SerializerReferenceMap reference_map_;
     264             :   ExternalReferenceEncoder external_reference_encoder_;
     265             :   RootIndexMap root_index_map_;
     266             :   CodeAddressMap* code_address_map_ = nullptr;
     267             :   std::vector<byte> code_buffer_;
     268             :   std::vector<HeapObject> deferred_objects_;  // To handle stack overflow.
     269             :   int recursion_depth_ = 0;
     270             :   SerializerAllocator allocator_;
     271             : 
     272             : #ifdef OBJECT_PRINT
     273             :   static const int kInstanceTypes = LAST_TYPE + 1;
     274             :   int* instance_type_count_[LAST_SPACE];
     275             :   size_t* instance_type_size_[LAST_SPACE];
     276             : #endif  // OBJECT_PRINT
     277             : 
     278             : #ifdef DEBUG
     279             :   std::vector<HeapObject> stack_;
     280             : #endif  // DEBUG
     281             : 
     282             :   friend class SerializerAllocator;
     283             : 
     284             :   DISALLOW_COPY_AND_ASSIGN(Serializer);
     285             : };
     286             : 
     287             : class RelocInfoIterator;
     288             : 
     289             : class Serializer::ObjectSerializer : public ObjectVisitor {
     290             :  public:
     291             :   ObjectSerializer(Serializer* serializer, HeapObject obj,
     292             :                    SnapshotByteSink* sink)
     293             :       : serializer_(serializer),
     294             :         object_(obj),
     295             :         sink_(sink),
     296     1931884 :         bytes_processed_so_far_(0) {
     297             : #ifdef DEBUG
     298             :     serializer_->PushStack(obj);
     299             : #endif  // DEBUG
     300             :   }
     301             :   // NOLINTNEXTLINE (modernize-use-equals-default)
     302     1935985 :   ~ObjectSerializer() override {
     303             : #ifdef DEBUG
     304             :     serializer_->PopStack();
     305             : #endif  // DEBUG
     306           0 :   }
     307             :   void Serialize();
     308             :   void SerializeObject();
     309             :   void SerializeDeferred();
     310             :   void VisitPointers(HeapObject host, ObjectSlot start,
     311             :                      ObjectSlot end) override;
     312             :   void VisitPointers(HeapObject host, MaybeObjectSlot start,
     313             :                      MaybeObjectSlot end) override;
     314             :   void VisitEmbeddedPointer(Code host, RelocInfo* target) override;
     315             :   void VisitExternalReference(Foreign host, Address* p) override;
     316             :   void VisitExternalReference(Code host, RelocInfo* rinfo) override;
     317             :   void VisitInternalReference(Code host, RelocInfo* rinfo) override;
     318             :   void VisitCodeTarget(Code host, RelocInfo* target) override;
     319             :   void VisitRuntimeEntry(Code host, RelocInfo* reloc) override;
     320             :   void VisitOffHeapTarget(Code host, RelocInfo* target) override;
     321             : 
     322             :  private:
     323             :   void SerializePrologue(AllocationSpace space, int size, Map map);
     324             : 
     325             :   // This function outputs or skips the raw data between the last pointer and
     326             :   // up to the current position.
     327             :   void SerializeContent(Map map, int size);
     328             :   void OutputRawData(Address up_to);
     329             :   void OutputCode(int size);
     330             :   int32_t SerializeBackingStore(void* backing_store, int32_t byte_length);
     331             :   void SerializeJSTypedArray();
     332             :   void SerializeJSArrayBuffer();
     333             :   void SerializeExternalString();
     334             :   void SerializeExternalStringAsSequentialString();
     335             : 
     336             :   Serializer* serializer_;
     337             :   HeapObject object_;
     338             :   SnapshotByteSink* sink_;
     339             :   int bytes_processed_so_far_;
     340             : };
     341             : 
     342             : }  // namespace internal
     343             : }  // namespace v8
     344             : 
     345             : #endif  // V8_SNAPSHOT_SERIALIZER_H_

Generated by: LCOV version 1.10