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