5 #ifndef V8_SNAPSHOT_EMBEDDED_FILE_WRITER_H_ 6 #define V8_SNAPSHOT_EMBEDDED_FILE_WRITER_H_ 11 #include "src/globals.h" 12 #include "src/snapshot/snapshot.h" 24 static constexpr
char kDefaultEmbeddedVariant[] =
"Default";
30 void SetFile(FILE* fp) { fp_ = fp; }
36 void AlignToCodeAlignment();
38 void DeclareUint32(
const char* name,
uint32_t value);
39 void DeclarePointerToSymbol(
const char* name,
const char* target);
41 void DeclareLabel(
const char* name);
43 void DeclareFunctionBegin(
const char* name);
44 void DeclareFunctionEnd(
const char* name);
47 int HexLiteral(uint64_t value);
49 void Comment(
const char*
string);
50 void Newline() { fprintf(fp_,
"\n"); }
55 int IndentedDataDirective(DataDirective directive);
57 FILE* fp()
const {
return fp_; }
60 void DeclareSymbolGlobal(
const char* name);
77 void SetEmbeddedFile(
const char* embedded_src_path) {
78 embedded_src_path_ = embedded_src_path;
81 void SetEmbeddedVariant(
const char* embedded_variant) {
82 embedded_variant_ = embedded_variant;
86 MaybeWriteEmbeddedFile(blob);
91 if (embedded_src_path_ ==
nullptr)
return;
93 FILE* fp = GetFileDescriptorOrDie(embedded_src_path_);
98 WriteFilePrologue(&writer);
99 WriteMetadataSection(&writer, blob);
100 WriteInstructionStreams(&writer, blob);
101 WriteFileEpilogue(&writer, blob);
106 static FILE* GetFileDescriptorOrDie(
const char* filename) {
107 FILE* fp = v8::base::OS::FOpen(filename,
"wb");
109 i::PrintF(
"Unable to open file \"%s\" for writing.\n", filename);
116 w->Comment(
"Autogenerated file. Do not edit.");
122 static constexpr
int kTemporaryStringLength = 256;
126 char embedded_blob_data_symbol[kTemporaryStringLength];
128 "v8_%s_embedded_blob_data_", embedded_variant_);
130 w->Comment(
"The embedded blob starts here. Metadata comes first, followed");
131 w->Comment(
"by builtin instruction streams.");
133 w->AlignToCodeAlignment();
134 w->DeclareLabel(embedded_blob_data_symbol);
136 WriteBinaryContentsAsInlineAssembly(w, blob->data(),
137 i::EmbeddedData::RawDataOffset());
142 const bool is_default_variant =
143 std::strcmp(embedded_variant_, kDefaultEmbeddedVariant) == 0;
145 for (
int i = 0;
i < i::Builtins::builtin_count;
i++) {
146 if (!blob->ContainsBuiltin(
i))
continue;
148 char builtin_symbol[kTemporaryStringLength];
149 if (is_default_variant) {
152 i::Builtins::name(
i));
155 embedded_variant_, i::Builtins::name(
i));
162 w->DeclareFunctionBegin(builtin_symbol);
163 WriteBinaryContentsAsInlineAssembly(
165 reinterpret_cast<const uint8_t*>(blob->InstructionStartOfBuiltin(
i)),
166 blob->PaddedInstructionSizeOfBuiltin(
i));
167 w->DeclareFunctionEnd(builtin_symbol);
175 char embedded_blob_data_symbol[kTemporaryStringLength];
177 "v8_%s_embedded_blob_data_", embedded_variant_);
179 char embedded_blob_symbol[kTemporaryStringLength];
180 i::SNPrintF(
i::Vector<char>(embedded_blob_symbol),
"v8_%s_embedded_blob_",
183 w->Comment(
"Pointer to the beginning of the embedded blob.");
185 w->DeclarePointerToSymbol(embedded_blob_symbol,
186 embedded_blob_data_symbol);
191 char embedded_blob_size_symbol[kTemporaryStringLength];
193 "v8_%s_embedded_blob_size_", embedded_variant_);
195 w->Comment(
"The size of the embedded blob in bytes.");
197 w->DeclareUint32(embedded_blob_size_symbol, blob->size());
204 #if defined(_MSC_VER) && !defined(__clang__) 205 #define V8_COMPILER_IS_MSVC 208 #ifdef V8_COMPILER_IS_MSVC 216 static constexpr DataDirective kByteChunkDirective = kQuad;
217 static constexpr
int kByteChunkSize = 8;
220 int current_line_length,
const uint8_t* data) {
221 const uint64_t* quad_ptr =
reinterpret_cast<const uint64_t*
>(data);
222 return current_line_length + w->HexLiteral(*quad_ptr);
224 #else // V8_COMPILER_IS_MSVC 225 static constexpr DataDirective kByteChunkDirective = kOcta;
226 static constexpr
int kByteChunkSize = 16;
229 int current_line_length,
const uint8_t* data) {
230 const uint64_t* quad_ptr1 =
reinterpret_cast<const uint64_t*
>(data);
231 const uint64_t* quad_ptr2 =
reinterpret_cast<const uint64_t*
>(data + 8);
233 #ifdef V8_TARGET_BIG_ENDIAN 234 uint64_t part1 = *quad_ptr1;
235 uint64_t part2 = *quad_ptr2;
237 uint64_t part1 = *quad_ptr2;
238 uint64_t part2 = *quad_ptr1;
239 #endif // V8_TARGET_BIG_ENDIAN 242 current_line_length +=
243 fprintf(w->fp(),
"0x%" PRIx64
"%016" PRIx64, part1, part2);
245 current_line_length += fprintf(w->fp(),
"0x%" PRIx64, part2);
247 return current_line_length;
249 #endif // V8_COMPILER_IS_MSVC 250 #undef V8_COMPILER_IS_MSVC 253 int current_line_length,
254 DataDirective directive) {
256 if (current_line_length == 0) {
257 printed_chars = w->IndentedDataDirective(directive);
258 DCHECK_LT(0, printed_chars);
260 printed_chars = fprintf(w->fp(),
",");
261 DCHECK_EQ(1, printed_chars);
263 return current_line_length + printed_chars;
267 int current_line_length,
int write_size) {
268 static const int kTextWidth = 100;
272 if (current_line_length + strlen(
",0x") + write_size * 2 > kTextWidth) {
273 fprintf(w->fp(),
"\n");
276 return current_line_length;
280 static void WriteBinaryContentsAsInlineAssembly(
283 int current_line_length = 0;
288 for (;
i <= size - kByteChunkSize;
i += kByteChunkSize) {
289 current_line_length = WriteDirectiveOrSeparator(w, current_line_length,
290 kByteChunkDirective);
291 current_line_length = WriteByteChunk(w, current_line_length, data +
i);
292 current_line_length =
293 WriteLineEndIfNeeded(w, current_line_length, kByteChunkSize);
295 if (current_line_length != 0) w->Newline();
296 current_line_length = 0;
299 for (;
i < size;
i++) {
300 current_line_length =
301 WriteDirectiveOrSeparator(w, current_line_length, kByte);
302 current_line_length += w->HexLiteral(data[
i]);
303 current_line_length = WriteLineEndIfNeeded(w, current_line_length, 1);
305 if (current_line_length != 0) w->Newline();
308 const char* embedded_src_path_ =
nullptr;
309 const char* embedded_variant_ = kDefaultEmbeddedVariant;
315 #endif // V8_SNAPSHOT_EMBEDDED_FILE_WRITER_H_