diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-24 11:30:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-30 12:56:19 +0000 |
commit | 6036726eb981b6c4b42047513b9d3f4ac865daac (patch) | |
tree | 673593e70678e7789766d1f732eb51f613a2703b /chromium/v8/src/snapshot | |
parent | 466052c4e7c052268fd931888cd58961da94c586 (diff) | |
download | qtwebengine-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.cc | 6 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/code-serializer.h | 1 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/deserializer.cc | 36 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/deserializer.h | 3 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/macros.h | 4 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/mksnapshot.cc | 40 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/object-deserializer.cc | 7 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/partial-deserializer.cc | 2 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/partial-serializer.cc | 2 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer-common.h | 8 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer.cc | 96 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer.h | 11 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/snapshot-common.cc | 62 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/snapshot.h | 44 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/startup-serializer.cc | 20 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/startup-serializer.h | 8 |
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(); |