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: 66 void SerializeCodeObject(Code* code_object, HowToCode how_to_code, 67 WhereToPoint where_to_point) override; 68 bool ElideObject(Object* obj) override; 69 70 private: 71 WasmCompiledModuleSerializer(Isolate* isolate, uint32_t source_hash, 72 Handle<Context> native_context, 73 Handle<SeqOneByteString> module_bytes); 74 DISALLOW_COPY_AND_ASSIGN(WasmCompiledModuleSerializer); 75 }; 76 77 // Wrapper around ScriptData to provide code-serializer-specific functionality. 78 class SerializedCodeData : public SerializedData { 79 public: 80 enum SanityCheckResult { 81 CHECK_SUCCESS = 0, 82 MAGIC_NUMBER_MISMATCH = 1, 83 VERSION_MISMATCH = 2, 84 SOURCE_MISMATCH = 3, 85 CPU_FEATURES_MISMATCH = 4, 86 FLAGS_MISMATCH = 5, 87 CHECKSUM_MISMATCH = 6, 88 INVALID_HEADER = 7 89 }; 90 91 // The data header consists of uint32_t-sized entries: 92 // [0] magic number and external reference count 93 // [1] version hash 94 // [2] source hash 95 // [3] cpu features 96 // [4] flag hash 97 // [5] number of code stub keys 98 // [6] number of reservation size entries 99 // [7] payload length 100 // [8] payload checksum part 1 101 // [9] payload checksum part 2 102 // ... reservations 103 // ... code stub keys 104 // ... serialized payload 105 static const int kVersionHashOffset = kMagicNumberOffset + kInt32Size; 106 static const int kSourceHashOffset = kVersionHashOffset + kInt32Size; 107 static const int kCpuFeaturesOffset = kSourceHashOffset + kInt32Size; 108 static const int kFlagHashOffset = kCpuFeaturesOffset + kInt32Size; 109 static const int kNumReservationsOffset = kFlagHashOffset + kInt32Size; 110 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size; 111 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size; 112 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size; 113 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size; 114 static const int kHeaderSize = kChecksum2Offset + kInt32Size; 115 116 // Used when consuming. 117 static const SerializedCodeData FromCachedData( 118 Isolate* isolate, ScriptData* cached_data, uint32_t expected_source_hash, 119 SanityCheckResult* rejection_result); 120 121 // Used when producing. 122 SerializedCodeData(const List<byte>* payload, const CodeSerializer* cs); 123 124 // Return ScriptData object and relinquish ownership over it to the caller. 125 ScriptData* GetScriptData(); 126 127 Vector<const Reservation> Reservations() const; 128 Vector<const byte> Payload() const; 129 130 Vector<const uint32_t> CodeStubKeys() const; 131 132 static uint32_t SourceHash(Handle<String> source); 133 134 private: 135 explicit SerializedCodeData(ScriptData* data); SerializedCodeData(const byte * data,int size)136 SerializedCodeData(const byte* data, int size) 137 : SerializedData(const_cast<byte*>(data), size) {} 138 DataWithoutHeader()139 Vector<const byte> DataWithoutHeader() const { 140 return Vector<const byte>(data_ + kHeaderSize, size_ - kHeaderSize); 141 } 142 143 SanityCheckResult SanityCheck(Isolate* isolate, 144 uint32_t expected_source_hash) const; 145 }; 146 147 } // namespace internal 148 } // namespace v8 149 150 #endif // V8_SNAPSHOT_CODE_SERIALIZER_H_ 151