Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/hydrogen.cc

Issue 296113008: Allow HPushArgument to handle more than one argument. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase, and use int instead of unsigned Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/code-stubs-hydrogen.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 // Load the value in case of cache hit. 1719 // Load the value in case of cache hit.
1720 HValue* key_index = Pop(); 1720 HValue* key_index = Pop();
1721 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); 1721 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1());
1722 Push(Add<HLoadKeyed>(number_string_cache, value_index, 1722 Push(Add<HLoadKeyed>(number_string_cache, value_index,
1723 static_cast<HValue*>(NULL), 1723 static_cast<HValue*>(NULL),
1724 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); 1724 FAST_ELEMENTS, ALLOW_RETURN_HOLE));
1725 } 1725 }
1726 if_found.Else(); 1726 if_found.Else();
1727 { 1727 {
1728 // Cache miss, fallback to runtime. 1728 // Cache miss, fallback to runtime.
1729 Add<HPushArgument>(object); 1729 Add<HPushArguments>(zone(), object);
1730 Push(Add<HCallRuntime>( 1730 Push(Add<HCallRuntime>(
1731 isolate()->factory()->empty_string(), 1731 isolate()->factory()->empty_string(),
1732 Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache), 1732 Runtime::FunctionForId(Runtime::kHiddenNumberToStringSkipCache),
1733 1)); 1733 1));
1734 } 1734 }
1735 if_found.End(); 1735 if_found.End();
1736 1736
1737 return Pop(); 1737 return Pop();
1738 } 1738 }
1739 1739
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2043 2043
2044 // Count the native string addition. 2044 // Count the native string addition.
2045 AddIncrementCounter(isolate()->counters()->string_add_native()); 2045 AddIncrementCounter(isolate()->counters()->string_add_native());
2046 2046
2047 // Return the sequential string. 2047 // Return the sequential string.
2048 Push(result); 2048 Push(result);
2049 } 2049 }
2050 if_sameencodingandsequential.Else(); 2050 if_sameencodingandsequential.Else();
2051 { 2051 {
2052 // Fallback to the runtime to add the two strings. 2052 // Fallback to the runtime to add the two strings.
2053 Add<HPushArgument>(left); 2053 Add<HPushArguments>(zone(), left, right);
2054 Add<HPushArgument>(right);
2055 Push(Add<HCallRuntime>( 2054 Push(Add<HCallRuntime>(
2056 isolate()->factory()->empty_string(), 2055 isolate()->factory()->empty_string(),
2057 Runtime::FunctionForId(Runtime::kHiddenStringAdd), 2056 Runtime::FunctionForId(Runtime::kHiddenStringAdd),
2058 2)); 2057 2));
2059 } 2058 }
2060 if_sameencodingandsequential.End(); 2059 if_sameencodingandsequential.End();
2061 } 2060 }
2062 if_createcons.End(); 2061 if_createcons.End();
2063 2062
2064 return Pop(); 2063 return Pop();
(...skipping 2116 matching lines...) Expand 10 before | Expand all | Expand 10 after
4181 } 4180 }
4182 } 4181 }
4183 4182
4184 4183
4185 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { 4184 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) {
4186 ZoneList<HValue*> arguments(count, zone()); 4185 ZoneList<HValue*> arguments(count, zone());
4187 for (int i = 0; i < count; ++i) { 4186 for (int i = 0; i < count; ++i) {
4188 arguments.Add(Pop(), zone()); 4187 arguments.Add(Pop(), zone());
4189 } 4188 }
4190 4189
4190 HPushArguments* push_args = New<HPushArguments>(zone());
4191 while (!arguments.is_empty()) { 4191 while (!arguments.is_empty()) {
4192 Add<HPushArgument>(arguments.RemoveLast()); 4192 push_args->AddArgument(arguments.RemoveLast());
4193 } 4193 }
4194 AddInstruction(push_args);
4194 } 4195 }
4195 4196
4196 4197
4197 template <class Instruction> 4198 template <class Instruction>
4198 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 4199 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
4199 PushArgumentsFromEnvironment(call->argument_count()); 4200 PushArgumentsFromEnvironment(call->argument_count());
4200 return call; 4201 return call;
4201 } 4202 }
4202 4203
4203 4204
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 } else { 5178 } else {
5178 NoObservableSideEffectsScope no_effects(this); 5179 NoObservableSideEffectsScope no_effects(this);
5179 Handle<FixedArray> closure_literals(closure->literals(), isolate()); 5180 Handle<FixedArray> closure_literals(closure->literals(), isolate());
5180 Handle<FixedArray> constant_properties = expr->constant_properties(); 5181 Handle<FixedArray> constant_properties = expr->constant_properties();
5181 int literal_index = expr->literal_index(); 5182 int literal_index = expr->literal_index();
5182 int flags = expr->fast_elements() 5183 int flags = expr->fast_elements()
5183 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; 5184 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags;
5184 flags |= expr->has_function() 5185 flags |= expr->has_function()
5185 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 5186 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
5186 5187
5187 Add<HPushArgument>(Add<HConstant>(closure_literals)); 5188 Add<HPushArguments>(zone(),
5188 Add<HPushArgument>(Add<HConstant>(literal_index)); 5189 Add<HConstant>(closure_literals),
5189 Add<HPushArgument>(Add<HConstant>(constant_properties)); 5190 Add<HConstant>(literal_index),
5190 Add<HPushArgument>(Add<HConstant>(flags)); 5191 Add<HConstant>(constant_properties),
5192 Add<HConstant>(flags));
5191 5193
5192 // TODO(mvstanton): Add a flag to turn off creation of any 5194 // TODO(mvstanton): Add a flag to turn off creation of any
5193 // AllocationMementos for this call: we are in crankshaft and should have 5195 // AllocationMementos for this call: we are in crankshaft and should have
5194 // learned enough about transition behavior to stop emitting mementos. 5196 // learned enough about transition behavior to stop emitting mementos.
5195 Runtime::FunctionId function_id = Runtime::kHiddenCreateObjectLiteral; 5197 Runtime::FunctionId function_id = Runtime::kHiddenCreateObjectLiteral;
5196 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5198 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5197 Runtime::FunctionForId(function_id), 5199 Runtime::FunctionForId(function_id),
5198 4); 5200 4);
5199 } 5201 }
5200 5202
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
5335 NoObservableSideEffectsScope no_effects(this); 5337 NoObservableSideEffectsScope no_effects(this);
5336 // Boilerplate already exists and constant elements are never accessed, 5338 // Boilerplate already exists and constant elements are never accessed,
5337 // pass an empty fixed array to the runtime function instead. 5339 // pass an empty fixed array to the runtime function instead.
5338 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 5340 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
5339 int literal_index = expr->literal_index(); 5341 int literal_index = expr->literal_index();
5340 int flags = expr->depth() == 1 5342 int flags = expr->depth() == 1
5341 ? ArrayLiteral::kShallowElements 5343 ? ArrayLiteral::kShallowElements
5342 : ArrayLiteral::kNoFlags; 5344 : ArrayLiteral::kNoFlags;
5343 flags |= ArrayLiteral::kDisableMementos; 5345 flags |= ArrayLiteral::kDisableMementos;
5344 5346
5345 Add<HPushArgument>(Add<HConstant>(literals)); 5347 Add<HPushArguments>(zone(),
5346 Add<HPushArgument>(Add<HConstant>(literal_index)); 5348 Add<HConstant>(literals),
5347 Add<HPushArgument>(Add<HConstant>(constants)); 5349 Add<HConstant>(literal_index),
5348 Add<HPushArgument>(Add<HConstant>(flags)); 5350 Add<HConstant>(constants),
5351 Add<HConstant>(flags));
5349 5352
5350 // TODO(mvstanton): Consider a flag to turn off creation of any 5353 // TODO(mvstanton): Consider a flag to turn off creation of any
5351 // AllocationMementos for this call: we are in crankshaft and should have 5354 // AllocationMementos for this call: we are in crankshaft and should have
5352 // learned enough about transition behavior to stop emitting mementos. 5355 // learned enough about transition behavior to stop emitting mementos.
5353 Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral; 5356 Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral;
5354 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5357 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5355 Runtime::FunctionForId(function_id), 5358 Runtime::FunctionForId(function_id),
5356 4); 5359 4);
5357 5360
5358 // De-opt if elements kind changed from boilerplate_elements_kind. 5361 // De-opt if elements kind changed from boilerplate_elements_kind.
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
6372 ASSERT(current_block() != NULL); 6375 ASSERT(current_block() != NULL);
6373 ASSERT(current_block()->HasPredecessor()); 6376 ASSERT(current_block()->HasPredecessor());
6374 // We don't optimize functions with invalid left-hand sides in 6377 // We don't optimize functions with invalid left-hand sides in
6375 // assignments, count operations, or for-in. Consequently throw can 6378 // assignments, count operations, or for-in. Consequently throw can
6376 // currently only occur in an effect context. 6379 // currently only occur in an effect context.
6377 ASSERT(ast_context()->IsEffect()); 6380 ASSERT(ast_context()->IsEffect());
6378 CHECK_ALIVE(VisitForValue(expr->exception())); 6381 CHECK_ALIVE(VisitForValue(expr->exception()));
6379 6382
6380 HValue* value = environment()->Pop(); 6383 HValue* value = environment()->Pop();
6381 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 6384 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
6382 Add<HPushArgument>(value); 6385 Add<HPushArguments>(zone(), value);
6383 Add<HCallRuntime>(isolate()->factory()->empty_string(), 6386 Add<HCallRuntime>(isolate()->factory()->empty_string(),
6384 Runtime::FunctionForId(Runtime::kHiddenThrow), 1); 6387 Runtime::FunctionForId(Runtime::kHiddenThrow), 1);
6385 Add<HSimulate>(expr->id()); 6388 Add<HSimulate>(expr->id());
6386 6389
6387 // If the throw definitely exits the function, we can finish with a dummy 6390 // If the throw definitely exits the function, we can finish with a dummy
6388 // control flow at this point. This is not the case if the throw is inside 6391 // control flow at this point. This is not the case if the throw is inside
6389 // an inlined function which may be replaced. 6392 // an inlined function which may be replaced.
6390 if (call_context() == NULL) { 6393 if (call_context() == NULL) {
6391 FinishExitCurrentBlock(New<HAbnormalExit>()); 6394 FinishExitCurrentBlock(New<HAbnormalExit>());
6392 } 6395 }
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
6774 // Push arguments when entering inlined function. 6777 // Push arguments when entering inlined function.
6775 HEnterInlined* entry = function_state()->entry(); 6778 HEnterInlined* entry = function_state()->entry();
6776 entry->set_arguments_pushed(); 6779 entry->set_arguments_pushed();
6777 6780
6778 HArgumentsObject* arguments = entry->arguments_object(); 6781 HArgumentsObject* arguments = entry->arguments_object();
6779 const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); 6782 const ZoneList<HValue*>* arguments_values = arguments->arguments_values();
6780 6783
6781 HInstruction* insert_after = entry; 6784 HInstruction* insert_after = entry;
6782 for (int i = 0; i < arguments_values->length(); i++) { 6785 for (int i = 0; i < arguments_values->length(); i++) {
6783 HValue* argument = arguments_values->at(i); 6786 HValue* argument = arguments_values->at(i);
6784 HInstruction* push_argument = New<HPushArgument>(argument); 6787 HInstruction* push_argument = New<HPushArguments>(zone(), argument);
6785 push_argument->InsertAfter(insert_after); 6788 push_argument->InsertAfter(insert_after);
6786 insert_after = push_argument; 6789 insert_after = push_argument;
6787 } 6790 }
6788 6791
6789 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true); 6792 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true);
6790 arguments_elements->ClearFlag(HValue::kUseGVN); 6793 arguments_elements->ClearFlag(HValue::kUseGVN);
6791 arguments_elements->InsertAfter(insert_after); 6794 arguments_elements->InsertAfter(insert_after);
6792 function_state()->set_arguments_elements(arguments_elements); 6795 function_state()->set_arguments_elements(arguments_elements);
6793 } 6796 }
6794 6797
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after
8069 PushArgumentsFromEnvironment(argc + 1); 8072 PushArgumentsFromEnvironment(argc + 1);
8070 // Drop function after call. 8073 // Drop function after call.
8071 drop_extra = true; 8074 drop_extra = true;
8072 break; 8075 break;
8073 case kCallApiGetter: 8076 case kCallApiGetter:
8074 // Receiver and prototype chain cannot have changed. 8077 // Receiver and prototype chain cannot have changed.
8075 ASSERT_EQ(0, argc); 8078 ASSERT_EQ(0, argc);
8076 ASSERT_EQ(NULL, receiver); 8079 ASSERT_EQ(NULL, receiver);
8077 // Receiver is on expression stack. 8080 // Receiver is on expression stack.
8078 receiver = Pop(); 8081 receiver = Pop();
8079 Add<HPushArgument>(receiver); 8082 Add<HPushArguments>(zone(), receiver);
8080 break; 8083 break;
8081 case kCallApiSetter: 8084 case kCallApiSetter:
8082 { 8085 {
8083 is_store = true; 8086 is_store = true;
8084 // Receiver and prototype chain cannot have changed. 8087 // Receiver and prototype chain cannot have changed.
8085 ASSERT_EQ(1, argc); 8088 ASSERT_EQ(1, argc);
8086 ASSERT_EQ(NULL, receiver); 8089 ASSERT_EQ(NULL, receiver);
8087 // Receiver and value are on expression stack. 8090 // Receiver and value are on expression stack.
8088 HValue* value = Pop(); 8091 HValue* value = Pop();
8089 receiver = Pop(); 8092 receiver = Pop();
8090 Add<HPushArgument>(receiver); 8093 Add<HPushArguments>(zone(), receiver, value);
8091 Add<HPushArgument>(value);
8092 break; 8094 break;
8093 } 8095 }
8094 } 8096 }
8095 8097
8096 HValue* holder = NULL; 8098 HValue* holder = NULL;
8097 switch (holder_lookup) { 8099 switch (holder_lookup) {
8098 case CallOptimization::kHolderFound: 8100 case CallOptimization::kHolderFound:
8099 holder = Add<HConstant>(api_holder); 8101 holder = Add<HConstant>(api_holder);
8100 break; 8102 break;
8101 case CallOptimization::kHolderIsReceiver: 8103 case CallOptimization::kHolderIsReceiver:
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
8649 if (TryInlineConstruct(expr, receiver)) { 8651 if (TryInlineConstruct(expr, receiver)) {
8650 // Inlining worked, add a dependency on the initial map to make sure that 8652 // Inlining worked, add a dependency on the initial map to make sure that
8651 // this code is deoptimized whenever the initial map of the constructor 8653 // this code is deoptimized whenever the initial map of the constructor
8652 // changes. 8654 // changes.
8653 Map::AddDependentCompilationInfo( 8655 Map::AddDependentCompilationInfo(
8654 initial_map, DependentCode::kInitialMapChangedGroup, top_info()); 8656 initial_map, DependentCode::kInitialMapChangedGroup, top_info());
8655 return; 8657 return;
8656 } 8658 }
8657 8659
8658 // TODO(mstarzinger): For now we remove the previous HAllocate and all 8660 // TODO(mstarzinger): For now we remove the previous HAllocate and all
8659 // corresponding instructions and instead add HPushArgument for the 8661 // corresponding instructions and instead add HPushArguments for the
8660 // arguments in case inlining failed. What we actually should do is for 8662 // arguments in case inlining failed. What we actually should do is for
8661 // inlining to try to build a subgraph without mutating the parent graph. 8663 // inlining to try to build a subgraph without mutating the parent graph.
8662 HInstruction* instr = current_block()->last(); 8664 HInstruction* instr = current_block()->last();
8663 do { 8665 do {
8664 HInstruction* prev_instr = instr->previous(); 8666 HInstruction* prev_instr = instr->previous();
8665 instr->DeleteAndReplaceWith(NULL); 8667 instr->DeleteAndReplaceWith(NULL);
8666 instr = prev_instr; 8668 instr = prev_instr;
8667 } while (instr != check); 8669 } while (instr != check);
8668 environment()->SetExpressionStackAt(receiver_index, function); 8670 environment()->SetExpressionStackAt(receiver_index, function);
8669 HInstruction* call = 8671 HInstruction* call =
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
9128 9130
9129 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 9131 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
9130 Property* prop = expr->expression()->AsProperty(); 9132 Property* prop = expr->expression()->AsProperty();
9131 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9133 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9132 if (prop != NULL) { 9134 if (prop != NULL) {
9133 CHECK_ALIVE(VisitForValue(prop->obj())); 9135 CHECK_ALIVE(VisitForValue(prop->obj()));
9134 CHECK_ALIVE(VisitForValue(prop->key())); 9136 CHECK_ALIVE(VisitForValue(prop->key()));
9135 HValue* key = Pop(); 9137 HValue* key = Pop();
9136 HValue* obj = Pop(); 9138 HValue* obj = Pop();
9137 HValue* function = AddLoadJSBuiltin(Builtins::DELETE); 9139 HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
9138 Add<HPushArgument>(obj); 9140 Add<HPushArguments>(zone(),
9139 Add<HPushArgument>(key); 9141 obj, key, Add<HConstant>(function_strict_mode()));
9140 Add<HPushArgument>(Add<HConstant>(function_strict_mode()));
9141 // TODO(olivf) InvokeFunction produces a check for the parameter count, 9142 // TODO(olivf) InvokeFunction produces a check for the parameter count,
9142 // even though we are certain to pass the correct number of arguments here. 9143 // even though we are certain to pass the correct number of arguments here.
9143 HInstruction* instr = New<HInvokeFunction>(function, 3); 9144 HInstruction* instr = New<HInvokeFunction>(function, 3);
9144 return ast_context()->ReturnInstruction(instr, expr->id()); 9145 return ast_context()->ReturnInstruction(instr, expr->id());
9145 } else if (proxy != NULL) { 9146 } else if (proxy != NULL) {
9146 Variable* var = proxy->var(); 9147 Variable* var = proxy->var();
9147 if (var->IsUnallocated()) { 9148 if (var->IsUnallocated()) {
9148 Bailout(kDeleteWithGlobalVariable); 9149 Bailout(kDeleteWithGlobalVariable);
9149 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 9150 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
9150 // Result of deleting non-global variables is false. 'this' is not 9151 // Result of deleting non-global variables is false. 'this' is not
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
9615 right = BuildCheckString(right); 9616 right = BuildCheckString(right);
9616 } 9617 }
9617 9618
9618 // Convert left argument as necessary. 9619 // Convert left argument as necessary.
9619 if (left_type->Is(Type::Number())) { 9620 if (left_type->Is(Type::Number())) {
9620 ASSERT(right_type->Is(Type::String())); 9621 ASSERT(right_type->Is(Type::String()));
9621 left = BuildNumberToString(left, left_type); 9622 left = BuildNumberToString(left, left_type);
9622 } else if (!left_type->Is(Type::String())) { 9623 } else if (!left_type->Is(Type::String())) {
9623 ASSERT(right_type->Is(Type::String())); 9624 ASSERT(right_type->Is(Type::String()));
9624 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); 9625 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
9625 Add<HPushArgument>(left); 9626 Add<HPushArguments>(zone(), left, right);
9626 Add<HPushArgument>(right);
9627 return AddUncasted<HInvokeFunction>(function, 2); 9627 return AddUncasted<HInvokeFunction>(function, 2);
9628 } 9628 }
9629 9629
9630 // Convert right argument as necessary. 9630 // Convert right argument as necessary.
9631 if (right_type->Is(Type::Number())) { 9631 if (right_type->Is(Type::Number())) {
9632 ASSERT(left_type->Is(Type::String())); 9632 ASSERT(left_type->Is(Type::String()));
9633 right = BuildNumberToString(right, right_type); 9633 right = BuildNumberToString(right, right_type);
9634 } else if (!right_type->Is(Type::String())) { 9634 } else if (!right_type->Is(Type::String())) {
9635 ASSERT(left_type->Is(Type::String())); 9635 ASSERT(left_type->Is(Type::String()));
9636 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 9636 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
9637 Add<HPushArgument>(left); 9637 Add<HPushArguments>(zone(), left, right);
9638 Add<HPushArgument>(right);
9639 return AddUncasted<HInvokeFunction>(function, 2); 9638 return AddUncasted<HInvokeFunction>(function, 2);
9640 } 9639 }
9641 9640
9642 // Fast path for empty constant strings. 9641 // Fast path for empty constant strings.
9643 if (left->IsConstant() && 9642 if (left->IsConstant() &&
9644 HConstant::cast(left)->HasStringValue() && 9643 HConstant::cast(left)->HasStringValue() &&
9645 HConstant::cast(left)->StringValue()->length() == 0) { 9644 HConstant::cast(left)->StringValue()->length() == 0) {
9646 return right; 9645 return right;
9647 } 9646 }
9648 if (right->IsConstant() && 9647 if (right->IsConstant() &&
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
9690 9689
9691 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 9690 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) ||
9692 (right_rep.IsTagged() && !right_rep.IsSmi()); 9691 (right_rep.IsTagged() && !right_rep.IsSmi());
9693 9692
9694 HInstruction* instr = NULL; 9693 HInstruction* instr = NULL;
9695 // Only the stub is allowed to call into the runtime, since otherwise we would 9694 // Only the stub is allowed to call into the runtime, since otherwise we would
9696 // inline several instructions (including the two pushes) for every tagged 9695 // inline several instructions (including the two pushes) for every tagged
9697 // operation in optimized code, which is more expensive, than a stub call. 9696 // operation in optimized code, which is more expensive, than a stub call.
9698 if (graph()->info()->IsStub() && is_non_primitive) { 9697 if (graph()->info()->IsStub() && is_non_primitive) {
9699 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); 9698 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op));
9700 Add<HPushArgument>(left); 9699 Add<HPushArguments>(zone(), left, right);
9701 Add<HPushArgument>(right);
9702 instr = AddUncasted<HInvokeFunction>(function, 2); 9700 instr = AddUncasted<HInvokeFunction>(function, 2);
9703 } else { 9701 } else {
9704 switch (op) { 9702 switch (op) {
9705 case Token::ADD: 9703 case Token::ADD:
9706 instr = AddUncasted<HAdd>(left, right); 9704 instr = AddUncasted<HAdd>(left, right);
9707 break; 9705 break;
9708 case Token::SUB: 9706 case Token::SUB:
9709 instr = AddUncasted<HSub>(left, right); 9707 instr = AddUncasted<HSub>(left, right);
9710 break; 9708 break;
9711 case Token::MUL: 9709 case Token::MUL:
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
10055 Add<HCheckValue>(right, target); 10053 Add<HCheckValue>(right, target);
10056 HInstanceOfKnownGlobal* result = 10054 HInstanceOfKnownGlobal* result =
10057 New<HInstanceOfKnownGlobal>(left, target); 10055 New<HInstanceOfKnownGlobal>(left, target);
10058 return ast_context()->ReturnInstruction(result, expr->id()); 10056 return ast_context()->ReturnInstruction(result, expr->id());
10059 } 10057 }
10060 10058
10061 // Code below assumes that we don't fall through. 10059 // Code below assumes that we don't fall through.
10062 UNREACHABLE(); 10060 UNREACHABLE();
10063 } else if (op == Token::IN) { 10061 } else if (op == Token::IN) {
10064 HValue* function = AddLoadJSBuiltin(Builtins::IN); 10062 HValue* function = AddLoadJSBuiltin(Builtins::IN);
10065 Add<HPushArgument>(left); 10063 Add<HPushArguments>(zone(), left, right);
10066 Add<HPushArgument>(right);
10067 // TODO(olivf) InvokeFunction produces a check for the parameter count, 10064 // TODO(olivf) InvokeFunction produces a check for the parameter count,
10068 // even though we are certain to pass the correct number of arguments here. 10065 // even though we are certain to pass the correct number of arguments here.
10069 HInstruction* result = New<HInvokeFunction>(function, 2); 10066 HInstruction* result = New<HInvokeFunction>(function, 2);
10070 return ast_context()->ReturnInstruction(result, expr->id()); 10067 return ast_context()->ReturnInstruction(result, expr->id());
10071 } 10068 }
10072 10069
10073 PushBeforeSimulateBehavior push_behavior = 10070 PushBeforeSimulateBehavior push_behavior =
10074 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 10071 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE
10075 : PUSH_BEFORE_SIMULATE; 10072 : PUSH_BEFORE_SIMULATE;
10076 HControlInstruction* compare = BuildCompareInstruction( 10073 HControlInstruction* compare = BuildCompareInstruction(
(...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after
11814 if (ShouldProduceTraceOutput()) { 11811 if (ShouldProduceTraceOutput()) {
11815 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11812 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11816 } 11813 }
11817 11814
11818 #ifdef DEBUG 11815 #ifdef DEBUG
11819 graph_->Verify(false); // No full verify. 11816 graph_->Verify(false); // No full verify.
11820 #endif 11817 #endif
11821 } 11818 }
11822 11819
11823 } } // namespace v8::internal 11820 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs-hydrogen.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698