summaryrefslogtreecommitdiff
path: root/chromium/v8/src/snapshot
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-24 11:30:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-30 12:56:19 +0000
commit6036726eb981b6c4b42047513b9d3f4ac865daac (patch)
tree673593e70678e7789766d1f732eb51f613a2703b /chromium/v8/src/snapshot
parent466052c4e7c052268fd931888cd58961da94c586 (diff)
downloadqtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/v8/src/snapshot')
-rw-r--r--chromium/v8/src/snapshot/code-serializer.cc6
-rw-r--r--chromium/v8/src/snapshot/code-serializer.h1
-rw-r--r--chromium/v8/src/snapshot/deserializer.cc36
-rw-r--r--chromium/v8/src/snapshot/deserializer.h3
-rw-r--r--chromium/v8/src/snapshot/macros.h4
-rw-r--r--chromium/v8/src/snapshot/mksnapshot.cc40
-rw-r--r--chromium/v8/src/snapshot/object-deserializer.cc7
-rw-r--r--chromium/v8/src/snapshot/partial-deserializer.cc2
-rw-r--r--chromium/v8/src/snapshot/partial-serializer.cc2
-rw-r--r--chromium/v8/src/snapshot/serializer-common.h8
-rw-r--r--chromium/v8/src/snapshot/serializer.cc96
-rw-r--r--chromium/v8/src/snapshot/serializer.h11
-rw-r--r--chromium/v8/src/snapshot/snapshot-common.cc62
-rw-r--r--chromium/v8/src/snapshot/snapshot.h44
-rw-r--r--chromium/v8/src/snapshot/startup-serializer.cc20
-rw-r--r--chromium/v8/src/snapshot/startup-serializer.h8
16 files changed, 195 insertions, 155 deletions
diff --git a/chromium/v8/src/snapshot/code-serializer.cc b/chromium/v8/src/snapshot/code-serializer.cc
index e91799cdadd..5db7cae94b2 100644
--- a/chromium/v8/src/snapshot/code-serializer.cc
+++ b/chromium/v8/src/snapshot/code-serializer.cc
@@ -57,7 +57,6 @@ ScriptCompiler::CachedData* CodeSerializer::Serialize(
// TODO(7110): Enable serialization of Asm modules once the AsmWasmData is
// context independent.
if (script->ContainsAsmModule()) return nullptr;
- if (isolate->debug()->is_active()) return nullptr;
isolate->heap()->read_only_space()->ClearStringPaddingIfNeeded();
@@ -206,8 +205,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
debug_bytecode_array = debug_info->DebugBytecodeArray();
sfi->SetDebugBytecodeArray(debug_info->OriginalBytecodeArray());
}
- sfi->set_function_identifier_or_debug_info(
- debug_info->function_identifier());
+ sfi->set_script_or_debug_info(debug_info->script());
}
DCHECK(!sfi->HasDebugInfo());
@@ -219,7 +217,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
// Restore debug info
if (debug_info != nullptr) {
- sfi->set_function_identifier_or_debug_info(debug_info);
+ sfi->set_script_or_debug_info(debug_info);
if (debug_bytecode_array != nullptr) {
sfi->SetDebugBytecodeArray(debug_bytecode_array);
}
diff --git a/chromium/v8/src/snapshot/code-serializer.h b/chromium/v8/src/snapshot/code-serializer.h
index c4878811ec3..d1f19ef081e 100644
--- a/chromium/v8/src/snapshot/code-serializer.h
+++ b/chromium/v8/src/snapshot/code-serializer.h
@@ -5,7 +5,6 @@
#ifndef V8_SNAPSHOT_CODE_SERIALIZER_H_
#define V8_SNAPSHOT_CODE_SERIALIZER_H_
-#include "src/parsing/preparse-data.h"
#include "src/snapshot/serializer.h"
namespace v8 {
diff --git a/chromium/v8/src/snapshot/deserializer.cc b/chromium/v8/src/snapshot/deserializer.cc
index dcb37ce63c6..3ed360e14a6 100644
--- a/chromium/v8/src/snapshot/deserializer.cc
+++ b/chromium/v8/src/snapshot/deserializer.cc
@@ -5,9 +5,12 @@
#include "src/snapshot/deserializer.h"
#include "src/assembler-inl.h"
+#include "src/heap/heap-write-barrier-inl.h"
#include "src/isolate.h"
#include "src/objects/api-callbacks.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/string.h"
#include "src/snapshot/builtin-deserializer-allocator.h"
@@ -207,15 +210,17 @@ HeapObject* Deserializer<AllocatorT>::PostProcessNewObject(HeapObject* obj,
if (obj->map() == ReadOnlyRoots(isolate_).native_source_string_map()) {
ExternalOneByteString* string = ExternalOneByteString::cast(obj);
DCHECK(string->is_short());
- string->set_resource(
- NativesExternalStringResource::DecodeForDeserialization(
- string->resource()));
+ string->SetResource(
+ isolate_, NativesExternalStringResource::DecodeForDeserialization(
+ string->resource()));
} else {
ExternalString* string = ExternalString::cast(obj);
uint32_t index = string->resource_as_uint32();
Address address =
static_cast<Address>(isolate_->api_external_references()[index]);
string->set_address_as_resource(address);
+ isolate_->heap()->UpdateExternalString(string, 0,
+ string->ExternalPayloadSize());
}
isolate_->heap()->RegisterExternalString(String::cast(obj));
} else if (obj->IsJSTypedArray()) {
@@ -319,8 +324,7 @@ HeapObject* Deserializer<AllocatorT>::GetBackReferencedObject(int space) {
return obj;
}
-// This routine writes the new object into the pointer provided and then
-// returns true if the new object was in young space and false otherwise.
+// This routine writes the new object into the pointer provided.
// The reason for this strange interface is that otherwise the object is
// written very late, which means the FreeSpace map is not set up by the
// time we need to use it to mark the space at the end of a page free.
@@ -506,14 +510,13 @@ bool Deserializer<AllocatorT>::ReadData(MaybeObject** current,
// object.
case kExternalReference + kPlain + kStartOfObject:
current = reinterpret_cast<MaybeObject**>(ReadExternalReferenceCase(
- kPlain, isolate, reinterpret_cast<void**>(current),
- current_object_address));
+ kPlain, reinterpret_cast<void**>(current), current_object_address));
break;
// Find an external reference and write a pointer to it in the current
// code object.
case kExternalReference + kFromCode + kStartOfObject:
current = reinterpret_cast<MaybeObject**>(ReadExternalReferenceCase(
- kFromCode, isolate, reinterpret_cast<void**>(current),
+ kFromCode, reinterpret_cast<void**>(current),
current_object_address));
break;
@@ -711,10 +714,9 @@ bool Deserializer<AllocatorT>::ReadData(MaybeObject** current,
UnalignedCopy(current, &hot_maybe_object);
if (write_barrier_needed && Heap::InNewSpace(hot_object)) {
Address current_address = reinterpret_cast<Address>(current);
- isolate->heap()->RecordWrite(
- HeapObject::FromAddress(current_object_address),
- reinterpret_cast<MaybeObject**>(current_address),
- hot_maybe_object);
+ GenerationalBarrier(HeapObject::FromAddress(current_object_address),
+ reinterpret_cast<MaybeObject**>(current_address),
+ hot_maybe_object);
}
current++;
break;
@@ -761,8 +763,7 @@ bool Deserializer<AllocatorT>::ReadData(MaybeObject** current,
template <class AllocatorT>
void** Deserializer<AllocatorT>::ReadExternalReferenceCase(
- HowToCode how, Isolate* isolate, void** current,
- Address current_object_address) {
+ HowToCode how, void** current, Address current_object_address) {
int skip = source_.GetInt();
current = reinterpret_cast<void**>(reinterpret_cast<Address>(current) + skip);
uint32_t reference_id = static_cast<uint32_t>(source_.GetInt());
@@ -873,10 +874,9 @@ MaybeObject** Deserializer<AllocatorT>::ReadDataCase(
if (emit_write_barrier && write_barrier_needed) {
Address current_address = reinterpret_cast<Address>(current);
SLOW_DCHECK(isolate->heap()->ContainsSlow(current_object_address));
- isolate->heap()->RecordWrite(
- HeapObject::FromAddress(current_object_address),
- reinterpret_cast<MaybeObject**>(current_address),
- *reinterpret_cast<MaybeObject**>(current_address));
+ GenerationalBarrier(HeapObject::FromAddress(current_object_address),
+ reinterpret_cast<MaybeObject**>(current_address),
+ *reinterpret_cast<MaybeObject**>(current_address));
}
if (!current_was_incremented) {
current++;
diff --git a/chromium/v8/src/snapshot/deserializer.h b/chromium/v8/src/snapshot/deserializer.h
index d3b57b21372..f13bc03fd44 100644
--- a/chromium/v8/src/snapshot/deserializer.h
+++ b/chromium/v8/src/snapshot/deserializer.h
@@ -124,8 +124,7 @@ class Deserializer : public SerializerDeserializer {
// A helper function for ReadData for reading external references.
// Returns the new value of {current}.
- inline void** ReadExternalReferenceCase(HowToCode how, Isolate* isolate,
- void** current,
+ inline void** ReadExternalReferenceCase(HowToCode how, void** current,
Address current_object_address);
void ReadObject(int space_number, MaybeObject** write_back,
diff --git a/chromium/v8/src/snapshot/macros.h b/chromium/v8/src/snapshot/macros.h
index 5ea6917c168..8551281614f 100644
--- a/chromium/v8/src/snapshot/macros.h
+++ b/chromium/v8/src/snapshot/macros.h
@@ -31,7 +31,11 @@
#else // !MACOSX && !WIN && !AIX
#define V8_ASM_MANGLE_LABEL ""
#define V8_ASM_RODATA_SECTION ".section .rodata\n"
+#if defined(OS_CHROMEOS) // ChromeOS
+#define V8_ASM_TEXT_SECTION ".section .text.hot.embedded\n"
+#else
#define V8_ASM_TEXT_SECTION ".section .text\n"
+#endif
#if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64)
#define V8_ASM_DECLARE(NAME) ".global " V8_ASM_MANGLE_LABEL NAME "\n"
#else
diff --git a/chromium/v8/src/snapshot/mksnapshot.cc b/chromium/v8/src/snapshot/mksnapshot.cc
index 9516108749f..a2303613d64 100644
--- a/chromium/v8/src/snapshot/mksnapshot.cc
+++ b/chromium/v8/src/snapshot/mksnapshot.cc
@@ -153,6 +153,9 @@ class SnapshotWriter {
static void WriteEmbeddedFileData(FILE* fp, const i::EmbeddedData* blob,
const char* embedded_variant) {
+ fprintf(fp, "V8_EMBEDDED_TEXT_HEADER(v8_%s_embedded_blob_)\n",
+ embedded_variant);
+#ifdef V8_OS_MACOSX
// Note: On some platforms (observed on mac64), inserting labels into the
// .byte stream causes the compiler to reorder symbols, invalidating stored
// offsets.
@@ -161,16 +164,47 @@ class SnapshotWriter {
// there since the chrome build process on mac verifies the order of symbols
// present in the binary.
// For now, the straight-forward solution seems to be to just emit a pure
- // .byte stream.
- fprintf(fp, "V8_EMBEDDED_TEXT_HEADER(v8_%s_embedded_blob_)\n",
- embedded_variant);
+ // .byte stream on OSX.
WriteBinaryContentsAsByteDirective(fp, blob->data(), blob->size());
+#else
+ WriteBinaryContentsAsByteDirective(fp, blob->data(),
+ i::EmbeddedData::RawDataOffset());
+ WriteBuiltins(fp, blob, embedded_variant);
+#endif
fprintf(fp, "extern \"C\" const uint8_t v8_%s_embedded_blob_[];\n",
embedded_variant);
fprintf(fp, "static const uint32_t v8_embedded_blob_size_ = %d;\n\n",
blob->size());
}
+ static void WriteBuiltins(FILE* fp, const i::EmbeddedData* blob,
+ const char* embedded_variant) {
+ const bool is_default_variant =
+ std::strcmp(embedded_variant, "Default") == 0;
+ for (int i = 0; i < i::Builtins::builtin_count; i++) {
+ if (!blob->ContainsBuiltin(i)) continue;
+
+ // 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.
+ if (is_default_variant) {
+ // Create nicer symbol names for the default mode.
+ fprintf(fp, "__asm__(V8_ASM_LABEL(\"Builtins_%s\"));\n",
+ i::Builtins::name(i));
+ } else {
+ fprintf(fp, "__asm__(V8_ASM_LABEL(\"%s_Builtins_%s\"));\n",
+ embedded_variant, i::Builtins::name(i));
+ }
+
+ WriteBinaryContentsAsByteDirective(
+ fp,
+ reinterpret_cast<const uint8_t*>(blob->InstructionStartOfBuiltin(i)),
+ blob->PaddedInstructionSizeOfBuiltin(i));
+ }
+ fprintf(fp, "\n");
+ }
+
static void WriteBinaryContentsAsByteDirective(FILE* fp, const uint8_t* data,
uint32_t size) {
static const int kTextWidth = 80;
diff --git a/chromium/v8/src/snapshot/object-deserializer.cc b/chromium/v8/src/snapshot/object-deserializer.cc
index 2fb86867d0c..aabc5bf1e0f 100644
--- a/chromium/v8/src/snapshot/object-deserializer.cc
+++ b/chromium/v8/src/snapshot/object-deserializer.cc
@@ -59,7 +59,7 @@ void ObjectDeserializer::
DCHECK(deserializing_user_code());
for (Code* code : new_code_objects()) {
// Record all references to embedded objects in the new code object.
- isolate()->heap()->RecordWritesIntoCode(code);
+ WriteBarrierForCode(code);
Assembler::FlushICache(code->raw_instruction_start(),
code->raw_instruction_size());
}
@@ -85,8 +85,9 @@ void ObjectDeserializer::CommitPostProcessedObjects() {
ScriptEvent(Logger::ScriptEventType::kDeserialize, script->id()));
LOG(isolate(), ScriptDetails(*script));
// Add script to list.
- Handle<Object> list =
- FixedArrayOfWeakCells::Add(isolate(), factory->script_list(), script);
+ Handle<WeakArrayList> list = factory->script_list();
+ list = WeakArrayList::AddToEnd(isolate(), list,
+ MaybeObjectHandle::Weak(script));
heap->SetRootScriptList(*list);
}
}
diff --git a/chromium/v8/src/snapshot/partial-deserializer.cc b/chromium/v8/src/snapshot/partial-deserializer.cc
index 626106a3532..a7725946364 100644
--- a/chromium/v8/src/snapshot/partial-deserializer.cc
+++ b/chromium/v8/src/snapshot/partial-deserializer.cc
@@ -4,7 +4,7 @@
#include "src/snapshot/partial-deserializer.h"
-#include "src/api.h"
+#include "src/api-inl.h"
#include "src/heap/heap-inl.h"
#include "src/snapshot/snapshot.h"
diff --git a/chromium/v8/src/snapshot/partial-serializer.cc b/chromium/v8/src/snapshot/partial-serializer.cc
index 5161629fa47..d127aa5f0a5 100644
--- a/chromium/v8/src/snapshot/partial-serializer.cc
+++ b/chromium/v8/src/snapshot/partial-serializer.cc
@@ -5,7 +5,7 @@
#include "src/snapshot/partial-serializer.h"
#include "src/snapshot/startup-serializer.h"
-#include "src/api.h"
+#include "src/api-inl.h"
#include "src/objects-inl.h"
namespace v8 {
diff --git a/chromium/v8/src/snapshot/serializer-common.h b/chromium/v8/src/snapshot/serializer-common.h
index f4db5513bb1..34a6b646769 100644
--- a/chromium/v8/src/snapshot/serializer-common.h
+++ b/chromium/v8/src/snapshot/serializer-common.h
@@ -10,7 +10,7 @@
#include "src/external-reference-table.h"
#include "src/globals.h"
#include "src/snapshot/references.h"
-#include "src/utils.h"
+#include "src/v8memory.h"
#include "src/visitors.h"
namespace v8 {
@@ -300,8 +300,10 @@ class SerializedData {
SerializedData(byte* data, int size)
: data_(data), size_(size), owns_data_(false) {}
SerializedData() : data_(nullptr), size_(0), owns_data_(false) {}
- SerializedData(SerializedData&& other)
- : data_(other.data_), size_(other.size_), owns_data_(other.owns_data_) {
+ SerializedData(SerializedData&& other) V8_NOEXCEPT
+ : data_(other.data_),
+ size_(other.size_),
+ owns_data_(other.owns_data_) {
// Ensure |other| will not attempt to destroy our data in destructor.
other.owns_data_ = false;
}
diff --git a/chromium/v8/src/snapshot/serializer.cc b/chromium/v8/src/snapshot/serializer.cc
index 67644b83f34..56d87b89165 100644
--- a/chromium/v8/src/snapshot/serializer.cc
+++ b/chromium/v8/src/snapshot/serializer.cc
@@ -5,8 +5,11 @@
#include "src/snapshot/serializer.h"
#include "src/assembler-inl.h"
+#include "src/heap/heap.h"
#include "src/interpreter/interpreter.h"
#include "src/objects/code.h"
+#include "src/objects/js-array-buffer-inl.h"
+#include "src/objects/js-array-inl.h"
#include "src/objects/map.h"
#include "src/snapshot/builtin-serializer-allocator.h"
#include "src/snapshot/natives.h"
@@ -23,21 +26,19 @@ Serializer<AllocatorT>::Serializer(Isolate* isolate)
allocator_(this) {
#ifdef OBJECT_PRINT
if (FLAG_serialization_statistics) {
- instance_type_count_ = NewArray<int>(kInstanceTypes);
- instance_type_size_ = NewArray<size_t>(kInstanceTypes);
- read_only_instance_type_count_ = NewArray<int>(kInstanceTypes);
- read_only_instance_type_size_ = NewArray<size_t>(kInstanceTypes);
- for (int i = 0; i < kInstanceTypes; i++) {
- instance_type_count_[i] = 0;
- instance_type_size_[i] = 0;
- read_only_instance_type_count_[i] = 0;
- read_only_instance_type_size_[i] = 0;
+ for (int space = 0; space < LAST_SPACE; ++space) {
+ instance_type_count_[space] = NewArray<int>(kInstanceTypes);
+ instance_type_size_[space] = NewArray<size_t>(kInstanceTypes);
+ for (int i = 0; i < kInstanceTypes; i++) {
+ instance_type_count_[space][i] = 0;
+ instance_type_size_[space][i] = 0;
+ }
}
} else {
- instance_type_count_ = nullptr;
- instance_type_size_ = nullptr;
- read_only_instance_type_count_ = nullptr;
- read_only_instance_type_size_ = nullptr;
+ for (int space = 0; space < LAST_SPACE; ++space) {
+ instance_type_count_[space] = nullptr;
+ instance_type_size_[space] = nullptr;
+ }
}
#endif // OBJECT_PRINT
}
@@ -46,11 +47,11 @@ template <class AllocatorT>
Serializer<AllocatorT>::~Serializer() {
if (code_address_map_ != nullptr) delete code_address_map_;
#ifdef OBJECT_PRINT
- if (instance_type_count_ != nullptr) {
- DeleteArray(instance_type_count_);
- DeleteArray(instance_type_size_);
- DeleteArray(read_only_instance_type_count_);
- DeleteArray(read_only_instance_type_size_);
+ for (int space = 0; space < LAST_SPACE; ++space) {
+ if (instance_type_count_[space] != nullptr) {
+ DeleteArray(instance_type_count_[space]);
+ DeleteArray(instance_type_size_[space]);
+ }
}
#endif // OBJECT_PRINT
}
@@ -60,13 +61,8 @@ template <class AllocatorT>
void Serializer<AllocatorT>::CountInstanceType(Map* map, int size,
AllocationSpace space) {
int instance_type = map->instance_type();
- if (space != RO_SPACE) {
- instance_type_count_[instance_type]++;
- instance_type_size_[instance_type] += size;
- } else {
- read_only_instance_type_count_[instance_type]++;
- read_only_instance_type_size_[instance_type] += size;
- }
+ instance_type_count_[space][instance_type]++;
+ instance_type_size_[space][instance_type] += size;
}
#endif // OBJECT_PRINT
@@ -79,28 +75,18 @@ void Serializer<AllocatorT>::OutputStatistics(const char* name) {
#ifdef OBJECT_PRINT
PrintF(" Instance types (count and bytes):\n");
-#define PRINT_INSTANCE_TYPE(Name) \
- if (instance_type_count_[Name]) { \
- PrintF("%10d %10" PRIuS " %s\n", instance_type_count_[Name], \
- instance_type_size_[Name], #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], \
+ instance_type_size_[space][Name], \
+ AllocationSpaceName(static_cast<AllocationSpace>(space)), #Name); \
+ } \
}
INSTANCE_TYPE_LIST(PRINT_INSTANCE_TYPE)
#undef PRINT_INSTANCE_TYPE
- size_t read_only_total = 0;
-#define UPDATE_TOTAL(Name) \
- read_only_total += read_only_instance_type_size_[Name];
- INSTANCE_TYPE_LIST(UPDATE_TOTAL)
-#undef UPDATE_TOTAL
- if (read_only_total > 0) {
- PrintF("\n Read Only Instance types (count and bytes):\n");
-#define PRINT_INSTANCE_TYPE(Name) \
- if (read_only_instance_type_count_[Name]) { \
- PrintF("%10d %10" PRIuS " %s\n", read_only_instance_type_count_[Name], \
- read_only_instance_type_size_[Name], #Name); \
- }
- INSTANCE_TYPE_LIST(PRINT_INSTANCE_TYPE)
-#undef PRINT_INSTANCE_TYPE
- }
+
PrintF("\n");
#endif // OBJECT_PRINT
}
@@ -130,11 +116,16 @@ void Serializer<AllocatorT>::VisitRootPointers(Root root,
if (root == Root::kBuiltins || root == Root::kDispatchTable) return;
for (Object** current = start; current < end; current++) {
- if ((*current)->IsSmi()) {
- PutSmi(Smi::cast(*current));
- } else {
- SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
- }
+ SerializeRootObject(*current);
+ }
+}
+
+template <class AllocatorT>
+void Serializer<AllocatorT>::SerializeRootObject(Object* object) {
+ if (object->IsSmi()) {
+ PutSmi(Smi::cast(object));
+ } else {
+ SerializeObject(HeapObject::cast(object), kPlain, kStartOfObject, 0);
}
}
@@ -260,7 +251,7 @@ void Serializer<AllocatorT>::PutRoot(
// Assert that the first 32 root array items are a conscious choice. They are
// chosen so that the most common ones can be encoded more efficiently.
- STATIC_ASSERT(Heap::kEmptyDescriptorArrayRootIndex ==
+ STATIC_ASSERT(Heap::kArgumentsMarkerRootIndex ==
kNumberOfRootArrayConstants - 1);
if (how_to_code == kPlain && where_to_point == kStartOfObject &&
@@ -1007,9 +998,10 @@ void Serializer<AllocatorT>::ObjectSerializer::OutputCode(int size) {
int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
- RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
- RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
+ RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
+ RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
+ RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
RelocInfo* rinfo = it.rinfo();
rinfo->WipeOut();
diff --git a/chromium/v8/src/snapshot/serializer.h b/chromium/v8/src/snapshot/serializer.h
index 6a5d1a4aaca..9427cb6c78c 100644
--- a/chromium/v8/src/snapshot/serializer.h
+++ b/chromium/v8/src/snapshot/serializer.h
@@ -28,8 +28,8 @@ class CodeAddressMap : public CodeEventLogger {
isolate_->logger()->RemoveCodeEventListener(this);
}
- void CodeMoveEvent(AbstractCode* from, Address to) override {
- address_to_name_map_.Move(from->address(), to);
+ void CodeMoveEvent(AbstractCode* from, AbstractCode* to) override {
+ address_to_name_map_.Move(from->address(), to->address());
}
void CodeDisableOptEvent(AbstractCode* code,
@@ -170,6 +170,7 @@ class Serializer : public SerializerDeserializer {
void VisitRootPointers(Root root, const char* description, Object** start,
Object** end) override;
+ void SerializeRootObject(Object* object);
void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
int skip);
@@ -253,10 +254,8 @@ class Serializer : public SerializerDeserializer {
#ifdef OBJECT_PRINT
static const int kInstanceTypes = LAST_TYPE + 1;
- int* instance_type_count_;
- size_t* instance_type_size_;
- int* read_only_instance_type_count_;
- size_t* read_only_instance_type_size_;
+ int* instance_type_count_[LAST_SPACE];
+ size_t* instance_type_size_[LAST_SPACE];
#endif // OBJECT_PRINT
#ifdef DEBUG
diff --git a/chromium/v8/src/snapshot/snapshot-common.cc b/chromium/v8/src/snapshot/snapshot-common.cc
index 5da7bb0f494..31f378792b3 100644
--- a/chromium/v8/src/snapshot/snapshot-common.cc
+++ b/chromium/v8/src/snapshot/snapshot-common.cc
@@ -6,7 +6,6 @@
#include "src/snapshot/snapshot.h"
-#include "src/api.h"
#include "src/assembler-inl.h"
#include "src/base/platform/platform.h"
#include "src/callable.h"
@@ -308,6 +307,10 @@ bool BuiltinAliasesOffHeapTrampolineRegister(Isolate* isolate, Code* code) {
case Builtins::TFJ:
case Builtins::TFS:
break;
+
+ // 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.
@@ -347,6 +350,7 @@ void FinalizeEmbeddedCodeTargets(Isolate* isolate, EmbeddedData* blob) {
// On X64, ARM, ARM64 we emit relative builtin-to-builtin jumps for isolate
// independent builtins in the snapshot. This fixes up the relative jumps
// to the right offsets in the snapshot.
+ // See also: Code::IsIsolateIndependent.
while (!on_heap_it.done()) {
DCHECK(!off_heap_it.done());
@@ -355,8 +359,10 @@ void FinalizeEmbeddedCodeTargets(Isolate* isolate, EmbeddedData* blob) {
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
CHECK(Builtins::IsIsolateIndependentBuiltin(target));
+ // 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();
off_heap_it.next();
@@ -378,8 +384,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Builtins* builtins = isolate->builtins();
// Store instruction stream lengths and offsets.
- std::vector<uint32_t> lengths(kTableSize);
- std::vector<uint32_t> offsets(kTableSize);
+ std::vector<struct Metadata> metadata(kTableSize);
bool saw_unsafe_builtin = false;
uint32_t raw_data_size = 0;
@@ -395,6 +400,16 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
saw_unsafe_builtin = true;
fprintf(stderr, "%s is not isolate-independent.\n", Builtins::name(i));
}
+ if (Builtins::IsWasmRuntimeStub(i) &&
+ RelocInfo::RequiresRelocation(code)) {
+ // Wasm additionally requires that its runtime stubs must be
+ // individually PIC (i.e. we must be able to copy each stub outside the
+ // embedded area without relocations). In particular, that means
+ // pc-relative calls to other builtins are disallowed.
+ saw_unsafe_builtin = true;
+ fprintf(stderr, "%s is a wasm runtime stub but needs relocation.\n",
+ Builtins::name(i));
+ }
if (BuiltinAliasesOffHeapTrampolineRegister(isolate, code)) {
saw_unsafe_builtin = true;
fprintf(stderr, "%s aliases the off-heap trampoline register.\n",
@@ -404,14 +419,13 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
uint32_t length = static_cast<uint32_t>(code->raw_instruction_size());
DCHECK_EQ(0, raw_data_size % kCodeAlignment);
- offsets[i] = raw_data_size;
- lengths[i] = length;
+ metadata[i].instructions_offset = raw_data_size;
+ metadata[i].instructions_length = length;
// Align the start of each instruction stream.
- raw_data_size += RoundUp<kCodeAlignment>(length);
+ raw_data_size += PadAndAlign(length);
} else {
- offsets[i] = raw_data_size;
- lengths[i] = 0;
+ metadata[i].instructions_offset = raw_data_size;
}
}
CHECK_WITH_MSG(
@@ -421,22 +435,23 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
"If in doubt, ask jgruber@");
const uint32_t blob_size = RawDataOffset() + raw_data_size;
- uint8_t* blob = new uint8_t[blob_size];
- std::memset(blob, 0, blob_size);
+ uint8_t* const blob = new uint8_t[blob_size];
+ uint8_t* const raw_data_start = blob + RawDataOffset();
- // Write the offsets and length tables.
- DCHECK_EQ(OffsetsSize(), sizeof(offsets[0]) * offsets.size());
- std::memcpy(blob + OffsetsOffset(), offsets.data(), OffsetsSize());
+ // Initially zap the entire blob, effectively padding the alignment area
+ // between two builtins with int3's (on x64/ia32).
+ ZapCode(reinterpret_cast<Address>(blob), blob_size);
- DCHECK_EQ(LengthsSize(), sizeof(lengths[0]) * lengths.size());
- std::memcpy(blob + LengthsOffset(), lengths.data(), LengthsSize());
+ // Write the metadata tables.
+ DCHECK_EQ(MetadataSize(), sizeof(metadata[0]) * metadata.size());
+ std::memcpy(blob + MetadataOffset(), metadata.data(), MetadataSize());
// Write the raw data section.
for (int i = 0; i < Builtins::builtin_count; i++) {
if (!Builtins::IsIsolateIndependent(i)) continue;
Code* code = builtins->builtin(i);
- uint32_t offset = offsets[i];
- uint8_t* dst = blob + RawDataOffset() + offset;
+ uint32_t offset = metadata[i].instructions_offset;
+ uint8_t* dst = raw_data_start + offset;
DCHECK_LE(RawDataOffset() + offset + code->raw_instruction_size(),
blob_size);
std::memcpy(dst, reinterpret_cast<uint8_t*>(code->raw_instruction_start()),
@@ -471,8 +486,8 @@ EmbeddedData EmbeddedData::FromBlob() {
Address EmbeddedData::InstructionStartOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
- const uint32_t* offsets = Offsets();
- const uint8_t* result = RawData() + offsets[i];
+ const struct Metadata* metadata = Metadata();
+ const uint8_t* result = RawData() + metadata[i].instructions_offset;
DCHECK_LE(result, data_ + size_);
DCHECK_IMPLIES(result == data_ + size_, InstructionSizeOfBuiltin(i) == 0);
return reinterpret_cast<Address>(result);
@@ -480,8 +495,8 @@ Address EmbeddedData::InstructionStartOfBuiltin(int i) const {
uint32_t EmbeddedData::InstructionSizeOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
- const uint32_t* lengths = Lengths();
- return lengths[i];
+ const struct Metadata* metadata = Metadata();
+ return metadata[i].instructions_length;
}
size_t EmbeddedData::CreateHash() const {
@@ -520,8 +535,7 @@ void EmbeddedData::PrintStatistics() const {
const int k90th = embedded_count * 0.90;
const int k99th = embedded_count * 0.99;
- const int metadata_size =
- static_cast<int>(HashSize() + OffsetsSize() + LengthsSize());
+ const int metadata_size = static_cast<int>(HashSize() + MetadataSize());
PrintF("EmbeddedData:\n");
PrintF(" Total size: %d\n",
diff --git a/chromium/v8/src/snapshot/snapshot.h b/chromium/v8/src/snapshot/snapshot.h
index 26f1cdb44bd..b973ebb3566 100644
--- a/chromium/v8/src/snapshot/snapshot.h
+++ b/chromium/v8/src/snapshot/snapshot.h
@@ -96,7 +96,7 @@ class EmbeddedData final {
// Padded with kCodeAlignment.
uint32_t PaddedInstructionSizeOfBuiltin(int i) const {
- return RoundUp<kCodeAlignment>(InstructionSizeOfBuiltin(i));
+ return PadAndAlign(InstructionSizeOfBuiltin(i));
}
size_t CreateHash() const;
@@ -104,41 +104,49 @@ class EmbeddedData final {
return *reinterpret_cast<const size_t*>(data_ + HashOffset());
}
+ struct Metadata {
+ // Blob layout information.
+ uint32_t instructions_offset;
+ uint32_t instructions_length;
+ };
+ STATIC_ASSERT(offsetof(Metadata, instructions_offset) == 0);
+ STATIC_ASSERT(offsetof(Metadata, instructions_length) == kUInt32Size);
+ STATIC_ASSERT(sizeof(Metadata) == kUInt32Size + kUInt32Size);
+
// The layout of the blob is as follows:
//
- // [0] hash of the remaining blob
- // [1] offset of instruction stream 0
- // ... offsets
- // [N + 1] length of instruction stream 0
- // ... lengths
- // ... instruction streams
+ // [0] hash of the remaining blob
+ // [1] metadata of instruction stream 0
+ // ... metadata
+ // ... instruction streams
static constexpr uint32_t kTableSize = Builtins::builtin_count;
static constexpr uint32_t HashOffset() { return 0; }
static constexpr uint32_t HashSize() { return kSizetSize; }
- static constexpr uint32_t OffsetsOffset() {
+ static constexpr uint32_t MetadataOffset() {
return HashOffset() + HashSize();
}
- static constexpr uint32_t OffsetsSize() { return kUInt32Size * kTableSize; }
- static constexpr uint32_t LengthsOffset() {
- return OffsetsOffset() + OffsetsSize();
+ static constexpr uint32_t MetadataSize() {
+ return sizeof(struct Metadata) * kTableSize;
}
- static constexpr uint32_t LengthsSize() { return kUInt32Size * kTableSize; }
static constexpr uint32_t RawDataOffset() {
- return RoundUp<kCodeAlignment>(LengthsOffset() + LengthsSize());
+ return PadAndAlign(MetadataOffset() + MetadataSize());
}
private:
EmbeddedData(const uint8_t* data, uint32_t size) : data_(data), size_(size) {}
- const uint32_t* Offsets() const {
- return reinterpret_cast<const uint32_t*>(data_ + OffsetsOffset());
- }
- const uint32_t* Lengths() const {
- return reinterpret_cast<const uint32_t*>(data_ + LengthsOffset());
+ const Metadata* Metadata() const {
+ return reinterpret_cast<const struct Metadata*>(data_ + MetadataOffset());
}
const uint8_t* RawData() const { return data_ + RawDataOffset(); }
+ static constexpr int PadAndAlign(int size) {
+ // Ensure we have at least one byte trailing the actual builtin
+ // instructions which we can later fill with int3.
+ return RoundUp<kCodeAlignment>(size + 1);
+ }
+
void PrintStatistics() const;
const uint8_t* data_;
diff --git a/chromium/v8/src/snapshot/startup-serializer.cc b/chromium/v8/src/snapshot/startup-serializer.cc
index 34c23a60773..9ad6cda5d10 100644
--- a/chromium/v8/src/snapshot/startup-serializer.cc
+++ b/chromium/v8/src/snapshot/startup-serializer.cc
@@ -70,8 +70,9 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
} else if (obj->IsSharedFunctionInfo()) {
// Clear inferred name for native functions.
SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
- if (!shared->IsSubjectToDebugging() && shared->HasInferredName()) {
- shared->set_inferred_name(ReadOnlyRoots(isolate()).empty_string());
+ if (!shared->IsSubjectToDebugging() && shared->HasUncompiledData()) {
+ shared->uncompiled_data()->set_inferred_name(
+ ReadOnlyRoots(isolate()).empty_string());
}
}
@@ -131,24 +132,13 @@ void StartupSerializer::VisitRootPointers(Root root, const char* description,
Object** start, Object** end) {
if (start == isolate()->heap()->roots_array_start()) {
// Serializing the root list needs special handling:
- // - The first pass over the root list only serializes immortal immovables.
- // - The second pass over the root list serializes the rest.
// - Only root list elements that have been fully serialized can be
- // referenced via as root by using kRootArray bytecodes.
- int skip = 0;
+ // referenced using kRootArray bytecodes.
for (Object** current = start; current < end; current++) {
+ SerializeRootObject(*current);
int root_index = static_cast<int>(current - start);
- if ((*current)->IsSmi()) {
- FlushSkip(skip);
- PutSmi(Smi::cast(*current));
- } else {
- SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject,
- skip);
- }
root_has_been_serialized_.set(root_index);
- skip = 0;
}
- FlushSkip(skip);
} else {
Serializer::VisitRootPointers(root, description, start, end);
}
diff --git a/chromium/v8/src/snapshot/startup-serializer.h b/chromium/v8/src/snapshot/startup-serializer.h
index 190cc595291..cf334d10b20 100644
--- a/chromium/v8/src/snapshot/startup-serializer.h
+++ b/chromium/v8/src/snapshot/startup-serializer.h
@@ -18,10 +18,10 @@ class StartupSerializer : public Serializer<> {
~StartupSerializer() override;
// Serialize the current state of the heap. The order is:
- // 1) Immortal immovable roots
- // 2) Remaining strong references.
- // 3) Partial snapshot cache.
- // 4) Weak references (e.g. the string table).
+ // 1) Strong roots
+ // 2) Builtins and bytecode handlers
+ // 3) Partial snapshot cache
+ // 4) Weak references (e.g. the string table)
void SerializeStrongReferences();
void SerializeWeakReferencesAndDeferred();