Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1543)

Unified Diff: src/snapshot/serialize.cc

Issue 1173013002: Deserializer: flush code objects in large object space. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/snapshot/serialize.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/snapshot/serialize.cc
diff --git a/src/snapshot/serialize.cc b/src/snapshot/serialize.cc
index ace8225b8246caf958f3bf335b2c33c423e19576..293834cee2bacf293b5df9bd296abd8911dc75ea 100644
--- a/src/snapshot/serialize.cc
+++ b/src/snapshot/serialize.cc
@@ -516,10 +516,18 @@ void Deserializer::DecodeReservation(
void Deserializer::FlushICacheForNewCodeObjects() {
- PageIterator it(isolate_->heap()->code_space());
- while (it.has_next()) {
- Page* p = it.next();
- CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start());
+ if (!deserializing_user_code_) {
+ // The entire isolate is newly deserialized. Simply flush all code pages.
+ PageIterator it(isolate_->heap()->code_space());
+ while (it.has_next()) {
+ Page* p = it.next();
+ CpuFeatures::FlushICache(p->area_start(),
+ p->area_end() - p->area_start());
+ }
+ }
+ for (Code* code : new_code_objects_) {
+ CpuFeatures::FlushICache(code->instruction_start(),
+ code->instruction_size());
}
}
@@ -612,9 +620,9 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
VisitPointer(&outdated_contexts);
DeserializeDeferredObjects();
- // There's no code deserialized here. If this assert fires
- // then that's changed and logging should be added to notify
- // the profiler et al of the new code.
+ // There's no code deserialized here. If this assert fires then that's
+ // changed and logging should be added to notify the profiler et al of the
+ // new code, which also has to be flushed from instruction cache.
CHECK_EQ(start_address, code_space->top());
CHECK(outdated_contexts->IsFixedArray());
*outdated_contexts_out =
@@ -667,9 +675,8 @@ void Deserializer::DeserializeDeferredObjects() {
Object** end = reinterpret_cast<Object**>(obj_address + size);
bool filled = ReadData(start, end, space, obj_address);
CHECK(filled);
- if (object->IsAllocationSite()) {
- RelinkAllocationSite(AllocationSite::cast(object));
- }
+ DCHECK(CanBeDeferred(object));
+ PostProcessNewObject(object, space);
}
}
@@ -705,43 +712,52 @@ class StringTableInsertionKey : public HashTableKey {
};
-HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj) {
- DCHECK(deserializing_user_code());
- if (obj->IsString()) {
- String* string = String::cast(obj);
- // Uninitialize hash field as the hash seed may have changed.
- string->set_hash_field(String::kEmptyHashField);
- if (string->IsInternalizedString()) {
- DisallowHeapAllocation no_gc;
- HandleScope scope(isolate_);
- StringTableInsertionKey key(string);
- String* canonical = *StringTable::LookupKey(isolate_, &key);
- string->SetForwardedInternalizedString(canonical);
- return canonical;
+HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
+ if (deserializing_user_code()) {
+ if (obj->IsString()) {
+ String* string = String::cast(obj);
+ // Uninitialize hash field as the hash seed may have changed.
+ string->set_hash_field(String::kEmptyHashField);
+ if (string->IsInternalizedString()) {
+ // Canonicalize the internalized string. If it already exists in the
+ // string table, set it to forward to the existing one.
+ DisallowHeapAllocation no_gc;
+ HandleScope scope(isolate_);
+ StringTableInsertionKey key(string);
+ String* canonical = *StringTable::LookupKey(isolate_, &key);
+ string->SetForwardedInternalizedString(canonical);
+ return canonical;
+ }
+ } else if (obj->IsScript()) {
+ // Assign a new script id to avoid collision.
+ Script::cast(obj)->set_id(isolate_->heap()->NextScriptId());
+ } else {
+ DCHECK(CanBeDeferred(obj));
}
- } else if (obj->IsScript()) {
- Script::cast(obj)->set_id(isolate_->heap()->NextScriptId());
- } else {
- DCHECK(CanBeDeferred(obj));
}
- return obj;
-}
-
-
-void Deserializer::RelinkAllocationSite(AllocationSite* obj) {
- DCHECK(obj->IsAllocationSite());
- // Allocation sites are present in the snapshot, and must be linked into
- // a list at deserialization time.
- AllocationSite* site = AllocationSite::cast(obj);
- // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
- // as a (weak) root. If this root is relocated correctly,
- // RelinkAllocationSite() isn't necessary.
- if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) {
- site->set_weak_next(isolate_->heap()->undefined_value());
- } else {
- site->set_weak_next(isolate_->heap()->allocation_sites_list());
+ if (obj->IsAllocationSite()) {
+ DCHECK(obj->IsAllocationSite());
+ // Allocation sites are present in the snapshot, and must be linked into
+ // a list at deserialization time.
+ AllocationSite* site = AllocationSite::cast(obj);
+ // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
+ // as a (weak) root. If this root is relocated correctly, this becomes
+ // unnecessary.
+ if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) {
+ site->set_weak_next(isolate_->heap()->undefined_value());
+ } else {
+ site->set_weak_next(isolate_->heap()->allocation_sites_list());
+ }
+ isolate_->heap()->set_allocation_sites_list(site);
+ } else if (obj->IsCode()) {
+ // We flush all code pages after deserializing the startup snapshot. In that
+ // case, we only need to remember code objects in the large object space.
+ // When deserializing user code, remember each individual code object.
+ if (deserializing_user_code() || space == LO_SPACE) {
+ new_code_objects_.Add(Code::cast(obj));
+ }
}
- isolate_->heap()->set_allocation_sites_list(site);
+ return obj;
}
@@ -803,11 +819,7 @@ void Deserializer::ReadObject(int space_number, Object** write_back) {
if (ReadData(current, limit, space_number, address)) {
// Only post process if object content has not been deferred.
- if (obj->IsAllocationSite()) {
- RelinkAllocationSite(AllocationSite::cast(obj));
- }
-
- if (deserializing_user_code()) obj = PostProcessNewObject(obj);
+ obj = PostProcessNewObject(obj, space_number);
}
Object* write_back_obj = obj;
« no previous file with comments | « src/snapshot/serialize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698