summaryrefslogtreecommitdiff
path: root/deps/v8/src/snapshot
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2019-08-01 08:38:30 +0200
committerMichaël Zasso <targos@protonmail.com>2019-08-01 12:53:56 +0200
commit2dcc3665abf57c3607cebffdeeca062f5894885d (patch)
tree4f560748132edcfb4c22d6f967a7e80d23d7ea2c /deps/v8/src/snapshot
parent1ee47d550c6de132f06110aa13eceb7551d643b3 (diff)
downloadandroid-node-v8-2dcc3665abf57c3607cebffdeeca062f5894885d.tar.gz
android-node-v8-2dcc3665abf57c3607cebffdeeca062f5894885d.tar.bz2
android-node-v8-2dcc3665abf57c3607cebffdeeca062f5894885d.zip
deps: update V8 to 7.6.303.28
PR-URL: https://github.com/nodejs/node/pull/28016 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Refael Ackermann (רפאל פלחי) <refack@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Diffstat (limited to 'deps/v8/src/snapshot')
-rw-r--r--deps/v8/src/snapshot/code-serializer.cc98
-rw-r--r--deps/v8/src/snapshot/deserializer-allocator.cc17
-rw-r--r--deps/v8/src/snapshot/deserializer-allocator.h2
-rw-r--r--deps/v8/src/snapshot/deserializer.cc173
-rw-r--r--deps/v8/src/snapshot/deserializer.h6
-rw-r--r--deps/v8/src/snapshot/embedded-file-writer.cc843
-rw-r--r--deps/v8/src/snapshot/embedded-file-writer.h483
-rw-r--r--deps/v8/src/snapshot/embedded/embedded-data.cc (renamed from deps/v8/src/snapshot/embedded-data.cc)40
-rw-r--r--deps/v8/src/snapshot/embedded/embedded-data.h (renamed from deps/v8/src/snapshot/embedded-data.h)13
-rw-r--r--deps/v8/src/snapshot/embedded/embedded-empty.cc (renamed from deps/v8/src/snapshot/embedded-empty.cc)0
-rw-r--r--deps/v8/src/snapshot/embedded/embedded-file-writer.cc214
-rw-r--r--deps/v8/src/snapshot/embedded/embedded-file-writer.h221
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.cc132
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.h64
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc156
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.h105
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.cc140
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.h63
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.cc109
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.h61
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc615
-rw-r--r--deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.h78
-rw-r--r--deps/v8/src/snapshot/mksnapshot.cc116
-rw-r--r--deps/v8/src/snapshot/natives-common.cc4
-rw-r--r--deps/v8/src/snapshot/natives-external.cc10
-rw-r--r--deps/v8/src/snapshot/natives.h4
-rw-r--r--deps/v8/src/snapshot/object-deserializer.cc18
-rw-r--r--deps/v8/src/snapshot/partial-deserializer.cc2
-rw-r--r--deps/v8/src/snapshot/partial-serializer.cc73
-rw-r--r--deps/v8/src/snapshot/partial-serializer.h4
-rw-r--r--deps/v8/src/snapshot/read-only-deserializer.cc23
-rw-r--r--deps/v8/src/snapshot/read-only-serializer.cc27
-rw-r--r--deps/v8/src/snapshot/read-only-serializer.h5
-rw-r--r--deps/v8/src/snapshot/references.h4
-rw-r--r--deps/v8/src/snapshot/roots-serializer.cc8
-rw-r--r--deps/v8/src/snapshot/roots-serializer.h2
-rw-r--r--deps/v8/src/snapshot/serializer-allocator.cc2
-rw-r--r--deps/v8/src/snapshot/serializer-common.cc16
-rw-r--r--deps/v8/src/snapshot/serializer-common.h22
-rw-r--r--deps/v8/src/snapshot/serializer.cc187
-rw-r--r--deps/v8/src/snapshot/serializer.h17
-rw-r--r--deps/v8/src/snapshot/snapshot-common.cc73
-rw-r--r--deps/v8/src/snapshot/snapshot-external.cc3
-rw-r--r--deps/v8/src/snapshot/snapshot-source-sink.cc4
-rw-r--r--deps/v8/src/snapshot/snapshot-source-sink.h4
-rw-r--r--deps/v8/src/snapshot/snapshot.h10
-rw-r--r--deps/v8/src/snapshot/startup-deserializer.cc6
-rw-r--r--deps/v8/src/snapshot/startup-serializer.cc67
48 files changed, 2482 insertions, 1862 deletions
diff --git a/deps/v8/src/snapshot/code-serializer.cc b/deps/v8/src/snapshot/code-serializer.cc
index da60ea189d..b4e75a6c20 100644
--- a/deps/v8/src/snapshot/code-serializer.cc
+++ b/deps/v8/src/snapshot/code-serializer.cc
@@ -4,17 +4,17 @@
#include "src/snapshot/code-serializer.h"
-#include "src/counters.h"
+#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/heap/heap-inl.h"
-#include "src/log.h"
-#include "src/macro-assembler.h"
-#include "src/objects-inl.h"
+#include "src/logging/counters.h"
+#include "src/logging/log.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
+#include "src/objects/visitors.h"
#include "src/snapshot/object-deserializer.h"
#include "src/snapshot/snapshot.h"
-#include "src/version.h"
-#include "src/visitors.h"
+#include "src/utils/version.h"
namespace v8 {
namespace internal {
@@ -50,15 +50,13 @@ ScriptCompiler::CachedData* CodeSerializer::Serialize(
Handle<Script> script(Script::cast(info->script()), isolate);
if (FLAG_trace_serializer) {
PrintF("[Serializing from");
- script->name()->ShortPrint();
+ script->name().ShortPrint();
PrintF("]\n");
}
// TODO(7110): Enable serialization of Asm modules once the AsmWasmData is
// context independent.
if (script->ContainsAsmModule()) return nullptr;
- isolate->heap()->read_only_space()->ClearStringPaddingIfNeeded();
-
// Serialize code object.
Handle<String> source(String::cast(script->source()), isolate);
CodeSerializer cs(isolate, SerializedCodeData::SourceHash(
@@ -104,7 +102,7 @@ bool CodeSerializer::SerializeReadOnlyObject(HeapObject obj) {
// For objects in RO_SPACE, never serialize the object, but instead create a
// back reference that encodes the page number as the chunk_index and the
// offset within the page as the chunk_offset.
- Address address = obj->address();
+ Address address = obj.address();
Page* page = Page::FromAddress(address);
uint32_t chunk_index = 0;
for (Page* p : *read_only_space) {
@@ -114,7 +112,7 @@ bool CodeSerializer::SerializeReadOnlyObject(HeapObject obj) {
uint32_t chunk_offset = static_cast<uint32_t>(page->Offset(address));
SerializerReference back_reference =
SerializerReference::BackReference(RO_SPACE, chunk_index, chunk_offset);
- reference_map()->Add(reinterpret_cast<void*>(obj->ptr()), back_reference);
+ reference_map()->Add(reinterpret_cast<void*>(obj.ptr()), back_reference);
CHECK(SerializeBackReference(obj));
return true;
}
@@ -128,60 +126,60 @@ void CodeSerializer::SerializeObject(HeapObject obj) {
if (SerializeReadOnlyObject(obj)) return;
- CHECK(!obj->IsCode());
+ CHECK(!obj.IsCode());
ReadOnlyRoots roots(isolate());
if (ElideObject(obj)) {
return SerializeObject(roots.undefined_value());
}
- if (obj->IsScript()) {
+ if (obj.IsScript()) {
Script script_obj = Script::cast(obj);
- DCHECK_NE(script_obj->compilation_type(), Script::COMPILATION_TYPE_EVAL);
+ DCHECK_NE(script_obj.compilation_type(), Script::COMPILATION_TYPE_EVAL);
// We want to differentiate between undefined and uninitialized_symbol for
// context_data for now. It is hack to allow debugging for scripts that are
// included as a part of custom snapshot. (see debug::Script::IsEmbedded())
- Object context_data = script_obj->context_data();
+ Object context_data = script_obj.context_data();
if (context_data != roots.undefined_value() &&
context_data != roots.uninitialized_symbol()) {
- script_obj->set_context_data(roots.undefined_value());
+ script_obj.set_context_data(roots.undefined_value());
}
// We don't want to serialize host options to avoid serializing unnecessary
// object graph.
- FixedArray host_options = script_obj->host_defined_options();
- script_obj->set_host_defined_options(roots.empty_fixed_array());
+ FixedArray host_options = script_obj.host_defined_options();
+ script_obj.set_host_defined_options(roots.empty_fixed_array());
SerializeGeneric(obj);
- script_obj->set_host_defined_options(host_options);
- script_obj->set_context_data(context_data);
+ script_obj.set_host_defined_options(host_options);
+ script_obj.set_context_data(context_data);
return;
}
- if (obj->IsSharedFunctionInfo()) {
+ if (obj.IsSharedFunctionInfo()) {
SharedFunctionInfo sfi = SharedFunctionInfo::cast(obj);
// TODO(7110): Enable serializing of Asm modules once the AsmWasmData
// is context independent.
- DCHECK(!sfi->IsApiFunction() && !sfi->HasAsmWasmData());
+ DCHECK(!sfi.IsApiFunction() && !sfi.HasAsmWasmData());
DebugInfo debug_info;
BytecodeArray debug_bytecode_array;
- if (sfi->HasDebugInfo()) {
+ if (sfi.HasDebugInfo()) {
// Clear debug info.
- debug_info = sfi->GetDebugInfo();
- if (debug_info->HasInstrumentedBytecodeArray()) {
- debug_bytecode_array = debug_info->DebugBytecodeArray();
- sfi->SetDebugBytecodeArray(debug_info->OriginalBytecodeArray());
+ debug_info = sfi.GetDebugInfo();
+ if (debug_info.HasInstrumentedBytecodeArray()) {
+ debug_bytecode_array = debug_info.DebugBytecodeArray();
+ sfi.SetDebugBytecodeArray(debug_info.OriginalBytecodeArray());
}
- sfi->set_script_or_debug_info(debug_info->script());
+ sfi.set_script_or_debug_info(debug_info.script());
}
- DCHECK(!sfi->HasDebugInfo());
+ DCHECK(!sfi.HasDebugInfo());
SerializeGeneric(obj);
// Restore debug info
if (!debug_info.is_null()) {
- sfi->set_script_or_debug_info(debug_info);
+ sfi.set_script_or_debug_info(debug_info);
if (!debug_bytecode_array.is_null()) {
- sfi->SetDebugBytecodeArray(debug_bytecode_array);
+ sfi.SetDebugBytecodeArray(debug_bytecode_array);
}
}
return;
@@ -194,24 +192,24 @@ void CodeSerializer::SerializeObject(HeapObject obj) {
// --interpreted-frames-native-stack is on. See v8:9122 for more context
#ifndef V8_TARGET_ARCH_ARM
if (V8_UNLIKELY(FLAG_interpreted_frames_native_stack) &&
- obj->IsInterpreterData()) {
- obj = InterpreterData::cast(obj)->bytecode_array();
+ obj.IsInterpreterData()) {
+ obj = InterpreterData::cast(obj).bytecode_array();
}
#endif // V8_TARGET_ARCH_ARM
- if (obj->IsBytecodeArray()) {
+ if (obj.IsBytecodeArray()) {
// Clear the stack frame cache if present
- BytecodeArray::cast(obj)->ClearFrameCacheFromSourcePositionTable();
+ BytecodeArray::cast(obj).ClearFrameCacheFromSourcePositionTable();
}
// Past this point we should not see any (context-specific) maps anymore.
- CHECK(!obj->IsMap());
+ CHECK(!obj.IsMap());
// There should be no references to the global object embedded.
- CHECK(!obj->IsJSGlobalProxy() && !obj->IsJSGlobalObject());
+ CHECK(!obj.IsJSGlobalProxy() && !obj.IsJSGlobalObject());
// Embedded FixedArrays that need rehashing must support rehashing.
- CHECK_IMPLIES(obj->NeedsRehashing(), obj->CanBeRehashed());
+ CHECK_IMPLIES(obj.NeedsRehashing(), obj.CanBeRehashed());
// We expect no instantiated function objects or contexts.
- CHECK(!obj->IsJSFunction() && !obj->IsContext());
+ CHECK(!obj.IsJSFunction() && !obj.IsContext());
SerializeGeneric(obj);
}
@@ -233,13 +231,13 @@ void CreateInterpreterDataForDeserializedCode(Isolate* isolate,
Script script = Script::cast(sfi->script());
Handle<Script> script_handle(script, isolate);
String name = ReadOnlyRoots(isolate).empty_string();
- if (script->name()->IsString()) name = String::cast(script->name());
+ if (script.name().IsString()) name = String::cast(script.name());
Handle<String> name_handle(name, isolate);
SharedFunctionInfo::ScriptIterator iter(isolate, script);
for (SharedFunctionInfo info = iter.Next(); !info.is_null();
info = iter.Next()) {
- if (!info->HasBytecodeArray()) continue;
+ if (!info.HasBytecodeArray()) continue;
Handle<Code> code = isolate->factory()->CopyCode(Handle<Code>::cast(
isolate->factory()->interpreter_entry_trampoline_for_profiling()));
@@ -247,15 +245,15 @@ void CreateInterpreterDataForDeserializedCode(Isolate* isolate,
Handle<InterpreterData>::cast(isolate->factory()->NewStruct(
INTERPRETER_DATA_TYPE, AllocationType::kOld));
- interpreter_data->set_bytecode_array(info->GetBytecodeArray());
+ interpreter_data->set_bytecode_array(info.GetBytecodeArray());
interpreter_data->set_interpreter_trampoline(*code);
- info->set_interpreter_data(*interpreter_data);
+ info.set_interpreter_data(*interpreter_data);
if (!log_code_creation) continue;
Handle<AbstractCode> abstract_code = Handle<AbstractCode>::cast(code);
- int line_num = script->GetLineNumber(info->StartPosition()) + 1;
- int column_num = script->GetColumnNumber(info->StartPosition()) + 1;
+ int line_num = script.GetLineNumber(info.StartPosition()) + 1;
+ int column_num = script.GetColumnNumber(info.StartPosition()) + 1;
PROFILE(isolate,
CodeCreateEvent(CodeEventListener::INTERPRETED_FUNCTION_TAG,
*abstract_code, info, *name_handle, line_num,
@@ -320,6 +318,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
? String::cast(script->name())
: ReadOnlyRoots(isolate).empty_string(),
isolate);
+
if (FLAG_log_function_events) {
LOG(isolate,
FunctionEvent("deserialize", script->id(),
@@ -328,15 +327,16 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
}
if (log_code_creation) {
Script::InitLineEnds(script);
+
DisallowHeapAllocation no_gc;
SharedFunctionInfo::ScriptIterator iter(isolate, *script);
for (i::SharedFunctionInfo info = iter.Next(); !info.is_null();
info = iter.Next()) {
- if (info->is_compiled()) {
- int line_num = script->GetLineNumber(info->StartPosition()) + 1;
- int column_num = script->GetColumnNumber(info->StartPosition()) + 1;
+ if (info.is_compiled()) {
+ int line_num = script->GetLineNumber(info.StartPosition()) + 1;
+ int column_num = script->GetColumnNumber(info.StartPosition()) + 1;
PROFILE(isolate, CodeCreateEvent(CodeEventListener::SCRIPT_TAG,
- info->abstract_code(), info, *name,
+ info.abstract_code(), info, *name,
line_num, column_num));
}
}
diff --git a/deps/v8/src/snapshot/deserializer-allocator.cc b/deps/v8/src/snapshot/deserializer-allocator.cc
index 7862865d43..4fb600d1dd 100644
--- a/deps/v8/src/snapshot/deserializer-allocator.cc
+++ b/deps/v8/src/snapshot/deserializer-allocator.cc
@@ -29,7 +29,7 @@ Address DeserializerAllocator::AllocateRaw(AllocationSpace space, int size) {
AllocationResult result = lo_space->AllocateRaw(size);
HeapObject obj = result.ToObjectChecked();
deserialized_large_objects_.push_back(obj);
- return obj->address();
+ return obj.address();
} else if (space == MAP_SPACE) {
DCHECK_EQ(Map::kSize, size);
return allocated_maps_[next_map_index_++];
@@ -44,7 +44,10 @@ Address DeserializerAllocator::AllocateRaw(AllocationSpace space, int size) {
int chunk_index = current_chunk_[space];
DCHECK_LE(high_water_[space], reservation[chunk_index].end);
#endif
- if (space == CODE_SPACE) SkipList::Update(address, size);
+ if (space == CODE_SPACE)
+ MemoryChunk::FromAddress(address)
+ ->GetCodeObjectRegistry()
+ ->RegisterNewlyAllocatedCodeObject(address);
return address;
}
}
@@ -60,11 +63,11 @@ Address DeserializerAllocator::Allocate(AllocationSpace space, int size) {
// If one of the following assertions fails, then we are deserializing an
// aligned object when the filler maps have not been deserialized yet.
// We require filler maps as padding to align the object.
- DCHECK(ReadOnlyRoots(heap_).free_space_map()->IsMap());
- DCHECK(ReadOnlyRoots(heap_).one_pointer_filler_map()->IsMap());
- DCHECK(ReadOnlyRoots(heap_).two_pointer_filler_map()->IsMap());
+ DCHECK(ReadOnlyRoots(heap_).free_space_map().IsMap());
+ DCHECK(ReadOnlyRoots(heap_).one_pointer_filler_map().IsMap());
+ DCHECK(ReadOnlyRoots(heap_).two_pointer_filler_map().IsMap());
obj = heap_->AlignWithFiller(obj, size, reserved, next_alignment_);
- address = obj->address();
+ address = obj.address();
next_alignment_ = kWordAligned;
return address;
} else {
@@ -103,7 +106,7 @@ HeapObject DeserializerAllocator::GetObject(AllocationSpace space,
if (next_alignment_ != kWordAligned) {
int padding = Heap::GetFillToAlign(address, next_alignment_);
next_alignment_ = kWordAligned;
- DCHECK(padding == 0 || HeapObject::FromAddress(address)->IsFiller());
+ DCHECK(padding == 0 || HeapObject::FromAddress(address).IsFiller());
address += padding;
}
return HeapObject::FromAddress(address);
diff --git a/deps/v8/src/snapshot/deserializer-allocator.h b/deps/v8/src/snapshot/deserializer-allocator.h
index 56bd4d1b0e..27cacc79d5 100644
--- a/deps/v8/src/snapshot/deserializer-allocator.h
+++ b/deps/v8/src/snapshot/deserializer-allocator.h
@@ -5,7 +5,7 @@
#ifndef V8_SNAPSHOT_DESERIALIZER_ALLOCATOR_H_
#define V8_SNAPSHOT_DESERIALIZER_ALLOCATOR_H_
-#include "src/globals.h"
+#include "src/common/globals.h"
#include "src/heap/heap.h"
#include "src/objects/heap-object.h"
#include "src/snapshot/serializer-common.h"
diff --git a/deps/v8/src/snapshot/deserializer.cc b/deps/v8/src/snapshot/deserializer.cc
index 3759c53c21..1fd590db26 100644
--- a/deps/v8/src/snapshot/deserializer.cc
+++ b/deps/v8/src/snapshot/deserializer.cc
@@ -4,24 +4,24 @@
#include "src/snapshot/deserializer.h"
-#include "src/assembler-inl.h"
+#include "src/codegen/assembler-inl.h"
+#include "src/execution/isolate.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/heap/read-only-heap.h"
#include "src/interpreter/interpreter.h"
-#include "src/isolate.h"
-#include "src/log.h"
-#include "src/objects-body-descriptors-inl.h"
+#include "src/logging/log.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/cell-inl.h"
#include "src/objects/hash-table.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/maybe-object.h"
+#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/slots.h"
#include "src/objects/smi.h"
#include "src/objects/string.h"
-#include "src/roots.h"
+#include "src/roots/roots.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/snapshot.h"
#include "src/tracing/trace-event.h"
@@ -71,7 +71,7 @@ void Deserializer::Initialize(Isolate* isolate) {
void Deserializer::Rehash() {
DCHECK(can_rehash() || deserializing_user_code());
for (HeapObject item : to_rehash_) {
- item->RehashBasedOnMap(ReadOnlyRoots(isolate_));
+ item.RehashBasedOnMap(ReadOnlyRoots(isolate_));
}
}
@@ -117,7 +117,7 @@ void Deserializer::DeserializeDeferredObjects() {
DCHECK_EQ(code - space, kNewObject);
HeapObject object = GetBackReferencedObject(space);
int size = source_.GetInt() << kTaggedSizeLog2;
- Address obj_address = object->address();
+ Address obj_address = object.address();
// Object's map is already initialized, now read the rest.
MaybeObjectSlot start(obj_address + kTaggedSize);
MaybeObjectSlot end(obj_address + size);
@@ -154,28 +154,26 @@ void Deserializer::LogNewMapEvents() {
void Deserializer::LogScriptEvents(Script script) {
DisallowHeapAllocation no_gc;
LOG(isolate_,
- ScriptEvent(Logger::ScriptEventType::kDeserialize, script->id()));
+ ScriptEvent(Logger::ScriptEventType::kDeserialize, script.id()));
LOG(isolate_, ScriptDetails(script));
TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("v8.compile"), "Script",
- TRACE_ID_WITH_SCOPE("v8::internal::Script", script->id()));
+ TRACE_ID_WITH_SCOPE("v8::internal::Script", script.id()));
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("v8.compile"), "Script",
- TRACE_ID_WITH_SCOPE("v8::internal::Script", script->id()),
- script->ToTracedValue());
+ TRACE_ID_WITH_SCOPE("v8::internal::Script", script.id()),
+ script.ToTracedValue());
}
StringTableInsertionKey::StringTableInsertionKey(String string)
- : StringTableKey(ComputeHashField(string)), string_(string) {
- DCHECK(string->IsInternalizedString());
+ : StringTableKey(ComputeHashField(string), string.length()),
+ string_(string) {
+ DCHECK(string.IsInternalizedString());
}
-bool StringTableInsertionKey::IsMatch(Object string) {
- // We know that all entries in a hash table had their hash keys created.
- // Use that knowledge to have fast failure.
- if (Hash() != String::cast(string)->Hash()) return false;
- // We want to compare the content of two internalized strings here.
- return string_->SlowEquals(String::cast(string));
+bool StringTableInsertionKey::IsMatch(String string) {
+ // We want to compare the content of two strings here.
+ return string_.SlowEquals(string);
}
Handle<String> StringTableInsertionKey::AsHandle(Isolate* isolate) {
@@ -184,44 +182,58 @@ Handle<String> StringTableInsertionKey::AsHandle(Isolate* isolate) {
uint32_t StringTableInsertionKey::ComputeHashField(String string) {
// Make sure hash_field() is computed.
- string->Hash();
- return string->hash_field();
+ string.Hash();
+ return string.hash_field();
}
+namespace {
+
+String ForwardStringIfExists(Isolate* isolate, StringTableInsertionKey* key) {
+ StringTable table = isolate->heap()->string_table();
+ int entry = table.FindEntry(isolate, key);
+ if (entry == kNotFound) return String();
+
+ String canonical = String::cast(table.KeyAt(entry));
+ DCHECK_NE(canonical, key->string());
+ key->string().MakeThin(isolate, canonical);
+ return canonical;
+}
+
+} // namespace
+
HeapObject Deserializer::PostProcessNewObject(HeapObject obj, int space) {
if ((FLAG_rehash_snapshot && can_rehash_) || deserializing_user_code()) {
- if (obj->IsString()) {
+ if (obj.IsString()) {
// Uninitialize hash field as we need to recompute the hash.
String string = String::cast(obj);
- string->set_hash_field(String::kEmptyHashField);
+ string.set_hash_field(String::kEmptyHashField);
// Rehash strings before read-only space is sealed. Strings outside
// read-only space are rehashed lazily. (e.g. when rehashing dictionaries)
if (space == RO_SPACE) {
to_rehash_.push_back(obj);
}
- } else if (obj->NeedsRehashing()) {
+ } else if (obj.NeedsRehashing()) {
to_rehash_.push_back(obj);
}
}
if (deserializing_user_code()) {
- if (obj->IsString()) {
+ if (obj.IsString()) {
String string = String::cast(obj);
- if (string->IsInternalizedString()) {
+ if (string.IsInternalizedString()) {
// Canonicalize the internalized string. If it already exists in the
// string table, set it to forward to the existing one.
StringTableInsertionKey key(string);
- String canonical =
- StringTable::ForwardStringIfExists(isolate_, &key, string);
+ String canonical = ForwardStringIfExists(isolate_, &key);
if (!canonical.is_null()) return canonical;
new_internalized_strings_.push_back(handle(string, isolate_));
return string;
}
- } else if (obj->IsScript()) {
+ } else if (obj.IsScript()) {
new_scripts_.push_back(handle(Script::cast(obj), isolate_));
- } else if (obj->IsAllocationSite()) {
+ } else if (obj.IsAllocationSite()) {
// We should link new allocation sites, but we can't do this immediately
// because |AllocationSite::HasWeakNext()| internally accesses
// |Heap::roots_| that may not have been initialized yet. So defer this to
@@ -231,93 +243,86 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj, int space) {
DCHECK(CanBeDeferred(obj));
}
}
- if (obj->IsScript()) {
+ if (obj.IsScript()) {
LogScriptEvents(Script::cast(obj));
- } else if (obj->IsCode()) {
+ } else if (obj.IsCode()) {
// We flush all code pages after deserializing the startup snapshot.
// Hence we only remember each individual code object when deserializing
// user code.
if (deserializing_user_code() || space == LO_SPACE) {
new_code_objects_.push_back(Code::cast(obj));
}
- } else if (FLAG_trace_maps && obj->IsMap()) {
+ } else if (FLAG_trace_maps && obj.IsMap()) {
// Keep track of all seen Maps to log them later since they might be only
// partially initialized at this point.
new_maps_.push_back(Map::cast(obj));
- } else if (obj->IsAccessorInfo()) {
+ } else if (obj.IsAccessorInfo()) {
#ifdef USE_SIMULATOR
accessor_infos_.push_back(AccessorInfo::cast(obj));
#endif
- } else if (obj->IsCallHandlerInfo()) {
+ } else if (obj.IsCallHandlerInfo()) {
#ifdef USE_SIMULATOR
call_handler_infos_.push_back(CallHandlerInfo::cast(obj));
#endif
- } else if (obj->IsExternalString()) {
- if (obj->map() == ReadOnlyRoots(isolate_).native_source_string_map()) {
+ } else if (obj.IsExternalString()) {
+ if (obj.map() == ReadOnlyRoots(isolate_).native_source_string_map()) {
ExternalOneByteString string = ExternalOneByteString::cast(obj);
- DCHECK(string->is_uncached());
- string->SetResource(
+ DCHECK(string.is_uncached());
+ string.SetResource(
isolate_, NativesExternalStringResource::DecodeForDeserialization(
- string->resource()));
+ string.resource()));
} else {
ExternalString string = ExternalString::cast(obj);
- uint32_t index = string->resource_as_uint32();
+ uint32_t index = string.resource_as_uint32();
Address address =
static_cast<Address>(isolate_->api_external_references()[index]);
- string->set_address_as_resource(address);
+ string.set_address_as_resource(address);
isolate_->heap()->UpdateExternalString(string, 0,
- string->ExternalPayloadSize());
+ string.ExternalPayloadSize());
}
isolate_->heap()->RegisterExternalString(String::cast(obj));
- } else if (obj->IsJSTypedArray()) {
+ } else if (obj.IsJSDataView()) {
+ JSDataView data_view = JSDataView::cast(obj);
+ JSArrayBuffer buffer = JSArrayBuffer::cast(data_view.buffer());
+ data_view.set_data_pointer(
+ reinterpret_cast<uint8_t*>(buffer.backing_store()) +
+ data_view.byte_offset());
+ } else if (obj.IsJSTypedArray()) {
JSTypedArray typed_array = JSTypedArray::cast(obj);
- CHECK_LE(typed_array->byte_offset(), Smi::kMaxValue);
- int32_t byte_offset = static_cast<int32_t>(typed_array->byte_offset());
- if (byte_offset > 0) {
- FixedTypedArrayBase elements =
- FixedTypedArrayBase::cast(typed_array->elements());
- // Must be off-heap layout.
- DCHECK(!typed_array->is_on_heap());
-
- void* pointer_with_offset = reinterpret_cast<void*>(
- reinterpret_cast<intptr_t>(elements->external_pointer()) +
- byte_offset);
- elements->set_external_pointer(pointer_with_offset);
+ // Only fixup for the off-heap case.
+ if (!typed_array.is_on_heap()) {
+ Smi store_index(
+ reinterpret_cast<Address>(typed_array.external_pointer()));
+ byte* backing_store = off_heap_backing_stores_[store_index.value()] +
+ typed_array.byte_offset();
+ typed_array.set_external_pointer(backing_store);
}
- } else if (obj->IsJSArrayBuffer()) {
+ } else if (obj.IsJSArrayBuffer()) {
JSArrayBuffer buffer = JSArrayBuffer::cast(obj);
// Only fixup for the off-heap case.
- if (buffer->backing_store() != nullptr) {
- Smi store_index(reinterpret_cast<Address>(buffer->backing_store()));
- void* backing_store = off_heap_backing_stores_[store_index->value()];
+ if (buffer.backing_store() != nullptr) {
+ Smi store_index(reinterpret_cast<Address>(buffer.backing_store()));
+ void* backing_store = off_heap_backing_stores_[store_index.value()];
- buffer->set_backing_store(backing_store);
+ buffer.set_backing_store(backing_store);
isolate_->heap()->RegisterNewArrayBuffer(buffer);
}
- } else if (obj->IsFixedTypedArrayBase()) {
- FixedTypedArrayBase fta = FixedTypedArrayBase::cast(obj);
- // Only fixup for the off-heap case.
- if (fta->base_pointer() == Smi::kZero) {
- Smi store_index(reinterpret_cast<Address>(fta->external_pointer()));
- void* backing_store = off_heap_backing_stores_[store_index->value()];
- fta->set_external_pointer(backing_store);
- }
- } else if (obj->IsBytecodeArray()) {
+ } else if (obj.IsBytecodeArray()) {
// TODO(mythria): Remove these once we store the default values for these
// fields in the serializer.
BytecodeArray bytecode_array = BytecodeArray::cast(obj);
- bytecode_array->set_osr_loop_nesting_level(0);
+ bytecode_array.set_osr_loop_nesting_level(0);
}
#ifdef DEBUG
- if (obj->IsDescriptorArray()) {
+ if (obj.IsDescriptorArray()) {
DescriptorArray descriptor_array = DescriptorArray::cast(obj);
- DCHECK_EQ(0, descriptor_array->raw_number_of_marked_descriptors());
+ DCHECK_EQ(0, descriptor_array.raw_number_of_marked_descriptors());
}
#endif
// Check alignment.
- DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(),
- HeapObject::RequiredAlignment(obj->map())));
+ DCHECK_EQ(0, Heap::GetFillToAlign(obj.address(),
+ HeapObject::RequiredAlignment(obj.map())));
return obj;
}
@@ -356,12 +361,12 @@ HeapObject Deserializer::GetBackReferencedObject(int space) {
}
}
- if (deserializing_user_code() && obj->IsThinString()) {
- obj = ThinString::cast(obj)->actual();
+ if (deserializing_user_code() && obj.IsThinString()) {
+ obj = ThinString::cast(obj).actual();
}
hot_objects_.Add(obj);
- DCHECK(!HasWeakHeapObjectTag(obj->ptr()));
+ DCHECK(!HasWeakHeapObjectTag(obj));
return obj;
}
@@ -393,7 +398,7 @@ HeapObject Deserializer::ReadObject(int space_number) {
}
#ifdef DEBUG
- if (obj->IsCode()) {
+ if (obj.IsCode()) {
DCHECK(space_number == CODE_SPACE || space_number == CODE_LO_SPACE);
} else {
DCHECK(space_number != CODE_SPACE && space_number != CODE_LO_SPACE);
@@ -424,7 +429,7 @@ void Deserializer::ReadCodeObjectBody(int space_number,
void Deserializer::VisitCodeTarget(Code host, RelocInfo* rinfo) {
HeapObject object = ReadObject();
- rinfo->set_target_address(Code::cast(object)->raw_instruction_start());
+ rinfo->set_target_address(Code::cast(object).raw_instruction_start());
}
void Deserializer::VisitEmbeddedPointer(Code host, RelocInfo* rinfo) {
@@ -460,8 +465,8 @@ void Deserializer::VisitInternalReference(Code host, RelocInfo* rinfo) {
// Internal reference target is encoded as an offset from code entry.
int target_offset = source_.GetInt();
DCHECK_LT(static_cast<unsigned>(target_offset),
- static_cast<unsigned>(host->raw_instruction_size()));
- Address target = host->entry() + target_offset;
+ static_cast<unsigned>(host.raw_instruction_size()));
+ Address target = host.entry() + target_offset;
Assembler::deserialization_set_target_internal_reference_at(
rinfo->pc(), target, rinfo->rmode());
}
@@ -619,7 +624,7 @@ bool Deserializer::ReadData(TSlot current, TSlot limit, int source_space,
HeapObject obj = HeapObject::FromAddress(current_object_address);
// If the deferred object is a map, its instance type may be used
// during deserialization. Initialize it with a temporary value.
- if (obj->IsMap()) Map::cast(obj)->set_instance_type(FILLER_TYPE);
+ if (obj.IsMap()) Map::cast(obj).set_instance_type(FILLER_TYPE);
current = limit;
return false;
}
@@ -814,7 +819,7 @@ TSlot Deserializer::ReadDataCase(Isolate* isolate, TSlot current,
} else if (bytecode == kReadOnlyObjectCache) {
int cache_index = source_.GetInt();
heap_object = HeapObject::cast(
- isolate->heap()->read_only_heap()->read_only_object_cache()->at(
+ isolate->heap()->read_only_heap()->cached_read_only_object(
cache_index));
DCHECK(!Heap::InYoungGeneration(heap_object));
emit_write_barrier = false;
diff --git a/deps/v8/src/snapshot/deserializer.h b/deps/v8/src/snapshot/deserializer.h
index 86536ca81c..6e3f497d38 100644
--- a/deps/v8/src/snapshot/deserializer.h
+++ b/deps/v8/src/snapshot/deserializer.h
@@ -186,14 +186,16 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer {
};
// Used to insert a deserialized internalized string into the string table.
-class StringTableInsertionKey : public StringTableKey {
+class StringTableInsertionKey final : public StringTableKey {
public:
explicit StringTableInsertionKey(String string);
- bool IsMatch(Object string) override;
+ bool IsMatch(String string) override;
V8_WARN_UNUSED_RESULT Handle<String> AsHandle(Isolate* isolate) override;
+ String string() const { return string_; }
+
private:
uint32_t ComputeHashField(String string);
diff --git a/deps/v8/src/snapshot/embedded-file-writer.cc b/deps/v8/src/snapshot/embedded-file-writer.cc
deleted file mode 100644
index 3ead35bd9a..0000000000
--- a/deps/v8/src/snapshot/embedded-file-writer.cc
+++ /dev/null
@@ -1,843 +0,0 @@
-// Copyright 2018 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.
-
-#include "src/snapshot/embedded-file-writer.h"
-
-#include <algorithm>
-#include <cinttypes>
-
-#include "src/objects/code-inl.h"
-
-namespace v8 {
-namespace internal {
-
-// V8_CC_MSVC is true for both MSVC and clang on windows. clang can handle
-// __asm__-style inline assembly but MSVC cannot, and thus we need a more
-// precise compiler detection that can distinguish between the two. clang on
-// windows sets both __clang__ and _MSC_VER, MSVC sets only _MSC_VER.
-#if defined(_MSC_VER) && !defined(__clang__)
-#define V8_COMPILER_IS_MSVC
-#endif
-
-// MSVC uses MASM for x86 and x64, while it has a ARMASM for ARM32 and
-// ARMASM64 for ARM64. Since ARMASM and ARMASM64 accept a slightly tweaked
-// version of ARM assembly language, they are referred to together in Visual
-// Studio project files as MARMASM.
-//
-// ARM assembly language docs:
-// http://infocenter.arm.com/help/topic/com.arm.doc.dui0802b/index.html
-// Microsoft ARM assembler and assembly language docs:
-// https://docs.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference
-#if defined(V8_COMPILER_IS_MSVC)
-#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_ARM)
-#define V8_ASSEMBLER_IS_MARMASM
-#elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
-#define V8_ASSEMBLER_IS_MASM
-#else
-#error Unknown Windows assembler target architecture.
-#endif
-#endif
-
-// Name mangling.
-// Symbols are prefixed with an underscore on 32-bit architectures.
-#if defined(V8_TARGET_OS_WIN) && !defined(V8_TARGET_ARCH_X64) && \
- !defined(V8_TARGET_ARCH_ARM64)
-#define SYMBOL_PREFIX "_"
-#else
-#define SYMBOL_PREFIX ""
-#endif
-
-// Platform-independent bits.
-// -----------------------------------------------------------------------------
-
-namespace {
-
-DataDirective PointerSizeDirective() {
- if (kSystemPointerSize == 8) {
- return kQuad;
- } else {
- CHECK_EQ(4, kSystemPointerSize);
- return kLong;
- }
-}
-
-} // namespace
-
-const char* DirectiveAsString(DataDirective directive) {
-#if defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
- switch (directive) {
- case kByte:
- return "BYTE";
- case kLong:
- return "DWORD";
- case kQuad:
- return "QWORD";
- default:
- UNREACHABLE();
- }
-#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
- switch (directive) {
- case kByte:
- return "DCB";
- case kLong:
- return "DCDU";
- case kQuad:
- return "DCQU";
- default:
- UNREACHABLE();
- }
-#elif defined(V8_OS_AIX)
- switch (directive) {
- case kByte:
- return ".byte";
- case kLong:
- return ".long";
- case kQuad:
- return ".llong";
- default:
- UNREACHABLE();
- }
-#else
- switch (directive) {
- case kByte:
- return ".byte";
- case kLong:
- return ".long";
- case kQuad:
- return ".quad";
- case kOcta:
- return ".octa";
- }
- UNREACHABLE();
-#endif
-}
-
-void EmbeddedFileWriter::PrepareBuiltinSourcePositionMap(Builtins* builtins) {
- for (int i = 0; i < Builtins::builtin_count; i++) {
- // Retrieve the SourcePositionTable and copy it.
- Code code = builtins->builtin(i);
- // Verify that the code object is still the "real code" and not a
- // trampoline (which wouldn't have source positions).
- DCHECK(!code->is_off_heap_trampoline());
- std::vector<unsigned char> data(
- code->SourcePositionTable()->GetDataStartAddress(),
- code->SourcePositionTable()->GetDataEndAddress());
- source_positions_[i] = data;
- }
-}
-
-#if defined(V8_OS_WIN_X64)
-std::string EmbeddedFileWriter::BuiltinsUnwindInfoLabel() const {
- char embedded_blob_data_symbol[kTemporaryStringLength];
- i::SNPrintF(i::Vector<char>(embedded_blob_data_symbol),
- "%s_Builtins_UnwindInfo", embedded_variant_);
- return embedded_blob_data_symbol;
-}
-
-void EmbeddedFileWriter::SetBuiltinUnwindData(
- int builtin_index, const win64_unwindinfo::BuiltinUnwindInfo& unwind_info) {
- DCHECK_LT(builtin_index, Builtins::builtin_count);
- unwind_infos_[builtin_index] = unwind_info;
-}
-
-void EmbeddedFileWriter::WriteUnwindInfoEntry(
- PlatformDependentEmbeddedFileWriter* w, uint64_t rva_start,
- uint64_t rva_end) const {
- w->DeclareRvaToSymbol(EmbeddedBlobDataSymbol().c_str(), rva_start);
- w->DeclareRvaToSymbol(EmbeddedBlobDataSymbol().c_str(), rva_end);
- w->DeclareRvaToSymbol(BuiltinsUnwindInfoLabel().c_str());
-}
-
-void EmbeddedFileWriter::WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
- const i::EmbeddedData* blob) const {
- // Emit an UNWIND_INFO (XDATA) struct, which contains the unwinding
- // information that is used for all builtin functions.
- DCHECK(win64_unwindinfo::CanEmitUnwindInfoForBuiltins());
- w->Comment("xdata for all the code in the embedded blob.");
- w->DeclareExternalFunction(CRASH_HANDLER_FUNCTION_NAME_STRING);
-
- w->StartXdataSection();
- {
- w->DeclareLabel(BuiltinsUnwindInfoLabel().c_str());
- std::vector<uint8_t> xdata =
- win64_unwindinfo::GetUnwindInfoForBuiltinFunctions();
- WriteBinaryContentsAsInlineAssembly(w, xdata.data(),
- static_cast<uint32_t>(xdata.size()));
- w->Comment(" ExceptionHandler");
- w->DeclareRvaToSymbol(CRASH_HANDLER_FUNCTION_NAME_STRING);
- }
- w->EndXdataSection();
- w->Newline();
-
- // Emit a RUNTIME_FUNCTION (PDATA) entry for each builtin function, as
- // documented here:
- // https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
- w->Comment(
- "pdata for all the code in the embedded blob (structs of type "
- "RUNTIME_FUNCTION).");
- w->Comment(" BeginAddress");
- w->Comment(" EndAddress");
- w->Comment(" UnwindInfoAddress");
- w->StartPdataSection();
- {
- Address prev_builtin_end_offset = 0;
- for (int i = 0; i < Builtins::builtin_count; i++) {
- // Some builtins are leaf functions from the point of view of Win64 stack
- // walking: they do not move the stack pointer and do not require a PDATA
- // entry because the return address can be retrieved from [rsp].
- 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();
- if (xdata_desc.empty()) {
- // Some builtins do not have any "push rbp - mov rbp, rsp" instructions
- // to start a stack frame. We still emit a PDATA entry as if they had,
- // relying on the fact that we can find the previous frame address from
- // rbp in most cases. Note that since the function does not really start
- // with a 'push rbp' we need to specify the start RVA in the PDATA entry
- // a few bytes before the beginning of the function, if it does not
- // overlap the end of the previous builtin.
- WriteUnwindInfoEntry(
- w,
- std::max(prev_builtin_end_offset,
- builtin_start_offset - win64_unwindinfo::kRbpPrefixLength),
- builtin_start_offset + builtin_size);
- } else {
- // Some builtins have one or more "push rbp - mov rbp, rsp" sequences,
- // but not necessarily at the beginning of the function. In this case
- // we want to yield a PDATA entry for each block of instructions that
- // emit an rbp frame. If the function does not start with 'push rbp'
- // we also emit a PDATA entry for the initial block of code up to the
- // first 'push rbp', like in the case above.
- if (xdata_desc[0] > 0) {
- WriteUnwindInfoEntry(w,
- std::max(prev_builtin_end_offset,
- builtin_start_offset -
- win64_unwindinfo::kRbpPrefixLength),
- builtin_start_offset + xdata_desc[0]);
- }
-
- 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;
- WriteUnwindInfoEntry(w, builtin_start_offset + chunk_start,
- builtin_start_offset + chunk_end);
- }
- }
-
- prev_builtin_end_offset = builtin_start_offset + builtin_size;
- w->Newline();
- }
- }
- w->EndPdataSection();
- w->Newline();
-}
-#endif
-
-// V8_OS_MACOSX
-// Fuchsia target is explicitly excluded here for Mac hosts. This is to avoid
-// generating uncompilable assembly files for the Fuchsia target.
-// -----------------------------------------------------------------------------
-
-#if defined(V8_OS_MACOSX) && !defined(V8_TARGET_OS_FUCHSIA)
-
-void PlatformDependentEmbeddedFileWriter::SectionText() {
- fprintf(fp_, ".text\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionData() {
- fprintf(fp_, ".data\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionRoData() {
- fprintf(fp_, ".const_data\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
- uint32_t value) {
- DeclareSymbolGlobal(name);
- DeclareLabel(name);
- IndentedDataDirective(kLong);
- fprintf(fp_, "%d", value);
- Newline();
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
- const char* name, const char* target) {
- DeclareSymbolGlobal(name);
- DeclareLabel(name);
- fprintf(fp_, " %s _%s\n", DirectiveAsString(PointerSizeDirective()), target);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
- const char* name) {
- // TODO(jgruber): Investigate switching to .globl. Using .private_extern
- // prevents something along the compilation chain from messing with the
- // embedded blob. Using .global here causes embedded blob hash verification
- // failures at runtime.
- fprintf(fp_, ".private_extern _%s\n", name);
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
- fprintf(fp_, ".balign 32\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
- fprintf(fp_, ".balign 8\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
- fprintf(fp_, "// %s\n", string);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
- fprintf(fp_, "_%s:\n", name);
-}
-
-void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
- const char* filename,
- int line) {
- fprintf(fp_, ".loc %d %d\n", fileid, line);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
- const char* name) {
- DeclareLabel(name);
-
- // TODO(mvstanton): Investigate the proper incantations to mark the label as
- // a function on OSX.
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
-}
-
-int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
- return fprintf(fp_, "0x%" PRIx64, value);
-}
-
-void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
- int fileid, const char* filename) {
- fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
-}
-
-void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
-
-int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
- DataDirective directive) {
- return fprintf(fp_, " %s ", DirectiveAsString(directive));
-}
-
-// V8_OS_AIX
-// -----------------------------------------------------------------------------
-
-#elif defined(V8_OS_AIX)
-
-void PlatformDependentEmbeddedFileWriter::SectionText() {
- fprintf(fp_, ".csect .text[PR]\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionData() {
- fprintf(fp_, ".csect .data[RW]\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionRoData() {
- fprintf(fp_, ".csect[RO]\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
- uint32_t value) {
- DeclareSymbolGlobal(name);
- fprintf(fp_, ".align 2\n");
- fprintf(fp_, "%s:\n", name);
- IndentedDataDirective(kLong);
- fprintf(fp_, "%d\n", value);
- Newline();
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
- const char* name, const char* target) {
- AlignToCodeAlignment();
- DeclareLabel(name);
- fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
- Newline();
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
- const char* name) {
- fprintf(fp_, ".globl %s\n", name);
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
- fprintf(fp_, ".align 5\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
- fprintf(fp_, ".align 3\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
- fprintf(fp_, "// %s\n", string);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
- DeclareSymbolGlobal(name);
- fprintf(fp_, "%s:\n", name);
-}
-
-void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
- const char* filename,
- int line) {
- fprintf(fp_, ".xline %d, \"%s\"\n", line, filename);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
- const char* name) {
- Newline();
- DeclareSymbolGlobal(name);
- fprintf(fp_, ".csect %s[DS]\n", name); // function descriptor
- fprintf(fp_, "%s:\n", name);
- fprintf(fp_, ".llong .%s, 0, 0\n", name);
- SectionText();
- fprintf(fp_, ".%s:\n", name);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
-}
-
-int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
- return fprintf(fp_, "0x%" PRIx64, value);
-}
-
-void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
- int fileid, const char* filename) {
- // File name cannot be declared with an identifier on AIX.
- // We use the SourceInfo method to emit debug info in
- //.xline <line-number> <file-name> format.
-}
-
-void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
-
-int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
- DataDirective directive) {
- return fprintf(fp_, " %s ", DirectiveAsString(directive));
-}
-
-// V8_TARGET_OS_WIN (MSVC)
-// -----------------------------------------------------------------------------
-
-#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
-
-// For MSVC builds we emit assembly in MASM syntax.
-// See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
-
-void PlatformDependentEmbeddedFileWriter::SectionText() {
- fprintf(fp_, ".CODE\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionData() {
- fprintf(fp_, ".DATA\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionRoData() {
- fprintf(fp_, ".CONST\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
- uint32_t value) {
- DeclareSymbolGlobal(name);
- fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
- value);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
- const char* name, const char* target) {
- DeclareSymbolGlobal(name);
- fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
- DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
-}
-
-#if defined(V8_OS_WIN_X64)
-
-void PlatformDependentEmbeddedFileWriter::StartPdataSection() {
- fprintf(fp_, "OPTION DOTNAME\n");
- fprintf(fp_, ".pdata SEGMENT DWORD READ ''\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::EndPdataSection() {
- fprintf(fp_, ".pdata ENDS\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::StartXdataSection() {
- fprintf(fp_, "OPTION DOTNAME\n");
- fprintf(fp_, ".xdata SEGMENT DWORD READ ''\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::EndXdataSection() {
- fprintf(fp_, ".xdata ENDS\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFunction(
- const char* name) {
- fprintf(fp_, "EXTERN %s : PROC\n", name);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareRvaToSymbol(const char* name,
- uint64_t offset) {
- if (offset > 0) {
- fprintf(fp_, "DD IMAGEREL %s+%llu\n", name, offset);
- } else {
- fprintf(fp_, "DD IMAGEREL %s\n", name);
- }
-}
-
-#endif // defined(V8_OS_WIN_X64)
-
-void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
- const char* name) {
- fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
- // Diverges from other platforms due to compile error
- // 'invalid combination with segment alignment'.
- fprintf(fp_, "ALIGN 4\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
- fprintf(fp_, "ALIGN 4\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
- fprintf(fp_, "; %s\n", string);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
- fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
- DirectiveAsString(kByte));
-}
-
-void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
- const char* filename,
- int line) {
- // TODO(mvstanton): output source information for MSVC.
- // Its syntax is #line <line> "<filename>"
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
- const char* name) {
- fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
- fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
-}
-
-int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
- return fprintf(fp_, "0%" PRIx64 "h", value);
-}
-
-void PlatformDependentEmbeddedFileWriter::FilePrologue() {
-#if !defined(V8_TARGET_ARCH_X64)
- fprintf(fp_, ".MODEL FLAT\n");
-#endif
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
- int fileid, const char* filename) {}
-
-void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
- fprintf(fp_, "END\n");
-}
-
-int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
- DataDirective directive) {
- return fprintf(fp_, " %s ", DirectiveAsString(directive));
-}
-
-#undef V8_ASSEMBLER_IS_MASM
-
-#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
-
-// The the AARCH64 ABI requires instructions be 4-byte-aligned and Windows does
-// not have a stricter alignment requirement (see the TEXTAREA macro of
-// kxarm64.h in the Windows SDK), so code is 4-byte-aligned.
-// The data fields in the emitted assembly tend to be accessed with 8-byte
-// LDR instructions, so data is 8-byte-aligned.
-//
-// armasm64's warning A4228 states
-// Alignment value exceeds AREA alignment; alignment not guaranteed
-// To ensure that ALIGN directives are honored, their values are defined as
-// equal to their corresponding AREA's ALIGN attributes.
-
-#define ARM64_DATA_ALIGNMENT_POWER (3)
-#define ARM64_DATA_ALIGNMENT (1 << ARM64_DATA_ALIGNMENT_POWER)
-#define ARM64_CODE_ALIGNMENT_POWER (2)
-#define ARM64_CODE_ALIGNMENT (1 << ARM64_CODE_ALIGNMENT_POWER)
-
-void PlatformDependentEmbeddedFileWriter::SectionText() {
- fprintf(fp_, " AREA |.text|, CODE, ALIGN=%d, READONLY\n",
- ARM64_CODE_ALIGNMENT_POWER);
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionData() {
- fprintf(fp_, " AREA |.data|, DATA, ALIGN=%d, READWRITE\n",
- ARM64_DATA_ALIGNMENT_POWER);
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionRoData() {
- fprintf(fp_, " AREA |.rodata|, DATA, ALIGN=%d, READONLY\n",
- ARM64_DATA_ALIGNMENT_POWER);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
- uint32_t value) {
- DeclareSymbolGlobal(name);
- fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
- value);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
- const char* name, const char* target) {
- DeclareSymbolGlobal(name);
- fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
- DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
- const char* name) {
- fprintf(fp_, " EXPORT %s%s\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
- fprintf(fp_, " ALIGN %d\n", ARM64_CODE_ALIGNMENT);
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
- fprintf(fp_, " ALIGN %d\n", ARM64_DATA_ALIGNMENT);
-}
-
-void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
- fprintf(fp_, "; %s\n", string);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
- fprintf(fp_, "%s%s\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
- const char* filename,
- int line) {
- // TODO(mvstanton): output source information for MSVC.
- // Its syntax is #line <line> "<filename>"
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
- const char* name) {
- fprintf(fp_, "%s%s FUNCTION\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
- fprintf(fp_, " ENDFUNC\n");
-}
-
-int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
- return fprintf(fp_, "0x%" PRIx64, value);
-}
-
-void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
- int fileid, const char* filename) {}
-
-void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
- fprintf(fp_, " END\n");
-}
-
-int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
- DataDirective directive) {
- return fprintf(fp_, " %s ", DirectiveAsString(directive));
-}
-
-#undef V8_ASSEMBLER_IS_MARMASM
-#undef ARM64_DATA_ALIGNMENT_POWER
-#undef ARM64_DATA_ALIGNMENT
-#undef ARM64_CODE_ALIGNMENT_POWER
-#undef ARM64_CODE_ALIGNMENT
-
-// Everything but AIX, Windows with MSVC, or OSX.
-// -----------------------------------------------------------------------------
-
-#else
-
-void PlatformDependentEmbeddedFileWriter::SectionText() {
-#ifdef OS_CHROMEOS
- fprintf(fp_, ".section .text.hot.embedded\n");
-#else
- fprintf(fp_, ".section .text\n");
-#endif
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionData() {
- fprintf(fp_, ".section .data\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::SectionRoData() {
- if (i::FLAG_target_os == std::string("win"))
- fprintf(fp_, ".section .rdata\n");
- else
- fprintf(fp_, ".section .rodata\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
- uint32_t value) {
- DeclareSymbolGlobal(name);
- DeclareLabel(name);
- IndentedDataDirective(kLong);
- fprintf(fp_, "%d", value);
- Newline();
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
- const char* name, const char* target) {
- DeclareSymbolGlobal(name);
- DeclareLabel(name);
- fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
- SYMBOL_PREFIX, target);
-}
-
-#if defined(V8_OS_WIN_X64)
-
-void PlatformDependentEmbeddedFileWriter::StartPdataSection() {
- fprintf(fp_, ".section .pdata\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::EndPdataSection() {}
-
-void PlatformDependentEmbeddedFileWriter::StartXdataSection() {
- fprintf(fp_, ".section .xdata\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::EndXdataSection() {}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFunction(
- const char* name) {}
-
-void PlatformDependentEmbeddedFileWriter::DeclareRvaToSymbol(const char* name,
- uint64_t offset) {
- if (offset > 0) {
- fprintf(fp_, ".rva %s + %llu\n", name, offset);
- } else {
- fprintf(fp_, ".rva %s\n", name);
- }
-}
-
-#endif // defined(V8_OS_WIN_X64)
-
-void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
- const char* name) {
- fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
- fprintf(fp_, ".balign 32\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
- // On Windows ARM64, s390, PPC and possibly more platforms, aligned load
- // instructions are used to retrieve v8_Default_embedded_blob_ and/or
- // v8_Default_embedded_blob_size_. The generated instructions require the
- // load target to be aligned at 8 bytes (2^3).
- fprintf(fp_, ".balign 8\n");
-}
-
-void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
- fprintf(fp_, "// %s\n", string);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
- fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
-}
-
-void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
- const char* filename,
- int line) {
- fprintf(fp_, ".loc %d %d\n", fileid, line);
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
- const char* name) {
- DeclareLabel(name);
-
- if (i::FLAG_target_os == std::string("win")) {
-#if defined(V8_TARGET_ARCH_ARM64)
- // Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
- // in PE/COFF for Windows.
-#else
- // The directives for inserting debugging information on Windows come
- // from the PE (Portable Executable) and COFF (Common Object File Format)
- // standards. Documented here:
- // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
- //
- // .scl 2 means StorageClass external.
- // .type 32 means Type Representation Function.
- fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
-#endif
- } else {
-#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
- // ELF format binaries on ARM use ".type <function name>, %function"
- // to create a DWARF subprogram entry.
- fprintf(fp_, ".type %s, %%function\n", name);
-#else
- // Other ELF Format binaries use ".type <function name>, @function"
- // to create a DWARF subprogram entry.
- fprintf(fp_, ".type %s, @function\n", name);
-#endif
- }
-}
-
-void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
-}
-
-int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
- return fprintf(fp_, "0x%" PRIx64, value);
-}
-
-void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
-
-void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
- int fileid, const char* filename) {
- // Replace any Windows style paths (backslashes) with forward
- // slashes.
- std::string fixed_filename(filename);
- for (auto& c : fixed_filename) {
- if (c == '\\') {
- c = '/';
- }
- }
- fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
-}
-
-void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
-
-int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
- DataDirective directive) {
- return fprintf(fp_, " %s ", DirectiveAsString(directive));
-}
-
-#endif
-
-#undef SYMBOL_PREFIX
-#undef V8_COMPILER_IS_MSVC
-
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded-file-writer.h b/deps/v8/src/snapshot/embedded-file-writer.h
deleted file mode 100644
index 0f4978cfd8..0000000000
--- a/deps/v8/src/snapshot/embedded-file-writer.h
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2018 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_EMBEDDED_FILE_WRITER_H_
-#define V8_SNAPSHOT_EMBEDDED_FILE_WRITER_H_
-
-#include <cstdio>
-#include <cstring>
-
-#include "src/globals.h"
-#include "src/snapshot/snapshot.h"
-#include "src/source-position-table.h"
-
-#if defined(V8_OS_WIN_X64)
-#include "src/unwinding-info-win64.h"
-#endif
-
-namespace v8 {
-namespace internal {
-
-enum DataDirective {
- kByte,
- kLong,
- kQuad,
- kOcta,
-};
-
-static constexpr char kDefaultEmbeddedVariant[] = "Default";
-
-// The platform-dependent logic for emitting assembly code for the generated
-// embedded.S file.
-class EmbeddedFileWriter;
-class PlatformDependentEmbeddedFileWriter final {
- public:
- void SetFile(FILE* fp) { fp_ = fp; }
-
- void SectionText();
- void SectionData();
- void SectionRoData();
-
- void AlignToCodeAlignment();
- void AlignToDataAlignment();
-
- void DeclareUint32(const char* name, uint32_t value);
- void DeclarePointerToSymbol(const char* name, const char* target);
-
-#if defined(V8_OS_WIN_X64)
- void StartPdataSection();
- void EndPdataSection();
- void StartXdataSection();
- void EndXdataSection();
- void DeclareExternalFunction(const char* name);
-
- // Emits an RVA (address relative to the module load address) specified as an
- // offset from a given symbol.
- void DeclareRvaToSymbol(const char* name, uint64_t offset = 0);
-#endif
-
- void DeclareLabel(const char* name);
-
- void SourceInfo(int fileid, const char* filename, int line);
- void DeclareFunctionBegin(const char* name);
- void DeclareFunctionEnd(const char* name);
-
- // Returns the number of printed characters.
- int HexLiteral(uint64_t value);
-
- void Comment(const char* string);
- void Newline() { fprintf(fp_, "\n"); }
-
- void FilePrologue();
- void DeclareExternalFilename(int fileid, const char* filename);
- void FileEpilogue();
-
- int IndentedDataDirective(DataDirective directive);
-
- FILE* fp() const { return fp_; }
-
- private:
- void DeclareSymbolGlobal(const char* name);
-
- private:
- FILE* fp_ = nullptr;
-};
-
-// When writing out compiled builtins to a file, we
-// Detailed source-code information about builtins can only be obtained by
-// registration on the isolate during compilation.
-class EmbeddedFileWriterInterface {
- public:
- // We maintain a database of filenames to synthetic IDs.
- virtual int LookupOrAddExternallyCompiledFilename(const char* filename) = 0;
- virtual const char* GetExternallyCompiledFilename(int index) const = 0;
- virtual int GetExternallyCompiledFilenameCount() const = 0;
-
- // The isolate will call the method below just prior to replacing the
- // compiled builtin Code objects with trampolines.
- virtual void PrepareBuiltinSourcePositionMap(Builtins* builtins) = 0;
-
-#if defined(V8_OS_WIN_X64)
- virtual void SetBuiltinUnwindData(
- int builtin_index,
- const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) = 0;
-#endif
-};
-
-// Generates the embedded.S file which is later compiled into the final v8
-// binary. Its contents are exported through two symbols:
-//
-// v8_<variant>_embedded_blob_ (intptr_t):
-// a pointer to the start of the embedded blob.
-// v8_<variant>_embedded_blob_size_ (uint32_t):
-// size of the embedded blob in bytes.
-//
-// The variant is usually "Default" but can be modified in multisnapshot builds.
-class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
- public:
- int LookupOrAddExternallyCompiledFilename(const char* filename) override {
- auto result = external_filenames_.find(filename);
- if (result != external_filenames_.end()) {
- return result->second;
- }
- int new_id =
- ExternalFilenameIndexToId(static_cast<int>(external_filenames_.size()));
- external_filenames_.insert(std::make_pair(filename, new_id));
- external_filenames_by_index_.push_back(filename);
- DCHECK_EQ(external_filenames_by_index_.size(), external_filenames_.size());
- return new_id;
- }
-
- const char* GetExternallyCompiledFilename(int fileid) const override {
- size_t index = static_cast<size_t>(ExternalFilenameIdToIndex(fileid));
- DCHECK_GE(index, 0);
- DCHECK_LT(index, external_filenames_by_index_.size());
-
- return external_filenames_by_index_[index];
- }
-
- int GetExternallyCompiledFilenameCount() const override {
- return static_cast<int>(external_filenames_.size());
- }
-
- void PrepareBuiltinSourcePositionMap(Builtins* builtins) override;
-
-#if defined(V8_OS_WIN_X64)
- void SetBuiltinUnwindData(
- int builtin_index,
- const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) override;
-#endif
-
- void SetEmbeddedFile(const char* embedded_src_path) {
- embedded_src_path_ = embedded_src_path;
- }
-
- void SetEmbeddedVariant(const char* embedded_variant) {
- embedded_variant_ = embedded_variant;
- }
-
- void WriteEmbedded(const i::EmbeddedData* blob) const {
- MaybeWriteEmbeddedFile(blob);
- }
-
- private:
- void MaybeWriteEmbeddedFile(const i::EmbeddedData* blob) const {
- if (embedded_src_path_ == nullptr) return;
-
- FILE* fp = GetFileDescriptorOrDie(embedded_src_path_);
-
- PlatformDependentEmbeddedFileWriter writer;
- writer.SetFile(fp);
-
- WriteFilePrologue(&writer);
- WriteExternalFilenames(&writer);
- WriteMetadataSection(&writer, blob);
- WriteInstructionStreams(&writer, blob);
- WriteFileEpilogue(&writer, blob);
-
- fclose(fp);
- }
-
- static FILE* GetFileDescriptorOrDie(const char* filename) {
- FILE* fp = v8::base::OS::FOpen(filename, "wb");
- if (fp == nullptr) {
- i::PrintF("Unable to open file \"%s\" for writing.\n", filename);
- exit(1);
- }
- return fp;
- }
-
- void WriteFilePrologue(PlatformDependentEmbeddedFileWriter* w) const {
- w->Comment("Autogenerated file. Do not edit.");
- w->Newline();
- w->FilePrologue();
- }
-
- void WriteExternalFilenames(PlatformDependentEmbeddedFileWriter* w) const {
- w->Comment(
- "Source positions in the embedded blob refer to filenames by id.");
- w->Comment("Assembly directives here map the id to a filename.");
- w->Newline();
-
- // Write external filenames.
- int size = static_cast<int>(external_filenames_by_index_.size());
- for (int i = 0; i < size; i++) {
- w->DeclareExternalFilename(ExternalFilenameIndexToId(i),
- external_filenames_by_index_[i]);
- }
- }
-
- // Fairly arbitrary but should fit all symbol names.
- static constexpr int kTemporaryStringLength = 256;
-
- std::string EmbeddedBlobDataSymbol() const {
- char embedded_blob_data_symbol[kTemporaryStringLength];
- i::SNPrintF(i::Vector<char>(embedded_blob_data_symbol),
- "v8_%s_embedded_blob_data_", embedded_variant_);
- return embedded_blob_data_symbol;
- }
-
- void WriteMetadataSection(PlatformDependentEmbeddedFileWriter* w,
- const i::EmbeddedData* blob) const {
- w->Comment("The embedded blob starts here. Metadata comes first, followed");
- w->Comment("by builtin instruction streams.");
- w->SectionText();
- w->AlignToCodeAlignment();
- w->DeclareLabel(EmbeddedBlobDataSymbol().c_str());
-
- WriteBinaryContentsAsInlineAssembly(w, blob->data(),
- i::EmbeddedData::RawDataOffset());
- }
-
- void WriteBuiltin(PlatformDependentEmbeddedFileWriter* w,
- const i::EmbeddedData* blob, const int builtin_id) const {
- const bool is_default_variant =
- std::strcmp(embedded_variant_, kDefaultEmbeddedVariant) == 0;
-
- char builtin_symbol[kTemporaryStringLength];
- if (is_default_variant) {
- // Create nicer symbol names for the default mode.
- i::SNPrintF(i::Vector<char>(builtin_symbol), "Builtins_%s",
- i::Builtins::name(builtin_id));
- } else {
- i::SNPrintF(i::Vector<char>(builtin_symbol), "%s_Builtins_%s",
- embedded_variant_, i::Builtins::name(builtin_id));
- }
-
- // Labels created here will show up in backtraces. We check in
- // Isolate::SetEmbeddedBlob that the blob layout remains unchanged, i.e.
- // that labels do not insert bytes into the middle of the blob byte
- // stream.
- w->DeclareFunctionBegin(builtin_symbol);
- const std::vector<byte>& current_positions = source_positions_[builtin_id];
-
- // The code below interleaves bytes of assembly code for the builtin
- // function with source positions at the appropriate offsets.
- Vector<const byte> vpos(current_positions.data(), current_positions.size());
- v8::internal::SourcePositionTableIterator positions(
- vpos, SourcePositionTableIterator::kExternalOnly);
-
- const uint8_t* data = reinterpret_cast<const uint8_t*>(
- blob->InstructionStartOfBuiltin(builtin_id));
- uint32_t size = blob->PaddedInstructionSizeOfBuiltin(builtin_id);
- uint32_t i = 0;
- uint32_t next_offset = static_cast<uint32_t>(
- positions.done() ? size : positions.code_offset());
- while (i < size) {
- if (i == next_offset) {
- // Write source directive.
- w->SourceInfo(positions.source_position().ExternalFileId(),
- GetExternallyCompiledFilename(
- positions.source_position().ExternalFileId()),
- positions.source_position().ExternalLine());
- positions.Advance();
- next_offset = static_cast<uint32_t>(
- positions.done() ? size : positions.code_offset());
- }
- CHECK_GE(next_offset, i);
- WriteBinaryContentsAsInlineAssembly(w, data + i, next_offset - i);
- i = next_offset;
- }
-
- w->DeclareFunctionEnd(builtin_symbol);
- }
-
- void WriteInstructionStreams(PlatformDependentEmbeddedFileWriter* w,
- const i::EmbeddedData* blob) const {
- for (int i = 0; i < i::Builtins::builtin_count; i++) {
- if (!blob->ContainsBuiltin(i)) continue;
-
- WriteBuiltin(w, blob, i);
- }
- w->Newline();
- }
-
- void WriteFileEpilogue(PlatformDependentEmbeddedFileWriter* w,
- const i::EmbeddedData* blob) const {
- {
- char embedded_blob_symbol[kTemporaryStringLength];
- i::SNPrintF(i::Vector<char>(embedded_blob_symbol), "v8_%s_embedded_blob_",
- embedded_variant_);
-
- w->Comment("Pointer to the beginning of the embedded blob.");
- w->SectionData();
- w->AlignToDataAlignment();
- w->DeclarePointerToSymbol(embedded_blob_symbol,
- EmbeddedBlobDataSymbol().c_str());
- w->Newline();
- }
-
- {
- char embedded_blob_size_symbol[kTemporaryStringLength];
- i::SNPrintF(i::Vector<char>(embedded_blob_size_symbol),
- "v8_%s_embedded_blob_size_", embedded_variant_);
-
- w->Comment("The size of the embedded blob in bytes.");
- w->SectionRoData();
- w->AlignToDataAlignment();
- w->DeclareUint32(embedded_blob_size_symbol, blob->size());
- w->Newline();
- }
-
-#if defined(V8_OS_WIN_X64)
- if (win64_unwindinfo::CanEmitUnwindInfoForBuiltins()) {
- WriteUnwindInfo(w, blob);
- }
-#endif
-
- w->FileEpilogue();
- }
-
-#if defined(V8_OS_WIN_X64)
- std::string BuiltinsUnwindInfoLabel() const;
- void WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
- const i::EmbeddedData* blob) const;
- void WriteUnwindInfoEntry(PlatformDependentEmbeddedFileWriter* w,
- uint64_t rva_start, uint64_t rva_end) const;
-#endif
-
-#if defined(_MSC_VER) && !defined(__clang__)
-#define V8_COMPILER_IS_MSVC
-#endif
-
-#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;
-
- static int WriteByteChunk(PlatformDependentEmbeddedFileWriter* 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;
-
- static int WriteByteChunk(PlatformDependentEmbeddedFileWriter* 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;
-
- static int WriteByteChunk(PlatformDependentEmbeddedFileWriter* 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
-
- static int WriteDirectiveOrSeparator(PlatformDependentEmbeddedFileWriter* w,
- int current_line_length,
- DataDirective directive) {
- int printed_chars;
- if (current_line_length == 0) {
- printed_chars = w->IndentedDataDirective(directive);
- DCHECK_LT(0, printed_chars);
- } else {
- printed_chars = fprintf(w->fp(), ",");
- DCHECK_EQ(1, printed_chars);
- }
- return current_line_length + printed_chars;
- }
-
- static int WriteLineEndIfNeeded(PlatformDependentEmbeddedFileWriter* w,
- int current_line_length, int write_size) {
- static const int kTextWidth = 100;
- // Check if adding ',0xFF...FF\n"' would force a line wrap. This doesn't use
- // the actual size of the string to be written to determine this so it's
- // more conservative than strictly needed.
- if (current_line_length + strlen(",0x") + write_size * 2 > kTextWidth) {
- fprintf(w->fp(), "\n");
- return 0;
- } else {
- return current_line_length;
- }
- }
-
- static void WriteBinaryContentsAsInlineAssembly(
- PlatformDependentEmbeddedFileWriter* w, const uint8_t* data,
- uint32_t size) {
- int current_line_length = 0;
- uint32_t i = 0;
-
- // Begin by writing out byte chunks.
- for (; i + kByteChunkSize < size; i += kByteChunkSize) {
- current_line_length = WriteDirectiveOrSeparator(w, current_line_length,
- kByteChunkDirective);
- current_line_length = WriteByteChunk(w, current_line_length, data + i);
- current_line_length =
- WriteLineEndIfNeeded(w, current_line_length, kByteChunkSize);
- }
- if (current_line_length != 0) w->Newline();
- current_line_length = 0;
-
- // Write any trailing bytes one-by-one.
- for (; i < size; i++) {
- current_line_length =
- WriteDirectiveOrSeparator(w, current_line_length, kByte);
- current_line_length += w->HexLiteral(data[i]);
- current_line_length = WriteLineEndIfNeeded(w, current_line_length, 1);
- }
-
- if (current_line_length != 0) w->Newline();
- }
-
- static int ExternalFilenameIndexToId(int index) {
- return kFirstExternalFilenameId + index;
- }
-
- static int ExternalFilenameIdToIndex(int id) {
- return id - kFirstExternalFilenameId;
- }
-
- std::vector<byte> source_positions_[Builtins::builtin_count];
-
-#if defined(V8_OS_WIN_X64)
- win64_unwindinfo::BuiltinUnwindInfo unwind_infos_[Builtins::builtin_count];
-#endif
-
- // In assembly directives, filename ids need to begin with 1.
- static const int kFirstExternalFilenameId = 1;
- std::map<const char*, int> external_filenames_;
- std::vector<const char*> external_filenames_by_index_;
-
- const char* embedded_src_path_ = nullptr;
- const char* embedded_variant_ = kDefaultEmbeddedVariant;
-};
-
-} // namespace internal
-} // namespace v8
-
-#endif // V8_SNAPSHOT_EMBEDDED_FILE_WRITER_H_
diff --git a/deps/v8/src/snapshot/embedded-data.cc b/deps/v8/src/snapshot/embedded/embedded-data.cc
index 0488c2f2c7..0474d3babe 100644
--- a/deps/v8/src/snapshot/embedded-data.cc
+++ b/deps/v8/src/snapshot/embedded/embedded-data.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/snapshot/embedded-data.h"
+#include "src/snapshot/embedded/embedded-data.h"
-#include "src/assembler-inl.h"
-#include "src/callable.h"
-#include "src/objects-inl.h"
+#include "src/codegen/assembler-inl.h"
+#include "src/codegen/callable.h"
+#include "src/objects/objects-inl.h"
#include "src/snapshot/snapshot.h"
namespace v8 {
@@ -89,8 +89,8 @@ void InstructionStream::FreeOffHeapInstructionStream(uint8_t* data,
namespace {
bool BuiltinAliasesOffHeapTrampolineRegister(Isolate* isolate, Code code) {
- DCHECK(Builtins::IsIsolateIndependent(code->builtin_index()));
- switch (Builtins::KindOf(code->builtin_index())) {
+ DCHECK(Builtins::IsIsolateIndependent(code.builtin_index()));
+ switch (Builtins::KindOf(code.builtin_index())) {
case Builtins::CPP:
case Builtins::TFC:
case Builtins::TFH:
@@ -101,14 +101,13 @@ bool BuiltinAliasesOffHeapTrampolineRegister(Isolate* isolate, Code code) {
// Bytecode handlers will only ever be used by the interpreter and so there
// will never be a need to use trampolines with them.
case Builtins::BCH:
- case Builtins::API:
case Builtins::ASM:
// TODO(jgruber): Extend checks to remaining kinds.
return false;
}
Callable callable = Builtins::CallableFor(
- isolate, static_cast<Builtins::Name>(code->builtin_index()));
+ isolate, static_cast<Builtins::Name>(code.builtin_index()));
CallInterfaceDescriptor descriptor = callable.descriptor();
if (descriptor.ContextRegister() == kOffHeapTrampolineRegister) {
@@ -152,7 +151,7 @@ void FinalizeEmbeddedCodeTargets(Isolate* isolate, EmbeddedData* blob) {
// Do not emit write-barrier for off-heap writes.
off_heap_it.rinfo()->set_target_address(
- blob->InstructionStartOfBuiltin(target->builtin_index()),
+ blob->InstructionStartOfBuiltin(target.builtin_index()),
SKIP_WRITE_BARRIER);
on_heap_it.next();
@@ -186,7 +185,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
if (Builtins::IsIsolateIndependent(i)) {
// Sanity-check that the given builtin is isolate-independent and does not
// use the trampoline register in its calling convention.
- if (!code->IsIsolateIndependent(isolate)) {
+ if (!code.IsIsolateIndependent(isolate)) {
saw_unsafe_builtin = true;
fprintf(stderr, "%s is not isolate-independent.\n", Builtins::name(i));
}
@@ -206,7 +205,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Builtins::name(i));
}
- uint32_t length = static_cast<uint32_t>(code->raw_instruction_size());
+ uint32_t length = static_cast<uint32_t>(code.raw_instruction_size());
DCHECK_EQ(0, raw_data_size % kCodeAlignment);
metadata[i].instructions_offset = raw_data_size;
@@ -249,10 +248,10 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Code code = builtins->builtin(i);
uint32_t offset = metadata[i].instructions_offset;
uint8_t* dst = raw_data_start + offset;
- DCHECK_LE(RawDataOffset() + offset + code->raw_instruction_size(),
+ DCHECK_LE(RawDataOffset() + offset + code.raw_instruction_size(),
blob_size);
- std::memcpy(dst, reinterpret_cast<uint8_t*>(code->raw_instruction_start()),
- code->raw_instruction_size());
+ std::memcpy(dst, reinterpret_cast<uint8_t*>(code.raw_instruction_start()),
+ code.raw_instruction_size());
}
EmbeddedData d(blob, blob_size);
@@ -290,6 +289,19 @@ uint32_t EmbeddedData::InstructionSizeOfBuiltin(int i) const {
return metadata[i].instructions_length;
}
+Address EmbeddedData::InstructionStartOfBytecodeHandlers() const {
+ return InstructionStartOfBuiltin(Builtins::kFirstBytecodeHandler);
+}
+
+Address EmbeddedData::InstructionEndOfBytecodeHandlers() const {
+ STATIC_ASSERT(Builtins::kFirstBytecodeHandler + kNumberOfBytecodeHandlers +
+ 2 * kNumberOfWideBytecodeHandlers ==
+ Builtins::builtin_count);
+ int lastBytecodeHandler = Builtins::builtin_count - 1;
+ return InstructionStartOfBuiltin(lastBytecodeHandler) +
+ InstructionSizeOfBuiltin(lastBytecodeHandler);
+}
+
size_t EmbeddedData::CreateEmbeddedBlobHash() const {
STATIC_ASSERT(EmbeddedBlobHashOffset() == 0);
STATIC_ASSERT(EmbeddedBlobHashSize() == kSizetSize);
diff --git a/deps/v8/src/snapshot/embedded-data.h b/deps/v8/src/snapshot/embedded/embedded-data.h
index 5c5653e2ca..58905668f2 100644
--- a/deps/v8/src/snapshot/embedded-data.h
+++ b/deps/v8/src/snapshot/embedded/embedded-data.h
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef V8_SNAPSHOT_EMBEDDED_DATA_H_
-#define V8_SNAPSHOT_EMBEDDED_DATA_H_
+#ifndef V8_SNAPSHOT_EMBEDDED_EMBEDDED_DATA_H_
+#define V8_SNAPSHOT_EMBEDDED_EMBEDDED_DATA_H_
#include "src/base/macros.h"
#include "src/builtins/builtins.h"
-#include "src/globals.h"
-#include "src/isolate.h"
+#include "src/common/globals.h"
+#include "src/execution/isolate.h"
namespace v8 {
namespace internal {
@@ -57,6 +57,9 @@ class EmbeddedData final {
Address InstructionStartOfBuiltin(int i) const;
uint32_t InstructionSizeOfBuiltin(int i) const;
+ Address InstructionStartOfBytecodeHandlers() const;
+ Address InstructionEndOfBytecodeHandlers() const;
+
bool ContainsBuiltin(int i) const { return InstructionSizeOfBuiltin(i) > 0; }
uint32_t AddressForHashing(Address addr) {
@@ -140,4 +143,4 @@ class EmbeddedData final {
} // namespace internal
} // namespace v8
-#endif // V8_SNAPSHOT_EMBEDDED_DATA_H_
+#endif // V8_SNAPSHOT_EMBEDDED_EMBEDDED_DATA_H_
diff --git a/deps/v8/src/snapshot/embedded-empty.cc b/deps/v8/src/snapshot/embedded/embedded-empty.cc
index 9ffb3458d3..9ffb3458d3 100644
--- a/deps/v8/src/snapshot/embedded-empty.cc
+++ b/deps/v8/src/snapshot/embedded/embedded-empty.cc
diff --git a/deps/v8/src/snapshot/embedded/embedded-file-writer.cc b/deps/v8/src/snapshot/embedded/embedded-file-writer.cc
new file mode 100644
index 0000000000..4703ef4822
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/embedded-file-writer.cc
@@ -0,0 +1,214 @@
+// Copyright 2018 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.
+
+#include "src/snapshot/embedded/embedded-file-writer.h"
+
+#include <cinttypes>
+
+#include "src/codegen/source-position-table.h"
+#include "src/objects/code-inl.h"
+
+namespace v8 {
+namespace internal {
+
+void EmbeddedFileWriter::WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
+ const i::EmbeddedData* blob,
+ const int builtin_id) const {
+ const bool is_default_variant =
+ std::strcmp(embedded_variant_, kDefaultEmbeddedVariant) == 0;
+
+ i::EmbeddedVector<char, kTemporaryStringLength> builtin_symbol;
+ if (is_default_variant) {
+ // Create nicer symbol names for the default mode.
+ i::SNPrintF(builtin_symbol, "Builtins_%s", i::Builtins::name(builtin_id));
+ } else {
+ i::SNPrintF(builtin_symbol, "%s_Builtins_%s", embedded_variant_,
+ i::Builtins::name(builtin_id));
+ }
+
+ // Labels created here will show up in backtraces. We check in
+ // Isolate::SetEmbeddedBlob that the blob layout remains unchanged, i.e.
+ // that labels do not insert bytes into the middle of the blob byte
+ // stream.
+ w->DeclareFunctionBegin(builtin_symbol.begin());
+ const std::vector<byte>& current_positions = source_positions_[builtin_id];
+
+ // The code below interleaves bytes of assembly code for the builtin
+ // function with source positions at the appropriate offsets.
+ Vector<const byte> vpos(current_positions.data(), current_positions.size());
+ v8::internal::SourcePositionTableIterator positions(
+ vpos, SourcePositionTableIterator::kExternalOnly);
+
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(
+ blob->InstructionStartOfBuiltin(builtin_id));
+ uint32_t size = blob->PaddedInstructionSizeOfBuiltin(builtin_id);
+ uint32_t i = 0;
+ uint32_t next_offset =
+ static_cast<uint32_t>(positions.done() ? size : positions.code_offset());
+ while (i < size) {
+ if (i == next_offset) {
+ // Write source directive.
+ w->SourceInfo(positions.source_position().ExternalFileId(),
+ GetExternallyCompiledFilename(
+ positions.source_position().ExternalFileId()),
+ positions.source_position().ExternalLine());
+ positions.Advance();
+ next_offset = static_cast<uint32_t>(
+ positions.done() ? size : positions.code_offset());
+ }
+ CHECK_GE(next_offset, i);
+ WriteBinaryContentsAsInlineAssembly(w, data + i, next_offset - i);
+ i = next_offset;
+ }
+
+ w->DeclareFunctionEnd(builtin_symbol.begin());
+}
+
+void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
+ const i::EmbeddedData* blob) const {
+ {
+ i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_symbol;
+ i::SNPrintF(embedded_blob_symbol, "v8_%s_embedded_blob_",
+ embedded_variant_);
+
+ w->Comment("Pointer to the beginning of the embedded blob.");
+ w->SectionData();
+ w->AlignToDataAlignment();
+ w->DeclarePointerToSymbol(embedded_blob_symbol.begin(),
+ EmbeddedBlobDataSymbol().c_str());
+ w->Newline();
+ }
+
+ {
+ i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_size_symbol;
+ i::SNPrintF(embedded_blob_size_symbol, "v8_%s_embedded_blob_size_",
+ embedded_variant_);
+
+ w->Comment("The size of the embedded blob in bytes.");
+ w->SectionRoData();
+ w->AlignToDataAlignment();
+ w->DeclareUint32(embedded_blob_size_symbol.begin(), blob->size());
+ w->Newline();
+ }
+
+#if defined(V8_OS_WIN_X64)
+ {
+ i::EmbeddedVector<char, kTemporaryStringLength> unwind_info_symbol;
+ i::SNPrintF(unwind_info_symbol, "%s_Builtins_UnwindInfo",
+ embedded_variant_);
+
+ w->MaybeEmitUnwindData(unwind_info_symbol.begin(),
+ EmbeddedBlobDataSymbol().c_str(), blob,
+ reinterpret_cast<const void*>(&unwind_infos_[0]));
+ }
+#endif
+
+ w->FileEpilogue();
+}
+
+namespace {
+
+int WriteDirectiveOrSeparator(PlatformEmbeddedFileWriterBase* w,
+ int current_line_length,
+ DataDirective directive) {
+ int printed_chars;
+ if (current_line_length == 0) {
+ printed_chars = w->IndentedDataDirective(directive);
+ DCHECK_LT(0, printed_chars);
+ } else {
+ printed_chars = fprintf(w->fp(), ",");
+ DCHECK_EQ(1, printed_chars);
+ }
+ return current_line_length + printed_chars;
+}
+
+int WriteLineEndIfNeeded(PlatformEmbeddedFileWriterBase* w,
+ int current_line_length, int write_size) {
+ static const int kTextWidth = 100;
+ // Check if adding ',0xFF...FF\n"' would force a line wrap. This doesn't use
+ // the actual size of the string to be written to determine this so it's
+ // more conservative than strictly needed.
+ if (current_line_length + strlen(",0x") + write_size * 2 > kTextWidth) {
+ fprintf(w->fp(), "\n");
+ return 0;
+ } else {
+ return current_line_length;
+ }
+}
+
+} // namespace
+
+// static
+void EmbeddedFileWriter::WriteBinaryContentsAsInlineAssembly(
+ PlatformEmbeddedFileWriterBase* w, const uint8_t* data, uint32_t size) {
+ int current_line_length = 0;
+ uint32_t i = 0;
+
+ // Begin by writing out byte chunks.
+ 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, directive);
+ current_line_length += w->WriteByteChunk(data + i);
+ current_line_length =
+ WriteLineEndIfNeeded(w, current_line_length, byte_chunk_size);
+ }
+ if (current_line_length != 0) w->Newline();
+ current_line_length = 0;
+
+ // Write any trailing bytes one-by-one.
+ for (; i < size; i++) {
+ current_line_length =
+ WriteDirectiveOrSeparator(w, current_line_length, kByte);
+ current_line_length += w->HexLiteral(data[i]);
+ current_line_length = WriteLineEndIfNeeded(w, current_line_length, 1);
+ }
+
+ if (current_line_length != 0) w->Newline();
+}
+
+int EmbeddedFileWriter::LookupOrAddExternallyCompiledFilename(
+ const char* filename) {
+ auto result = external_filenames_.find(filename);
+ if (result != external_filenames_.end()) {
+ return result->second;
+ }
+ int new_id =
+ ExternalFilenameIndexToId(static_cast<int>(external_filenames_.size()));
+ external_filenames_.insert(std::make_pair(filename, new_id));
+ external_filenames_by_index_.push_back(filename);
+ DCHECK_EQ(external_filenames_by_index_.size(), external_filenames_.size());
+ return new_id;
+}
+
+const char* EmbeddedFileWriter::GetExternallyCompiledFilename(
+ int fileid) const {
+ size_t index = static_cast<size_t>(ExternalFilenameIdToIndex(fileid));
+ DCHECK_GE(index, 0);
+ DCHECK_LT(index, external_filenames_by_index_.size());
+
+ return external_filenames_by_index_[index];
+}
+
+int EmbeddedFileWriter::GetExternallyCompiledFilenameCount() const {
+ return static_cast<int>(external_filenames_.size());
+}
+
+void EmbeddedFileWriter::PrepareBuiltinSourcePositionMap(Builtins* builtins) {
+ for (int i = 0; i < Builtins::builtin_count; i++) {
+ // Retrieve the SourcePositionTable and copy it.
+ Code code = builtins->builtin(i);
+ // Verify that the code object is still the "real code" and not a
+ // trampoline (which wouldn't have source positions).
+ DCHECK(!code.is_off_heap_trampoline());
+ std::vector<unsigned char> data(
+ code.SourcePositionTable().GetDataStartAddress(),
+ code.SourcePositionTable().GetDataEndAddress());
+ source_positions_[i] = data;
+ }
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded/embedded-file-writer.h b/deps/v8/src/snapshot/embedded/embedded-file-writer.h
new file mode 100644
index 0000000000..c26465ae6a
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/embedded-file-writer.h
@@ -0,0 +1,221 @@
+// Copyright 2018 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_EMBEDDED_EMBEDDED_FILE_WRITER_H_
+#define V8_SNAPSHOT_EMBEDDED_EMBEDDED_FILE_WRITER_H_
+
+#include <cinttypes>
+#include <cstdio>
+#include <cstring>
+
+#include "src/common/globals.h"
+#include "src/snapshot/embedded/embedded-data.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
+
+#if defined(V8_OS_WIN_X64)
+#include "src/diagnostics/unwinding-info-win64.h"
+#endif
+
+namespace v8 {
+namespace internal {
+
+static constexpr char kDefaultEmbeddedVariant[] = "Default";
+
+// Detailed source-code information about builtins can only be obtained by
+// registration on the isolate during compilation.
+class EmbeddedFileWriterInterface {
+ public:
+ // We maintain a database of filenames to synthetic IDs.
+ virtual int LookupOrAddExternallyCompiledFilename(const char* filename) = 0;
+ virtual const char* GetExternallyCompiledFilename(int index) const = 0;
+ virtual int GetExternallyCompiledFilenameCount() const = 0;
+
+ // The isolate will call the method below just prior to replacing the
+ // compiled builtin Code objects with trampolines.
+ virtual void PrepareBuiltinSourcePositionMap(Builtins* builtins) = 0;
+
+#if defined(V8_OS_WIN_X64)
+ virtual void SetBuiltinUnwindData(
+ int builtin_index,
+ const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) = 0;
+#endif
+};
+
+// Generates the embedded.S file which is later compiled into the final v8
+// binary. Its contents are exported through two symbols:
+//
+// v8_<variant>_embedded_blob_ (intptr_t):
+// a pointer to the start of the embedded blob.
+// v8_<variant>_embedded_blob_size_ (uint32_t):
+// size of the embedded blob in bytes.
+//
+// The variant is usually "Default" but can be modified in multisnapshot builds.
+class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
+ public:
+ int LookupOrAddExternallyCompiledFilename(const char* filename) override;
+ const char* GetExternallyCompiledFilename(int fileid) const override;
+ int GetExternallyCompiledFilenameCount() const override;
+
+ void PrepareBuiltinSourcePositionMap(Builtins* builtins) override;
+
+#if defined(V8_OS_WIN_X64)
+ 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
+
+ void SetEmbeddedFile(const char* embedded_src_path) {
+ embedded_src_path_ = embedded_src_path;
+ }
+
+ void SetEmbeddedVariant(const char* embedded_variant) {
+ if (embedded_variant == nullptr) return;
+ embedded_variant_ = embedded_variant;
+ }
+
+ void SetTargetArch(const char* target_arch) { target_arch_ = target_arch; }
+
+ void SetTargetOs(const char* target_os) { target_os_ = target_os; }
+
+ void WriteEmbedded(const i::EmbeddedData* blob) const {
+ MaybeWriteEmbeddedFile(blob);
+ }
+
+ private:
+ void MaybeWriteEmbeddedFile(const i::EmbeddedData* blob) const {
+ if (embedded_src_path_ == nullptr) return;
+
+ FILE* fp = GetFileDescriptorOrDie(embedded_src_path_);
+
+ std::unique_ptr<PlatformEmbeddedFileWriterBase> writer =
+ NewPlatformEmbeddedFileWriter(target_arch_, target_os_);
+ writer->SetFile(fp);
+
+ WriteFilePrologue(writer.get());
+ WriteExternalFilenames(writer.get());
+ WriteMetadataSection(writer.get(), blob);
+ WriteInstructionStreams(writer.get(), blob);
+ WriteFileEpilogue(writer.get(), blob);
+
+ fclose(fp);
+ }
+
+ static FILE* GetFileDescriptorOrDie(const char* filename) {
+ FILE* fp = v8::base::OS::FOpen(filename, "wb");
+ if (fp == nullptr) {
+ i::PrintF("Unable to open file \"%s\" for writing.\n", filename);
+ exit(1);
+ }
+ return fp;
+ }
+
+ void WriteFilePrologue(PlatformEmbeddedFileWriterBase* w) const {
+ w->Comment("Autogenerated file. Do not edit.");
+ w->Newline();
+ w->FilePrologue();
+ }
+
+ void WriteExternalFilenames(PlatformEmbeddedFileWriterBase* w) const {
+ w->Comment(
+ "Source positions in the embedded blob refer to filenames by id.");
+ w->Comment("Assembly directives here map the id to a filename.");
+ w->Newline();
+
+ // Write external filenames.
+ int size = static_cast<int>(external_filenames_by_index_.size());
+ for (int i = 0; i < size; i++) {
+ w->DeclareExternalFilename(ExternalFilenameIndexToId(i),
+ external_filenames_by_index_[i]);
+ }
+ }
+
+ // Fairly arbitrary but should fit all symbol names.
+ static constexpr int kTemporaryStringLength = 256;
+
+ std::string EmbeddedBlobDataSymbol() const {
+ i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_data_symbol;
+ i::SNPrintF(embedded_blob_data_symbol, "v8_%s_embedded_blob_data_",
+ embedded_variant_);
+ return std::string{embedded_blob_data_symbol.begin()};
+ }
+
+ void WriteMetadataSection(PlatformEmbeddedFileWriterBase* w,
+ const i::EmbeddedData* blob) const {
+ w->Comment("The embedded blob starts here. Metadata comes first, followed");
+ w->Comment("by builtin instruction streams.");
+ w->SectionText();
+ w->AlignToCodeAlignment();
+ w->DeclareLabel(EmbeddedBlobDataSymbol().c_str());
+
+ WriteBinaryContentsAsInlineAssembly(w, blob->data(),
+ i::EmbeddedData::RawDataOffset());
+ }
+
+ void WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
+ const i::EmbeddedData* blob, const int builtin_id) const;
+
+ void WriteInstructionStreams(PlatformEmbeddedFileWriterBase* w,
+ const i::EmbeddedData* blob) const {
+ for (int i = 0; i < i::Builtins::builtin_count; i++) {
+ if (!blob->ContainsBuiltin(i)) continue;
+
+ WriteBuiltin(w, blob, i);
+ }
+ w->Newline();
+ }
+
+ void WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
+ 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
+
+ static void WriteBinaryContentsAsInlineAssembly(
+ PlatformEmbeddedFileWriterBase* w, const uint8_t* data, uint32_t size);
+
+ // In assembly directives, filename ids need to begin with 1.
+ static constexpr int kFirstExternalFilenameId = 1;
+ static int ExternalFilenameIndexToId(int index) {
+ return kFirstExternalFilenameId + index;
+ }
+ static int ExternalFilenameIdToIndex(int id) {
+ return id - kFirstExternalFilenameId;
+ }
+
+ private:
+ std::vector<byte> source_positions_[Builtins::builtin_count];
+
+#if defined(V8_OS_WIN_X64)
+ win64_unwindinfo::BuiltinUnwindInfo unwind_infos_[Builtins::builtin_count];
+#endif
+
+ std::map<const char*, int> external_filenames_;
+ std::vector<const char*> external_filenames_by_index_;
+
+ // The file to generate or nullptr.
+ const char* embedded_src_path_ = nullptr;
+
+ // The variant is only used in multi-snapshot builds and otherwise set to
+ // "Default".
+ const char* embedded_variant_ = kDefaultEmbeddedVariant;
+
+ // {target_arch} and {target_os} control the generated assembly format. Note
+ // these may differ from both host- and target-platforms specified through
+ // e.g. V8_OS_* and V8_TARGET_ARCH_* defines.
+ const char* target_arch_ = nullptr;
+ const char* target_os_ = nullptr;
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SNAPSHOT_EMBEDDED_EMBEDDED_FILE_WRITER_H_
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.cc
new file mode 100644
index 0000000000..3aef77e341
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.cc
@@ -0,0 +1,132 @@
+// Copyright 2019 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.
+
+#include "src/snapshot/embedded/platform-embedded-file-writer-aix.h"
+
+namespace v8 {
+namespace internal {
+
+#define SYMBOL_PREFIX ""
+
+namespace {
+
+const char* DirectiveAsString(DataDirective directive) {
+ switch (directive) {
+ case kByte:
+ return ".byte";
+ case kLong:
+ return ".long";
+ case kQuad:
+ return ".llong";
+ default:
+ UNREACHABLE();
+ }
+}
+
+} // namespace
+
+void PlatformEmbeddedFileWriterAIX::SectionText() {
+ fprintf(fp_, ".csect .text[PR]\n");
+}
+
+void PlatformEmbeddedFileWriterAIX::SectionData() {
+ fprintf(fp_, ".csect .data[RW]\n");
+}
+
+void PlatformEmbeddedFileWriterAIX::SectionRoData() {
+ fprintf(fp_, ".csect[RO]\n");
+}
+
+void PlatformEmbeddedFileWriterAIX::DeclareUint32(const char* name,
+ uint32_t value) {
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, ".align 2\n");
+ fprintf(fp_, "%s:\n", name);
+ IndentedDataDirective(kLong);
+ fprintf(fp_, "%d\n", value);
+ Newline();
+}
+
+void PlatformEmbeddedFileWriterAIX::DeclarePointerToSymbol(const char* name,
+ const char* target) {
+ AlignToCodeAlignment();
+ DeclareLabel(name);
+ fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
+ Newline();
+}
+
+void PlatformEmbeddedFileWriterAIX::DeclareSymbolGlobal(const char* name) {
+ fprintf(fp_, ".globl %s\n", name);
+}
+
+void PlatformEmbeddedFileWriterAIX::AlignToCodeAlignment() {
+ fprintf(fp_, ".align 5\n");
+}
+
+void PlatformEmbeddedFileWriterAIX::AlignToDataAlignment() {
+ fprintf(fp_, ".align 3\n");
+}
+
+void PlatformEmbeddedFileWriterAIX::Comment(const char* string) {
+ fprintf(fp_, "// %s\n", string);
+}
+
+void PlatformEmbeddedFileWriterAIX::DeclareLabel(const char* name) {
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, "%s:\n", name);
+}
+
+void PlatformEmbeddedFileWriterAIX::SourceInfo(int fileid, const char* filename,
+ int line) {
+ fprintf(fp_, ".xline %d, \"%s\"\n", line, filename);
+}
+
+void PlatformEmbeddedFileWriterAIX::DeclareFunctionBegin(const char* name) {
+ Newline();
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, ".csect %s[DS]\n", name); // function descriptor
+ fprintf(fp_, "%s:\n", name);
+ fprintf(fp_, ".llong .%s, 0, 0\n", name);
+ SectionText();
+ fprintf(fp_, ".%s:\n", name);
+}
+
+void PlatformEmbeddedFileWriterAIX::DeclareFunctionEnd(const char* name) {}
+
+int PlatformEmbeddedFileWriterAIX::HexLiteral(uint64_t value) {
+ return fprintf(fp_, "0x%" PRIx64, value);
+}
+
+void PlatformEmbeddedFileWriterAIX::FilePrologue() {}
+
+void PlatformEmbeddedFileWriterAIX::DeclareExternalFilename(
+ int fileid, const char* filename) {
+ // File name cannot be declared with an identifier on AIX.
+ // We use the SourceInfo method to emit debug info in
+ //.xline <line-number> <file-name> format.
+}
+
+void PlatformEmbeddedFileWriterAIX::FileEpilogue() {}
+
+int PlatformEmbeddedFileWriterAIX::IndentedDataDirective(
+ DataDirective directive) {
+ 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
+} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.h b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.h
new file mode 100644
index 0000000000..6119d50623
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-aix.h
@@ -0,0 +1,64 @@
+// Copyright 2019 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_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_AIX_H_
+#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_AIX_H_
+
+#include "src/base/macros.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
+
+namespace v8 {
+namespace internal {
+
+class PlatformEmbeddedFileWriterAIX : public PlatformEmbeddedFileWriterBase {
+ public:
+ PlatformEmbeddedFileWriterAIX(EmbeddedTargetArch target_arch,
+ EmbeddedTargetOs target_os)
+ : target_arch_(target_arch), target_os_(target_os) {
+ USE(target_arch_);
+ USE(target_os_);
+ DCHECK_EQ(target_os_, EmbeddedTargetOs::kAIX);
+ }
+
+ void SectionText() override;
+ void SectionData() override;
+ void SectionRoData() override;
+
+ void AlignToCodeAlignment() override;
+ void AlignToDataAlignment() override;
+
+ void DeclareUint32(const char* name, uint32_t value) override;
+ void DeclarePointerToSymbol(const char* name, const char* target) override;
+
+ void DeclareLabel(const char* name) override;
+
+ void SourceInfo(int fileid, const char* filename, int line) override;
+ void DeclareFunctionBegin(const char* name) override;
+ void DeclareFunctionEnd(const char* name) override;
+
+ int HexLiteral(uint64_t value) override;
+
+ void Comment(const char* string) override;
+
+ void FilePrologue() override;
+ void DeclareExternalFilename(int fileid, const char* filename) override;
+ void FileEpilogue() override;
+
+ int IndentedDataDirective(DataDirective directive) override;
+
+ DataDirective ByteChunkDataDirective() const override;
+ int WriteByteChunk(const uint8_t* data) override;
+
+ private:
+ void DeclareSymbolGlobal(const char* name);
+
+ private:
+ const EmbeddedTargetArch target_arch_;
+ const EmbeddedTargetOs target_os_;
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_AIX_H_
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc
new file mode 100644
index 0000000000..a17f039fa2
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc
@@ -0,0 +1,156 @@
+// Copyright 2019 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.
+
+#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
+
+#include <string>
+
+#include "src/common/globals.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-aix.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-mac.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-win.h"
+
+namespace v8 {
+namespace internal {
+
+DataDirective PointerSizeDirective() {
+ if (kSystemPointerSize == 8) {
+ return kQuad;
+ } else {
+ CHECK_EQ(4, kSystemPointerSize);
+ return kLong;
+ }
+}
+
+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() {
+#if defined(V8_TARGET_ARCH_ARM)
+ return EmbeddedTargetArch::kArm;
+#elif defined(V8_TARGET_ARCH_ARM64)
+ return EmbeddedTargetArch::kArm64;
+#elif defined(V8_TARGET_ARCH_IA32)
+ return EmbeddedTargetArch::kIA32;
+#elif defined(V8_TARGET_ARCH_X64)
+ return EmbeddedTargetArch::kX64;
+#else
+ return EmbeddedTargetArch::kGeneric;
+#endif
+}
+
+EmbeddedTargetArch ToEmbeddedTargetArch(const char* s) {
+ if (s == nullptr) {
+ return DefaultEmbeddedTargetArch();
+ }
+
+ std::string string(s);
+ if (string == "arm") {
+ return EmbeddedTargetArch::kArm;
+ } else if (string == "arm64") {
+ return EmbeddedTargetArch::kArm64;
+ } else if (string == "ia32") {
+ return EmbeddedTargetArch::kIA32;
+ } else if (string == "x64") {
+ return EmbeddedTargetArch::kX64;
+ } else {
+ return EmbeddedTargetArch::kGeneric;
+ }
+}
+
+EmbeddedTargetOs DefaultEmbeddedTargetOs() {
+#if defined(V8_OS_AIX)
+ return EmbeddedTargetOs::kAIX;
+#elif defined(V8_OS_MACOSX)
+ return EmbeddedTargetOs::kMac;
+#elif defined(V8_OS_WIN)
+ return EmbeddedTargetOs::kWin;
+#else
+ return EmbeddedTargetOs::kGeneric;
+#endif
+}
+
+EmbeddedTargetOs ToEmbeddedTargetOs(const char* s) {
+ if (s == nullptr) {
+ return DefaultEmbeddedTargetOs();
+ }
+
+ std::string string(s);
+ if (string == "aix") {
+ return EmbeddedTargetOs::kAIX;
+ } else if (string == "chromeos") {
+ return EmbeddedTargetOs::kChromeOS;
+ } else if (string == "fuchsia") {
+ return EmbeddedTargetOs::kFuchsia;
+ } else if (string == "ios" || string == "mac") {
+ return EmbeddedTargetOs::kMac;
+ } else if (string == "win") {
+ return EmbeddedTargetOs::kWin;
+ } else {
+ return EmbeddedTargetOs::kGeneric;
+ }
+}
+
+} // namespace
+
+std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter(
+ const char* target_arch, const char* target_os) {
+ auto embedded_target_arch = ToEmbeddedTargetArch(target_arch);
+ auto embedded_target_os = ToEmbeddedTargetOs(target_os);
+
+ if (embedded_target_os == EmbeddedTargetOs::kAIX) {
+ return base::make_unique<PlatformEmbeddedFileWriterAIX>(
+ embedded_target_arch, embedded_target_os);
+ } else if (embedded_target_os == EmbeddedTargetOs::kMac) {
+ return base::make_unique<PlatformEmbeddedFileWriterMac>(
+ embedded_target_arch, embedded_target_os);
+ } else if (embedded_target_os == EmbeddedTargetOs::kWin) {
+ return base::make_unique<PlatformEmbeddedFileWriterWin>(
+ embedded_target_arch, embedded_target_os);
+ } else {
+ return base::make_unique<PlatformEmbeddedFileWriterGeneric>(
+ embedded_target_arch, embedded_target_os);
+ }
+
+ UNREACHABLE();
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.h b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.h
new file mode 100644
index 0000000000..0f1763ba24
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.h
@@ -0,0 +1,105 @@
+// Copyright 2019 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_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
+#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
+
+#include <cinttypes>
+#include <cstdio> // For FILE.
+#include <memory>
+
+namespace v8 {
+namespace internal {
+
+class EmbeddedData;
+
+enum DataDirective {
+ kByte,
+ kLong,
+ kQuad,
+ kOcta,
+};
+
+DataDirective PointerSizeDirective();
+int DataDirectiveSize(DataDirective directive);
+
+enum class EmbeddedTargetOs {
+ kAIX,
+ kChromeOS,
+ kFuchsia,
+ kMac,
+ kWin,
+ kGeneric, // Everything not covered above falls in here.
+};
+
+enum class EmbeddedTargetArch {
+ kArm,
+ kArm64,
+ kIA32,
+ kX64,
+ kGeneric, // Everything not covered above falls in here.
+};
+
+// The platform-dependent logic for emitting assembly code for the generated
+// embedded.S file.
+class PlatformEmbeddedFileWriterBase {
+ public:
+ virtual ~PlatformEmbeddedFileWriterBase() = default;
+
+ void SetFile(FILE* fp) { fp_ = fp; }
+ FILE* fp() const { return fp_; }
+
+ virtual void SectionText() = 0;
+ virtual void SectionData() = 0;
+ virtual void SectionRoData() = 0;
+
+ virtual void AlignToCodeAlignment() = 0;
+ virtual void AlignToDataAlignment() = 0;
+
+ virtual void DeclareUint32(const char* name, uint32_t value) = 0;
+ virtual void DeclarePointerToSymbol(const char* name, const char* target) = 0;
+
+ virtual void DeclareLabel(const char* name) = 0;
+
+ virtual void SourceInfo(int fileid, const char* filename, int line) = 0;
+ virtual void DeclareFunctionBegin(const char* name) = 0;
+ virtual void DeclareFunctionEnd(const char* name) = 0;
+
+ // Returns the number of printed characters.
+ virtual int HexLiteral(uint64_t value) = 0;
+
+ virtual void Comment(const char* string) = 0;
+ virtual void Newline() { fprintf(fp_, "\n"); }
+
+ virtual void FilePrologue() = 0;
+ virtual void DeclareExternalFilename(int fileid, const char* filename) = 0;
+ virtual void FileEpilogue() = 0;
+
+ 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.
+ //
+ // Emits unwinding data on x64 Windows, and does nothing otherwise.
+ virtual void MaybeEmitUnwindData(const char* unwind_info_symbol,
+ const char* embedded_blob_data_symbol,
+ const EmbeddedData* blob,
+ const void* unwind_infos) {}
+
+ protected:
+ FILE* fp_ = nullptr;
+};
+
+// The factory function. Returns the appropriate platform-specific instance.
+std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter(
+ const char* target_arch, const char* target_os);
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.cc
new file mode 100644
index 0000000000..4cee1ac131
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.cc
@@ -0,0 +1,140 @@
+// Copyright 2019 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.
+
+#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h"
+
+#include <algorithm>
+#include <cinttypes>
+
+#include "src/common/globals.h"
+
+namespace v8 {
+namespace internal {
+
+#define SYMBOL_PREFIX ""
+
+namespace {
+
+const char* DirectiveAsString(DataDirective directive) {
+ switch (directive) {
+ case kByte:
+ return ".byte";
+ case kLong:
+ return ".long";
+ case kQuad:
+ return ".quad";
+ case kOcta:
+ return ".octa";
+ }
+ UNREACHABLE();
+}
+
+} // namespace
+
+void PlatformEmbeddedFileWriterGeneric::SectionText() {
+ if (target_os_ == EmbeddedTargetOs::kChromeOS) {
+ fprintf(fp_, ".section .text.hot.embedded\n");
+ } else {
+ fprintf(fp_, ".section .text\n");
+ }
+}
+
+void PlatformEmbeddedFileWriterGeneric::SectionData() {
+ fprintf(fp_, ".section .data\n");
+}
+
+void PlatformEmbeddedFileWriterGeneric::SectionRoData() {
+ fprintf(fp_, ".section .rodata\n");
+}
+
+void PlatformEmbeddedFileWriterGeneric::DeclareUint32(const char* name,
+ uint32_t value) {
+ DeclareSymbolGlobal(name);
+ DeclareLabel(name);
+ IndentedDataDirective(kLong);
+ fprintf(fp_, "%d", value);
+ Newline();
+}
+
+void PlatformEmbeddedFileWriterGeneric::DeclarePointerToSymbol(
+ const char* name, const char* target) {
+ DeclareSymbolGlobal(name);
+ DeclareLabel(name);
+ fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
+ SYMBOL_PREFIX, target);
+}
+
+void PlatformEmbeddedFileWriterGeneric::DeclareSymbolGlobal(const char* name) {
+ fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterGeneric::AlignToCodeAlignment() {
+ fprintf(fp_, ".balign 32\n");
+}
+
+void PlatformEmbeddedFileWriterGeneric::AlignToDataAlignment() {
+ // On Windows ARM64, s390, PPC and possibly more platforms, aligned load
+ // instructions are used to retrieve v8_Default_embedded_blob_ and/or
+ // v8_Default_embedded_blob_size_. The generated instructions require the
+ // load target to be aligned at 8 bytes (2^3).
+ fprintf(fp_, ".balign 8\n");
+}
+
+void PlatformEmbeddedFileWriterGeneric::Comment(const char* string) {
+ fprintf(fp_, "// %s\n", string);
+}
+
+void PlatformEmbeddedFileWriterGeneric::DeclareLabel(const char* name) {
+ fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterGeneric::SourceInfo(int fileid,
+ const char* filename,
+ int line) {
+ fprintf(fp_, ".loc %d %d\n", fileid, line);
+}
+
+void PlatformEmbeddedFileWriterGeneric::DeclareFunctionBegin(const char* name) {
+ DeclareLabel(name);
+
+ if (target_arch_ == EmbeddedTargetArch::kArm ||
+ target_arch_ == EmbeddedTargetArch::kArm64) {
+ // ELF format binaries on ARM use ".type <function name>, %function"
+ // to create a DWARF subprogram entry.
+ fprintf(fp_, ".type %s, %%function\n", name);
+ } else {
+ // Other ELF Format binaries use ".type <function name>, @function"
+ // to create a DWARF subprogram entry.
+ fprintf(fp_, ".type %s, @function\n", name);
+ }
+}
+
+void PlatformEmbeddedFileWriterGeneric::DeclareFunctionEnd(const char* name) {}
+
+int PlatformEmbeddedFileWriterGeneric::HexLiteral(uint64_t value) {
+ return fprintf(fp_, "0x%" PRIx64, value);
+}
+
+void PlatformEmbeddedFileWriterGeneric::FilePrologue() {}
+
+void PlatformEmbeddedFileWriterGeneric::DeclareExternalFilename(
+ int fileid, const char* filename) {
+ // Replace any Windows style paths (backslashes) with forward
+ // slashes.
+ std::string fixed_filename(filename);
+ std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/');
+ fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
+}
+
+void PlatformEmbeddedFileWriterGeneric::FileEpilogue() {}
+
+int PlatformEmbeddedFileWriterGeneric::IndentedDataDirective(
+ DataDirective directive) {
+ return fprintf(fp_, " %s ", DirectiveAsString(directive));
+}
+
+#undef SYMBOL_PREFIX
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.h b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.h
new file mode 100644
index 0000000000..0c76e7df88
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-generic.h
@@ -0,0 +1,63 @@
+// Copyright 2019 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_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_GENERIC_H_
+#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_GENERIC_H_
+
+#include "src/base/macros.h"
+#include "src/common/globals.h" // For V8_OS_WIN_X64
+#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
+
+namespace v8 {
+namespace internal {
+
+class PlatformEmbeddedFileWriterGeneric
+ : public PlatformEmbeddedFileWriterBase {
+ public:
+ PlatformEmbeddedFileWriterGeneric(EmbeddedTargetArch target_arch,
+ EmbeddedTargetOs target_os)
+ : target_arch_(target_arch), target_os_(target_os) {
+ DCHECK(target_os_ == EmbeddedTargetOs::kChromeOS ||
+ target_os_ == EmbeddedTargetOs::kFuchsia ||
+ target_os_ == EmbeddedTargetOs::kGeneric);
+ }
+
+ void SectionText() override;
+ void SectionData() override;
+ void SectionRoData() override;
+
+ void AlignToCodeAlignment() override;
+ void AlignToDataAlignment() override;
+
+ void DeclareUint32(const char* name, uint32_t value) override;
+ void DeclarePointerToSymbol(const char* name, const char* target) override;
+
+ void DeclareLabel(const char* name) override;
+
+ void SourceInfo(int fileid, const char* filename, int line) override;
+ void DeclareFunctionBegin(const char* name) override;
+ void DeclareFunctionEnd(const char* name) override;
+
+ int HexLiteral(uint64_t value) override;
+
+ void Comment(const char* string) override;
+
+ void FilePrologue() override;
+ void DeclareExternalFilename(int fileid, const char* filename) override;
+ void FileEpilogue() override;
+
+ int IndentedDataDirective(DataDirective directive) override;
+
+ private:
+ void DeclareSymbolGlobal(const char* name);
+
+ private:
+ const EmbeddedTargetArch target_arch_;
+ const EmbeddedTargetOs target_os_;
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_GENERIC_H_
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.cc
new file mode 100644
index 0000000000..4be3c7ac6b
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.cc
@@ -0,0 +1,109 @@
+// Copyright 2019 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.
+
+#include "src/snapshot/embedded/platform-embedded-file-writer-mac.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+const char* DirectiveAsString(DataDirective directive) {
+ switch (directive) {
+ case kByte:
+ return ".byte";
+ case kLong:
+ return ".long";
+ case kQuad:
+ return ".quad";
+ case kOcta:
+ return ".octa";
+ }
+ UNREACHABLE();
+}
+
+} // namespace
+
+void PlatformEmbeddedFileWriterMac::SectionText() { fprintf(fp_, ".text\n"); }
+
+void PlatformEmbeddedFileWriterMac::SectionData() { fprintf(fp_, ".data\n"); }
+
+void PlatformEmbeddedFileWriterMac::SectionRoData() {
+ fprintf(fp_, ".const_data\n");
+}
+
+void PlatformEmbeddedFileWriterMac::DeclareUint32(const char* name,
+ uint32_t value) {
+ DeclareSymbolGlobal(name);
+ DeclareLabel(name);
+ IndentedDataDirective(kLong);
+ fprintf(fp_, "%d", value);
+ Newline();
+}
+
+void PlatformEmbeddedFileWriterMac::DeclarePointerToSymbol(const char* name,
+ const char* target) {
+ DeclareSymbolGlobal(name);
+ DeclareLabel(name);
+ fprintf(fp_, " %s _%s\n", DirectiveAsString(PointerSizeDirective()), target);
+}
+
+void PlatformEmbeddedFileWriterMac::DeclareSymbolGlobal(const char* name) {
+ // TODO(jgruber): Investigate switching to .globl. Using .private_extern
+ // prevents something along the compilation chain from messing with the
+ // embedded blob. Using .global here causes embedded blob hash verification
+ // failures at runtime.
+ fprintf(fp_, ".private_extern _%s\n", name);
+}
+
+void PlatformEmbeddedFileWriterMac::AlignToCodeAlignment() {
+ fprintf(fp_, ".balign 32\n");
+}
+
+void PlatformEmbeddedFileWriterMac::AlignToDataAlignment() {
+ fprintf(fp_, ".balign 8\n");
+}
+
+void PlatformEmbeddedFileWriterMac::Comment(const char* string) {
+ fprintf(fp_, "// %s\n", string);
+}
+
+void PlatformEmbeddedFileWriterMac::DeclareLabel(const char* name) {
+ fprintf(fp_, "_%s:\n", name);
+}
+
+void PlatformEmbeddedFileWriterMac::SourceInfo(int fileid, const char* filename,
+ int line) {
+ fprintf(fp_, ".loc %d %d\n", fileid, line);
+}
+
+void PlatformEmbeddedFileWriterMac::DeclareFunctionBegin(const char* name) {
+ DeclareLabel(name);
+
+ // TODO(mvstanton): Investigate the proper incantations to mark the label as
+ // a function on OSX.
+}
+
+void PlatformEmbeddedFileWriterMac::DeclareFunctionEnd(const char* name) {}
+
+int PlatformEmbeddedFileWriterMac::HexLiteral(uint64_t value) {
+ return fprintf(fp_, "0x%" PRIx64, value);
+}
+
+void PlatformEmbeddedFileWriterMac::FilePrologue() {}
+
+void PlatformEmbeddedFileWriterMac::DeclareExternalFilename(
+ int fileid, const char* filename) {
+ fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
+}
+
+void PlatformEmbeddedFileWriterMac::FileEpilogue() {}
+
+int PlatformEmbeddedFileWriterMac::IndentedDataDirective(
+ DataDirective directive) {
+ return fprintf(fp_, " %s ", DirectiveAsString(directive));
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.h b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.h
new file mode 100644
index 0000000000..4f2cd3d6ae
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-mac.h
@@ -0,0 +1,61 @@
+// Copyright 2019 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_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_MAC_H_
+#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_MAC_H_
+
+#include "src/base/macros.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
+
+namespace v8 {
+namespace internal {
+
+class PlatformEmbeddedFileWriterMac : public PlatformEmbeddedFileWriterBase {
+ public:
+ PlatformEmbeddedFileWriterMac(EmbeddedTargetArch target_arch,
+ EmbeddedTargetOs target_os)
+ : target_arch_(target_arch), target_os_(target_os) {
+ USE(target_arch_);
+ USE(target_os_);
+ DCHECK_EQ(target_os_, EmbeddedTargetOs::kMac);
+ }
+
+ void SectionText() override;
+ void SectionData() override;
+ void SectionRoData() override;
+
+ void AlignToCodeAlignment() override;
+ void AlignToDataAlignment() override;
+
+ void DeclareUint32(const char* name, uint32_t value) override;
+ void DeclarePointerToSymbol(const char* name, const char* target) override;
+
+ void DeclareLabel(const char* name) override;
+
+ void SourceInfo(int fileid, const char* filename, int line) override;
+ void DeclareFunctionBegin(const char* name) override;
+ void DeclareFunctionEnd(const char* name) override;
+
+ int HexLiteral(uint64_t value) override;
+
+ void Comment(const char* string) override;
+
+ void FilePrologue() override;
+ void DeclareExternalFilename(int fileid, const char* filename) override;
+ void FileEpilogue() override;
+
+ int IndentedDataDirective(DataDirective directive) override;
+
+ private:
+ void DeclareSymbolGlobal(const char* name);
+
+ private:
+ const EmbeddedTargetArch target_arch_;
+ const EmbeddedTargetOs target_os_;
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_MAC_H_
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc
new file mode 100644
index 0000000000..69457e11a5
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc
@@ -0,0 +1,615 @@
+// Copyright 2019 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.
+
+#include "src/snapshot/embedded/platform-embedded-file-writer-win.h"
+
+#include <algorithm>
+
+#include "src/common/globals.h" // For V8_OS_WIN_X64.
+
+#if defined(V8_OS_WIN_X64)
+#include "src/builtins/builtins.h"
+#include "src/diagnostics/unwinding-info-win64.h"
+#include "src/snapshot/embedded/embedded-data.h"
+#endif
+
+namespace v8 {
+namespace internal {
+
+// V8_CC_MSVC is true for both MSVC and clang on windows. clang can handle
+// __asm__-style inline assembly but MSVC cannot, and thus we need a more
+// precise compiler detection that can distinguish between the two. clang on
+// windows sets both __clang__ and _MSC_VER, MSVC sets only _MSC_VER.
+#if defined(_MSC_VER) && !defined(__clang__)
+#define V8_COMPILER_IS_MSVC
+#endif
+
+// MSVC uses MASM for x86 and x64, while it has a ARMASM for ARM32 and
+// ARMASM64 for ARM64. Since ARMASM and ARMASM64 accept a slightly tweaked
+// version of ARM assembly language, they are referred to together in Visual
+// Studio project files as MARMASM.
+//
+// ARM assembly language docs:
+// http://infocenter.arm.com/help/topic/com.arm.doc.dui0802b/index.html
+// Microsoft ARM assembler and assembly language docs:
+// https://docs.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference
+#if defined(V8_COMPILER_IS_MSVC)
+#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_ARM)
+#define V8_ASSEMBLER_IS_MARMASM
+#elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
+#define V8_ASSEMBLER_IS_MASM
+#else
+#error Unknown Windows assembler target architecture.
+#endif
+#endif
+
+// Name mangling.
+// Symbols are prefixed with an underscore on 32-bit architectures.
+#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM64)
+#define SYMBOL_PREFIX "_"
+#else
+#define SYMBOL_PREFIX ""
+#endif
+
+// Notes:
+//
+// Cross-bitness builds are unsupported. It's thus safe to detect bitness
+// through compile-time defines.
+//
+// Cross-compiler builds (e.g. with mixed use of clang / MSVC) are likewise
+// unsupported and hence the compiler can also be detected through compile-time
+// defines.
+
+namespace {
+
+const char* DirectiveAsString(DataDirective directive) {
+#if defined(V8_ASSEMBLER_IS_MASM)
+ switch (directive) {
+ case kByte:
+ return "BYTE";
+ case kLong:
+ return "DWORD";
+ case kQuad:
+ return "QWORD";
+ default:
+ UNREACHABLE();
+ }
+#elif defined(V8_ASSEMBLER_IS_MARMASM)
+ switch (directive) {
+ case kByte:
+ return "DCB";
+ case kLong:
+ return "DCDU";
+ case kQuad:
+ return "DCQU";
+ default:
+ UNREACHABLE();
+ }
+#else
+ switch (directive) {
+ case kByte:
+ return ".byte";
+ case kLong:
+ return ".long";
+ case kQuad:
+ return ".quad";
+ case kOcta:
+ return ".octa";
+ }
+ UNREACHABLE();
+#endif
+}
+
+#if defined(V8_OS_WIN_X64)
+
+void WriteUnwindInfoEntry(PlatformEmbeddedFileWriterWin* w,
+ const char* unwind_info_symbol,
+ const char* embedded_blob_data_symbol,
+ uint64_t rva_start, uint64_t rva_end) {
+ w->DeclareRvaToSymbol(embedded_blob_data_symbol, rva_start);
+ w->DeclareRvaToSymbol(embedded_blob_data_symbol, rva_end);
+ w->DeclareRvaToSymbol(unwind_info_symbol);
+}
+
+void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
+ const char* unwind_info_symbol,
+ const char* embedded_blob_data_symbol,
+ const EmbeddedData* blob,
+ const win64_unwindinfo::BuiltinUnwindInfo* unwind_infos) {
+ // Emit an UNWIND_INFO (XDATA) struct, which contains the unwinding
+ // information that is used for all builtin functions.
+ DCHECK(win64_unwindinfo::CanEmitUnwindInfoForBuiltins());
+ w->Comment("xdata for all the code in the embedded blob.");
+ w->DeclareExternalFunction(CRASH_HANDLER_FUNCTION_NAME_STRING);
+
+ w->StartXdataSection();
+ {
+ w->DeclareLabel(unwind_info_symbol);
+
+ std::vector<uint8_t> xdata =
+ win64_unwindinfo::GetUnwindInfoForBuiltinFunctions();
+ DCHECK(!xdata.empty());
+
+ w->IndentedDataDirective(kByte);
+ for (size_t i = 0; i < xdata.size(); i++) {
+ if (i > 0) fprintf(w->fp(), ",");
+ w->HexLiteral(xdata[i]);
+ }
+ w->Newline();
+
+ w->Comment(" ExceptionHandler");
+ w->DeclareRvaToSymbol(CRASH_HANDLER_FUNCTION_NAME_STRING);
+ }
+ w->EndXdataSection();
+ w->Newline();
+
+ // Emit a RUNTIME_FUNCTION (PDATA) entry for each builtin function, as
+ // documented here:
+ // https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
+ w->Comment(
+ "pdata for all the code in the embedded blob (structs of type "
+ "RUNTIME_FUNCTION).");
+ w->Comment(" BeginAddress");
+ w->Comment(" EndAddress");
+ w->Comment(" UnwindInfoAddress");
+ w->StartPdataSection();
+ {
+ Address prev_builtin_end_offset = 0;
+ for (int i = 0; i < Builtins::builtin_count; i++) {
+ // Some builtins are leaf functions from the point of view of Win64 stack
+ // walking: they do not move the stack pointer and do not require a PDATA
+ // entry because the return address can be retrieved from [rsp].
+ 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();
+ if (xdata_desc.empty()) {
+ // Some builtins do not have any "push rbp - mov rbp, rsp" instructions
+ // to start a stack frame. We still emit a PDATA entry as if they had,
+ // relying on the fact that we can find the previous frame address from
+ // rbp in most cases. Note that since the function does not really start
+ // with a 'push rbp' we need to specify the start RVA in the PDATA entry
+ // a few bytes before the beginning of the function, if it does not
+ // overlap the end of the previous builtin.
+ WriteUnwindInfoEntry(
+ w, unwind_info_symbol, embedded_blob_data_symbol,
+ std::max(prev_builtin_end_offset,
+ builtin_start_offset - win64_unwindinfo::kRbpPrefixLength),
+ builtin_start_offset + builtin_size);
+ } else {
+ // Some builtins have one or more "push rbp - mov rbp, rsp" sequences,
+ // but not necessarily at the beginning of the function. In this case
+ // we want to yield a PDATA entry for each block of instructions that
+ // emit an rbp frame. If the function does not start with 'push rbp'
+ // we also emit a PDATA entry for the initial block of code up to the
+ // first 'push rbp', like in the case above.
+ if (xdata_desc[0] > 0) {
+ WriteUnwindInfoEntry(w, unwind_info_symbol, embedded_blob_data_symbol,
+ std::max(prev_builtin_end_offset,
+ builtin_start_offset -
+ win64_unwindinfo::kRbpPrefixLength),
+ builtin_start_offset + xdata_desc[0]);
+ }
+
+ 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;
+ WriteUnwindInfoEntry(w, unwind_info_symbol, embedded_blob_data_symbol,
+ builtin_start_offset + chunk_start,
+ builtin_start_offset + chunk_end);
+ }
+ }
+
+ prev_builtin_end_offset = builtin_start_offset + builtin_size;
+ w->Newline();
+ }
+ }
+ w->EndPdataSection();
+ w->Newline();
+}
+#endif // defined(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)
+ 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)
+}
+
+// Windows, MSVC, not arm/arm64.
+// -----------------------------------------------------------------------------
+
+#if defined(V8_ASSEMBLER_IS_MASM)
+
+// For MSVC builds we emit assembly in MASM syntax.
+// See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
+
+void PlatformEmbeddedFileWriterWin::SectionText() { fprintf(fp_, ".CODE\n"); }
+
+void PlatformEmbeddedFileWriterWin::SectionData() { fprintf(fp_, ".DATA\n"); }
+
+void PlatformEmbeddedFileWriterWin::SectionRoData() {
+ fprintf(fp_, ".CONST\n");
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareUint32(const char* name,
+ uint32_t value) {
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
+ value);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclarePointerToSymbol(const char* name,
+ const char* target) {
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
+ DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
+}
+
+void PlatformEmbeddedFileWriterWin::StartPdataSection() {
+ fprintf(fp_, "OPTION DOTNAME\n");
+ fprintf(fp_, ".pdata SEGMENT DWORD READ ''\n");
+}
+
+void PlatformEmbeddedFileWriterWin::EndPdataSection() {
+ fprintf(fp_, ".pdata ENDS\n");
+}
+
+void PlatformEmbeddedFileWriterWin::StartXdataSection() {
+ fprintf(fp_, "OPTION DOTNAME\n");
+ fprintf(fp_, ".xdata SEGMENT DWORD READ ''\n");
+}
+
+void PlatformEmbeddedFileWriterWin::EndXdataSection() {
+ fprintf(fp_, ".xdata ENDS\n");
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareExternalFunction(const char* name) {
+ fprintf(fp_, "EXTERN %s : PROC\n", name);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareRvaToSymbol(const char* name,
+ uint64_t offset) {
+ if (offset > 0) {
+ fprintf(fp_, "DD IMAGEREL %s+%llu\n", name, offset);
+ } else {
+ fprintf(fp_, "DD IMAGEREL %s\n", name);
+ }
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareSymbolGlobal(const char* name) {
+ fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::AlignToCodeAlignment() {
+ // Diverges from other platforms due to compile error
+ // 'invalid combination with segment alignment'.
+ fprintf(fp_, "ALIGN 4\n");
+}
+
+void PlatformEmbeddedFileWriterWin::AlignToDataAlignment() {
+ fprintf(fp_, "ALIGN 4\n");
+}
+
+void PlatformEmbeddedFileWriterWin::Comment(const char* string) {
+ fprintf(fp_, "; %s\n", string);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareLabel(const char* name) {
+ fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
+ DirectiveAsString(kByte));
+}
+
+void PlatformEmbeddedFileWriterWin::SourceInfo(int fileid, const char* filename,
+ int line) {
+ // TODO(mvstanton): output source information for MSVC.
+ // Its syntax is #line <line> "<filename>"
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareFunctionBegin(const char* name) {
+ fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareFunctionEnd(const char* name) {
+ fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
+}
+
+int PlatformEmbeddedFileWriterWin::HexLiteral(uint64_t value) {
+ return fprintf(fp_, "0%" PRIx64 "h", value);
+}
+
+void PlatformEmbeddedFileWriterWin::FilePrologue() {
+ if (target_arch_ != EmbeddedTargetArch::kX64) {
+ fprintf(fp_, ".MODEL FLAT\n");
+ }
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareExternalFilename(
+ int fileid, const char* filename) {}
+
+void PlatformEmbeddedFileWriterWin::FileEpilogue() { fprintf(fp_, "END\n"); }
+
+int PlatformEmbeddedFileWriterWin::IndentedDataDirective(
+ DataDirective directive) {
+ return fprintf(fp_, " %s ", DirectiveAsString(directive));
+}
+
+// Windows, MSVC, arm/arm64.
+// -----------------------------------------------------------------------------
+
+#elif defined(V8_ASSEMBLER_IS_MARMASM)
+
+// The AARCH64 ABI requires instructions be 4-byte-aligned and Windows does
+// not have a stricter alignment requirement (see the TEXTAREA macro of
+// kxarm64.h in the Windows SDK), so code is 4-byte-aligned.
+// The data fields in the emitted assembly tend to be accessed with 8-byte
+// LDR instructions, so data is 8-byte-aligned.
+//
+// armasm64's warning A4228 states
+// Alignment value exceeds AREA alignment; alignment not guaranteed
+// To ensure that ALIGN directives are honored, their values are defined as
+// equal to their corresponding AREA's ALIGN attributes.
+
+#define ARM64_DATA_ALIGNMENT_POWER (3)
+#define ARM64_DATA_ALIGNMENT (1 << ARM64_DATA_ALIGNMENT_POWER)
+#define ARM64_CODE_ALIGNMENT_POWER (2)
+#define ARM64_CODE_ALIGNMENT (1 << ARM64_CODE_ALIGNMENT_POWER)
+
+void PlatformEmbeddedFileWriterWin::SectionText() {
+ fprintf(fp_, " AREA |.text|, CODE, ALIGN=%d, READONLY\n",
+ ARM64_CODE_ALIGNMENT_POWER);
+}
+
+void PlatformEmbeddedFileWriterWin::SectionData() {
+ fprintf(fp_, " AREA |.data|, DATA, ALIGN=%d, READWRITE\n",
+ ARM64_DATA_ALIGNMENT_POWER);
+}
+
+void PlatformEmbeddedFileWriterWin::SectionRoData() {
+ fprintf(fp_, " AREA |.rodata|, DATA, ALIGN=%d, READONLY\n",
+ ARM64_DATA_ALIGNMENT_POWER);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareUint32(const char* name,
+ uint32_t value) {
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
+ value);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclarePointerToSymbol(const char* name,
+ const char* target) {
+ DeclareSymbolGlobal(name);
+ fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
+ DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareSymbolGlobal(const char* name) {
+ fprintf(fp_, " EXPORT %s%s\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::AlignToCodeAlignment() {
+ fprintf(fp_, " ALIGN %d\n", ARM64_CODE_ALIGNMENT);
+}
+
+void PlatformEmbeddedFileWriterWin::AlignToDataAlignment() {
+ fprintf(fp_, " ALIGN %d\n", ARM64_DATA_ALIGNMENT);
+}
+
+void PlatformEmbeddedFileWriterWin::Comment(const char* string) {
+ fprintf(fp_, "; %s\n", string);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareLabel(const char* name) {
+ fprintf(fp_, "%s%s\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::SourceInfo(int fileid, const char* filename,
+ int line) {
+ // TODO(mvstanton): output source information for MSVC.
+ // Its syntax is #line <line> "<filename>"
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareFunctionBegin(const char* name) {
+ fprintf(fp_, "%s%s FUNCTION\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareFunctionEnd(const char* name) {
+ fprintf(fp_, " ENDFUNC\n");
+}
+
+int PlatformEmbeddedFileWriterWin::HexLiteral(uint64_t value) {
+ return fprintf(fp_, "0x%" PRIx64, value);
+}
+
+void PlatformEmbeddedFileWriterWin::FilePrologue() {}
+
+void PlatformEmbeddedFileWriterWin::DeclareExternalFilename(
+ int fileid, const char* filename) {}
+
+void PlatformEmbeddedFileWriterWin::FileEpilogue() { fprintf(fp_, " END\n"); }
+
+int PlatformEmbeddedFileWriterWin::IndentedDataDirective(
+ DataDirective directive) {
+ return fprintf(fp_, " %s ", DirectiveAsString(directive));
+}
+
+#undef ARM64_DATA_ALIGNMENT_POWER
+#undef ARM64_DATA_ALIGNMENT
+#undef ARM64_CODE_ALIGNMENT_POWER
+#undef ARM64_CODE_ALIGNMENT
+
+// All Windows builds without MSVC.
+// -----------------------------------------------------------------------------
+
+#else
+
+void PlatformEmbeddedFileWriterWin::SectionText() {
+ fprintf(fp_, ".section .text\n");
+}
+
+void PlatformEmbeddedFileWriterWin::SectionData() {
+ fprintf(fp_, ".section .data\n");
+}
+
+void PlatformEmbeddedFileWriterWin::SectionRoData() {
+ fprintf(fp_, ".section .rdata\n");
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareUint32(const char* name,
+ uint32_t value) {
+ DeclareSymbolGlobal(name);
+ DeclareLabel(name);
+ IndentedDataDirective(kLong);
+ fprintf(fp_, "%d", value);
+ Newline();
+}
+
+void PlatformEmbeddedFileWriterWin::DeclarePointerToSymbol(const char* name,
+ const char* target) {
+ DeclareSymbolGlobal(name);
+ DeclareLabel(name);
+ fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
+ SYMBOL_PREFIX, target);
+}
+
+void PlatformEmbeddedFileWriterWin::StartPdataSection() {
+ fprintf(fp_, ".section .pdata\n");
+}
+
+void PlatformEmbeddedFileWriterWin::EndPdataSection() {}
+
+void PlatformEmbeddedFileWriterWin::StartXdataSection() {
+ fprintf(fp_, ".section .xdata\n");
+}
+
+void PlatformEmbeddedFileWriterWin::EndXdataSection() {}
+
+void PlatformEmbeddedFileWriterWin::DeclareExternalFunction(const char* name) {}
+
+void PlatformEmbeddedFileWriterWin::DeclareRvaToSymbol(const char* name,
+ uint64_t offset) {
+ if (offset > 0) {
+ fprintf(fp_, ".rva %s + %" PRIu64 "\n", name, offset);
+ } else {
+ fprintf(fp_, ".rva %s\n", name);
+ }
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareSymbolGlobal(const char* name) {
+ fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::AlignToCodeAlignment() {
+ fprintf(fp_, ".balign 32\n");
+}
+
+void PlatformEmbeddedFileWriterWin::AlignToDataAlignment() {
+ // On Windows ARM64, s390, PPC and possibly more platforms, aligned load
+ // instructions are used to retrieve v8_Default_embedded_blob_ and/or
+ // v8_Default_embedded_blob_size_. The generated instructions require the
+ // load target to be aligned at 8 bytes (2^3).
+ fprintf(fp_, ".balign 8\n");
+}
+
+void PlatformEmbeddedFileWriterWin::Comment(const char* string) {
+ fprintf(fp_, "// %s\n", string);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareLabel(const char* name) {
+ fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
+}
+
+void PlatformEmbeddedFileWriterWin::SourceInfo(int fileid, const char* filename,
+ int line) {
+ fprintf(fp_, ".loc %d %d\n", fileid, line);
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareFunctionBegin(const char* name) {
+ DeclareLabel(name);
+
+ if (target_arch_ == EmbeddedTargetArch::kArm64) {
+ // Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
+ // in PE/COFF for Windows.
+ } else {
+ // The directives for inserting debugging information on Windows come
+ // from the PE (Portable Executable) and COFF (Common Object File Format)
+ // standards. Documented here:
+ // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
+ //
+ // .scl 2 means StorageClass external.
+ // .type 32 means Type Representation Function.
+ fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
+ }
+}
+
+void PlatformEmbeddedFileWriterWin::DeclareFunctionEnd(const char* name) {}
+
+int PlatformEmbeddedFileWriterWin::HexLiteral(uint64_t value) {
+ return fprintf(fp_, "0x%" PRIx64, value);
+}
+
+void PlatformEmbeddedFileWriterWin::FilePrologue() {}
+
+void PlatformEmbeddedFileWriterWin::DeclareExternalFilename(
+ int fileid, const char* filename) {
+ // Replace any Windows style paths (backslashes) with forward
+ // slashes.
+ std::string fixed_filename(filename);
+ std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/');
+ fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
+}
+
+void PlatformEmbeddedFileWriterWin::FileEpilogue() {}
+
+int PlatformEmbeddedFileWriterWin::IndentedDataDirective(
+ DataDirective directive) {
+ return fprintf(fp_, " %s ", DirectiveAsString(directive));
+}
+
+#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
+#undef V8_COMPILER_IS_MSVC
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.h b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.h
new file mode 100644
index 0000000000..376c6cc6ef
--- /dev/null
+++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.h
@@ -0,0 +1,78 @@
+// Copyright 2019 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_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_WIN_H_
+#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_WIN_H_
+
+#include "src/base/macros.h"
+#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
+
+namespace v8 {
+namespace internal {
+
+class PlatformEmbeddedFileWriterWin : public PlatformEmbeddedFileWriterBase {
+ public:
+ PlatformEmbeddedFileWriterWin(EmbeddedTargetArch target_arch,
+ EmbeddedTargetOs target_os)
+ : target_arch_(target_arch), target_os_(target_os) {
+ USE(target_os_);
+ DCHECK_EQ(target_os_, EmbeddedTargetOs::kWin);
+ }
+
+ void SectionText() override;
+ void SectionData() override;
+ void SectionRoData() override;
+
+ void AlignToCodeAlignment() override;
+ void AlignToDataAlignment() override;
+
+ void DeclareUint32(const char* name, uint32_t value) override;
+ void DeclarePointerToSymbol(const char* name, const char* target) override;
+
+ void DeclareLabel(const char* name) override;
+
+ void SourceInfo(int fileid, const char* filename, int line) override;
+ void DeclareFunctionBegin(const char* name) override;
+ void DeclareFunctionEnd(const char* name) override;
+
+ int HexLiteral(uint64_t value) override;
+
+ void Comment(const char* string) override;
+
+ void FilePrologue() override;
+ void DeclareExternalFilename(int fileid, const char* filename) override;
+ void FileEpilogue() override;
+
+ int IndentedDataDirective(DataDirective directive) override;
+
+ DataDirective ByteChunkDataDirective() const override;
+ int WriteByteChunk(const uint8_t* data) override;
+
+ void StartPdataSection();
+ void EndPdataSection();
+ void StartXdataSection();
+ void EndXdataSection();
+ void DeclareExternalFunction(const char* name);
+
+ // Emits an RVA (address relative to the module load address) specified as an
+ // offset from a given symbol.
+ void DeclareRvaToSymbol(const char* name, uint64_t offset = 0);
+
+ void MaybeEmitUnwindData(const char* unwind_info_symbol,
+ const char* embedded_blob_data_symbol,
+ const EmbeddedData* blob,
+ const void* unwind_infos) override;
+
+ private:
+ void DeclareSymbolGlobal(const char* name);
+
+ private:
+ const EmbeddedTargetArch target_arch_;
+ const EmbeddedTargetOs target_os_;
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_WIN_H_
diff --git a/deps/v8/src/snapshot/mksnapshot.cc b/deps/v8/src/snapshot/mksnapshot.cc
index f44f71e145..6bf198230f 100644
--- a/deps/v8/src/snapshot/mksnapshot.cc
+++ b/deps/v8/src/snapshot/mksnapshot.cc
@@ -8,16 +8,16 @@
#include <iomanip>
#include "include/libplatform/libplatform.h"
-#include "src/assembler-arch.h"
#include "src/base/platform/platform.h"
-#include "src/flags.h"
-#include "src/msan.h"
-#include "src/snapshot/embedded-file-writer.h"
+#include "src/codegen/assembler-arch.h"
+#include "src/codegen/source-position-table.h"
+#include "src/flags/flags.h"
+#include "src/sanitizer/msan.h"
+#include "src/snapshot/embedded/embedded-file-writer.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/partial-serializer.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/startup-serializer.h"
-#include "src/source-position-table.h"
namespace {
@@ -70,7 +70,7 @@ class SnapshotFileWriter {
static void WriteSnapshotFilePrefix(FILE* fp) {
fprintf(fp, "// Autogenerated snapshot file. Do not edit.\n\n");
- fprintf(fp, "#include \"src/v8.h\"\n");
+ fprintf(fp, "#include \"src/init/v8.h\"\n");
fprintf(fp, "#include \"src/base/platform/platform.h\"\n\n");
fprintf(fp, "#include \"src/snapshot/snapshot.h\"\n\n");
fprintf(fp, "namespace v8 {\n");
@@ -87,7 +87,8 @@ class SnapshotFileWriter {
static void WriteSnapshotFileData(FILE* fp,
const i::Vector<const i::byte>& blob) {
- fprintf(fp, "static const byte blob_data[] = {\n");
+ fprintf(fp,
+ "alignas(kPointerAlignment) static const byte blob_data[] = {\n");
WriteBinaryContentsAsCArray(fp, blob);
fprintf(fp, "};\n");
fprintf(fp, "static const int blob_size = %d;\n", blob.length());
@@ -143,100 +144,37 @@ char* GetExtraCode(char* filename, const char* description) {
return chars;
}
-bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,
- const char* utf8_source, const char* name) {
+v8::StartupData CreateSnapshotDataBlob(v8::Isolate* isolate,
+ const char* embedded_source) {
v8::base::ElapsedTimer timer;
timer.Start();
- v8::Context::Scope context_scope(context);
- v8::TryCatch try_catch(isolate);
- v8::Local<v8::String> source_string;
- if (!v8::String::NewFromUtf8(isolate, utf8_source, v8::NewStringType::kNormal)
- .ToLocal(&source_string)) {
- return false;
- }
- v8::Local<v8::String> resource_name =
- v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal)
- .ToLocalChecked();
- v8::ScriptOrigin origin(resource_name);
- v8::ScriptCompiler::Source source(source_string, origin);
- v8::Local<v8::Script> script;
- if (!v8::ScriptCompiler::Compile(context, &source).ToLocal(&script))
- return false;
- if (script->Run(context).IsEmpty()) return false;
- if (i::FLAG_profile_deserialization) {
- i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name,
- timer.Elapsed().InMillisecondsF());
- }
- timer.Stop();
- CHECK(!try_catch.HasCaught());
- return true;
-}
-v8::StartupData CreateSnapshotDataBlob(v8::SnapshotCreator* snapshot_creator,
- const char* script_source = nullptr) {
- // Create a new isolate and a new context from scratch, optionally run
- // a script to embed, and serialize to create a snapshot blob.
- v8::StartupData result = {nullptr, 0};
- v8::base::ElapsedTimer timer;
- timer.Start();
- {
- v8::Isolate* isolate = snapshot_creator->GetIsolate();
- {
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- if (script_source != nullptr &&
- !RunExtraCode(isolate, context, script_source, "<embedded>")) {
- return result;
- }
- snapshot_creator->SetDefaultContext(context);
- }
- result = snapshot_creator->CreateBlob(
- v8::SnapshotCreator::FunctionCodeHandling::kClear);
- }
+ v8::StartupData result = i::CreateSnapshotDataBlobInternal(
+ v8::SnapshotCreator::FunctionCodeHandling::kClear, embedded_source,
+ isolate);
if (i::FLAG_profile_deserialization) {
i::PrintF("Creating snapshot took %0.3f ms\n",
timer.Elapsed().InMillisecondsF());
}
+
timer.Stop();
return result;
}
-v8::StartupData WarmUpSnapshotDataBlob(v8::SnapshotCreator* snapshot_creator,
+v8::StartupData WarmUpSnapshotDataBlob(v8::StartupData cold_snapshot_blob,
const char* warmup_source) {
- CHECK_NOT_NULL(warmup_source);
- // Use following steps to create a warmed up snapshot blob from a cold one:
- // - Create a new isolate from the cold snapshot.
- // - Create a new context to run the warmup script. This will trigger
- // compilation of executed functions.
- // - Create a new context. This context will be unpolluted.
- // - Serialize the isolate and the second context into a new snapshot blob.
- v8::StartupData result = {nullptr, 0};
v8::base::ElapsedTimer timer;
timer.Start();
- {
- v8::Isolate* isolate = snapshot_creator->GetIsolate();
- {
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) {
- return result;
- }
- }
- {
- v8::HandleScope handle_scope(isolate);
- isolate->ContextDisposedNotification(false);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- snapshot_creator->SetDefaultContext(context);
- }
- result = snapshot_creator->CreateBlob(
- v8::SnapshotCreator::FunctionCodeHandling::kKeep);
- }
+
+ v8::StartupData result =
+ i::WarmUpSnapshotDataBlobInternal(cold_snapshot_blob, warmup_source);
if (i::FLAG_profile_deserialization) {
i::PrintF("Warming up snapshot took %0.3f ms\n",
timer.Elapsed().InMillisecondsF());
}
+
timer.Stop();
return result;
}
@@ -301,9 +239,9 @@ int main(int argc, char** argv) {
i::EmbeddedFileWriter embedded_writer;
embedded_writer.SetEmbeddedFile(i::FLAG_embedded_src);
- if (i::FLAG_embedded_variant != nullptr) {
- embedded_writer.SetEmbeddedVariant(i::FLAG_embedded_variant);
- }
+ embedded_writer.SetEmbeddedVariant(i::FLAG_embedded_variant);
+ embedded_writer.SetTargetArch(i::FLAG_target_arch);
+ embedded_writer.SetTargetOs(i::FLAG_target_os);
std::unique_ptr<char> embed_script(
GetExtraCode(argc >= 2 ? argv[1] : nullptr, "embedding"));
@@ -331,18 +269,18 @@ int main(int argc, char** argv) {
// to be written out if builtins are embedded.
i_isolate->RegisterEmbeddedFileWriter(&embedded_writer);
}
- v8::SnapshotCreator snapshot_creator(isolate);
+ blob = CreateSnapshotDataBlob(isolate, embed_script.get());
if (i::FLAG_embedded_builtins) {
+ // At this point, the Isolate has been torn down but the embedded blob
+ // is still alive (we called DisableEmbeddedBlobRefcounting above).
+ // That's fine as far as the embedded file writer is concerned.
WriteEmbeddedFile(&embedded_writer);
}
- blob = CreateSnapshotDataBlob(&snapshot_creator, embed_script.get());
}
if (warmup_script) {
- CHECK(blob.raw_size > 0 && blob.data != nullptr);
v8::StartupData cold = blob;
- v8::SnapshotCreator snapshot_creator(nullptr, &cold);
- blob = WarmUpSnapshotDataBlob(&snapshot_creator, warmup_script.get());
+ blob = WarmUpSnapshotDataBlob(cold, warmup_script.get());
delete[] cold.data;
}
diff --git a/deps/v8/src/snapshot/natives-common.cc b/deps/v8/src/snapshot/natives-common.cc
index 4cb7b5f0da..321b74b45c 100644
--- a/deps/v8/src/snapshot/natives-common.cc
+++ b/deps/v8/src/snapshot/natives-common.cc
@@ -5,7 +5,7 @@
// The common functionality when building with internal or external natives.
#include "src/heap/heap.h"
-#include "src/objects-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/snapshot/natives.h"
namespace v8 {
@@ -19,7 +19,7 @@ NativesExternalStringResource::NativesExternalStringResource(NativeType type,
CHECK_EQ(EXTRAS, type_);
DCHECK(index < ExtraNatives::GetBuiltinsCount());
source = ExtraNatives::GetScriptSource(index);
- data_ = source.start();
+ data_ = source.begin();
length_ = source.length();
}
diff --git a/deps/v8/src/snapshot/natives-external.cc b/deps/v8/src/snapshot/natives-external.cc
index c9177bbc99..fe67f33087 100644
--- a/deps/v8/src/snapshot/natives-external.cc
+++ b/deps/v8/src/snapshot/natives-external.cc
@@ -6,7 +6,7 @@
#include "src/base/logging.h"
#include "src/snapshot/snapshot-source-sink.h"
-#include "src/vector.h"
+#include "src/utils/vector.h"
#ifndef V8_USE_EXTERNAL_STARTUP_DATA
#error natives-external.cc is used only for the external snapshot build.
@@ -44,7 +44,7 @@ class NativesStore {
for (int i = 0; i < static_cast<int>(native_ids_.size()); ++i) {
int native_id_length = native_ids_[i].length();
if ((static_cast<int>(strlen(id)) == native_id_length) &&
- (strncmp(id, native_ids_[i].start(), native_id_length) == 0)) {
+ (strncmp(id, native_ids_[i].begin(), native_id_length) == 0)) {
return i;
}
}
@@ -76,9 +76,9 @@ class NativesStore {
const char extension[] = ".js";
Vector<char> name(Vector<char>::New(id_length + sizeof(native) - 1 +
sizeof(extension) - 1));
- memcpy(name.start(), native, sizeof(native) - 1);
- memcpy(name.start() + sizeof(native) - 1, id, id_length);
- memcpy(name.start() + sizeof(native) - 1 + id_length, extension,
+ memcpy(name.begin(), native, sizeof(native) - 1);
+ memcpy(name.begin() + sizeof(native) - 1, id, id_length);
+ memcpy(name.begin() + sizeof(native) - 1 + id_length, extension,
sizeof(extension) - 1);
return Vector<const char>::cast(name);
}
diff --git a/deps/v8/src/snapshot/natives.h b/deps/v8/src/snapshot/natives.h
index 76b8bf1bde..f294d33b5c 100644
--- a/deps/v8/src/snapshot/natives.h
+++ b/deps/v8/src/snapshot/natives.h
@@ -6,8 +6,8 @@
#define V8_SNAPSHOT_NATIVES_H_
#include "include/v8.h"
-#include "src/objects.h"
-#include "src/vector.h"
+#include "src/utils/vector.h"
+#include "src/objects/objects.h"
namespace v8 { class StartupData; } // Forward declaration.
diff --git a/deps/v8/src/snapshot/object-deserializer.cc b/deps/v8/src/snapshot/object-deserializer.cc
index 44b7088380..63a0cfca17 100644
--- a/deps/v8/src/snapshot/object-deserializer.cc
+++ b/deps/v8/src/snapshot/object-deserializer.cc
@@ -4,11 +4,11 @@
#include "src/snapshot/object-deserializer.h"
-#include "src/assembler-inl.h"
+#include "src/codegen/assembler-inl.h"
+#include "src/execution/isolate.h"
#include "src/heap/heap-inl.h"
-#include "src/isolate.h"
-#include "src/objects.h"
#include "src/objects/allocation-site-inl.h"
+#include "src/objects/objects.h"
#include "src/objects/slots.h"
#include "src/snapshot/code-serializer.h"
@@ -61,8 +61,8 @@ void ObjectDeserializer::FlushICache() {
for (Code code : new_code_objects()) {
// Record all references to embedded objects in the new code object.
WriteBarrierForCode(code);
- FlushInstructionCache(code->raw_instruction_start(),
- code->raw_instruction_size());
+ FlushInstructionCache(code.raw_instruction_start(),
+ code.raw_instruction_size());
}
}
@@ -73,8 +73,6 @@ void ObjectDeserializer::CommitPostProcessedObjects() {
for (Handle<String> string : new_internalized_strings()) {
DisallowHeapAllocation no_gc;
StringTableInsertionKey key(*string);
- DCHECK(
- StringTable::ForwardStringIfExists(isolate(), &key, *string).is_null());
StringTable::AddKeyNoResize(isolate(), &key);
}
@@ -98,14 +96,14 @@ void ObjectDeserializer::LinkAllocationSites() {
// Allocation sites are present in the snapshot, and must be linked into
// a list at deserialization time.
for (AllocationSite site : new_allocation_sites()) {
- if (!site->HasWeakNext()) continue;
+ if (!site.HasWeakNext()) continue;
// TODO(mvstanton): consider treating the heap()->allocation_sites_list()
// as a (weak) root. If this root is relocated correctly, this becomes
// unnecessary.
if (heap->allocation_sites_list() == Smi::kZero) {
- site->set_weak_next(ReadOnlyRoots(heap).undefined_value());
+ site.set_weak_next(ReadOnlyRoots(heap).undefined_value());
} else {
- site->set_weak_next(heap->allocation_sites_list());
+ site.set_weak_next(heap->allocation_sites_list());
}
heap->set_allocation_sites_list(site);
}
diff --git a/deps/v8/src/snapshot/partial-deserializer.cc b/deps/v8/src/snapshot/partial-deserializer.cc
index 4dd25980e8..9b56f129df 100644
--- a/deps/v8/src/snapshot/partial-deserializer.cc
+++ b/deps/v8/src/snapshot/partial-deserializer.cc
@@ -4,7 +4,7 @@
#include "src/snapshot/partial-deserializer.h"
-#include "src/api-inl.h"
+#include "src/api/api-inl.h"
#include "src/heap/heap-inl.h"
#include "src/objects/slots.h"
#include "src/snapshot/snapshot.h"
diff --git a/deps/v8/src/snapshot/partial-serializer.cc b/deps/v8/src/snapshot/partial-serializer.cc
index 6c650be4c1..036f0a0414 100644
--- a/deps/v8/src/snapshot/partial-serializer.cc
+++ b/deps/v8/src/snapshot/partial-serializer.cc
@@ -5,10 +5,11 @@
#include "src/snapshot/partial-serializer.h"
#include "src/snapshot/startup-serializer.h"
-#include "src/api-inl.h"
-#include "src/math-random.h"
-#include "src/microtask-queue.h"
-#include "src/objects-inl.h"
+#include "src/api/api-inl.h"
+#include "src/execution/microtask-queue.h"
+#include "src/heap/combined-heap.h"
+#include "src/numbers/math-random.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
namespace v8 {
@@ -31,29 +32,28 @@ PartialSerializer::~PartialSerializer() {
void PartialSerializer::Serialize(Context* o, bool include_global_proxy) {
context_ = *o;
- DCHECK(context_->IsNativeContext());
+ DCHECK(context_.IsNativeContext());
reference_map()->AddAttachedReference(
- reinterpret_cast<void*>(context_->global_proxy()->ptr()));
+ reinterpret_cast<void*>(context_.global_proxy().ptr()));
// The bootstrap snapshot has a code-stub context. When serializing the
// partial snapshot, it is chained into the weak context list on the isolate
// and it's next context pointer may point to the code-stub context. Clear
// it before serializing, it will get re-added to the context list
// explicitly when it's loaded.
- context_->set(Context::NEXT_CONTEXT_LINK,
- ReadOnlyRoots(isolate()).undefined_value());
- DCHECK(!context_->global_object()->IsUndefined());
+ context_.set(Context::NEXT_CONTEXT_LINK,
+ ReadOnlyRoots(isolate()).undefined_value());
+ DCHECK(!context_.global_object().IsUndefined());
// Reset math random cache to get fresh random numbers.
MathRandom::ResetContext(context_);
#ifdef DEBUG
- MicrotaskQueue* microtask_queue =
- context_->native_context()->microtask_queue();
+ MicrotaskQueue* microtask_queue = context_.native_context().microtask_queue();
DCHECK_EQ(0, microtask_queue->size());
DCHECK(!microtask_queue->HasMicrotasksSuppressions());
DCHECK_EQ(0, microtask_queue->GetMicrotasksScopeDepth());
DCHECK(microtask_queue->DebugMicrotasksScopeDepthIsZero());
#endif
- context_->native_context()->set_microtask_queue(nullptr);
+ context_.native_context().set_microtask_queue(nullptr);
VisitRootPointer(Root::kPartialSnapshotCache, nullptr, FullObjectSlot(o));
SerializeDeferredObjects();
@@ -92,18 +92,18 @@ void PartialSerializer::SerializeObject(HeapObject obj) {
DCHECK(!startup_serializer_->ReferenceMapContains(obj));
// All the internalized strings that the partial snapshot needs should be
// either in the root table or in the partial snapshot cache.
- DCHECK(!obj->IsInternalizedString());
+ DCHECK(!obj.IsInternalizedString());
// Function and object templates are not context specific.
- DCHECK(!obj->IsTemplateInfo());
+ DCHECK(!obj.IsTemplateInfo());
// We should not end up at another native context.
- DCHECK_IMPLIES(obj != context_, !obj->IsNativeContext());
+ DCHECK_IMPLIES(obj != context_, !obj.IsNativeContext());
// Clear literal boilerplates and feedback.
- if (obj->IsFeedbackVector()) FeedbackVector::cast(obj)->ClearSlots(isolate());
+ if (obj.IsFeedbackVector()) FeedbackVector::cast(obj).ClearSlots(isolate());
// Clear InterruptBudget when serializing FeedbackCell.
- if (obj->IsFeedbackCell()) {
- FeedbackCell::cast(obj)->set_interrupt_budget(
+ if (obj.IsFeedbackCell()) {
+ FeedbackCell::cast(obj).set_interrupt_budget(
FeedbackCell::GetInitialInterruptBudget());
}
@@ -111,12 +111,12 @@ void PartialSerializer::SerializeObject(HeapObject obj) {
return;
}
- if (obj->IsJSFunction()) {
+ if (obj.IsJSFunction()) {
// Unconditionally reset the JSFunction to its SFI's code, since we can't
// serialize optimized code anyway.
JSFunction closure = JSFunction::cast(obj);
- closure->ResetIfBytecodeFlushed();
- if (closure->is_compiled()) closure->set_code(closure->shared()->GetCode());
+ closure.ResetIfBytecodeFlushed();
+ if (closure.is_compiled()) closure.set_code(closure.shared().GetCode());
}
CheckRehashability(obj);
@@ -131,12 +131,12 @@ bool PartialSerializer::ShouldBeInThePartialSnapshotCache(HeapObject o) {
// allow them to be part of the partial snapshot because they contain a
// unique ID, and deserializing several partial snapshots containing script
// would cause dupes.
- DCHECK(!o->IsScript());
- return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() ||
- o->IsCode() || o->IsScopeInfo() || o->IsAccessorInfo() ||
- o->IsTemplateInfo() || o->IsClassPositions() ||
- o->map() == ReadOnlyRoots(startup_serializer_->isolate())
- .fixed_cow_array_map();
+ DCHECK(!o.IsScript());
+ return o.IsName() || o.IsSharedFunctionInfo() || o.IsHeapNumber() ||
+ o.IsCode() || o.IsScopeInfo() || o.IsAccessorInfo() ||
+ o.IsTemplateInfo() || o.IsClassPositions() ||
+ o.map() == ReadOnlyRoots(startup_serializer_->isolate())
+ .fixed_cow_array_map();
}
namespace {
@@ -144,12 +144,12 @@ bool DataIsEmpty(const StartupData& data) { return data.raw_size == 0; }
} // anonymous namespace
bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) {
- if (!obj->IsJSObject()) return false;
+ if (!obj.IsJSObject()) return false;
JSObject js_obj = JSObject::cast(obj);
- int embedder_fields_count = js_obj->GetEmbedderFieldCount();
+ int embedder_fields_count = js_obj.GetEmbedderFieldCount();
if (embedder_fields_count == 0) return false;
CHECK_GT(embedder_fields_count, 0);
- DCHECK(!js_obj->NeedsRehashing());
+ DCHECK(!js_obj.NeedsRehashing());
DisallowHeapAllocation no_gc;
DisallowJavascriptExecution no_js(isolate());
@@ -170,14 +170,13 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) {
EmbedderDataSlot embedder_data_slot(js_obj, i);
original_embedder_values.emplace_back(embedder_data_slot.load_raw(no_gc));
Object object = embedder_data_slot.load_tagged();
- if (object->IsHeapObject()) {
- DCHECK(isolate()->heap()->Contains(HeapObject::cast(object)));
+ if (object.IsHeapObject()) {
+ DCHECK(IsValidHeapObject(isolate()->heap(), HeapObject::cast(object)));
serialized_data.push_back({nullptr, 0});
} else {
// If no serializer is provided and the field was empty, we serialize it
// by default to nullptr.
- if (serialize_embedder_fields_.callback == nullptr &&
- object->ptr() == 0) {
+ if (serialize_embedder_fields_.callback == nullptr && object.ptr() == 0) {
serialized_data.push_back({nullptr, 0});
} else {
DCHECK_NOT_NULL(serialize_embedder_fields_.callback);
@@ -205,7 +204,7 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) {
// 4) Obtain back reference for the serialized object.
SerializerReference reference =
- reference_map()->LookupReference(reinterpret_cast<void*>(js_obj->ptr()));
+ reference_map()->LookupReference(reinterpret_cast<void*>(js_obj.ptr()));
DCHECK(reference.is_back_reference());
// 5) Write data returned by the embedder callbacks into a separate sink,
@@ -236,8 +235,8 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) {
void PartialSerializer::CheckRehashability(HeapObject obj) {
if (!can_be_rehashed_) return;
- if (!obj->NeedsRehashing()) return;
- if (obj->CanBeRehashed()) return;
+ if (!obj.NeedsRehashing()) return;
+ if (obj.CanBeRehashed()) return;
can_be_rehashed_ = false;
}
diff --git a/deps/v8/src/snapshot/partial-serializer.h b/deps/v8/src/snapshot/partial-serializer.h
index fcba9feed2..d8e9ee2496 100644
--- a/deps/v8/src/snapshot/partial-serializer.h
+++ b/deps/v8/src/snapshot/partial-serializer.h
@@ -5,9 +5,9 @@
#ifndef V8_SNAPSHOT_PARTIAL_SERIALIZER_H_
#define V8_SNAPSHOT_PARTIAL_SERIALIZER_H_
-#include "src/address-map.h"
-#include "src/contexts.h"
+#include "src/objects/contexts.h"
#include "src/snapshot/serializer.h"
+#include "src/utils/address-map.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/snapshot/read-only-deserializer.cc b/deps/v8/src/snapshot/read-only-deserializer.cc
index b1b22cc70b..576e644846 100644
--- a/deps/v8/src/snapshot/read-only-deserializer.cc
+++ b/deps/v8/src/snapshot/read-only-deserializer.cc
@@ -4,12 +4,12 @@
#include "src/snapshot/read-only-deserializer.h"
-#include "src/api.h"
+#include "src/api/api.h"
+#include "src/execution/v8threads.h"
#include "src/heap/heap-inl.h" // crbug.com/v8/8499
#include "src/heap/read-only-heap.h"
#include "src/objects/slots.h"
#include "src/snapshot/snapshot.h"
-#include "src/v8threads.h"
namespace v8 {
namespace internal {
@@ -21,12 +21,15 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
V8::FatalProcessOutOfMemory(isolate, "ReadOnlyDeserializer");
}
+ ReadOnlyHeap* ro_heap = isolate->heap()->read_only_heap();
+
// No active threads.
DCHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse());
// No active handles.
DCHECK(isolate->handle_scope_implementer()->blocks()->empty());
+ // Read-only object cache is not yet populated.
+ DCHECK(!ro_heap->read_only_object_cache_is_initialized());
// Partial snapshot cache is not yet populated.
- DCHECK(isolate->heap()->read_only_heap()->read_only_object_cache()->empty());
DCHECK(isolate->partial_snapshot_cache()->empty());
// Builtins are not yet created.
DCHECK(!isolate->builtins()->is_initialized());
@@ -36,22 +39,16 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
ReadOnlyRoots roots(isolate);
roots.Iterate(this);
- isolate->heap()
- ->read_only_heap()
- ->read_only_space()
- ->RepairFreeListsAfterDeserialization();
+ ro_heap->read_only_space()->RepairFreeListsAfterDeserialization();
// Deserialize the Read-only Object Cache.
- std::vector<Object>* cache =
- isolate->heap()->read_only_heap()->read_only_object_cache();
for (size_t i = 0;; ++i) {
- // Extend the array ready to get a value when deserializing.
- if (cache->size() <= i) cache->push_back(Smi::kZero);
+ Object* object = ro_heap->ExtendReadOnlyObjectCache();
// During deserialization, the visitor populates the read-only object
// cache and eventually terminates the cache with undefined.
VisitRootPointer(Root::kReadOnlyObjectCache, nullptr,
- FullObjectSlot(&cache->at(i)));
- if (cache->at(i)->IsUndefined(roots)) break;
+ FullObjectSlot(object));
+ if (object->IsUndefined(roots)) break;
}
DeserializeDeferredObjects();
}
diff --git a/deps/v8/src/snapshot/read-only-serializer.cc b/deps/v8/src/snapshot/read-only-serializer.cc
index a65ce4903e..f4b45a15cc 100644
--- a/deps/v8/src/snapshot/read-only-serializer.cc
+++ b/deps/v8/src/snapshot/read-only-serializer.cc
@@ -4,14 +4,14 @@
#include "src/snapshot/read-only-serializer.h"
-#include "src/api.h"
-#include "src/code-tracer.h"
-#include "src/global-handles.h"
+#include "src/api/api.h"
+#include "src/diagnostics/code-tracer.h"
+#include "src/execution/v8threads.h"
+#include "src/handles/global-handles.h"
#include "src/heap/read-only-heap.h"
-#include "src/objects-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
#include "src/snapshot/startup-serializer.h"
-#include "src/v8threads.h"
namespace v8 {
namespace internal {
@@ -27,7 +27,7 @@ ReadOnlySerializer::~ReadOnlySerializer() {
void ReadOnlySerializer::SerializeObject(HeapObject obj) {
CHECK(ReadOnlyHeap::Contains(obj));
- CHECK_IMPLIES(obj->IsString(), obj->IsInternalizedString());
+ CHECK_IMPLIES(obj.IsString(), obj.IsInternalizedString());
if (SerializeHotObject(obj)) return;
if (IsRootAndHasBeenSerialized(obj) && SerializeRoot(obj)) {
@@ -40,6 +40,9 @@ void ReadOnlySerializer::SerializeObject(HeapObject obj) {
// Object has not yet been serialized. Serialize it here.
ObjectSerializer object_serializer(this, obj, &sink_);
object_serializer.Serialize();
+#ifdef DEBUG
+ serialized_objects_.insert(obj);
+#endif
}
void ReadOnlySerializer::SerializeReadOnlyRoots() {
@@ -60,6 +63,16 @@ void ReadOnlySerializer::FinalizeSerialization() {
FullObjectSlot(&undefined));
SerializeDeferredObjects();
Pad();
+
+#ifdef DEBUG
+ // Check that every object on read-only heap is reachable (and was
+ // serialized).
+ ReadOnlyHeapIterator iterator(isolate()->heap()->read_only_heap());
+ for (HeapObject object = iterator.Next(); !object.is_null();
+ object = iterator.Next()) {
+ CHECK(serialized_objects_.count(object));
+ }
+#endif
}
bool ReadOnlySerializer::MustBeDeferred(HeapObject object) {
@@ -75,7 +88,7 @@ bool ReadOnlySerializer::MustBeDeferred(HeapObject object) {
// not be fulfilled during deserialization until few first root objects are
// serialized. But we must serialize Map objects since deserializer checks
// that these root objects are indeed Maps.
- return !object->IsMap();
+ return !object.IsMap();
}
bool ReadOnlySerializer::SerializeUsingReadOnlyObjectCache(
diff --git a/deps/v8/src/snapshot/read-only-serializer.h b/deps/v8/src/snapshot/read-only-serializer.h
index 753432502e..c73c397647 100644
--- a/deps/v8/src/snapshot/read-only-serializer.h
+++ b/deps/v8/src/snapshot/read-only-serializer.h
@@ -5,6 +5,8 @@
#ifndef V8_SNAPSHOT_READ_ONLY_SERIALIZER_H_
#define V8_SNAPSHOT_READ_ONLY_SERIALIZER_H_
+#include <unordered_set>
+
#include "src/snapshot/roots-serializer.h"
namespace v8 {
@@ -35,6 +37,9 @@ class V8_EXPORT_PRIVATE ReadOnlySerializer : public RootsSerializer {
void SerializeObject(HeapObject o) override;
bool MustBeDeferred(HeapObject object) override;
+#ifdef DEBUG
+ std::unordered_set<HeapObject, Object::Hasher> serialized_objects_;
+#endif
DISALLOW_COPY_AND_ASSIGN(ReadOnlySerializer);
};
diff --git a/deps/v8/src/snapshot/references.h b/deps/v8/src/snapshot/references.h
index ff3196115c..e7c44236ac 100644
--- a/deps/v8/src/snapshot/references.h
+++ b/deps/v8/src/snapshot/references.h
@@ -5,9 +5,9 @@
#ifndef V8_SNAPSHOT_REFERENCES_H_
#define V8_SNAPSHOT_REFERENCES_H_
-#include "src/assert-scope.h"
#include "src/base/hashmap.h"
-#include "src/utils.h"
+#include "src/common/assert-scope.h"
+#include "src/utils/utils.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/snapshot/roots-serializer.cc b/deps/v8/src/snapshot/roots-serializer.cc
index e634c45eff..f354dec158 100644
--- a/deps/v8/src/snapshot/roots-serializer.cc
+++ b/deps/v8/src/snapshot/roots-serializer.cc
@@ -4,9 +4,9 @@
#include "src/snapshot/roots-serializer.h"
+#include "src/execution/isolate.h"
#include "src/heap/heap.h"
-#include "src/isolate.h"
-#include "src/objects-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
namespace v8 {
@@ -58,8 +58,8 @@ void RootsSerializer::VisitRootPointers(Root root, const char* description,
void RootsSerializer::CheckRehashability(HeapObject obj) {
if (!can_be_rehashed_) return;
- if (!obj->NeedsRehashing()) return;
- if (obj->CanBeRehashed()) return;
+ if (!obj.NeedsRehashing()) return;
+ if (obj.CanBeRehashed()) return;
can_be_rehashed_ = false;
}
diff --git a/deps/v8/src/snapshot/roots-serializer.h b/deps/v8/src/snapshot/roots-serializer.h
index 50c63402d2..cfb59dd75e 100644
--- a/deps/v8/src/snapshot/roots-serializer.h
+++ b/deps/v8/src/snapshot/roots-serializer.h
@@ -7,8 +7,8 @@
#include <bitset>
+#include "src/objects/visitors.h"
#include "src/snapshot/serializer.h"
-#include "src/visitors.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/snapshot/serializer-allocator.cc b/deps/v8/src/snapshot/serializer-allocator.cc
index d596678789..763244137f 100644
--- a/deps/v8/src/snapshot/serializer-allocator.cc
+++ b/deps/v8/src/snapshot/serializer-allocator.cc
@@ -144,7 +144,7 @@ void SerializerAllocator::OutputStatistics() {
for (int space = FIRST_SPACE; space < kNumberOfPreallocatedSpaces; space++) {
size_t s = pending_chunk_[space];
for (uint32_t chunk_size : completed_chunks_[space]) s += chunk_size;
- PrintF("%16" PRIuS, s);
+ PrintF("%16zu", s);
}
STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
diff --git a/deps/v8/src/snapshot/serializer-common.cc b/deps/v8/src/snapshot/serializer-common.cc
index fa8d19e438..2869c2bf24 100644
--- a/deps/v8/src/snapshot/serializer-common.cc
+++ b/deps/v8/src/snapshot/serializer-common.cc
@@ -4,9 +4,9 @@
#include "src/snapshot/serializer-common.h"
-#include "src/external-reference-table.h"
-#include "src/objects-inl.h"
+#include "src/codegen/external-reference-table.h"
#include "src/objects/foreign-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
namespace v8 {
@@ -120,28 +120,28 @@ void SerializerDeserializer::Iterate(Isolate* isolate, RootVisitor* visitor) {
// and eventually terminates the cache with undefined.
visitor->VisitRootPointer(Root::kPartialSnapshotCache, nullptr,
FullObjectSlot(&cache->at(i)));
- if (cache->at(i)->IsUndefined(isolate)) break;
+ if (cache->at(i).IsUndefined(isolate)) break;
}
}
bool SerializerDeserializer::CanBeDeferred(HeapObject o) {
- return !o->IsString() && !o->IsScript() && !o->IsJSTypedArray();
+ return !o.IsString() && !o.IsScript() && !o.IsJSTypedArray();
}
void SerializerDeserializer::RestoreExternalReferenceRedirectors(
const std::vector<AccessorInfo>& accessor_infos) {
// Restore wiped accessor infos.
for (AccessorInfo info : accessor_infos) {
- Foreign::cast(info->js_getter())
- ->set_foreign_address(info->redirected_getter());
+ Foreign::cast(info.js_getter())
+ .set_foreign_address(info.redirected_getter());
}
}
void SerializerDeserializer::RestoreExternalReferenceRedirectors(
const std::vector<CallHandlerInfo>& call_handler_infos) {
for (CallHandlerInfo info : call_handler_infos) {
- Foreign::cast(info->js_callback())
- ->set_foreign_address(info->redirected_callback());
+ Foreign::cast(info.js_callback())
+ .set_foreign_address(info.redirected_callback());
}
}
diff --git a/deps/v8/src/snapshot/serializer-common.h b/deps/v8/src/snapshot/serializer-common.h
index a373683886..30da8db662 100644
--- a/deps/v8/src/snapshot/serializer-common.h
+++ b/deps/v8/src/snapshot/serializer-common.h
@@ -5,14 +5,14 @@
#ifndef V8_SNAPSHOT_SERIALIZER_COMMON_H_
#define V8_SNAPSHOT_SERIALIZER_COMMON_H_
-#include "src/address-map.h"
#include "src/base/bits.h"
-#include "src/external-reference-table.h"
-#include "src/globals.h"
-#include "src/msan.h"
+#include "src/codegen/external-reference-table.h"
+#include "src/common/globals.h"
+#include "src/common/v8memory.h"
+#include "src/objects/visitors.h"
+#include "src/sanitizer/msan.h"
#include "src/snapshot/references.h"
-#include "src/v8memory.h"
-#include "src/visitors.h"
+#include "src/utils/address-map.h"
namespace v8 {
namespace internal {
@@ -370,13 +370,19 @@ class Checksum {
#ifdef MEMORY_SANITIZER
// Computing the checksum includes padding bytes for objects like strings.
// Mark every object as initialized in the code serializer.
- MSAN_MEMORY_IS_INITIALIZED(payload.start(), payload.length());
+ MSAN_MEMORY_IS_INITIALIZED(payload.begin(), payload.length());
#endif // MEMORY_SANITIZER
// Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit.
uintptr_t a = 1;
uintptr_t b = 0;
- const uintptr_t* cur = reinterpret_cast<const uintptr_t*>(payload.start());
+ // TODO(jgruber, v8:9171): The following DCHECK should ideally hold since we
+ // access payload through an uintptr_t pointer later on; and some
+ // architectures, e.g. arm, may generate instructions that expect correct
+ // alignment. However, we do not control alignment for external snapshots.
+ // DCHECK(IsAligned(reinterpret_cast<intptr_t>(payload.begin()),
+ // kIntptrSize));
DCHECK(IsAligned(payload.length(), kIntptrSize));
+ const uintptr_t* cur = reinterpret_cast<const uintptr_t*>(payload.begin());
const uintptr_t* end = cur + payload.length() / kIntptrSize;
while (cur < end) {
// Unsigned overflow expected and intended.
diff --git a/deps/v8/src/snapshot/serializer.cc b/deps/v8/src/snapshot/serializer.cc
index 447a69aea8..9eefbe2c48 100644
--- a/deps/v8/src/snapshot/serializer.cc
+++ b/deps/v8/src/snapshot/serializer.cc
@@ -4,7 +4,7 @@
#include "src/snapshot/serializer.h"
-#include "src/assembler-inl.h"
+#include "src/codegen/assembler-inl.h"
#include "src/heap/heap-inl.h" // For Space::identity().
#include "src/heap/read-only-heap.h"
#include "src/interpreter/interpreter.h"
@@ -58,7 +58,7 @@ Serializer::~Serializer() {
#ifdef OBJECT_PRINT
void Serializer::CountInstanceType(Map map, int size, AllocationSpace space) {
- int instance_type = map->instance_type();
+ int instance_type = map.instance_type();
instance_type_count_[space][instance_type]++;
instance_type_size_[space][instance_type] += size;
}
@@ -75,8 +75,7 @@ void Serializer::OutputStatistics(const char* name) {
#define PRINT_INSTANCE_TYPE(Name) \
for (int space = 0; space < LAST_SPACE; ++space) { \
if (instance_type_count_[space][Name]) { \
- PrintF("%10d %10" PRIuS " %-10s %s\n", \
- instance_type_count_[space][Name], \
+ PrintF("%10d %10zu %-10s %s\n", instance_type_count_[space][Name], \
instance_type_size_[space][Name], \
Heap::GetSpaceName(static_cast<AllocationSpace>(space)), #Name); \
} \
@@ -108,7 +107,7 @@ void Serializer::VisitRootPointers(Root root, const char* description,
}
void Serializer::SerializeRootObject(Object object) {
- if (object->IsSmi()) {
+ if (object.IsSmi()) {
PutSmi(Smi::cast(object));
} else {
SerializeObject(HeapObject::cast(object));
@@ -116,12 +115,10 @@ void Serializer::SerializeRootObject(Object object) {
}
#ifdef DEBUG
-void Serializer::PrintStack() { PrintStack(std::cout); }
-
-void Serializer::PrintStack(std::ostream& out) {
+void Serializer::PrintStack() {
for (const auto o : stack_) {
- o.Print(out);
- out << "\n";
+ o.Print();
+ PrintF("\n");
}
}
#endif // DEBUG
@@ -144,10 +141,9 @@ bool Serializer::SerializeHotObject(HeapObject obj) {
DCHECK(index >= 0 && index < kNumberOfHotObjects);
if (FLAG_trace_serializer) {
PrintF(" Encoding hot object %d:", index);
- obj->ShortPrint();
+ obj.ShortPrint();
PrintF("\n");
}
- // TODO(ishell): remove kHotObjectWithSkip
sink_.Put(kHotObject + index, "HotObject");
return true;
}
@@ -170,7 +166,7 @@ bool Serializer::SerializeBackReference(HeapObject obj) {
DCHECK(reference.is_back_reference());
if (FLAG_trace_serializer) {
PrintF(" Encoding back reference to: ");
- obj->ShortPrint();
+ obj.ShortPrint();
PrintF("\n");
}
@@ -183,15 +179,15 @@ bool Serializer::SerializeBackReference(HeapObject obj) {
}
bool Serializer::ObjectIsBytecodeHandler(HeapObject obj) const {
- if (!obj->IsCode()) return false;
- return (Code::cast(obj)->kind() == Code::BYTECODE_HANDLER);
+ if (!obj.IsCode()) return false;
+ return (Code::cast(obj).kind() == Code::BYTECODE_HANDLER);
}
void Serializer::PutRoot(RootIndex root, HeapObject object) {
int root_index = static_cast<int>(root);
if (FLAG_trace_serializer) {
PrintF(" Encoding root %d:", root_index);
- object->ShortPrint();
+ object.ShortPrint();
PrintF("\n");
}
@@ -247,7 +243,7 @@ void Serializer::PutAttachedReference(SerializerReference reference) {
}
int Serializer::PutAlignmentPrefix(HeapObject object) {
- AllocationAlignment alignment = HeapObject::RequiredAlignment(object->map());
+ AllocationAlignment alignment = HeapObject::RequiredAlignment(object.map());
if (alignment != kWordAligned) {
DCHECK(1 <= alignment && alignment <= 3);
byte prefix = (kAlignmentPrefix - 1) + alignment;
@@ -290,10 +286,10 @@ void Serializer::InitializeCodeAddressMap() {
Code Serializer::CopyCode(Code code) {
code_buffer_.clear(); // Clear buffer without deleting backing store.
- int size = code->CodeSize();
+ int size = code.CodeSize();
code_buffer_.insert(code_buffer_.end(),
- reinterpret_cast<byte*>(code->address()),
- reinterpret_cast<byte*>(code->address() + size));
+ reinterpret_cast<byte*>(code.address()),
+ reinterpret_cast<byte*>(code.address() + size));
// When pointer compression is enabled the checked cast will try to
// decompress map field of off-heap Code object.
return Code::unchecked_cast(HeapObject::FromAddress(
@@ -304,16 +300,16 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
int size, Map map) {
if (serializer_->code_address_map_) {
const char* code_name =
- serializer_->code_address_map_->Lookup(object_->address());
+ serializer_->code_address_map_->Lookup(object_.address());
LOG(serializer_->isolate_,
- CodeNameEvent(object_->address(), sink_->Position(), code_name));
+ CodeNameEvent(object_.address(), sink_->Position(), code_name));
}
SerializerReference back_reference;
if (space == LO_SPACE) {
sink_->Put(kNewObject + space, "NewLargeObject");
sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
- CHECK(!object_->IsCode());
+ CHECK(!object_.IsCode());
back_reference = serializer_->allocator()->AllocateLargeObject(size);
} else if (space == MAP_SPACE) {
DCHECK_EQ(Map::kSize, size);
@@ -363,56 +359,48 @@ int32_t Serializer::ObjectSerializer::SerializeBackingStore(
void Serializer::ObjectSerializer::SerializeJSTypedArray() {
JSTypedArray typed_array = JSTypedArray::cast(object_);
- FixedTypedArrayBase elements =
- FixedTypedArrayBase::cast(typed_array->elements());
-
- if (!typed_array->WasDetached()) {
- if (!typed_array->is_on_heap()) {
+ if (!typed_array.WasDetached()) {
+ if (!typed_array.is_on_heap()) {
// Explicitly serialize the backing store now.
- JSArrayBuffer buffer = JSArrayBuffer::cast(typed_array->buffer());
- CHECK_LE(buffer->byte_length(), Smi::kMaxValue);
- CHECK_LE(typed_array->byte_offset(), Smi::kMaxValue);
- int32_t byte_length = static_cast<int32_t>(buffer->byte_length());
- int32_t byte_offset = static_cast<int32_t>(typed_array->byte_offset());
+ JSArrayBuffer buffer = JSArrayBuffer::cast(typed_array.buffer());
+ CHECK_LE(buffer.byte_length(), Smi::kMaxValue);
+ CHECK_LE(typed_array.byte_offset(), Smi::kMaxValue);
+ int32_t byte_length = static_cast<int32_t>(buffer.byte_length());
+ int32_t byte_offset = static_cast<int32_t>(typed_array.byte_offset());
// We need to calculate the backing store from the external pointer
// because the ArrayBuffer may already have been serialized.
void* backing_store = reinterpret_cast<void*>(
- reinterpret_cast<intptr_t>(elements->external_pointer()) -
+ reinterpret_cast<intptr_t>(typed_array.external_pointer()) -
byte_offset);
int32_t ref = SerializeBackingStore(backing_store, byte_length);
// The external_pointer is the backing_store + typed_array->byte_offset.
// To properly share the buffer, we set the backing store ref here. On
// deserialization we re-add the byte_offset to external_pointer.
- elements->set_external_pointer(
+ typed_array.set_external_pointer(
reinterpret_cast<void*>(Smi::FromInt(ref).ptr()));
}
} else {
- // When a JSArrayBuffer is detached, the FixedTypedArray that points to the
- // same backing store does not know anything about it. This fixup step finds
- // detached TypedArrays and clears the values in the FixedTypedArray so that
- // we don't try to serialize the now invalid backing store.
- elements->set_external_pointer(reinterpret_cast<void*>(Smi::kZero.ptr()));
- elements->set_length(0);
+ typed_array.set_external_pointer(nullptr);
}
SerializeObject();
}
void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
JSArrayBuffer buffer = JSArrayBuffer::cast(object_);
- void* backing_store = buffer->backing_store();
+ void* backing_store = buffer.backing_store();
// We cannot store byte_length larger than Smi range in the snapshot.
- CHECK_LE(buffer->byte_length(), Smi::kMaxValue);
- int32_t byte_length = static_cast<int32_t>(buffer->byte_length());
+ CHECK_LE(buffer.byte_length(), Smi::kMaxValue);
+ int32_t byte_length = static_cast<int32_t>(buffer.byte_length());
// The embedder-allocated backing store only exists for the off-heap case.
if (backing_store != nullptr) {
int32_t ref = SerializeBackingStore(backing_store, byte_length);
- buffer->set_backing_store(reinterpret_cast<void*>(Smi::FromInt(ref).ptr()));
+ buffer.set_backing_store(reinterpret_cast<void*>(Smi::FromInt(ref).ptr()));
}
SerializeObject();
- buffer->set_backing_store(backing_store);
+ buffer.set_backing_store(backing_store);
}
void Serializer::ObjectSerializer::SerializeExternalString() {
@@ -422,30 +410,30 @@ void Serializer::ObjectSerializer::SerializeExternalString() {
// for native native source code strings, we replace the resource field
// with the native source id.
// For the rest we serialize them to look like ordinary sequential strings.
- if (object_->map() != ReadOnlyRoots(heap).native_source_string_map()) {
+ if (object_.map() != ReadOnlyRoots(heap).native_source_string_map()) {
ExternalString string = ExternalString::cast(object_);
- Address resource = string->resource_as_address();
+ Address resource = string.resource_as_address();
ExternalReferenceEncoder::Value reference;
if (serializer_->external_reference_encoder_.TryEncode(resource).To(
&reference)) {
DCHECK(reference.is_from_api());
- string->set_uint32_as_resource(reference.index());
+ string.set_uint32_as_resource(reference.index());
SerializeObject();
- string->set_address_as_resource(resource);
+ string.set_address_as_resource(resource);
} else {
SerializeExternalStringAsSequentialString();
}
} else {
ExternalOneByteString string = ExternalOneByteString::cast(object_);
- DCHECK(string->is_uncached());
+ DCHECK(string.is_uncached());
const NativesExternalStringResource* resource =
reinterpret_cast<const NativesExternalStringResource*>(
- string->resource());
+ string.resource());
// Replace the resource field with the type and index of the native source.
- string->set_resource(resource->EncodeForSerialization());
+ string.set_resource(resource->EncodeForSerialization());
SerializeObject();
// Restore the resource field.
- string->set_resource(resource);
+ string.set_resource(resource);
}
}
@@ -453,29 +441,29 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
// Instead of serializing this as an external string, we serialize
// an imaginary sequential string with the same content.
ReadOnlyRoots roots(serializer_->isolate());
- DCHECK(object_->IsExternalString());
- DCHECK(object_->map() != roots.native_source_string_map());
+ DCHECK(object_.IsExternalString());
+ DCHECK(object_.map() != roots.native_source_string_map());
ExternalString string = ExternalString::cast(object_);
- int length = string->length();
+ int length = string.length();
Map map;
int content_size;
int allocation_size;
const byte* resource;
// Find the map and size for the imaginary sequential string.
- bool internalized = object_->IsInternalizedString();
- if (object_->IsExternalOneByteString()) {
+ bool internalized = object_.IsInternalizedString();
+ if (object_.IsExternalOneByteString()) {
map = internalized ? roots.one_byte_internalized_string_map()
: roots.one_byte_string_map();
allocation_size = SeqOneByteString::SizeFor(length);
content_size = length * kCharSize;
resource = reinterpret_cast<const byte*>(
- ExternalOneByteString::cast(string)->resource()->data());
+ ExternalOneByteString::cast(string).resource()->data());
} else {
map = internalized ? roots.internalized_string_map() : roots.string_map();
allocation_size = SeqTwoByteString::SizeFor(length);
content_size = length * kShortSize;
resource = reinterpret_cast<const byte*>(
- ExternalTwoByteString::cast(string)->resource()->data());
+ ExternalTwoByteString::cast(string).resource()->data());
}
AllocationSpace space =
@@ -491,7 +479,7 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
sink_->PutInt(bytes_to_output, "length");
// Serialize string header (except for map).
- uint8_t* string_start = reinterpret_cast<uint8_t*>(string->address());
+ uint8_t* string_start = reinterpret_cast<uint8_t*>(string.address());
for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) {
sink_->PutSection(string_start[i], "StringHeader");
}
@@ -511,19 +499,19 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
class UnlinkWeakNextScope {
public:
explicit UnlinkWeakNextScope(Heap* heap, HeapObject object) {
- if (object->IsAllocationSite() &&
- AllocationSite::cast(object)->HasWeakNext()) {
+ if (object.IsAllocationSite() &&
+ AllocationSite::cast(object).HasWeakNext()) {
object_ = object;
- next_ = AllocationSite::cast(object)->weak_next();
- AllocationSite::cast(object)->set_weak_next(
+ next_ = AllocationSite::cast(object).weak_next();
+ AllocationSite::cast(object).set_weak_next(
ReadOnlyRoots(heap).undefined_value());
}
}
~UnlinkWeakNextScope() {
if (!object_.is_null()) {
- AllocationSite::cast(object_)->set_weak_next(next_,
- UPDATE_WEAK_WRITE_BARRIER);
+ AllocationSite::cast(object_).set_weak_next(next_,
+ UPDATE_WEAK_WRITE_BARRIER);
}
}
@@ -536,48 +524,48 @@ class UnlinkWeakNextScope {
void Serializer::ObjectSerializer::Serialize() {
if (FLAG_trace_serializer) {
PrintF(" Encoding heap object: ");
- object_->ShortPrint();
+ object_.ShortPrint();
PrintF("\n");
}
- if (object_->IsExternalString()) {
+ if (object_.IsExternalString()) {
SerializeExternalString();
return;
} else if (!ReadOnlyHeap::Contains(object_)) {
// Only clear padding for strings outside RO_SPACE. RO_SPACE should have
// been cleared elsewhere.
- if (object_->IsSeqOneByteString()) {
+ if (object_.IsSeqOneByteString()) {
// Clear padding bytes at the end. Done here to avoid having to do this
// at allocation sites in generated code.
- SeqOneByteString::cast(object_)->clear_padding();
- } else if (object_->IsSeqTwoByteString()) {
- SeqTwoByteString::cast(object_)->clear_padding();
+ SeqOneByteString::cast(object_).clear_padding();
+ } else if (object_.IsSeqTwoByteString()) {
+ SeqTwoByteString::cast(object_).clear_padding();
}
}
- if (object_->IsJSTypedArray()) {
+ if (object_.IsJSTypedArray()) {
SerializeJSTypedArray();
return;
}
- if (object_->IsJSArrayBuffer()) {
+ if (object_.IsJSArrayBuffer()) {
SerializeJSArrayBuffer();
return;
}
// We don't expect fillers.
- DCHECK(!object_->IsFiller());
+ DCHECK(!object_.IsFiller());
- if (object_->IsScript()) {
+ if (object_.IsScript()) {
// Clear cached line ends.
Object undefined = ReadOnlyRoots(serializer_->isolate()).undefined_value();
- Script::cast(object_)->set_line_ends(undefined);
+ Script::cast(object_).set_line_ends(undefined);
}
SerializeObject();
}
void Serializer::ObjectSerializer::SerializeObject() {
- int size = object_->Size();
- Map map = object_->map();
+ int size = object_.Size();
+ Map map = object_.map();
AllocationSpace space =
MemoryChunk::FromHeapObject(object_)->owner()->identity();
// Young generation large objects are tenured.
@@ -606,12 +594,12 @@ void Serializer::ObjectSerializer::SerializeObject() {
void Serializer::ObjectSerializer::SerializeDeferred() {
if (FLAG_trace_serializer) {
PrintF(" Encoding deferred heap object: ");
- object_->ShortPrint();
+ object_.ShortPrint();
PrintF("\n");
}
- int size = object_->Size();
- Map map = object_->map();
+ int size = object_.Size();
+ Map map = object_.map();
SerializerReference back_reference =
serializer_->reference_map()->LookupReference(
reinterpret_cast<void*>(object_.ptr()));
@@ -631,16 +619,16 @@ void Serializer::ObjectSerializer::SerializeDeferred() {
void Serializer::ObjectSerializer::SerializeContent(Map map, int size) {
UnlinkWeakNextScope unlink_weak_next(serializer_->isolate()->heap(), object_);
- if (object_->IsCode()) {
+ if (object_.IsCode()) {
// For code objects, output raw bytes first.
OutputCode(size);
// Then iterate references via reloc info.
- object_->IterateBody(map, size, this);
+ object_.IterateBody(map, size, this);
} else {
// For other objects, iterate references first.
- object_->IterateBody(map, size, this);
+ object_.IterateBody(map, size, this);
// Then output data payload, if any.
- OutputRawData(object_->address() + size);
+ OutputRawData(object_.address() + size);
}
}
@@ -714,7 +702,7 @@ void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code host,
void Serializer::ObjectSerializer::VisitExternalReference(Foreign host,
Address* p) {
auto encoded_reference =
- serializer_->EncodeExternalReference(host->foreign_address());
+ serializer_->EncodeExternalReference(host.foreign_address());
if (encoded_reference.is_from_api()) {
sink_->Put(kApiReference, "ApiRef");
} else {
@@ -741,10 +729,10 @@ void Serializer::ObjectSerializer::VisitExternalReference(Code host,
void Serializer::ObjectSerializer::VisitInternalReference(Code host,
RelocInfo* rinfo) {
- Address entry = Code::cast(object_)->entry();
+ Address entry = Code::cast(object_).entry();
DCHECK_GE(rinfo->target_internal_reference(), entry);
uintptr_t target_offset = rinfo->target_internal_reference() - entry;
- DCHECK_LE(target_offset, Code::cast(object_)->raw_instruction_size());
+ DCHECK_LE(target_offset, Code::cast(object_).raw_instruction_size());
sink_->Put(kInternalReference, "InternalRef");
sink_->PutInt(target_offset, "internal ref value");
}
@@ -767,7 +755,7 @@ void Serializer::ObjectSerializer::VisitOffHeapTarget(Code host,
CHECK(Builtins::IsIsolateIndependentBuiltin(target));
sink_->Put(kOffHeapTarget, "OffHeapTarget");
- sink_->PutInt(target->builtin_index(), "builtin index");
+ sink_->PutInt(target.builtin_index(), "builtin index");
bytes_processed_so_far_ += rinfo->target_address_size();
}
@@ -807,7 +795,7 @@ void OutputRawWithCustomField(SnapshotByteSink* sink, Address object_start,
} // anonymous namespace
void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
- Address object_start = object_->address();
+ Address object_start = object_.address();
int base = bytes_processed_so_far_;
int up_to_offset = static_cast<int>(up_to - object_start);
int to_skip = up_to_offset - bytes_processed_so_far_;
@@ -829,13 +817,13 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
__msan_check_mem_is_initialized(
reinterpret_cast<void*>(object_start + base), bytes_to_output);
#endif // MEMORY_SANITIZER
- if (object_->IsBytecodeArray()) {
+ if (object_.IsBytecodeArray()) {
// The bytecode age field can be changed by GC concurrently.
byte field_value = BytecodeArray::kNoAgeBytecodeAge;
OutputRawWithCustomField(sink_, object_start, base, bytes_to_output,
BytecodeArray::kBytecodeAgeOffset,
sizeof(field_value), &field_value);
- } else if (object_->IsDescriptorArray()) {
+ } else if (object_.IsDescriptorArray()) {
// The number of marked descriptors field can be changed by GC
// concurrently.
byte field_value[2];
@@ -859,7 +847,8 @@ void Serializer::ObjectSerializer::OutputCode(int size) {
// and wipe all pointers in the copy, which we then serialize.
Code off_heap_code = serializer_->CopyCode(on_heap_code);
int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
- RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
+ RelocInfo::ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) |
+ RelocInfo::ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
@@ -868,7 +857,7 @@ void Serializer::ObjectSerializer::OutputCode(int size) {
// With enabled pointer compression normal accessors no longer work for
// off-heap objects, so we have to get the relocation info data via the
// on-heap code object.
- ByteArray relocation_info = on_heap_code->unchecked_relocation_info();
+ ByteArray relocation_info = on_heap_code.unchecked_relocation_info();
for (RelocIterator it(off_heap_code, relocation_info, mode_mask); !it.done();
it.next()) {
RelocInfo* rinfo = it.rinfo();
@@ -876,9 +865,9 @@ void Serializer::ObjectSerializer::OutputCode(int size) {
}
// We need to wipe out the header fields *after* wiping out the
// relocations, because some of these fields are needed for the latter.
- off_heap_code->WipeOutHeader();
+ off_heap_code.WipeOutHeader();
- Address start = off_heap_code->address() + Code::kDataStart;
+ Address start = off_heap_code.address() + Code::kDataStart;
int bytes_to_output = size - Code::kDataStart;
DCHECK(IsAligned(bytes_to_output, kTaggedSize));
diff --git a/deps/v8/src/snapshot/serializer.h b/deps/v8/src/snapshot/serializer.h
index 49ffddbefb..c9e7fada80 100644
--- a/deps/v8/src/snapshot/serializer.h
+++ b/deps/v8/src/snapshot/serializer.h
@@ -7,10 +7,10 @@
#include <map>
-#include "src/isolate.h"
-#include "src/log.h"
-#include "src/objects.h"
-#include "src/snapshot/embedded-data.h"
+#include "src/execution/isolate.h"
+#include "src/logging/log.h"
+#include "src/objects/objects.h"
+#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/serializer-allocator.h"
#include "src/snapshot/serializer-common.h"
#include "src/snapshot/snapshot-source-sink.h"
@@ -29,7 +29,7 @@ class CodeAddressMap : public CodeEventLogger {
}
void CodeMoveEvent(AbstractCode from, AbstractCode to) override {
- address_to_name_map_.Move(from->address(), to->address());
+ address_to_name_map_.Move(from.address(), to.address());
}
void CodeDisableOptEvent(AbstractCode code,
@@ -116,7 +116,7 @@ class CodeAddressMap : public CodeEventLogger {
void LogRecordedBuffer(AbstractCode code, SharedFunctionInfo,
const char* name, int length) override {
- address_to_name_map_.Insert(code->address(), name, length);
+ address_to_name_map_.Insert(code.address(), name, length);
}
void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
@@ -167,7 +167,7 @@ class Serializer : public SerializerDeserializer {
bool ReferenceMapContains(HeapObject o) {
return reference_map()
- ->LookupReference(reinterpret_cast<void*>(o->ptr()))
+ ->LookupReference(reinterpret_cast<void*>(o.ptr()))
.is_valid();
}
@@ -235,7 +235,7 @@ class Serializer : public SerializerDeserializer {
Code CopyCode(Code code);
void QueueDeferredObject(HeapObject obj) {
- DCHECK(reference_map_.LookupReference(reinterpret_cast<void*>(obj->ptr()))
+ DCHECK(reference_map_.LookupReference(reinterpret_cast<void*>(obj.ptr()))
.is_back_reference());
deferred_objects_.push_back(obj);
}
@@ -250,7 +250,6 @@ class Serializer : public SerializerDeserializer {
void PushStack(HeapObject o) { stack_.push_back(o); }
void PopStack() { stack_.pop_back(); }
void PrintStack();
- void PrintStack(std::ostream&);
#endif // DEBUG
SerializerReferenceMap* reference_map() { return &reference_map_; }
diff --git a/deps/v8/src/snapshot/snapshot-common.cc b/deps/v8/src/snapshot/snapshot-common.cc
index 271317836c..f489999f88 100644
--- a/deps/v8/src/snapshot/snapshot-common.cc
+++ b/deps/v8/src/snapshot/snapshot-common.cc
@@ -7,11 +7,12 @@
#include "src/snapshot/snapshot.h"
#include "src/base/platform/platform.h"
-#include "src/counters.h"
+#include "src/logging/counters.h"
#include "src/snapshot/partial-deserializer.h"
#include "src/snapshot/read-only-deserializer.h"
#include "src/snapshot/startup-deserializer.h"
-#include "src/version.h"
+#include "src/utils/memcopy.h"
+#include "src/utils/version.h"
namespace v8 {
namespace internal {
@@ -151,7 +152,7 @@ v8::StartupData Snapshot::CreateSnapshotBlob(
uint32_t payload_length =
static_cast<uint32_t>(startup_snapshot->RawData().length());
CopyBytes(data + payload_offset,
- reinterpret_cast<const char*>(startup_snapshot->RawData().start()),
+ reinterpret_cast<const char*>(startup_snapshot->RawData().begin()),
payload_length);
if (FLAG_profile_deserialization) {
PrintF("Snapshot blob consists of:\n%10d bytes in %d chunks for startup\n",
@@ -165,7 +166,7 @@ v8::StartupData Snapshot::CreateSnapshotBlob(
payload_length = read_only_snapshot->RawData().length();
CopyBytes(
data + payload_offset,
- reinterpret_cast<const char*>(read_only_snapshot->RawData().start()),
+ reinterpret_cast<const char*>(read_only_snapshot->RawData().begin()),
payload_length);
if (FLAG_profile_deserialization) {
PrintF("%10d bytes for read-only\n", payload_length);
@@ -179,7 +180,7 @@ v8::StartupData Snapshot::CreateSnapshotBlob(
payload_length = context_snapshot->RawData().length();
CopyBytes(
data + payload_offset,
- reinterpret_cast<const char*>(context_snapshot->RawData().start()),
+ reinterpret_cast<const char*>(context_snapshot->RawData().begin()),
payload_length);
if (FLAG_profile_deserialization) {
PrintF("%10d bytes in %d chunks for context #%d\n", payload_length,
@@ -379,29 +380,55 @@ bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,
} // namespace
-// TODO(jgruber): Merge with related code in mksnapshot.cc and
-// inspector-test.cc.
v8::StartupData CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling,
- const char* embedded_source) {
- // Create a new isolate and a new context from scratch, optionally run
- // a script to embed, and serialize to create a snapshot blob.
- v8::StartupData result = {nullptr, 0};
+ const char* embedded_source, v8::Isolate* isolate) {
+ // If no isolate is passed in, create it (and a new context) from scratch.
+ if (isolate == nullptr) isolate = v8::Isolate::Allocate();
+
+ // Optionally run a script to embed, and serialize to create a snapshot blob.
+ v8::SnapshotCreator snapshot_creator(isolate);
{
- v8::SnapshotCreator snapshot_creator;
- v8::Isolate* isolate = snapshot_creator.GetIsolate();
- {
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- if (embedded_source != nullptr &&
- !RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
- return result;
- }
- snapshot_creator.SetDefaultContext(context);
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ if (embedded_source != nullptr &&
+ !RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
+ return {};
}
- result = snapshot_creator.CreateBlob(function_code_handling);
+ snapshot_creator.SetDefaultContext(context);
}
- return result;
+ return snapshot_creator.CreateBlob(function_code_handling);
+}
+
+v8::StartupData WarmUpSnapshotDataBlobInternal(
+ v8::StartupData cold_snapshot_blob, const char* warmup_source) {
+ CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != nullptr);
+ CHECK_NOT_NULL(warmup_source);
+
+ // Use following steps to create a warmed up snapshot blob from a cold one:
+ // - Create a new isolate from the cold snapshot.
+ // - Create a new context to run the warmup script. This will trigger
+ // compilation of executed functions.
+ // - Create a new context. This context will be unpolluted.
+ // - Serialize the isolate and the second context into a new snapshot blob.
+ v8::SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob);
+ v8::Isolate* isolate = snapshot_creator.GetIsolate();
+ {
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) {
+ return {};
+ }
+ }
+ {
+ v8::HandleScope handle_scope(isolate);
+ isolate->ContextDisposedNotification(false);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ snapshot_creator.SetDefaultContext(context);
+ }
+
+ return snapshot_creator.CreateBlob(
+ v8::SnapshotCreator::FunctionCodeHandling::kKeep);
}
} // namespace internal
diff --git a/deps/v8/src/snapshot/snapshot-external.cc b/deps/v8/src/snapshot/snapshot-external.cc
index c5f56ebb5a..d77ddae2aa 100644
--- a/deps/v8/src/snapshot/snapshot-external.cc
+++ b/deps/v8/src/snapshot/snapshot-external.cc
@@ -7,9 +7,8 @@
#include "src/snapshot/snapshot.h"
#include "src/base/platform/mutex.h"
+#include "src/init/v8.h" // for V8::Initialize
#include "src/snapshot/snapshot-source-sink.h"
-#include "src/v8.h" // for V8::Initialize
-
#ifndef V8_USE_EXTERNAL_STARTUP_DATA
#error snapshot-external.cc is used only for the external snapshot build.
diff --git a/deps/v8/src/snapshot/snapshot-source-sink.cc b/deps/v8/src/snapshot/snapshot-source-sink.cc
index ffc6ad0973..e39e2b393c 100644
--- a/deps/v8/src/snapshot/snapshot-source-sink.cc
+++ b/deps/v8/src/snapshot/snapshot-source-sink.cc
@@ -6,8 +6,8 @@
#include "src/snapshot/snapshot-source-sink.h"
#include "src/base/logging.h"
-#include "src/handles-inl.h"
-#include "src/objects-inl.h"
+#include "src/handles/handles-inl.h"
+#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/snapshot/snapshot-source-sink.h b/deps/v8/src/snapshot/snapshot-source-sink.h
index f5b35b174e..61396aaa71 100644
--- a/deps/v8/src/snapshot/snapshot-source-sink.h
+++ b/deps/v8/src/snapshot/snapshot-source-sink.h
@@ -6,7 +6,7 @@
#define V8_SNAPSHOT_SNAPSHOT_SOURCE_SINK_H_
#include "src/base/logging.h"
-#include "src/utils.h"
+#include "src/utils/utils.h"
namespace v8 {
namespace internal {
@@ -25,7 +25,7 @@ class SnapshotByteSource final {
position_(0) {}
explicit SnapshotByteSource(Vector<const byte> payload)
- : data_(payload.start()), length_(payload.length()), position_(0) {}
+ : data_(payload.begin()), length_(payload.length()), position_(0) {}
~SnapshotByteSource() = default;
diff --git a/deps/v8/src/snapshot/snapshot.h b/deps/v8/src/snapshot/snapshot.h
index 3f50f1060e..a9995b2d3e 100644
--- a/deps/v8/src/snapshot/snapshot.h
+++ b/deps/v8/src/snapshot/snapshot.h
@@ -8,8 +8,7 @@
#include "src/snapshot/partial-serializer.h"
#include "src/snapshot/startup-serializer.h"
-#include "src/objects-inl.h"
-#include "src/utils.h"
+#include "src/utils/utils.h"
namespace v8 {
namespace internal {
@@ -163,7 +162,12 @@ class Snapshot : public AllStatic {
// mksnapshot.
V8_EXPORT_PRIVATE v8::StartupData CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling,
- const char* embedded_source);
+ const char* embedded_source, v8::Isolate* isolate = nullptr);
+
+// Convenience wrapper around snapshot data blob warmup used e.g. by tests and
+// mksnapshot.
+V8_EXPORT_PRIVATE v8::StartupData WarmUpSnapshotDataBlobInternal(
+ v8::StartupData cold_snapshot_blob, const char* warmup_source);
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
void SetSnapshotFromFile(StartupData* snapshot_blob);
diff --git a/deps/v8/src/snapshot/startup-deserializer.cc b/deps/v8/src/snapshot/startup-deserializer.cc
index 65def345ce..168bc678fe 100644
--- a/deps/v8/src/snapshot/startup-deserializer.cc
+++ b/deps/v8/src/snapshot/startup-deserializer.cc
@@ -4,11 +4,11 @@
#include "src/snapshot/startup-deserializer.h"
-#include "src/api.h"
-#include "src/assembler-inl.h"
+#include "src/api/api.h"
+#include "src/codegen/assembler-inl.h"
+#include "src/execution/v8threads.h"
#include "src/heap/heap-inl.h"
#include "src/snapshot/snapshot.h"
-#include "src/v8threads.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/snapshot/startup-serializer.cc b/deps/v8/src/snapshot/startup-serializer.cc
index 47b3f0f41b..62a786f984 100644
--- a/deps/v8/src/snapshot/startup-serializer.cc
+++ b/deps/v8/src/snapshot/startup-serializer.cc
@@ -4,18 +4,17 @@
#include "src/snapshot/startup-serializer.h"
-#include "src/api.h"
-#include "src/code-tracer.h"
-#include "src/contexts.h"
-#include "src/deoptimizer.h"
-#include "src/global-handles.h"
+#include "src/api/api.h"
+#include "src/deoptimizer/deoptimizer.h"
+#include "src/execution/v8threads.h"
+#include "src/handles/global-handles.h"
#include "src/heap/heap-inl.h"
#include "src/heap/read-only-heap.h"
-#include "src/objects-inl.h"
+#include "src/objects/contexts.h"
#include "src/objects/foreign-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
#include "src/snapshot/read-only-serializer.h"
-#include "src/v8threads.h"
namespace v8 {
namespace internal {
@@ -37,25 +36,25 @@ StartupSerializer::~StartupSerializer() {
namespace {
bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) {
- if (!obj->IsCode()) return false;
+ if (!obj.IsCode()) return false;
Code code = Code::cast(obj);
// TODO(v8:8768): Deopt entry code should not be serialized.
- if (code->kind() == Code::STUB && isolate->deoptimizer_data() != nullptr) {
+ if (code.kind() == Code::STUB && isolate->deoptimizer_data() != nullptr) {
if (isolate->deoptimizer_data()->IsDeoptEntryCode(code)) return false;
}
- if (code->kind() == Code::REGEXP) return false;
- if (!code->is_builtin()) return true;
+ if (code.kind() == Code::REGEXP) return false;
+ if (!code.is_builtin()) return true;
if (!FLAG_embedded_builtins) return false;
- if (code->is_off_heap_trampoline()) return false;
+ if (code.is_off_heap_trampoline()) return false;
// An on-heap builtin. We only expect this for the interpreter entry
// trampoline copy stored on the root list and transitively called builtins.
// See Heap::interpreter_entry_trampoline_for_profiling.
- switch (code->builtin_index()) {
+ switch (code.builtin_index()) {
case Builtins::kAbort:
case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
case Builtins::kInterpreterEntryTrampoline:
@@ -72,16 +71,7 @@ bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) {
#endif // DEBUG
void StartupSerializer::SerializeObject(HeapObject obj) {
-#ifdef DEBUG
- if (obj.IsJSFunction()) {
- v8::base::OS::PrintError("Reference stack:\n");
- PrintStack(std::cerr);
- obj.Print(std::cerr);
- FATAL(
- "JSFunction should be added through the context snapshot instead of "
- "the isolate snapshot");
- }
-#endif // DEBUG
+ DCHECK(!obj.IsJSFunction());
DCHECK(!IsUnexpectedCodeObject(isolate(), obj));
if (SerializeHotObject(obj)) return;
@@ -94,26 +84,25 @@ void StartupSerializer::SerializeObject(HeapObject obj) {
use_simulator = true;
#endif
- if (use_simulator && obj->IsAccessorInfo()) {
+ if (use_simulator && obj.IsAccessorInfo()) {
// Wipe external reference redirects in the accessor info.
AccessorInfo info = AccessorInfo::cast(obj);
- Address original_address = Foreign::cast(info->getter())->foreign_address();
- Foreign::cast(info->js_getter())->set_foreign_address(original_address);
+ Address original_address = Foreign::cast(info.getter()).foreign_address();
+ Foreign::cast(info.js_getter()).set_foreign_address(original_address);
accessor_infos_.push_back(info);
- } else if (use_simulator && obj->IsCallHandlerInfo()) {
+ } else if (use_simulator && obj.IsCallHandlerInfo()) {
CallHandlerInfo info = CallHandlerInfo::cast(obj);
- Address original_address =
- Foreign::cast(info->callback())->foreign_address();
- Foreign::cast(info->js_callback())->set_foreign_address(original_address);
+ Address original_address = Foreign::cast(info.callback()).foreign_address();
+ Foreign::cast(info.js_callback()).set_foreign_address(original_address);
call_handler_infos_.push_back(info);
- } else if (obj->IsScript() && Script::cast(obj)->IsUserJavaScript()) {
- Script::cast(obj)->set_context_data(
+ } else if (obj.IsScript() && Script::cast(obj).IsUserJavaScript()) {
+ Script::cast(obj).set_context_data(
ReadOnlyRoots(isolate()).uninitialized_symbol());
- } else if (obj->IsSharedFunctionInfo()) {
+ } else if (obj.IsSharedFunctionInfo()) {
// Clear inferred name for native functions.
SharedFunctionInfo shared = SharedFunctionInfo::cast(obj);
- if (!shared->IsSubjectToDebugging() && shared->HasUncompiledData()) {
- shared->uncompiled_data()->set_inferred_name(
+ if (!shared.IsSubjectToDebugging() && shared.HasUncompiledData()) {
+ shared.uncompiled_data().set_inferred_name(
ReadOnlyRoots(isolate()).empty_string());
}
}
@@ -160,7 +149,7 @@ SerializedHandleChecker::SerializedHandleChecker(Isolate* isolate,
: isolate_(isolate) {
AddToSet(isolate->heap()->serialized_objects());
for (auto const& context : *contexts) {
- AddToSet(context->serialized_objects());
+ AddToSet(context.serialized_objects());
}
}
@@ -177,8 +166,8 @@ void StartupSerializer::SerializeUsingPartialSnapshotCache(
}
void SerializedHandleChecker::AddToSet(FixedArray serialized) {
- int length = serialized->length();
- for (int i = 0; i < length; i++) serialized_.insert(serialized->get(i));
+ int length = serialized.length();
+ for (int i = 0; i < length; i++) serialized_.insert(serialized.get(i));
}
void SerializedHandleChecker::VisitRootPointers(Root root,
@@ -189,7 +178,7 @@ void SerializedHandleChecker::VisitRootPointers(Root root,
if (serialized_.find(*p) != serialized_.end()) continue;
PrintF("%s handle not serialized: ",
root == Root::kGlobalHandles ? "global" : "eternal");
- (*p)->Print();
+ (*p).Print();
ok_ = false;
}
}