| 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 2247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4442 ASSERT(target_shared->has_deoptimization_support()); | 4445 ASSERT(target_shared->has_deoptimization_support()); |
| 4443 TypeFeedbackOracle target_oracle( | 4446 TypeFeedbackOracle target_oracle( |
| 4444 Handle<Code>(target_shared->code()), | 4447 Handle<Code>(target_shared->code()), |
| 4445 Handle<Context>(target->context()->global_context())); | 4448 Handle<Context>(target->context()->global_context())); |
| 4446 FunctionState target_state(this, &target_info, &target_oracle); | 4449 FunctionState target_state(this, &target_info, &target_oracle); |
| 4447 | 4450 |
| 4448 HConstant* undefined = graph()->GetConstantUndefined(); | 4451 HConstant* undefined = graph()->GetConstantUndefined(); |
| 4449 HEnvironment* inner_env = | 4452 HEnvironment* inner_env = |
| 4450 environment()->CopyForInlining(target, | 4453 environment()->CopyForInlining(target, |
| 4451 function, | 4454 function, |
| 4452 HEnvironment::HYDROGEN, | |
| 4453 undefined, | 4455 undefined, |
| 4454 call_kind); | 4456 call_kind); |
| 4455 HBasicBlock* body_entry = CreateBasicBlock(inner_env); | 4457 HBasicBlock* body_entry = CreateBasicBlock(inner_env); |
| 4456 current_block()->Goto(body_entry); | 4458 current_block()->Goto(body_entry); |
| 4457 body_entry->SetJoinId(expr->ReturnId()); | 4459 body_entry->SetJoinId(expr->ReturnId()); |
| 4458 set_current_block(body_entry); | 4460 set_current_block(body_entry); |
| 4459 AddInstruction(new(zone()) HEnterInlined(target, | 4461 AddInstruction(new(zone()) HEnterInlined(target, |
| 4460 function, | 4462 function, |
| 4461 call_kind)); | 4463 call_kind)); |
| 4462 VisitDeclarations(target_info.scope()->declarations()); | 4464 VisitDeclarations(target_info.scope()->declarations()); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4685 ASSERT(current_block() != NULL); | 4687 ASSERT(current_block() != NULL); |
| 4686 ASSERT(current_block()->HasPredecessor()); | 4688 ASSERT(current_block()->HasPredecessor()); |
| 4687 Expression* callee = expr->expression(); | 4689 Expression* callee = expr->expression(); |
| 4688 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 4690 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 4689 HInstruction* call = NULL; | 4691 HInstruction* call = NULL; |
| 4690 | 4692 |
| 4691 Property* prop = callee->AsProperty(); | 4693 Property* prop = callee->AsProperty(); |
| 4692 if (prop != NULL) { | 4694 if (prop != NULL) { |
| 4693 if (!prop->key()->IsPropertyName()) { | 4695 if (!prop->key()->IsPropertyName()) { |
| 4694 // Keyed function call. | 4696 // Keyed function call. |
| 4695 CHECK_ALIVE(VisitForValue(prop->obj())); | 4697 CHECK_ALIVE(VisitArgument(prop->obj())); |
| 4696 | 4698 |
| 4697 CHECK_ALIVE(VisitForValue(prop->key())); | 4699 CHECK_ALIVE(VisitForValue(prop->key())); |
| 4698 // 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. |
| 4699 HValue* key = Pop(); | 4701 HValue* key = Pop(); |
| 4700 HValue* receiver = Pop(); | 4702 HValue* receiver = Pop(); |
| 4701 Push(key); | 4703 Push(key); |
| 4702 Push(receiver); | 4704 Push(receiver); |
| 4703 | 4705 |
| 4704 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4706 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 4705 | 4707 |
| 4706 HValue* context = environment()->LookupContext(); | 4708 HValue* context = environment()->LookupContext(); |
| 4707 call = PreProcessCall( | 4709 call = new(zone()) HCallKeyed(context, key, argument_count); |
| 4708 new(zone()) HCallKeyed(context, key, argument_count)); | |
| 4709 call->set_position(expr->position()); | 4710 call->set_position(expr->position()); |
| 4710 Drop(1); // Key. | 4711 Drop(argument_count + 1); // 1 is the key. |
| 4711 ast_context()->ReturnInstruction(call, expr->id()); | 4712 ast_context()->ReturnInstruction(call, expr->id()); |
| 4712 return; | 4713 return; |
| 4713 } | 4714 } |
| 4714 | 4715 |
| 4715 // Named function call. | 4716 // Named function call. |
| 4716 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); | 4717 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); |
| 4717 | 4718 |
| 4718 if (TryCallApply(expr)) return; | 4719 if (TryCallApply(expr)) return; |
| 4719 | 4720 |
| 4720 CHECK_ALIVE(VisitForValue(prop->obj())); | 4721 CHECK_ALIVE(VisitForValue(prop->obj())); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4760 } else { | 4761 } else { |
| 4761 HValue* context = environment()->LookupContext(); | 4762 HValue* context = environment()->LookupContext(); |
| 4762 call = PreProcessCall( | 4763 call = PreProcessCall( |
| 4763 new(zone()) HCallNamed(context, name, argument_count)); | 4764 new(zone()) HCallNamed(context, name, argument_count)); |
| 4764 } | 4765 } |
| 4765 | 4766 |
| 4766 } else { | 4767 } else { |
| 4767 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 4768 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 4768 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); | 4769 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); |
| 4769 | 4770 |
| 4770 if (!global_call) { | |
| 4771 ++argument_count; | |
| 4772 CHECK_ALIVE(VisitForValue(expr->expression())); | |
| 4773 } | |
| 4774 | |
| 4775 if (global_call) { | 4771 if (global_call) { |
| 4776 bool known_global_function = false; | 4772 bool known_global_function = false; |
| 4777 // 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 |
| 4778 // 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 |
| 4779 // and generate optimized code for calling the function. | 4775 // and generate optimized code for calling the function. |
| 4780 LookupResult lookup; | 4776 LookupResult lookup; |
| 4781 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 4777 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
| 4782 if (type == kUseCell && | 4778 if (type == kUseCell && |
| 4783 !info()->global_object()->IsAccessCheckNeeded()) { | 4779 !info()->global_object()->IsAccessCheckNeeded()) { |
| 4784 Handle<GlobalObject> global(info()->global_object()); | 4780 Handle<GlobalObject> global(info()->global_object()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4804 AddInstruction(global_receiver); | 4800 AddInstruction(global_receiver); |
| 4805 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 4801 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
| 4806 IsGlobalObject()); | 4802 IsGlobalObject()); |
| 4807 environment()->SetExpressionStackAt(receiver_index, global_receiver); | 4803 environment()->SetExpressionStackAt(receiver_index, global_receiver); |
| 4808 | 4804 |
| 4809 if (TryInline(expr)) return; | 4805 if (TryInline(expr)) return; |
| 4810 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 4806 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
| 4811 argument_count)); | 4807 argument_count)); |
| 4812 } else { | 4808 } else { |
| 4813 HValue* context = environment()->LookupContext(); | 4809 HValue* context = environment()->LookupContext(); |
| 4814 PushAndAdd(new(zone()) HGlobalObject(context)); | 4810 HGlobalObject* receiver = new(zone()) HGlobalObject(context); |
| 4815 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4811 AddInstruction(receiver); |
| 4812 PushAndAdd(new(zone()) HPushArgument(receiver)); |
| 4813 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 4816 | 4814 |
| 4817 call = PreProcessCall(new(zone()) HCallGlobal(context, | 4815 call = new(zone()) HCallGlobal(context, var->name(), argument_count); |
| 4818 var->name(), | 4816 Drop(argument_count); |
| 4819 argument_count)); | |
| 4820 } | 4817 } |
| 4821 | 4818 |
| 4822 } else { | 4819 } else { |
| 4820 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 4823 HValue* context = environment()->LookupContext(); | 4821 HValue* context = environment()->LookupContext(); |
| 4824 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 4822 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 4823 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
| 4825 AddInstruction(global_object); | 4824 AddInstruction(global_object); |
| 4826 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); | 4825 AddInstruction(receiver); |
| 4827 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4826 PushAndAdd(new(zone()) HPushArgument(receiver)); |
| 4827 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 4828 | 4828 |
| 4829 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); |
| 4830 } | 4833 } |
| 4831 } | 4834 } |
| 4832 | 4835 |
| 4833 call->set_position(expr->position()); | 4836 call->set_position(expr->position()); |
| 4834 ast_context()->ReturnInstruction(call, expr->id()); | 4837 ast_context()->ReturnInstruction(call, expr->id()); |
| 4835 } | 4838 } |
| 4836 | 4839 |
| 4837 | 4840 |
| 4838 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 4841 void HGraphBuilder::VisitCallNew(CallNew* expr) { |
| 4839 ASSERT(!HasStackOverflow()); | 4842 ASSERT(!HasStackOverflow()); |
| 4840 ASSERT(current_block() != NULL); | 4843 ASSERT(current_block() != NULL); |
| 4841 ASSERT(current_block()->HasPredecessor()); | 4844 ASSERT(current_block()->HasPredecessor()); |
| 4842 // 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 |
| 4843 // JS construct call builtin. | 4846 // JS construct call builtin. |
| 4844 CHECK_ALIVE(VisitForValue(expr->expression())); | 4847 HValue* constructor = NULL; |
| 4845 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4848 CHECK_ALIVE(constructor = VisitArgument(expr->expression())); |
| 4849 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 4846 | 4850 |
| 4847 HValue* context = environment()->LookupContext(); | 4851 HValue* context = environment()->LookupContext(); |
| 4848 | 4852 |
| 4849 // 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 |
| 4850 // to the construct call. | 4854 // to the construct call. |
| 4851 int arg_count = expr->arguments()->length() + 1; // Plus constructor. | 4855 int arg_count = expr->arguments()->length() + 1; // Plus constructor. |
| 4852 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); | |
| 4853 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); | 4856 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); |
| 4854 call->set_position(expr->position()); | 4857 call->set_position(expr->position()); |
| 4855 PreProcessCall(call); | 4858 Drop(arg_count); |
| 4856 ast_context()->ReturnInstruction(call, expr->id()); | 4859 ast_context()->ReturnInstruction(call, expr->id()); |
| 4857 } | 4860 } |
| 4858 | 4861 |
| 4859 | 4862 |
| 4860 // Support for generating inlined runtime functions. | 4863 // Support for generating inlined runtime functions. |
| 4861 | 4864 |
| 4862 // Lookup table for generators for runtime calls that are generated inline. | 4865 // Lookup table for generators for runtime calls that are generated inline. |
| 4863 // Elements of the table are member pointers to functions of HGraphBuilder. | 4866 // Elements of the table are member pointers to functions of HGraphBuilder. |
| 4864 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ | 4867 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ |
| 4865 &HGraphBuilder::Generate##Name, | 4868 &HGraphBuilder::Generate##Name, |
| (...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6205 loop_header->AddPhi(phi); | 6208 loop_header->AddPhi(phi); |
| 6206 } | 6209 } |
| 6207 new_env->ClearHistory(); | 6210 new_env->ClearHistory(); |
| 6208 return new_env; | 6211 return new_env; |
| 6209 } | 6212 } |
| 6210 | 6213 |
| 6211 | 6214 |
| 6212 HEnvironment* HEnvironment::CopyForInlining( | 6215 HEnvironment* HEnvironment::CopyForInlining( |
| 6213 Handle<JSFunction> target, | 6216 Handle<JSFunction> target, |
| 6214 FunctionLiteral* function, | 6217 FunctionLiteral* function, |
| 6215 CompilationPhase compilation_phase, | |
| 6216 HConstant* undefined, | 6218 HConstant* undefined, |
| 6217 CallKind call_kind) const { | 6219 CallKind call_kind) const { |
| 6218 // Outer environment is a copy of this one without the arguments. | 6220 // Outer environment is a copy of this one without the arguments. |
| 6219 int arity = function->scope()->num_parameters(); | 6221 int arity = function->scope()->num_parameters(); |
| 6220 HEnvironment* outer = Copy(); | 6222 HEnvironment* outer = Copy(); |
| 6221 outer->Drop(arity + 1); // Including receiver. | 6223 outer->Drop(arity + 1); // Including receiver. |
| 6222 outer->ClearHistory(); | 6224 outer->ClearHistory(); |
| 6223 Zone* zone = closure()->GetIsolate()->zone(); | 6225 Zone* zone = closure()->GetIsolate()->zone(); |
| 6224 HEnvironment* inner = | 6226 HEnvironment* inner = |
| 6225 new(zone) HEnvironment(outer, function->scope(), target); | 6227 new(zone) HEnvironment(outer, function->scope(), target); |
| 6226 // Get the argument values from the original environment. | 6228 // Get the argument values from the original environment. |
| 6227 if (compilation_phase == HYDROGEN) { | 6229 for (int i = 0; i <= arity; ++i) { // Include receiver. |
| 6228 for (int i = 0; i <= arity; ++i) { // Include receiver. | 6230 HValue* push = ExpressionStackAt(arity - i); |
| 6229 HValue* push = ExpressionStackAt(arity - i); | 6231 inner->SetValueAt(i, push); |
| 6230 inner->SetValueAt(i, push); | |
| 6231 } | |
| 6232 } else { | |
| 6233 ASSERT(compilation_phase == LITHIUM); | |
| 6234 for (int i = 0; i <= arity; ++i) { // Include receiver. | |
| 6235 HValue* push = ExpressionStackAt(arity - i); | |
| 6236 inner->SetValueAt(i, push); | |
| 6237 } | |
| 6238 } | 6232 } |
| 6239 // If the function we are inlining is a strict mode function or a | 6233 // If the function we are inlining is a strict mode function or a |
| 6240 // builtin function, pass undefined as the receiver for function | 6234 // builtin function, pass undefined as the receiver for function |
| 6241 // calls (instead of the global receiver). | 6235 // calls (instead of the global receiver). |
| 6242 if ((target->shared()->native() || function->strict_mode()) && | 6236 if ((target->shared()->native() || function->strict_mode()) && |
| 6243 call_kind == CALL_AS_FUNCTION) { | 6237 call_kind == CALL_AS_FUNCTION) { |
| 6244 inner->SetValueAt(0, undefined); | 6238 inner->SetValueAt(0, undefined); |
| 6245 } | 6239 } |
| 6246 inner->SetValueAt(arity + 1, outer->LookupContext()); | 6240 inner->SetValueAt(arity + 1, outer->LookupContext()); |
| 6247 for (int i = arity + 2; i < inner->length(); ++i) { | 6241 for (int i = arity + 2; i < inner->length(); ++i) { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6583 } | 6577 } |
| 6584 } | 6578 } |
| 6585 | 6579 |
| 6586 #ifdef DEBUG | 6580 #ifdef DEBUG |
| 6587 if (graph_ != NULL) graph_->Verify(); | 6581 if (graph_ != NULL) graph_->Verify(); |
| 6588 if (allocator_ != NULL) allocator_->Verify(); | 6582 if (allocator_ != NULL) allocator_->Verify(); |
| 6589 #endif | 6583 #endif |
| 6590 } | 6584 } |
| 6591 | 6585 |
| 6592 } } // namespace v8::internal | 6586 } } // namespace v8::internal |
| OLD | NEW |