| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 4ca3fead1782def067a3f38d354dc2791547ebff..4988d4e34e26e4c2c05e22c5520c6818be90b88e 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -13643,20 +13643,6 @@ void Map::AddDependentCode(Handle<Map> map,
|
| }
|
|
|
|
|
| -DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) {
|
| - Recompute(entries);
|
| -}
|
| -
|
| -
|
| -void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) {
|
| - start_indexes_[0] = 0;
|
| - for (int g = 1; g <= kGroupCount; g++) {
|
| - int count = entries->number_of_entries(static_cast<DependencyGroup>(g - 1));
|
| - start_indexes_[g] = start_indexes_[g - 1] + count;
|
| - }
|
| -}
|
| -
|
| -
|
| Handle<DependentCode> DependentCode::InsertCompilationDependencies(
|
| Handle<DependentCode> entries, DependencyGroup group,
|
| Handle<Foreign> info) {
|
| @@ -13674,44 +13660,54 @@ Handle<DependentCode> DependentCode::InsertWeakCode(
|
| Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
|
| DependencyGroup group,
|
| Handle<Object> object) {
|
| - GroupStartIndexes starts(*entries);
|
| - int start = starts.at(group);
|
| - int end = starts.at(group + 1);
|
| - int number_of_entries = starts.number_of_entries();
|
| + if (entries->length() == 0 || entries->group() > group) {
|
| + // There is no such group.
|
| + return DependentCode::New(group, object, entries);
|
| + }
|
| + if (entries->group() < group) {
|
| + // The group comes later in the list.
|
| + Handle<DependentCode> old_next(entries->next_link());
|
| + Handle<DependentCode> new_next = Insert(old_next, group, object);
|
| + if (!old_next.is_identical_to(new_next)) {
|
| + entries->set_next_link(*new_next);
|
| + }
|
| + return entries;
|
| + }
|
| + DCHECK_EQ(group, entries->group());
|
| + int count = entries->count();
|
| // Check for existing entry to avoid duplicates.
|
| - for (int i = start; i < end; i++) {
|
| + for (int i = 0; i < count; i++) {
|
| if (entries->object_at(i) == *object) return entries;
|
| }
|
| - if (entries->length() < kCodesStartIndex + number_of_entries + 1) {
|
| + if (entries->length() < kCodesStartIndex + count + 1) {
|
| 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);
|
| + // Count could have changed, reload it.
|
| + count = entries->count();
|
| }
|
| -
|
| - entries->ExtendGroup(group);
|
| - entries->set_object_at(end, *object);
|
| - entries->set_number_of_entries(group, end + 1 - start);
|
| + entries->set_object_at(count, *object);
|
| + entries->set_count(count + 1);
|
| return entries;
|
| }
|
|
|
|
|
| +Handle<DependentCode> DependentCode::New(DependencyGroup group,
|
| + Handle<Object> object,
|
| + Handle<DependentCode> next) {
|
| + Isolate* isolate = next->GetIsolate();
|
| + Handle<DependentCode> result = Handle<DependentCode>::cast(
|
| + isolate->factory()->NewFixedArray(kCodesStartIndex + 1, TENURED));
|
| + result->set_next_link(*next);
|
| + result->set_flags(GroupField::encode(group) | CountField::encode(1));
|
| + result->set_object_at(0, *object);
|
| + return result;
|
| +}
|
| +
|
| +
|
| Handle<DependentCode> DependentCode::EnsureSpace(
|
| Handle<DependentCode> entries) {
|
| - Isolate* isolate = entries->GetIsolate();
|
| - if (entries->length() == 0) {
|
| - entries = Handle<DependentCode>::cast(
|
| - isolate->factory()->NewFixedArray(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());
|
| + Isolate* isolate = entries->GetIsolate();
|
| + int capacity = kCodesStartIndex + DependentCode::Grow(entries->count());
|
| int grow_by = capacity - entries->length();
|
| return Handle<DependentCode>::cast(
|
| isolate->factory()->CopyFixedArrayAndGrow(entries, grow_by, TENURED));
|
| @@ -13719,46 +13715,47 @@ Handle<DependentCode> DependentCode::EnsureSpace(
|
|
|
|
|
| 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++;
|
| + int old_count = count();
|
| + int new_count = 0;
|
| + for (int i = 0; i < old_count; i++) {
|
| + Object* obj = object_at(i);
|
| + if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) {
|
| + if (i != new_count) {
|
| + copy(i, new_count);
|
| }
|
| + new_count++;
|
| }
|
| - if (count != end - start) {
|
| - set_number_of_entries(static_cast<DependencyGroup>(g), count);
|
| - }
|
| - n += count;
|
| }
|
| - return n < starts.number_of_entries();
|
| + set_count(new_count);
|
| + for (int i = new_count; i < old_count; i++) {
|
| + clear_at(i);
|
| + }
|
| + return new_count < old_count;
|
| }
|
|
|
|
|
| void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info,
|
| WeakCell* code_cell) {
|
| + if (this->length() == 0 || this->group() > group) {
|
| + // There is no such group.
|
| + return;
|
| + }
|
| + if (this->group() < group) {
|
| + // The group comes later in the list.
|
| + next_link()->UpdateToFinishedCode(group, info, code_cell);
|
| + return;
|
| + }
|
| + DCHECK_EQ(group, this->group());
|
| DisallowHeapAllocation no_gc;
|
| - GroupStartIndexes starts(this);
|
| - int start = starts.at(group);
|
| - int end = starts.at(group + 1);
|
| - for (int i = start; i < end; i++) {
|
| + int count = this->count();
|
| + for (int i = 0; i < count; i++) {
|
| if (object_at(i) == info) {
|
| set_object_at(i, code_cell);
|
| break;
|
| }
|
| }
|
| -
|
| #ifdef DEBUG
|
| - for (int i = start; i < end; i++) {
|
| + for (int i = 0; i < count; i++) {
|
| DCHECK(object_at(i) != info);
|
| }
|
| #endif
|
| @@ -13767,34 +13764,36 @@ void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info,
|
|
|
| void DependentCode::RemoveCompilationDependencies(
|
| DependentCode::DependencyGroup group, Foreign* info) {
|
| + if (this->length() == 0 || this->group() > group) {
|
| + // There is no such group.
|
| + return;
|
| + }
|
| + if (this->group() < group) {
|
| + // The group comes later in the list.
|
| + next_link()->RemoveCompilationDependencies(group, info);
|
| + return;
|
| + }
|
| + DCHECK_EQ(group, this->group());
|
| DisallowHeapAllocation no_allocation;
|
| - GroupStartIndexes starts(this);
|
| - int start = starts.at(group);
|
| - int end = starts.at(group + 1);
|
| + int old_count = count();
|
| // Find compilation info wrapper.
|
| int info_pos = -1;
|
| - for (int i = start; i < end; i++) {
|
| + for (int i = 0; i < old_count; i++) {
|
| if (object_at(i) == info) {
|
| info_pos = i;
|
| break;
|
| }
|
| }
|
| if (info_pos == -1) return; // Not found.
|
| - int gap = info_pos;
|
| - // Use the last of each group to fill the gap in the previous group.
|
| - for (int i = group; i < kGroupCount; i++) {
|
| - int last_of_group = starts.at(i + 1) - 1;
|
| - DCHECK(last_of_group >= gap);
|
| - if (last_of_group == gap) continue;
|
| - copy(last_of_group, gap);
|
| - gap = last_of_group;
|
| - }
|
| - DCHECK(gap == starts.number_of_entries() - 1);
|
| - clear_at(gap); // Clear last gap.
|
| - set_number_of_entries(group, end - start - 1);
|
| + // Use the last code to fill the gap.
|
| + if (info_pos < old_count - 1) {
|
| + copy(old_count - 1, info_pos);
|
| + }
|
| + clear_at(old_count - 1);
|
| + set_count(old_count - 1);
|
|
|
| #ifdef DEBUG
|
| - for (int i = start; i < end - 1; i++) {
|
| + for (int i = 0; i < old_count - 1; i++) {
|
| DCHECK(object_at(i) != info);
|
| }
|
| #endif
|
| @@ -13802,30 +13801,55 @@ void DependentCode::RemoveCompilationDependencies(
|
|
|
|
|
| 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 (this->length() == 0 || this->group() > group) {
|
| + // There is no such group.
|
| + return false;
|
| + }
|
| + if (this->group() < group) {
|
| + // The group comes later in the list.
|
| + return next_link()->Contains(group, code_cell);
|
| + }
|
| + DCHECK_EQ(group, this->group());
|
| + int count = this->count();
|
| + for (int i = 0; i < count; i++) {
|
| if (object_at(i) == code_cell) return true;
|
| }
|
| return false;
|
| }
|
|
|
|
|
| +bool DependentCode::IsEmpty(DependencyGroup group) {
|
| + if (this->length() == 0 || this->group() > group) {
|
| + // There is no such group.
|
| + return true;
|
| + }
|
| + if (this->group() < group) {
|
| + // The group comes later in the list.
|
| + return next_link()->IsEmpty(group);
|
| + }
|
| + DCHECK_EQ(group, this->group());
|
| + return count() == 0;
|
| +}
|
| +
|
| +
|
| bool DependentCode::MarkCodeForDeoptimization(
|
| Isolate* isolate,
|
| DependentCode::DependencyGroup group) {
|
| + if (this->length() == 0 || this->group() > group) {
|
| + // There is no such group.
|
| + return false;
|
| + }
|
| + if (this->group() < group) {
|
| + // The group comes later in the list.
|
| + return next_link()->MarkCodeForDeoptimization(isolate, group);
|
| + }
|
| + DCHECK_EQ(group, this->group());
|
| DisallowHeapAllocation no_allocation_scope;
|
| - DependentCode::GroupStartIndexes starts(this);
|
| - int start = starts.at(group);
|
| - int end = starts.at(group + 1);
|
| - int code_entries = starts.number_of_entries();
|
| - if (start == end) return false;
|
| -
|
| // 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++) {
|
| + int count = this->count();
|
| + for (int i = 0; i < count; i++) {
|
| Object* obj = object_at(i);
|
| if (obj->IsWeakCell()) {
|
| WeakCell* cell = WeakCell::cast(obj);
|
| @@ -13846,16 +13870,10 @@ bool DependentCode::MarkCodeForDeoptimization(
|
| info->Abort();
|
| }
|
| }
|
| - // Compact the array by moving all subsequent groups to fill in the new holes.
|
| - for (int src = end, dst = start; src < code_entries; src++, dst++) {
|
| - copy(src, dst);
|
| - }
|
| - // Now the holes are at the end of the array, zap them for heap-verifier.
|
| - int removed = end - start;
|
| - for (int i = code_entries - removed; i < code_entries; i++) {
|
| + for (int i = 0; i < count; i++) {
|
| clear_at(i);
|
| }
|
| - set_number_of_entries(group, 0);
|
| + set_count(0);
|
| return marked;
|
| }
|
|
|
|
|