| 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 |