• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CODE_SERIALIZER_H_
6 #define V8_SNAPSHOT_CODE_SERIALIZER_H_
7 
8 #include "src/base/macros.h"
9 #include "src/snapshot/serializer.h"
10 #include "src/snapshot/snapshot-data.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 class PersistentHandles;
16 
17 class V8_EXPORT_PRIVATE AlignedCachedData {
18  public:
19   AlignedCachedData(const byte* data, int length);
~AlignedCachedData()20   ~AlignedCachedData() {
21     if (owns_data_) DeleteArray(data_);
22   }
23   AlignedCachedData(const AlignedCachedData&) = delete;
24   AlignedCachedData& operator=(const AlignedCachedData&) = delete;
25 
data()26   const byte* data() const { return data_; }
length()27   int length() const { return length_; }
rejected()28   bool rejected() const { return rejected_; }
29 
Reject()30   void Reject() { rejected_ = true; }
31 
HasDataOwnership()32   bool HasDataOwnership() const { return owns_data_; }
33 
AcquireDataOwnership()34   void AcquireDataOwnership() {
35     DCHECK(!owns_data_);
36     owns_data_ = true;
37   }
38 
ReleaseDataOwnership()39   void ReleaseDataOwnership() {
40     DCHECK(owns_data_);
41     owns_data_ = false;
42   }
43 
44  private:
45   bool owns_data_ : 1;
46   bool rejected_ : 1;
47   const byte* data_;
48   int length_;
49 };
50 
51 enum class SerializedCodeSanityCheckResult {
52   kSuccess = 0,
53   kMagicNumberMismatch = 1,
54   kVersionMismatch = 2,
55   kSourceMismatch = 3,
56   kFlagsMismatch = 5,
57   kChecksumMismatch = 6,
58   kInvalidHeader = 7,
59   kLengthMismatch = 8
60 };
61 
62 class CodeSerializer : public Serializer {
63  public:
64   struct OffThreadDeserializeData {
65    private:
66     friend class CodeSerializer;
67     MaybeHandle<SharedFunctionInfo> maybe_result;
68     std::vector<Handle<Script>> scripts;
69     std::unique_ptr<PersistentHandles> persistent_handles;
70     SerializedCodeSanityCheckResult sanity_check_result;
71   };
72 
73   CodeSerializer(const CodeSerializer&) = delete;
74   CodeSerializer& operator=(const CodeSerializer&) = delete;
75   V8_EXPORT_PRIVATE static ScriptCompiler::CachedData* Serialize(
76       Handle<SharedFunctionInfo> info);
77 
78   AlignedCachedData* SerializeSharedFunctionInfo(
79       Handle<SharedFunctionInfo> info);
80 
81   V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
82       Isolate* isolate, AlignedCachedData* cached_data, Handle<String> source,
83       ScriptOriginOptions origin_options);
84 
85   V8_WARN_UNUSED_RESULT static OffThreadDeserializeData
86   StartDeserializeOffThread(LocalIsolate* isolate,
87                             AlignedCachedData* cached_data);
88 
89   V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo>
90   FinishOffThreadDeserialize(Isolate* isolate, OffThreadDeserializeData&& data,
91                              AlignedCachedData* cached_data,
92                              Handle<String> source,
93                              ScriptOriginOptions origin_options);
94 
source_hash()95   uint32_t source_hash() const { return source_hash_; }
96 
97  protected:
98   CodeSerializer(Isolate* isolate, uint32_t source_hash);
~CodeSerializer()99   ~CodeSerializer() override { OutputStatistics("CodeSerializer"); }
100 
ElideObject(Object obj)101   virtual bool ElideObject(Object obj) { return false; }
102   void SerializeGeneric(Handle<HeapObject> heap_object);
103 
104  private:
105   void SerializeObjectImpl(Handle<HeapObject> o) override;
106 
107   bool SerializeReadOnlyObject(HeapObject obj,
108                                const DisallowGarbageCollection& no_gc);
109 
110   DISALLOW_GARBAGE_COLLECTION(no_gc_)
111   uint32_t source_hash_;
112 };
113 
114 // Wrapper around ScriptData to provide code-serializer-specific functionality.
115 class SerializedCodeData : public SerializedData {
116  public:
117   // The data header consists of uint32_t-sized entries:
118   // [0] magic number and (internally provided) external reference count
119   // [1] version hash
120   // [2] source hash
121   // [3] flag hash
122   // [4] payload length
123   // [5] payload checksum
124   // ...  serialized payload
125   static const uint32_t kVersionHashOffset = kMagicNumberOffset + kUInt32Size;
126   static const uint32_t kSourceHashOffset = kVersionHashOffset + kUInt32Size;
127   static const uint32_t kFlagHashOffset = kSourceHashOffset + kUInt32Size;
128   static const uint32_t kPayloadLengthOffset = kFlagHashOffset + kUInt32Size;
129   static const uint32_t kChecksumOffset = kPayloadLengthOffset + kUInt32Size;
130   static const uint32_t kUnalignedHeaderSize = kChecksumOffset + kUInt32Size;
131   static const uint32_t kHeaderSize = POINTER_SIZE_ALIGN(kUnalignedHeaderSize);
132 
133   // Used when consuming.
134   static SerializedCodeData FromCachedData(
135       AlignedCachedData* cached_data, uint32_t expected_source_hash,
136       SerializedCodeSanityCheckResult* rejection_result);
137   // For cached data which is consumed before the source is available (e.g.
138   // off-thread).
139   static SerializedCodeData FromCachedDataWithoutSource(
140       AlignedCachedData* cached_data,
141       SerializedCodeSanityCheckResult* rejection_result);
142   // For cached data which was previously already sanity checked by
143   // FromCachedDataWithoutSource. The rejection result from that call should be
144   // passed into this one.
145   static SerializedCodeData FromPartiallySanityCheckedCachedData(
146       AlignedCachedData* cached_data, uint32_t expected_source_hash,
147       SerializedCodeSanityCheckResult* rejection_result);
148 
149   // Used when producing.
150   SerializedCodeData(const std::vector<byte>* payload,
151                      const CodeSerializer* cs);
152 
153   // Return ScriptData object and relinquish ownership over it to the caller.
154   AlignedCachedData* GetScriptData();
155 
156   base::Vector<const byte> Payload() const;
157 
158   static uint32_t SourceHash(Handle<String> source,
159                              ScriptOriginOptions origin_options);
160 
161  private:
162   explicit SerializedCodeData(AlignedCachedData* data);
163   SerializedCodeData(const byte* data, int size)
164       : SerializedData(const_cast<byte*>(data), size) {}
165 
166   base::Vector<const byte> ChecksummedContent() const {
167     return base::Vector<const byte>(data_ + kHeaderSize, size_ - kHeaderSize);
168   }
169 
170   SerializedCodeSanityCheckResult SanityCheck(
171       uint32_t expected_source_hash) const;
172   SerializedCodeSanityCheckResult SanityCheckJustSource(
173       uint32_t expected_source_hash) const;
174   SerializedCodeSanityCheckResult SanityCheckWithoutSource() const;
175 };
176 
177 }  // namespace internal
178 }  // namespace v8
179 
180 #endif  // V8_SNAPSHOT_CODE_SERIALIZER_H_
181