| Index: src/objects.cc
 | 
| diff --git a/src/objects.cc b/src/objects.cc
 | 
| index 6512c607799dd34fd71e69aa8e656681ff3f5e42..bdd0818fceafcceedc155b88b92ad2f8e8c6aa7e 100644
 | 
| --- a/src/objects.cc
 | 
| +++ b/src/objects.cc
 | 
| @@ -11091,6 +11091,24 @@ void Map::ZapPrototypeTransitions() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void Map::AddDependentCompilationInfo(DependentCode::DependencyGroup group,
 | 
| +                                      CompilationInfo* info) {
 | 
| +  Handle<DependentCode> dep(dependent_code());
 | 
| +  Handle<DependentCode> codes =
 | 
| +      DependentCode::Insert(dep, group, info->object_wrapper());
 | 
| +  if (*codes != dependent_code()) set_dependent_code(*codes);
 | 
| +  info->dependent_maps(group)->Add(Handle<Map>(this), info->zone());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Map::AddDependentCode(DependentCode::DependencyGroup group,
 | 
| +                           Handle<Code> code) {
 | 
| +  Handle<DependentCode> codes = DependentCode::Insert(
 | 
| +      Handle<DependentCode>(dependent_code()), group, code);
 | 
| +  if (*codes != dependent_code()) set_dependent_code(*codes);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) {
 | 
|    Recompute(entries);
 | 
|  }
 | 
| @@ -11107,13 +11125,13 @@ void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) {
 | 
|  
 | 
|  Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
 | 
|                                              DependencyGroup group,
 | 
| -                                            Handle<Code> value) {
 | 
| +                                            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 (start < end && entries->code_at(end - 1) == *value) {
 | 
| -    // Do not append the code if it is already in the array.
 | 
| +  if (start < end && entries->object_at(end - 1) == *object) {
 | 
| +    // Do not append the compilation info if it is already in the array.
 | 
|      // It is sufficient to just check only the last element because
 | 
|      // we process embedded maps of an optimized code in one batch.
 | 
|      return entries;
 | 
| @@ -11130,7 +11148,7 @@ Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
 | 
|      end = starts.at(group + 1);
 | 
|      number_of_entries = starts.number_of_entries();
 | 
|      for (int i = 0; i < number_of_entries; i++) {
 | 
| -      entries->clear_code_at(i);
 | 
| +      entries->clear_at(i);
 | 
|      }
 | 
|      // If the old fixed array was empty, we need to reset counters of the
 | 
|      // new array.
 | 
| @@ -11142,17 +11160,79 @@ Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
 | 
|      entries = new_entries;
 | 
|    }
 | 
|    entries->ExtendGroup(group);
 | 
| -  entries->set_code_at(end, *value);
 | 
| +  entries->set_object_at(end, *object);
 | 
|    entries->set_number_of_entries(group, end + 1 - start);
 | 
|    return entries;
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void DependentCode::UpdateToFinishedCode(DependencyGroup group,
 | 
| +                                         CompilationInfo* info,
 | 
| +                                         Code* code) {
 | 
| +  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);
 | 
| +      break;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +#ifdef DEBUG
 | 
| +  for (int i = start; i < end; i++) {
 | 
| +    ASSERT(is_code_at(i) || compilation_info_at(i) != info);
 | 
| +  }
 | 
| +#endif
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group,
 | 
| +                                          CompilationInfo* 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) {
 | 
| +      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;
 | 
| +    ASSERT(last_of_group >= gap);
 | 
| +    if (last_of_group == gap) continue;
 | 
| +    copy(last_of_group, gap);
 | 
| +    gap = last_of_group;
 | 
| +  }
 | 
| +  ASSERT(gap == starts.number_of_entries() - 1);
 | 
| +  clear_at(gap);  // Clear last gap.
 | 
| +  set_number_of_entries(group, end - start - 1);
 | 
| +
 | 
| +#ifdef DEBUG
 | 
| +  for (int i = start; i < end - 1; i++) {
 | 
| +    ASSERT(is_code_at(i) || compilation_info_at(i) != info);
 | 
| +  }
 | 
| +#endif
 | 
| +}
 | 
| +
 | 
| +
 | 
|  bool DependentCode::Contains(DependencyGroup group, Code* code) {
 | 
|    GroupStartIndexes starts(this);
 | 
| -  int number_of_entries = starts.at(kGroupCount);
 | 
| +  int number_of_entries = starts.number_of_entries();
 | 
|    for (int i = 0; i < number_of_entries; i++) {
 | 
| -    if (code_at(i) == code) return true;
 | 
| +    if (object_at(i) == code) return true;
 | 
|    }
 | 
|    return false;
 | 
|  }
 | 
| @@ -11173,20 +11253,25 @@ void DependentCode::DeoptimizeDependentCodeGroup(
 | 
|    DependentCode::GroupStartIndexes starts(this);
 | 
|    int start = starts.at(group);
 | 
|    int end = starts.at(group + 1);
 | 
| -  int number_of_entries = starts.at(DependentCode::kGroupCount);
 | 
| +  int code_entries = starts.number_of_entries();
 | 
|    if (start == end) return;
 | 
|    for (int i = start; i < end; i++) {
 | 
| -    Code* code = code_at(i);
 | 
| -    code->set_marked_for_deoptimization(true);
 | 
| +    if (is_code_at(i)) {
 | 
| +      Code* code = code_at(i);
 | 
| +      code->set_marked_for_deoptimization(true);
 | 
| +    } else {
 | 
| +      CompilationInfo* info = compilation_info_at(i);
 | 
| +      info->AbortDueToDependentMap();
 | 
| +    }
 | 
|    }
 | 
|    // Compact the array by moving all subsequent groups to fill in the new holes.
 | 
| -  for (int src = end, dst = start; src < number_of_entries; src++, dst++) {
 | 
| -    set_code_at(dst, code_at(src));
 | 
| +  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 = number_of_entries - removed; i < number_of_entries; i++) {
 | 
| -    clear_code_at(i);
 | 
| +  for (int i = code_entries - removed; i < code_entries; i++) {
 | 
| +    clear_at(i);
 | 
|    }
 | 
|    set_number_of_entries(group, 0);
 | 
|    DeoptimizeDependentCodeFilter filter;
 | 
| 
 |