LCOV - code coverage report
Current view: top level - src/snapshot - serializer.h (source / functions) Hit Total Coverage
Test: app.info Lines: 26 74 35.1 %
Date: 2017-10-20 Functions: 7 44 15.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             : #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/default-serializer-allocator.h"
      14             : #include "src/snapshot/serializer-common.h"
      15             : #include "src/snapshot/snapshot-source-sink.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20             : class CodeAddressMap : public CodeEventLogger {
      21             :  public:
      22         936 :   explicit CodeAddressMap(Isolate* isolate) : isolate_(isolate) {
      23         624 :     isolate->logger()->addCodeEventListener(this);
      24         312 :   }
      25             : 
      26         936 :   ~CodeAddressMap() override {
      27         312 :     isolate_->logger()->removeCodeEventListener(this);
      28         624 :   }
      29             : 
      30           0 :   void CodeMoveEvent(AbstractCode* from, Address to) override {
      31           0 :     address_to_name_map_.Move(from->address(), to);
      32           0 :   }
      33             : 
      34           0 :   void CodeDisableOptEvent(AbstractCode* code,
      35           0 :                            SharedFunctionInfo* shared) override {}
      36             : 
      37             :   const char* Lookup(Address address) {
      38     1348056 :     return address_to_name_map_.Lookup(address);
      39             :   }
      40             : 
      41             :  private:
      42             :   class NameMap {
      43             :    public:
      44             :     NameMap() : impl_() {}
      45             : 
      46         312 :     ~NameMap() {
      47         624 :       for (base::HashMap::Entry* p = impl_.Start(); p != nullptr;
      48             :            p = impl_.Next(p)) {
      49           0 :         DeleteArray(static_cast<const char*>(p->value));
      50             :       }
      51         312 :     }
      52             : 
      53           0 :     void Insert(Address code_address, const char* name, int name_size) {
      54           0 :       base::HashMap::Entry* entry = FindOrCreateEntry(code_address);
      55           0 :       if (entry->value == nullptr) {
      56           0 :         entry->value = CopyName(name, name_size);
      57             :       }
      58           0 :     }
      59             : 
      60             :     const char* Lookup(Address code_address) {
      61     1348056 :       base::HashMap::Entry* entry = FindEntry(code_address);
      62             :       return (entry != nullptr) ? static_cast<const char*>(entry->value)
      63     1348056 :                                 : nullptr;
      64             :     }
      65             : 
      66             :     void Remove(Address code_address) {
      67             :       base::HashMap::Entry* entry = FindEntry(code_address);
      68             :       if (entry != nullptr) {
      69             :         DeleteArray(static_cast<char*>(entry->value));
      70             :         RemoveEntry(entry);
      71             :       }
      72             :     }
      73             : 
      74           0 :     void Move(Address from, Address to) {
      75           0 :       if (from == to) return;
      76           0 :       base::HashMap::Entry* from_entry = FindEntry(from);
      77             :       DCHECK_NOT_NULL(from_entry);
      78           0 :       void* value = from_entry->value;
      79             :       RemoveEntry(from_entry);
      80           0 :       base::HashMap::Entry* to_entry = FindOrCreateEntry(to);
      81             :       DCHECK_NULL(to_entry->value);
      82           0 :       to_entry->value = value;
      83             :     }
      84             : 
      85             :    private:
      86           0 :     static char* CopyName(const char* name, int name_size) {
      87           0 :       char* result = NewArray<char>(name_size + 1);
      88           0 :       for (int i = 0; i < name_size; ++i) {
      89           0 :         char c = name[i];
      90           0 :         if (c == '\0') c = ' ';
      91           0 :         result[i] = c;
      92             :       }
      93           0 :       result[name_size] = '\0';
      94           0 :       return result;
      95             :     }
      96             : 
      97           0 :     base::HashMap::Entry* FindOrCreateEntry(Address code_address) {
      98             :       return impl_.LookupOrInsert(code_address,
      99           0 :                                   ComputePointerHash(code_address));
     100             :     }
     101             : 
     102     1348056 :     base::HashMap::Entry* FindEntry(Address code_address) {
     103     1348056 :       return impl_.Lookup(code_address, ComputePointerHash(code_address));
     104             :     }
     105             : 
     106             :     void RemoveEntry(base::HashMap::Entry* entry) {
     107           0 :       impl_.Remove(entry->key, entry->hash);
     108             :     }
     109             : 
     110             :     base::HashMap impl_;
     111             : 
     112             :     DISALLOW_COPY_AND_ASSIGN(NameMap);
     113             :   };
     114             : 
     115           0 :   void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*,
     116             :                          const char* name, int length) override {
     117           0 :     address_to_name_map_.Insert(code->address(), name, length);
     118           0 :   }
     119             : 
     120             :   NameMap address_to_name_map_;
     121             :   Isolate* isolate_;
     122             : };
     123             : 
     124             : template <class AllocatorT = DefaultSerializerAllocator>
     125             : class Serializer : public SerializerDeserializer {
     126             :  public:
     127             :   explicit Serializer(Isolate* isolate);
     128             :   ~Serializer() override;
     129             : 
     130           0 :   std::vector<SerializedData::Reservation> EncodeReservations() const {
     131         891 :     return allocator_.EncodeReservations();
     132             :   }
     133             : 
     134           0 :   const std::vector<byte>* Payload() const { return sink_.data(); }
     135             : 
     136           0 :   bool ReferenceMapContains(HeapObject* o) {
     137           0 :     return reference_map()->Lookup(o).is_valid();
     138             :   }
     139             : 
     140       15193 :   Isolate* isolate() const { return isolate_; }
     141             : 
     142             :  protected:
     143             :   class ObjectSerializer;
     144             :   class RecursionScope {
     145             :    public:
     146           0 :     explicit RecursionScope(Serializer* serializer) : serializer_(serializer) {
     147     1511422 :       serializer_->recursion_depth_++;
     148           0 :     }
     149     1511422 :     ~RecursionScope() { serializer_->recursion_depth_--; }
     150           0 :     bool ExceedsMaximum() {
     151           0 :       return serializer_->recursion_depth_ >= kMaxRecursionDepth;
     152             :     }
     153             : 
     154             :    private:
     155             :     static const int kMaxRecursionDepth = 32;
     156             :     Serializer* serializer_;
     157             :   };
     158             : 
     159             :   void SerializeDeferredObjects();
     160             :   virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
     161             :                                WhereToPoint where_to_point, int skip) = 0;
     162             : 
     163             :   virtual bool MustBeDeferred(HeapObject* object);
     164             : 
     165             :   void VisitRootPointers(Root root, Object** start, Object** end) override;
     166             : 
     167             :   void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
     168             :                int skip);
     169             :   void PutSmi(Smi* smi);
     170             :   void PutBackReference(HeapObject* object, SerializerReference reference);
     171             :   void PutAttachedReference(SerializerReference reference,
     172             :                             HowToCode how_to_code, WhereToPoint where_to_point);
     173             :   // Emit alignment prefix if necessary, return required padding space in bytes.
     174             :   int PutAlignmentPrefix(HeapObject* object);
     175             :   void PutNextChunk(int space);
     176             : 
     177             :   // Returns true if the object was successfully serialized as hot object.
     178             :   bool SerializeHotObject(HeapObject* obj, HowToCode how_to_code,
     179             :                           WhereToPoint where_to_point, int skip);
     180             : 
     181             :   // Returns true if the object was successfully serialized as back reference.
     182             :   bool SerializeBackReference(HeapObject* obj, HowToCode how_to_code,
     183             :                               WhereToPoint where_to_point, int skip);
     184             : 
     185             :   // Determines whether the interpreter trampoline is replaced by CompileLazy.
     186             :   enum BuiltinReferenceSerializationMode {
     187             :     kDefault,
     188             :     kCanonicalizeCompileLazy,
     189             :   };
     190             : 
     191             :   // Returns true if the object was successfully serialized as a builtin
     192             :   // reference.
     193             :   bool SerializeBuiltinReference(
     194             :       HeapObject* obj, HowToCode how_to_code, WhereToPoint where_to_point,
     195             :       int skip, BuiltinReferenceSerializationMode mode = kDefault);
     196             : 
     197     3611691 :   inline void FlushSkip(int skip) {
     198     3611691 :     if (skip != 0) {
     199             :       sink_.Put(kSkip, "SkipFromSerializeObject");
     200      974678 :       sink_.PutInt(skip, "SkipDistanceFromSerializeObject");
     201             :     }
     202     3611691 :   }
     203             : 
     204           0 :   ExternalReferenceEncoder::Value EncodeExternalReference(Address addr) {
     205      845893 :     return external_reference_encoder_.Encode(addr);
     206             :   }
     207             : 
     208             :   // GetInt reads 4 bytes at once, requiring padding at the end.
     209             :   void Pad();
     210             : 
     211             :   // We may not need the code address map for logging for every instance
     212             :   // of the serializer.  Initialize it on demand.
     213             :   void InitializeCodeAddressMap();
     214             : 
     215             :   Code* CopyCode(Code* code);
     216             : 
     217           0 :   void QueueDeferredObject(HeapObject* obj) {
     218             :     DCHECK(reference_map_.Lookup(obj).is_back_reference());
     219        3628 :     deferred_objects_.push_back(obj);
     220           0 :   }
     221             : 
     222             :   void OutputStatistics(const char* name);
     223             : 
     224             : #ifdef OBJECT_PRINT
     225             :   void CountInstanceType(Map* map, int size);
     226             : #endif  // OBJECT_PRINT
     227             : 
     228             : #ifdef DEBUG
     229             :   void PushStack(HeapObject* o) { stack_.push_back(o); }
     230             :   void PopStack() { stack_.pop_back(); }
     231             :   void PrintStack();
     232             : #endif  // DEBUG
     233             : 
     234           0 :   SerializerReferenceMap* reference_map() { return &reference_map_; }
     235           0 :   RootIndexMap* root_index_map() { return &root_index_map_; }
     236           0 :   AllocatorT* allocator() { return &allocator_; }
     237             : 
     238             :   SnapshotByteSink sink_;  // Used directly by subclasses.
     239             : 
     240             :  private:
     241             :   Isolate* isolate_;
     242             :   SerializerReferenceMap reference_map_;
     243             :   ExternalReferenceEncoder external_reference_encoder_;
     244             :   RootIndexMap root_index_map_;
     245             :   CodeAddressMap* code_address_map_ = nullptr;
     246             :   std::vector<byte> code_buffer_;
     247             :   std::vector<HeapObject*> deferred_objects_;  // To handle stack overflow.
     248             :   int recursion_depth_ = 0;
     249             :   AllocatorT allocator_;
     250             : 
     251             : #ifdef OBJECT_PRINT
     252             :   static const int kInstanceTypes = 256;
     253             :   int* instance_type_count_;
     254             :   size_t* instance_type_size_;
     255             : #endif  // OBJECT_PRINT
     256             : 
     257             : #ifdef DEBUG
     258             :   std::vector<HeapObject*> stack_;
     259             : #endif  // DEBUG
     260             : 
     261             :   friend class DefaultSerializerAllocator;
     262             : 
     263             :   DISALLOW_COPY_AND_ASSIGN(Serializer);
     264             : };
     265             : 
     266             : template <class AllocatorT>
     267             : class Serializer<AllocatorT>::ObjectSerializer : public ObjectVisitor {
     268             :  public:
     269           0 :   ObjectSerializer(Serializer* serializer, HeapObject* obj,
     270             :                    SnapshotByteSink* sink, HowToCode how_to_code,
     271             :                    WhereToPoint where_to_point)
     272             :       : serializer_(serializer),
     273             :         object_(obj),
     274             :         sink_(sink),
     275             :         reference_representation_(how_to_code + where_to_point),
     276     3030150 :         bytes_processed_so_far_(0) {
     277             : #ifdef DEBUG
     278             :     serializer_->PushStack(obj);
     279             : #endif  // DEBUG
     280           0 :   }
     281           0 :   ~ObjectSerializer() override {
     282             : #ifdef DEBUG
     283             :     serializer_->PopStack();
     284             : #endif  // DEBUG
     285     1515075 :   }
     286             :   void Serialize();
     287             :   void SerializeObject();
     288             :   void SerializeDeferred();
     289             :   void VisitPointers(HeapObject* host, Object** start, Object** end) override;
     290             :   void VisitEmbeddedPointer(Code* host, RelocInfo* target) override;
     291             :   void VisitExternalReference(Foreign* host, Address* p) override;
     292             :   void VisitExternalReference(Code* host, RelocInfo* rinfo) override;
     293             :   void VisitInternalReference(Code* host, RelocInfo* rinfo) override;
     294             :   void VisitCodeTarget(Code* host, RelocInfo* target) override;
     295             :   void VisitRuntimeEntry(Code* host, RelocInfo* reloc) override;
     296             : 
     297             :  private:
     298             :   void SerializePrologue(AllocationSpace space, int size, Map* map);
     299             : 
     300             :   // This function outputs or skips the raw data between the last pointer and
     301             :   // up to the current position.
     302             :   void SerializeContent(Map* map, int size);
     303             :   void OutputRawData(Address up_to);
     304             :   void OutputCode(int size);
     305             :   int SkipTo(Address to);
     306             :   int32_t SerializeBackingStore(void* backing_store, int32_t byte_length);
     307             :   void FixupIfNeutered();
     308             :   void SerializeJSArrayBuffer();
     309             :   void SerializeFixedTypedArray();
     310             :   void SerializeExternalString();
     311             :   void SerializeExternalStringAsSequentialString();
     312             : 
     313             :   Serializer* serializer_;
     314             :   HeapObject* object_;
     315             :   SnapshotByteSink* sink_;
     316             :   std::map<void*, Smi*> backing_stores;
     317             :   int reference_representation_;
     318             :   int bytes_processed_so_far_;
     319             : };
     320             : 
     321             : }  // namespace internal
     322             : }  // namespace v8
     323             : 
     324             : #endif  // V8_SNAPSHOT_SERIALIZER_H_

Generated by: LCOV version 1.10