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

Side by Side Diff: src/hydrogen.cc

Issue 9838059: Rollback of r11118, r11109 in trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 9 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') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 void HBasicBlock::AddInstruction(HInstruction* instr) { 106 void HBasicBlock::AddInstruction(HInstruction* instr) {
107 ASSERT(!IsStartBlock() || !IsFinished()); 107 ASSERT(!IsStartBlock() || !IsFinished());
108 ASSERT(!instr->IsLinked()); 108 ASSERT(!instr->IsLinked());
109 ASSERT(!IsFinished()); 109 ASSERT(!IsFinished());
110 if (first_ == NULL) { 110 if (first_ == NULL) {
111 HBlockEntry* entry = new(zone()) HBlockEntry(); 111 HBlockEntry* entry = new(zone()) HBlockEntry();
112 entry->InitializeAsFirst(this); 112 entry->InitializeAsFirst(this);
113 first_ = last_ = entry; 113 first_ = last_ = entry;
114 } 114 }
115 instr->InsertAfter(last_); 115 instr->InsertAfter(last_);
116 last_ = instr;
116 } 117 }
117 118
118 119
119 HDeoptimize* HBasicBlock::CreateDeoptimize( 120 HDeoptimize* HBasicBlock::CreateDeoptimize(
120 HDeoptimize::UseEnvironment has_uses) { 121 HDeoptimize::UseEnvironment has_uses) {
121 ASSERT(HasEnvironment()); 122 ASSERT(HasEnvironment());
122 if (has_uses == HDeoptimize::kNoUses) return new(zone()) HDeoptimize(0); 123 if (has_uses == HDeoptimize::kNoUses) return new(zone()) HDeoptimize(0);
123 124
124 HEnvironment* environment = last_environment(); 125 HEnvironment* environment = last_environment();
125 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length()); 126 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 void HBasicBlock::Finish(HControlInstruction* end) { 158 void HBasicBlock::Finish(HControlInstruction* end) {
158 ASSERT(!IsFinished()); 159 ASSERT(!IsFinished());
159 AddInstruction(end); 160 AddInstruction(end);
160 end_ = end; 161 end_ = end;
161 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 162 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
162 it.Current()->RegisterPredecessor(this); 163 it.Current()->RegisterPredecessor(this);
163 } 164 }
164 } 165 }
165 166
166 167
167 void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) { 168 void HBasicBlock::Goto(HBasicBlock* block, bool drop_extra) {
168 bool drop_extra = state != NULL && state->drop_extra();
169 bool arguments_pushed = state != NULL && state->arguments_pushed();
170
171 if (block->IsInlineReturnTarget()) { 169 if (block->IsInlineReturnTarget()) {
172 AddInstruction(new(zone()) HLeaveInlined(arguments_pushed)); 170 AddInstruction(new(zone()) HLeaveInlined);
173 last_environment_ = last_environment()->DiscardInlined(drop_extra); 171 last_environment_ = last_environment()->DiscardInlined(drop_extra);
174 } 172 }
175
176 AddSimulate(AstNode::kNoNumber); 173 AddSimulate(AstNode::kNoNumber);
177 HGoto* instr = new(zone()) HGoto(block); 174 HGoto* instr = new(zone()) HGoto(block);
178 Finish(instr); 175 Finish(instr);
179 } 176 }
180 177
181 178
182 void HBasicBlock::AddLeaveInlined(HValue* return_value, 179 void HBasicBlock::AddLeaveInlined(HValue* return_value,
183 HBasicBlock* target, 180 HBasicBlock* target,
184 FunctionState* state) { 181 bool drop_extra) {
185 bool drop_extra = state != NULL && state->drop_extra();
186 bool arguments_pushed = state != NULL && state->arguments_pushed();
187
188 ASSERT(target->IsInlineReturnTarget()); 182 ASSERT(target->IsInlineReturnTarget());
189 ASSERT(return_value != NULL); 183 ASSERT(return_value != NULL);
190 AddInstruction(new(zone()) HLeaveInlined(arguments_pushed)); 184 AddInstruction(new(zone()) HLeaveInlined);
191 last_environment_ = last_environment()->DiscardInlined(drop_extra); 185 last_environment_ = last_environment()->DiscardInlined(drop_extra);
192 last_environment()->Push(return_value); 186 last_environment()->Push(return_value);
193 AddSimulate(AstNode::kNoNumber); 187 AddSimulate(AstNode::kNoNumber);
194 HGoto* instr = new(zone()) HGoto(target); 188 HGoto* instr = new(zone()) HGoto(target);
195 Finish(instr); 189 Finish(instr);
196 } 190 }
197 191
198 192
199 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 193 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
200 ASSERT(!HasEnvironment()); 194 ASSERT(!HasEnvironment());
(...skipping 1976 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 CompilationInfo* info, 2171 CompilationInfo* info,
2178 TypeFeedbackOracle* oracle, 2172 TypeFeedbackOracle* oracle,
2179 ReturnHandlingFlag return_handling) 2173 ReturnHandlingFlag return_handling)
2180 : owner_(owner), 2174 : owner_(owner),
2181 compilation_info_(info), 2175 compilation_info_(info),
2182 oracle_(oracle), 2176 oracle_(oracle),
2183 call_context_(NULL), 2177 call_context_(NULL),
2184 return_handling_(return_handling), 2178 return_handling_(return_handling),
2185 function_return_(NULL), 2179 function_return_(NULL),
2186 test_context_(NULL), 2180 test_context_(NULL),
2187 entry_(NULL),
2188 arguments_elements_(NULL),
2189 outer_(owner->function_state()) { 2181 outer_(owner->function_state()) {
2190 if (outer_ != NULL) { 2182 if (outer_ != NULL) {
2191 // State for an inline function. 2183 // State for an inline function.
2192 if (owner->ast_context()->IsTest()) { 2184 if (owner->ast_context()->IsTest()) {
2193 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 2185 HBasicBlock* if_true = owner->graph()->CreateBasicBlock();
2194 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 2186 HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
2195 if_true->MarkAsInlineReturnTarget(); 2187 if_true->MarkAsInlineReturnTarget();
2196 if_false->MarkAsInlineReturnTarget(); 2188 if_false->MarkAsInlineReturnTarget();
2197 Expression* cond = TestContext::cast(owner->ast_context())->condition(); 2189 Expression* cond = TestContext::cast(owner->ast_context())->condition();
2198 // The AstContext constructor pushed on the context stack. This newed 2190 // The AstContext constructor pushed on the context stack. This newed
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 } 2330 }
2339 2331
2340 2332
2341 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { 2333 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) {
2342 ASSERT(!instr->HasObservableSideEffects()); 2334 ASSERT(!instr->HasObservableSideEffects());
2343 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 2335 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2344 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 2336 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2345 instr->SetSuccessorAt(0, empty_true); 2337 instr->SetSuccessorAt(0, empty_true);
2346 instr->SetSuccessorAt(1, empty_false); 2338 instr->SetSuccessorAt(1, empty_false);
2347 owner()->current_block()->Finish(instr); 2339 owner()->current_block()->Finish(instr);
2348 empty_true->Goto(if_true(), owner()->function_state()); 2340 empty_true->Goto(if_true(), owner()->function_state()->drop_extra());
2349 empty_false->Goto(if_false(), owner()->function_state()); 2341 empty_false->Goto(if_false(), owner()->function_state()->drop_extra());
2350 owner()->set_current_block(NULL); 2342 owner()->set_current_block(NULL);
2351 } 2343 }
2352 2344
2353 2345
2354 void TestContext::BuildBranch(HValue* value) { 2346 void TestContext::BuildBranch(HValue* value) {
2355 // We expect the graph to be in edge-split form: there is no edge that 2347 // We expect the graph to be in edge-split form: there is no edge that
2356 // connects a branch node to a join node. We conservatively ensure that 2348 // connects a branch node to a join node. We conservatively ensure that
2357 // property by always adding an empty block on the outgoing edges of this 2349 // property by always adding an empty block on the outgoing edges of this
2358 // branch. 2350 // branch.
2359 HGraphBuilder* builder = owner(); 2351 HGraphBuilder* builder = owner();
2360 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { 2352 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
2361 builder->Bailout("arguments object value in a test context"); 2353 builder->Bailout("arguments object value in a test context");
2362 } 2354 }
2363 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 2355 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
2364 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 2356 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
2365 unsigned test_id = condition()->test_id(); 2357 unsigned test_id = condition()->test_id();
2366 ToBooleanStub::Types expected(builder->oracle()->ToBooleanTypes(test_id)); 2358 ToBooleanStub::Types expected(builder->oracle()->ToBooleanTypes(test_id));
2367 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); 2359 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
2368 builder->current_block()->Finish(test); 2360 builder->current_block()->Finish(test);
2369 2361
2370 empty_true->Goto(if_true(), owner()->function_state()); 2362 empty_true->Goto(if_true(), owner()->function_state()->drop_extra());
2371 empty_false->Goto(if_false(), owner()->function_state()); 2363 empty_false->Goto(if_false(), owner()->function_state()->drop_extra());
2372 builder->set_current_block(NULL); 2364 builder->set_current_block(NULL);
2373 } 2365 }
2374 2366
2375 2367
2376 // HGraphBuilder infrastructure for bailing out and checking bailouts. 2368 // HGraphBuilder infrastructure for bailing out and checking bailouts.
2377 #define CHECK_BAILOUT(call) \ 2369 #define CHECK_BAILOUT(call) \
2378 do { \ 2370 do { \
2379 call; \ 2371 call; \
2380 if (HasStackOverflow()) return; \ 2372 if (HasStackOverflow()) return; \
2381 } while (false) 2373 } while (false)
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
2852 CHECK_ALIVE(VisitForValue(stmt->expression())); 2844 CHECK_ALIVE(VisitForValue(stmt->expression()));
2853 HValue* result = environment()->Pop(); 2845 HValue* result = environment()->Pop();
2854 current_block()->FinishExit(new(zone()) HReturn(result)); 2846 current_block()->FinishExit(new(zone()) HReturn(result));
2855 } else if (function_state()->is_construct()) { 2847 } else if (function_state()->is_construct()) {
2856 // Return from an inlined construct call. In a test context the return 2848 // Return from an inlined construct call. In a test context the return
2857 // value will always evaluate to true, in a value context the return value 2849 // value will always evaluate to true, in a value context the return value
2858 // needs to be a JSObject. 2850 // needs to be a JSObject.
2859 if (context->IsTest()) { 2851 if (context->IsTest()) {
2860 TestContext* test = TestContext::cast(context); 2852 TestContext* test = TestContext::cast(context);
2861 CHECK_ALIVE(VisitForEffect(stmt->expression())); 2853 CHECK_ALIVE(VisitForEffect(stmt->expression()));
2862 current_block()->Goto(test->if_true(), function_state()); 2854 current_block()->Goto(test->if_true(), function_state()->drop_extra());
2863 } else if (context->IsEffect()) { 2855 } else if (context->IsEffect()) {
2864 CHECK_ALIVE(VisitForEffect(stmt->expression())); 2856 CHECK_ALIVE(VisitForEffect(stmt->expression()));
2865 current_block()->Goto(function_return(), function_state()); 2857 current_block()->Goto(function_return(), function_state()->drop_extra());
2866 } else { 2858 } else {
2867 ASSERT(context->IsValue()); 2859 ASSERT(context->IsValue());
2868 CHECK_ALIVE(VisitForValue(stmt->expression())); 2860 CHECK_ALIVE(VisitForValue(stmt->expression()));
2869 HValue* return_value = Pop(); 2861 HValue* return_value = Pop();
2870 HValue* receiver = environment()->Lookup(0); 2862 HValue* receiver = environment()->Lookup(0);
2871 HHasInstanceTypeAndBranch* typecheck = 2863 HHasInstanceTypeAndBranch* typecheck =
2872 new(zone()) HHasInstanceTypeAndBranch(return_value, 2864 new(zone()) HHasInstanceTypeAndBranch(return_value,
2873 FIRST_SPEC_OBJECT_TYPE, 2865 FIRST_SPEC_OBJECT_TYPE,
2874 LAST_SPEC_OBJECT_TYPE); 2866 LAST_SPEC_OBJECT_TYPE);
2875 HBasicBlock* if_spec_object = graph()->CreateBasicBlock(); 2867 HBasicBlock* if_spec_object = graph()->CreateBasicBlock();
2876 HBasicBlock* not_spec_object = graph()->CreateBasicBlock(); 2868 HBasicBlock* not_spec_object = graph()->CreateBasicBlock();
2877 typecheck->SetSuccessorAt(0, if_spec_object); 2869 typecheck->SetSuccessorAt(0, if_spec_object);
2878 typecheck->SetSuccessorAt(1, not_spec_object); 2870 typecheck->SetSuccessorAt(1, not_spec_object);
2879 current_block()->Finish(typecheck); 2871 current_block()->Finish(typecheck);
2880 if_spec_object->AddLeaveInlined(return_value, 2872 if_spec_object->AddLeaveInlined(return_value,
2881 function_return(), 2873 function_return(),
2882 function_state()); 2874 function_state()->drop_extra());
2883 not_spec_object->AddLeaveInlined(receiver, 2875 not_spec_object->AddLeaveInlined(receiver,
2884 function_return(), 2876 function_return(),
2885 function_state()); 2877 function_state()->drop_extra());
2886 } 2878 }
2887 } else { 2879 } else {
2888 // Return from an inlined function, visit the subexpression in the 2880 // Return from an inlined function, visit the subexpression in the
2889 // expression context of the call. 2881 // expression context of the call.
2890 if (context->IsTest()) { 2882 if (context->IsTest()) {
2891 TestContext* test = TestContext::cast(context); 2883 TestContext* test = TestContext::cast(context);
2892 VisitForControl(stmt->expression(), 2884 VisitForControl(stmt->expression(),
2893 test->if_true(), 2885 test->if_true(),
2894 test->if_false()); 2886 test->if_false());
2895 } else if (context->IsEffect()) { 2887 } else if (context->IsEffect()) {
2896 CHECK_ALIVE(VisitForEffect(stmt->expression())); 2888 CHECK_ALIVE(VisitForEffect(stmt->expression()));
2897 current_block()->Goto(function_return(), function_state()); 2889 current_block()->Goto(function_return(), function_state()->drop_extra());
2898 } else { 2890 } else {
2899 ASSERT(context->IsValue()); 2891 ASSERT(context->IsValue());
2900 CHECK_ALIVE(VisitForValue(stmt->expression())); 2892 CHECK_ALIVE(VisitForValue(stmt->expression()));
2901 HValue* return_value = Pop(); 2893 HValue* return_value = Pop();
2902 current_block()->AddLeaveInlined(return_value, 2894 current_block()->AddLeaveInlined(return_value,
2903 function_return(), 2895 function_return(),
2904 function_state()); 2896 function_state()->drop_extra());
2905 } 2897 }
2906 } 2898 }
2907 set_current_block(NULL); 2899 set_current_block(NULL);
2908 } 2900 }
2909 2901
2910 2902
2911 void HGraphBuilder::VisitWithStatement(WithStatement* stmt) { 2903 void HGraphBuilder::VisitWithStatement(WithStatement* stmt) {
2912 ASSERT(!HasStackOverflow()); 2904 ASSERT(!HasStackOverflow());
2913 ASSERT(current_block() != NULL); 2905 ASSERT(current_block() != NULL);
2914 ASSERT(current_block()->HasPredecessor()); 2906 ASSERT(current_block()->HasPredecessor());
(...skipping 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after
4938 } 4930 }
4939 4931
4940 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { 4932 bool HGraphBuilder::TryArgumentsAccess(Property* expr) {
4941 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 4933 VariableProxy* proxy = expr->obj()->AsVariableProxy();
4942 if (proxy == NULL) return false; 4934 if (proxy == NULL) return false;
4943 if (!proxy->var()->IsStackAllocated()) return false; 4935 if (!proxy->var()->IsStackAllocated()) return false;
4944 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 4936 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) {
4945 return false; 4937 return false;
4946 } 4938 }
4947 4939
4940 // Our implementation of arguments (based on this stack frame or an
4941 // adapter below it) does not work for inlined functions.
4948 if (function_state()->outer() != NULL) { 4942 if (function_state()->outer() != NULL) {
4949 // Push arguments when entering inlined function. 4943 Bailout("arguments access in inlined function");
4950 if (!function_state()->arguments_pushed()) { 4944 return true;
4951 HEnvironment* arguments_env = environment()->arguments_environment();
4952
4953 HInstruction* insert_after = function_state()->entry();
4954 ASSERT(insert_after->IsEnterInlined());
4955 HEnterInlined::cast(insert_after)->set_materializes_arguments(true);
4956
4957 for (int i = 0; i < arguments_env->parameter_count(); i++) {
4958 HValue* argument = arguments_env->Lookup(i);
4959 HInstruction* push_argument = new(zone()) HPushArgument(argument);
4960 push_argument->InsertAfter(insert_after);
4961 insert_after = push_argument;
4962 }
4963
4964 HInstruction* arguments_elements = new(zone()) HArgumentsElements();
4965 arguments_elements->ClearFlag(HValue::kUseGVN);
4966 arguments_elements->InsertAfter(insert_after);
4967 function_state()->set_arguments_elements(arguments_elements);
4968 }
4969 } 4945 }
4970 4946
4971 HInstruction* result = NULL; 4947 HInstruction* result = NULL;
4972 if (expr->key()->IsPropertyName()) { 4948 if (expr->key()->IsPropertyName()) {
4973 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 4949 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
4974 if (!name->IsEqualTo(CStrVector("length"))) return false; 4950 if (!name->IsEqualTo(CStrVector("length"))) return false;
4975 4951 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
4976 if (function_state()->outer() == NULL) { 4952 result = new(zone()) HArgumentsLength(elements);
4977 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
4978 result = new(zone()) HArgumentsLength(elements);
4979 } else {
4980 // Number of arguments without receiver.
4981 int argument_count = environment()->
4982 arguments_environment()->parameter_count() - 1;
4983 result = new(zone()) HConstant(
4984 Handle<Object>(Smi::FromInt(argument_count)),
4985 Representation::Integer32());
4986 }
4987 } else { 4953 } else {
4988 Push(graph()->GetArgumentsObject()); 4954 Push(graph()->GetArgumentsObject());
4989 VisitForValue(expr->key()); 4955 VisitForValue(expr->key());
4990 if (HasStackOverflow() || current_block() == NULL) return true; 4956 if (HasStackOverflow() || current_block() == NULL) return true;
4991 HValue* key = Pop(); 4957 HValue* key = Pop();
4992 Drop(1); // Arguments object. 4958 Drop(1); // Arguments object.
4993 if (function_state()->outer() == NULL) { 4959 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
4994 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 4960 HInstruction* length = AddInstruction(
4995 HInstruction* length = AddInstruction( 4961 new(zone()) HArgumentsLength(elements));
4996 new(zone()) HArgumentsLength(elements)); 4962 HInstruction* checked_key =
4997 HInstruction* checked_key = 4963 AddInstruction(new(zone()) HBoundsCheck(key, length));
4998 AddInstruction(new(zone()) HBoundsCheck(key, length)); 4964 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
4999 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
5000 } else {
5001 // Number of arguments without receiver.
5002 HInstruction* elements = function_state()->arguments_elements();
5003 int argument_count = environment()->
5004 arguments_environment()->parameter_count() - 1;
5005 HInstruction* length = AddInstruction(new(zone()) HConstant(
5006 Handle<Object>(Smi::FromInt(argument_count)),
5007 Representation::Integer32()));
5008 HInstruction* checked_key =
5009 AddInstruction(new(zone()) HBoundsCheck(key, length));
5010 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
5011 }
5012 } 4965 }
5013 ast_context()->ReturnInstruction(result, expr->id()); 4966 ast_context()->ReturnInstruction(result, expr->id());
5014 return true; 4967 return true;
5015 } 4968 }
5016 4969
5017 4970
5018 void HGraphBuilder::VisitProperty(Property* expr) { 4971 void HGraphBuilder::VisitProperty(Property* expr) {
5019 ASSERT(!HasStackOverflow()); 4972 ASSERT(!HasStackOverflow());
5020 ASSERT(current_block() != NULL); 4973 ASSERT(current_block() != NULL);
5021 ASSERT(current_block()->HasPredecessor()); 4974 ASSERT(current_block()->HasPredecessor());
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
5409 // IA32 only, overwrite the caller's context in the deoptimization 5362 // IA32 only, overwrite the caller's context in the deoptimization
5410 // environment with the correct one. 5363 // environment with the correct one.
5411 // 5364 //
5412 // TODO(kmillikin): implement the same inlining on other platforms so we 5365 // TODO(kmillikin): implement the same inlining on other platforms so we
5413 // can remove the unsightly ifdefs in this function. 5366 // can remove the unsightly ifdefs in this function.
5414 HConstant* context = new HConstant(Handle<Context>(target->context()), 5367 HConstant* context = new HConstant(Handle<Context>(target->context()),
5415 Representation::Tagged()); 5368 Representation::Tagged());
5416 AddInstruction(context); 5369 AddInstruction(context);
5417 inner_env->BindContext(context); 5370 inner_env->BindContext(context);
5418 #endif 5371 #endif
5372 AddSimulate(return_id);
5373 current_block()->UpdateEnvironment(inner_env);
5374 AddInstruction(new(zone()) HEnterInlined(target,
5375 arguments->length(),
5376 function,
5377 call_kind,
5378 function_state()->is_construct()));
5419 // If the function uses arguments object create and bind one. 5379 // If the function uses arguments object create and bind one.
5420 if (function->scope()->arguments() != NULL) { 5380 if (function->scope()->arguments() != NULL) {
5421 ASSERT(function->scope()->arguments()->IsStackAllocated()); 5381 ASSERT(function->scope()->arguments()->IsStackAllocated());
5422 inner_env->Bind(function->scope()->arguments(), 5382 environment()->Bind(function->scope()->arguments(),
5423 graph()->GetArgumentsObject()); 5383 graph()->GetArgumentsObject());
5424 } 5384 }
5425
5426 AddSimulate(return_id);
5427 current_block()->UpdateEnvironment(inner_env);
5428
5429 HInstruction* enter_inlined =
5430 AddInstruction(new(zone()) HEnterInlined(target,
5431 arguments->length(),
5432 function,
5433 call_kind,
5434 function_state()->is_construct(),
5435 function->scope()->arguments()));
5436 function_state()->set_entry(enter_inlined);
5437 VisitDeclarations(target_info.scope()->declarations()); 5385 VisitDeclarations(target_info.scope()->declarations());
5438 VisitStatements(function->body()); 5386 VisitStatements(function->body());
5439 if (HasStackOverflow()) { 5387 if (HasStackOverflow()) {
5440 // Bail out if the inline function did, as we cannot residualize a call 5388 // Bail out if the inline function did, as we cannot residualize a call
5441 // instead. 5389 // instead.
5442 TraceInline(target, caller, "inline graph construction failed"); 5390 TraceInline(target, caller, "inline graph construction failed");
5443 target_shared->DisableOptimization(); 5391 target_shared->DisableOptimization();
5444 inline_bailout_ = true; 5392 inline_bailout_ = true;
5445 delete target_state; 5393 delete target_state;
5446 return true; 5394 return true;
5447 } 5395 }
5448 5396
5449 // Update inlined nodes count. 5397 // Update inlined nodes count.
5450 inlined_count_ += nodes_added; 5398 inlined_count_ += nodes_added;
5451 5399
5452 TraceInline(target, caller, NULL); 5400 TraceInline(target, caller, NULL);
5453 5401
5454 if (current_block() != NULL) { 5402 if (current_block() != NULL) {
5455 // Add default return value (i.e. undefined for normals calls or the newly 5403 // Add default return value (i.e. undefined for normals calls or the newly
5456 // allocated receiver for construct calls) if control can fall off the 5404 // allocated receiver for construct calls) if control can fall off the
5457 // body. In a test context, undefined is false and any JSObject is true. 5405 // body. In a test context, undefined is false and any JSObject is true.
5458 if (call_context()->IsValue()) { 5406 if (call_context()->IsValue()) {
5459 ASSERT(function_return() != NULL); 5407 ASSERT(function_return() != NULL);
5460 HValue* return_value = function_state()->is_construct() 5408 HValue* return_value = function_state()->is_construct()
5461 ? receiver 5409 ? receiver
5462 : undefined; 5410 : undefined;
5463 current_block()->AddLeaveInlined(return_value, 5411 current_block()->AddLeaveInlined(return_value,
5464 function_return(), 5412 function_return(),
5465 function_state()); 5413 function_state()->drop_extra());
5466 } else if (call_context()->IsEffect()) { 5414 } else if (call_context()->IsEffect()) {
5467 ASSERT(function_return() != NULL); 5415 ASSERT(function_return() != NULL);
5468 current_block()->Goto(function_return(), function_state()); 5416 current_block()->Goto(function_return(), function_state()->drop_extra());
5469 } else { 5417 } else {
5470 ASSERT(call_context()->IsTest()); 5418 ASSERT(call_context()->IsTest());
5471 ASSERT(inlined_test_context() != NULL); 5419 ASSERT(inlined_test_context() != NULL);
5472 HBasicBlock* target = function_state()->is_construct() 5420 HBasicBlock* target = function_state()->is_construct()
5473 ? inlined_test_context()->if_true() 5421 ? inlined_test_context()->if_true()
5474 : inlined_test_context()->if_false(); 5422 : inlined_test_context()->if_false();
5475 current_block()->Goto(target, function_state()); 5423 current_block()->Goto(target, function_state()->drop_extra());
5476 } 5424 }
5477 } 5425 }
5478 5426
5479 // Fix up the function exits. 5427 // Fix up the function exits.
5480 if (inlined_test_context() != NULL) { 5428 if (inlined_test_context() != NULL) {
5481 HBasicBlock* if_true = inlined_test_context()->if_true(); 5429 HBasicBlock* if_true = inlined_test_context()->if_true();
5482 HBasicBlock* if_false = inlined_test_context()->if_false(); 5430 HBasicBlock* if_false = inlined_test_context()->if_false();
5483 5431
5484 // Pop the return test context from the expression context stack. 5432 // Pop the return test context from the expression context stack.
5485 ASSERT(ast_context() == inlined_test_context()); 5433 ASSERT(ast_context() == inlined_test_context());
5486 ClearInlinedTestContext(); 5434 ClearInlinedTestContext();
5487 delete target_state; 5435 delete target_state;
5488 5436
5489 // Forward to the real test context. 5437 // Forward to the real test context.
5490 if (if_true->HasPredecessor()) { 5438 if (if_true->HasPredecessor()) {
5491 if_true->SetJoinId(ast_id); 5439 if_true->SetJoinId(ast_id);
5492 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 5440 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
5493 if_true->Goto(true_target, function_state()); 5441 if_true->Goto(true_target, function_state()->drop_extra());
5494 } 5442 }
5495 if (if_false->HasPredecessor()) { 5443 if (if_false->HasPredecessor()) {
5496 if_false->SetJoinId(ast_id); 5444 if_false->SetJoinId(ast_id);
5497 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 5445 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
5498 if_false->Goto(false_target, function_state()); 5446 if_false->Goto(false_target, function_state()->drop_extra());
5499 } 5447 }
5500 set_current_block(NULL); 5448 set_current_block(NULL);
5501 return true; 5449 return true;
5502 5450
5503 } else if (function_return()->HasPredecessor()) { 5451 } else if (function_return()->HasPredecessor()) {
5504 function_return()->SetJoinId(ast_id); 5452 function_return()->SetJoinId(ast_id);
5505 set_current_block(function_return()); 5453 set_current_block(function_return());
5506 } else { 5454 } else {
5507 set_current_block(NULL); 5455 set_current_block(NULL);
5508 } 5456 }
(...skipping 2704 matching lines...) Expand 10 before | Expand all | Expand 10 after
8213 } 8161 }
8214 } 8162 }
8215 8163
8216 #ifdef DEBUG 8164 #ifdef DEBUG
8217 if (graph_ != NULL) graph_->Verify(false); // No full verify. 8165 if (graph_ != NULL) graph_->Verify(false); // No full verify.
8218 if (allocator_ != NULL) allocator_->Verify(); 8166 if (allocator_ != NULL) allocator_->Verify();
8219 #endif 8167 #endif
8220 } 8168 }
8221 8169
8222 } } // namespace v8::internal 8170 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698