OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3539 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, | 3539 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, |
3540 CompilationInfo* info, | 3540 CompilationInfo* info, |
3541 InliningKind inlining_kind) | 3541 InliningKind inlining_kind) |
3542 : owner_(owner), | 3542 : owner_(owner), |
3543 compilation_info_(info), | 3543 compilation_info_(info), |
3544 call_context_(NULL), | 3544 call_context_(NULL), |
3545 inlining_kind_(inlining_kind), | 3545 inlining_kind_(inlining_kind), |
3546 function_return_(NULL), | 3546 function_return_(NULL), |
3547 test_context_(NULL), | 3547 test_context_(NULL), |
3548 entry_(NULL), | 3548 entry_(NULL), |
3549 arguments_object_(NULL), | |
3550 arguments_elements_(NULL), | 3549 arguments_elements_(NULL), |
3551 outer_(owner->function_state()) { | 3550 outer_(owner->function_state()) { |
3552 if (outer_ != NULL) { | 3551 if (outer_ != NULL) { |
3553 // State for an inline function. | 3552 // State for an inline function. |
3554 if (owner->ast_context()->IsTest()) { | 3553 if (owner->ast_context()->IsTest()) { |
3555 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); | 3554 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); |
3556 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); | 3555 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); |
3557 if_true->MarkAsInlineReturnTarget(owner->current_block()); | 3556 if_true->MarkAsInlineReturnTarget(owner->current_block()); |
3558 if_false->MarkAsInlineReturnTarget(owner->current_block()); | 3557 if_false->MarkAsInlineReturnTarget(owner->current_block()); |
3559 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); | 3558 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); |
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4691 return call; | 4690 return call; |
4692 } | 4691 } |
4693 | 4692 |
4694 | 4693 |
4695 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { | 4694 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
4696 HConstant* undefined_constant = new(zone()) HConstant( | 4695 HConstant* undefined_constant = new(zone()) HConstant( |
4697 isolate()->factory()->undefined_value(), Representation::Tagged()); | 4696 isolate()->factory()->undefined_value(), Representation::Tagged()); |
4698 AddInstruction(undefined_constant); | 4697 AddInstruction(undefined_constant); |
4699 graph()->set_undefined_constant(undefined_constant); | 4698 graph()->set_undefined_constant(undefined_constant); |
4700 | 4699 |
4701 // Create an arguments object containing the initial parameters. Set the | 4700 HArgumentsObject* object = new(zone()) HArgumentsObject; |
4702 // initial values of parameters including "this" having parameter index 0. | 4701 AddInstruction(object); |
| 4702 graph()->SetArgumentsObject(object); |
| 4703 |
| 4704 // Set the initial values of parameters including "this". "This" has |
| 4705 // parameter index 0. |
4703 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); | 4706 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
4704 HArgumentsObject* arguments_object = | 4707 |
4705 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); | |
4706 for (int i = 0; i < environment()->parameter_count(); ++i) { | 4708 for (int i = 0; i < environment()->parameter_count(); ++i) { |
4707 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); | 4709 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); |
4708 arguments_object->AddArgument(parameter, zone()); | |
4709 environment()->Bind(i, parameter); | 4710 environment()->Bind(i, parameter); |
4710 } | 4711 } |
4711 AddInstruction(arguments_object); | |
4712 graph()->SetArgumentsObject(arguments_object); | |
4713 | 4712 |
4714 // First special is HContext. | 4713 // First special is HContext. |
4715 HInstruction* context = AddInstruction(new(zone()) HContext); | 4714 HInstruction* context = AddInstruction(new(zone()) HContext); |
4716 environment()->BindContext(context); | 4715 environment()->BindContext(context); |
4717 | 4716 |
4718 // Initialize specials and locals to undefined. | 4717 // Initialize specials and locals to undefined. |
4719 for (int i = environment()->parameter_count() + 1; | 4718 for (int i = environment()->parameter_count() + 1; |
4720 i < environment()->length(); | 4719 i < environment()->length(); |
4721 ++i) { | 4720 ++i) { |
4722 environment()->Bind(i, undefined_constant); | 4721 environment()->Bind(i, undefined_constant); |
(...skipping 2699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7422 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { | 7421 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { |
7423 // Outermost function already has arguments on the stack. | 7422 // Outermost function already has arguments on the stack. |
7424 if (function_state()->outer() == NULL) return; | 7423 if (function_state()->outer() == NULL) return; |
7425 | 7424 |
7426 if (function_state()->arguments_pushed()) return; | 7425 if (function_state()->arguments_pushed()) return; |
7427 | 7426 |
7428 // Push arguments when entering inlined function. | 7427 // Push arguments when entering inlined function. |
7429 HEnterInlined* entry = function_state()->entry(); | 7428 HEnterInlined* entry = function_state()->entry(); |
7430 entry->set_arguments_pushed(); | 7429 entry->set_arguments_pushed(); |
7431 | 7430 |
7432 HArgumentsObject* arguments = entry->arguments_object(); | 7431 ZoneList<HValue*>* arguments_values = entry->arguments_values(); |
7433 const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); | |
7434 | 7432 |
7435 HInstruction* insert_after = entry; | 7433 HInstruction* insert_after = entry; |
7436 for (int i = 0; i < arguments_values->length(); i++) { | 7434 for (int i = 0; i < arguments_values->length(); i++) { |
7437 HValue* argument = arguments_values->at(i); | 7435 HValue* argument = arguments_values->at(i); |
7438 HInstruction* push_argument = new(zone()) HPushArgument(argument); | 7436 HInstruction* push_argument = new(zone()) HPushArgument(argument); |
7439 push_argument->InsertAfter(insert_after); | 7437 push_argument->InsertAfter(insert_after); |
7440 insert_after = push_argument; | 7438 insert_after = push_argument; |
7441 } | 7439 } |
7442 | 7440 |
7443 HArgumentsElements* arguments_elements = | 7441 HArgumentsElements* arguments_elements = |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8024 // can remove the unsightly ifdefs in this function. | 8022 // can remove the unsightly ifdefs in this function. |
8025 HConstant* context = | 8023 HConstant* context = |
8026 new(zone()) HConstant(Handle<Context>(target->context()), | 8024 new(zone()) HConstant(Handle<Context>(target->context()), |
8027 Representation::Tagged()); | 8025 Representation::Tagged()); |
8028 AddInstruction(context); | 8026 AddInstruction(context); |
8029 inner_env->BindContext(context); | 8027 inner_env->BindContext(context); |
8030 #endif | 8028 #endif |
8031 | 8029 |
8032 AddSimulate(return_id); | 8030 AddSimulate(return_id); |
8033 current_block()->UpdateEnvironment(inner_env); | 8031 current_block()->UpdateEnvironment(inner_env); |
8034 HArgumentsObject* arguments_object = NULL; | 8032 ZoneList<HValue*>* arguments_values = NULL; |
8035 | 8033 |
8036 // If the function uses arguments object create and bind one, also copy | 8034 // If the function uses arguments copy current arguments values |
8037 // current arguments values to use them for materialization. | 8035 // to use them for materialization. |
8038 if (function->scope()->arguments() != NULL) { | 8036 if (function->scope()->arguments() != NULL) { |
8039 ASSERT(function->scope()->arguments()->IsStackAllocated()); | |
8040 HEnvironment* arguments_env = inner_env->arguments_environment(); | 8037 HEnvironment* arguments_env = inner_env->arguments_environment(); |
8041 int arguments_count = arguments_env->parameter_count(); | 8038 int arguments_count = arguments_env->parameter_count(); |
8042 arguments_object = new(zone()) HArgumentsObject(arguments_count, zone()); | 8039 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
8043 inner_env->Bind(function->scope()->arguments(), arguments_object); | |
8044 for (int i = 0; i < arguments_count; i++) { | 8040 for (int i = 0; i < arguments_count; i++) { |
8045 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); | 8041 arguments_values->Add(arguments_env->Lookup(i), zone()); |
8046 } | 8042 } |
8047 AddInstruction(arguments_object); | |
8048 } | 8043 } |
8049 | 8044 |
8050 HEnterInlined* enter_inlined = | 8045 HEnterInlined* enter_inlined = |
8051 new(zone()) HEnterInlined(target, | 8046 new(zone()) HEnterInlined(target, |
8052 arguments_count, | 8047 arguments_count, |
8053 function, | 8048 function, |
8054 function_state()->inlining_kind(), | 8049 function_state()->inlining_kind(), |
8055 function->scope()->arguments(), | 8050 function->scope()->arguments(), |
8056 arguments_object, | 8051 arguments_values, |
8057 undefined_receiver, | 8052 undefined_receiver, |
8058 zone()); | 8053 zone()); |
8059 function_state()->set_entry(enter_inlined); | 8054 function_state()->set_entry(enter_inlined); |
8060 AddInstruction(enter_inlined); | 8055 AddInstruction(enter_inlined); |
8061 | 8056 |
| 8057 // If the function uses arguments object create and bind one. |
| 8058 if (function->scope()->arguments() != NULL) { |
| 8059 ASSERT(function->scope()->arguments()->IsStackAllocated()); |
| 8060 inner_env->Bind(function->scope()->arguments(), |
| 8061 graph()->GetArgumentsObject()); |
| 8062 } |
| 8063 |
| 8064 |
8062 VisitDeclarations(target_info.scope()->declarations()); | 8065 VisitDeclarations(target_info.scope()->declarations()); |
8063 VisitStatements(function->body()); | 8066 VisitStatements(function->body()); |
8064 if (HasStackOverflow()) { | 8067 if (HasStackOverflow()) { |
8065 // Bail out if the inline function did, as we cannot residualize a call | 8068 // Bail out if the inline function did, as we cannot residualize a call |
8066 // instead. | 8069 // instead. |
8067 TraceInline(target, caller, "inline graph construction failed"); | 8070 TraceInline(target, caller, "inline graph construction failed"); |
8068 target_shared->DisableOptimization("inlining bailed out"); | 8071 target_shared->DisableOptimization("inlining bailed out"); |
8069 inline_bailout_ = true; | 8072 inline_bailout_ = true; |
8070 delete target_state; | 8073 delete target_state; |
8071 return true; | 8074 return true; |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8483 new(zone()) HApplyArguments(function, | 8486 new(zone()) HApplyArguments(function, |
8484 wrapped_receiver, | 8487 wrapped_receiver, |
8485 length, | 8488 length, |
8486 elements); | 8489 elements); |
8487 result->set_position(expr->position()); | 8490 result->set_position(expr->position()); |
8488 ast_context()->ReturnInstruction(result, expr->id()); | 8491 ast_context()->ReturnInstruction(result, expr->id()); |
8489 return true; | 8492 return true; |
8490 } else { | 8493 } else { |
8491 // We are inside inlined function and we know exactly what is inside | 8494 // We are inside inlined function and we know exactly what is inside |
8492 // arguments object. But we need to be able to materialize at deopt. | 8495 // arguments object. But we need to be able to materialize at deopt. |
| 8496 // TODO(mstarzinger): For now we just ensure arguments are pushed |
| 8497 // right after HEnterInlined, but we could be smarter about this. |
| 8498 EnsureArgumentsArePushedForAccess(); |
8493 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), | 8499 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), |
8494 function_state()->entry()->arguments_object()->arguments_count()); | 8500 function_state()->entry()->arguments_values()->length()); |
8495 HArgumentsObject* args = function_state()->entry()->arguments_object(); | 8501 HEnterInlined* entry = function_state()->entry(); |
8496 const ZoneList<HValue*>* arguments_values = args->arguments_values(); | 8502 ZoneList<HValue*>* arguments_values = entry->arguments_values(); |
8497 int arguments_count = arguments_values->length(); | 8503 int arguments_count = arguments_values->length(); |
8498 PushAndAdd(new(zone()) HWrapReceiver(receiver, function)); | 8504 PushAndAdd(new(zone()) HWrapReceiver(receiver, function)); |
8499 for (int i = 1; i < arguments_count; i++) { | 8505 for (int i = 1; i < arguments_count; i++) { |
8500 Push(arguments_values->at(i)); | 8506 Push(arguments_values->at(i)); |
8501 } | 8507 } |
8502 | 8508 |
8503 Handle<JSFunction> known_function; | 8509 Handle<JSFunction> known_function; |
8504 if (function->IsConstant()) { | 8510 if (function->IsConstant()) { |
8505 HConstant* constant_function = HConstant::cast(function); | 8511 HConstant* constant_function = HConstant::cast(function); |
8506 known_function = Handle<JSFunction>::cast(constant_function->handle()); | 8512 known_function = Handle<JSFunction>::cast(constant_function->handle()); |
(...skipping 2494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11001 | 11007 |
11002 HEnvironment::HEnvironment(HEnvironment* outer, | 11008 HEnvironment::HEnvironment(HEnvironment* outer, |
11003 Handle<JSFunction> closure, | 11009 Handle<JSFunction> closure, |
11004 FrameType frame_type, | 11010 FrameType frame_type, |
11005 int arguments, | 11011 int arguments, |
11006 Zone* zone) | 11012 Zone* zone) |
11007 : closure_(closure), | 11013 : closure_(closure), |
11008 values_(arguments, zone), | 11014 values_(arguments, zone), |
11009 frame_type_(frame_type), | 11015 frame_type_(frame_type), |
11010 parameter_count_(arguments), | 11016 parameter_count_(arguments), |
11011 specials_count_(0), | |
11012 local_count_(0), | 11017 local_count_(0), |
11013 outer_(outer), | 11018 outer_(outer), |
11014 entry_(NULL), | 11019 entry_(NULL), |
11015 pop_count_(0), | 11020 pop_count_(0), |
11016 push_count_(0), | 11021 push_count_(0), |
11017 ast_id_(BailoutId::None()), | 11022 ast_id_(BailoutId::None()), |
11018 zone_(zone) { | 11023 zone_(zone) { |
11019 } | 11024 } |
11020 | 11025 |
11021 | 11026 |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11617 } | 11622 } |
11618 } | 11623 } |
11619 | 11624 |
11620 #ifdef DEBUG | 11625 #ifdef DEBUG |
11621 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11626 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11622 if (allocator_ != NULL) allocator_->Verify(); | 11627 if (allocator_ != NULL) allocator_->Verify(); |
11623 #endif | 11628 #endif |
11624 } | 11629 } |
11625 | 11630 |
11626 } } // namespace v8::internal | 11631 } } // namespace v8::internal |
OLD | NEW |