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