| 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 "hydrogen.h" | 5 #include "hydrogen.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "v8.h" | 9 #include "v8.h" |
| 10 #include "allocation-site-scopes.h" | 10 #include "allocation-site-scopes.h" |
| (...skipping 1716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 // Load the value in case of cache hit. | 1727 // Load the value in case of cache hit. |
| 1728 HValue* key_index = Pop(); | 1728 HValue* key_index = Pop(); |
| 1729 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | 1729 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); |
| 1730 Push(Add<HLoadKeyed>(number_string_cache, value_index, | 1730 Push(Add<HLoadKeyed>(number_string_cache, value_index, |
| 1731 static_cast<HValue*>(NULL), | 1731 static_cast<HValue*>(NULL), |
| 1732 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); | 1732 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); |
| 1733 } | 1733 } |
| 1734 if_found.Else(); | 1734 if_found.Else(); |
| 1735 { | 1735 { |
| 1736 // Cache miss, fallback to runtime. | 1736 // Cache miss, fallback to runtime. |
| 1737 Add<HPushArguments>(zone(), object); | 1737 Add<HPushArguments>(object); |
| 1738 Push(Add<HCallRuntime>( | 1738 Push(Add<HCallRuntime>( |
| 1739 isolate()->factory()->empty_string(), | 1739 isolate()->factory()->empty_string(), |
| 1740 Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache), | 1740 Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache), |
| 1741 1)); | 1741 1)); |
| 1742 } | 1742 } |
| 1743 if_found.End(); | 1743 if_found.End(); |
| 1744 | 1744 |
| 1745 return Pop(); | 1745 return Pop(); |
| 1746 } | 1746 } |
| 1747 | 1747 |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 | 2051 |
| 2052 // Count the native string addition. | 2052 // Count the native string addition. |
| 2053 AddIncrementCounter(isolate()->counters()->string_add_native()); | 2053 AddIncrementCounter(isolate()->counters()->string_add_native()); |
| 2054 | 2054 |
| 2055 // Return the sequential string. | 2055 // Return the sequential string. |
| 2056 Push(result); | 2056 Push(result); |
| 2057 } | 2057 } |
| 2058 if_sameencodingandsequential.Else(); | 2058 if_sameencodingandsequential.Else(); |
| 2059 { | 2059 { |
| 2060 // Fallback to the runtime to add the two strings. | 2060 // Fallback to the runtime to add the two strings. |
| 2061 Add<HPushArguments>(zone(), left, right); | 2061 Add<HPushArguments>(left, right); |
| 2062 Push(Add<HCallRuntime>( | 2062 Push(Add<HCallRuntime>( |
| 2063 isolate()->factory()->empty_string(), | 2063 isolate()->factory()->empty_string(), |
| 2064 Runtime::FunctionForId(Runtime::kHiddenStringAdd), | 2064 Runtime::FunctionForId(Runtime::kHiddenStringAdd), |
| 2065 2)); | 2065 2)); |
| 2066 } | 2066 } |
| 2067 if_sameencodingandsequential.End(); | 2067 if_sameencodingandsequential.End(); |
| 2068 } | 2068 } |
| 2069 if_createcons.End(); | 2069 if_createcons.End(); |
| 2070 | 2070 |
| 2071 return Pop(); | 2071 return Pop(); |
| (...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4190 } | 4190 } |
| 4191 } | 4191 } |
| 4192 | 4192 |
| 4193 | 4193 |
| 4194 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { | 4194 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { |
| 4195 ZoneList<HValue*> arguments(count, zone()); | 4195 ZoneList<HValue*> arguments(count, zone()); |
| 4196 for (int i = 0; i < count; ++i) { | 4196 for (int i = 0; i < count; ++i) { |
| 4197 arguments.Add(Pop(), zone()); | 4197 arguments.Add(Pop(), zone()); |
| 4198 } | 4198 } |
| 4199 | 4199 |
| 4200 HPushArguments* push_args = New<HPushArguments>(zone()); | 4200 HPushArguments* push_args = New<HPushArguments>(); |
| 4201 while (!arguments.is_empty()) { | 4201 while (!arguments.is_empty()) { |
| 4202 push_args->AddArgument(arguments.RemoveLast()); | 4202 push_args->AddInput(arguments.RemoveLast()); |
| 4203 } | 4203 } |
| 4204 AddInstruction(push_args); | 4204 AddInstruction(push_args); |
| 4205 } | 4205 } |
| 4206 | 4206 |
| 4207 | 4207 |
| 4208 template <class Instruction> | 4208 template <class Instruction> |
| 4209 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4209 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
| 4210 PushArgumentsFromEnvironment(call->argument_count()); | 4210 PushArgumentsFromEnvironment(call->argument_count()); |
| 4211 return call; | 4211 return call; |
| 4212 } | 4212 } |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5188 } else { | 5188 } else { |
| 5189 NoObservableSideEffectsScope no_effects(this); | 5189 NoObservableSideEffectsScope no_effects(this); |
| 5190 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 5190 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
| 5191 Handle<FixedArray> constant_properties = expr->constant_properties(); | 5191 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 5192 int literal_index = expr->literal_index(); | 5192 int literal_index = expr->literal_index(); |
| 5193 int flags = expr->fast_elements() | 5193 int flags = expr->fast_elements() |
| 5194 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 5194 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
| 5195 flags |= expr->has_function() | 5195 flags |= expr->has_function() |
| 5196 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 5196 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
| 5197 | 5197 |
| 5198 Add<HPushArguments>(zone(), | 5198 Add<HPushArguments>(Add<HConstant>(closure_literals), |
| 5199 Add<HConstant>(closure_literals), | |
| 5200 Add<HConstant>(literal_index), | 5199 Add<HConstant>(literal_index), |
| 5201 Add<HConstant>(constant_properties), | 5200 Add<HConstant>(constant_properties), |
| 5202 Add<HConstant>(flags)); | 5201 Add<HConstant>(flags)); |
| 5203 | 5202 |
| 5204 // TODO(mvstanton): Add a flag to turn off creation of any | 5203 // TODO(mvstanton): Add a flag to turn off creation of any |
| 5205 // AllocationMementos for this call: we are in crankshaft and should have | 5204 // AllocationMementos for this call: we are in crankshaft and should have |
| 5206 // learned enough about transition behavior to stop emitting mementos. | 5205 // learned enough about transition behavior to stop emitting mementos. |
| 5207 Runtime::FunctionId function_id = Runtime::kHiddenCreateObjectLiteral; | 5206 Runtime::FunctionId function_id = Runtime::kHiddenCreateObjectLiteral; |
| 5208 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5207 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 5209 Runtime::FunctionForId(function_id), | 5208 Runtime::FunctionForId(function_id), |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5347 NoObservableSideEffectsScope no_effects(this); | 5346 NoObservableSideEffectsScope no_effects(this); |
| 5348 // Boilerplate already exists and constant elements are never accessed, | 5347 // Boilerplate already exists and constant elements are never accessed, |
| 5349 // pass an empty fixed array to the runtime function instead. | 5348 // pass an empty fixed array to the runtime function instead. |
| 5350 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 5349 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 5351 int literal_index = expr->literal_index(); | 5350 int literal_index = expr->literal_index(); |
| 5352 int flags = expr->depth() == 1 | 5351 int flags = expr->depth() == 1 |
| 5353 ? ArrayLiteral::kShallowElements | 5352 ? ArrayLiteral::kShallowElements |
| 5354 : ArrayLiteral::kNoFlags; | 5353 : ArrayLiteral::kNoFlags; |
| 5355 flags |= ArrayLiteral::kDisableMementos; | 5354 flags |= ArrayLiteral::kDisableMementos; |
| 5356 | 5355 |
| 5357 Add<HPushArguments>(zone(), | 5356 Add<HPushArguments>(Add<HConstant>(literals), |
| 5358 Add<HConstant>(literals), | |
| 5359 Add<HConstant>(literal_index), | 5357 Add<HConstant>(literal_index), |
| 5360 Add<HConstant>(constants), | 5358 Add<HConstant>(constants), |
| 5361 Add<HConstant>(flags)); | 5359 Add<HConstant>(flags)); |
| 5362 | 5360 |
| 5363 // TODO(mvstanton): Consider a flag to turn off creation of any | 5361 // TODO(mvstanton): Consider a flag to turn off creation of any |
| 5364 // AllocationMementos for this call: we are in crankshaft and should have | 5362 // AllocationMementos for this call: we are in crankshaft and should have |
| 5365 // learned enough about transition behavior to stop emitting mementos. | 5363 // learned enough about transition behavior to stop emitting mementos. |
| 5366 Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral; | 5364 Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral; |
| 5367 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5365 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 5368 Runtime::FunctionForId(function_id), | 5366 Runtime::FunctionForId(function_id), |
| (...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6366 ASSERT(current_block() != NULL); | 6364 ASSERT(current_block() != NULL); |
| 6367 ASSERT(current_block()->HasPredecessor()); | 6365 ASSERT(current_block()->HasPredecessor()); |
| 6368 // We don't optimize functions with invalid left-hand sides in | 6366 // We don't optimize functions with invalid left-hand sides in |
| 6369 // assignments, count operations, or for-in. Consequently throw can | 6367 // assignments, count operations, or for-in. Consequently throw can |
| 6370 // currently only occur in an effect context. | 6368 // currently only occur in an effect context. |
| 6371 ASSERT(ast_context()->IsEffect()); | 6369 ASSERT(ast_context()->IsEffect()); |
| 6372 CHECK_ALIVE(VisitForValue(expr->exception())); | 6370 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 6373 | 6371 |
| 6374 HValue* value = environment()->Pop(); | 6372 HValue* value = environment()->Pop(); |
| 6375 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); | 6373 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 6376 Add<HPushArguments>(zone(), value); | 6374 Add<HPushArguments>(value); |
| 6377 Add<HCallRuntime>(isolate()->factory()->empty_string(), | 6375 Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 6378 Runtime::FunctionForId(Runtime::kHiddenThrow), 1); | 6376 Runtime::FunctionForId(Runtime::kHiddenThrow), 1); |
| 6379 Add<HSimulate>(expr->id()); | 6377 Add<HSimulate>(expr->id()); |
| 6380 | 6378 |
| 6381 // If the throw definitely exits the function, we can finish with a dummy | 6379 // If the throw definitely exits the function, we can finish with a dummy |
| 6382 // control flow at this point. This is not the case if the throw is inside | 6380 // control flow at this point. This is not the case if the throw is inside |
| 6383 // an inlined function which may be replaced. | 6381 // an inlined function which may be replaced. |
| 6384 if (call_context() == NULL) { | 6382 if (call_context() == NULL) { |
| 6385 FinishExitCurrentBlock(New<HAbnormalExit>()); | 6383 FinishExitCurrentBlock(New<HAbnormalExit>()); |
| 6386 } | 6384 } |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6768 // Push arguments when entering inlined function. | 6766 // Push arguments when entering inlined function. |
| 6769 HEnterInlined* entry = function_state()->entry(); | 6767 HEnterInlined* entry = function_state()->entry(); |
| 6770 entry->set_arguments_pushed(); | 6768 entry->set_arguments_pushed(); |
| 6771 | 6769 |
| 6772 HArgumentsObject* arguments = entry->arguments_object(); | 6770 HArgumentsObject* arguments = entry->arguments_object(); |
| 6773 const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); | 6771 const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); |
| 6774 | 6772 |
| 6775 HInstruction* insert_after = entry; | 6773 HInstruction* insert_after = entry; |
| 6776 for (int i = 0; i < arguments_values->length(); i++) { | 6774 for (int i = 0; i < arguments_values->length(); i++) { |
| 6777 HValue* argument = arguments_values->at(i); | 6775 HValue* argument = arguments_values->at(i); |
| 6778 HInstruction* push_argument = New<HPushArguments>(zone(), argument); | 6776 HInstruction* push_argument = New<HPushArguments>(argument); |
| 6779 push_argument->InsertAfter(insert_after); | 6777 push_argument->InsertAfter(insert_after); |
| 6780 insert_after = push_argument; | 6778 insert_after = push_argument; |
| 6781 } | 6779 } |
| 6782 | 6780 |
| 6783 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); | 6781 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); |
| 6784 arguments_elements->ClearFlag(HValue::kUseGVN); | 6782 arguments_elements->ClearFlag(HValue::kUseGVN); |
| 6785 arguments_elements->InsertAfter(insert_after); | 6783 arguments_elements->InsertAfter(insert_after); |
| 6786 function_state()->set_arguments_elements(arguments_elements); | 6784 function_state()->set_arguments_elements(arguments_elements); |
| 6787 } | 6785 } |
| 6788 | 6786 |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8063 PushArgumentsFromEnvironment(argc + 1); | 8061 PushArgumentsFromEnvironment(argc + 1); |
| 8064 // Drop function after call. | 8062 // Drop function after call. |
| 8065 drop_extra = true; | 8063 drop_extra = true; |
| 8066 break; | 8064 break; |
| 8067 case kCallApiGetter: | 8065 case kCallApiGetter: |
| 8068 // Receiver and prototype chain cannot have changed. | 8066 // Receiver and prototype chain cannot have changed. |
| 8069 ASSERT_EQ(0, argc); | 8067 ASSERT_EQ(0, argc); |
| 8070 ASSERT_EQ(NULL, receiver); | 8068 ASSERT_EQ(NULL, receiver); |
| 8071 // Receiver is on expression stack. | 8069 // Receiver is on expression stack. |
| 8072 receiver = Pop(); | 8070 receiver = Pop(); |
| 8073 Add<HPushArguments>(zone(), receiver); | 8071 Add<HPushArguments>(receiver); |
| 8074 break; | 8072 break; |
| 8075 case kCallApiSetter: | 8073 case kCallApiSetter: |
| 8076 { | 8074 { |
| 8077 is_store = true; | 8075 is_store = true; |
| 8078 // Receiver and prototype chain cannot have changed. | 8076 // Receiver and prototype chain cannot have changed. |
| 8079 ASSERT_EQ(1, argc); | 8077 ASSERT_EQ(1, argc); |
| 8080 ASSERT_EQ(NULL, receiver); | 8078 ASSERT_EQ(NULL, receiver); |
| 8081 // Receiver and value are on expression stack. | 8079 // Receiver and value are on expression stack. |
| 8082 HValue* value = Pop(); | 8080 HValue* value = Pop(); |
| 8083 receiver = Pop(); | 8081 receiver = Pop(); |
| 8084 Add<HPushArguments>(zone(), receiver, value); | 8082 Add<HPushArguments>(receiver, value); |
| 8085 break; | 8083 break; |
| 8086 } | 8084 } |
| 8087 } | 8085 } |
| 8088 | 8086 |
| 8089 HValue* holder = NULL; | 8087 HValue* holder = NULL; |
| 8090 switch (holder_lookup) { | 8088 switch (holder_lookup) { |
| 8091 case CallOptimization::kHolderFound: | 8089 case CallOptimization::kHolderFound: |
| 8092 holder = Add<HConstant>(api_holder); | 8090 holder = Add<HConstant>(api_holder); |
| 8093 break; | 8091 break; |
| 8094 case CallOptimization::kHolderIsReceiver: | 8092 case CallOptimization::kHolderIsReceiver: |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9120 | 9118 |
| 9121 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { | 9119 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
| 9122 Property* prop = expr->expression()->AsProperty(); | 9120 Property* prop = expr->expression()->AsProperty(); |
| 9123 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9121 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9124 if (prop != NULL) { | 9122 if (prop != NULL) { |
| 9125 CHECK_ALIVE(VisitForValue(prop->obj())); | 9123 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 9126 CHECK_ALIVE(VisitForValue(prop->key())); | 9124 CHECK_ALIVE(VisitForValue(prop->key())); |
| 9127 HValue* key = Pop(); | 9125 HValue* key = Pop(); |
| 9128 HValue* obj = Pop(); | 9126 HValue* obj = Pop(); |
| 9129 HValue* function = AddLoadJSBuiltin(Builtins::DELETE); | 9127 HValue* function = AddLoadJSBuiltin(Builtins::DELETE); |
| 9130 Add<HPushArguments>(zone(), | 9128 Add<HPushArguments>(obj, key, Add<HConstant>(function_strict_mode())); |
| 9131 obj, key, Add<HConstant>(function_strict_mode())); | |
| 9132 // TODO(olivf) InvokeFunction produces a check for the parameter count, | 9129 // TODO(olivf) InvokeFunction produces a check for the parameter count, |
| 9133 // even though we are certain to pass the correct number of arguments here. | 9130 // even though we are certain to pass the correct number of arguments here. |
| 9134 HInstruction* instr = New<HInvokeFunction>(function, 3); | 9131 HInstruction* instr = New<HInvokeFunction>(function, 3); |
| 9135 return ast_context()->ReturnInstruction(instr, expr->id()); | 9132 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 9136 } else if (proxy != NULL) { | 9133 } else if (proxy != NULL) { |
| 9137 Variable* var = proxy->var(); | 9134 Variable* var = proxy->var(); |
| 9138 if (var->IsUnallocated()) { | 9135 if (var->IsUnallocated()) { |
| 9139 Bailout(kDeleteWithGlobalVariable); | 9136 Bailout(kDeleteWithGlobalVariable); |
| 9140 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 9137 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 9141 // Result of deleting non-global variables is false. 'this' is not | 9138 // Result of deleting non-global variables is false. 'this' is not |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9601 right = BuildCheckString(right); | 9598 right = BuildCheckString(right); |
| 9602 } | 9599 } |
| 9603 | 9600 |
| 9604 // Convert left argument as necessary. | 9601 // Convert left argument as necessary. |
| 9605 if (left_type->Is(Type::Number())) { | 9602 if (left_type->Is(Type::Number())) { |
| 9606 ASSERT(right_type->Is(Type::String())); | 9603 ASSERT(right_type->Is(Type::String())); |
| 9607 left = BuildNumberToString(left, left_type); | 9604 left = BuildNumberToString(left, left_type); |
| 9608 } else if (!left_type->Is(Type::String())) { | 9605 } else if (!left_type->Is(Type::String())) { |
| 9609 ASSERT(right_type->Is(Type::String())); | 9606 ASSERT(right_type->Is(Type::String())); |
| 9610 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); | 9607 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); |
| 9611 Add<HPushArguments>(zone(), left, right); | 9608 Add<HPushArguments>(left, right); |
| 9612 return AddUncasted<HInvokeFunction>(function, 2); | 9609 return AddUncasted<HInvokeFunction>(function, 2); |
| 9613 } | 9610 } |
| 9614 | 9611 |
| 9615 // Convert right argument as necessary. | 9612 // Convert right argument as necessary. |
| 9616 if (right_type->Is(Type::Number())) { | 9613 if (right_type->Is(Type::Number())) { |
| 9617 ASSERT(left_type->Is(Type::String())); | 9614 ASSERT(left_type->Is(Type::String())); |
| 9618 right = BuildNumberToString(right, right_type); | 9615 right = BuildNumberToString(right, right_type); |
| 9619 } else if (!right_type->Is(Type::String())) { | 9616 } else if (!right_type->Is(Type::String())) { |
| 9620 ASSERT(left_type->Is(Type::String())); | 9617 ASSERT(left_type->Is(Type::String())); |
| 9621 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); | 9618 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
| 9622 Add<HPushArguments>(zone(), left, right); | 9619 Add<HPushArguments>(left, right); |
| 9623 return AddUncasted<HInvokeFunction>(function, 2); | 9620 return AddUncasted<HInvokeFunction>(function, 2); |
| 9624 } | 9621 } |
| 9625 | 9622 |
| 9626 // Fast path for empty constant strings. | 9623 // Fast path for empty constant strings. |
| 9627 if (left->IsConstant() && | 9624 if (left->IsConstant() && |
| 9628 HConstant::cast(left)->HasStringValue() && | 9625 HConstant::cast(left)->HasStringValue() && |
| 9629 HConstant::cast(left)->StringValue()->length() == 0) { | 9626 HConstant::cast(left)->StringValue()->length() == 0) { |
| 9630 return right; | 9627 return right; |
| 9631 } | 9628 } |
| 9632 if (right->IsConstant() && | 9629 if (right->IsConstant() && |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9674 | 9671 |
| 9675 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 9672 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
| 9676 (right_rep.IsTagged() && !right_rep.IsSmi()); | 9673 (right_rep.IsTagged() && !right_rep.IsSmi()); |
| 9677 | 9674 |
| 9678 HInstruction* instr = NULL; | 9675 HInstruction* instr = NULL; |
| 9679 // Only the stub is allowed to call into the runtime, since otherwise we would | 9676 // Only the stub is allowed to call into the runtime, since otherwise we would |
| 9680 // inline several instructions (including the two pushes) for every tagged | 9677 // inline several instructions (including the two pushes) for every tagged |
| 9681 // operation in optimized code, which is more expensive, than a stub call. | 9678 // operation in optimized code, which is more expensive, than a stub call. |
| 9682 if (graph()->info()->IsStub() && is_non_primitive) { | 9679 if (graph()->info()->IsStub() && is_non_primitive) { |
| 9683 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); | 9680 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); |
| 9684 Add<HPushArguments>(zone(), left, right); | 9681 Add<HPushArguments>(left, right); |
| 9685 instr = AddUncasted<HInvokeFunction>(function, 2); | 9682 instr = AddUncasted<HInvokeFunction>(function, 2); |
| 9686 } else { | 9683 } else { |
| 9687 switch (op) { | 9684 switch (op) { |
| 9688 case Token::ADD: | 9685 case Token::ADD: |
| 9689 instr = AddUncasted<HAdd>(left, right); | 9686 instr = AddUncasted<HAdd>(left, right); |
| 9690 break; | 9687 break; |
| 9691 case Token::SUB: | 9688 case Token::SUB: |
| 9692 instr = AddUncasted<HSub>(left, right); | 9689 instr = AddUncasted<HSub>(left, right); |
| 9693 break; | 9690 break; |
| 9694 case Token::MUL: | 9691 case Token::MUL: |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10038 Add<HCheckValue>(right, target); | 10035 Add<HCheckValue>(right, target); |
| 10039 HInstanceOfKnownGlobal* result = | 10036 HInstanceOfKnownGlobal* result = |
| 10040 New<HInstanceOfKnownGlobal>(left, target); | 10037 New<HInstanceOfKnownGlobal>(left, target); |
| 10041 return ast_context()->ReturnInstruction(result, expr->id()); | 10038 return ast_context()->ReturnInstruction(result, expr->id()); |
| 10042 } | 10039 } |
| 10043 | 10040 |
| 10044 // Code below assumes that we don't fall through. | 10041 // Code below assumes that we don't fall through. |
| 10045 UNREACHABLE(); | 10042 UNREACHABLE(); |
| 10046 } else if (op == Token::IN) { | 10043 } else if (op == Token::IN) { |
| 10047 HValue* function = AddLoadJSBuiltin(Builtins::IN); | 10044 HValue* function = AddLoadJSBuiltin(Builtins::IN); |
| 10048 Add<HPushArguments>(zone(), left, right); | 10045 Add<HPushArguments>(left, right); |
| 10049 // TODO(olivf) InvokeFunction produces a check for the parameter count, | 10046 // TODO(olivf) InvokeFunction produces a check for the parameter count, |
| 10050 // even though we are certain to pass the correct number of arguments here. | 10047 // even though we are certain to pass the correct number of arguments here. |
| 10051 HInstruction* result = New<HInvokeFunction>(function, 2); | 10048 HInstruction* result = New<HInvokeFunction>(function, 2); |
| 10052 return ast_context()->ReturnInstruction(result, expr->id()); | 10049 return ast_context()->ReturnInstruction(result, expr->id()); |
| 10053 } | 10050 } |
| 10054 | 10051 |
| 10055 PushBeforeSimulateBehavior push_behavior = | 10052 PushBeforeSimulateBehavior push_behavior = |
| 10056 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE | 10053 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE |
| 10057 : PUSH_BEFORE_SIMULATE; | 10054 : PUSH_BEFORE_SIMULATE; |
| 10058 HControlInstruction* compare = BuildCompareInstruction( | 10055 HControlInstruction* compare = BuildCompareInstruction( |
| (...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11796 if (ShouldProduceTraceOutput()) { | 11793 if (ShouldProduceTraceOutput()) { |
| 11797 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11794 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11798 } | 11795 } |
| 11799 | 11796 |
| 11800 #ifdef DEBUG | 11797 #ifdef DEBUG |
| 11801 graph_->Verify(false); // No full verify. | 11798 graph_->Verify(false); // No full verify. |
| 11802 #endif | 11799 #endif |
| 11803 } | 11800 } |
| 11804 | 11801 |
| 11805 } } // namespace v8::internal | 11802 } } // namespace v8::internal |
| OLD | NEW |