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); |
} |