| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 8802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8813 return TryInline(expr->target(), expr->arguments()->length(), | 8813 return TryInline(expr->target(), expr->arguments()->length(), |
| 8814 implicit_return_value, expr->id(), expr->ReturnId(), | 8814 implicit_return_value, expr->id(), expr->ReturnId(), |
| 8815 CONSTRUCT_CALL_RETURN, TailCallMode::kDisallow); | 8815 CONSTRUCT_CALL_RETURN, TailCallMode::kDisallow); |
| 8816 } | 8816 } |
| 8817 | 8817 |
| 8818 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter, | 8818 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter, |
| 8819 Handle<Map> receiver_map, | 8819 Handle<Map> receiver_map, |
| 8820 BailoutId ast_id, | 8820 BailoutId ast_id, |
| 8821 BailoutId return_id) { | 8821 BailoutId return_id) { |
| 8822 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; | 8822 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; |
| 8823 if (getter->IsJSFunction()) { | 8823 return getter->IsJSFunction() && |
| 8824 Handle<JSFunction> getter_function = Handle<JSFunction>::cast(getter); | 8824 TryInline(Handle<JSFunction>::cast(getter), 0, NULL, ast_id, return_id, |
| 8825 return TryInlineBuiltinGetterCall(getter_function, receiver_map, ast_id) || | 8825 GETTER_CALL_RETURN, TailCallMode::kDisallow); |
| 8826 TryInline(getter_function, 0, NULL, ast_id, return_id, | |
| 8827 GETTER_CALL_RETURN, TailCallMode::kDisallow); | |
| 8828 } | |
| 8829 return false; | |
| 8830 } | 8826 } |
| 8831 | 8827 |
| 8832 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter, | 8828 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter, |
| 8833 Handle<Map> receiver_map, | 8829 Handle<Map> receiver_map, |
| 8834 BailoutId id, | 8830 BailoutId id, |
| 8835 BailoutId assignment_id, | 8831 BailoutId assignment_id, |
| 8836 HValue* implicit_return_value) { | 8832 HValue* implicit_return_value) { |
| 8837 if (TryInlineApiSetter(setter, receiver_map, id)) return true; | 8833 if (TryInlineApiSetter(setter, receiver_map, id)) return true; |
| 8838 return setter->IsJSFunction() && | 8834 return setter->IsJSFunction() && |
| 8839 TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value, | 8835 TryInline(Handle<JSFunction>::cast(setter), 1, implicit_return_value, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8911 bool HOptimizedGraphBuilder::CanInlineArrayResizeOperation( | 8907 bool HOptimizedGraphBuilder::CanInlineArrayResizeOperation( |
| 8912 Handle<Map> receiver_map) { | 8908 Handle<Map> receiver_map) { |
| 8913 return !receiver_map.is_null() && receiver_map->prototype()->IsJSObject() && | 8909 return !receiver_map.is_null() && receiver_map->prototype()->IsJSObject() && |
| 8914 receiver_map->instance_type() == JS_ARRAY_TYPE && | 8910 receiver_map->instance_type() == JS_ARRAY_TYPE && |
| 8915 IsFastElementsKind(receiver_map->elements_kind()) && | 8911 IsFastElementsKind(receiver_map->elements_kind()) && |
| 8916 !receiver_map->is_dictionary_map() && receiver_map->is_extensible() && | 8912 !receiver_map->is_dictionary_map() && receiver_map->is_extensible() && |
| 8917 (!receiver_map->is_prototype_map() || receiver_map->is_stable()) && | 8913 (!receiver_map->is_prototype_map() || receiver_map->is_stable()) && |
| 8918 !IsReadOnlyLengthDescriptor(receiver_map); | 8914 !IsReadOnlyLengthDescriptor(receiver_map); |
| 8919 } | 8915 } |
| 8920 | 8916 |
| 8921 bool HOptimizedGraphBuilder::TryInlineBuiltinGetterCall( | |
| 8922 Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id) { | |
| 8923 if (!function->shared()->HasBuiltinFunctionId()) return false; | |
| 8924 BuiltinFunctionId id = function->shared()->builtin_function_id(); | |
| 8925 | |
| 8926 // Try to inline getter calls like DataView.prototype.byteLength/byteOffset | |
| 8927 // as operations in the calling function. | |
| 8928 switch (id) { | |
| 8929 case kDataViewBuffer: { | |
| 8930 if (!receiver_map->IsJSDataViewMap()) return false; | |
| 8931 HObjectAccess access = HObjectAccess::ForMapAndOffset( | |
| 8932 receiver_map, JSDataView::kBufferOffset); | |
| 8933 HValue* object = Pop(); // receiver | |
| 8934 HInstruction* result = New<HLoadNamedField>(object, object, access); | |
| 8935 ast_context()->ReturnInstruction(result, ast_id); | |
| 8936 return true; | |
| 8937 } | |
| 8938 case kDataViewByteLength: | |
| 8939 case kDataViewByteOffset: { | |
| 8940 if (!receiver_map->IsJSDataViewMap()) return false; | |
| 8941 int offset = (id == kDataViewByteLength) ? JSDataView::kByteLengthOffset | |
| 8942 : JSDataView::kByteOffsetOffset; | |
| 8943 HObjectAccess access = | |
| 8944 HObjectAccess::ForMapAndOffset(receiver_map, offset); | |
| 8945 HValue* object = Pop(); // receiver | |
| 8946 HValue* checked_object = Add<HCheckArrayBufferNotNeutered>(object); | |
| 8947 HInstruction* result = | |
| 8948 New<HLoadNamedField>(object, checked_object, access); | |
| 8949 ast_context()->ReturnInstruction(result, ast_id); | |
| 8950 return true; | |
| 8951 } | |
| 8952 case kTypedArrayByteLength: | |
| 8953 case kTypedArrayByteOffset: | |
| 8954 case kTypedArrayLength: { | |
| 8955 if (!receiver_map->IsJSTypedArrayMap()) return false; | |
| 8956 int offset = (id == kTypedArrayLength) | |
| 8957 ? JSTypedArray::kLengthOffset | |
| 8958 : (id == kTypedArrayByteLength) | |
| 8959 ? JSTypedArray::kByteLengthOffset | |
| 8960 : JSTypedArray::kByteOffsetOffset; | |
| 8961 HObjectAccess access = | |
| 8962 HObjectAccess::ForMapAndOffset(receiver_map, offset); | |
| 8963 HValue* object = Pop(); // receiver | |
| 8964 HValue* checked_object = Add<HCheckArrayBufferNotNeutered>(object); | |
| 8965 HInstruction* result = | |
| 8966 New<HLoadNamedField>(object, checked_object, access); | |
| 8967 ast_context()->ReturnInstruction(result, ast_id); | |
| 8968 return true; | |
| 8969 } | |
| 8970 default: | |
| 8971 return false; | |
| 8972 } | |
| 8973 } | |
| 8974 | 8917 |
| 8975 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( | 8918 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
| 8976 Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id, | 8919 Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map, |
| 8977 int args_count_no_receiver) { | 8920 int args_count_no_receiver) { |
| 8978 if (!function->shared()->HasBuiltinFunctionId()) return false; | 8921 if (!function->shared()->HasBuiltinFunctionId()) return false; |
| 8979 BuiltinFunctionId id = function->shared()->builtin_function_id(); | 8922 BuiltinFunctionId id = function->shared()->builtin_function_id(); |
| 8980 int argument_count = args_count_no_receiver + 1; // Plus receiver. | 8923 int argument_count = args_count_no_receiver + 1; // Plus receiver. |
| 8981 | 8924 |
| 8982 if (receiver_map.is_null()) { | 8925 if (receiver_map.is_null()) { |
| 8983 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); | 8926 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); |
| 8984 if (receiver->IsConstant() && | 8927 if (receiver->IsConstant() && |
| 8985 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { | 8928 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { |
| 8986 receiver_map = | 8929 receiver_map = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9011 } | 8954 } |
| 9012 case kStringCharCodeAt: | 8955 case kStringCharCodeAt: |
| 9013 case kStringCharAt: | 8956 case kStringCharAt: |
| 9014 if (argument_count == 2) { | 8957 if (argument_count == 2) { |
| 9015 HValue* index = Pop(); | 8958 HValue* index = Pop(); |
| 9016 HValue* string = Pop(); | 8959 HValue* string = Pop(); |
| 9017 Drop(1); // Function. | 8960 Drop(1); // Function. |
| 9018 HInstruction* char_code = | 8961 HInstruction* char_code = |
| 9019 BuildStringCharCodeAt(string, index); | 8962 BuildStringCharCodeAt(string, index); |
| 9020 if (id == kStringCharCodeAt) { | 8963 if (id == kStringCharCodeAt) { |
| 9021 ast_context()->ReturnInstruction(char_code, ast_id); | 8964 ast_context()->ReturnInstruction(char_code, expr->id()); |
| 9022 return true; | 8965 return true; |
| 9023 } | 8966 } |
| 9024 AddInstruction(char_code); | 8967 AddInstruction(char_code); |
| 9025 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); | 8968 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); |
| 9026 ast_context()->ReturnInstruction(result, ast_id); | 8969 ast_context()->ReturnInstruction(result, expr->id()); |
| 9027 return true; | 8970 return true; |
| 9028 } | 8971 } |
| 9029 break; | 8972 break; |
| 9030 case kStringFromCharCode: | 8973 case kStringFromCharCode: |
| 9031 if (argument_count == 2) { | 8974 if (argument_count == 2) { |
| 9032 HValue* argument = Pop(); | 8975 HValue* argument = Pop(); |
| 9033 Drop(2); // Receiver and function. | 8976 Drop(2); // Receiver and function. |
| 9034 argument = AddUncasted<HForceRepresentation>( | 8977 argument = AddUncasted<HForceRepresentation>( |
| 9035 argument, Representation::Integer32()); | 8978 argument, Representation::Integer32()); |
| 9036 argument->SetFlag(HValue::kTruncatingToInt32); | 8979 argument->SetFlag(HValue::kTruncatingToInt32); |
| 9037 HInstruction* result = NewUncasted<HStringCharFromCode>(argument); | 8980 HInstruction* result = NewUncasted<HStringCharFromCode>(argument); |
| 9038 ast_context()->ReturnInstruction(result, ast_id); | 8981 ast_context()->ReturnInstruction(result, expr->id()); |
| 9039 return true; | 8982 return true; |
| 9040 } | 8983 } |
| 9041 break; | 8984 break; |
| 9042 case kMathExp: | 8985 case kMathExp: |
| 9043 if (!FLAG_fast_math) break; | 8986 if (!FLAG_fast_math) break; |
| 9044 // Fall through if FLAG_fast_math. | 8987 // Fall through if FLAG_fast_math. |
| 9045 case kMathRound: | 8988 case kMathRound: |
| 9046 case kMathFround: | 8989 case kMathFround: |
| 9047 case kMathFloor: | 8990 case kMathFloor: |
| 9048 case kMathAbs: | 8991 case kMathAbs: |
| 9049 case kMathSqrt: | 8992 case kMathSqrt: |
| 9050 case kMathLog: | 8993 case kMathLog: |
| 9051 case kMathClz32: | 8994 case kMathClz32: |
| 9052 if (argument_count == 2) { | 8995 if (argument_count == 2) { |
| 9053 HValue* argument = Pop(); | 8996 HValue* argument = Pop(); |
| 9054 Drop(2); // Receiver and function. | 8997 Drop(2); // Receiver and function. |
| 9055 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); | 8998 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); |
| 9056 ast_context()->ReturnInstruction(op, ast_id); | 8999 ast_context()->ReturnInstruction(op, expr->id()); |
| 9057 return true; | 9000 return true; |
| 9058 } | 9001 } |
| 9059 break; | 9002 break; |
| 9060 case kMathPow: | 9003 case kMathPow: |
| 9061 if (argument_count == 3) { | 9004 if (argument_count == 3) { |
| 9062 HValue* right = Pop(); | 9005 HValue* right = Pop(); |
| 9063 HValue* left = Pop(); | 9006 HValue* left = Pop(); |
| 9064 Drop(2); // Receiver and function. | 9007 Drop(2); // Receiver and function. |
| 9065 HInstruction* result = NULL; | 9008 HInstruction* result = NULL; |
| 9066 // Use sqrt() if exponent is 0.5 or -0.5. | 9009 // Use sqrt() if exponent is 0.5 or -0.5. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9077 DCHECK(!sqrt->HasObservableSideEffects()); | 9020 DCHECK(!sqrt->HasObservableSideEffects()); |
| 9078 result = NewUncasted<HDiv>(one, sqrt); | 9021 result = NewUncasted<HDiv>(one, sqrt); |
| 9079 } else if (exponent == 2.0) { | 9022 } else if (exponent == 2.0) { |
| 9080 result = NewUncasted<HMul>(left, left); | 9023 result = NewUncasted<HMul>(left, left); |
| 9081 } | 9024 } |
| 9082 } | 9025 } |
| 9083 | 9026 |
| 9084 if (result == NULL) { | 9027 if (result == NULL) { |
| 9085 result = NewUncasted<HPower>(left, right); | 9028 result = NewUncasted<HPower>(left, right); |
| 9086 } | 9029 } |
| 9087 ast_context()->ReturnInstruction(result, ast_id); | 9030 ast_context()->ReturnInstruction(result, expr->id()); |
| 9088 return true; | 9031 return true; |
| 9089 } | 9032 } |
| 9090 break; | 9033 break; |
| 9091 case kMathMax: | 9034 case kMathMax: |
| 9092 case kMathMin: | 9035 case kMathMin: |
| 9093 if (argument_count == 3) { | 9036 if (argument_count == 3) { |
| 9094 HValue* right = Pop(); | 9037 HValue* right = Pop(); |
| 9095 HValue* left = Pop(); | 9038 HValue* left = Pop(); |
| 9096 Drop(2); // Receiver and function. | 9039 Drop(2); // Receiver and function. |
| 9097 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin | 9040 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin |
| 9098 : HMathMinMax::kMathMax; | 9041 : HMathMinMax::kMathMax; |
| 9099 HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); | 9042 HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); |
| 9100 ast_context()->ReturnInstruction(result, ast_id); | 9043 ast_context()->ReturnInstruction(result, expr->id()); |
| 9101 return true; | 9044 return true; |
| 9102 } | 9045 } |
| 9103 break; | 9046 break; |
| 9104 case kMathImul: | 9047 case kMathImul: |
| 9105 if (argument_count == 3) { | 9048 if (argument_count == 3) { |
| 9106 HValue* right = Pop(); | 9049 HValue* right = Pop(); |
| 9107 HValue* left = Pop(); | 9050 HValue* left = Pop(); |
| 9108 Drop(2); // Receiver and function. | 9051 Drop(2); // Receiver and function. |
| 9109 HInstruction* result = | 9052 HInstruction* result = |
| 9110 HMul::NewImul(isolate(), zone(), context(), left, right); | 9053 HMul::NewImul(isolate(), zone(), context(), left, right); |
| 9111 ast_context()->ReturnInstruction(result, ast_id); | 9054 ast_context()->ReturnInstruction(result, expr->id()); |
| 9112 return true; | 9055 return true; |
| 9113 } | 9056 } |
| 9114 break; | 9057 break; |
| 9115 case kArrayPop: { | 9058 case kArrayPop: { |
| 9116 if (!CanInlineArrayResizeOperation(receiver_map)) return false; | 9059 if (!CanInlineArrayResizeOperation(receiver_map)) return false; |
| 9117 ElementsKind elements_kind = receiver_map->elements_kind(); | 9060 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 9118 | 9061 |
| 9119 Drop(args_count_no_receiver); | 9062 Drop(args_count_no_receiver); |
| 9120 HValue* result; | 9063 HValue* result; |
| 9121 HValue* reduced_length; | 9064 HValue* reduced_length; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9157 elements_kind, STORE); | 9100 elements_kind, STORE); |
| 9158 Add<HStoreNamedField>( | 9101 Add<HStoreNamedField>( |
| 9159 checked_object, HObjectAccess::ForArrayLength(elements_kind), | 9102 checked_object, HObjectAccess::ForArrayLength(elements_kind), |
| 9160 reduced_length, STORE_TO_INITIALIZED_ENTRY); | 9103 reduced_length, STORE_TO_INITIALIZED_ENTRY); |
| 9161 | 9104 |
| 9162 if (!ast_context()->IsEffect()) Push(result); | 9105 if (!ast_context()->IsEffect()) Push(result); |
| 9163 | 9106 |
| 9164 length_checker.End(); | 9107 length_checker.End(); |
| 9165 } | 9108 } |
| 9166 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); | 9109 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); |
| 9167 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 9110 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 9168 if (!ast_context()->IsEffect()) Drop(1); | 9111 if (!ast_context()->IsEffect()) Drop(1); |
| 9169 | 9112 |
| 9170 ast_context()->ReturnValue(result); | 9113 ast_context()->ReturnValue(result); |
| 9171 return true; | 9114 return true; |
| 9172 } | 9115 } |
| 9173 case kArrayPush: { | 9116 case kArrayPush: { |
| 9174 if (!CanInlineArrayResizeOperation(receiver_map)) return false; | 9117 if (!CanInlineArrayResizeOperation(receiver_map)) return false; |
| 9175 ElementsKind elements_kind = receiver_map->elements_kind(); | 9118 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 9176 | 9119 |
| 9177 // If there may be elements accessors in the prototype chain, the fast | 9120 // If there may be elements accessors in the prototype chain, the fast |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9210 | 9153 |
| 9211 new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); | 9154 new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); |
| 9212 | 9155 |
| 9213 bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 9156 bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 9214 HValue* checked_array = Add<HCheckMaps>(array, receiver_map); | 9157 HValue* checked_array = Add<HCheckMaps>(array, receiver_map); |
| 9215 BuildUncheckedMonomorphicElementAccess( | 9158 BuildUncheckedMonomorphicElementAccess( |
| 9216 checked_array, length, value_to_push, is_array, elements_kind, | 9159 checked_array, length, value_to_push, is_array, elements_kind, |
| 9217 STORE, NEVER_RETURN_HOLE, STORE_AND_GROW_NO_TRANSITION); | 9160 STORE, NEVER_RETURN_HOLE, STORE_AND_GROW_NO_TRANSITION); |
| 9218 | 9161 |
| 9219 if (!ast_context()->IsEffect()) Push(new_size); | 9162 if (!ast_context()->IsEffect()) Push(new_size); |
| 9220 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 9163 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 9221 if (!ast_context()->IsEffect()) Drop(1); | 9164 if (!ast_context()->IsEffect()) Drop(1); |
| 9222 } | 9165 } |
| 9223 | 9166 |
| 9224 ast_context()->ReturnValue(new_size); | 9167 ast_context()->ReturnValue(new_size); |
| 9225 return true; | 9168 return true; |
| 9226 } | 9169 } |
| 9227 case kArrayShift: { | 9170 case kArrayShift: { |
| 9228 if (!CanInlineArrayResizeOperation(receiver_map)) return false; | 9171 if (!CanInlineArrayResizeOperation(receiver_map)) return false; |
| 9229 ElementsKind kind = receiver_map->elements_kind(); | 9172 ElementsKind kind = receiver_map->elements_kind(); |
| 9230 | 9173 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9324 Add<HPushArguments>(receiver); | 9267 Add<HPushArguments>(receiver); |
| 9325 result = AddInstruction(NewCallConstantFunction( | 9268 result = AddInstruction(NewCallConstantFunction( |
| 9326 function, 1, TailCallMode::kDisallow, TailCallMode::kDisallow)); | 9269 function, 1, TailCallMode::kDisallow, TailCallMode::kDisallow)); |
| 9327 if (!ast_context()->IsEffect()) Push(result); | 9270 if (!ast_context()->IsEffect()) Push(result); |
| 9328 } | 9271 } |
| 9329 if_inline.End(); | 9272 if_inline.End(); |
| 9330 } | 9273 } |
| 9331 if_lengthiszero.End(); | 9274 if_lengthiszero.End(); |
| 9332 } | 9275 } |
| 9333 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); | 9276 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); |
| 9334 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 9277 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 9335 if (!ast_context()->IsEffect()) Drop(1); | 9278 if (!ast_context()->IsEffect()) Drop(1); |
| 9336 ast_context()->ReturnValue(result); | 9279 ast_context()->ReturnValue(result); |
| 9337 return true; | 9280 return true; |
| 9338 } | 9281 } |
| 9339 case kArrayIndexOf: | 9282 case kArrayIndexOf: |
| 9340 case kArrayLastIndexOf: { | 9283 case kArrayLastIndexOf: { |
| 9341 if (receiver_map.is_null()) return false; | 9284 if (receiver_map.is_null()) return false; |
| 9342 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | 9285 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; |
| 9343 if (!receiver_map->prototype()->IsJSObject()) return false; | 9286 if (!receiver_map->prototype()->IsJSObject()) return false; |
| 9344 ElementsKind kind = receiver_map->elements_kind(); | 9287 ElementsKind kind = receiver_map->elements_kind(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 9361 | 9304 |
| 9362 HValue* search_element = Pop(); | 9305 HValue* search_element = Pop(); |
| 9363 HValue* receiver = Pop(); | 9306 HValue* receiver = Pop(); |
| 9364 Drop(1); // Drop function. | 9307 Drop(1); // Drop function. |
| 9365 | 9308 |
| 9366 ArrayIndexOfMode mode = (id == kArrayIndexOf) | 9309 ArrayIndexOfMode mode = (id == kArrayIndexOf) |
| 9367 ? kFirstIndexOf : kLastIndexOf; | 9310 ? kFirstIndexOf : kLastIndexOf; |
| 9368 HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode); | 9311 HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode); |
| 9369 | 9312 |
| 9370 if (!ast_context()->IsEffect()) Push(index); | 9313 if (!ast_context()->IsEffect()) Push(index); |
| 9371 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 9314 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 9372 if (!ast_context()->IsEffect()) Drop(1); | 9315 if (!ast_context()->IsEffect()) Drop(1); |
| 9373 ast_context()->ReturnValue(index); | 9316 ast_context()->ReturnValue(index); |
| 9374 return true; | 9317 return true; |
| 9375 } | 9318 } |
| 9376 default: | 9319 default: |
| 9377 // Not yet supported for inlining. | 9320 // Not yet supported for inlining. |
| 9378 break; | 9321 break; |
| 9379 } | 9322 } |
| 9380 return false; | 9323 return false; |
| 9381 } | 9324 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9558 | 9501 |
| 9559 | 9502 |
| 9560 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function, | 9503 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function, |
| 9561 int arguments_count) { | 9504 int arguments_count) { |
| 9562 Handle<JSFunction> known_function; | 9505 Handle<JSFunction> known_function; |
| 9563 int args_count_no_receiver = arguments_count - 1; | 9506 int args_count_no_receiver = arguments_count - 1; |
| 9564 if (function->IsConstant() && | 9507 if (function->IsConstant() && |
| 9565 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 9508 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 9566 known_function = | 9509 known_function = |
| 9567 Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate())); | 9510 Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate())); |
| 9568 if (TryInlineBuiltinMethodCall(known_function, Handle<Map>(), expr->id(), | 9511 if (TryInlineBuiltinMethodCall(expr, known_function, Handle<Map>(), |
| 9569 args_count_no_receiver)) { | 9512 args_count_no_receiver)) { |
| 9570 if (FLAG_trace_inlining) { | 9513 if (FLAG_trace_inlining) { |
| 9571 PrintF("Inlining builtin "); | 9514 PrintF("Inlining builtin "); |
| 9572 known_function->ShortPrint(); | 9515 known_function->ShortPrint(); |
| 9573 PrintF("\n"); | 9516 PrintF("\n"); |
| 9574 } | 9517 } |
| 9575 return; | 9518 return; |
| 9576 } | 9519 } |
| 9577 | 9520 |
| 9578 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { | 9521 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9959 Push(receiver); | 9902 Push(receiver); |
| 9960 | 9903 |
| 9961 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 9904 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 9962 HConstant::cast(function)->handle(isolate())); | 9905 HConstant::cast(function)->handle(isolate())); |
| 9963 expr->set_target(known_function); | 9906 expr->set_target(known_function); |
| 9964 | 9907 |
| 9965 if (TryIndirectCall(expr)) return; | 9908 if (TryIndirectCall(expr)) return; |
| 9966 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9909 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 9967 | 9910 |
| 9968 Handle<Map> map = maps->length() == 1 ? maps->first() : Handle<Map>(); | 9911 Handle<Map> map = maps->length() == 1 ? maps->first() : Handle<Map>(); |
| 9969 if (TryInlineBuiltinMethodCall(known_function, map, expr->id(), | 9912 if (TryInlineBuiltinMethodCall(expr, known_function, map, |
| 9970 expr->arguments()->length())) { | 9913 expr->arguments()->length())) { |
| 9971 if (FLAG_trace_inlining) { | 9914 if (FLAG_trace_inlining) { |
| 9972 PrintF("Inlining builtin "); | 9915 PrintF("Inlining builtin "); |
| 9973 known_function->ShortPrint(); | 9916 known_function->ShortPrint(); |
| 9974 PrintF("\n"); | 9917 PrintF("\n"); |
| 9975 } | 9918 } |
| 9976 return; | 9919 return; |
| 9977 } | 9920 } |
| 9978 if (TryInlineApiMethodCall(expr, receiver, maps)) return; | 9921 if (TryInlineApiMethodCall(expr, receiver, maps)) return; |
| 9979 | 9922 |
| (...skipping 3721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13701 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13644 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13702 } | 13645 } |
| 13703 | 13646 |
| 13704 #ifdef DEBUG | 13647 #ifdef DEBUG |
| 13705 graph_->Verify(false); // No full verify. | 13648 graph_->Verify(false); // No full verify. |
| 13706 #endif | 13649 #endif |
| 13707 } | 13650 } |
| 13708 | 13651 |
| 13709 } // namespace internal | 13652 } // namespace internal |
| 13710 } // namespace v8 | 13653 } // namespace v8 |
| OLD | NEW |