Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 9443d20b33356b173a12266024df7f61b308e10f..44057dbd9f51de787e62c18fe9bf196a36260a77 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -11884,9 +11884,9 @@ void Map::ZapPrototypeTransitions() { |
void Map::AddDependentCompilationInfo(Handle<Map> map, |
DependentCode::DependencyGroup group, |
CompilationInfo* info) { |
- Handle<DependentCode> codes = |
- DependentCode::Insert(handle(map->dependent_code(), info->isolate()), |
- group, info->object_wrapper()); |
+ Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
+ handle(map->dependent_code(), info->isolate()), group, |
+ info->object_wrapper()); |
if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
info->dependencies(group)->Add(map, info->zone()); |
} |
@@ -11896,8 +11896,9 @@ void Map::AddDependentCompilationInfo(Handle<Map> map, |
void Map::AddDependentCode(Handle<Map> map, |
DependentCode::DependencyGroup group, |
Handle<Code> code) { |
- Handle<DependentCode> codes = DependentCode::Insert( |
- Handle<DependentCode>(map->dependent_code()), group, code); |
+ Handle<WeakCell> cell = Code::WeakCellFor(code); |
+ Handle<DependentCode> codes = DependentCode::InsertWeakCode( |
+ Handle<DependentCode>(map->dependent_code()), group, cell); |
if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
} |
@@ -11929,6 +11930,20 @@ DependentCode* DependentCode::ForObject(Handle<HeapObject> object, |
} |
+Handle<DependentCode> DependentCode::InsertCompilationInfo( |
+ Handle<DependentCode> entries, DependencyGroup group, |
+ Handle<Foreign> info) { |
+ return Insert(entries, group, info); |
+} |
+ |
+ |
+Handle<DependentCode> DependentCode::InsertWeakCode( |
+ Handle<DependentCode> entries, DependencyGroup group, |
+ Handle<WeakCell> code_cell) { |
+ return Insert(entries, group, code_cell); |
+} |
+ |
+ |
Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
DependencyGroup group, |
Handle<Object> object) { |
@@ -11941,27 +11956,13 @@ Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
if (entries->object_at(i) == *object) return entries; |
} |
if (entries->length() < kCodesStartIndex + number_of_entries + 1) { |
- int capacity = kCodesStartIndex + number_of_entries + 1; |
- if (capacity > 5) capacity = capacity * 5 / 4; |
- Handle<DependentCode> new_entries = Handle<DependentCode>::cast( |
- FixedArray::CopySize(entries, capacity, TENURED)); |
- // The number of codes can change after GC. |
+ entries = EnsureSpace(entries); |
+ // The number of codes can change after Compact and GC. |
starts.Recompute(*entries); |
start = starts.at(group); |
end = starts.at(group + 1); |
- number_of_entries = starts.number_of_entries(); |
- for (int i = 0; i < number_of_entries; i++) { |
- entries->clear_at(i); |
- } |
- // If the old fixed array was empty, we need to reset counters of the |
- // new array. |
- if (number_of_entries == 0) { |
- for (int g = 0; g < kGroupCount; g++) { |
- new_entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0); |
- } |
- } |
- entries = new_entries; |
} |
+ |
entries->ExtendGroup(group); |
entries->set_object_at(end, *object); |
entries->set_number_of_entries(group, end + 1 - start); |
@@ -11969,42 +11970,82 @@ Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
} |
-void DependentCode::UpdateToFinishedCode(DependencyGroup group, |
- CompilationInfo* info, |
- Code* code) { |
+Handle<DependentCode> DependentCode::EnsureSpace( |
+ Handle<DependentCode> entries) { |
+ if (entries->length() == 0) { |
+ entries = Handle<DependentCode>::cast( |
+ FixedArray::CopySize(entries, kCodesStartIndex + 1, TENURED)); |
+ for (int g = 0; g < kGroupCount; g++) { |
+ entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0); |
+ } |
+ return entries; |
+ } |
+ if (entries->Compact()) return entries; |
+ GroupStartIndexes starts(*entries); |
+ int capacity = |
+ kCodesStartIndex + DependentCode::Grow(starts.number_of_entries()); |
+ return Handle<DependentCode>::cast( |
+ FixedArray::CopySize(entries, capacity, TENURED)); |
+} |
+ |
+ |
+bool DependentCode::Compact() { |
+ GroupStartIndexes starts(this); |
+ int n = 0; |
+ for (int g = 0; g < kGroupCount; g++) { |
+ int start = starts.at(g); |
+ int end = starts.at(g + 1); |
+ int count = 0; |
+ DCHECK(start >= n); |
+ for (int i = start; i < end; i++) { |
+ Object* obj = object_at(i); |
+ if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) { |
+ if (i != n + count) { |
+ copy(i, n + count); |
+ } |
+ count++; |
+ } |
+ } |
+ if (count != end - start) { |
+ set_number_of_entries(static_cast<DependencyGroup>(g), count); |
+ } |
+ n += count; |
+ } |
+ return n < starts.number_of_entries(); |
+} |
+ |
+ |
+void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info, |
+ WeakCell* code_cell) { |
DisallowHeapAllocation no_gc; |
- AllowDeferredHandleDereference get_object_wrapper; |
- Foreign* info_wrapper = *info->object_wrapper(); |
GroupStartIndexes starts(this); |
int start = starts.at(group); |
int end = starts.at(group + 1); |
for (int i = start; i < end; i++) { |
- if (object_at(i) == info_wrapper) { |
- set_object_at(i, code); |
+ if (object_at(i) == info) { |
+ set_object_at(i, code_cell); |
break; |
} |
} |
#ifdef DEBUG |
for (int i = start; i < end; i++) { |
- DCHECK(is_code_at(i) || compilation_info_at(i) != info); |
+ DCHECK(object_at(i) != info); |
} |
#endif |
} |
void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, |
- CompilationInfo* info) { |
+ Foreign* info) { |
DisallowHeapAllocation no_allocation; |
- AllowDeferredHandleDereference get_object_wrapper; |
- Foreign* info_wrapper = *info->object_wrapper(); |
GroupStartIndexes starts(this); |
int start = starts.at(group); |
int end = starts.at(group + 1); |
// Find compilation info wrapper. |
int info_pos = -1; |
for (int i = start; i < end; i++) { |
- if (object_at(i) == info_wrapper) { |
+ if (object_at(i) == info) { |
info_pos = i; |
break; |
} |
@@ -12025,18 +12066,18 @@ void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, |
#ifdef DEBUG |
for (int i = start; i < end - 1; i++) { |
- DCHECK(is_code_at(i) || compilation_info_at(i) != info); |
+ DCHECK(object_at(i) != info); |
} |
#endif |
} |
-bool DependentCode::Contains(DependencyGroup group, Code* code) { |
+bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) { |
GroupStartIndexes starts(this); |
int start = starts.at(group); |
int end = starts.at(group + 1); |
for (int i = start; i < end; i++) { |
- if (object_at(i) == code) return true; |
+ if (object_at(i) == code_cell) return true; |
} |
return false; |
} |
@@ -12054,15 +12095,24 @@ bool DependentCode::MarkCodeForDeoptimization( |
// Mark all the code that needs to be deoptimized. |
bool marked = false; |
+ bool invalidate_embedded_objects = group == kWeakCodeGroup; |
for (int i = start; i < end; i++) { |
- if (is_code_at(i)) { |
- Code* code = code_at(i); |
+ Object* obj = object_at(i); |
+ if (obj->IsWeakCell()) { |
+ WeakCell* cell = WeakCell::cast(obj); |
+ if (cell->cleared()) continue; |
+ Code* code = Code::cast(cell->value()); |
if (!code->marked_for_deoptimization()) { |
SetMarkedForDeoptimization(code, group); |
+ if (invalidate_embedded_objects) { |
+ code->InvalidateEmbeddedObjects(); |
+ } |
marked = true; |
} |
} else { |
- CompilationInfo* info = compilation_info_at(i); |
+ DCHECK(obj->IsForeign()); |
+ CompilationInfo* info = reinterpret_cast<CompilationInfo*>( |
+ Foreign::cast(obj)->foreign_address()); |
info->AbortDueToDependencyChange(); |
} |
} |
@@ -12086,7 +12136,6 @@ void DependentCode::DeoptimizeDependentCodeGroup( |
DCHECK(AllowCodeDependencyChange::IsAllowed()); |
DisallowHeapAllocation no_allocation_scope; |
bool marked = MarkCodeForDeoptimization(isolate, group); |
- |
if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); |
} |
@@ -13167,7 +13216,7 @@ void AllocationSite::AddDependentCompilationInfo( |
CompilationInfo* info) { |
Handle<DependentCode> dep(site->dependent_code()); |
Handle<DependentCode> codes = |
- DependentCode::Insert(dep, group, info->object_wrapper()); |
+ DependentCode::InsertCompilationInfo(dep, group, info->object_wrapper()); |
if (*codes != site->dependent_code()) site->set_dependent_code(*codes); |
info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); |
} |
@@ -15980,7 +16029,7 @@ void ObjectHashTable::RemoveEntry(int entry) { |
} |
-Object* WeakHashTable::Lookup(Handle<Object> key) { |
+Object* WeakHashTable::Lookup(Handle<HeapObject> key) { |
DisallowHeapAllocation no_gc; |
DCHECK(IsKey(*key)); |
int entry = FindEntry(key); |
@@ -15990,36 +16039,31 @@ Object* WeakHashTable::Lookup(Handle<Object> key) { |
Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, |
- Handle<Object> key, |
- Handle<Object> value) { |
+ Handle<HeapObject> key, |
+ Handle<HeapObject> value) { |
DCHECK(table->IsKey(*key)); |
int entry = table->FindEntry(key); |
// Key is already in table, just overwrite value. |
if (entry != kNotFound) { |
- // TODO(ulan): Skipping write barrier is a temporary solution to avoid |
- // memory leaks. Remove this once we have special visitor for weak fixed |
- // arrays. |
- table->set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER); |
+ table->set(EntryToValueIndex(entry), *value); |
return table; |
} |
+ Handle<WeakCell> key_cell = key->GetIsolate()->factory()->NewWeakCell(key); |
+ |
// Check whether the hash table should be extended. |
table = EnsureCapacity(table, 1, key, TENURED); |
- table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key, value); |
+ table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value); |
return table; |
} |
-void WeakHashTable::AddEntry(int entry, |
- Handle<Object> key, |
- Handle<Object> value) { |
+void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell, |
+ Handle<HeapObject> value) { |
DisallowHeapAllocation no_allocation; |
- // TODO(ulan): Skipping write barrier is a temporary solution to avoid |
- // memory leaks. Remove this once we have special visitor for weak fixed |
- // arrays. |
- set(EntryToIndex(entry), *key, SKIP_WRITE_BARRIER); |
- set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER); |
+ set(EntryToIndex(entry), *key_cell); |
+ set(EntryToValueIndex(entry), *value); |
ElementAdded(); |
} |
@@ -16962,10 +17006,9 @@ Handle<Object> PropertyCell::SetValueInferType(Handle<PropertyCell> cell, |
// static |
void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, |
CompilationInfo* info) { |
- Handle<DependentCode> codes = |
- DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
- DependentCode::kPropertyCellChangedGroup, |
- info->object_wrapper()); |
+ Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
+ handle(cell->dependent_code(), info->isolate()), |
+ DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
cell, info->zone()); |