5 #include "src/snapshot/serializer.h" 7 #include "src/assembler-inl.h" 8 #include "src/heap/heap.h" 9 #include "src/interpreter/interpreter.h" 10 #include "src/objects/code.h" 11 #include "src/objects/js-array-buffer-inl.h" 12 #include "src/objects/js-array-inl.h" 13 #include "src/objects/map.h" 14 #include "src/objects/slots-inl.h" 15 #include "src/objects/smi.h" 16 #include "src/snapshot/natives.h" 17 #include "src/snapshot/snapshot.h" 22 Serializer::Serializer(Isolate* isolate)
24 external_reference_encoder_(isolate),
25 root_index_map_(isolate),
28 if (FLAG_serialization_statistics) {
29 for (
int space = 0; space < LAST_SPACE; ++space) {
30 instance_type_count_[space] = NewArray<int>(kInstanceTypes);
31 instance_type_size_[space] = NewArray<size_t>(kInstanceTypes);
32 for (
int i = 0;
i < kInstanceTypes;
i++) {
33 instance_type_count_[space][
i] = 0;
34 instance_type_size_[space][
i] = 0;
38 for (
int space = 0; space < LAST_SPACE; ++space) {
39 instance_type_count_[space] =
nullptr;
40 instance_type_size_[space] =
nullptr;
43 #endif // OBJECT_PRINT 46 Serializer::~Serializer() {
47 if (code_address_map_ !=
nullptr)
delete code_address_map_;
49 for (
int space = 0; space < LAST_SPACE; ++space) {
50 if (instance_type_count_[space] !=
nullptr) {
51 DeleteArray(instance_type_count_[space]);
52 DeleteArray(instance_type_size_[space]);
55 #endif // OBJECT_PRINT 59 void Serializer::CountInstanceType(Map map,
int size, AllocationSpace space) {
60 int instance_type = map->instance_type();
61 instance_type_count_[space][instance_type]++;
62 instance_type_size_[space][instance_type] += size;
64 #endif // OBJECT_PRINT 66 void Serializer::OutputStatistics(
const char* name) {
67 if (!FLAG_serialization_statistics)
return;
69 PrintF(
"%s:\n", name);
70 allocator()->OutputStatistics();
73 PrintF(
" Instance types (count and bytes):\n");
74 #define PRINT_INSTANCE_TYPE(Name) \ 75 for (int space = 0; space < LAST_SPACE; ++space) { \ 76 if (instance_type_count_[space][Name]) { \ 77 PrintF("%10d %10" PRIuS " %-10s %s\n", \ 78 instance_type_count_[space][Name], \ 79 instance_type_size_[space][Name], \ 80 AllocationSpaceName(static_cast<AllocationSpace>(space)), #Name); \ 83 INSTANCE_TYPE_LIST(PRINT_INSTANCE_TYPE)
84 #undef PRINT_INSTANCE_TYPE 87 #endif // OBJECT_PRINT 90 void Serializer::SerializeDeferredObjects() {
91 while (!deferred_objects_.empty()) {
92 HeapObject* obj = deferred_objects_.back();
93 deferred_objects_.pop_back();
94 ObjectSerializer obj_serializer(
this, obj, &sink_, kPlain, kStartOfObject);
95 obj_serializer.SerializeDeferred();
97 sink_.Put(kSynchronize,
"Finished with deferred objects");
100 bool Serializer::MustBeDeferred(HeapObject*
object) {
return false; }
102 void Serializer::VisitRootPointers(Root root,
const char* description,
103 ObjectSlot start, ObjectSlot end) {
104 for (ObjectSlot current = start; current < end; ++current) {
105 SerializeRootObject(*current);
109 void Serializer::SerializeRootObject(Object*
object) {
110 if (object->IsSmi()) {
111 PutSmi(Smi::cast(
object));
113 SerializeObject(HeapObject::cast(
object), kPlain, kStartOfObject, 0);
118 void Serializer::PrintStack() {
119 for (
const auto o : stack_) {
126 bool Serializer::SerializeRoot(HeapObject* obj, HowToCode how_to_code,
127 WhereToPoint where_to_point,
int skip) {
128 RootIndex root_index;
131 if (root_index_map()->Lookup(obj, &root_index)) {
132 PutRoot(root_index, obj, how_to_code, where_to_point, skip);
138 bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code,
139 WhereToPoint where_to_point,
int skip) {
140 if (how_to_code != kPlain || where_to_point != kStartOfObject)
return false;
142 int index = hot_objects_.Find(obj);
143 if (index == HotObjectsList::kNotFound)
return false;
144 DCHECK(index >= 0 && index < kNumberOfHotObjects);
145 if (FLAG_trace_serializer) {
146 PrintF(
" Encoding hot object %d:", index);
151 sink_.Put(kHotObjectWithSkip + index,
"HotObjectWithSkip");
152 sink_.PutInt(skip,
"HotObjectSkipDistance");
154 sink_.Put(kHotObject + index,
"HotObject");
159 bool Serializer::SerializeBackReference(HeapObject* obj, HowToCode how_to_code,
160 WhereToPoint where_to_point,
int skip) {
161 SerializerReference reference = reference_map_.LookupReference(obj);
162 if (!reference.is_valid())
return false;
167 if (reference.is_attached_reference()) {
169 if (FLAG_trace_serializer) {
170 PrintF(
" Encoding attached reference %d\n",
171 reference.attached_reference_index());
173 PutAttachedReference(reference, how_to_code, where_to_point);
175 DCHECK(reference.is_back_reference());
176 if (FLAG_trace_serializer) {
177 PrintF(
" Encoding back reference to: ");
182 PutAlignmentPrefix(obj);
183 AllocationSpace space = reference.space();
185 sink_.Put(kBackref + how_to_code + where_to_point + space,
"BackRef");
187 sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space,
189 sink_.PutInt(skip,
"BackRefSkipDistance");
191 PutBackReference(obj, reference);
196 bool Serializer::ObjectIsBytecodeHandler(HeapObject* obj)
const {
197 if (!obj->IsCode())
return false;
198 return (Code::cast(obj)->kind() == Code::BYTECODE_HANDLER);
201 void Serializer::PutRoot(RootIndex root, HeapObject*
object,
202 SerializerDeserializer::HowToCode how_to_code,
203 SerializerDeserializer::WhereToPoint where_to_point,
205 int root_index =
static_cast<int>(root);
206 if (FLAG_trace_serializer) {
207 PrintF(
" Encoding root %d:", root_index);
208 object->ShortPrint();
214 STATIC_ASSERT(static_cast<int>(RootIndex::kArgumentsMarker) ==
215 kNumberOfRootArrayConstants - 1);
217 if (how_to_code == kPlain && where_to_point == kStartOfObject &&
218 root_index < kNumberOfRootArrayConstants && !Heap::InNewSpace(
object)) {
220 sink_.Put(kRootArrayConstants + root_index,
"RootConstant");
222 sink_.Put(kRootArrayConstantsWithSkip + root_index,
"RootConstant");
223 sink_.PutInt(skip,
"SkipInPutRoot");
227 sink_.Put(kRootArray + how_to_code + where_to_point,
"RootSerialization");
228 sink_.PutInt(root_index,
"root_index");
229 hot_objects_.Add(
object);
233 void Serializer::PutSmi(Smi smi) {
234 sink_.Put(kOnePointerRawData,
"Smi");
235 Address raw_value = smi.ptr();
236 byte bytes[kPointerSize];
237 memcpy(bytes, &raw_value, kPointerSize);
238 for (
int i = 0;
i < kPointerSize;
i++) sink_.Put(bytes[
i],
"Byte");
241 void Serializer::PutBackReference(HeapObject*
object,
242 SerializerReference reference) {
243 DCHECK(allocator()->BackReferenceIsAlreadyAllocated(reference));
244 switch (reference.space()) {
246 sink_.PutInt(reference.map_index(),
"BackRefMapIndex");
250 sink_.PutInt(reference.large_object_index(),
"BackRefLargeObjectIndex");
254 sink_.PutInt(reference.chunk_index(),
"BackRefChunkIndex");
255 sink_.PutInt(reference.chunk_offset(),
"BackRefChunkOffset");
259 hot_objects_.Add(
object);
262 void Serializer::PutAttachedReference(SerializerReference reference,
263 HowToCode how_to_code,
264 WhereToPoint where_to_point) {
265 DCHECK(reference.is_attached_reference());
266 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
267 (how_to_code == kFromCode && where_to_point == kStartOfObject) ||
268 (how_to_code == kFromCode && where_to_point == kInnerPointer));
269 sink_.Put(kAttachedReference + how_to_code + where_to_point,
"AttachedRef");
270 sink_.PutInt(reference.attached_reference_index(),
"AttachedRefIndex");
273 int Serializer::PutAlignmentPrefix(HeapObject*
object) {
274 AllocationAlignment alignment = HeapObject::RequiredAlignment(object->map());
275 if (alignment != kWordAligned) {
276 DCHECK(1 <= alignment && alignment <= 3);
277 byte prefix = (kAlignmentPrefix - 1) + alignment;
278 sink_.Put(prefix,
"Alignment");
279 return Heap::GetMaximumFillToAlign(alignment);
284 void Serializer::PutNextChunk(
int space) {
285 sink_.Put(kNextChunk,
"NextChunk");
286 sink_.Put(space,
"NextChunkSpace");
289 void Serializer::Pad(
int padding_offset) {
292 for (
unsigned i = 0;
i <
sizeof(int32_t) - 1;
i++) {
293 sink_.Put(kNop,
"Padding");
296 while (!IsAligned(sink_.Position() + padding_offset, kPointerAlignment)) {
297 sink_.Put(kNop,
"Padding");
301 void Serializer::InitializeCodeAddressMap() {
302 isolate_->InitializeLoggingAndCounters();
303 code_address_map_ =
new CodeAddressMap(isolate_);
306 Code Serializer::CopyCode(Code code) {
307 code_buffer_.clear();
308 int size = code->CodeSize();
309 code_buffer_.insert(code_buffer_.end(),
310 reinterpret_cast<byte*
>(code->address()),
311 reinterpret_cast<byte*>(code->address() + size));
312 return Code::cast(HeapObject::FromAddress(
313 reinterpret_cast<Address>(&code_buffer_.front())));
316 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
318 if (serializer_->code_address_map_) {
319 const char* code_name =
320 serializer_->code_address_map_->Lookup(object_->address());
321 LOG(serializer_->isolate_,
322 CodeNameEvent(object_->address(), sink_->Position(), code_name));
325 SerializerReference back_reference;
326 if (space == LO_SPACE) {
327 sink_->Put(kNewObject + reference_representation_ + space,
329 sink_->PutInt(size >> kObjectAlignmentBits,
"ObjectSizeInWords");
330 CHECK(!object_->IsCode());
331 back_reference = serializer_->allocator()->AllocateLargeObject(size);
332 }
else if (space == MAP_SPACE) {
333 DCHECK_EQ(Map::kSize, size);
334 back_reference = serializer_->allocator()->AllocateMap();
335 sink_->Put(kNewObject + reference_representation_ + space,
"NewMap");
337 sink_->PutInt(size >> kObjectAlignmentBits,
"ObjectSizeInWords");
339 int fill = serializer_->PutAlignmentPrefix(object_);
340 back_reference = serializer_->allocator()->Allocate(space, size + fill);
341 sink_->Put(kNewObject + reference_representation_ + space,
"NewObject");
342 sink_->PutInt(size >> kObjectAlignmentBits,
"ObjectSizeInWords");
346 if (FLAG_serialization_statistics) {
347 serializer_->CountInstanceType(map, size, space);
349 #endif // OBJECT_PRINT 352 serializer_->reference_map()->Add(object_, back_reference);
355 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
358 int32_t Serializer::ObjectSerializer::SerializeBackingStore(
359 void* backing_store, int32_t byte_length) {
360 SerializerReference reference =
361 serializer_->reference_map()->LookupReference(backing_store);
364 if (!reference.is_valid()) {
365 sink_->Put(kOffHeapBackingStore,
"Off-heap backing store");
366 sink_->PutInt(byte_length,
"length");
367 sink_->PutRaw(static_cast<byte*>(backing_store), byte_length,
369 reference = serializer_->allocator()->AllocateOffHeapBackingStore();
371 serializer_->reference_map()->Add(backing_store, reference);
374 return static_cast<int32_t
>(reference.off_heap_backing_store_index());
377 void Serializer::ObjectSerializer::SerializeJSTypedArray() {
378 JSTypedArray* typed_array = JSTypedArray::cast(object_);
379 FixedTypedArrayBase elements =
380 FixedTypedArrayBase::cast(typed_array->elements());
382 if (!typed_array->WasNeutered()) {
383 if (!typed_array->is_on_heap()) {
385 JSArrayBuffer* buffer = JSArrayBuffer::cast(typed_array->buffer());
386 CHECK_LE(buffer->byte_length(), Smi::kMaxValue);
387 CHECK_LE(typed_array->byte_offset(), Smi::kMaxValue);
388 int32_t byte_length =
static_cast<int32_t
>(buffer->byte_length());
389 int32_t byte_offset =
static_cast<int32_t
>(typed_array->byte_offset());
393 void* backing_store =
reinterpret_cast<void*
>(
394 reinterpret_cast<intptr_t
>(elements->external_pointer()) -
396 int32_t ref = SerializeBackingStore(backing_store, byte_length);
401 elements->set_external_pointer(Smi::FromInt(ref));
408 elements->set_external_pointer(Smi::kZero);
409 elements->set_length(0);
414 void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
415 JSArrayBuffer* buffer = JSArrayBuffer::cast(object_);
416 void* backing_store = buffer->backing_store();
418 CHECK_LE(buffer->byte_length(), Smi::kMaxValue);
419 int32_t byte_length =
static_cast<int32_t
>(buffer->byte_length());
422 if (backing_store !=
nullptr) {
423 int32_t ref = SerializeBackingStore(backing_store, byte_length);
424 buffer->set_backing_store(Smi::FromInt(ref));
427 buffer->set_backing_store(backing_store);
430 void Serializer::ObjectSerializer::SerializeExternalString() {
431 Heap* heap = serializer_->isolate()->heap();
437 if (object_->map() != ReadOnlyRoots(heap).native_source_string_map()) {
438 ExternalString
string = ExternalString::cast(object_);
439 Address resource =
string->resource_as_address();
440 ExternalReferenceEncoder::Value reference;
441 if (serializer_->external_reference_encoder_.TryEncode(resource).To(
443 DCHECK(reference.is_from_api());
444 string->set_uint32_as_resource(reference.index());
446 string->set_address_as_resource(resource);
448 SerializeExternalStringAsSequentialString();
451 ExternalOneByteString
string = ExternalOneByteString::cast(object_);
452 DCHECK(string->is_uncached());
453 const NativesExternalStringResource* resource =
454 reinterpret_cast<const NativesExternalStringResource*
>(
457 string->set_resource(resource->EncodeForSerialization());
460 string->set_resource(resource);
464 void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
467 ReadOnlyRoots roots(serializer_->isolate());
468 DCHECK(object_->IsExternalString());
469 DCHECK(object_->map() != roots.native_source_string_map());
470 ExternalString
string = ExternalString::cast(object_);
471 int length =
string->length();
475 const byte* resource;
477 bool internalized = object_->IsInternalizedString();
478 if (object_->IsExternalOneByteString()) {
479 map = internalized ? roots.one_byte_internalized_string_map()
480 : roots.one_byte_string_map();
481 allocation_size = SeqOneByteString::SizeFor(length);
482 content_size = length * kCharSize;
483 resource =
reinterpret_cast<const byte*
>(
484 ExternalOneByteString::cast(
string)->resource()->data());
486 map = internalized ? roots.internalized_string_map() : roots.string_map();
487 allocation_size = SeqTwoByteString::SizeFor(length);
488 content_size = length * kShortSize;
489 resource =
reinterpret_cast<const byte*
>(
490 ExternalTwoByteString::cast(
string)->resource()->data());
493 AllocationSpace space =
494 (allocation_size > kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_SPACE;
495 SerializePrologue(space, allocation_size, map);
498 int bytes_to_output = allocation_size - HeapObject::kHeaderSize;
501 sink_->Put(kVariableRawData,
"RawDataForString");
502 sink_->PutInt(bytes_to_output,
"length");
505 uint8_t* string_start =
reinterpret_cast<uint8_t*
>(
string->address());
506 for (
int i = HeapObject::kHeaderSize;
i < SeqString::kHeaderSize;
i++) {
507 sink_->PutSection(string_start[
i],
"StringHeader");
511 sink_->PutRaw(resource, content_size,
"StringContent");
515 int padding_size = allocation_size - SeqString::kHeaderSize - content_size;
516 DCHECK(0 <= padding_size && padding_size < kObjectAlignment);
517 for (
int i = 0;
i < padding_size;
i++) sink_->PutSection(0,
"StringPadding");
526 if (object->IsAllocationSite() &&
527 AllocationSite::cast(
object)->HasWeakNext()) {
529 next_ = AllocationSite::cast(
object)->weak_next();
530 AllocationSite::cast(
object)->set_weak_next(
536 if (object_ !=
nullptr) {
537 AllocationSite::cast(object_)->set_weak_next(next_,
538 UPDATE_WEAK_WRITE_BARRIER);
545 DISALLOW_HEAP_ALLOCATION(no_gc_);
548 void Serializer::ObjectSerializer::Serialize() {
549 if (FLAG_trace_serializer) {
550 PrintF(
" Encoding heap object: ");
551 object_->ShortPrint();
555 if (object_->IsExternalString()) {
556 SerializeExternalString();
558 }
else if (!serializer_->isolate()->heap()->InReadOnlySpace(object_)) {
561 if (object_->IsSeqOneByteString()) {
564 SeqOneByteString::cast(object_)->clear_padding();
565 }
else if (object_->IsSeqTwoByteString()) {
566 SeqTwoByteString::cast(object_)->clear_padding();
569 if (object_->IsJSTypedArray()) {
570 SerializeJSTypedArray();
573 if (object_->IsJSArrayBuffer()) {
574 SerializeJSArrayBuffer();
579 DCHECK(!object_->IsFiller());
581 if (object_->IsScript()) {
583 Object* undefined = ReadOnlyRoots(serializer_->isolate()).undefined_value();
584 Script::cast(object_)->set_line_ends(undefined);
590 void Serializer::ObjectSerializer::SerializeObject() {
591 int size = object_->Size();
592 Map map = object_->map();
593 AllocationSpace space =
594 MemoryChunk::FromAddress(object_->address())->owner()->identity();
596 if (space == NEW_LO_SPACE) {
599 SerializePrologue(space, size, map);
602 CHECK_EQ(0, bytes_processed_so_far_);
603 bytes_processed_so_far_ = kPointerSize;
605 RecursionScope recursion(serializer_);
608 if ((recursion.ExceedsMaximum() && CanBeDeferred(object_)) ||
609 serializer_->MustBeDeferred(object_)) {
610 serializer_->QueueDeferredObject(object_);
611 sink_->Put(kDeferred,
"Deferring object content");
615 SerializeContent(map, size);
618 void Serializer::ObjectSerializer::SerializeDeferred() {
619 if (FLAG_trace_serializer) {
620 PrintF(
" Encoding deferred heap object: ");
621 object_->ShortPrint();
625 int size = object_->Size();
626 Map map = object_->map();
627 SerializerReference back_reference =
628 serializer_->reference_map()->LookupReference(object_);
629 DCHECK(back_reference.is_back_reference());
632 CHECK_EQ(0, bytes_processed_so_far_);
633 bytes_processed_so_far_ = kPointerSize;
635 serializer_->PutAlignmentPrefix(object_);
636 sink_->Put(kNewObject + back_reference.space(),
"deferred object");
637 serializer_->PutBackReference(object_, back_reference);
638 sink_->PutInt(size >> kPointerSizeLog2,
"deferred object size");
640 SerializeContent(map, size);
643 void Serializer::ObjectSerializer::SerializeContent(Map map,
int size) {
644 UnlinkWeakNextScope unlink_weak_next(serializer_->isolate()->heap(), object_);
645 if (object_->IsCode()) {
649 object_->IterateBody(map, size,
this);
651 serializer_->FlushSkip(SkipTo(object_->address() + size));
654 object_->IterateBody(map, size,
this);
656 OutputRawData(object_->address() + size);
660 void Serializer::ObjectSerializer::VisitPointers(HeapObject* host,
663 VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end));
666 void Serializer::ObjectSerializer::VisitPointers(HeapObject* host,
667 MaybeObjectSlot start,
668 MaybeObjectSlot end) {
669 MaybeObjectSlot current = start;
670 while (current < end) {
671 while (current < end && (*current)->IsSmi()) {
675 OutputRawData(current.address());
679 while (current < end && (*current)->IsCleared()) {
680 sink_->Put(kClearedWeakReference,
"ClearedWeakReference");
681 bytes_processed_so_far_ += kPointerSize;
684 HeapObject* current_contents;
685 HeapObjectReferenceType reference_type;
686 while (current < end &&
687 (*current)->GetHeapObject(¤t_contents, &reference_type)) {
688 RootIndex root_index;
691 if (current != start &&
692 serializer_->root_index_map()->Lookup(current_contents,
694 RootsTable::IsImmortalImmovable(root_index) &&
695 *current == *(current - 1)) {
696 DCHECK_EQ(reference_type, HeapObjectReferenceType::STRONG);
697 DCHECK(!Heap::InNewSpace(current_contents));
698 int repeat_count = 1;
699 while (current + repeat_count < end - 1 &&
700 *(current + repeat_count) == *current) {
703 current += repeat_count;
704 bytes_processed_so_far_ += repeat_count * kPointerSize;
705 if (repeat_count > kNumberOfFixedRepeat) {
706 sink_->Put(kVariableRepeat,
"VariableRepeat");
707 sink_->PutInt(repeat_count,
"repeat count");
709 sink_->Put(kFixedRepeatStart + repeat_count,
"FixedRepeat");
712 if (reference_type == HeapObjectReferenceType::WEAK) {
713 sink_->Put(kWeakPrefix,
"WeakReference");
715 serializer_->SerializeObject(current_contents, kPlain, kStartOfObject,
717 bytes_processed_so_far_ += kPointerSize;
724 void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code host,
726 int skip = SkipTo(rinfo->target_address_address());
727 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
728 Object*
object = rinfo->target_object();
729 serializer_->SerializeObject(HeapObject::cast(
object), how_to_code,
730 kStartOfObject, skip);
731 bytes_processed_so_far_ += rinfo->target_address_size();
734 void Serializer::ObjectSerializer::VisitExternalReference(Foreign* host,
736 int skip = SkipTo(reinterpret_cast<Address>(p));
738 auto encoded_reference = serializer_->EncodeExternalReference(target);
739 if (encoded_reference.is_from_api()) {
740 sink_->Put(kApiReference,
"ApiRef");
742 sink_->Put(kExternalReference + kPlain + kStartOfObject,
"ExternalRef");
744 sink_->PutInt(skip,
"SkipB4ExternalRef");
745 sink_->PutInt(encoded_reference.index(),
"reference index");
746 bytes_processed_so_far_ += kPointerSize;
749 void Serializer::ObjectSerializer::VisitExternalReference(Code host,
751 int skip = SkipTo(rinfo->target_address_address());
752 Address target = rinfo->target_external_reference();
753 auto encoded_reference = serializer_->EncodeExternalReference(target);
754 if (encoded_reference.is_from_api()) {
755 DCHECK(!rinfo->IsCodedSpecially());
756 sink_->Put(kApiReference,
"ApiRef");
758 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
759 sink_->Put(kExternalReference + how_to_code + kStartOfObject,
762 sink_->PutInt(skip,
"SkipB4ExternalRef");
763 DCHECK_NE(target, kNullAddress);
764 sink_->PutInt(encoded_reference.index(),
"reference index");
765 bytes_processed_so_far_ += rinfo->target_address_size();
768 void Serializer::ObjectSerializer::VisitInternalReference(Code host,
776 Address entry = Code::cast(object_)->entry();
777 DCHECK_GE(rinfo->target_internal_reference_address(), entry);
778 uintptr_t pc_offset = rinfo->target_internal_reference_address() - entry;
779 DCHECK_LE(pc_offset, Code::cast(object_)->raw_instruction_size());
780 DCHECK_GE(rinfo->target_internal_reference(), entry);
781 uintptr_t target_offset = rinfo->target_internal_reference() - entry;
782 DCHECK_LE(target_offset, Code::cast(object_)->raw_instruction_size());
783 sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE
785 : kInternalReferenceEncoded,
787 sink_->PutInt(pc_offset,
"internal ref address");
788 sink_->PutInt(target_offset,
"internal ref value");
791 void Serializer::ObjectSerializer::VisitRuntimeEntry(Code host,
793 int skip = SkipTo(rinfo->target_address_address());
794 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
795 Address target = rinfo->target_address();
796 auto encoded_reference = serializer_->EncodeExternalReference(target);
797 DCHECK(!encoded_reference.is_from_api());
798 sink_->Put(kExternalReference + how_to_code + kStartOfObject,
"ExternalRef");
799 sink_->PutInt(skip,
"SkipB4ExternalRef");
800 sink_->PutInt(encoded_reference.index(),
"reference index");
801 bytes_processed_so_far_ += rinfo->target_address_size();
804 void Serializer::ObjectSerializer::VisitOffHeapTarget(Code host,
806 DCHECK(FLAG_embedded_builtins);
808 STATIC_ASSERT(EmbeddedData::kTableSize == Builtins::builtin_count);
809 CHECK(Builtins::IsIsolateIndependentBuiltin(host));
810 Address addr = rinfo->target_off_heap_target();
811 CHECK_NE(kNullAddress, addr);
812 CHECK(!InstructionStream::TryLookupCode(serializer_->isolate(), addr)
816 int skip = SkipTo(rinfo->target_address_address());
817 sink_->Put(kOffHeapTarget,
"OffHeapTarget");
818 sink_->PutInt(skip,
"SkipB4OffHeapTarget");
819 sink_->PutInt(host->builtin_index(),
"builtin index");
820 bytes_processed_so_far_ += rinfo->target_address_size();
824 class CompareRelocInfo {
826 bool operator()(RelocInfo x, RelocInfo y) {
830 if (HasTargetAddressAddress(x.rmode())) {
831 x_num = x.target_address_address();
833 if (HasTargetAddressAddress(y.rmode())) {
834 y_num = y.target_address_address();
836 return x_num > y_num;
840 static bool HasTargetAddressAddress(RelocInfo::Mode mode) {
841 return RelocInfo::IsEmbeddedObject(mode) || RelocInfo::IsCodeTarget(mode) ||
842 RelocInfo::IsExternalReference(mode) ||
843 RelocInfo::IsRuntimeEntry(mode);
848 void Serializer::ObjectSerializer::VisitRelocInfo(RelocIterator* it) {
849 std::priority_queue<RelocInfo, std::vector<RelocInfo>, CompareRelocInfo>
851 for (; !it->done(); it->next()) {
852 reloc_queue.push(*it->rinfo());
854 while (!reloc_queue.empty()) {
855 RelocInfo rinfo = reloc_queue.top();
861 void Serializer::ObjectSerializer::VisitCodeTarget(Code host,
863 int skip = SkipTo(rinfo->target_address_address());
864 Code
object = Code::GetCodeFromTargetAddress(rinfo->target_address());
865 serializer_->SerializeObject(
object, kFromCode, kInnerPointer, skip);
866 bytes_processed_so_far_ += rinfo->target_address_size();
869 void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
870 Address object_start = object_->address();
871 int base = bytes_processed_so_far_;
872 int up_to_offset =
static_cast<int>(up_to - object_start);
873 int to_skip = up_to_offset - bytes_processed_so_far_;
874 int bytes_to_output = to_skip;
875 bytes_processed_so_far_ += to_skip;
876 DCHECK_GE(to_skip, 0);
877 if (bytes_to_output != 0) {
878 DCHECK(to_skip == bytes_to_output);
879 if (IsAligned(bytes_to_output, kPointerAlignment) &&
880 bytes_to_output <= kNumberOfFixedRawData * kPointerSize) {
881 int size_in_words = bytes_to_output >> kPointerSizeLog2;
882 sink_->PutSection(kFixedRawDataStart + size_in_words,
"FixedRawData");
884 sink_->Put(kVariableRawData,
"VariableRawData");
885 sink_->PutInt(bytes_to_output,
"length");
887 #ifdef MEMORY_SANITIZER 889 __msan_check_mem_is_initialized(
890 reinterpret_cast<void*>(object_start + base), bytes_to_output);
891 #endif // MEMORY_SANITIZER 892 if (object_->IsBytecodeArray()) {
894 const int bytes_to_age_byte = BytecodeArray::kBytecodeAgeOffset - base;
895 if (0 <= bytes_to_age_byte && bytes_to_age_byte < bytes_to_output) {
896 sink_->PutRaw(reinterpret_cast<byte*>(object_start + base),
897 bytes_to_age_byte,
"Bytes");
898 byte bytecode_age = BytecodeArray::kNoAgeBytecodeAge;
899 sink_->PutRaw(&bytecode_age, 1,
"Bytes");
900 const int bytes_written = bytes_to_age_byte + 1;
902 reinterpret_cast<byte*>(object_start + base + bytes_written),
903 bytes_to_output - bytes_written,
"Bytes");
905 sink_->PutRaw(reinterpret_cast<byte*>(object_start + base),
906 bytes_to_output,
"Bytes");
909 sink_->PutRaw(reinterpret_cast<byte*>(object_start + base),
910 bytes_to_output,
"Bytes");
915 int Serializer::ObjectSerializer::SkipTo(Address to) {
916 Address object_start = object_->address();
917 int up_to_offset =
static_cast<int>(to - object_start);
918 int to_skip = up_to_offset - bytes_processed_so_far_;
919 bytes_processed_so_far_ += to_skip;
923 DCHECK_GE(to_skip, 0);
927 void Serializer::ObjectSerializer::OutputCode(
int size) {
928 DCHECK_EQ(kPointerSize, bytes_processed_so_far_);
929 Code on_heap_code = Code::cast(object_);
932 Code off_heap_code = serializer_->CopyCode(on_heap_code);
933 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
934 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
935 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
936 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
937 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
938 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
939 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
943 ByteArray relocation_info = on_heap_code->unchecked_relocation_info();
944 for (RelocIterator it(off_heap_code, relocation_info, mode_mask); !it.done();
946 RelocInfo* rinfo = it.rinfo();
951 off_heap_code->WipeOutHeader();
953 Address start = off_heap_code->address() + Code::kDataStart;
954 int bytes_to_output = size - Code::kDataStart;
956 sink_->Put(kVariableRawCode,
"VariableRawCode");
957 sink_->PutInt(bytes_to_output,
"length");
959 #ifdef MEMORY_SANITIZER 961 __msan_check_mem_is_initialized(reinterpret_cast<void*>(start),
963 #endif // MEMORY_SANITIZER 964 sink_->PutRaw(reinterpret_cast<byte*>(start), bytes_to_output,
"Code");