[mksnapshot] Refactor platform-specific WriteByteChunk
This moves the platform-specific WriteByteChunk (& friends) into platform-specific embedded file writers. Bug: v8:9103 Change-Id: I0113c90dbf661a39dabe62b420cf6a160ee1be1d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1631412 Auto-Submit: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Commit-Queue: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#61852}
This commit is contained in:
parent
8c5d0e65c8
commit
6cc1fffc51
@ -123,70 +123,6 @@ int WriteDirectiveOrSeparator(PlatformEmbeddedFileWriterBase* w,
|
||||
return current_line_length + printed_chars;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define V8_COMPILER_IS_MSVC
|
||||
#endif
|
||||
|
||||
// TODO(jgruber): Move these sections into platform-dependent file writers.
|
||||
|
||||
#if defined(V8_COMPILER_IS_MSVC)
|
||||
// Windows MASM doesn't have an .octa directive, use QWORDs instead.
|
||||
// Note: MASM *really* does not like large data streams. It takes over 5
|
||||
// minutes to assemble the ~350K lines of embedded.S produced when using
|
||||
// BYTE directives in a debug build. QWORD produces roughly 120KLOC and
|
||||
// reduces assembly time to ~40 seconds. Still terrible, but much better
|
||||
// than before. See also: https://crbug.com/v8/8475.
|
||||
static constexpr DataDirective kByteChunkDirective = kQuad;
|
||||
static constexpr int kByteChunkSize = 8;
|
||||
|
||||
int WriteByteChunk(PlatformEmbeddedFileWriterBase* w, int current_line_length,
|
||||
const uint8_t* data) {
|
||||
const uint64_t* quad_ptr = reinterpret_cast<const uint64_t*>(data);
|
||||
return current_line_length + w->HexLiteral(*quad_ptr);
|
||||
}
|
||||
|
||||
#elif defined(V8_OS_AIX)
|
||||
// PPC uses a fixed 4 byte instruction set, using .long
|
||||
// to prevent any unnecessary padding.
|
||||
static constexpr DataDirective kByteChunkDirective = kLong;
|
||||
static constexpr int kByteChunkSize = 4;
|
||||
|
||||
int WriteByteChunk(PlatformEmbeddedFileWriterBase* w, int current_line_length,
|
||||
const uint8_t* data) {
|
||||
const uint32_t* long_ptr = reinterpret_cast<const uint32_t*>(data);
|
||||
return current_line_length + w->HexLiteral(*long_ptr);
|
||||
}
|
||||
|
||||
#else // defined(V8_COMPILER_IS_MSVC) || defined(V8_OS_AIX)
|
||||
static constexpr DataDirective kByteChunkDirective = kOcta;
|
||||
static constexpr int kByteChunkSize = 16;
|
||||
|
||||
int WriteByteChunk(PlatformEmbeddedFileWriterBase* w, int current_line_length,
|
||||
const uint8_t* data) {
|
||||
const size_t size = kInt64Size;
|
||||
|
||||
uint64_t part1, part2;
|
||||
// Use memcpy for the reads since {data} is not guaranteed to be aligned.
|
||||
#ifdef V8_TARGET_BIG_ENDIAN
|
||||
memcpy(&part1, data, size);
|
||||
memcpy(&part2, data + size, size);
|
||||
#else
|
||||
memcpy(&part1, data + size, size);
|
||||
memcpy(&part2, data, size);
|
||||
#endif // V8_TARGET_BIG_ENDIAN
|
||||
|
||||
if (part1 != 0) {
|
||||
current_line_length +=
|
||||
fprintf(w->fp(), "0x%" PRIx64 "%016" PRIx64, part1, part2);
|
||||
} else {
|
||||
current_line_length += fprintf(w->fp(), "0x%" PRIx64, part2);
|
||||
}
|
||||
return current_line_length;
|
||||
}
|
||||
#endif // defined(V8_COMPILER_IS_MSVC) || defined(V8_OS_AIX)
|
||||
|
||||
#undef V8_COMPILER_IS_MSVC
|
||||
|
||||
int WriteLineEndIfNeeded(PlatformEmbeddedFileWriterBase* w,
|
||||
int current_line_length, int write_size) {
|
||||
static const int kTextWidth = 100;
|
||||
@ -210,12 +146,14 @@ void EmbeddedFileWriter::WriteBinaryContentsAsInlineAssembly(
|
||||
uint32_t i = 0;
|
||||
|
||||
// Begin by writing out byte chunks.
|
||||
for (; i + kByteChunkSize < size; i += kByteChunkSize) {
|
||||
const DataDirective directive = w->ByteChunkDataDirective();
|
||||
const int byte_chunk_size = DataDirectiveSize(directive);
|
||||
for (; i + byte_chunk_size < size; i += byte_chunk_size) {
|
||||
current_line_length =
|
||||
WriteDirectiveOrSeparator(w, current_line_length, kByteChunkDirective);
|
||||
current_line_length = WriteByteChunk(w, current_line_length, data + i);
|
||||
WriteDirectiveOrSeparator(w, current_line_length, directive);
|
||||
current_line_length += w->WriteByteChunk(data + i);
|
||||
current_line_length =
|
||||
WriteLineEndIfNeeded(w, current_line_length, kByteChunkSize);
|
||||
WriteLineEndIfNeeded(w, current_line_length, byte_chunk_size);
|
||||
}
|
||||
if (current_line_length != 0) w->Newline();
|
||||
current_line_length = 0;
|
||||
|
@ -114,6 +114,18 @@ int PlatformEmbeddedFileWriterAIX::IndentedDataDirective(
|
||||
return fprintf(fp_, " %s ", DirectiveAsString(directive));
|
||||
}
|
||||
|
||||
DataDirective PlatformEmbeddedFileWriterAIX::ByteChunkDataDirective() const {
|
||||
// PPC uses a fixed 4 byte instruction set, using .long
|
||||
// to prevent any unnecessary padding.
|
||||
return kLong;
|
||||
}
|
||||
|
||||
int PlatformEmbeddedFileWriterAIX::WriteByteChunk(const uint8_t* data) {
|
||||
DCHECK_EQ(ByteChunkDataDirective(), kLong);
|
||||
const uint32_t* long_ptr = reinterpret_cast<const uint32_t*>(data);
|
||||
return HexLiteral(*long_ptr);
|
||||
}
|
||||
|
||||
#undef SYMBOL_PREFIX
|
||||
|
||||
} // namespace internal
|
||||
|
@ -47,6 +47,9 @@ class PlatformEmbeddedFileWriterAIX : public PlatformEmbeddedFileWriterBase {
|
||||
|
||||
int IndentedDataDirective(DataDirective directive) override;
|
||||
|
||||
DataDirective ByteChunkDataDirective() const override;
|
||||
int WriteByteChunk(const uint8_t* data) override;
|
||||
|
||||
private:
|
||||
void DeclareSymbolGlobal(const char* name);
|
||||
|
||||
|
@ -24,6 +24,42 @@ DataDirective PointerSizeDirective() {
|
||||
}
|
||||
}
|
||||
|
||||
int DataDirectiveSize(DataDirective directive) {
|
||||
switch (directive) {
|
||||
case kByte:
|
||||
return 1;
|
||||
case kLong:
|
||||
return 4;
|
||||
case kQuad:
|
||||
return 8;
|
||||
case kOcta:
|
||||
return 16;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
int PlatformEmbeddedFileWriterBase::WriteByteChunk(const uint8_t* data) {
|
||||
DCHECK_EQ(ByteChunkDataDirective(), kOcta);
|
||||
|
||||
static constexpr size_t kSize = kInt64Size;
|
||||
|
||||
uint64_t part1, part2;
|
||||
// Use memcpy for the reads since {data} is not guaranteed to be aligned.
|
||||
#ifdef V8_TARGET_BIG_ENDIAN
|
||||
memcpy(&part1, data, kSize);
|
||||
memcpy(&part2, data + kSize, kSize);
|
||||
#else
|
||||
memcpy(&part1, data + kSize, kSize);
|
||||
memcpy(&part2, data, kSize);
|
||||
#endif // V8_TARGET_BIG_ENDIAN
|
||||
|
||||
if (part1 != 0) {
|
||||
return fprintf(fp(), "0x%" PRIx64 "%016" PRIx64, part1, part2);
|
||||
} else {
|
||||
return fprintf(fp(), "0x%" PRIx64, part2);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
EmbeddedTargetArch DefaultEmbeddedTargetArch() {
|
||||
|
@ -22,6 +22,7 @@ enum DataDirective {
|
||||
};
|
||||
|
||||
DataDirective PointerSizeDirective();
|
||||
int DataDirectiveSize(DataDirective directive);
|
||||
|
||||
enum class EmbeddedTargetOs {
|
||||
kAIX,
|
||||
@ -77,6 +78,9 @@ class PlatformEmbeddedFileWriterBase {
|
||||
|
||||
virtual int IndentedDataDirective(DataDirective directive) = 0;
|
||||
|
||||
virtual DataDirective ByteChunkDataDirective() const { return kOcta; }
|
||||
virtual int WriteByteChunk(const uint8_t* data);
|
||||
|
||||
// This awkward interface works around the fact that unwind data emission
|
||||
// is both high-level and platform-dependent. The former implies it should
|
||||
// live in EmbeddedFileWriter, but code there should be platform-independent.
|
||||
|
@ -582,6 +582,30 @@ int PlatformEmbeddedFileWriterWin::IndentedDataDirective(
|
||||
|
||||
#endif
|
||||
|
||||
DataDirective PlatformEmbeddedFileWriterWin::ByteChunkDataDirective() const {
|
||||
#if defined(V8_COMPILER_IS_MSVC)
|
||||
// Windows MASM doesn't have an .octa directive, use QWORDs instead.
|
||||
// Note: MASM *really* does not like large data streams. It takes over 5
|
||||
// minutes to assemble the ~350K lines of embedded.S produced when using
|
||||
// BYTE directives in a debug build. QWORD produces roughly 120KLOC and
|
||||
// reduces assembly time to ~40 seconds. Still terrible, but much better
|
||||
// than before. See also: https://crbug.com/v8/8475.
|
||||
return kQuad;
|
||||
#else
|
||||
return PlatformEmbeddedFileWriterBase::ByteChunkDataDirective();
|
||||
#endif
|
||||
}
|
||||
|
||||
int PlatformEmbeddedFileWriterWin::WriteByteChunk(const uint8_t* data) {
|
||||
#if defined(V8_COMPILER_IS_MSVC)
|
||||
DCHECK_EQ(ByteChunkDataDirective(), kQuad);
|
||||
const uint64_t* quad_ptr = reinterpret_cast<const uint64_t*>(data);
|
||||
return HexLiteral(*quad_ptr);
|
||||
#else
|
||||
return PlatformEmbeddedFileWriterBase::WriteByteChunk(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef SYMBOL_PREFIX
|
||||
#undef V8_ASSEMBLER_IS_MASM
|
||||
#undef V8_ASSEMBLER_IS_MARMASM
|
||||
|
@ -46,6 +46,9 @@ class PlatformEmbeddedFileWriterWin : public PlatformEmbeddedFileWriterBase {
|
||||
|
||||
int IndentedDataDirective(DataDirective directive) override;
|
||||
|
||||
DataDirective ByteChunkDataDirective() const override;
|
||||
int WriteByteChunk(const uint8_t* data) override;
|
||||
|
||||
void StartPdataSection();
|
||||
void EndPdataSection();
|
||||
void StartXdataSection();
|
||||
|
Loading…
Reference in New Issue
Block a user