| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 | 121 |
| 122 HSimulate* HBasicBlock::CreateSimulate(int id) { | 122 HSimulate* HBasicBlock::CreateSimulate(int id) { |
| 123 ASSERT(HasEnvironment()); | 123 ASSERT(HasEnvironment()); |
| 124 HEnvironment* environment = last_environment(); | 124 HEnvironment* environment = last_environment(); |
| 125 ASSERT(id == AstNode::kNoNumber || | 125 ASSERT(id == AstNode::kNoNumber || |
| 126 environment->closure()->shared()->VerifyBailoutId(id)); | 126 environment->closure()->shared()->VerifyBailoutId(id)); |
| 127 | 127 |
| 128 int push_count = environment->push_count(); | 128 int push_count = environment->push_count(); |
| 129 int pop_count = environment->pop_count(); | 129 int pop_count = environment->pop_count(); |
| 130 | 130 |
| 131 int length = environment->values()->length(); | 131 int length = environment->length(); |
| 132 HSimulate* instr = new HSimulate(id, pop_count, length); | 132 HSimulate* instr = new HSimulate(id, pop_count, length); |
| 133 for (int i = push_count - 1; i >= 0; --i) { | 133 for (int i = push_count - 1; i >= 0; --i) { |
| 134 instr->AddPushedValue(environment->ExpressionStackAt(i)); | 134 instr->AddPushedValue(environment->ExpressionStackAt(i)); |
| 135 } | 135 } |
| 136 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { | 136 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { |
| 137 int index = environment->assigned_variables()->at(i); | 137 int index = environment->assigned_variables()->at(i); |
| 138 instr->AddAssignedValue(index, environment->Lookup(index)); | 138 instr->AddAssignedValue(index, environment->Lookup(index)); |
| 139 } | 139 } |
| 140 environment->ClearHistory(); | 140 environment->ClearHistory(); |
| 141 return instr; | 141 return instr; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 215 |
| 216 | 216 |
| 217 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { | 217 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { |
| 218 if (!predecessors_.is_empty()) { | 218 if (!predecessors_.is_empty()) { |
| 219 // Only loop header blocks can have a predecessor added after | 219 // Only loop header blocks can have a predecessor added after |
| 220 // instructions have been added to the block (they have phis for all | 220 // instructions have been added to the block (they have phis for all |
| 221 // values in the environment, these phis may be eliminated later). | 221 // values in the environment, these phis may be eliminated later). |
| 222 ASSERT(IsLoopHeader() || first_ == NULL); | 222 ASSERT(IsLoopHeader() || first_ == NULL); |
| 223 HEnvironment* incoming_env = pred->last_environment(); | 223 HEnvironment* incoming_env = pred->last_environment(); |
| 224 if (IsLoopHeader()) { | 224 if (IsLoopHeader()) { |
| 225 ASSERT(phis()->length() == incoming_env->values()->length()); | 225 ASSERT(phis()->length() == incoming_env->length()); |
| 226 for (int i = 0; i < phis_.length(); ++i) { | 226 for (int i = 0; i < phis_.length(); ++i) { |
| 227 phis_[i]->AddInput(incoming_env->values()->at(i)); | 227 phis_[i]->AddInput(incoming_env->values()->at(i)); |
| 228 } | 228 } |
| 229 } else { | 229 } else { |
| 230 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 230 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
| 231 } | 231 } |
| 232 } else if (!HasEnvironment() && !IsFinished()) { | 232 } else if (!HasEnvironment() && !IsFinished()) { |
| 233 ASSERT(!IsLoopHeader()); | 233 ASSERT(!IsLoopHeader()); |
| 234 SetInitialEnvironment(pred->last_environment()->Copy()); | 234 SetInitialEnvironment(pred->last_environment()->Copy()); |
| 235 } | 235 } |
| (...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 } | 1975 } |
| 1976 } | 1976 } |
| 1977 | 1977 |
| 1978 | 1978 |
| 1979 // Implementation of utility classes to represent an expression's context in | 1979 // Implementation of utility classes to represent an expression's context in |
| 1980 // the AST. | 1980 // the AST. |
| 1981 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) | 1981 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) |
| 1982 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { | 1982 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { |
| 1983 owner->set_ast_context(this); // Push. | 1983 owner->set_ast_context(this); // Push. |
| 1984 #ifdef DEBUG | 1984 #ifdef DEBUG |
| 1985 original_count_ = owner->environment()->total_count(); | 1985 original_length_ = owner->environment()->length(); |
| 1986 #endif | 1986 #endif |
| 1987 } | 1987 } |
| 1988 | 1988 |
| 1989 | 1989 |
| 1990 AstContext::~AstContext() { | 1990 AstContext::~AstContext() { |
| 1991 owner_->set_ast_context(outer_); // Pop. | 1991 owner_->set_ast_context(outer_); // Pop. |
| 1992 } | 1992 } |
| 1993 | 1993 |
| 1994 | 1994 |
| 1995 EffectContext::~EffectContext() { | 1995 EffectContext::~EffectContext() { |
| 1996 ASSERT(owner()->HasStackOverflow() || | 1996 ASSERT(owner()->HasStackOverflow() || |
| 1997 !owner()->subgraph()->HasExit() || | 1997 !owner()->subgraph()->HasExit() || |
| 1998 owner()->environment()->total_count() == original_count_); | 1998 owner()->environment()->length() == original_length_); |
| 1999 } | 1999 } |
| 2000 | 2000 |
| 2001 | 2001 |
| 2002 ValueContext::~ValueContext() { | 2002 ValueContext::~ValueContext() { |
| 2003 ASSERT(owner()->HasStackOverflow() || | 2003 ASSERT(owner()->HasStackOverflow() || |
| 2004 !owner()->subgraph()->HasExit() || | 2004 !owner()->subgraph()->HasExit() || |
| 2005 owner()->environment()->total_count() == original_count_ + 1); | 2005 owner()->environment()->length() == original_length_ + 1); |
| 2006 } | 2006 } |
| 2007 | 2007 |
| 2008 | 2008 |
| 2009 void EffectContext::ReturnValue(HValue* value) { | 2009 void EffectContext::ReturnValue(HValue* value) { |
| 2010 // The value is simply ignored. | 2010 // The value is simply ignored. |
| 2011 } | 2011 } |
| 2012 | 2012 |
| 2013 | 2013 |
| 2014 void ValueContext::ReturnValue(HValue* value) { | 2014 void ValueContext::ReturnValue(HValue* value) { |
| 2015 // The value is tracked in the bailout environment, and communicated | 2015 // The value is tracked in the bailout environment, and communicated |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2336 | 2336 |
| 2337 // Set the initial values of parameters including "this". "This" has | 2337 // Set the initial values of parameters including "this". "This" has |
| 2338 // parameter index 0. | 2338 // parameter index 0. |
| 2339 int count = scope->num_parameters() + 1; | 2339 int count = scope->num_parameters() + 1; |
| 2340 for (int i = 0; i < count; ++i) { | 2340 for (int i = 0; i < count; ++i) { |
| 2341 HInstruction* parameter = AddInstruction(new HParameter(i)); | 2341 HInstruction* parameter = AddInstruction(new HParameter(i)); |
| 2342 environment()->Bind(i, parameter); | 2342 environment()->Bind(i, parameter); |
| 2343 } | 2343 } |
| 2344 | 2344 |
| 2345 // Set the initial values of stack-allocated locals. | 2345 // Set the initial values of stack-allocated locals. |
| 2346 for (int i = count; i < environment()->values()->length(); ++i) { | 2346 for (int i = count; i < environment()->length(); ++i) { |
| 2347 environment()->Bind(i, undefined_constant); | 2347 environment()->Bind(i, undefined_constant); |
| 2348 } | 2348 } |
| 2349 | 2349 |
| 2350 // Handle the arguments and arguments shadow variables specially (they do | 2350 // Handle the arguments and arguments shadow variables specially (they do |
| 2351 // not have declarations). | 2351 // not have declarations). |
| 2352 if (scope->arguments() != NULL) { | 2352 if (scope->arguments() != NULL) { |
| 2353 HArgumentsObject* object = new HArgumentsObject; | 2353 HArgumentsObject* object = new HArgumentsObject; |
| 2354 AddInstruction(object); | 2354 AddInstruction(object); |
| 2355 graph()->SetArgumentsObject(object); | 2355 graph()->SetArgumentsObject(object); |
| 2356 environment()->Bind(scope->arguments(), object); | 2356 environment()->Bind(scope->arguments(), object); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2695 HValue* true_value = graph()->GetConstantTrue(); | 2695 HValue* true_value = graph()->GetConstantTrue(); |
| 2696 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value); | 2696 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value); |
| 2697 exit_block()->Finish(branch); | 2697 exit_block()->Finish(branch); |
| 2698 | 2698 |
| 2699 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 2699 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
| 2700 non_osr_entry->Goto(loop_predecessor); | 2700 non_osr_entry->Goto(loop_predecessor); |
| 2701 | 2701 |
| 2702 int osr_entry_id = statement->OsrEntryId(); | 2702 int osr_entry_id = statement->OsrEntryId(); |
| 2703 // We want the correct environment at the OsrEntry instruction. Build | 2703 // We want the correct environment at the OsrEntry instruction. Build |
| 2704 // it explicitly. The expression stack should be empty. | 2704 // it explicitly. The expression stack should be empty. |
| 2705 int count = osr_entry->last_environment()->total_count(); | 2705 int count = osr_entry->last_environment()->length(); |
| 2706 ASSERT(count == (osr_entry->last_environment()->parameter_count() + | 2706 ASSERT(count == (osr_entry->last_environment()->parameter_count() + |
| 2707 osr_entry->last_environment()->local_count())); | 2707 osr_entry->last_environment()->local_count())); |
| 2708 for (int i = 0; i < count; ++i) { | 2708 for (int i = 0; i < count; ++i) { |
| 2709 HUnknownOSRValue* unknown = new HUnknownOSRValue; | 2709 HUnknownOSRValue* unknown = new HUnknownOSRValue; |
| 2710 osr_entry->AddInstruction(unknown); | 2710 osr_entry->AddInstruction(unknown); |
| 2711 osr_entry->last_environment()->Bind(i, unknown); | 2711 osr_entry->last_environment()->Bind(i, unknown); |
| 2712 } | 2712 } |
| 2713 | 2713 |
| 2714 osr_entry->AddSimulate(osr_entry_id); | 2714 osr_entry->AddSimulate(osr_entry_id); |
| 2715 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); | 2715 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3636 | 3636 |
| 3637 | 3637 |
| 3638 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, | 3638 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, |
| 3639 HValue* key, | 3639 HValue* key, |
| 3640 Property* expr) { | 3640 Property* expr) { |
| 3641 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); | 3641 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); |
| 3642 AddInstruction(new HCheckNonSmi(object)); | 3642 AddInstruction(new HCheckNonSmi(object)); |
| 3643 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3643 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3644 ASSERT(map->has_fast_elements()); | 3644 ASSERT(map->has_fast_elements()); |
| 3645 AddInstruction(new HCheckMap(object, map)); | 3645 AddInstruction(new HCheckMap(object, map)); |
| 3646 HInstruction* elements = AddInstruction(new HLoadElements(object)); | 3646 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); |
| 3647 HInstruction* length = AddInstruction(new HArrayLength(elements)); | 3647 HLoadElements* elements = new HLoadElements(object); |
| 3648 AddInstruction(new HBoundsCheck(key, length)); | 3648 HInstruction* length = NULL; |
| 3649 if (is_array) { |
| 3650 length = AddInstruction(new HJSArrayLength(object)); |
| 3651 AddInstruction(new HBoundsCheck(key, length)); |
| 3652 AddInstruction(elements); |
| 3653 } else { |
| 3654 AddInstruction(elements); |
| 3655 length = AddInstruction(new HFixedArrayLength(elements)); |
| 3656 AddInstruction(new HBoundsCheck(key, length)); |
| 3657 } |
| 3649 return new HLoadKeyedFastElement(elements, key); | 3658 return new HLoadKeyedFastElement(elements, key); |
| 3650 } | 3659 } |
| 3651 | 3660 |
| 3652 | 3661 |
| 3653 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 3662 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
| 3654 HValue* key, | 3663 HValue* key, |
| 3655 HValue* value) { | 3664 HValue* value) { |
| 3656 return new HStoreKeyedGeneric(object, key, value); | 3665 return new HStoreKeyedGeneric(object, key, value); |
| 3657 } | 3666 } |
| 3658 | 3667 |
| 3659 | 3668 |
| 3660 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, | 3669 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, |
| 3661 HValue* key, | 3670 HValue* key, |
| 3662 HValue* val, | 3671 HValue* val, |
| 3663 Expression* expr) { | 3672 Expression* expr) { |
| 3664 ASSERT(expr->IsMonomorphic()); | 3673 ASSERT(expr->IsMonomorphic()); |
| 3665 AddInstruction(new HCheckNonSmi(object)); | 3674 AddInstruction(new HCheckNonSmi(object)); |
| 3666 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3675 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3667 ASSERT(map->has_fast_elements()); | 3676 ASSERT(map->has_fast_elements()); |
| 3668 AddInstruction(new HCheckMap(object, map)); | 3677 AddInstruction(new HCheckMap(object, map)); |
| 3669 HInstruction* elements = AddInstruction(new HLoadElements(object)); | 3678 HInstruction* elements = AddInstruction(new HLoadElements(object)); |
| 3670 AddInstruction(new HCheckMap(elements, Factory::fixed_array_map())); | 3679 AddInstruction(new HCheckMap(elements, Factory::fixed_array_map())); |
| 3671 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); | 3680 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); |
| 3672 HInstruction* length = NULL; | 3681 HInstruction* length = NULL; |
| 3673 if (is_array) { | 3682 if (is_array) { |
| 3674 length = AddInstruction(new HArrayLength(object)); | 3683 length = AddInstruction(new HJSArrayLength(object)); |
| 3675 } else { | 3684 } else { |
| 3676 length = AddInstruction(new HArrayLength(elements)); | 3685 length = AddInstruction(new HFixedArrayLength(elements)); |
| 3677 } | 3686 } |
| 3678 AddInstruction(new HBoundsCheck(key, length)); | 3687 AddInstruction(new HBoundsCheck(key, length)); |
| 3679 return new HStoreKeyedFastElement(elements, key, val); | 3688 return new HStoreKeyedFastElement(elements, key, val); |
| 3680 } | 3689 } |
| 3681 | 3690 |
| 3682 | 3691 |
| 3683 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { | 3692 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { |
| 3684 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 3693 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
| 3685 if (proxy == NULL) return false; | 3694 if (proxy == NULL) return false; |
| 3686 if (!proxy->var()->IsStackAllocated()) return false; | 3695 if (!proxy->var()->IsStackAllocated()) return false; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3713 | 3722 |
| 3714 if (TryArgumentsAccess(expr)) return; | 3723 if (TryArgumentsAccess(expr)) return; |
| 3715 CHECK_BAILOUT; | 3724 CHECK_BAILOUT; |
| 3716 | 3725 |
| 3717 VISIT_FOR_VALUE(expr->obj()); | 3726 VISIT_FOR_VALUE(expr->obj()); |
| 3718 | 3727 |
| 3719 HInstruction* instr = NULL; | 3728 HInstruction* instr = NULL; |
| 3720 if (expr->IsArrayLength()) { | 3729 if (expr->IsArrayLength()) { |
| 3721 HValue* array = Pop(); | 3730 HValue* array = Pop(); |
| 3722 AddInstruction(new HCheckNonSmi(array)); | 3731 AddInstruction(new HCheckNonSmi(array)); |
| 3723 instr = new HArrayLength(array); | 3732 AddInstruction(new HCheckInstanceType(array, JS_ARRAY_TYPE, JS_ARRAY_TYPE)); |
| 3733 instr = new HJSArrayLength(array); |
| 3734 |
| 3735 } else if (expr->IsFunctionPrototype()) { |
| 3736 HValue* function = Pop(); |
| 3737 AddInstruction(new HCheckNonSmi(function)); |
| 3738 instr = new HLoadFunctionPrototype(function); |
| 3724 | 3739 |
| 3725 } else if (expr->key()->IsPropertyName()) { | 3740 } else if (expr->key()->IsPropertyName()) { |
| 3726 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 3741 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 3727 ZoneMapList* types = expr->GetReceiverTypes(); | 3742 ZoneMapList* types = expr->GetReceiverTypes(); |
| 3728 | 3743 |
| 3729 HValue* obj = Pop(); | 3744 HValue* obj = Pop(); |
| 3730 if (expr->IsMonomorphic()) { | 3745 if (expr->IsMonomorphic()) { |
| 3731 instr = BuildLoadNamed(obj, expr, types->first(), name); | 3746 instr = BuildLoadNamed(obj, expr, types->first(), name); |
| 3732 } else if (types != NULL && types->length() > 1) { | 3747 } else if (types != NULL && types->length() > 1) { |
| 3733 HandlePolymorphicLoadNamedField(expr, obj, types, name); | 3748 HandlePolymorphicLoadNamedField(expr, obj, types, name); |
| (...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4847 TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT); | 4862 TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT); |
| 4848 HInstruction* instr = NULL; | 4863 HInstruction* instr = NULL; |
| 4849 if (op == Token::INSTANCEOF) { | 4864 if (op == Token::INSTANCEOF) { |
| 4850 instr = new HInstanceOf(left, right); | 4865 instr = new HInstanceOf(left, right); |
| 4851 } else if (op == Token::IN) { | 4866 } else if (op == Token::IN) { |
| 4852 BAILOUT("Unsupported comparison: in"); | 4867 BAILOUT("Unsupported comparison: in"); |
| 4853 } else if (info.IsNonPrimitive()) { | 4868 } else if (info.IsNonPrimitive()) { |
| 4854 switch (op) { | 4869 switch (op) { |
| 4855 case Token::EQ: | 4870 case Token::EQ: |
| 4856 case Token::EQ_STRICT: { | 4871 case Token::EQ_STRICT: { |
| 4872 AddInstruction(new HCheckNonSmi(left)); |
| 4857 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left)); | 4873 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left)); |
| 4874 AddInstruction(new HCheckNonSmi(right)); |
| 4858 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right)); | 4875 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right)); |
| 4859 instr = new HCompareJSObjectEq(left, right); | 4876 instr = new HCompareJSObjectEq(left, right); |
| 4860 break; | 4877 break; |
| 4861 } | 4878 } |
| 4862 default: | 4879 default: |
| 4863 BAILOUT("Unsupported non-primitive compare"); | 4880 BAILOUT("Unsupported non-primitive compare"); |
| 4864 break; | 4881 break; |
| 4865 } | 4882 } |
| 4866 } else { | 4883 } else { |
| 4867 HCompare* compare = new HCompare(left, right, op); | 4884 HCompare* compare = new HCompare(left, right, op); |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5255 parameter_count_ = parameter_count; | 5272 parameter_count_ = parameter_count; |
| 5256 local_count_ = local_count; | 5273 local_count_ = local_count; |
| 5257 | 5274 |
| 5258 // Avoid reallocating the temporaries' backing store on the first Push. | 5275 // Avoid reallocating the temporaries' backing store on the first Push. |
| 5259 int total = parameter_count + local_count + stack_height; | 5276 int total = parameter_count + local_count + stack_height; |
| 5260 values_.Initialize(total + 4); | 5277 values_.Initialize(total + 4); |
| 5261 for (int i = 0; i < total; ++i) values_.Add(NULL); | 5278 for (int i = 0; i < total; ++i) values_.Add(NULL); |
| 5262 } | 5279 } |
| 5263 | 5280 |
| 5264 | 5281 |
| 5282 void HEnvironment::Initialize(const HEnvironment* other) { |
| 5283 closure_ = other->closure(); |
| 5284 values_.AddAll(other->values_); |
| 5285 assigned_variables_.AddAll(other->assigned_variables_); |
| 5286 parameter_count_ = other->parameter_count_; |
| 5287 local_count_ = other->local_count_; |
| 5288 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
| 5289 pop_count_ = other->pop_count_; |
| 5290 push_count_ = other->push_count_; |
| 5291 ast_id_ = other->ast_id_; |
| 5292 } |
| 5293 |
| 5294 |
| 5265 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 5295 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
| 5266 ASSERT(!block->IsLoopHeader()); | 5296 ASSERT(!block->IsLoopHeader()); |
| 5267 ASSERT(values_.length() == other->values_.length()); | 5297 ASSERT(values_.length() == other->values_.length()); |
| 5268 | 5298 |
| 5269 int length = values_.length(); | 5299 int length = values_.length(); |
| 5270 for (int i = 0; i < length; ++i) { | 5300 for (int i = 0; i < length; ++i) { |
| 5271 HValue* value = values_[i]; | 5301 HValue* value = values_[i]; |
| 5272 if (value != NULL && value->IsPhi() && value->block() == block) { | 5302 if (value != NULL && value->IsPhi() && value->block() == block) { |
| 5273 // There is already a phi for the i'th value. | 5303 // There is already a phi for the i'th value. |
| 5274 HPhi* phi = HPhi::cast(value); | 5304 HPhi* phi = HPhi::cast(value); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5285 phi->AddInput(old_value); | 5315 phi->AddInput(old_value); |
| 5286 } | 5316 } |
| 5287 phi->AddInput(other->values_[i]); | 5317 phi->AddInput(other->values_[i]); |
| 5288 this->values_[i] = phi; | 5318 this->values_[i] = phi; |
| 5289 block->AddPhi(phi); | 5319 block->AddPhi(phi); |
| 5290 } | 5320 } |
| 5291 } | 5321 } |
| 5292 } | 5322 } |
| 5293 | 5323 |
| 5294 | 5324 |
| 5295 void HEnvironment::Initialize(const HEnvironment* other) { | 5325 void HEnvironment::Bind(int index, HValue* value) { |
| 5296 closure_ = other->closure(); | 5326 ASSERT(value != NULL); |
| 5297 values_.AddAll(other->values_); | 5327 if (!assigned_variables_.Contains(index)) { |
| 5298 assigned_variables_.AddAll(other->assigned_variables_); | 5328 assigned_variables_.Add(index); |
| 5299 parameter_count_ = other->parameter_count_; | 5329 } |
| 5300 local_count_ = other->local_count_; | 5330 values_[index] = value; |
| 5301 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | |
| 5302 pop_count_ = other->pop_count_; | |
| 5303 push_count_ = other->push_count_; | |
| 5304 ast_id_ = other->ast_id_; | |
| 5305 } | 5331 } |
| 5306 | 5332 |
| 5307 | 5333 |
| 5308 int HEnvironment::IndexFor(Variable* variable) const { | 5334 bool HEnvironment::HasExpressionAt(int index) const { |
| 5309 Slot* slot = variable->AsSlot(); | 5335 return index >= parameter_count_ + local_count_; |
| 5310 ASSERT(slot != NULL && slot->IsStackAllocated()); | 5336 } |
| 5311 if (slot->type() == Slot::PARAMETER) { | 5337 |
| 5312 return slot->index() + 1; | 5338 |
| 5313 } else { | 5339 bool HEnvironment::ExpressionStackIsEmpty() const { |
| 5314 return parameter_count_ + slot->index(); | 5340 int first_expression = parameter_count() + local_count(); |
| 5341 ASSERT(length() >= first_expression); |
| 5342 return length() == first_expression; |
| 5343 } |
| 5344 |
| 5345 |
| 5346 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { |
| 5347 int count = index_from_top + 1; |
| 5348 int index = values_.length() - count; |
| 5349 ASSERT(HasExpressionAt(index)); |
| 5350 // The push count must include at least the element in question or else |
| 5351 // the new value will not be included in this environment's history. |
| 5352 if (push_count_ < count) { |
| 5353 // This is the same effect as popping then re-pushing 'count' elements. |
| 5354 pop_count_ += (count - push_count_); |
| 5355 push_count_ = count; |
| 5356 } |
| 5357 values_[index] = value; |
| 5358 } |
| 5359 |
| 5360 |
| 5361 void HEnvironment::Drop(int count) { |
| 5362 for (int i = 0; i < count; ++i) { |
| 5363 Pop(); |
| 5315 } | 5364 } |
| 5316 } | 5365 } |
| 5317 | 5366 |
| 5318 | 5367 |
| 5319 HEnvironment* HEnvironment::Copy() const { | 5368 HEnvironment* HEnvironment::Copy() const { |
| 5320 return new HEnvironment(this); | 5369 return new HEnvironment(this); |
| 5321 } | 5370 } |
| 5322 | 5371 |
| 5323 | 5372 |
| 5324 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 5373 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5369 for (int i = 0; i < local_count; ++i) { | 5418 for (int i = 0; i < local_count; ++i) { |
| 5370 inner->SetValueAt(local_base + i, undefined); | 5419 inner->SetValueAt(local_base + i, undefined); |
| 5371 } | 5420 } |
| 5372 | 5421 |
| 5373 inner->set_ast_id(function->id()); | 5422 inner->set_ast_id(function->id()); |
| 5374 return inner; | 5423 return inner; |
| 5375 } | 5424 } |
| 5376 | 5425 |
| 5377 | 5426 |
| 5378 void HEnvironment::PrintTo(StringStream* stream) { | 5427 void HEnvironment::PrintTo(StringStream* stream) { |
| 5379 for (int i = 0; i < total_count(); i++) { | 5428 for (int i = 0; i < length(); i++) { |
| 5380 if (i == 0) stream->Add("parameters\n"); | 5429 if (i == 0) stream->Add("parameters\n"); |
| 5381 if (i == parameter_count()) stream->Add("locals\n"); | 5430 if (i == parameter_count()) stream->Add("locals\n"); |
| 5382 if (i == parameter_count() + local_count()) stream->Add("expressions"); | 5431 if (i == parameter_count() + local_count()) stream->Add("expressions"); |
| 5383 HValue* val = values_.at(i); | 5432 HValue* val = values_.at(i); |
| 5384 stream->Add("%d: ", i); | 5433 stream->Add("%d: ", i); |
| 5385 if (val != NULL) { | 5434 if (val != NULL) { |
| 5386 val->PrintNameTo(stream); | 5435 val->PrintNameTo(stream); |
| 5387 } else { | 5436 } else { |
| 5388 stream->Add("NULL"); | 5437 stream->Add("NULL"); |
| 5389 } | 5438 } |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5677 } | 5726 } |
| 5678 | 5727 |
| 5679 #ifdef DEBUG | 5728 #ifdef DEBUG |
| 5680 if (graph_ != NULL) graph_->Verify(); | 5729 if (graph_ != NULL) graph_->Verify(); |
| 5681 if (chunk_ != NULL) chunk_->Verify(); | 5730 if (chunk_ != NULL) chunk_->Verify(); |
| 5682 if (allocator_ != NULL) allocator_->Verify(); | 5731 if (allocator_ != NULL) allocator_->Verify(); |
| 5683 #endif | 5732 #endif |
| 5684 } | 5733 } |
| 5685 | 5734 |
| 5686 } } // namespace v8::internal | 5735 } } // namespace v8::internal |
| OLD | NEW |