| Index: src/code-stubs-hydrogen.cc
 | 
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
 | 
| index f776abc043cb8d7e8f4c26f4ad4365819df2f5c8..95fa2a2e15df55c97f6292022240b97b5c8ac6ef 100644
 | 
| --- a/src/code-stubs-hydrogen.cc
 | 
| +++ b/src/code-stubs-hydrogen.cc
 | 
| @@ -100,21 +100,6 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
 | 
|                                          HValue* shared_info,
 | 
|                                          HValue* native_context);
 | 
|  
 | 
| -  // Tail calls handler found at array[map_index + 1].
 | 
| -  void TailCallHandler(HValue* receiver, HValue* name, HValue* array,
 | 
| -                       HValue* map_index, HValue* slot, HValue* vector);
 | 
| -
 | 
| -  // Tail calls handler_code.
 | 
| -  void TailCallHandler(HValue* receiver, HValue* name, HValue* slot,
 | 
| -                       HValue* vector, HValue* handler_code);
 | 
| -
 | 
| -  void TailCallMiss(HValue* receiver, HValue* name, HValue* slot,
 | 
| -                    HValue* vector, bool keyed_load);
 | 
| -
 | 
| -  // Handle MONOMORPHIC and POLYMORPHIC LoadIC and KeyedLoadIC cases.
 | 
| -  void HandleArrayCases(HValue* array, HValue* receiver, HValue* name,
 | 
| -                        HValue* slot, HValue* vector, bool keyed_load);
 | 
| -
 | 
|   private:
 | 
|    HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
 | 
|    HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
 | 
| @@ -2029,211 +2014,6 @@ Handle<Code> KeyedLoadGenericStub::GenerateCode() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
 | 
| -                                               HValue* array, HValue* map_index,
 | 
| -                                               HValue* slot, HValue* vector) {
 | 
| -  // The handler is at array[map_index + 1]. Compute this with a custom offset
 | 
| -  // to HLoadKeyed.
 | 
| -  int offset =
 | 
| -      GetDefaultHeaderSizeForElementsKind(FAST_ELEMENTS) + kPointerSize;
 | 
| -  HValue* handler_code = Add<HLoadKeyed>(
 | 
| -      array, map_index, nullptr, FAST_ELEMENTS, NEVER_RETURN_HOLE, offset);
 | 
| -  TailCallHandler(receiver, name, slot, vector, handler_code);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
 | 
| -                                               HValue* slot, HValue* vector,
 | 
| -                                               HValue* handler_code) {
 | 
| -  VectorLoadICDescriptor descriptor(isolate());
 | 
| -  HValue* op_vals[] = {context(), receiver, name, slot, vector};
 | 
| -  Add<HCallWithDescriptor>(handler_code, 0, descriptor,
 | 
| -                           Vector<HValue*>(op_vals, 5), TAIL_CALL);
 | 
| -  // We never return here, it is a tail call.
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void CodeStubGraphBuilderBase::TailCallMiss(HValue* receiver, HValue* name,
 | 
| -                                            HValue* slot, HValue* vector,
 | 
| -                                            bool keyed_load) {
 | 
| -  DCHECK(FLAG_vector_ics);
 | 
| -  Add<HTailCallThroughMegamorphicCache>(
 | 
| -      receiver, name, slot, vector,
 | 
| -      HTailCallThroughMegamorphicCache::ComputeFlags(keyed_load, true));
 | 
| -  // We never return here, it is a tail call.
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
 | 
| -                                                HValue* name, HValue* slot,
 | 
| -                                                HValue* vector,
 | 
| -                                                bool keyed_load) {
 | 
| -  HConstant* constant_two = Add<HConstant>(2);
 | 
| -  HConstant* constant_three = Add<HConstant>(3);
 | 
| -
 | 
| -  IfBuilder if_receiver_heap_object(this);
 | 
| -  if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver);
 | 
| -  if_receiver_heap_object.Then();
 | 
| -  Push(AddLoadMap(receiver, nullptr));
 | 
| -  if_receiver_heap_object.Else();
 | 
| -  HConstant* heap_number_map =
 | 
| -      Add<HConstant>(isolate()->factory()->heap_number_map());
 | 
| -  Push(heap_number_map);
 | 
| -  if_receiver_heap_object.End();
 | 
| -  HValue* receiver_map = Pop();
 | 
| -
 | 
| -  HValue* start =
 | 
| -      keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
 | 
| -  HValue* weak_cell =
 | 
| -      Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
 | 
| -  // Load the weak cell value. It may be Smi(0), or a map. Compare nonetheless
 | 
| -  // against the receiver_map.
 | 
| -  HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr,
 | 
| -                                           HObjectAccess::ForWeakCellValue());
 | 
| -
 | 
| -  IfBuilder if_correct_map(this);
 | 
| -  if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
 | 
| -  if_correct_map.Then();
 | 
| -  { TailCallHandler(receiver, name, array, start, slot, vector); }
 | 
| -  if_correct_map.Else();
 | 
| -  {
 | 
| -    // If our array has more elements, the ic is polymorphic. Look for the
 | 
| -    // receiver map in the rest of the array.
 | 
| -    HValue* length = AddLoadFixedArrayLength(array, nullptr);
 | 
| -    LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement,
 | 
| -                        constant_two);
 | 
| -    start = keyed_load ? constant_three : constant_two;
 | 
| -    HValue* key = builder.BeginBody(start, length, Token::LT);
 | 
| -    {
 | 
| -      HValue* weak_cell = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS,
 | 
| -                                          ALLOW_RETURN_HOLE);
 | 
| -      HValue* array_map = Add<HLoadNamedField>(
 | 
| -          weak_cell, nullptr, HObjectAccess::ForWeakCellValue());
 | 
| -      IfBuilder if_correct_poly_map(this);
 | 
| -      if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
 | 
| -                                                        array_map);
 | 
| -      if_correct_poly_map.Then();
 | 
| -      { TailCallHandler(receiver, name, array, key, slot, vector); }
 | 
| -    }
 | 
| -    builder.EndBody();
 | 
| -  }
 | 
| -  if_correct_map.End();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -template <>
 | 
| -HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
 | 
| -  HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
 | 
| -  HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
 | 
| -  HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
 | 
| -  HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
 | 
| -
 | 
| -  // If the feedback is an array, then the IC is in the monomorphic or
 | 
| -  // polymorphic state.
 | 
| -  HValue* feedback =
 | 
| -      Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
 | 
| -  IfBuilder array_checker(this);
 | 
| -  array_checker.If<HCompareMap>(feedback,
 | 
| -                                isolate()->factory()->fixed_array_map());
 | 
| -  array_checker.Then();
 | 
| -  { HandleArrayCases(feedback, receiver, name, slot, vector, false); }
 | 
| -  array_checker.Else();
 | 
| -  {
 | 
| -    // Is the IC megamorphic?
 | 
| -    IfBuilder mega_checker(this);
 | 
| -    HConstant* megamorphic_symbol =
 | 
| -        Add<HConstant>(isolate()->factory()->megamorphic_symbol());
 | 
| -    mega_checker.If<HCompareObjectEqAndBranch>(feedback, megamorphic_symbol);
 | 
| -    mega_checker.Then();
 | 
| -    {
 | 
| -      // Probe the stub cache.
 | 
| -      Add<HTailCallThroughMegamorphicCache>(
 | 
| -          receiver, name, slot, vector,
 | 
| -          HTailCallThroughMegamorphicCache::ComputeFlags(false, false));
 | 
| -    }
 | 
| -    mega_checker.End();
 | 
| -  }
 | 
| -  array_checker.End();
 | 
| -
 | 
| -  TailCallMiss(receiver, name, slot, vector, false);
 | 
| -  return graph()->GetConstant0();
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Handle<Code> VectorLoadStub::GenerateCode() { return DoGenerateCode(this); }
 | 
| -
 | 
| -
 | 
| -template <>
 | 
| -HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
 | 
| -  HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
 | 
| -  HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
 | 
| -  HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
 | 
| -  HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
 | 
| -  HConstant* zero = graph()->GetConstant0();
 | 
| -
 | 
| -  // If the feedback is an array, then the IC is in the monomorphic or
 | 
| -  // polymorphic state.
 | 
| -  HValue* feedback =
 | 
| -      Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
 | 
| -  IfBuilder array_checker(this);
 | 
| -  array_checker.If<HCompareMap>(feedback,
 | 
| -                                isolate()->factory()->fixed_array_map());
 | 
| -  array_checker.Then();
 | 
| -  {
 | 
| -    // If feedback[0] is 0, then the IC has element handlers and name should be
 | 
| -    // a smi. If feedback[0] is a string, verify that it matches name.
 | 
| -    HValue* recorded_name = Add<HLoadKeyed>(feedback, zero, nullptr,
 | 
| -                                            FAST_ELEMENTS, ALLOW_RETURN_HOLE);
 | 
| -
 | 
| -    IfBuilder recorded_name_is_zero(this);
 | 
| -    recorded_name_is_zero.If<HCompareObjectEqAndBranch>(recorded_name, zero);
 | 
| -    recorded_name_is_zero.Then();
 | 
| -    { Add<HCheckSmi>(name); }
 | 
| -    recorded_name_is_zero.Else();
 | 
| -    {
 | 
| -      IfBuilder strings_match(this);
 | 
| -      strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name);
 | 
| -      strings_match.Then();
 | 
| -      TailCallMiss(receiver, name, slot, vector, true);
 | 
| -      strings_match.End();
 | 
| -    }
 | 
| -    recorded_name_is_zero.End();
 | 
| -
 | 
| -    HandleArrayCases(feedback, receiver, name, slot, vector, true);
 | 
| -  }
 | 
| -  array_checker.Else();
 | 
| -  {
 | 
| -    // Check if the IC is in megamorphic state.
 | 
| -    IfBuilder megamorphic_checker(this);
 | 
| -    HConstant* megamorphic_symbol =
 | 
| -        Add<HConstant>(isolate()->factory()->megamorphic_symbol());
 | 
| -    megamorphic_checker.If<HCompareObjectEqAndBranch>(feedback,
 | 
| -                                                      megamorphic_symbol);
 | 
| -    megamorphic_checker.Then();
 | 
| -    {
 | 
| -      // Tail-call to the megamorphic KeyedLoadIC, treating it like a handler.
 | 
| -      Handle<Code> stub = KeyedLoadIC::ChooseMegamorphicStub(isolate());
 | 
| -      HValue* constant_stub = Add<HConstant>(stub);
 | 
| -      LoadDescriptor descriptor(isolate());
 | 
| -      HValue* op_vals[] = {context(), receiver, name};
 | 
| -      Add<HCallWithDescriptor>(constant_stub, 0, descriptor,
 | 
| -                               Vector<HValue*>(op_vals, 3), TAIL_CALL);
 | 
| -      // We never return here, it is a tail call.
 | 
| -    }
 | 
| -    megamorphic_checker.End();
 | 
| -  }
 | 
| -  array_checker.End();
 | 
| -
 | 
| -  TailCallMiss(receiver, name, slot, vector, true);
 | 
| -  return zero;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Handle<Code> VectorKeyedLoadStub::GenerateCode() {
 | 
| -  return DoGenerateCode(this);
 | 
| -}
 | 
| -
 | 
| -
 | 
|  Handle<Code> MegamorphicLoadStub::GenerateCode() {
 | 
|    return DoGenerateCode(this);
 | 
|  }
 | 
| 
 |