Chromium Code Reviews| 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 8066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8077 if (TryInlineApiSetter(setter, receiver_map, id)) return true; | 8077 if (TryInlineApiSetter(setter, receiver_map, id)) return true; |
| 8078 return TryInline(setter, | 8078 return TryInline(setter, |
| 8079 1, | 8079 1, |
| 8080 implicit_return_value, | 8080 implicit_return_value, |
| 8081 id, assignment_id, | 8081 id, assignment_id, |
| 8082 SETTER_CALL_RETURN, | 8082 SETTER_CALL_RETURN, |
| 8083 source_position()); | 8083 source_position()); |
| 8084 } | 8084 } |
| 8085 | 8085 |
| 8086 | 8086 |
| 8087 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, | 8087 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function, |
| 8088 Call* expr, | 8088 Call* expr, |
| 8089 int arguments_count) { | 8089 int arguments_count) { |
| 8090 return TryInline(function, | 8090 return TryInline(function, |
| 8091 arguments_count, | 8091 arguments_count, |
| 8092 NULL, | 8092 NULL, |
| 8093 expr->id(), | 8093 expr->id(), |
| 8094 expr->ReturnId(), | 8094 expr->ReturnId(), |
| 8095 NORMAL_RETURN, | 8095 NORMAL_RETURN, |
| 8096 ScriptPositionToSourcePosition(expr->position())); | 8096 ScriptPositionToSourcePosition(expr->position())); |
| 8097 } | 8097 } |
| 8098 | 8098 |
| 8099 | 8099 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8131 break; | 8131 break; |
| 8132 default: | 8132 default: |
| 8133 // Not supported for inlining yet. | 8133 // Not supported for inlining yet. |
| 8134 break; | 8134 break; |
| 8135 } | 8135 } |
| 8136 return false; | 8136 return false; |
| 8137 } | 8137 } |
| 8138 | 8138 |
| 8139 | 8139 |
| 8140 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( | 8140 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
| 8141 Call* expr, | 8141 Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map, |
| 8142 HValue* receiver, | 8142 int args_count_no_receiver) { |
| 8143 Handle<Map> receiver_map) { | 8143 if (!function->shared()->HasBuiltinFunctionId()) return false; |
| 8144 BuiltinFunctionId id = function->shared()->builtin_function_id(); | |
| 8145 int argument_count = args_count_no_receiver + 1; // Plus receiver. | |
| 8146 | |
| 8147 if (receiver_map.is_null()) { | |
| 8148 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); | |
| 8149 if (receiver->IsConstant() && | |
| 8150 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { | |
| 8151 receiver_map = | |
| 8152 handle(Handle<HeapObject>::cast( | |
| 8153 HConstant::cast(receiver)->handle(isolate()))->map()); | |
|
Toon Verwaest
2015/04/24 18:51:07
This caused a major issue since no map-check is ad
| |
| 8154 } | |
| 8155 } | |
| 8144 // Try to inline calls like Math.* as operations in the calling function. | 8156 // Try to inline calls like Math.* as operations in the calling function. |
| 8145 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | |
| 8146 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | |
| 8147 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | |
| 8148 switch (id) { | 8157 switch (id) { |
| 8149 case kStringCharCodeAt: | 8158 case kStringCharCodeAt: |
| 8150 case kStringCharAt: | 8159 case kStringCharAt: |
| 8151 if (argument_count == 2) { | 8160 if (argument_count == 2) { |
| 8152 HValue* index = Pop(); | 8161 HValue* index = Pop(); |
| 8153 HValue* string = Pop(); | 8162 HValue* string = Pop(); |
| 8154 Drop(1); // Function. | 8163 Drop(1); // Function. |
| 8155 HInstruction* char_code = | 8164 HInstruction* char_code = |
| 8156 BuildStringCharCodeAt(string, index); | 8165 BuildStringCharCodeAt(string, index); |
| 8157 if (id == kStringCharCodeAt) { | 8166 if (id == kStringCharCodeAt) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8246 } | 8255 } |
| 8247 break; | 8256 break; |
| 8248 case kArrayPop: { | 8257 case kArrayPop: { |
| 8249 if (receiver_map.is_null()) return false; | 8258 if (receiver_map.is_null()) return false; |
| 8250 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | 8259 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; |
| 8251 ElementsKind elements_kind = receiver_map->elements_kind(); | 8260 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 8252 if (!IsFastElementsKind(elements_kind)) return false; | 8261 if (!IsFastElementsKind(elements_kind)) return false; |
| 8253 if (receiver_map->is_observed()) return false; | 8262 if (receiver_map->is_observed()) return false; |
| 8254 if (!receiver_map->is_extensible()) return false; | 8263 if (!receiver_map->is_extensible()) return false; |
| 8255 | 8264 |
| 8256 Drop(expr->arguments()->length()); | 8265 Drop(args_count_no_receiver); |
| 8257 HValue* result; | 8266 HValue* result; |
| 8258 HValue* reduced_length; | 8267 HValue* reduced_length; |
| 8259 HValue* receiver = Pop(); | 8268 HValue* receiver = Pop(); |
| 8260 | 8269 |
| 8261 HValue* checked_object = AddCheckMap(receiver, receiver_map); | 8270 HValue* checked_object = AddCheckMap(receiver, receiver_map); |
| 8262 HValue* length = Add<HLoadNamedField>( | 8271 HValue* length = Add<HLoadNamedField>( |
| 8263 checked_object, static_cast<HValue*>(NULL), | 8272 checked_object, static_cast<HValue*>(NULL), |
| 8264 HObjectAccess::ForArrayLength(elements_kind)); | 8273 HObjectAccess::ForArrayLength(elements_kind)); |
| 8265 | 8274 |
| 8266 Drop(1); // Function. | 8275 Drop(1); // Function. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8322 // inlined version can't be used. | 8331 // inlined version can't be used. |
| 8323 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; | 8332 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; |
| 8324 // If there currently can be no elements accessors on the prototype chain, | 8333 // If there currently can be no elements accessors on the prototype chain, |
| 8325 // it doesn't mean that there won't be any later. Install a full prototype | 8334 // it doesn't mean that there won't be any later. Install a full prototype |
| 8326 // chain check to trap element accessors being installed on the prototype | 8335 // chain check to trap element accessors being installed on the prototype |
| 8327 // chain, which would cause elements to go to dictionary mode and result | 8336 // chain, which would cause elements to go to dictionary mode and result |
| 8328 // in a map change. | 8337 // in a map change. |
| 8329 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 8338 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
| 8330 BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); | 8339 BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); |
| 8331 | 8340 |
| 8332 const int argc = expr->arguments()->length(); | 8341 const int argc = args_count_no_receiver; |
| 8333 if (argc != 1) return false; | 8342 if (argc != 1) return false; |
| 8334 | 8343 |
| 8335 HValue* value_to_push = Pop(); | 8344 HValue* value_to_push = Pop(); |
| 8336 HValue* array = Pop(); | 8345 HValue* array = Pop(); |
| 8337 Drop(1); // Drop function. | 8346 Drop(1); // Drop function. |
| 8338 | 8347 |
| 8339 HInstruction* new_size = NULL; | 8348 HInstruction* new_size = NULL; |
| 8340 HValue* length = NULL; | 8349 HValue* length = NULL; |
| 8341 | 8350 |
| 8342 { | 8351 { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8379 // chain check to trap element accessors being installed on the prototype | 8388 // chain check to trap element accessors being installed on the prototype |
| 8380 // chain, which would cause elements to go to dictionary mode and result | 8389 // chain, which would cause elements to go to dictionary mode and result |
| 8381 // in a map change. | 8390 // in a map change. |
| 8382 BuildCheckPrototypeMaps( | 8391 BuildCheckPrototypeMaps( |
| 8383 handle(JSObject::cast(receiver_map->prototype()), isolate()), | 8392 handle(JSObject::cast(receiver_map->prototype()), isolate()), |
| 8384 Handle<JSObject>::null()); | 8393 Handle<JSObject>::null()); |
| 8385 | 8394 |
| 8386 // Threshold for fast inlined Array.shift(). | 8395 // Threshold for fast inlined Array.shift(). |
| 8387 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); | 8396 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); |
| 8388 | 8397 |
| 8389 Drop(expr->arguments()->length()); | 8398 Drop(args_count_no_receiver); |
| 8390 HValue* receiver = Pop(); | 8399 HValue* receiver = Pop(); |
| 8391 HValue* function = Pop(); | 8400 HValue* function = Pop(); |
| 8392 HValue* result; | 8401 HValue* result; |
| 8393 | 8402 |
| 8394 { | 8403 { |
| 8395 NoObservableSideEffectsScope scope(this); | 8404 NoObservableSideEffectsScope scope(this); |
| 8396 | 8405 |
| 8397 HValue* length = Add<HLoadNamedField>( | 8406 HValue* length = Add<HLoadNamedField>( |
| 8398 receiver, static_cast<HValue*>(NULL), | 8407 receiver, static_cast<HValue*>(NULL), |
| 8399 HObjectAccess::ForArrayLength(kind)); | 8408 HObjectAccess::ForArrayLength(kind)); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8685 HInstruction* call = New<HCallWithDescriptor>( | 8694 HInstruction* call = New<HCallWithDescriptor>( |
| 8686 code_value, argc + 1, descriptor, | 8695 code_value, argc + 1, descriptor, |
| 8687 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); | 8696 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); |
| 8688 | 8697 |
| 8689 if (drop_extra) Drop(1); // Drop function. | 8698 if (drop_extra) Drop(1); // Drop function. |
| 8690 ast_context()->ReturnInstruction(call, ast_id); | 8699 ast_context()->ReturnInstruction(call, ast_id); |
| 8691 return true; | 8700 return true; |
| 8692 } | 8701 } |
| 8693 | 8702 |
| 8694 | 8703 |
| 8695 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { | 8704 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function, |
| 8705 int arguments_count) { | |
| 8706 Handle<JSFunction> known_function; | |
| 8707 int args_count_no_receiver = arguments_count - 1; | |
| 8708 if (function->IsConstant() && | |
| 8709 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | |
| 8710 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); | |
| 8711 Handle<Map> receiver_map; | |
| 8712 if (receiver->IsConstant() && | |
| 8713 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) { | |
| 8714 receiver_map = | |
| 8715 handle(Handle<HeapObject>::cast( | |
| 8716 HConstant::cast(receiver)->handle(isolate()))->map()); | |
| 8717 } | |
| 8718 | |
| 8719 known_function = | |
| 8720 Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate())); | |
| 8721 if (TryInlineBuiltinMethodCall(expr, known_function, receiver_map, | |
| 8722 args_count_no_receiver)) { | |
| 8723 if (FLAG_trace_inlining) { | |
| 8724 PrintF("Inlining builtin "); | |
| 8725 known_function->ShortPrint(); | |
| 8726 PrintF("\n"); | |
| 8727 } | |
| 8728 return; | |
| 8729 } | |
| 8730 | |
| 8731 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) { | |
| 8732 return; | |
| 8733 } | |
| 8734 } | |
| 8735 | |
| 8736 PushArgumentsFromEnvironment(arguments_count); | |
| 8737 HInvokeFunction* call = | |
| 8738 New<HInvokeFunction>(function, known_function, arguments_count); | |
| 8739 Drop(1); // Function | |
| 8740 ast_context()->ReturnInstruction(call, expr->id()); | |
| 8741 } | |
| 8742 | |
| 8743 | |
| 8744 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { | |
| 8696 DCHECK(expr->expression()->IsProperty()); | 8745 DCHECK(expr->expression()->IsProperty()); |
| 8697 | 8746 |
| 8698 if (!expr->IsMonomorphic()) { | 8747 if (!expr->IsMonomorphic()) { |
| 8699 return false; | 8748 return false; |
| 8700 } | 8749 } |
| 8701 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | 8750 Handle<Map> function_map = expr->GetReceiverTypes()->first(); |
| 8702 if (function_map->instance_type() != JS_FUNCTION_TYPE || | 8751 if (function_map->instance_type() != JS_FUNCTION_TYPE || |
| 8703 !expr->target()->shared()->HasBuiltinFunctionId() || | 8752 !expr->target()->shared()->HasBuiltinFunctionId()) { |
| 8704 expr->target()->shared()->builtin_function_id() != kFunctionApply) { | |
| 8705 return false; | 8753 return false; |
| 8706 } | 8754 } |
| 8707 | 8755 |
| 8708 if (current_info()->scope()->arguments() == NULL) return false; | 8756 switch (expr->target()->shared()->builtin_function_id()) { |
| 8757 case kFunctionCall: { | |
| 8758 if (expr->arguments()->length() == 0) return false; | |
| 8759 BuildFunctionCall(expr); | |
| 8760 return true; | |
| 8761 } | |
| 8762 case kFunctionApply: { | |
| 8763 // For .apply, only the pattern f.apply(receiver, arguments) | |
| 8764 // is supported. | |
| 8765 if (current_info()->scope()->arguments() == NULL) return false; | |
| 8709 | 8766 |
| 8767 ZoneList<Expression*>* args = expr->arguments(); | |
| 8768 if (args->length() != 2) return false; | |
| 8769 | |
| 8770 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | |
| 8771 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | |
| 8772 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | |
| 8773 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | |
| 8774 BuildFunctionApply(expr); | |
| 8775 return true; | |
| 8776 } | |
| 8777 default: { return false; } | |
| 8778 } | |
| 8779 UNREACHABLE(); | |
| 8780 } | |
| 8781 | |
| 8782 | |
| 8783 void HOptimizedGraphBuilder::BuildFunctionApply(Call* expr) { | |
| 8710 ZoneList<Expression*>* args = expr->arguments(); | 8784 ZoneList<Expression*>* args = expr->arguments(); |
| 8711 if (args->length() != 2) return false; | 8785 CHECK_ALIVE(VisitForValue(args->at(0))); |
| 8712 | |
| 8713 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | |
| 8714 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | |
| 8715 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | |
| 8716 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | |
| 8717 | |
| 8718 // Found pattern f.apply(receiver, arguments). | |
| 8719 CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); | |
| 8720 HValue* receiver = Pop(); // receiver | 8786 HValue* receiver = Pop(); // receiver |
| 8721 HValue* function = Pop(); // f | 8787 HValue* function = Pop(); // f |
| 8722 Drop(1); // apply | 8788 Drop(1); // apply |
| 8723 | 8789 |
| 8790 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | |
| 8724 HValue* checked_function = AddCheckMap(function, function_map); | 8791 HValue* checked_function = AddCheckMap(function, function_map); |
| 8725 | 8792 |
| 8726 if (function_state()->outer() == NULL) { | 8793 if (function_state()->outer() == NULL) { |
| 8727 HInstruction* elements = Add<HArgumentsElements>(false); | 8794 HInstruction* elements = Add<HArgumentsElements>(false); |
| 8728 HInstruction* length = Add<HArgumentsLength>(elements); | 8795 HInstruction* length = Add<HArgumentsLength>(elements); |
| 8729 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); | 8796 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); |
| 8730 HInstruction* result = New<HApplyArguments>(function, | 8797 HInstruction* result = New<HApplyArguments>(function, |
| 8731 wrapped_receiver, | 8798 wrapped_receiver, |
| 8732 length, | 8799 length, |
| 8733 elements); | 8800 elements); |
| 8734 ast_context()->ReturnInstruction(result, expr->id()); | 8801 ast_context()->ReturnInstruction(result, expr->id()); |
| 8735 return true; | |
| 8736 } else { | 8802 } else { |
| 8737 // We are inside inlined function and we know exactly what is inside | 8803 // We are inside inlined function and we know exactly what is inside |
| 8738 // arguments object. But we need to be able to materialize at deopt. | 8804 // arguments object. But we need to be able to materialize at deopt. |
| 8739 DCHECK_EQ(environment()->arguments_environment()->parameter_count(), | 8805 DCHECK_EQ(environment()->arguments_environment()->parameter_count(), |
| 8740 function_state()->entry()->arguments_object()->arguments_count()); | 8806 function_state()->entry()->arguments_object()->arguments_count()); |
| 8741 HArgumentsObject* args = function_state()->entry()->arguments_object(); | 8807 HArgumentsObject* args = function_state()->entry()->arguments_object(); |
| 8742 const ZoneList<HValue*>* arguments_values = args->arguments_values(); | 8808 const ZoneList<HValue*>* arguments_values = args->arguments_values(); |
| 8743 int arguments_count = arguments_values->length(); | 8809 int arguments_count = arguments_values->length(); |
| 8744 Push(function); | 8810 Push(function); |
| 8745 Push(BuildWrapReceiver(receiver, checked_function)); | 8811 Push(BuildWrapReceiver(receiver, checked_function)); |
| 8746 for (int i = 1; i < arguments_count; i++) { | 8812 for (int i = 1; i < arguments_count; i++) { |
| 8747 Push(arguments_values->at(i)); | 8813 Push(arguments_values->at(i)); |
| 8748 } | 8814 } |
| 8749 | 8815 HandleIndirectCall(expr, function, arguments_count); |
| 8750 Handle<JSFunction> known_function; | |
| 8751 if (function->IsConstant() && | |
| 8752 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | |
| 8753 known_function = Handle<JSFunction>::cast( | |
| 8754 HConstant::cast(function)->handle(isolate())); | |
| 8755 int args_count = arguments_count - 1; // Excluding receiver. | |
| 8756 if (TryInlineApply(known_function, expr, args_count)) return true; | |
| 8757 } | |
| 8758 | |
| 8759 PushArgumentsFromEnvironment(arguments_count); | |
| 8760 HInvokeFunction* call = New<HInvokeFunction>( | |
| 8761 function, known_function, arguments_count); | |
| 8762 Drop(1); // Function. | |
| 8763 ast_context()->ReturnInstruction(call, expr->id()); | |
| 8764 return true; | |
| 8765 } | 8816 } |
| 8766 } | 8817 } |
| 8767 | 8818 |
| 8768 | 8819 |
| 8820 // f.call(...) | |
| 8821 void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) { | |
| 8822 HValue* function = Top(); // f | |
| 8823 Handle<Map> function_map = expr->GetReceiverTypes()->first(); | |
| 8824 HValue* checked_function = AddCheckMap(function, function_map); | |
| 8825 | |
| 8826 // f and call are on the stack in the unoptimized code | |
| 8827 // during evaluation of the arguments. | |
| 8828 CHECK_ALIVE(VisitExpressions(expr->arguments())); | |
| 8829 | |
| 8830 int args_length = expr->arguments()->length(); | |
| 8831 int receiver_index = args_length - 1; | |
| 8832 // Patch the receiver. | |
| 8833 HValue* receiver = BuildWrapReceiver( | |
| 8834 environment()->ExpressionStackAt(receiver_index), checked_function); | |
| 8835 environment()->SetExpressionStackAt(receiver_index, receiver); | |
| 8836 | |
| 8837 // Call must not be on the stack from now on. | |
| 8838 int call_index = args_length + 1; | |
| 8839 environment()->RemoveExpressionStackAt(call_index); | |
| 8840 | |
| 8841 HandleIndirectCall(expr, function, args_length); | |
| 8842 } | |
| 8843 | |
| 8844 | |
| 8769 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, | 8845 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, |
| 8770 Handle<JSFunction> target) { | 8846 Handle<JSFunction> target) { |
| 8771 SharedFunctionInfo* shared = target->shared(); | 8847 SharedFunctionInfo* shared = target->shared(); |
| 8772 if (shared->strict_mode() == SLOPPY && !shared->native()) { | 8848 if (shared->strict_mode() == SLOPPY && !shared->native()) { |
| 8773 // Cannot embed a direct reference to the global proxy | 8849 // Cannot embed a direct reference to the global proxy |
| 8774 // as is it dropped on deserialization. | 8850 // as is it dropped on deserialization. |
| 8775 CHECK(!isolate()->serializer_enabled()); | 8851 CHECK(!isolate()->serializer_enabled()); |
| 8776 Handle<JSObject> global_proxy(target->context()->global_proxy()); | 8852 Handle<JSObject> global_proxy(target->context()->global_proxy()); |
| 8777 return Add<HConstant>(global_proxy); | 8853 return Add<HConstant>(global_proxy); |
| 8778 } | 8854 } |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9021 environment()->SetExpressionStackAt(0, function); | 9097 environment()->SetExpressionStackAt(0, function); |
| 9022 | 9098 |
| 9023 Push(receiver); | 9099 Push(receiver); |
| 9024 | 9100 |
| 9025 if (function->IsConstant() && | 9101 if (function->IsConstant() && |
| 9026 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 9102 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 9027 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 9103 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 9028 HConstant::cast(function)->handle(isolate())); | 9104 HConstant::cast(function)->handle(isolate())); |
| 9029 expr->set_target(known_function); | 9105 expr->set_target(known_function); |
| 9030 | 9106 |
| 9031 if (TryCallApply(expr)) return; | 9107 if (TryIndirectCall(expr)) return; |
| 9032 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9108 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 9033 | 9109 |
| 9034 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); | 9110 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); |
| 9035 if (TryInlineBuiltinMethodCall(expr, receiver, map)) { | 9111 if (TryInlineBuiltinMethodCall(expr, known_function, map, |
| 9112 expr->arguments()->length())) { | |
| 9036 if (FLAG_trace_inlining) { | 9113 if (FLAG_trace_inlining) { |
| 9037 PrintF("Inlining builtin "); | 9114 PrintF("Inlining builtin "); |
| 9038 known_function->ShortPrint(); | 9115 known_function->ShortPrint(); |
| 9039 PrintF("\n"); | 9116 PrintF("\n"); |
| 9040 } | 9117 } |
| 9041 return; | 9118 return; |
| 9042 } | 9119 } |
| 9043 if (TryInlineApiMethodCall(expr, receiver, types)) return; | 9120 if (TryInlineApiMethodCall(expr, receiver, types)) return; |
| 9044 | 9121 |
| 9045 // Wrap the receiver if necessary. | 9122 // Wrap the receiver if necessary. |
| (...skipping 3017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12063 // the new value will not be included in this environment's history. | 12140 // the new value will not be included in this environment's history. |
| 12064 if (push_count_ < count) { | 12141 if (push_count_ < count) { |
| 12065 // This is the same effect as popping then re-pushing 'count' elements. | 12142 // This is the same effect as popping then re-pushing 'count' elements. |
| 12066 pop_count_ += (count - push_count_); | 12143 pop_count_ += (count - push_count_); |
| 12067 push_count_ = count; | 12144 push_count_ = count; |
| 12068 } | 12145 } |
| 12069 values_[index] = value; | 12146 values_[index] = value; |
| 12070 } | 12147 } |
| 12071 | 12148 |
| 12072 | 12149 |
| 12150 HValue* HEnvironment::RemoveExpressionStackAt(int index_from_top) { | |
| 12151 int count = index_from_top + 1; | |
| 12152 int index = values_.length() - count; | |
| 12153 DCHECK(HasExpressionAt(index)); | |
| 12154 // Simulate popping 'count' elements and then | |
| 12155 // pushing 'count - 1' elements back. | |
| 12156 pop_count_ += Max(count - push_count_, 0); | |
| 12157 push_count_ = Max(push_count_ - count, 0) + (count - 1); | |
| 12158 return values_.Remove(index); | |
| 12159 } | |
| 12160 | |
| 12161 | |
| 12073 void HEnvironment::Drop(int count) { | 12162 void HEnvironment::Drop(int count) { |
| 12074 for (int i = 0; i < count; ++i) { | 12163 for (int i = 0; i < count; ++i) { |
| 12075 Pop(); | 12164 Pop(); |
| 12076 } | 12165 } |
| 12077 } | 12166 } |
| 12078 | 12167 |
| 12079 | 12168 |
| 12080 HEnvironment* HEnvironment::Copy() const { | 12169 HEnvironment* HEnvironment::Copy() const { |
| 12081 return new(zone()) HEnvironment(this, zone()); | 12170 return new(zone()) HEnvironment(this, zone()); |
| 12082 } | 12171 } |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12519 if (ShouldProduceTraceOutput()) { | 12608 if (ShouldProduceTraceOutput()) { |
| 12520 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12609 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12521 } | 12610 } |
| 12522 | 12611 |
| 12523 #ifdef DEBUG | 12612 #ifdef DEBUG |
| 12524 graph_->Verify(false); // No full verify. | 12613 graph_->Verify(false); // No full verify. |
| 12525 #endif | 12614 #endif |
| 12526 } | 12615 } |
| 12527 | 12616 |
| 12528 } } // namespace v8::internal | 12617 } } // namespace v8::internal |
| OLD | NEW |