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