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

Side by Side Diff: src/hydrogen.cc

Issue 7274020: Better placement of argument pushing for a few hydrogen call instructions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 5 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/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2172 2172
2173 2173
2174 void HGraphBuilder::VisitForControl(Expression* expr, 2174 void HGraphBuilder::VisitForControl(Expression* expr,
2175 HBasicBlock* true_block, 2175 HBasicBlock* true_block,
2176 HBasicBlock* false_block) { 2176 HBasicBlock* false_block) {
2177 TestContext for_test(this, expr, true_block, false_block); 2177 TestContext for_test(this, expr, true_block, false_block);
2178 Visit(expr); 2178 Visit(expr);
2179 } 2179 }
2180 2180
2181 2181
2182 void HGraphBuilder::VisitArgument(Expression* expr) { 2182 HValue* HGraphBuilder::VisitArgument(Expression* expr) {
2183 CHECK_ALIVE(VisitForValue(expr)); 2183 VisitForValue(expr);
2184 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); 2184 if (HasStackOverflow() || current_block() == NULL) return NULL;
2185 HValue* value = Pop();
2186 Push(AddInstruction(new(zone()) HPushArgument(value)));
2187 return value;
2185 } 2188 }
2186 2189
2187 2190
2188 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { 2191 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) {
2189 for (int i = 0; i < arguments->length(); i++) { 2192 for (int i = 0; i < arguments->length(); i++) {
2190 CHECK_ALIVE(VisitArgument(arguments->at(i))); 2193 CHECK_ALIVE(VisitArgument(arguments->at(i)));
2191 } 2194 }
2192 } 2195 }
2193 2196
2194 2197
(...skipping 2489 matching lines...) Expand 10 before | Expand all | Expand 10 after
4684 ASSERT(current_block() != NULL); 4687 ASSERT(current_block() != NULL);
4685 ASSERT(current_block()->HasPredecessor()); 4688 ASSERT(current_block()->HasPredecessor());
4686 Expression* callee = expr->expression(); 4689 Expression* callee = expr->expression();
4687 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4690 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4688 HInstruction* call = NULL; 4691 HInstruction* call = NULL;
4689 4692
4690 Property* prop = callee->AsProperty(); 4693 Property* prop = callee->AsProperty();
4691 if (prop != NULL) { 4694 if (prop != NULL) {
4692 if (!prop->key()->IsPropertyName()) { 4695 if (!prop->key()->IsPropertyName()) {
4693 // Keyed function call. 4696 // Keyed function call.
4694 CHECK_ALIVE(VisitForValue(prop->obj())); 4697 CHECK_ALIVE(VisitArgument(prop->obj()));
4695 4698
4696 CHECK_ALIVE(VisitForValue(prop->key())); 4699 CHECK_ALIVE(VisitForValue(prop->key()));
4697 // Push receiver and key like the non-optimized code generator expects it. 4700 // Push receiver and key like the non-optimized code generator expects it.
4698 HValue* key = Pop(); 4701 HValue* key = Pop();
4699 HValue* receiver = Pop(); 4702 HValue* receiver = Pop();
4700 Push(key); 4703 Push(key);
4701 Push(receiver); 4704 Push(receiver);
4702 4705
4703 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4706 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4704 4707
4705 HValue* context = environment()->LookupContext(); 4708 HValue* context = environment()->LookupContext();
4706 call = PreProcessCall( 4709 call = new(zone()) HCallKeyed(context, key, argument_count);
4707 new(zone()) HCallKeyed(context, key, argument_count));
4708 call->set_position(expr->position()); 4710 call->set_position(expr->position());
4709 Drop(1); // Key. 4711 Drop(argument_count + 1); // 1 is the key.
4710 ast_context()->ReturnInstruction(call, expr->id()); 4712 ast_context()->ReturnInstruction(call, expr->id());
4711 return; 4713 return;
4712 } 4714 }
4713 4715
4714 // Named function call. 4716 // Named function call.
4715 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 4717 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
4716 4718
4717 if (TryCallApply(expr)) return; 4719 if (TryCallApply(expr)) return;
4718 4720
4719 CHECK_ALIVE(VisitForValue(prop->obj())); 4721 CHECK_ALIVE(VisitForValue(prop->obj()));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4759 } else { 4761 } else {
4760 HValue* context = environment()->LookupContext(); 4762 HValue* context = environment()->LookupContext();
4761 call = PreProcessCall( 4763 call = PreProcessCall(
4762 new(zone()) HCallNamed(context, name, argument_count)); 4764 new(zone()) HCallNamed(context, name, argument_count));
4763 } 4765 }
4764 4766
4765 } else { 4767 } else {
4766 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4768 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4767 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); 4769 bool global_call = (var != NULL) && var->is_global() && !var->is_this();
4768 4770
4769 if (!global_call) {
4770 ++argument_count;
4771 CHECK_ALIVE(VisitForValue(expr->expression()));
4772 }
4773
4774 if (global_call) { 4771 if (global_call) {
4775 bool known_global_function = false; 4772 bool known_global_function = false;
4776 // If there is a global property cell for the name at compile time and 4773 // If there is a global property cell for the name at compile time and
4777 // access check is not enabled we assume that the function will not change 4774 // access check is not enabled we assume that the function will not change
4778 // and generate optimized code for calling the function. 4775 // and generate optimized code for calling the function.
4779 LookupResult lookup; 4776 LookupResult lookup;
4780 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); 4777 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
4781 if (type == kUseCell && 4778 if (type == kUseCell &&
4782 !info()->global_object()->IsAccessCheckNeeded()) { 4779 !info()->global_object()->IsAccessCheckNeeded()) {
4783 Handle<GlobalObject> global(info()->global_object()); 4780 Handle<GlobalObject> global(info()->global_object());
(...skipping 19 matching lines...) Expand all
4803 AddInstruction(global_receiver); 4800 AddInstruction(global_receiver);
4804 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4801 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4805 IsGlobalObject()); 4802 IsGlobalObject());
4806 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4803 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4807 4804
4808 if (TryInline(expr)) return; 4805 if (TryInline(expr)) return;
4809 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 4806 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
4810 argument_count)); 4807 argument_count));
4811 } else { 4808 } else {
4812 HValue* context = environment()->LookupContext(); 4809 HValue* context = environment()->LookupContext();
4813 PushAndAdd(new(zone()) HGlobalObject(context)); 4810 HGlobalObject* receiver = new(zone()) HGlobalObject(context);
4814 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4811 AddInstruction(receiver);
4812 PushAndAdd(new(zone()) HPushArgument(receiver));
4813 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4815 4814
4816 call = PreProcessCall(new(zone()) HCallGlobal(context, 4815 call = new(zone()) HCallGlobal(context, var->name(), argument_count);
4817 var->name(), 4816 Drop(argument_count);
4818 argument_count));
4819 } 4817 }
4820 4818
4821 } else { 4819 } else {
4820 CHECK_ALIVE(VisitArgument(expr->expression()));
4822 HValue* context = environment()->LookupContext(); 4821 HValue* context = environment()->LookupContext();
4823 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 4822 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4823 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object);
4824 AddInstruction(global_object); 4824 AddInstruction(global_object);
4825 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); 4825 AddInstruction(receiver);
4826 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4826 PushAndAdd(new(zone()) HPushArgument(receiver));
4827 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4827 4828
4828 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); 4829 // The function to call is treated as an argument to the call function
4830 // stub.
4831 call = new(zone()) HCallFunction(context, argument_count + 1);
4832 Drop(argument_count + 1);
4829 } 4833 }
4830 } 4834 }
4831 4835
4832 call->set_position(expr->position()); 4836 call->set_position(expr->position());
4833 ast_context()->ReturnInstruction(call, expr->id()); 4837 ast_context()->ReturnInstruction(call, expr->id());
4834 } 4838 }
4835 4839
4836 4840
4837 void HGraphBuilder::VisitCallNew(CallNew* expr) { 4841 void HGraphBuilder::VisitCallNew(CallNew* expr) {
4838 ASSERT(!HasStackOverflow()); 4842 ASSERT(!HasStackOverflow());
4839 ASSERT(current_block() != NULL); 4843 ASSERT(current_block() != NULL);
4840 ASSERT(current_block()->HasPredecessor()); 4844 ASSERT(current_block()->HasPredecessor());
4841 // The constructor function is also used as the receiver argument to the 4845 // The constructor function is also used as the receiver argument to the
4842 // JS construct call builtin. 4846 // JS construct call builtin.
4843 CHECK_ALIVE(VisitForValue(expr->expression())); 4847 HValue* constructor = NULL;
4844 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4848 CHECK_ALIVE(constructor = VisitArgument(expr->expression()));
Kevin Millikin (Chromium) 2011/06/28 10:51:29 I realize this is kind of ugly. Feel free to sugg
4849 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4845 4850
4846 HValue* context = environment()->LookupContext(); 4851 HValue* context = environment()->LookupContext();
4847 4852
4848 // The constructor is both an operand to the instruction and an argument 4853 // The constructor is both an operand to the instruction and an argument
4849 // to the construct call. 4854 // to the construct call.
4850 int arg_count = expr->arguments()->length() + 1; // Plus constructor. 4855 int arg_count = expr->arguments()->length() + 1; // Plus constructor.
4851 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
4852 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); 4856 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count);
4853 call->set_position(expr->position()); 4857 call->set_position(expr->position());
4854 PreProcessCall(call); 4858 Drop(arg_count);
4855 ast_context()->ReturnInstruction(call, expr->id()); 4859 ast_context()->ReturnInstruction(call, expr->id());
4856 } 4860 }
4857 4861
4858 4862
4859 // Support for generating inlined runtime functions. 4863 // Support for generating inlined runtime functions.
4860 4864
4861 // Lookup table for generators for runtime calls that are generated inline. 4865 // Lookup table for generators for runtime calls that are generated inline.
4862 // Elements of the table are member pointers to functions of HGraphBuilder. 4866 // Elements of the table are member pointers to functions of HGraphBuilder.
4863 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 4867 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
4864 &HGraphBuilder::Generate##Name, 4868 &HGraphBuilder::Generate##Name,
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after
6573 } 6577 }
6574 } 6578 }
6575 6579
6576 #ifdef DEBUG 6580 #ifdef DEBUG
6577 if (graph_ != NULL) graph_->Verify(); 6581 if (graph_ != NULL) graph_->Verify();
6578 if (allocator_ != NULL) allocator_->Verify(); 6582 if (allocator_ != NULL) allocator_->Verify();
6579 #endif 6583 #endif
6580 } 6584 }
6581 6585
6582 } } // namespace v8::internal 6586 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698