summaryrefslogtreecommitdiff
path: root/chromium/v8/src/snapshot/embedded
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/snapshot/embedded')
-rw-r--r--chromium/v8/src/snapshot/embedded/embedded-data.cc25
-rw-r--r--chromium/v8/src/snapshot/embedded/embedded-file-writer.cc4
-rw-r--r--chromium/v8/src/snapshot/embedded/embedded-file-writer.h19
-rw-r--r--chromium/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc112
4 files changed, 136 insertions, 24 deletions
diff --git a/chromium/v8/src/snapshot/embedded/embedded-data.cc b/chromium/v8/src/snapshot/embedded/embedded-data.cc
index 0474d3babe0..2f6d17d6b2b 100644
--- a/chromium/v8/src/snapshot/embedded/embedded-data.cc
+++ b/chromium/v8/src/snapshot/embedded/embedded-data.cc
@@ -55,20 +55,35 @@ Code InstructionStream::TryLookupCode(Isolate* isolate, Address address) {
void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate,
uint8_t** data,
uint32_t* size) {
+ // Create the embedded blob from scratch using the current Isolate's heap.
EmbeddedData d = EmbeddedData::FromIsolate(isolate);
+ // Allocate the backing store that will contain the embedded blob in this
+ // Isolate. The backing store is on the native heap, *not* on V8's garbage-
+ // collected heap.
v8::PageAllocator* page_allocator = v8::internal::GetPlatformPageAllocator();
- const uint32_t page_size =
+ const uint32_t alignment =
static_cast<uint32_t>(page_allocator->AllocatePageSize());
- const uint32_t allocated_size = RoundUp(d.size(), page_size);
+
+ void* const requested_allocation_address =
+ AlignedAddress(isolate->heap()->GetRandomMmapAddr(), alignment);
+ const uint32_t allocation_size = RoundUp(d.size(), alignment);
uint8_t* allocated_bytes = static_cast<uint8_t*>(
- AllocatePages(page_allocator, isolate->heap()->GetRandomMmapAddr(),
- allocated_size, page_size, PageAllocator::kReadWrite));
+ AllocatePages(page_allocator, requested_allocation_address,
+ allocation_size, alignment, PageAllocator::kReadWrite));
CHECK_NOT_NULL(allocated_bytes);
+ // Copy the embedded blob into the newly allocated backing store. Switch
+ // permissions to read-execute since builtin code is immutable from now on
+ // and must be executable in case any JS execution is triggered.
+ //
+ // Once this backing store is set as the current_embedded_blob, V8 cannot tell
+ // the difference between a 'real' embedded build (where the blob is embedded
+ // in the binary) and what we are currently setting up here (where the blob is
+ // on the native heap).
std::memcpy(allocated_bytes, d.data(), d.size());
- CHECK(SetPermissions(page_allocator, allocated_bytes, allocated_size,
+ CHECK(SetPermissions(page_allocator, allocated_bytes, allocation_size,
PageAllocator::kReadExecute));
*data = allocated_bytes;
diff --git a/chromium/v8/src/snapshot/embedded/embedded-file-writer.cc b/chromium/v8/src/snapshot/embedded/embedded-file-writer.cc
index 4703ef48224..5f57993fc32 100644
--- a/chromium/v8/src/snapshot/embedded/embedded-file-writer.cc
+++ b/chromium/v8/src/snapshot/embedded/embedded-file-writer.cc
@@ -92,7 +92,7 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
w->Newline();
}
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_OS_WIN64)
{
i::EmbeddedVector<char, kTemporaryStringLength> unwind_info_symbol;
i::SNPrintF(unwind_info_symbol, "%s_Builtins_UnwindInfo",
@@ -102,7 +102,7 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
EmbeddedBlobDataSymbol().c_str(), blob,
reinterpret_cast<const void*>(&unwind_infos_[0]));
}
-#endif
+#endif // V8_OS_WIN64
w->FileEpilogue();
}
diff --git a/chromium/v8/src/snapshot/embedded/embedded-file-writer.h b/chromium/v8/src/snapshot/embedded/embedded-file-writer.h
index c26465ae6a7..e487b9be9bc 100644
--- a/chromium/v8/src/snapshot/embedded/embedded-file-writer.h
+++ b/chromium/v8/src/snapshot/embedded/embedded-file-writer.h
@@ -13,9 +13,9 @@
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_OS_WIN64)
#include "src/diagnostics/unwinding-info-win64.h"
-#endif
+#endif // V8_OS_WIN64
namespace v8 {
namespace internal {
@@ -35,11 +35,11 @@ class EmbeddedFileWriterInterface {
// compiled builtin Code objects with trampolines.
virtual void PrepareBuiltinSourcePositionMap(Builtins* builtins) = 0;
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_OS_WIN64)
virtual void SetBuiltinUnwindData(
int builtin_index,
const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) = 0;
-#endif
+#endif // V8_OS_WIN64
};
// Generates the embedded.S file which is later compiled into the final v8
@@ -59,14 +59,14 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
void PrepareBuiltinSourcePositionMap(Builtins* builtins) override;
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_OS_WIN64)
void SetBuiltinUnwindData(
int builtin_index,
const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) override {
DCHECK_LT(builtin_index, Builtins::builtin_count);
unwind_infos_[builtin_index] = unwinding_info;
}
-#endif
+#endif // V8_OS_WIN64
void SetEmbeddedFile(const char* embedded_src_path) {
embedded_src_path_ = embedded_src_path;
@@ -172,9 +172,6 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
const i::EmbeddedData* blob) const;
#if defined(V8_OS_WIN_X64)
- std::string BuiltinsUnwindInfoLabel() const;
- void WriteUnwindInfo(PlatformEmbeddedFileWriterBase* w,
- const i::EmbeddedData* blob) const;
void WriteUnwindInfoEntry(PlatformEmbeddedFileWriterBase* w,
uint64_t rva_start, uint64_t rva_end) const;
#endif
@@ -194,9 +191,9 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
private:
std::vector<byte> source_positions_[Builtins::builtin_count];
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_OS_WIN64)
win64_unwindinfo::BuiltinUnwindInfo unwind_infos_[Builtins::builtin_count];
-#endif
+#endif // V8_OS_WIN64
std::map<const char*, int> external_filenames_;
std::vector<const char*> external_filenames_by_index_;
diff --git a/chromium/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc b/chromium/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc
index 69457e11a55..9a9a26fbd0a 100644
--- a/chromium/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc
+++ b/chromium/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc
@@ -6,13 +6,14 @@
#include <algorithm>
-#include "src/common/globals.h" // For V8_OS_WIN_X64.
+#include "src/common/globals.h" // For V8_OS_WIN64
-#if defined(V8_OS_WIN_X64)
+#if defined(V8_OS_WIN64)
#include "src/builtins/builtins.h"
#include "src/diagnostics/unwinding-info-win64.h"
#include "src/snapshot/embedded/embedded-data.h"
-#endif
+#include "src/snapshot/embedded/embedded-file-writer.h"
+#endif // V8_OS_WIN64
namespace v8 {
namespace internal {
@@ -213,20 +214,118 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
w->EndPdataSection();
w->Newline();
}
-#endif // defined(V8_OS_WIN_X64)
+
+#elif defined(V8_OS_WIN_ARM64)
+
+void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
+ const char* unwind_info_symbol,
+ const char* embedded_blob_data_symbol,
+ const EmbeddedData* blob,
+ const win64_unwindinfo::BuiltinUnwindInfo* unwind_infos) {
+ DCHECK(win64_unwindinfo::CanEmitUnwindInfoForBuiltins());
+
+ // Fairly arbitrary but should fit all symbol names.
+ static constexpr int kTemporaryStringLength = 256;
+ i::EmbeddedVector<char, kTemporaryStringLength> unwind_info_full_symbol;
+
+ // Emit a RUNTIME_FUNCTION (PDATA) entry for each builtin function, as
+ // documented here:
+ // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling.
+ w->Comment(
+ "pdata for all the code in the embedded blob (structs of type "
+ "RUNTIME_FUNCTION).");
+ w->Comment(" BeginAddress");
+ w->Comment(" UnwindInfoAddress");
+ w->StartPdataSection();
+ std::vector<int> code_chunks;
+ std::vector<int> fp_adjustments;
+
+ for (int i = 0; i < Builtins::builtin_count; i++) {
+ if (!blob->ContainsBuiltin(i)) continue;
+ if (unwind_infos[i].is_leaf_function()) continue;
+
+ uint64_t builtin_start_offset = blob->InstructionStartOfBuiltin(i) -
+ reinterpret_cast<Address>(blob->data());
+ uint32_t builtin_size = blob->InstructionSizeOfBuiltin(i);
+
+ const std::vector<int>& xdata_desc = unwind_infos[i].fp_offsets();
+ const std::vector<int>& xdata_fp_adjustments =
+ unwind_infos[i].fp_adjustments();
+ DCHECK_EQ(xdata_desc.size(), xdata_fp_adjustments.size());
+
+ for (size_t j = 0; j < xdata_desc.size(); j++) {
+ int chunk_start = xdata_desc[j];
+ int chunk_end =
+ (j < xdata_desc.size() - 1) ? xdata_desc[j + 1] : builtin_size;
+ int chunk_len = ::RoundUp(chunk_end - chunk_start, kInstrSize);
+
+ while (chunk_len > 0) {
+ int allowed_chunk_len =
+ std::min(chunk_len, win64_unwindinfo::kMaxFunctionLength);
+ chunk_len -= win64_unwindinfo::kMaxFunctionLength;
+
+ // Record the chunk length and fp_adjustment for emitting UNWIND_INFO
+ // later.
+ code_chunks.push_back(allowed_chunk_len);
+ fp_adjustments.push_back(xdata_fp_adjustments[j]);
+ i::SNPrintF(unwind_info_full_symbol, "%s_%u", unwind_info_symbol,
+ code_chunks.size());
+ w->DeclareRvaToSymbol(embedded_blob_data_symbol,
+ builtin_start_offset + chunk_start);
+ w->DeclareRvaToSymbol(unwind_info_full_symbol.begin());
+ }
+ }
+ }
+ w->EndPdataSection();
+ w->Newline();
+
+ // Emit an UNWIND_INFO (XDATA) structs, which contains the unwinding
+ // information.
+ w->DeclareExternalFunction(CRASH_HANDLER_FUNCTION_NAME_STRING);
+ w->StartXdataSection();
+ {
+ for (size_t i = 0; i < code_chunks.size(); i++) {
+ i::SNPrintF(unwind_info_full_symbol, "%s_%u", unwind_info_symbol, i + 1);
+ w->DeclareLabel(unwind_info_full_symbol.begin());
+ std::vector<uint8_t> xdata =
+ win64_unwindinfo::GetUnwindInfoForBuiltinFunction(code_chunks[i],
+ fp_adjustments[i]);
+
+ w->IndentedDataDirective(kByte);
+ for (size_t j = 0; j < xdata.size(); j++) {
+ if (j > 0) fprintf(w->fp(), ",");
+ w->HexLiteral(xdata[j]);
+ }
+ w->Newline();
+ w->DeclareRvaToSymbol(CRASH_HANDLER_FUNCTION_NAME_STRING);
+ }
+ }
+ w->EndXdataSection();
+ w->Newline();
+}
+
+#endif // V8_OS_WIN_X64
} // namespace
void PlatformEmbeddedFileWriterWin::MaybeEmitUnwindData(
const char* unwind_info_symbol, const char* embedded_blob_data_symbol,
const EmbeddedData* blob, const void* unwind_infos) {
-#if defined(V8_OS_WIN_X64)
+// Windows ARM64 supports cross build which could require unwind info for
+// host_os. Ignore this case because it is only used in build time.
+#if defined(V8_OS_WIN_ARM64)
+ if (target_arch_ != EmbeddedTargetArch::kArm64) {
+ return;
+ }
+#endif // V8_OS_WIN_ARM64
+
+#if defined(V8_OS_WIN64)
if (win64_unwindinfo::CanEmitUnwindInfoForBuiltins()) {
EmitUnwindData(this, unwind_info_symbol, embedded_blob_data_symbol, blob,
reinterpret_cast<const win64_unwindinfo::BuiltinUnwindInfo*>(
unwind_infos));
}
-#endif // defined(V8_OS_WIN_X64)
+#endif // V8_OS_WIN64
}
// Windows, MSVC, not arm/arm64.
@@ -544,6 +643,7 @@ void PlatformEmbeddedFileWriterWin::DeclareFunctionBegin(const char* name) {
if (target_arch_ == EmbeddedTargetArch::kArm64) {
// Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
// in PE/COFF for Windows.
+ DeclareSymbolGlobal(name);
} else {
// The directives for inserting debugging information on Windows come
// from the PE (Portable Executable) and COFF (Common Object File Format)