OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |