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 |