| 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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 int current_space = NEW_SPACE; | 493 int current_space = NEW_SPACE; |
| 494 for (auto& r : res) { | 494 for (auto& r : res) { |
| 495 reservations_[current_space].Add({r.chunk_size(), NULL, NULL}); | 495 reservations_[current_space].Add({r.chunk_size(), NULL, NULL}); |
| 496 if (r.is_last()) current_space++; | 496 if (r.is_last()) current_space++; |
| 497 } | 497 } |
| 498 DCHECK_EQ(kNumberOfSpaces, current_space); | 498 DCHECK_EQ(kNumberOfSpaces, current_space); |
| 499 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; | 499 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; |
| 500 } | 500 } |
| 501 | 501 |
| 502 | 502 |
| 503 void Deserializer::FlushICacheForNewIsolate() { |
| 504 DCHECK(!deserializing_user_code_); |
| 505 // The entire isolate is newly deserialized. Simply flush all code pages. |
| 506 PageIterator it(isolate_->heap()->code_space()); |
| 507 while (it.has_next()) { |
| 508 Page* p = it.next(); |
| 509 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); |
| 510 } |
| 511 } |
| 512 |
| 513 |
| 503 void Deserializer::FlushICacheForNewCodeObjects() { | 514 void Deserializer::FlushICacheForNewCodeObjects() { |
| 504 if (!deserializing_user_code_) { | 515 DCHECK(deserializing_user_code_); |
| 505 // The entire isolate is newly deserialized. Simply flush all code pages. | |
| 506 PageIterator it(isolate_->heap()->code_space()); | |
| 507 while (it.has_next()) { | |
| 508 Page* p = it.next(); | |
| 509 CpuFeatures::FlushICache(p->area_start(), | |
| 510 p->area_end() - p->area_start()); | |
| 511 } | |
| 512 } | |
| 513 for (Code* code : new_code_objects_) { | 516 for (Code* code : new_code_objects_) { |
| 514 CpuFeatures::FlushICache(code->instruction_start(), | 517 CpuFeatures::FlushICache(code->instruction_start(), |
| 515 code->instruction_size()); | 518 code->instruction_size()); |
| 516 } | 519 } |
| 517 } | 520 } |
| 518 | 521 |
| 519 | 522 |
| 520 bool Deserializer::ReserveSpace() { | 523 bool Deserializer::ReserveSpace() { |
| 521 #ifdef DEBUG | 524 #ifdef DEBUG |
| 522 for (int i = NEW_SPACE; i < kNumberOfSpaces; ++i) { | 525 for (int i = NEW_SPACE; i < kNumberOfSpaces; ++i) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 550 // No active handles. | 553 // No active handles. |
| 551 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); | 554 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); |
| 552 | 555 |
| 553 { | 556 { |
| 554 DisallowHeapAllocation no_gc; | 557 DisallowHeapAllocation no_gc; |
| 555 isolate_->heap()->IterateSmiRoots(this); | 558 isolate_->heap()->IterateSmiRoots(this); |
| 556 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 559 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
| 557 isolate_->heap()->RepairFreeListsAfterDeserialization(); | 560 isolate_->heap()->RepairFreeListsAfterDeserialization(); |
| 558 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); | 561 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); |
| 559 DeserializeDeferredObjects(); | 562 DeserializeDeferredObjects(); |
| 563 FlushICacheForNewIsolate(); |
| 560 } | 564 } |
| 561 | 565 |
| 562 isolate_->heap()->set_native_contexts_list( | 566 isolate_->heap()->set_native_contexts_list( |
| 563 isolate_->heap()->code_stub_context()); | 567 isolate_->heap()->code_stub_context()); |
| 564 | 568 |
| 565 // The allocation site list is build during root iteration, but if no sites | 569 // The allocation site list is build during root iteration, but if no sites |
| 566 // were encountered then it needs to be initialized to undefined. | 570 // were encountered then it needs to be initialized to undefined. |
| 567 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { | 571 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { |
| 568 isolate_->heap()->set_allocation_sites_list( | 572 isolate_->heap()->set_allocation_sites_list( |
| 569 isolate_->heap()->undefined_value()); | 573 isolate_->heap()->undefined_value()); |
| 570 } | 574 } |
| 571 | 575 |
| 572 // Update data pointers to the external strings containing natives sources. | 576 // Update data pointers to the external strings containing natives sources. |
| 573 Natives::UpdateSourceCache(isolate_->heap()); | 577 Natives::UpdateSourceCache(isolate_->heap()); |
| 574 ExtraNatives::UpdateSourceCache(isolate_->heap()); | 578 ExtraNatives::UpdateSourceCache(isolate_->heap()); |
| 575 CodeStubNatives::UpdateSourceCache(isolate_->heap()); | 579 CodeStubNatives::UpdateSourceCache(isolate_->heap()); |
| 576 | 580 |
| 577 FlushICacheForNewCodeObjects(); | |
| 578 | |
| 579 // Issue code events for newly deserialized code objects. | 581 // Issue code events for newly deserialized code objects. |
| 580 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 582 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
| 581 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 583 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
| 582 } | 584 } |
| 583 | 585 |
| 584 | 586 |
| 585 MaybeHandle<Object> Deserializer::DeserializePartial( | 587 MaybeHandle<Object> Deserializer::DeserializePartial( |
| 586 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, | 588 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, |
| 587 Handle<FixedArray>* outdated_contexts_out) { | 589 Handle<FixedArray>* outdated_contexts_out) { |
| 588 Initialize(isolate); | 590 Initialize(isolate); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 return Handle<SharedFunctionInfo>(); | 626 return Handle<SharedFunctionInfo>(); |
| 625 } else { | 627 } else { |
| 626 deserializing_user_code_ = true; | 628 deserializing_user_code_ = true; |
| 627 HandleScope scope(isolate); | 629 HandleScope scope(isolate); |
| 628 Handle<SharedFunctionInfo> result; | 630 Handle<SharedFunctionInfo> result; |
| 629 { | 631 { |
| 630 DisallowHeapAllocation no_gc; | 632 DisallowHeapAllocation no_gc; |
| 631 Object* root; | 633 Object* root; |
| 632 VisitPointer(&root); | 634 VisitPointer(&root); |
| 633 DeserializeDeferredObjects(); | 635 DeserializeDeferredObjects(); |
| 636 FlushICacheForNewCodeObjects(); |
| 634 result = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); | 637 result = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); |
| 635 } | 638 } |
| 636 CommitPostProcessedObjects(isolate); | 639 CommitPostProcessedObjects(isolate); |
| 637 return scope.CloseAndEscape(result); | 640 return scope.CloseAndEscape(result); |
| 638 } | 641 } |
| 639 } | 642 } |
| 640 | 643 |
| 641 | 644 |
| 642 Deserializer::~Deserializer() { | 645 Deserializer::~Deserializer() { |
| 643 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. | 646 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. |
| (...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2619 Deserializer deserializer(scd.get()); | 2622 Deserializer deserializer(scd.get()); |
| 2620 deserializer.SetAttachedObjects(attached_objects); | 2623 deserializer.SetAttachedObjects(attached_objects); |
| 2621 | 2624 |
| 2622 // Deserialize. | 2625 // Deserialize. |
| 2623 Handle<SharedFunctionInfo> result; | 2626 Handle<SharedFunctionInfo> result; |
| 2624 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { | 2627 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { |
| 2625 // Deserializing may fail if the reservations cannot be fulfilled. | 2628 // Deserializing may fail if the reservations cannot be fulfilled. |
| 2626 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); | 2629 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); |
| 2627 return MaybeHandle<SharedFunctionInfo>(); | 2630 return MaybeHandle<SharedFunctionInfo>(); |
| 2628 } | 2631 } |
| 2629 deserializer.FlushICacheForNewCodeObjects(); | |
| 2630 | 2632 |
| 2631 if (FLAG_profile_deserialization) { | 2633 if (FLAG_profile_deserialization) { |
| 2632 double ms = timer.Elapsed().InMillisecondsF(); | 2634 double ms = timer.Elapsed().InMillisecondsF(); |
| 2633 int length = cached_data->length(); | 2635 int length = cached_data->length(); |
| 2634 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); | 2636 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); |
| 2635 } | 2637 } |
| 2636 result->set_deserialized(true); | 2638 result->set_deserialized(true); |
| 2637 | 2639 |
| 2638 if (isolate->logger()->is_logging_code_events() || | 2640 if (isolate->logger()->is_logging_code_events() || |
| 2639 isolate->cpu_profiler()->is_profiling()) { | 2641 isolate->cpu_profiler()->is_profiling()) { |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2875 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2877 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
| 2876 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2878 SanityCheckResult r = scd->SanityCheck(isolate, source); |
| 2877 if (r == CHECK_SUCCESS) return scd; | 2879 if (r == CHECK_SUCCESS) return scd; |
| 2878 cached_data->Reject(); | 2880 cached_data->Reject(); |
| 2879 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2881 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
| 2880 delete scd; | 2882 delete scd; |
| 2881 return NULL; | 2883 return NULL; |
| 2882 } | 2884 } |
| 2883 } // namespace internal | 2885 } // namespace internal |
| 2884 } // namespace v8 | 2886 } // namespace v8 |
| OLD | NEW |