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