| Index: src/objects.cc | 
| diff --git a/src/objects.cc b/src/objects.cc | 
| index a72585d696948c827a1659fb0d0c201003b9ac11..f31671726184d19d7ada4d4bed865ed927572b6c 100644 | 
| --- a/src/objects.cc | 
| +++ b/src/objects.cc | 
| @@ -3624,6 +3624,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 
| } | 
|  | 
| set_map(new_map); | 
| +  map_of_this->NotifyObjectLayoutChange(); | 
|  | 
| set_properties(dictionary); | 
|  | 
| @@ -5292,6 +5293,7 @@ MaybeObject* Map::CopyDropDescriptors() { | 
| result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 
| result->set_is_shared(false); | 
| result->ClearCodeCache(GetHeap()); | 
| +  NotifyObjectLayoutChange(); | 
| return result; | 
| } | 
|  | 
| @@ -9501,14 +9503,27 @@ void Map::ZapPrototypeTransitions() { | 
| } | 
|  | 
|  | 
| +DependentCodes::GroupStartIndexes::GroupStartIndexes(DependentCodes* codes) { | 
| +  Recompute(codes); | 
| +} | 
| + | 
| + | 
| +void DependentCodes::GroupStartIndexes::Recompute(DependentCodes* codes) { | 
| +  start_indexes_[0] = 0; | 
| +  for (int g = 1; g <= kGroupCount; g++) { | 
| +    int count = codes->number_of_codes(static_cast<DependencyGroup>(g - 1)); | 
| +    start_indexes_[g] = start_indexes_[g - 1] + count; | 
| +  } | 
| +} | 
| + | 
| + | 
| Handle<DependentCodes> DependentCodes::Insert(Handle<DependentCodes> codes, | 
| DependencyGroup group, | 
| Handle<Code> value) { | 
| -  GroupStartIndexes starts; | 
| -  codes->ComputeGroupStartIndexes(starts); | 
| -  int start = starts[group]; | 
| -  int end = starts[group + 1]; | 
| -  int number_of_codes = starts[kGroupCount]; | 
| +  GroupStartIndexes starts(*codes); | 
| +  int start = starts.at(group); | 
| +  int end = starts.at(group + 1); | 
| +  int number_of_codes = starts.at(kGroupCount); | 
| if (start < end && codes->code_at(end - 1) == *value) { | 
| // Do not append the code if it is already in the array. | 
| // It is sufficient to just check only the last element because | 
| @@ -9522,10 +9537,10 @@ Handle<DependentCodes> DependentCodes::Insert(Handle<DependentCodes> codes, | 
| Handle<DependentCodes> new_codes = Handle<DependentCodes>::cast( | 
| factory->CopySizeFixedArray(codes, capacity)); | 
| // The number of codes can change after GC. | 
| -    codes->ComputeGroupStartIndexes(starts); | 
| -    start = starts[group]; | 
| -    end = starts[group + 1]; | 
| -    number_of_codes = starts[kGroupCount]; | 
| +    starts.Recompute(*codes); | 
| +    start = starts.at(group); | 
| +    end = starts.at(group + 1); | 
| +    number_of_codes = starts.at(kGroupCount); | 
| for (int i = 0; i < number_of_codes; i++) { | 
| codes->clear_code_at(i); | 
| } | 
| @@ -9546,9 +9561,8 @@ Handle<DependentCodes> DependentCodes::Insert(Handle<DependentCodes> codes, | 
|  | 
|  | 
| bool DependentCodes::Contains(DependencyGroup group, Code* code) { | 
| -  GroupStartIndexes starts; | 
| -  ComputeGroupStartIndexes(starts); | 
| -  int number_of_codes = starts[kGroupCount]; | 
| +  GroupStartIndexes starts(this); | 
| +  int number_of_codes = starts.at(kGroupCount); | 
| for (int i = 0; i < number_of_codes; i++) { | 
| if (code_at(i) == code) return true; | 
| } | 
| @@ -9556,6 +9570,35 @@ bool DependentCodes::Contains(DependencyGroup group, Code* code) { | 
| } | 
|  | 
|  | 
| +class DeoptimizeDependentCodeFilter : public OptimizedFunctionFilter { | 
| + public: | 
| +  virtual bool TakeFunction(JSFunction* function) { | 
| +    return function->code()->marked_for_deoptimization(); | 
| +  } | 
| +}; | 
| + | 
| + | 
| +void Map::DeoptimizeDependentCodes(DependentCodes::DependencyGroup group) { | 
| +  AssertNoAllocation no_allocation_scope; | 
| +  DependentCodes* codes = dependent_codes(); | 
| +  DependentCodes::GroupStartIndexes starts(codes); | 
| +  int start = starts.at(group); | 
| +  int end = starts.at(group + 1); | 
| +  int number_of_codes = starts.at(DependentCodes::kGroupCount); | 
| +  if (start == end) return; | 
| +  for (int i = start; i < end; i++) { | 
| +    Code* code = codes->code_at(i); | 
| +    code->set_marked_for_deoptimization(true); | 
| +  } | 
| +  for (int src = end, dst = start; src < number_of_codes; src++, dst++) { | 
| +    codes->set_code_at(dst, codes->code_at(src)); | 
| +  } | 
| +  codes->set_number_of_codes(group, 0); | 
| +  DeoptimizeDependentCodeFilter filter; | 
| +  Deoptimizer::DeoptimizeAllFunctionsWith(&filter); | 
| +} | 
| + | 
| + | 
| MaybeObject* JSReceiver::SetPrototype(Object* value, | 
| bool skip_hidden_prototypes) { | 
| #ifdef DEBUG | 
|  |