• 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/snapshot/serializer.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 class ScriptData {
14  public:
15   ScriptData(const byte* data, int length);
~ScriptData()16   ~ScriptData() {
17     if (owns_data_) DeleteArray(data_);
18   }
19 
data()20   const byte* data() const { return data_; }
length()21   int length() const { return length_; }
rejected()22   bool rejected() const { return rejected_; }
23 
Reject()24   void Reject() { rejected_ = true; }
25 
AcquireDataOwnership()26   void AcquireDataOwnership() {
27     DCHECK(!owns_data_);
28     owns_data_ = true;
29   }
30 
ReleaseDataOwnership()31   void ReleaseDataOwnership() {
32     DCHECK(owns_data_);
33     owns_data_ = false;
34   }
35 
36  private:
37   bool owns_data_ : 1;
38   bool rejected_ : 1;
39   const byte* data_;
40   int length_;
41 
42   DISALLOW_COPY_AND_ASSIGN(ScriptData);
43 };
44 
45 class CodeSerializer : public Serializer<> {
46  public:
47   static ScriptCompiler::CachedData* Serialize(Handle<SharedFunctionInfo> info);
48 
49   ScriptData* SerializeSharedFunctionInfo(Handle<SharedFunctionInfo> info);
50 
51   V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
52       Isolate* isolate, ScriptData* cached_data, Handle<String> source,
53       ScriptOriginOptions origin_options);
54 
stub_keys()55   const std::vector<uint32_t>* stub_keys() const { return &stub_keys_; }
56 
source_hash()57   uint32_t source_hash() const { return source_hash_; }
58 
59  protected:
60   CodeSerializer(Isolate* isolate, uint32_t source_hash);
~CodeSerializer()61   ~CodeSerializer() override { OutputStatistics("CodeSerializer"); }
62 
SerializeCodeObject(Code * code_object,HowToCode how_to_code,WhereToPoint where_to_point)63   virtual void SerializeCodeObject(Code* code_object, HowToCode how_to_code,
64                                    WhereToPoint where_to_point) {
65     UNREACHABLE();
66   }
67 
ElideObject(Object * obj)68   virtual bool ElideObject(Object* obj) { return false; }
69   void SerializeGeneric(HeapObject* heap_object, HowToCode how_to_code,
70                         WhereToPoint where_to_point);
71 
72  private:
73   void SerializeObject(HeapObject* o, HowToCode how_to_code,
74                        WhereToPoint where_to_point, int skip) override;
75 
76   void SerializeCodeStub(Code* code_stub, HowToCode how_to_code,
77                          WhereToPoint where_to_point);
78 
79   bool SerializeReadOnlyObject(HeapObject* obj, HowToCode how_to_code,
80                                WhereToPoint where_to_point, int skip);
81 
82   DisallowHeapAllocation no_gc_;
83   uint32_t source_hash_;
84   std::vector<uint32_t> stub_keys_;
85   DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
86 };
87 
88 // Wrapper around ScriptData to provide code-serializer-specific functionality.
89 class SerializedCodeData : public SerializedData {
90  public:
91   enum SanityCheckResult {
92     CHECK_SUCCESS = 0,
93     MAGIC_NUMBER_MISMATCH = 1,
94     VERSION_MISMATCH = 2,
95     SOURCE_MISMATCH = 3,
96     CPU_FEATURES_MISMATCH = 4,
97     FLAGS_MISMATCH = 5,
98     CHECKSUM_MISMATCH = 6,
99     INVALID_HEADER = 7,
100     LENGTH_MISMATCH = 8
101   };
102 
103   // The data header consists of uint32_t-sized entries:
104   // [0] magic number and (internally provided) external reference count
105   // [1] extra (API-provided) external reference count
106   // [2] version hash
107   // [3] source hash
108   // [4] cpu features
109   // [5] flag hash
110   // [6] number of code stub keys
111   // [7] number of reservation size entries
112   // [8] payload length
113   // [9] payload checksum part 1
114   // [10] payload checksum part 2
115   // ...  reservations
116   // ...  code stub keys
117   // ...  serialized payload
118   static const uint32_t kVersionHashOffset = kMagicNumberOffset + kUInt32Size;
119   static const uint32_t kSourceHashOffset = kVersionHashOffset + kUInt32Size;
120   static const uint32_t kCpuFeaturesOffset = kSourceHashOffset + kUInt32Size;
121   static const uint32_t kFlagHashOffset = kCpuFeaturesOffset + kUInt32Size;
122   static const uint32_t kNumReservationsOffset = kFlagHashOffset + kUInt32Size;
123   static const uint32_t kNumCodeStubKeysOffset =
124       kNumReservationsOffset + kUInt32Size;
125   static const uint32_t kPayloadLengthOffset =
126       kNumCodeStubKeysOffset + kUInt32Size;
127   static const uint32_t kChecksum1Offset = kPayloadLengthOffset + kUInt32Size;
128   static const uint32_t kChecksum2Offset = kChecksum1Offset + kUInt32Size;
129   static const uint32_t kUnalignedHeaderSize = kChecksum2Offset + kUInt32Size;
130   static const uint32_t kHeaderSize = POINTER_SIZE_ALIGN(kUnalignedHeaderSize);
131 
132   // Used when consuming.
133   static SerializedCodeData FromCachedData(Isolate* isolate,
134                                            ScriptData* cached_data,
135                                            uint32_t expected_source_hash,
136                                            SanityCheckResult* rejection_result);
137 
138   // Used when producing.
139   SerializedCodeData(const std::vector<byte>* payload,
140                      const CodeSerializer* cs);
141 
142   // Return ScriptData object and relinquish ownership over it to the caller.
143   ScriptData* GetScriptData();
144 
145   std::vector<Reservation> Reservations() const;
146   Vector<const byte> Payload() const;
147 
148   Vector<const uint32_t> CodeStubKeys() const;
149 
150   static uint32_t SourceHash(Handle<String> source,
151                              ScriptOriginOptions origin_options);
152 
153  private:
154   explicit SerializedCodeData(ScriptData* data);
SerializedCodeData(const byte * data,int size)155   SerializedCodeData(const byte* data, int size)
156       : SerializedData(const_cast<byte*>(data), size) {}
157 
DataWithoutHeader()158   Vector<const byte> DataWithoutHeader() const {
159     return Vector<const byte>(data_ + kHeaderSize, size_ - kHeaderSize);
160   }
161 
162   SanityCheckResult SanityCheck(Isolate* isolate,
163                                 uint32_t expected_source_hash) const;
164 };
165 
166 }  // namespace internal
167 }  // namespace v8
168 
169 #endif  // V8_SNAPSHOT_CODE_SERIALIZER_H_
170