diff options
Diffstat (limited to 'deps/v8/src/serialize.cc')
-rw-r--r-- | deps/v8/src/serialize.cc | 188 |
1 files changed, 86 insertions, 102 deletions
diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc index 7ed36665e2..14b1b9cc96 100644 --- a/deps/v8/src/serialize.cc +++ b/deps/v8/src/serialize.cc @@ -297,15 +297,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { RUNTIME_ENTRY, 1, "Runtime::PerformGC"); - Add(ExternalReference::fill_heap_number_with_random_function( - isolate).address(), - RUNTIME_ENTRY, - 2, - "V8::FillHeapNumberWithRandom"); - Add(ExternalReference::random_uint32_function(isolate).address(), - RUNTIME_ENTRY, - 3, - "V8::Random"); Add(ExternalReference::delete_handle_scope_extensions(isolate).address(), RUNTIME_ENTRY, 4, @@ -325,8 +316,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { 7, "IncrementalMarking::RecordWrite"); - - // Miscellaneous Add(ExternalReference::roots_array_start(isolate).address(), UNCLASSIFIED, @@ -389,30 +378,10 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { 17, "Debug::step_in_fp_addr()"); #endif - Add(ExternalReference::double_fp_operation(Token::ADD, isolate).address(), - UNCLASSIFIED, - 18, - "add_two_doubles"); - Add(ExternalReference::double_fp_operation(Token::SUB, isolate).address(), - UNCLASSIFIED, - 19, - "sub_two_doubles"); - Add(ExternalReference::double_fp_operation(Token::MUL, isolate).address(), - UNCLASSIFIED, - 20, - "mul_two_doubles"); - Add(ExternalReference::double_fp_operation(Token::DIV, isolate).address(), - UNCLASSIFIED, - 21, - "div_two_doubles"); - Add(ExternalReference::double_fp_operation(Token::MOD, isolate).address(), + Add(ExternalReference::mod_two_doubles_operation(isolate).address(), UNCLASSIFIED, 22, "mod_two_doubles"); - Add(ExternalReference::compare_doubles(isolate).address(), - UNCLASSIFIED, - 23, - "compare_doubles"); #ifndef V8_INTERPRETED_REGEXP Add(ExternalReference::re_case_insensitive_compare_uc16(isolate).address(), UNCLASSIFIED, @@ -440,10 +409,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { UNCLASSIFIED, 29, "KeyedLookupCache::field_offsets()"); - Add(ExternalReference::transcendental_cache_array_address(isolate).address(), - UNCLASSIFIED, - 30, - "TranscendentalCache::caches()"); Add(ExternalReference::handle_scope_next_address(isolate).address(), UNCLASSIFIED, 31, @@ -536,20 +501,20 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { UNCLASSIFIED, 53, "Runtime::AllocateInNewSpace"); + Add(ExternalReference(Runtime::kAllocateInTargetSpace, isolate).address(), + UNCLASSIFIED, + 54, + "Runtime::AllocateInTargetSpace"); Add(ExternalReference::old_pointer_space_allocation_top_address( isolate).address(), UNCLASSIFIED, - 54, + 55, "Heap::OldPointerSpaceAllocationTopAddress"); Add(ExternalReference::old_pointer_space_allocation_limit_address( isolate).address(), UNCLASSIFIED, - 55, - "Heap::OldPointerSpaceAllocationLimitAddress"); - Add(ExternalReference(Runtime::kAllocateInOldPointerSpace, isolate).address(), - UNCLASSIFIED, 56, - "Runtime::AllocateInOldPointerSpace"); + "Heap::OldPointerSpaceAllocationLimitAddress"); Add(ExternalReference::old_data_space_allocation_top_address( isolate).address(), UNCLASSIFIED, @@ -560,30 +525,22 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { UNCLASSIFIED, 58, "Heap::OldDataSpaceAllocationLimitAddress"); - Add(ExternalReference(Runtime::kAllocateInOldDataSpace, isolate).address(), - UNCLASSIFIED, - 59, - "Runtime::AllocateInOldDataSpace"); Add(ExternalReference::new_space_high_promotion_mode_active_address(isolate). address(), UNCLASSIFIED, - 60, + 59, "Heap::NewSpaceAllocationLimitAddress"); Add(ExternalReference::allocation_sites_list_address(isolate).address(), UNCLASSIFIED, - 61, + 60, "Heap::allocation_sites_list_address()"); - Add(ExternalReference::record_object_allocation_function(isolate).address(), - UNCLASSIFIED, - 62, - "HeapProfiler::RecordObjectAllocationFromMasm"); Add(ExternalReference::address_of_uint32_bias().address(), UNCLASSIFIED, - 63, + 61, "uint32_bias"); Add(ExternalReference::get_mark_code_as_executed_function(isolate).address(), UNCLASSIFIED, - 64, + 62, "Code::MarkCodeAsExecuted"); // Add a small set of deopt entry addresses to encoder without generating the @@ -595,7 +552,7 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { entry, Deoptimizer::LAZY, Deoptimizer::CALCULATE_ENTRY_ADDRESS); - Add(address, LAZY_DEOPTIMIZATION, 64 + entry, "lazy_deopt"); + Add(address, LAZY_DEOPTIMIZATION, entry, "lazy_deopt"); } } @@ -813,6 +770,15 @@ Deserializer::Deserializer(SnapshotByteSource* source) } +void Deserializer::FlushICacheForNewCodeObjects() { + PageIterator it(isolate_->heap()->code_space()); + while (it.has_next()) { + Page* p = it.next(); + CPU::FlushICache(p->area_start(), p->area_end() - p->area_start()); + } +} + + void Deserializer::Deserialize(Isolate* isolate) { isolate_ = isolate; ASSERT(isolate_ != NULL); @@ -823,6 +789,7 @@ void Deserializer::Deserialize(Isolate* isolate) { ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty()); ASSERT_EQ(NULL, external_reference_decoder_); external_reference_decoder_ = new ExternalReferenceDecoder(isolate); + isolate_->heap()->IterateSmiRoots(this); isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); isolate_->heap()->RepairFreeListsAfterBoot(); isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); @@ -849,6 +816,8 @@ void Deserializer::Deserialize(Isolate* isolate) { } } + FlushICacheForNewCodeObjects(); + // Issue code events for newly deserialized code objects. LOG_CODE_EVENT(isolate_, LogCodeObjects()); LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); @@ -1285,7 +1254,6 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) : isolate_(isolate), sink_(sink), - current_root_index_(0), external_reference_encoder_(new ExternalReferenceEncoder(isolate)), root_index_wave_front_(0) { // The serializer is meant to be used only to generate initial heap images @@ -1311,7 +1279,7 @@ void StartupSerializer::SerializeStrongReferences() { CHECK_EQ(0, isolate->eternal_handles()->NumberOfHandles()); // We don't support serializing installed extensions. CHECK(!isolate->has_installed_extensions()); - + isolate->heap()->IterateSmiRoots(this); isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); } @@ -1668,86 +1636,71 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start, void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) { - Object** current = rinfo->target_object_address(); - int skip = OutputRawData(rinfo->target_address_address(), kCanReturnSkipInsteadOfSkipping); - HowToCode representation = rinfo->IsCodedSpecially() ? kFromCode : kPlain; - serializer_->SerializeObject(*current, representation, kStartOfObject, skip); + HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; + Object* object = rinfo->target_object(); + serializer_->SerializeObject(object, how_to_code, kStartOfObject, skip); bytes_processed_so_far_ += rinfo->target_address_size(); } void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { - Address references_start = reinterpret_cast<Address>(p); - int skip = OutputRawData(references_start, kCanReturnSkipInsteadOfSkipping); - + int skip = OutputRawData(reinterpret_cast<Address>(p), + kCanReturnSkipInsteadOfSkipping); sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); sink_->PutInt(skip, "SkipB4ExternalRef"); - int reference_id = serializer_->EncodeExternalReference(*p); - sink_->PutInt(reference_id, "reference id"); + Address target = *p; + sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); bytes_processed_so_far_ += kPointerSize; } void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { - Address references_start = rinfo->target_address_address(); - int skip = OutputRawData(references_start, kCanReturnSkipInsteadOfSkipping); - - Address* current = rinfo->target_reference_address(); - int representation = rinfo->IsCodedSpecially() ? - kFromCode + kStartOfObject : kPlain + kStartOfObject; - sink_->Put(kExternalReference + representation, "ExternalRef"); + int skip = OutputRawData(rinfo->target_address_address(), + kCanReturnSkipInsteadOfSkipping); + HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; + sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); sink_->PutInt(skip, "SkipB4ExternalRef"); - int reference_id = serializer_->EncodeExternalReference(*current); - sink_->PutInt(reference_id, "reference id"); + Address target = rinfo->target_reference(); + sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); bytes_processed_so_far_ += rinfo->target_address_size(); } void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { - Address target_start = rinfo->target_address_address(); - int skip = OutputRawData(target_start, kCanReturnSkipInsteadOfSkipping); - Address target = rinfo->target_address(); - uint32_t encoding = serializer_->EncodeExternalReference(target); - CHECK(target == NULL ? encoding == 0 : encoding != 0); - int representation; - // Can't use a ternary operator because of gcc. - if (rinfo->IsCodedSpecially()) { - representation = kStartOfObject + kFromCode; - } else { - representation = kStartOfObject + kPlain; - } - sink_->Put(kExternalReference + representation, "ExternalReference"); + int skip = OutputRawData(rinfo->target_address_address(), + kCanReturnSkipInsteadOfSkipping); + HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; + sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); sink_->PutInt(skip, "SkipB4ExternalRef"); - sink_->PutInt(encoding, "reference id"); + Address target = rinfo->target_address(); + sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); bytes_processed_so_far_ += rinfo->target_address_size(); } void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { - CHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); - Address target_start = rinfo->target_address_address(); - int skip = OutputRawData(target_start, kCanReturnSkipInsteadOfSkipping); - Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); - serializer_->SerializeObject(target, kFromCode, kInnerPointer, skip); + int skip = OutputRawData(rinfo->target_address_address(), + kCanReturnSkipInsteadOfSkipping); + Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); + serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); bytes_processed_so_far_ += rinfo->target_address_size(); } void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) { - Code* target = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping); - serializer_->SerializeObject(target, kPlain, kInnerPointer, skip); + Code* object = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); + serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); bytes_processed_so_far_ += kPointerSize; } void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { - ASSERT(rinfo->rmode() == RelocInfo::CELL); - Cell* cell = Cell::cast(rinfo->target_cell()); int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); - serializer_->SerializeObject(cell, kPlain, kInnerPointer, skip); + Cell* object = Cell::cast(rinfo->target_cell()); + serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); } @@ -1776,10 +1729,29 @@ void Serializer::ObjectSerializer::VisitExternalAsciiString( } +static Code* CloneCodeObject(HeapObject* code) { + Address copy = new byte[code->Size()]; + OS::MemCopy(copy, code->address(), code->Size()); + return Code::cast(HeapObject::FromAddress(copy)); +} + + +static void WipeOutRelocations(Code* code) { + int mode_mask = + RelocInfo::kCodeTargetMask | + RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | + RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | + RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); + for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { + it.rinfo()->WipeOut(); + } +} + + int Serializer::ObjectSerializer::OutputRawData( Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { Address object_start = object_->address(); - Address base = object_start + bytes_processed_so_far_; + 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_; int bytes_to_output = to_skip; @@ -1809,10 +1781,22 @@ int Serializer::ObjectSerializer::OutputRawData( sink_->Put(kRawData, "RawData"); sink_->PutInt(bytes_to_output, "length"); } + + // To make snapshots reproducible, we need to wipe out all pointers in code. + if (code_object_) { + Code* code = CloneCodeObject(object_); + WipeOutRelocations(code); + // We need to wipe out the header fields *after* wiping out the + // relocations, because some of these fields are needed for the latter. + code->WipeOutHeader(); + object_start = code->address(); + } + + const char* description = code_object_ ? "Code" : "Byte"; for (int i = 0; i < bytes_to_output; i++) { - unsigned int data = base[i]; - sink_->PutSection(data, "Byte"); + sink_->PutSection(object_start[base + i], description); } + if (code_object_) delete[] object_start; } if (to_skip != 0 && return_skip == kIgnoringReturn) { sink_->Put(kSkip, "Skip"); |