OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/snapshot/serialize.h" | 5 #include "src/snapshot/serialize.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 ExtraNatives::UpdateSourceCache(isolate_->heap()); | 554 ExtraNatives::UpdateSourceCache(isolate_->heap()); |
555 CodeStubNatives::UpdateSourceCache(isolate_->heap()); | 555 CodeStubNatives::UpdateSourceCache(isolate_->heap()); |
556 | 556 |
557 // Issue code events for newly deserialized code objects. | 557 // Issue code events for newly deserialized code objects. |
558 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 558 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
559 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 559 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
560 } | 560 } |
561 | 561 |
562 | 562 |
563 MaybeHandle<Object> Deserializer::DeserializePartial( | 563 MaybeHandle<Object> Deserializer::DeserializePartial( |
564 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, | 564 Isolate* isolate, Handle<JSGlobalProxy> global_proxy) { |
565 Handle<FixedArray>* outdated_contexts_out) { | |
566 Initialize(isolate); | 565 Initialize(isolate); |
567 if (!ReserveSpace()) { | 566 if (!ReserveSpace()) { |
568 V8::FatalProcessOutOfMemory("deserialize context"); | 567 V8::FatalProcessOutOfMemory("deserialize context"); |
569 return MaybeHandle<Object>(); | 568 return MaybeHandle<Object>(); |
570 } | 569 } |
571 | 570 |
572 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(1); | 571 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(1); |
573 attached_objects[kGlobalProxyReference] = global_proxy; | 572 attached_objects[kGlobalProxyReference] = global_proxy; |
574 SetAttachedObjects(attached_objects); | 573 SetAttachedObjects(attached_objects); |
575 | 574 |
576 DisallowHeapAllocation no_gc; | 575 DisallowHeapAllocation no_gc; |
577 // Keep track of the code space start and end pointers in case new | 576 // Keep track of the code space start and end pointers in case new |
578 // code objects were unserialized | 577 // code objects were unserialized |
579 OldSpace* code_space = isolate_->heap()->code_space(); | 578 OldSpace* code_space = isolate_->heap()->code_space(); |
580 Address start_address = code_space->top(); | 579 Address start_address = code_space->top(); |
581 Object* root; | 580 Object* root; |
582 Object* outdated_contexts; | |
583 VisitPointer(&root); | 581 VisitPointer(&root); |
584 DeserializeDeferredObjects(); | 582 DeserializeDeferredObjects(); |
585 VisitPointer(&outdated_contexts); | |
586 | 583 |
587 // There's no code deserialized here. If this assert fires then that's | 584 // There's no code deserialized here. If this assert fires then that's |
588 // changed and logging should be added to notify the profiler et al of the | 585 // changed and logging should be added to notify the profiler et al of the |
589 // new code, which also has to be flushed from instruction cache. | 586 // new code, which also has to be flushed from instruction cache. |
590 CHECK_EQ(start_address, code_space->top()); | 587 CHECK_EQ(start_address, code_space->top()); |
591 CHECK(outdated_contexts->IsFixedArray()); | |
592 *outdated_contexts_out = | |
593 Handle<FixedArray>(FixedArray::cast(outdated_contexts), isolate); | |
594 return Handle<Object>(root, isolate); | 588 return Handle<Object>(root, isolate); |
595 } | 589 } |
596 | 590 |
597 | 591 |
598 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( | 592 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( |
599 Isolate* isolate) { | 593 Isolate* isolate) { |
600 Initialize(isolate); | 594 Initialize(isolate); |
601 if (!ReserveSpace()) { | 595 if (!ReserveSpace()) { |
602 return Handle<SharedFunctionInfo>(); | 596 return Handle<SharedFunctionInfo>(); |
603 } else { | 597 } else { |
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1477 // it before serializing, it will get re-added to the context list | 1471 // it before serializing, it will get re-added to the context list |
1478 // explicitly when it's loaded. | 1472 // explicitly when it's loaded. |
1479 if (context->IsNativeContext()) { | 1473 if (context->IsNativeContext()) { |
1480 context->set(Context::NEXT_CONTEXT_LINK, | 1474 context->set(Context::NEXT_CONTEXT_LINK, |
1481 isolate_->heap()->undefined_value()); | 1475 isolate_->heap()->undefined_value()); |
1482 DCHECK(!context->global_object()->IsUndefined()); | 1476 DCHECK(!context->global_object()->IsUndefined()); |
1483 } | 1477 } |
1484 } | 1478 } |
1485 VisitPointer(o); | 1479 VisitPointer(o); |
1486 SerializeDeferredObjects(); | 1480 SerializeDeferredObjects(); |
1487 SerializeOutdatedContextsAsFixedArray(); | |
1488 Pad(); | 1481 Pad(); |
1489 } | 1482 } |
1490 | 1483 |
1491 | 1484 |
1492 void PartialSerializer::SerializeOutdatedContextsAsFixedArray() { | |
1493 int length = outdated_contexts_.length(); | |
1494 if (length == 0) { | |
1495 FixedArray* empty = isolate_->heap()->empty_fixed_array(); | |
1496 SerializeObject(empty, kPlain, kStartOfObject, 0); | |
1497 } else { | |
1498 // Serialize an imaginary fixed array containing outdated contexts. | |
1499 int size = FixedArray::SizeFor(length); | |
1500 Allocate(NEW_SPACE, size); | |
1501 sink_->Put(kNewObject + NEW_SPACE, "emulated FixedArray"); | |
1502 sink_->PutInt(size >> kObjectAlignmentBits, "FixedArray size in words"); | |
1503 Map* map = isolate_->heap()->fixed_array_map(); | |
1504 SerializeObject(map, kPlain, kStartOfObject, 0); | |
1505 Smi* length_smi = Smi::FromInt(length); | |
1506 sink_->Put(kOnePointerRawData, "Smi"); | |
1507 for (int i = 0; i < kPointerSize; i++) { | |
1508 sink_->Put(reinterpret_cast<byte*>(&length_smi)[i], "Byte"); | |
1509 } | |
1510 for (int i = 0; i < length; i++) { | |
1511 Context* context = outdated_contexts_[i]; | |
1512 BackReference back_reference = back_reference_map_.Lookup(context); | |
1513 sink_->Put(kBackref + back_reference.space(), "BackRef"); | |
1514 PutBackReference(context, back_reference); | |
1515 } | |
1516 } | |
1517 } | |
1518 | |
1519 | |
1520 bool Serializer::ShouldBeSkipped(Object** current) { | 1485 bool Serializer::ShouldBeSkipped(Object** current) { |
1521 Object** roots = isolate()->heap()->roots_array_start(); | 1486 Object** roots = isolate()->heap()->roots_array_start(); |
1522 return current == &roots[Heap::kStoreBufferTopRootIndex] | 1487 return current == &roots[Heap::kStoreBufferTopRootIndex] |
1523 || current == &roots[Heap::kStackLimitRootIndex] | 1488 || current == &roots[Heap::kStackLimitRootIndex] |
1524 || current == &roots[Heap::kRealStackLimitRootIndex]; | 1489 || current == &roots[Heap::kRealStackLimitRootIndex]; |
1525 } | 1490 } |
1526 | 1491 |
1527 | 1492 |
1528 void Serializer::VisitPointers(Object** start, Object** end) { | 1493 void Serializer::VisitPointers(Object** start, Object** end) { |
1529 for (Object** current = start; current < end; current++) { | 1494 for (Object** current = start; current < end; current++) { |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 | 1810 |
1846 // Clear literal boilerplates. | 1811 // Clear literal boilerplates. |
1847 if (obj->IsJSFunction() && !JSFunction::cast(obj)->shared()->bound()) { | 1812 if (obj->IsJSFunction() && !JSFunction::cast(obj)->shared()->bound()) { |
1848 FixedArray* literals = JSFunction::cast(obj)->literals(); | 1813 FixedArray* literals = JSFunction::cast(obj)->literals(); |
1849 for (int i = 0; i < literals->length(); i++) literals->set_undefined(i); | 1814 for (int i = 0; i < literals->length(); i++) literals->set_undefined(i); |
1850 } | 1815 } |
1851 | 1816 |
1852 // Object has not yet been serialized. Serialize it here. | 1817 // Object has not yet been serialized. Serialize it here. |
1853 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); | 1818 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); |
1854 serializer.Serialize(); | 1819 serializer.Serialize(); |
1855 | |
1856 // TODO(yangguo): We probably only need ScriptContext here for post- | |
1857 // processing in Genesis::HookUpGlobalThisBinding. | |
1858 if (obj->IsContext() && | |
1859 Context::cast(obj)->global_object() == global_object_) { | |
1860 // Context refers to the current global object. This reference will | |
1861 // become outdated after deserialization. | |
1862 outdated_contexts_.Add(Context::cast(obj)); | |
1863 } | |
1864 } | 1820 } |
1865 | 1821 |
1866 | 1822 |
1867 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, | 1823 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
1868 int size, Map* map) { | 1824 int size, Map* map) { |
1869 if (serializer_->code_address_map_) { | 1825 if (serializer_->code_address_map_) { |
1870 const char* code_name = | 1826 const char* code_name = |
1871 serializer_->code_address_map_->Lookup(object_->address()); | 1827 serializer_->code_address_map_->Lookup(object_->address()); |
1872 LOG(serializer_->isolate_, | 1828 LOG(serializer_->isolate_, |
1873 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1829 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2858 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2814 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
2859 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2815 SanityCheckResult r = scd->SanityCheck(isolate, source); |
2860 if (r == CHECK_SUCCESS) return scd; | 2816 if (r == CHECK_SUCCESS) return scd; |
2861 cached_data->Reject(); | 2817 cached_data->Reject(); |
2862 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2818 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
2863 delete scd; | 2819 delete scd; |
2864 return NULL; | 2820 return NULL; |
2865 } | 2821 } |
2866 } // namespace internal | 2822 } // namespace internal |
2867 } // namespace v8 | 2823 } // namespace v8 |
OLD | NEW |