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

Side by Side Diff: src/hydrogen.cc

Issue 6839015: Relax assumptions about control flow in the hydrogen graph. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 235
236 // Only the first entry into the loop is from outside the loop. All other 236 // Only the first entry into the loop is from outside the loop. All other
237 // entries must be back edges. 237 // entries must be back edges.
238 for (int i = 1; i < predecessors()->length(); ++i) { 238 for (int i = 1; i < predecessors()->length(); ++i) {
239 loop_information()->RegisterBackEdge(predecessors()->at(i)); 239 loop_information()->RegisterBackEdge(predecessors()->at(i));
240 } 240 }
241 } 241 }
242 242
243 243
244 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { 244 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
245 if (!predecessors_.is_empty()) { 245 if (HasPredecessor()) {
246 // Only loop header blocks can have a predecessor added after 246 // Only loop header blocks can have a predecessor added after
247 // instructions have been added to the block (they have phis for all 247 // instructions have been added to the block (they have phis for all
248 // values in the environment, these phis may be eliminated later). 248 // values in the environment, these phis may be eliminated later).
249 ASSERT(IsLoopHeader() || first_ == NULL); 249 ASSERT(IsLoopHeader() || first_ == NULL);
250 HEnvironment* incoming_env = pred->last_environment(); 250 HEnvironment* incoming_env = pred->last_environment();
251 if (IsLoopHeader()) { 251 if (IsLoopHeader()) {
252 ASSERT(phis()->length() == incoming_env->length()); 252 ASSERT(phis()->length() == incoming_env->length());
253 for (int i = 0; i < phis_.length(); ++i) { 253 for (int i = 0; i < phis_.length(); ++i) {
254 phis_[i]->AddInput(incoming_env->values()->at(i)); 254 phis_[i]->AddInput(incoming_env->values()->at(i));
255 } 255 }
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 return a->block()->block_id() - b->block()->block_id(); 1801 return a->block()->block_id() - b->block()->block_id();
1802 } 1802 }
1803 1803
1804 1804
1805 void HGraph::InsertRepresentationChangesForValue( 1805 void HGraph::InsertRepresentationChangesForValue(
1806 HValue* current, 1806 HValue* current,
1807 ZoneList<HValue*>* to_convert, 1807 ZoneList<HValue*>* to_convert,
1808 ZoneList<Representation>* to_convert_reps) { 1808 ZoneList<Representation>* to_convert_reps) {
1809 Representation r = current->representation(); 1809 Representation r = current->representation();
1810 if (r.IsNone()) return; 1810 if (r.IsNone()) return;
1811 if (current->uses()->length() == 0) return; 1811 if (current->uses()->is_empty()) return;
1812 1812
1813 // Collect the representation changes in a sorted list. This allows 1813 // Collect the representation changes in a sorted list. This allows
1814 // us to avoid duplicate changes without searching the list. 1814 // us to avoid duplicate changes without searching the list.
1815 ASSERT(to_convert->is_empty()); 1815 ASSERT(to_convert->is_empty());
1816 ASSERT(to_convert_reps->is_empty()); 1816 ASSERT(to_convert_reps->is_empty());
1817 for (int i = 0; i < current->uses()->length(); ++i) { 1817 for (int i = 0; i < current->uses()->length(); ++i) {
1818 HValue* use = current->uses()->at(i); 1818 HValue* use = current->uses()->at(i);
1819 // The occurrences index means the index within the operand array of "use" 1819 // The occurrences index means the index within the operand array of "use"
1820 // at which "current" is used. While iterating through the use array we 1820 // at which "current" is used. While iterating through the use array we
1821 // also have to iterate over the different occurrence indices. 1821 // also have to iterate over the different occurrence indices.
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2069 HTest* test = new(zone()) HTest(value, empty_true, empty_false); 2069 HTest* test = new(zone()) HTest(value, empty_true, empty_false);
2070 builder->current_block()->Finish(test); 2070 builder->current_block()->Finish(test);
2071 2071
2072 empty_true->Goto(if_true(), false); 2072 empty_true->Goto(if_true(), false);
2073 empty_false->Goto(if_false(), false); 2073 empty_false->Goto(if_false(), false);
2074 builder->set_current_block(NULL); 2074 builder->set_current_block(NULL);
2075 } 2075 }
2076 2076
2077 2077
2078 // HGraphBuilder infrastructure for bailing out and checking bailouts. 2078 // HGraphBuilder infrastructure for bailing out and checking bailouts.
2079 #define BAILOUT(reason) \ 2079 #define CHECK_BAILOUT(call) \
2080 do { \ 2080 do { \
2081 Bailout(reason); \ 2081 call; \
2082 return; \
2083 } while (false)
2084
2085
2086 #define CHECK_BAILOUT \
2087 do { \
2088 if (HasStackOverflow()) return; \ 2082 if (HasStackOverflow()) return; \
2089 } while (false) 2083 } while (false)
2090 2084
2091 2085
2092 #define VISIT_FOR_EFFECT(expr) \ 2086 #define CHECK_ALIVE(call) \
2093 do { \ 2087 do { \
2094 VisitForEffect(expr); \ 2088 call; \
2095 if (HasStackOverflow()) return; \ 2089 if (HasStackOverflow() || current_block() == NULL) return; \
2096 } while (false) 2090 } while (false)
2097 2091
2098 2092
2099 #define VISIT_FOR_VALUE(expr) \
2100 do { \
2101 VisitForValue(expr); \
2102 if (HasStackOverflow()) return; \
2103 } while (false)
2104
2105
2106 #define VISIT_FOR_CONTROL(expr, true_block, false_block) \
2107 do { \
2108 VisitForControl(expr, true_block, false_block); \
2109 if (HasStackOverflow()) return; \
2110 } while (false)
2111
2112
2113 void HGraphBuilder::Bailout(const char* reason) { 2093 void HGraphBuilder::Bailout(const char* reason) {
2114 if (FLAG_trace_bailout) { 2094 if (FLAG_trace_bailout) {
2115 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); 2095 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
2116 PrintF("Bailout in HGraphBuilder: @\"%s\": %s\n", *name, reason); 2096 PrintF("Bailout in HGraphBuilder: @\"%s\": %s\n", *name, reason);
2117 } 2097 }
2118 SetStackOverflow(); 2098 SetStackOverflow();
2119 } 2099 }
2120 2100
2121 2101
2122 void HGraphBuilder::VisitForEffect(Expression* expr) { 2102 void HGraphBuilder::VisitForEffect(Expression* expr) {
(...skipping 18 matching lines...) Expand all
2141 2121
2142 void HGraphBuilder::VisitForControl(Expression* expr, 2122 void HGraphBuilder::VisitForControl(Expression* expr,
2143 HBasicBlock* true_block, 2123 HBasicBlock* true_block,
2144 HBasicBlock* false_block) { 2124 HBasicBlock* false_block) {
2145 TestContext for_test(this, true_block, false_block); 2125 TestContext for_test(this, true_block, false_block);
2146 Visit(expr); 2126 Visit(expr);
2147 } 2127 }
2148 2128
2149 2129
2150 void HGraphBuilder::VisitArgument(Expression* expr) { 2130 void HGraphBuilder::VisitArgument(Expression* expr) {
2151 VISIT_FOR_VALUE(expr); 2131 CHECK_ALIVE(VisitForValue(expr));
2152 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); 2132 Push(AddInstruction(new(zone()) HPushArgument(Pop())));
2153 } 2133 }
2154 2134
2155 2135
2156 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { 2136 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) {
2157 for (int i = 0; i < arguments->length(); i++) { 2137 for (int i = 0; i < arguments->length(); i++) {
2158 VisitArgument(arguments->at(i)); 2138 VisitArgument(arguments->at(i));
2159 if (HasStackOverflow() || current_block() == NULL) return; 2139 if (HasStackOverflow() || current_block() == NULL) return;
2160 } 2140 }
2161 } 2141 }
2162 2142
2163 2143
2164 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { 2144 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
2165 for (int i = 0; i < exprs->length(); ++i) { 2145 for (int i = 0; i < exprs->length(); ++i) {
2166 VISIT_FOR_VALUE(exprs->at(i)); 2146 CHECK_ALIVE(VisitForValue(exprs->at(i)));
2167 } 2147 }
2168 } 2148 }
2169 2149
2170 2150
2171 HGraph* HGraphBuilder::CreateGraph() { 2151 HGraph* HGraphBuilder::CreateGraph() {
2172 graph_ = new(zone()) HGraph(info()); 2152 graph_ = new(zone()) HGraph(info());
2173 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); 2153 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info());
2174 2154
2175 { 2155 {
2176 HPhase phase("Block building"); 2156 HPhase phase("Block building");
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 2267
2288 while (!arguments.is_empty()) { 2268 while (!arguments.is_empty()) {
2289 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); 2269 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast()));
2290 } 2270 }
2291 return call; 2271 return call;
2292 } 2272 }
2293 2273
2294 2274
2295 void HGraphBuilder::SetupScope(Scope* scope) { 2275 void HGraphBuilder::SetupScope(Scope* scope) {
2296 // We don't yet handle the function name for named function expressions. 2276 // We don't yet handle the function name for named function expressions.
2297 if (scope->function() != NULL) BAILOUT("named function expression"); 2277 if (scope->function() != NULL) return Bailout("named function expression");
danno 2011/04/13 12:00:43 I didn't know this actually works, returning the r
Kevin Millikin (Chromium) 2011/04/13 12:23:24 I'm not sure if it's done elsewhere, I can't think
2298 2278
2299 HConstant* undefined_constant = new(zone()) HConstant( 2279 HConstant* undefined_constant = new(zone()) HConstant(
2300 isolate()->factory()->undefined_value(), Representation::Tagged()); 2280 isolate()->factory()->undefined_value(), Representation::Tagged());
2301 AddInstruction(undefined_constant); 2281 AddInstruction(undefined_constant);
2302 graph_->set_undefined_constant(undefined_constant); 2282 graph_->set_undefined_constant(undefined_constant);
2303 2283
2304 // Set the initial values of parameters including "this". "This" has 2284 // Set the initial values of parameters including "this". "This" has
2305 // parameter index 0. 2285 // parameter index 0.
2306 int count = scope->num_parameters() + 1; 2286 int count = scope->num_parameters() + 1;
2307 for (int i = 0; i < count; ++i) { 2287 for (int i = 0; i < count; ++i) {
2308 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); 2288 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i));
2309 environment()->Bind(i, parameter); 2289 environment()->Bind(i, parameter);
2310 } 2290 }
2311 2291
2312 // Set the initial values of stack-allocated locals. 2292 // Set the initial values of stack-allocated locals.
2313 for (int i = count; i < environment()->length(); ++i) { 2293 for (int i = count; i < environment()->length(); ++i) {
2314 environment()->Bind(i, undefined_constant); 2294 environment()->Bind(i, undefined_constant);
2315 } 2295 }
2316 2296
2317 // Handle the arguments and arguments shadow variables specially (they do 2297 // Handle the arguments and arguments shadow variables specially (they do
2318 // not have declarations). 2298 // not have declarations).
2319 if (scope->arguments() != NULL) { 2299 if (scope->arguments() != NULL) {
2320 if (!scope->arguments()->IsStackAllocated() || 2300 if (!scope->arguments()->IsStackAllocated() ||
2321 (scope->arguments_shadow() != NULL && 2301 (scope->arguments_shadow() != NULL &&
2322 !scope->arguments_shadow()->IsStackAllocated())) { 2302 !scope->arguments_shadow()->IsStackAllocated())) {
2323 BAILOUT("context-allocated arguments"); 2303 return Bailout("context-allocated arguments");
2324 } 2304 }
2325 HArgumentsObject* object = new(zone()) HArgumentsObject; 2305 HArgumentsObject* object = new(zone()) HArgumentsObject;
2326 AddInstruction(object); 2306 AddInstruction(object);
2327 graph()->SetArgumentsObject(object); 2307 graph()->SetArgumentsObject(object);
2328 environment()->Bind(scope->arguments(), object); 2308 environment()->Bind(scope->arguments(), object);
2329 if (scope->arguments_shadow() != NULL) { 2309 if (scope->arguments_shadow() != NULL) {
2330 environment()->Bind(scope->arguments_shadow(), object); 2310 environment()->Bind(scope->arguments_shadow(), object);
2331 } 2311 }
2332 } 2312 }
2333 } 2313 }
(...skipping 17 matching lines...) Expand all
2351 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 2331 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
2352 HBasicBlock* header = graph()->CreateBasicBlock(); 2332 HBasicBlock* header = graph()->CreateBasicBlock();
2353 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 2333 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
2354 header->SetInitialEnvironment(entry_env); 2334 header->SetInitialEnvironment(entry_env);
2355 header->AttachLoopInformation(); 2335 header->AttachLoopInformation();
2356 return header; 2336 return header;
2357 } 2337 }
2358 2338
2359 2339
2360 void HGraphBuilder::VisitBlock(Block* stmt) { 2340 void HGraphBuilder::VisitBlock(Block* stmt) {
2341 ASSERT(!HasStackOverflow());
2342 ASSERT(current_block() != NULL);
2343 ASSERT(current_block()->HasPredecessor());
2361 BreakAndContinueInfo break_info(stmt); 2344 BreakAndContinueInfo break_info(stmt);
2362 { BreakAndContinueScope push(&break_info, this); 2345 { BreakAndContinueScope push(&break_info, this);
2363 VisitStatements(stmt->statements()); 2346 CHECK_BAILOUT(VisitStatements(stmt->statements()));
2364 CHECK_BAILOUT;
2365 } 2347 }
2366 HBasicBlock* break_block = break_info.break_block(); 2348 HBasicBlock* break_block = break_info.break_block();
2367 if (break_block != NULL) { 2349 if (break_block != NULL) {
2368 if (current_block() != NULL) current_block()->Goto(break_block); 2350 if (current_block() != NULL) current_block()->Goto(break_block);
2369 break_block->SetJoinId(stmt->ExitId()); 2351 break_block->SetJoinId(stmt->ExitId());
2370 set_current_block(break_block); 2352 set_current_block(break_block);
2371 } 2353 }
2372 } 2354 }
2373 2355
2374 2356
2375 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { 2357 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
2358 ASSERT(!HasStackOverflow());
2359 ASSERT(current_block() != NULL);
2360 ASSERT(current_block()->HasPredecessor());
2376 VisitForEffect(stmt->expression()); 2361 VisitForEffect(stmt->expression());
2377 } 2362 }
2378 2363
2379 2364
2380 void HGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 2365 void HGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
2366 ASSERT(!HasStackOverflow());
2367 ASSERT(current_block() != NULL);
2368 ASSERT(current_block()->HasPredecessor());
2381 } 2369 }
2382 2370
2383 2371
2384 void HGraphBuilder::VisitIfStatement(IfStatement* stmt) { 2372 void HGraphBuilder::VisitIfStatement(IfStatement* stmt) {
2373 ASSERT(!HasStackOverflow());
2374 ASSERT(current_block() != NULL);
2375 ASSERT(current_block()->HasPredecessor());
2385 if (stmt->condition()->ToBooleanIsTrue()) { 2376 if (stmt->condition()->ToBooleanIsTrue()) {
2386 AddSimulate(stmt->ThenId()); 2377 AddSimulate(stmt->ThenId());
2387 Visit(stmt->then_statement()); 2378 Visit(stmt->then_statement());
2388 } else if (stmt->condition()->ToBooleanIsFalse()) { 2379 } else if (stmt->condition()->ToBooleanIsFalse()) {
2389 AddSimulate(stmt->ElseId()); 2380 AddSimulate(stmt->ElseId());
2390 Visit(stmt->else_statement()); 2381 Visit(stmt->else_statement());
2391 } else { 2382 } else {
2392 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 2383 HBasicBlock* cond_true = graph()->CreateBasicBlock();
2393 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 2384 HBasicBlock* cond_false = graph()->CreateBasicBlock();
2394 VISIT_FOR_CONTROL(stmt->condition(), cond_true, cond_false); 2385 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false));
2395 cond_true->SetJoinId(stmt->ThenId());
2396 cond_false->SetJoinId(stmt->ElseId());
2397 2386
2398 set_current_block(cond_true); 2387 if (cond_true->HasPredecessor()) {
2399 Visit(stmt->then_statement()); 2388 cond_true->SetJoinId(stmt->ThenId());
2400 CHECK_BAILOUT; 2389 set_current_block(cond_true);
2401 HBasicBlock* other = current_block(); 2390 CHECK_BAILOUT(Visit(stmt->then_statement()));
2391 cond_true = current_block();
2392 } else {
2393 cond_true = NULL;
2394 }
2402 2395
2403 set_current_block(cond_false); 2396 if (cond_false->HasPredecessor()) {
2404 Visit(stmt->else_statement()); 2397 cond_false->SetJoinId(stmt->ElseId());
2405 CHECK_BAILOUT; 2398 set_current_block(cond_false);
2399 CHECK_BAILOUT(Visit(stmt->else_statement()));
2400 cond_false = current_block();
2401 } else {
2402 cond_false = NULL;
2403 }
2406 2404
2407 HBasicBlock* join = CreateJoin(other, current_block(), stmt->id()); 2405 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->id());
2408 set_current_block(join); 2406 set_current_block(join);
2409 } 2407 }
2410 } 2408 }
2411 2409
2412 2410
2413 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( 2411 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get(
2414 BreakableStatement* stmt, 2412 BreakableStatement* stmt,
2415 BreakType type) { 2413 BreakType type) {
2416 BreakAndContinueScope* current = this; 2414 BreakAndContinueScope* current = this;
2417 while (current != NULL && current->info()->target() != stmt) { 2415 while (current != NULL && current->info()->target() != stmt) {
(...skipping 17 matching lines...) Expand all
2435 current->info()->set_continue_block(block); 2433 current->info()->set_continue_block(block);
2436 } 2434 }
2437 break; 2435 break;
2438 } 2436 }
2439 2437
2440 return block; 2438 return block;
2441 } 2439 }
2442 2440
2443 2441
2444 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 2442 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
2443 ASSERT(!HasStackOverflow());
2444 ASSERT(current_block() != NULL);
2445 ASSERT(current_block()->HasPredecessor());
2445 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), CONTINUE); 2446 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), CONTINUE);
2446 current_block()->Goto(continue_block); 2447 current_block()->Goto(continue_block);
2447 set_current_block(NULL); 2448 set_current_block(NULL);
2448 } 2449 }
2449 2450
2450 2451
2451 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 2452 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
2453 ASSERT(!HasStackOverflow());
2454 ASSERT(current_block() != NULL);
2455 ASSERT(current_block()->HasPredecessor());
2452 HBasicBlock* break_block = break_scope()->Get(stmt->target(), BREAK); 2456 HBasicBlock* break_block = break_scope()->Get(stmt->target(), BREAK);
2453 current_block()->Goto(break_block); 2457 current_block()->Goto(break_block);
2454 set_current_block(NULL); 2458 set_current_block(NULL);
2455 } 2459 }
2456 2460
2457 2461
2458 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 2462 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
2463 ASSERT(!HasStackOverflow());
2464 ASSERT(current_block() != NULL);
2465 ASSERT(current_block()->HasPredecessor());
2459 AstContext* context = call_context(); 2466 AstContext* context = call_context();
2460 if (context == NULL) { 2467 if (context == NULL) {
2461 // Not an inlined return, so an actual one. 2468 // Not an inlined return, so an actual one.
2462 VISIT_FOR_VALUE(stmt->expression()); 2469 CHECK_ALIVE(VisitForValue(stmt->expression()));
2463 HValue* result = environment()->Pop(); 2470 HValue* result = environment()->Pop();
2464 current_block()->FinishExit(new(zone()) HReturn(result)); 2471 current_block()->FinishExit(new(zone()) HReturn(result));
2465 set_current_block(NULL); 2472 set_current_block(NULL);
2466 } else { 2473 } else {
2467 // Return from an inlined function, visit the subexpression in the 2474 // Return from an inlined function, visit the subexpression in the
2468 // expression context of the call. 2475 // expression context of the call.
2469 if (context->IsTest()) { 2476 if (context->IsTest()) {
2470 TestContext* test = TestContext::cast(context); 2477 TestContext* test = TestContext::cast(context);
2471 VisitForControl(stmt->expression(), 2478 VisitForControl(stmt->expression(),
2472 test->if_true(), 2479 test->if_true(),
2473 test->if_false()); 2480 test->if_false());
2474 } else if (context->IsEffect()) { 2481 } else if (context->IsEffect()) {
2475 VISIT_FOR_EFFECT(stmt->expression()); 2482 CHECK_ALIVE(VisitForEffect(stmt->expression()));
2476 current_block()->Goto(function_return(), false); 2483 current_block()->Goto(function_return(), false);
2477 } else { 2484 } else {
2478 ASSERT(context->IsValue()); 2485 ASSERT(context->IsValue());
2479 VISIT_FOR_VALUE(stmt->expression()); 2486 CHECK_ALIVE(VisitForValue(stmt->expression()));
2480 HValue* return_value = environment()->Pop(); 2487 HValue* return_value = environment()->Pop();
2481 current_block()->AddLeaveInlined(return_value, function_return()); 2488 current_block()->AddLeaveInlined(return_value, function_return());
2482 } 2489 }
2483 set_current_block(NULL); 2490 set_current_block(NULL);
2484 } 2491 }
2485 } 2492 }
2486 2493
2487 2494
2488 void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { 2495 void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
2489 BAILOUT("WithEnterStatement"); 2496 ASSERT(!HasStackOverflow());
2497 ASSERT(current_block() != NULL);
2498 ASSERT(current_block()->HasPredecessor());
2499 return Bailout("WithEnterStatement");
2490 } 2500 }
2491 2501
2492 2502
2493 void HGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) { 2503 void HGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
2494 BAILOUT("WithExitStatement"); 2504 ASSERT(!HasStackOverflow());
2505 ASSERT(current_block() != NULL);
2506 ASSERT(current_block()->HasPredecessor());
2507 return Bailout("WithExitStatement");
2495 } 2508 }
2496 2509
2497 2510
2498 void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 2511 void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
2512 ASSERT(!HasStackOverflow());
2513 ASSERT(current_block() != NULL);
2514 ASSERT(current_block()->HasPredecessor());
2499 // We only optimize switch statements with smi-literal smi comparisons, 2515 // We only optimize switch statements with smi-literal smi comparisons,
2500 // with a bounded number of clauses. 2516 // with a bounded number of clauses.
2501 const int kCaseClauseLimit = 128; 2517 const int kCaseClauseLimit = 128;
2502 ZoneList<CaseClause*>* clauses = stmt->cases(); 2518 ZoneList<CaseClause*>* clauses = stmt->cases();
2503 int clause_count = clauses->length(); 2519 int clause_count = clauses->length();
2504 if (clause_count > kCaseClauseLimit) { 2520 if (clause_count > kCaseClauseLimit) {
2505 BAILOUT("SwitchStatement: too many clauses"); 2521 return Bailout("SwitchStatement: too many clauses");
2506 } 2522 }
2507 2523
2508 VISIT_FOR_VALUE(stmt->tag()); 2524 CHECK_ALIVE(VisitForValue(stmt->tag()));
2509 AddSimulate(stmt->EntryId()); 2525 AddSimulate(stmt->EntryId());
2510 HValue* tag_value = Pop(); 2526 HValue* tag_value = Pop();
2511 HBasicBlock* first_test_block = current_block(); 2527 HBasicBlock* first_test_block = current_block();
2512 2528
2513 // 1. Build all the tests, with dangling true branches. Unconditionally 2529 // 1. Build all the tests, with dangling true branches. Unconditionally
2514 // deoptimize if we encounter a non-smi comparison. 2530 // deoptimize if we encounter a non-smi comparison.
2515 for (int i = 0; i < clause_count; ++i) { 2531 for (int i = 0; i < clause_count; ++i) {
2516 CaseClause* clause = clauses->at(i); 2532 CaseClause* clause = clauses->at(i);
2517 if (clause->is_default()) continue; 2533 if (clause->is_default()) continue;
2518 if (!clause->label()->IsSmiLiteral()) { 2534 if (!clause->label()->IsSmiLiteral()) {
2519 BAILOUT("SwitchStatement: non-literal switch label"); 2535 return Bailout("SwitchStatement: non-literal switch label");
2520 } 2536 }
2521 2537
2522 // Unconditionally deoptimize on the first non-smi compare. 2538 // Unconditionally deoptimize on the first non-smi compare.
2523 clause->RecordTypeFeedback(oracle()); 2539 clause->RecordTypeFeedback(oracle());
2524 if (!clause->IsSmiCompare()) { 2540 if (!clause->IsSmiCompare()) {
2525 current_block()->FinishExitWithDeoptimization(); 2541 current_block()->FinishExitWithDeoptimization();
2526 set_current_block(NULL); 2542 set_current_block(NULL);
2527 break; 2543 break;
2528 } 2544 }
2529 2545
2530 // Otherwise generate a compare and branch. 2546 // Otherwise generate a compare and branch.
2531 VISIT_FOR_VALUE(clause->label()); 2547 CHECK_ALIVE(VisitForValue(clause->label()));
2532 HValue* label_value = Pop(); 2548 HValue* label_value = Pop();
2533 HCompare* compare = 2549 HCompare* compare =
2534 new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT); 2550 new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT);
2535 compare->SetInputRepresentation(Representation::Integer32()); 2551 compare->SetInputRepresentation(Representation::Integer32());
2536 ASSERT(!compare->HasSideEffects()); 2552 ASSERT(!compare->HasSideEffects());
2537 AddInstruction(compare); 2553 AddInstruction(compare);
2538 HBasicBlock* body_block = graph()->CreateBasicBlock(); 2554 HBasicBlock* body_block = graph()->CreateBasicBlock();
2539 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 2555 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
2540 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block); 2556 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block);
2541 current_block()->Finish(branch); 2557 current_block()->Finish(branch);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 // (c) Reachable only normally. 2599 // (c) Reachable only normally.
2584 set_current_block(normal_block); 2600 set_current_block(normal_block);
2585 } else { 2601 } else {
2586 // (d) Reachable both ways. 2602 // (d) Reachable both ways.
2587 HBasicBlock* join = CreateJoin(fall_through_block, 2603 HBasicBlock* join = CreateJoin(fall_through_block,
2588 normal_block, 2604 normal_block,
2589 clause->EntryId()); 2605 clause->EntryId());
2590 set_current_block(join); 2606 set_current_block(join);
2591 } 2607 }
2592 2608
2593 VisitStatements(clause->statements()); 2609 CHECK_BAILOUT(VisitStatements(clause->statements()));
2594 CHECK_BAILOUT;
2595 fall_through_block = current_block(); 2610 fall_through_block = current_block();
2596 } 2611 }
2597 } 2612 }
2598 2613
2599 // Create an up-to-3-way join. Use the break block if it exists since 2614 // Create an up-to-3-way join. Use the break block if it exists since
2600 // it's already a join block. 2615 // it's already a join block.
2601 HBasicBlock* break_block = break_info.break_block(); 2616 HBasicBlock* break_block = break_info.break_block();
2602 if (break_block == NULL) { 2617 if (break_block == NULL) {
2603 set_current_block(CreateJoin(fall_through_block, 2618 set_current_block(CreateJoin(fall_through_block,
2604 last_block, 2619 last_block,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 2659
2645 AddSimulate(osr_entry_id); 2660 AddSimulate(osr_entry_id);
2646 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); 2661 AddInstruction(new(zone()) HOsrEntry(osr_entry_id));
2647 current_block()->Goto(loop_predecessor); 2662 current_block()->Goto(loop_predecessor);
2648 loop_predecessor->SetJoinId(statement->EntryId()); 2663 loop_predecessor->SetJoinId(statement->EntryId());
2649 set_current_block(loop_predecessor); 2664 set_current_block(loop_predecessor);
2650 } 2665 }
2651 2666
2652 2667
2653 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 2668 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
2669 ASSERT(!HasStackOverflow());
2670 ASSERT(current_block() != NULL);
2671 ASSERT(current_block()->HasPredecessor());
2654 ASSERT(current_block() != NULL); 2672 ASSERT(current_block() != NULL);
2655 PreProcessOsrEntry(stmt); 2673 PreProcessOsrEntry(stmt);
2656 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 2674 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
2657 current_block()->Goto(loop_entry, false); 2675 current_block()->Goto(loop_entry, false);
2658 set_current_block(loop_entry); 2676 set_current_block(loop_entry);
2659 2677
2660 BreakAndContinueInfo break_info(stmt); 2678 BreakAndContinueInfo break_info(stmt);
2661 { BreakAndContinueScope push(&break_info, this); 2679 { BreakAndContinueScope push(&break_info, this);
2662 Visit(stmt->body()); 2680 CHECK_BAILOUT(Visit(stmt->body()));
2663 CHECK_BAILOUT;
2664 } 2681 }
2665 HBasicBlock* body_exit = 2682 HBasicBlock* body_exit =
2666 JoinContinue(stmt, current_block(), break_info.continue_block()); 2683 JoinContinue(stmt, current_block(), break_info.continue_block());
2667 HBasicBlock* loop_successor = NULL; 2684 HBasicBlock* loop_successor = NULL;
2668 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { 2685 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) {
2669 set_current_block(body_exit); 2686 set_current_block(body_exit);
2670 // The block for a true condition, the actual predecessor block of the 2687 // The block for a true condition, the actual predecessor block of the
2671 // back edge. 2688 // back edge.
2672 body_exit = graph()->CreateBasicBlock(); 2689 body_exit = graph()->CreateBasicBlock();
2673 loop_successor = graph()->CreateBasicBlock(); 2690 loop_successor = graph()->CreateBasicBlock();
2674 VISIT_FOR_CONTROL(stmt->cond(), body_exit, loop_successor); 2691 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_exit, loop_successor));
2675 body_exit->SetJoinId(stmt->BackEdgeId()); 2692 if (body_exit->HasPredecessor()) {
2676 loop_successor->SetJoinId(stmt->ExitId()); 2693 body_exit->SetJoinId(stmt->BackEdgeId());
2694 } else {
2695 body_exit = NULL;
2696 }
2697 if (loop_successor->HasPredecessor()) {
2698 loop_successor->SetJoinId(stmt->ExitId());
2699 } else {
2700 loop_successor = NULL;
2701 }
2677 } 2702 }
2678 HBasicBlock* loop_exit = CreateLoop(stmt, 2703 HBasicBlock* loop_exit = CreateLoop(stmt,
2679 loop_entry, 2704 loop_entry,
2680 body_exit, 2705 body_exit,
2681 loop_successor, 2706 loop_successor,
2682 break_info.break_block()); 2707 break_info.break_block());
2683 set_current_block(loop_exit); 2708 set_current_block(loop_exit);
2684 } 2709 }
2685 2710
2686 2711
2687 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 2712 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
2713 ASSERT(!HasStackOverflow());
2714 ASSERT(current_block() != NULL);
2715 ASSERT(current_block()->HasPredecessor());
2688 ASSERT(current_block() != NULL); 2716 ASSERT(current_block() != NULL);
2689 PreProcessOsrEntry(stmt); 2717 PreProcessOsrEntry(stmt);
2690 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 2718 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
2691 current_block()->Goto(loop_entry, false); 2719 current_block()->Goto(loop_entry, false);
2692 set_current_block(loop_entry); 2720 set_current_block(loop_entry);
2693 2721
2694 // If the condition is constant true, do not generate a branch. 2722 // If the condition is constant true, do not generate a branch.
2695 HBasicBlock* loop_successor = NULL; 2723 HBasicBlock* loop_successor = NULL;
2696 if (!stmt->cond()->ToBooleanIsTrue()) { 2724 if (!stmt->cond()->ToBooleanIsTrue()) {
2697 HBasicBlock* body_entry = graph()->CreateBasicBlock(); 2725 HBasicBlock* body_entry = graph()->CreateBasicBlock();
2698 loop_successor = graph()->CreateBasicBlock(); 2726 loop_successor = graph()->CreateBasicBlock();
2699 VISIT_FOR_CONTROL(stmt->cond(), body_entry, loop_successor); 2727 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
2700 body_entry->SetJoinId(stmt->BodyId()); 2728 if (body_entry->HasPredecessor()) {
2701 loop_successor->SetJoinId(stmt->ExitId()); 2729 body_entry->SetJoinId(stmt->BodyId());
2702 set_current_block(body_entry); 2730 set_current_block(body_entry);
2731 }
2732 if (loop_successor->HasPredecessor()) {
2733 loop_successor->SetJoinId(stmt->ExitId());
2734 } else {
2735 loop_successor = NULL;
2736 }
2703 } 2737 }
2704 2738
2705 BreakAndContinueInfo break_info(stmt); 2739 BreakAndContinueInfo break_info(stmt);
2706 { BreakAndContinueScope push(&break_info, this); 2740 if (current_block() != NULL) {
2707 Visit(stmt->body()); 2741 BreakAndContinueScope push(&break_info, this);
2708 CHECK_BAILOUT; 2742 CHECK_BAILOUT(Visit(stmt->body()));
2709 } 2743 }
2710 HBasicBlock* body_exit = 2744 HBasicBlock* body_exit =
2711 JoinContinue(stmt, current_block(), break_info.continue_block()); 2745 JoinContinue(stmt, current_block(), break_info.continue_block());
2712 HBasicBlock* loop_exit = CreateLoop(stmt, 2746 HBasicBlock* loop_exit = CreateLoop(stmt,
2713 loop_entry, 2747 loop_entry,
2714 body_exit, 2748 body_exit,
2715 loop_successor, 2749 loop_successor,
2716 break_info.break_block()); 2750 break_info.break_block());
2717 set_current_block(loop_exit); 2751 set_current_block(loop_exit);
2718 } 2752 }
2719 2753
2720 2754
2721 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { 2755 void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
2756 ASSERT(!HasStackOverflow());
2757 ASSERT(current_block() != NULL);
2758 ASSERT(current_block()->HasPredecessor());
2722 if (stmt->init() != NULL) { 2759 if (stmt->init() != NULL) {
2723 Visit(stmt->init()); 2760 CHECK_ALIVE(Visit(stmt->init()));
2724 CHECK_BAILOUT;
2725 } 2761 }
2726 ASSERT(current_block() != NULL); 2762 ASSERT(current_block() != NULL);
2727 PreProcessOsrEntry(stmt); 2763 PreProcessOsrEntry(stmt);
2728 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 2764 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
2729 current_block()->Goto(loop_entry, false); 2765 current_block()->Goto(loop_entry, false);
2730 set_current_block(loop_entry); 2766 set_current_block(loop_entry);
2731 2767
2732 HBasicBlock* loop_successor = NULL; 2768 HBasicBlock* loop_successor = NULL;
2733 if (stmt->cond() != NULL) { 2769 if (stmt->cond() != NULL) {
2734 HBasicBlock* body_entry = graph()->CreateBasicBlock(); 2770 HBasicBlock* body_entry = graph()->CreateBasicBlock();
2735 loop_successor = graph()->CreateBasicBlock(); 2771 loop_successor = graph()->CreateBasicBlock();
2736 VISIT_FOR_CONTROL(stmt->cond(), body_entry, loop_successor); 2772 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
2737 body_entry->SetJoinId(stmt->BodyId()); 2773 if (body_entry->HasPredecessor()) {
2738 loop_successor->SetJoinId(stmt->ExitId()); 2774 body_entry->SetJoinId(stmt->BodyId());
2739 set_current_block(body_entry); 2775 set_current_block(body_entry);
2776 }
2777 if (loop_successor->HasPredecessor()) {
2778 loop_successor->SetJoinId(stmt->ExitId());
2779 } else {
2780 loop_successor = NULL;
2781 }
2740 } 2782 }
2741 2783
2742 BreakAndContinueInfo break_info(stmt); 2784 BreakAndContinueInfo break_info(stmt);
2743 { BreakAndContinueScope push(&break_info, this); 2785 if (current_block() != NULL) {
2744 Visit(stmt->body()); 2786 BreakAndContinueScope push(&break_info, this);
2745 CHECK_BAILOUT; 2787 CHECK_BAILOUT(Visit(stmt->body()));
2746 } 2788 }
2747 HBasicBlock* body_exit = 2789 HBasicBlock* body_exit =
2748 JoinContinue(stmt, current_block(), break_info.continue_block()); 2790 JoinContinue(stmt, current_block(), break_info.continue_block());
2749 2791
2750 if (stmt->next() != NULL && body_exit != NULL) { 2792 if (stmt->next() != NULL && body_exit != NULL) {
2751 set_current_block(body_exit); 2793 set_current_block(body_exit);
2752 Visit(stmt->next()); 2794 CHECK_BAILOUT(Visit(stmt->next()));
2753 CHECK_BAILOUT;
2754 body_exit = current_block(); 2795 body_exit = current_block();
2755 } 2796 }
2756 2797
2757 HBasicBlock* loop_exit = CreateLoop(stmt, 2798 HBasicBlock* loop_exit = CreateLoop(stmt,
2758 loop_entry, 2799 loop_entry,
2759 body_exit, 2800 body_exit,
2760 loop_successor, 2801 loop_successor,
2761 break_info.break_block()); 2802 break_info.break_block());
2762 set_current_block(loop_exit); 2803 set_current_block(loop_exit);
2763 } 2804 }
2764 2805
2765 2806
2766 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 2807 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
2767 BAILOUT("ForInStatement"); 2808 ASSERT(!HasStackOverflow());
danno 2011/04/13 12:00:43 Turn these three checks into a single check, like
Kevin Millikin (Chromium) 2011/04/13 12:23:24 OK, I'll do that.
2809 ASSERT(current_block() != NULL);
2810 ASSERT(current_block()->HasPredecessor());
2811 return Bailout("ForInStatement");
2768 } 2812 }
2769 2813
2770 2814
2771 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 2815 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
2772 BAILOUT("TryCatchStatement"); 2816 ASSERT(!HasStackOverflow());
2817 ASSERT(current_block() != NULL);
2818 ASSERT(current_block()->HasPredecessor());
2819 return Bailout("TryCatchStatement");
2773 } 2820 }
2774 2821
2775 2822
2776 void HGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 2823 void HGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
2777 BAILOUT("TryFinallyStatement"); 2824 ASSERT(!HasStackOverflow());
2825 ASSERT(current_block() != NULL);
2826 ASSERT(current_block()->HasPredecessor());
2827 return Bailout("TryFinallyStatement");
2778 } 2828 }
2779 2829
2780 2830
2781 void HGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 2831 void HGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
2782 BAILOUT("DebuggerStatement"); 2832 ASSERT(!HasStackOverflow());
2833 ASSERT(current_block() != NULL);
2834 ASSERT(current_block()->HasPredecessor());
2835 return Bailout("DebuggerStatement");
2783 } 2836 }
2784 2837
2785 2838
2786 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( 2839 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
2787 Code* unoptimized_code, FunctionLiteral* expr) { 2840 Code* unoptimized_code, FunctionLiteral* expr) {
2788 int start_position = expr->start_position(); 2841 int start_position = expr->start_position();
2789 RelocIterator it(unoptimized_code); 2842 RelocIterator it(unoptimized_code);
2790 for (;!it.done(); it.next()) { 2843 for (;!it.done(); it.next()) {
2791 RelocInfo* rinfo = it.rinfo(); 2844 RelocInfo* rinfo = it.rinfo();
2792 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; 2845 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
2793 Object* obj = rinfo->target_object(); 2846 Object* obj = rinfo->target_object();
2794 if (obj->IsSharedFunctionInfo()) { 2847 if (obj->IsSharedFunctionInfo()) {
2795 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 2848 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
2796 if (shared->start_position() == start_position) { 2849 if (shared->start_position() == start_position) {
2797 return Handle<SharedFunctionInfo>(shared); 2850 return Handle<SharedFunctionInfo>(shared);
2798 } 2851 }
2799 } 2852 }
2800 } 2853 }
2801 2854
2802 return Handle<SharedFunctionInfo>(); 2855 return Handle<SharedFunctionInfo>();
2803 } 2856 }
2804 2857
2805 2858
2806 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 2859 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
2860 ASSERT(!HasStackOverflow());
2861 ASSERT(current_block() != NULL);
2862 ASSERT(current_block()->HasPredecessor());
2807 Handle<SharedFunctionInfo> shared_info = 2863 Handle<SharedFunctionInfo> shared_info =
2808 SearchSharedFunctionInfo(info()->shared_info()->code(), 2864 SearchSharedFunctionInfo(info()->shared_info()->code(),
2809 expr); 2865 expr);
2810 if (shared_info.is_null()) { 2866 if (shared_info.is_null()) {
2811 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); 2867 shared_info = Compiler::BuildFunctionInfo(expr, info()->script());
2812 } 2868 }
2813 CHECK_BAILOUT; 2869 // We also have a stack overflow if the recursive compilation did.
2870 if (HasStackOverflow()) return;
2814 HFunctionLiteral* instr = 2871 HFunctionLiteral* instr =
2815 new(zone()) HFunctionLiteral(shared_info, expr->pretenure()); 2872 new(zone()) HFunctionLiteral(shared_info, expr->pretenure());
2816 ast_context()->ReturnInstruction(instr, expr->id()); 2873 ast_context()->ReturnInstruction(instr, expr->id());
2817 } 2874 }
2818 2875
2819 2876
2820 void HGraphBuilder::VisitSharedFunctionInfoLiteral( 2877 void HGraphBuilder::VisitSharedFunctionInfoLiteral(
2821 SharedFunctionInfoLiteral* expr) { 2878 SharedFunctionInfoLiteral* expr) {
2822 BAILOUT("SharedFunctionInfoLiteral"); 2879 ASSERT(!HasStackOverflow());
2880 ASSERT(current_block() != NULL);
2881 ASSERT(current_block()->HasPredecessor());
2882 return Bailout("SharedFunctionInfoLiteral");
2823 } 2883 }
2824 2884
2825 2885
2826 void HGraphBuilder::VisitConditional(Conditional* expr) { 2886 void HGraphBuilder::VisitConditional(Conditional* expr) {
2887 ASSERT(!HasStackOverflow());
2888 ASSERT(current_block() != NULL);
2889 ASSERT(current_block()->HasPredecessor());
2827 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 2890 HBasicBlock* cond_true = graph()->CreateBasicBlock();
2828 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 2891 HBasicBlock* cond_false = graph()->CreateBasicBlock();
2829 VISIT_FOR_CONTROL(expr->condition(), cond_true, cond_false); 2892 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false));
2830 cond_true->SetJoinId(expr->ThenId());
2831 cond_false->SetJoinId(expr->ElseId());
2832 2893
2833 // Visit the true and false subexpressions in the same AST context as the 2894 // Visit the true and false subexpressions in the same AST context as the
2834 // whole expression. 2895 // whole expression.
2835 set_current_block(cond_true); 2896 if (cond_true->HasPredecessor()) {
2836 Visit(expr->then_expression()); 2897 cond_true->SetJoinId(expr->ThenId());
2837 CHECK_BAILOUT; 2898 set_current_block(cond_true);
2838 HBasicBlock* other = current_block(); 2899 CHECK_BAILOUT(Visit(expr->then_expression()));
2900 cond_true = current_block();
2901 } else {
2902 cond_true = NULL;
2903 }
2839 2904
2840 set_current_block(cond_false); 2905 if (cond_false->HasPredecessor()) {
2841 Visit(expr->else_expression()); 2906 cond_false->SetJoinId(expr->ElseId());
2842 CHECK_BAILOUT; 2907 set_current_block(cond_false);
2908 CHECK_BAILOUT(Visit(expr->else_expression()));
2909 cond_false = current_block();
2910 } else {
2911 cond_false = NULL;
2912 }
2843 2913
2844 if (!ast_context()->IsTest()) { 2914 if (!ast_context()->IsTest()) {
2845 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); 2915 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
2846 set_current_block(join); 2916 set_current_block(join);
2847 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 2917 if (join != NULL && !ast_context()->IsEffect()) {
2918 ast_context()->ReturnValue(Pop());
2919 }
2848 } 2920 }
2849 } 2921 }
2850 2922
2851 2923
2852 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty( 2924 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty(
2853 Variable* var, LookupResult* lookup, bool is_store) { 2925 Variable* var, LookupResult* lookup, bool is_store) {
2854 if (var->is_this() || !info()->has_global_object()) { 2926 if (var->is_this() || !info()->has_global_object()) {
2855 return kUseGeneric; 2927 return kUseGeneric;
2856 } 2928 }
2857 Handle<GlobalObject> global(info()->global_object()); 2929 Handle<GlobalObject> global(info()->global_object());
(...skipping 16 matching lines...) Expand all
2874 int length = info()->scope()->ContextChainLength(var->scope()); 2946 int length = info()->scope()->ContextChainLength(var->scope());
2875 while (length-- > 0) { 2947 while (length-- > 0) {
2876 context = new(zone()) HOuterContext(context); 2948 context = new(zone()) HOuterContext(context);
2877 AddInstruction(context); 2949 AddInstruction(context);
2878 } 2950 }
2879 return context; 2951 return context;
2880 } 2952 }
2881 2953
2882 2954
2883 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 2955 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
2956 ASSERT(!HasStackOverflow());
2957 ASSERT(current_block() != NULL);
2958 ASSERT(current_block()->HasPredecessor());
2884 Variable* variable = expr->AsVariable(); 2959 Variable* variable = expr->AsVariable();
2885 if (variable == NULL) { 2960 if (variable == NULL) {
2886 BAILOUT("reference to rewritten variable"); 2961 return Bailout("reference to rewritten variable");
2887 } else if (variable->IsStackAllocated()) { 2962 } else if (variable->IsStackAllocated()) {
2888 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { 2963 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) {
2889 BAILOUT("unsupported context for arguments object"); 2964 return Bailout("unsupported context for arguments object");
2890 } 2965 }
2891 ast_context()->ReturnValue(environment()->Lookup(variable)); 2966 ast_context()->ReturnValue(environment()->Lookup(variable));
2892 } else if (variable->IsContextSlot()) { 2967 } else if (variable->IsContextSlot()) {
2893 if (variable->mode() == Variable::CONST) { 2968 if (variable->mode() == Variable::CONST) {
2894 BAILOUT("reference to const context slot"); 2969 return Bailout("reference to const context slot");
2895 } 2970 }
2896 HValue* context = BuildContextChainWalk(variable); 2971 HValue* context = BuildContextChainWalk(variable);
2897 int index = variable->AsSlot()->index(); 2972 int index = variable->AsSlot()->index();
2898 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index); 2973 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index);
2899 ast_context()->ReturnInstruction(instr, expr->id()); 2974 ast_context()->ReturnInstruction(instr, expr->id());
2900 } else if (variable->is_global()) { 2975 } else if (variable->is_global()) {
2901 LookupResult lookup; 2976 LookupResult lookup;
2902 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false); 2977 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
2903 2978
2904 if (type == kUseCell && 2979 if (type == kUseCell &&
(...skipping 15 matching lines...) Expand all
2920 HLoadGlobalGeneric* instr = 2995 HLoadGlobalGeneric* instr =
2921 new(zone()) HLoadGlobalGeneric(context, 2996 new(zone()) HLoadGlobalGeneric(context,
2922 global_object, 2997 global_object,
2923 variable->name(), 2998 variable->name(),
2924 ast_context()->is_for_typeof()); 2999 ast_context()->is_for_typeof());
2925 instr->set_position(expr->position()); 3000 instr->set_position(expr->position());
2926 ASSERT(instr->HasSideEffects()); 3001 ASSERT(instr->HasSideEffects());
2927 ast_context()->ReturnInstruction(instr, expr->id()); 3002 ast_context()->ReturnInstruction(instr, expr->id());
2928 } 3003 }
2929 } else { 3004 } else {
2930 BAILOUT("reference to a variable which requires dynamic lookup"); 3005 return Bailout("reference to a variable which requires dynamic lookup");
2931 } 3006 }
2932 } 3007 }
2933 3008
2934 3009
2935 void HGraphBuilder::VisitLiteral(Literal* expr) { 3010 void HGraphBuilder::VisitLiteral(Literal* expr) {
3011 ASSERT(!HasStackOverflow());
3012 ASSERT(current_block() != NULL);
3013 ASSERT(current_block()->HasPredecessor());
2936 HConstant* instr = 3014 HConstant* instr =
2937 new(zone()) HConstant(expr->handle(), Representation::Tagged()); 3015 new(zone()) HConstant(expr->handle(), Representation::Tagged());
2938 ast_context()->ReturnInstruction(instr, expr->id()); 3016 ast_context()->ReturnInstruction(instr, expr->id());
2939 } 3017 }
2940 3018
2941 3019
2942 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 3020 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
3021 ASSERT(!HasStackOverflow());
3022 ASSERT(current_block() != NULL);
3023 ASSERT(current_block()->HasPredecessor());
2943 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(), 3024 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(),
2944 expr->flags(), 3025 expr->flags(),
2945 expr->literal_index()); 3026 expr->literal_index());
2946 ast_context()->ReturnInstruction(instr, expr->id()); 3027 ast_context()->ReturnInstruction(instr, expr->id());
2947 } 3028 }
2948 3029
2949 3030
2950 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 3031 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
3032 ASSERT(!HasStackOverflow());
3033 ASSERT(current_block() != NULL);
3034 ASSERT(current_block()->HasPredecessor());
2951 HContext* context = new(zone()) HContext; 3035 HContext* context = new(zone()) HContext;
2952 AddInstruction(context); 3036 AddInstruction(context);
2953 HObjectLiteral* literal = 3037 HObjectLiteral* literal =
2954 new(zone()) HObjectLiteral(context, 3038 new(zone()) HObjectLiteral(context,
2955 expr->constant_properties(), 3039 expr->constant_properties(),
2956 expr->fast_elements(), 3040 expr->fast_elements(),
2957 expr->literal_index(), 3041 expr->literal_index(),
2958 expr->depth(), 3042 expr->depth(),
2959 expr->has_function()); 3043 expr->has_function());
2960 // The object is expected in the bailout environment during computation 3044 // The object is expected in the bailout environment during computation
2961 // of the property values and is the value of the entire expression. 3045 // of the property values and is the value of the entire expression.
2962 PushAndAdd(literal); 3046 PushAndAdd(literal);
2963 3047
2964 expr->CalculateEmitStore(); 3048 expr->CalculateEmitStore();
2965 3049
2966 for (int i = 0; i < expr->properties()->length(); i++) { 3050 for (int i = 0; i < expr->properties()->length(); i++) {
2967 ObjectLiteral::Property* property = expr->properties()->at(i); 3051 ObjectLiteral::Property* property = expr->properties()->at(i);
2968 if (property->IsCompileTimeValue()) continue; 3052 if (property->IsCompileTimeValue()) continue;
2969 3053
2970 Literal* key = property->key(); 3054 Literal* key = property->key();
2971 Expression* value = property->value(); 3055 Expression* value = property->value();
2972 3056
2973 switch (property->kind()) { 3057 switch (property->kind()) {
2974 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 3058 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2975 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 3059 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
2976 // Fall through. 3060 // Fall through.
2977 case ObjectLiteral::Property::COMPUTED: 3061 case ObjectLiteral::Property::COMPUTED:
2978 if (key->handle()->IsSymbol()) { 3062 if (key->handle()->IsSymbol()) {
2979 if (property->emit_store()) { 3063 if (property->emit_store()) {
2980 VISIT_FOR_VALUE(value); 3064 CHECK_ALIVE(VisitForValue(value));
2981 HValue* value = Pop(); 3065 HValue* value = Pop();
2982 Handle<String> name = Handle<String>::cast(key->handle()); 3066 Handle<String> name = Handle<String>::cast(key->handle());
2983 HStoreNamedGeneric* store = 3067 HStoreNamedGeneric* store =
2984 new(zone()) HStoreNamedGeneric( 3068 new(zone()) HStoreNamedGeneric(
2985 context, 3069 context,
2986 literal, 3070 literal,
2987 name, 3071 name,
2988 value, 3072 value,
2989 function_strict_mode()); 3073 function_strict_mode());
2990 AddInstruction(store); 3074 AddInstruction(store);
2991 AddSimulate(key->id()); 3075 AddSimulate(key->id());
2992 } else { 3076 } else {
2993 VISIT_FOR_EFFECT(value); 3077 CHECK_ALIVE(VisitForEffect(value));
2994 } 3078 }
2995 break; 3079 break;
2996 } 3080 }
2997 // Fall through. 3081 // Fall through.
2998 case ObjectLiteral::Property::PROTOTYPE: 3082 case ObjectLiteral::Property::PROTOTYPE:
2999 case ObjectLiteral::Property::SETTER: 3083 case ObjectLiteral::Property::SETTER:
3000 case ObjectLiteral::Property::GETTER: 3084 case ObjectLiteral::Property::GETTER:
3001 BAILOUT("Object literal with complex property"); 3085 return Bailout("Object literal with complex property");
3002 default: UNREACHABLE(); 3086 default: UNREACHABLE();
3003 } 3087 }
3004 } 3088 }
3005 3089
3006 if (expr->has_function()) { 3090 if (expr->has_function()) {
3007 // Return the result of the transformation to fast properties 3091 // Return the result of the transformation to fast properties
3008 // instead of the original since this operation changes the map 3092 // instead of the original since this operation changes the map
3009 // of the object. This makes sure that the original object won't 3093 // of the object. This makes sure that the original object won't
3010 // be used by other optimized code before it is transformed 3094 // be used by other optimized code before it is transformed
3011 // (e.g. because of code motion). 3095 // (e.g. because of code motion).
3012 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); 3096 HToFastProperties* result = new(zone()) HToFastProperties(Pop());
3013 AddInstruction(result); 3097 AddInstruction(result);
3014 ast_context()->ReturnValue(result); 3098 ast_context()->ReturnValue(result);
3015 } else { 3099 } else {
3016 ast_context()->ReturnValue(Pop()); 3100 ast_context()->ReturnValue(Pop());
3017 } 3101 }
3018 } 3102 }
3019 3103
3020 3104
3021 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 3105 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
3106 ASSERT(!HasStackOverflow());
3107 ASSERT(current_block() != NULL);
3108 ASSERT(current_block()->HasPredecessor());
3022 ZoneList<Expression*>* subexprs = expr->values(); 3109 ZoneList<Expression*>* subexprs = expr->values();
3023 int length = subexprs->length(); 3110 int length = subexprs->length();
3024 3111
3025 HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(), 3112 HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(),
3026 length, 3113 length,
3027 expr->literal_index(), 3114 expr->literal_index(),
3028 expr->depth()); 3115 expr->depth());
3029 // The array is expected in the bailout environment during computation 3116 // The array is expected in the bailout environment during computation
3030 // of the property values and is the value of the entire expression. 3117 // of the property values and is the value of the entire expression.
3031 PushAndAdd(literal); 3118 PushAndAdd(literal);
3032 3119
3033 HLoadElements* elements = NULL; 3120 HLoadElements* elements = NULL;
3034 3121
3035 for (int i = 0; i < length; i++) { 3122 for (int i = 0; i < length; i++) {
3036 Expression* subexpr = subexprs->at(i); 3123 Expression* subexpr = subexprs->at(i);
3037 // If the subexpression is a literal or a simple materialized literal it 3124 // If the subexpression is a literal or a simple materialized literal it
3038 // is already set in the cloned array. 3125 // is already set in the cloned array.
3039 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 3126 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
3040 3127
3041 VISIT_FOR_VALUE(subexpr); 3128 CHECK_ALIVE(VisitForValue(subexpr));
3042 HValue* value = Pop(); 3129 HValue* value = Pop();
3043 if (!Smi::IsValid(i)) BAILOUT("Non-smi key in array literal"); 3130 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal");
3044 3131
3045 // Load the elements array before the first store. 3132 // Load the elements array before the first store.
3046 if (elements == NULL) { 3133 if (elements == NULL) {
3047 elements = new(zone()) HLoadElements(literal); 3134 elements = new(zone()) HLoadElements(literal);
3048 AddInstruction(elements); 3135 AddInstruction(elements);
3049 } 3136 }
3050 3137
3051 HValue* key = AddInstruction( 3138 HValue* key = AddInstruction(
3052 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), 3139 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
3053 Representation::Integer32())); 3140 Representation::Integer32()));
3054 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); 3141 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
3055 AddSimulate(expr->GetIdForElement(i)); 3142 AddSimulate(expr->GetIdForElement(i));
3056 } 3143 }
3057 ast_context()->ReturnValue(Pop()); 3144 ast_context()->ReturnValue(Pop());
3058 } 3145 }
3059 3146
3060 3147
3061 void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) { 3148 void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
3062 BAILOUT("CatchExtensionObject"); 3149 ASSERT(!HasStackOverflow());
3150 ASSERT(current_block() != NULL);
3151 ASSERT(current_block()->HasPredecessor());
3152 return Bailout("CatchExtensionObject");
3063 } 3153 }
3064 3154
3065 3155
3066 // Sets the lookup result and returns true if the store can be inlined. 3156 // Sets the lookup result and returns true if the store can be inlined.
3067 static bool ComputeStoredField(Handle<Map> type, 3157 static bool ComputeStoredField(Handle<Map> type,
3068 Handle<String> name, 3158 Handle<String> name,
3069 LookupResult* lookup) { 3159 LookupResult* lookup) {
3070 type->LookupInDescriptors(NULL, *name, lookup); 3160 type->LookupInDescriptors(NULL, *name, lookup);
3071 if (!lookup->IsPropertyOrTransition()) return false; 3161 if (!lookup->IsPropertyOrTransition()) return false;
3072 if (lookup->type() == FIELD) return true; 3162 if (lookup->type() == FIELD) return true;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
3231 join->SetJoinId(expr->id()); 3321 join->SetJoinId(expr->id());
3232 set_current_block(join); 3322 set_current_block(join);
3233 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 3323 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
3234 } 3324 }
3235 3325
3236 3326
3237 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 3327 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
3238 Property* prop = expr->target()->AsProperty(); 3328 Property* prop = expr->target()->AsProperty();
3239 ASSERT(prop != NULL); 3329 ASSERT(prop != NULL);
3240 expr->RecordTypeFeedback(oracle()); 3330 expr->RecordTypeFeedback(oracle());
3241 VISIT_FOR_VALUE(prop->obj()); 3331 CHECK_ALIVE(VisitForValue(prop->obj()));
3242 3332
3243 HValue* value = NULL; 3333 HValue* value = NULL;
3244 HInstruction* instr = NULL; 3334 HInstruction* instr = NULL;
3245 3335
3246 if (prop->key()->IsPropertyName()) { 3336 if (prop->key()->IsPropertyName()) {
3247 // Named store. 3337 // Named store.
3248 VISIT_FOR_VALUE(expr->value()); 3338 CHECK_ALIVE(VisitForValue(expr->value()));
3249 value = Pop(); 3339 value = Pop();
3250 HValue* object = Pop(); 3340 HValue* object = Pop();
3251 3341
3252 Literal* key = prop->key()->AsLiteral(); 3342 Literal* key = prop->key()->AsLiteral();
3253 Handle<String> name = Handle<String>::cast(key->handle()); 3343 Handle<String> name = Handle<String>::cast(key->handle());
3254 ASSERT(!name.is_null()); 3344 ASSERT(!name.is_null());
3255 3345
3256 ZoneMapList* types = expr->GetReceiverTypes(); 3346 ZoneMapList* types = expr->GetReceiverTypes();
3257 LookupResult lookup; 3347 LookupResult lookup;
3258 3348
3259 if (expr->IsMonomorphic()) { 3349 if (expr->IsMonomorphic()) {
3260 instr = BuildStoreNamed(object, value, expr); 3350 instr = BuildStoreNamed(object, value, expr);
3261 3351
3262 } else if (types != NULL && types->length() > 1) { 3352 } else if (types != NULL && types->length() > 1) {
3263 HandlePolymorphicStoreNamedField(expr, object, value, types, name); 3353 HandlePolymorphicStoreNamedField(expr, object, value, types, name);
3264 return; 3354 return;
3265 3355
3266 } else { 3356 } else {
3267 instr = BuildStoreNamedGeneric(object, name, value); 3357 instr = BuildStoreNamedGeneric(object, name, value);
3268 } 3358 }
3269 3359
3270 } else { 3360 } else {
3271 // Keyed store. 3361 // Keyed store.
3272 VISIT_FOR_VALUE(prop->key()); 3362 CHECK_ALIVE(VisitForValue(prop->key()));
3273 VISIT_FOR_VALUE(expr->value()); 3363 CHECK_ALIVE(VisitForValue(expr->value()));
3274 value = Pop(); 3364 value = Pop();
3275 HValue* key = Pop(); 3365 HValue* key = Pop();
3276 HValue* object = Pop(); 3366 HValue* object = Pop();
3277 instr = BuildStoreKeyed(object, key, value, expr); 3367 instr = BuildStoreKeyed(object, key, value, expr);
3278 } 3368 }
3279 Push(value); 3369 Push(value);
3280 instr->set_position(expr->position()); 3370 instr->set_position(expr->position());
3281 AddInstruction(instr); 3371 AddInstruction(instr);
3282 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3372 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3283 ast_context()->ReturnValue(Pop()); 3373 ast_context()->ReturnValue(Pop());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 VariableProxy* proxy = target->AsVariableProxy(); 3415 VariableProxy* proxy = target->AsVariableProxy();
3326 Variable* var = proxy->AsVariable(); 3416 Variable* var = proxy->AsVariable();
3327 Property* prop = target->AsProperty(); 3417 Property* prop = target->AsProperty();
3328 ASSERT(var == NULL || prop == NULL); 3418 ASSERT(var == NULL || prop == NULL);
3329 3419
3330 // We have a second position recorded in the FullCodeGenerator to have 3420 // We have a second position recorded in the FullCodeGenerator to have
3331 // type feedback for the binary operation. 3421 // type feedback for the binary operation.
3332 BinaryOperation* operation = expr->binary_operation(); 3422 BinaryOperation* operation = expr->binary_operation();
3333 3423
3334 if (var != NULL) { 3424 if (var != NULL) {
3335 VISIT_FOR_VALUE(operation); 3425 CHECK_ALIVE(VisitForValue(operation));
3336 3426
3337 if (var->is_global()) { 3427 if (var->is_global()) {
3338 HandleGlobalVariableAssignment(var, 3428 HandleGlobalVariableAssignment(var,
3339 Top(), 3429 Top(),
3340 expr->position(), 3430 expr->position(),
3341 expr->AssignmentId()); 3431 expr->AssignmentId());
3342 } else if (var->IsStackAllocated()) { 3432 } else if (var->IsStackAllocated()) {
3343 Bind(var, Top()); 3433 Bind(var, Top());
3344 } else if (var->IsContextSlot()) { 3434 } else if (var->IsContextSlot()) {
3345 HValue* context = BuildContextChainWalk(var); 3435 HValue* context = BuildContextChainWalk(var);
3346 int index = var->AsSlot()->index(); 3436 int index = var->AsSlot()->index();
3347 HStoreContextSlot* instr = 3437 HStoreContextSlot* instr =
3348 new(zone()) HStoreContextSlot(context, index, Top()); 3438 new(zone()) HStoreContextSlot(context, index, Top());
3349 AddInstruction(instr); 3439 AddInstruction(instr);
3350 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3440 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3351 } else { 3441 } else {
3352 BAILOUT("compound assignment to lookup slot"); 3442 return Bailout("compound assignment to lookup slot");
3353 } 3443 }
3354 ast_context()->ReturnValue(Pop()); 3444 ast_context()->ReturnValue(Pop());
3355 3445
3356 } else if (prop != NULL) { 3446 } else if (prop != NULL) {
3357 prop->RecordTypeFeedback(oracle()); 3447 prop->RecordTypeFeedback(oracle());
3358 3448
3359 if (prop->key()->IsPropertyName()) { 3449 if (prop->key()->IsPropertyName()) {
3360 // Named property. 3450 // Named property.
3361 VISIT_FOR_VALUE(prop->obj()); 3451 CHECK_ALIVE(VisitForValue(prop->obj()));
3362 HValue* obj = Top(); 3452 HValue* obj = Top();
3363 3453
3364 HInstruction* load = NULL; 3454 HInstruction* load = NULL;
3365 if (prop->IsMonomorphic()) { 3455 if (prop->IsMonomorphic()) {
3366 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 3456 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
3367 Handle<Map> map = prop->GetReceiverTypes()->first(); 3457 Handle<Map> map = prop->GetReceiverTypes()->first();
3368 load = BuildLoadNamed(obj, prop, map, name); 3458 load = BuildLoadNamed(obj, prop, map, name);
3369 } else { 3459 } else {
3370 load = BuildLoadNamedGeneric(obj, prop); 3460 load = BuildLoadNamedGeneric(obj, prop);
3371 } 3461 }
3372 PushAndAdd(load); 3462 PushAndAdd(load);
3373 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); 3463 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId());
3374 3464
3375 VISIT_FOR_VALUE(expr->value()); 3465 CHECK_ALIVE(VisitForValue(expr->value()));
3376 HValue* right = Pop(); 3466 HValue* right = Pop();
3377 HValue* left = Pop(); 3467 HValue* left = Pop();
3378 3468
3379 HInstruction* instr = BuildBinaryOperation(operation, left, right); 3469 HInstruction* instr = BuildBinaryOperation(operation, left, right);
3380 PushAndAdd(instr); 3470 PushAndAdd(instr);
3381 if (instr->HasSideEffects()) AddSimulate(operation->id()); 3471 if (instr->HasSideEffects()) AddSimulate(operation->id());
3382 3472
3383 HInstruction* store = BuildStoreNamed(obj, instr, prop); 3473 HInstruction* store = BuildStoreNamed(obj, instr, prop);
3384 AddInstruction(store); 3474 AddInstruction(store);
3385 // Drop the simulated receiver and value. Return the value. 3475 // Drop the simulated receiver and value. Return the value.
3386 Drop(2); 3476 Drop(2);
3387 Push(instr); 3477 Push(instr);
3388 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3478 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
3389 ast_context()->ReturnValue(Pop()); 3479 ast_context()->ReturnValue(Pop());
3390 3480
3391 } else { 3481 } else {
3392 // Keyed property. 3482 // Keyed property.
3393 VISIT_FOR_VALUE(prop->obj()); 3483 CHECK_ALIVE(VisitForValue(prop->obj()));
3394 VISIT_FOR_VALUE(prop->key()); 3484 CHECK_ALIVE(VisitForValue(prop->key()));
3395 HValue* obj = environment()->ExpressionStackAt(1); 3485 HValue* obj = environment()->ExpressionStackAt(1);
3396 HValue* key = environment()->ExpressionStackAt(0); 3486 HValue* key = environment()->ExpressionStackAt(0);
3397 3487
3398 HInstruction* load = BuildLoadKeyed(obj, key, prop); 3488 HInstruction* load = BuildLoadKeyed(obj, key, prop);
3399 PushAndAdd(load); 3489 PushAndAdd(load);
3400 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); 3490 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId());
3401 3491
3402 VISIT_FOR_VALUE(expr->value()); 3492 CHECK_ALIVE(VisitForValue(expr->value()));
3403 HValue* right = Pop(); 3493 HValue* right = Pop();
3404 HValue* left = Pop(); 3494 HValue* left = Pop();
3405 3495
3406 HInstruction* instr = BuildBinaryOperation(operation, left, right); 3496 HInstruction* instr = BuildBinaryOperation(operation, left, right);
3407 PushAndAdd(instr); 3497 PushAndAdd(instr);
3408 if (instr->HasSideEffects()) AddSimulate(operation->id()); 3498 if (instr->HasSideEffects()) AddSimulate(operation->id());
3409 3499
3410 expr->RecordTypeFeedback(oracle()); 3500 expr->RecordTypeFeedback(oracle());
3411 HInstruction* store = BuildStoreKeyed(obj, key, instr, expr); 3501 HInstruction* store = BuildStoreKeyed(obj, key, instr, expr);
3412 AddInstruction(store); 3502 AddInstruction(store);
3413 // Drop the simulated receiver, key, and value. Return the value. 3503 // Drop the simulated receiver, key, and value. Return the value.
3414 Drop(3); 3504 Drop(3);
3415 Push(instr); 3505 Push(instr);
3416 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3506 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
3417 ast_context()->ReturnValue(Pop()); 3507 ast_context()->ReturnValue(Pop());
3418 } 3508 }
3419 3509
3420 } else { 3510 } else {
3421 BAILOUT("invalid lhs in compound assignment"); 3511 return Bailout("invalid lhs in compound assignment");
3422 } 3512 }
3423 } 3513 }
3424 3514
3425 3515
3426 void HGraphBuilder::VisitAssignment(Assignment* expr) { 3516 void HGraphBuilder::VisitAssignment(Assignment* expr) {
3517 ASSERT(!HasStackOverflow());
3518 ASSERT(current_block() != NULL);
3519 ASSERT(current_block()->HasPredecessor());
3427 VariableProxy* proxy = expr->target()->AsVariableProxy(); 3520 VariableProxy* proxy = expr->target()->AsVariableProxy();
3428 Variable* var = proxy->AsVariable(); 3521 Variable* var = proxy->AsVariable();
3429 Property* prop = expr->target()->AsProperty(); 3522 Property* prop = expr->target()->AsProperty();
3430 ASSERT(var == NULL || prop == NULL); 3523 ASSERT(var == NULL || prop == NULL);
3431 3524
3432 if (expr->is_compound()) { 3525 if (expr->is_compound()) {
3433 HandleCompoundAssignment(expr); 3526 HandleCompoundAssignment(expr);
3434 return; 3527 return;
3435 } 3528 }
3436 3529
3437 if (var != NULL) { 3530 if (var != NULL) {
3438 if (proxy->IsArguments()) BAILOUT("assignment to arguments"); 3531 if (proxy->IsArguments()) return Bailout("assignment to arguments");
3439 3532
3440 // Handle the assignment. 3533 // Handle the assignment.
3441 if (var->IsStackAllocated()) { 3534 if (var->IsStackAllocated()) {
3442 HValue* value = NULL; 3535 HValue* value = NULL;
3443 // Handle stack-allocated variables on the right-hand side directly. 3536 // Handle stack-allocated variables on the right-hand side directly.
3444 // We do not allow the arguments object to occur in a context where it 3537 // We do not allow the arguments object to occur in a context where it
3445 // may escape, but assignments to stack-allocated locals are 3538 // may escape, but assignments to stack-allocated locals are
3446 // permitted. Handling such assignments here bypasses the check for 3539 // permitted. Handling such assignments here bypasses the check for
3447 // the arguments object in VisitVariableProxy. 3540 // the arguments object in VisitVariableProxy.
3448 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable(); 3541 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable();
3449 if (rhs_var != NULL && rhs_var->IsStackAllocated()) { 3542 if (rhs_var != NULL && rhs_var->IsStackAllocated()) {
3450 value = environment()->Lookup(rhs_var); 3543 value = environment()->Lookup(rhs_var);
3451 } else { 3544 } else {
3452 VISIT_FOR_VALUE(expr->value()); 3545 CHECK_ALIVE(VisitForValue(expr->value()));
3453 value = Pop(); 3546 value = Pop();
3454 } 3547 }
3455 Bind(var, value); 3548 Bind(var, value);
3456 ast_context()->ReturnValue(value); 3549 ast_context()->ReturnValue(value);
3457 3550
3458 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { 3551 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) {
3459 VISIT_FOR_VALUE(expr->value()); 3552 CHECK_ALIVE(VisitForValue(expr->value()));
3460 HValue* context = BuildContextChainWalk(var); 3553 HValue* context = BuildContextChainWalk(var);
3461 int index = var->AsSlot()->index(); 3554 int index = var->AsSlot()->index();
3462 HStoreContextSlot* instr = 3555 HStoreContextSlot* instr =
3463 new(zone()) HStoreContextSlot(context, index, Top()); 3556 new(zone()) HStoreContextSlot(context, index, Top());
3464 AddInstruction(instr); 3557 AddInstruction(instr);
3465 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3558 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3466 ast_context()->ReturnValue(Pop()); 3559 ast_context()->ReturnValue(Pop());
3467 3560
3468 } else if (var->is_global()) { 3561 } else if (var->is_global()) {
3469 VISIT_FOR_VALUE(expr->value()); 3562 CHECK_ALIVE(VisitForValue(expr->value()));
3470 HandleGlobalVariableAssignment(var, 3563 HandleGlobalVariableAssignment(var,
3471 Top(), 3564 Top(),
3472 expr->position(), 3565 expr->position(),
3473 expr->AssignmentId()); 3566 expr->AssignmentId());
3474 ast_context()->ReturnValue(Pop()); 3567 ast_context()->ReturnValue(Pop());
3475 3568
3476 } else { 3569 } else {
3477 BAILOUT("assignment to LOOKUP or const CONTEXT variable"); 3570 return Bailout("assignment to LOOKUP or const CONTEXT variable");
3478 } 3571 }
3479 3572
3480 } else if (prop != NULL) { 3573 } else if (prop != NULL) {
3481 HandlePropertyAssignment(expr); 3574 HandlePropertyAssignment(expr);
3482 } else { 3575 } else {
3483 BAILOUT("invalid left-hand side in assignment"); 3576 return Bailout("invalid left-hand side in assignment");
3484 } 3577 }
3485 } 3578 }
3486 3579
3487 3580
3488 void HGraphBuilder::VisitThrow(Throw* expr) { 3581 void HGraphBuilder::VisitThrow(Throw* expr) {
3582 ASSERT(!HasStackOverflow());
3583 ASSERT(current_block() != NULL);
3584 ASSERT(current_block()->HasPredecessor());
3489 // We don't optimize functions with invalid left-hand sides in 3585 // We don't optimize functions with invalid left-hand sides in
3490 // assignments, count operations, or for-in. Consequently throw can 3586 // assignments, count operations, or for-in. Consequently throw can
3491 // currently only occur in an effect context. 3587 // currently only occur in an effect context.
3492 ASSERT(ast_context()->IsEffect()); 3588 ASSERT(ast_context()->IsEffect());
3493 VISIT_FOR_VALUE(expr->exception()); 3589 CHECK_ALIVE(VisitForValue(expr->exception()));
3494 3590
3495 HValue* value = environment()->Pop(); 3591 HValue* value = environment()->Pop();
3496 HThrow* instr = new(zone()) HThrow(value); 3592 HThrow* instr = new(zone()) HThrow(value);
3497 instr->set_position(expr->position()); 3593 instr->set_position(expr->position());
3498 AddInstruction(instr); 3594 AddInstruction(instr);
3499 AddSimulate(expr->id()); 3595 AddSimulate(expr->id());
3500 current_block()->FinishExit(new(zone()) HAbnormalExit); 3596 current_block()->FinishExit(new(zone()) HAbnormalExit);
3501 set_current_block(NULL); 3597 set_current_block(NULL);
3502 } 3598 }
3503 3599
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3731 3827
3732 HInstruction* result = NULL; 3828 HInstruction* result = NULL;
3733 if (expr->key()->IsPropertyName()) { 3829 if (expr->key()->IsPropertyName()) {
3734 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3830 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3735 if (!name->IsEqualTo(CStrVector("length"))) return false; 3831 if (!name->IsEqualTo(CStrVector("length"))) return false;
3736 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 3832 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
3737 result = new(zone()) HArgumentsLength(elements); 3833 result = new(zone()) HArgumentsLength(elements);
3738 } else { 3834 } else {
3739 Push(graph()->GetArgumentsObject()); 3835 Push(graph()->GetArgumentsObject());
3740 VisitForValue(expr->key()); 3836 VisitForValue(expr->key());
3741 if (HasStackOverflow()) return false; 3837 if (HasStackOverflow() || current_block() == NULL) return true;
3742 HValue* key = Pop(); 3838 HValue* key = Pop();
3743 Drop(1); // Arguments object. 3839 Drop(1); // Arguments object.
3744 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 3840 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
3745 HInstruction* length = AddInstruction( 3841 HInstruction* length = AddInstruction(
3746 new(zone()) HArgumentsLength(elements)); 3842 new(zone()) HArgumentsLength(elements));
3747 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3843 AddInstruction(new(zone()) HBoundsCheck(key, length));
3748 result = new(zone()) HAccessArgumentsAt(elements, length, key); 3844 result = new(zone()) HAccessArgumentsAt(elements, length, key);
3749 } 3845 }
3750 ast_context()->ReturnInstruction(result, expr->id()); 3846 ast_context()->ReturnInstruction(result, expr->id());
3751 return true; 3847 return true;
3752 } 3848 }
3753 3849
3754 3850
3755 void HGraphBuilder::VisitProperty(Property* expr) { 3851 void HGraphBuilder::VisitProperty(Property* expr) {
3852 ASSERT(!HasStackOverflow());
3853 ASSERT(current_block() != NULL);
3854 ASSERT(current_block()->HasPredecessor());
3756 expr->RecordTypeFeedback(oracle()); 3855 expr->RecordTypeFeedback(oracle());
3757 3856
3758 if (TryArgumentsAccess(expr)) return; 3857 if (TryArgumentsAccess(expr)) return;
3759 CHECK_BAILOUT;
3760 3858
3761 VISIT_FOR_VALUE(expr->obj()); 3859 CHECK_ALIVE(VisitForValue(expr->obj()));
3762 3860
3763 HInstruction* instr = NULL; 3861 HInstruction* instr = NULL;
3764 if (expr->IsArrayLength()) { 3862 if (expr->IsArrayLength()) {
3765 HValue* array = Pop(); 3863 HValue* array = Pop();
3766 AddInstruction(new(zone()) HCheckNonSmi(array)); 3864 AddInstruction(new(zone()) HCheckNonSmi(array));
3767 AddInstruction(new(zone()) HCheckInstanceType(array, 3865 AddInstruction(new(zone()) HCheckInstanceType(array,
3768 JS_ARRAY_TYPE, 3866 JS_ARRAY_TYPE,
3769 JS_ARRAY_TYPE)); 3867 JS_ARRAY_TYPE));
3770 instr = new(zone()) HJSArrayLength(array); 3868 instr = new(zone()) HJSArrayLength(array);
3771 3869
3772 } else if (expr->IsStringLength()) { 3870 } else if (expr->IsStringLength()) {
3773 HValue* string = Pop(); 3871 HValue* string = Pop();
3774 AddInstruction(new(zone()) HCheckNonSmi(string)); 3872 AddInstruction(new(zone()) HCheckNonSmi(string));
3775 AddInstruction(new(zone()) HCheckInstanceType(string, 3873 AddInstruction(new(zone()) HCheckInstanceType(string,
3776 FIRST_STRING_TYPE, 3874 FIRST_STRING_TYPE,
3777 LAST_STRING_TYPE)); 3875 LAST_STRING_TYPE));
3778 instr = new(zone()) HStringLength(string); 3876 instr = new(zone()) HStringLength(string);
3779 } else if (expr->IsStringAccess()) { 3877 } else if (expr->IsStringAccess()) {
3780 VISIT_FOR_VALUE(expr->key()); 3878 CHECK_ALIVE(VisitForValue(expr->key()));
3781 HValue* index = Pop(); 3879 HValue* index = Pop();
3782 HValue* string = Pop(); 3880 HValue* string = Pop();
3783 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); 3881 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
3784 AddInstruction(char_code); 3882 AddInstruction(char_code);
3785 instr = new(zone()) HStringCharFromCode(char_code); 3883 instr = new(zone()) HStringCharFromCode(char_code);
3786 3884
3787 } else if (expr->IsFunctionPrototype()) { 3885 } else if (expr->IsFunctionPrototype()) {
3788 HValue* function = Pop(); 3886 HValue* function = Pop();
3789 AddInstruction(new(zone()) HCheckNonSmi(function)); 3887 AddInstruction(new(zone()) HCheckNonSmi(function));
3790 instr = new(zone()) HLoadFunctionPrototype(function); 3888 instr = new(zone()) HLoadFunctionPrototype(function);
3791 3889
3792 } else if (expr->key()->IsPropertyName()) { 3890 } else if (expr->key()->IsPropertyName()) {
3793 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3891 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3794 ZoneMapList* types = expr->GetReceiverTypes(); 3892 ZoneMapList* types = expr->GetReceiverTypes();
3795 3893
3796 HValue* obj = Pop(); 3894 HValue* obj = Pop();
3797 if (expr->IsMonomorphic()) { 3895 if (expr->IsMonomorphic()) {
3798 instr = BuildLoadNamed(obj, expr, types->first(), name); 3896 instr = BuildLoadNamed(obj, expr, types->first(), name);
3799 } else if (types != NULL && types->length() > 1) { 3897 } else if (types != NULL && types->length() > 1) {
3800 AddInstruction(new(zone()) HCheckNonSmi(obj)); 3898 AddInstruction(new(zone()) HCheckNonSmi(obj));
3801 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name); 3899 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name);
3802 } else { 3900 } else {
3803 instr = BuildLoadNamedGeneric(obj, expr); 3901 instr = BuildLoadNamedGeneric(obj, expr);
3804 } 3902 }
3805 3903
3806 } else { 3904 } else {
3807 VISIT_FOR_VALUE(expr->key()); 3905 CHECK_ALIVE(VisitForValue(expr->key()));
3808 3906
3809 HValue* key = Pop(); 3907 HValue* key = Pop();
3810 HValue* obj = Pop(); 3908 HValue* obj = Pop();
3811 instr = BuildLoadKeyed(obj, key, expr); 3909 instr = BuildLoadKeyed(obj, key, expr);
3812 } 3910 }
3813 instr->set_position(expr->position()); 3911 instr->set_position(expr->position());
3814 ast_context()->ReturnInstruction(instr, expr->id()); 3912 ast_context()->ReturnInstruction(instr, expr->id());
3815 } 3913 }
3816 3914
3817 3915
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3859 new(zone()) HCompareMap(receiver, map, if_true, if_false); 3957 new(zone()) HCompareMap(receiver, map, if_true, if_false);
3860 current_block()->Finish(compare); 3958 current_block()->Finish(compare);
3861 3959
3862 set_current_block(if_true); 3960 set_current_block(if_true);
3863 AddCheckConstantFunction(expr, receiver, map, false); 3961 AddCheckConstantFunction(expr, receiver, map, false);
3864 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { 3962 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
3865 PrintF("Trying to inline the polymorphic call to %s\n", 3963 PrintF("Trying to inline the polymorphic call to %s\n",
3866 *name->ToCString()); 3964 *name->ToCString());
3867 } 3965 }
3868 if (!FLAG_polymorphic_inlining || !TryInline(expr)) { 3966 if (!FLAG_polymorphic_inlining || !TryInline(expr)) {
3869 // Check for bailout, as trying to inline might fail due to bailout
3870 // during hydrogen processing.
3871 CHECK_BAILOUT;
3872 HCallConstantFunction* call = 3967 HCallConstantFunction* call =
3873 new(zone()) HCallConstantFunction(expr->target(), argument_count); 3968 new(zone()) HCallConstantFunction(expr->target(), argument_count);
3874 call->set_position(expr->position()); 3969 call->set_position(expr->position());
3875 PreProcessCall(call); 3970 PreProcessCall(call);
3876 AddInstruction(call); 3971 AddInstruction(call);
3877 if (!ast_context()->IsEffect()) Push(call); 3972 if (!ast_context()->IsEffect()) Push(call);
3878 } 3973 }
3879 3974
3880 if (current_block() != NULL) current_block()->Goto(join); 3975 if (current_block() != NULL) current_block()->Goto(join);
3881 set_current_block(if_false); 3976 set_current_block(if_false);
(...skipping 19 matching lines...) Expand all
3901 } else { 3996 } else {
3902 ast_context()->ReturnInstruction(call, expr->id()); 3997 ast_context()->ReturnInstruction(call, expr->id());
3903 return; 3998 return;
3904 } 3999 }
3905 } 4000 }
3906 4001
3907 // We assume that control flow is always live after an expression. So 4002 // We assume that control flow is always live after an expression. So
3908 // even without predecessors to the join block, we set it as the exit 4003 // even without predecessors to the join block, we set it as the exit
3909 // block and continue by adding instructions there. 4004 // block and continue by adding instructions there.
3910 ASSERT(join != NULL); 4005 ASSERT(join != NULL);
3911 set_current_block(join);
3912 if (join->HasPredecessor()) { 4006 if (join->HasPredecessor()) {
4007 set_current_block(join);
3913 join->SetJoinId(expr->id()); 4008 join->SetJoinId(expr->id());
3914 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 4009 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
4010 } else {
4011 set_current_block(NULL);
3915 } 4012 }
3916 } 4013 }
3917 4014
3918 4015
3919 void HGraphBuilder::TraceInline(Handle<JSFunction> target, const char* reason) { 4016 void HGraphBuilder::TraceInline(Handle<JSFunction> target, const char* reason) {
3920 if (FLAG_trace_inlining) { 4017 if (FLAG_trace_inlining) {
3921 if (reason == NULL) { 4018 if (reason == NULL) {
3922 // We are currently in the context of inlined function thus we have 4019 // We are currently in the context of inlined function thus we have
3923 // to go to an outer FunctionState to get caller. 4020 // to go to an outer FunctionState to get caller.
3924 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); 4021 SmartPointer<char> callee = target->shared()->DebugName()->ToCString();
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
4076 current_block()->Goto(body_entry); 4173 current_block()->Goto(body_entry);
4077 4174
4078 body_entry->SetJoinId(expr->ReturnId()); 4175 body_entry->SetJoinId(expr->ReturnId());
4079 set_current_block(body_entry); 4176 set_current_block(body_entry);
4080 AddInstruction(new(zone()) HEnterInlined(target, function)); 4177 AddInstruction(new(zone()) HEnterInlined(target, function));
4081 VisitStatements(function->body()); 4178 VisitStatements(function->body());
4082 if (HasStackOverflow()) { 4179 if (HasStackOverflow()) {
4083 // Bail out if the inline function did, as we cannot residualize a call 4180 // Bail out if the inline function did, as we cannot residualize a call
4084 // instead. 4181 // instead.
4085 TraceInline(target, "inline graph construction failed"); 4182 TraceInline(target, "inline graph construction failed");
4086 return false; 4183 return true;
4087 } 4184 }
4088 4185
4089 // Update inlined nodes count. 4186 // Update inlined nodes count.
4090 inlined_count_ += nodes_added; 4187 inlined_count_ += nodes_added;
4091 4188
4092 TraceInline(target, NULL); 4189 TraceInline(target, NULL);
4093 4190
4094 if (current_block() != NULL) { 4191 if (current_block() != NULL) {
4095 // Add a return of undefined if control can fall off the body. In a 4192 // Add a return of undefined if control can fall off the body. In a
4096 // test context, undefined is false. 4193 // test context, undefined is false.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 4229 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
4133 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 4230 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
4134 if_true->Goto(true_target, false); 4231 if_true->Goto(true_target, false);
4135 if_false->Goto(false_target, false); 4232 if_false->Goto(false_target, false);
4136 4233
4137 // TODO(kmillikin): Come up with a better way to handle this. It is too 4234 // TODO(kmillikin): Come up with a better way to handle this. It is too
4138 // subtle. NULL here indicates that the enclosing context has no control 4235 // subtle. NULL here indicates that the enclosing context has no control
4139 // flow to handle. 4236 // flow to handle.
4140 set_current_block(NULL); 4237 set_current_block(NULL);
4141 4238
4142 } else { 4239 } else if (function_return()->HasPredecessor()) {
4143 function_return()->SetJoinId(expr->id()); 4240 function_return()->SetJoinId(expr->id());
4144 set_current_block(function_return()); 4241 set_current_block(function_return());
4242 } else {
4243 set_current_block(NULL);
4145 } 4244 }
4146 4245
4147 return true; 4246 return true;
4148 } 4247 }
4149 4248
4150 4249
4151 bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, 4250 bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr,
4152 HValue* receiver, 4251 HValue* receiver,
4153 Handle<Map> receiver_map, 4252 Handle<Map> receiver_map,
4154 CheckType check_type) { 4253 CheckType check_type) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4260 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 4359 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
4261 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 4360 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
4262 HValue* arg_two_value = environment()->Lookup(arg_two->var()); 4361 HValue* arg_two_value = environment()->Lookup(arg_two->var());
4263 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 4362 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
4264 4363
4265 if (!expr->IsMonomorphic() || 4364 if (!expr->IsMonomorphic() ||
4266 expr->check_type() != RECEIVER_MAP_CHECK) return false; 4365 expr->check_type() != RECEIVER_MAP_CHECK) return false;
4267 4366
4268 // Found pattern f.apply(receiver, arguments). 4367 // Found pattern f.apply(receiver, arguments).
4269 VisitForValue(prop->obj()); 4368 VisitForValue(prop->obj());
4270 if (HasStackOverflow()) return false; 4369 if (HasStackOverflow() || current_block() == NULL) return true;
4271 HValue* function = Pop(); 4370 HValue* function = Pop();
4272 VisitForValue(args->at(0)); 4371 VisitForValue(args->at(0));
4273 if (HasStackOverflow()) return false; 4372 if (HasStackOverflow() || current_block() == NULL) return true;
4274 HValue* receiver = Pop(); 4373 HValue* receiver = Pop();
4275 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 4374 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
4276 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 4375 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
4277 AddCheckConstantFunction(expr, 4376 AddCheckConstantFunction(expr,
4278 function, 4377 function,
4279 expr->GetReceiverTypes()->first(), 4378 expr->GetReceiverTypes()->first(),
4280 true); 4379 true);
4281 HInstruction* result = 4380 HInstruction* result =
4282 new(zone()) HApplyArguments(function, receiver, length, elements); 4381 new(zone()) HApplyArguments(function, receiver, length, elements);
4283 result->set_position(expr->position()); 4382 result->set_position(expr->position());
4284 ast_context()->ReturnInstruction(result, expr->id()); 4383 ast_context()->ReturnInstruction(result, expr->id());
4285 return true; 4384 return true;
4286 } 4385 }
4287 4386
4288 4387
4289 void HGraphBuilder::VisitCall(Call* expr) { 4388 void HGraphBuilder::VisitCall(Call* expr) {
4389 ASSERT(!HasStackOverflow());
4390 ASSERT(current_block() != NULL);
4391 ASSERT(current_block()->HasPredecessor());
4290 Expression* callee = expr->expression(); 4392 Expression* callee = expr->expression();
4291 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4393 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4292 HInstruction* call = NULL; 4394 HInstruction* call = NULL;
4293 4395
4294 Property* prop = callee->AsProperty(); 4396 Property* prop = callee->AsProperty();
4295 if (prop != NULL) { 4397 if (prop != NULL) {
4296 if (!prop->key()->IsPropertyName()) { 4398 if (!prop->key()->IsPropertyName()) {
4297 // Keyed function call. 4399 // Keyed function call.
4298 VISIT_FOR_VALUE(prop->obj()); 4400 CHECK_ALIVE(VisitForValue(prop->obj()));
4299 4401
4300 VISIT_FOR_VALUE(prop->key()); 4402 CHECK_ALIVE(VisitForValue(prop->key()));
4301 // Push receiver and key like the non-optimized code generator expects it. 4403 // Push receiver and key like the non-optimized code generator expects it.
4302 HValue* key = Pop(); 4404 HValue* key = Pop();
4303 HValue* receiver = Pop(); 4405 HValue* receiver = Pop();
4304 Push(key); 4406 Push(key);
4305 Push(receiver); 4407 Push(receiver);
4306 4408
4307 VisitExpressions(expr->arguments()); 4409 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4308 CHECK_BAILOUT;
4309 4410
4310 HContext* context = new(zone()) HContext; 4411 HContext* context = new(zone()) HContext;
4311 AddInstruction(context); 4412 AddInstruction(context);
4312 call = PreProcessCall( 4413 call = PreProcessCall(
4313 new(zone()) HCallKeyed(context, key, argument_count)); 4414 new(zone()) HCallKeyed(context, key, argument_count));
4314 call->set_position(expr->position()); 4415 call->set_position(expr->position());
4315 Drop(1); // Key. 4416 Drop(1); // Key.
4316 ast_context()->ReturnInstruction(call, expr->id()); 4417 ast_context()->ReturnInstruction(call, expr->id());
4317 return; 4418 return;
4318 } 4419 }
4319 4420
4320 // Named function call. 4421 // Named function call.
4321 expr->RecordTypeFeedback(oracle()); 4422 expr->RecordTypeFeedback(oracle());
4322 4423
4323 if (TryCallApply(expr)) return; 4424 if (TryCallApply(expr)) {
4324 CHECK_BAILOUT; 4425 ASSERT(current_block() == NULL || current_block()->HasPredecessor());
4426 return;
4427 }
4325 4428
4326 VISIT_FOR_VALUE(prop->obj()); 4429 CHECK_ALIVE(VisitForValue(prop->obj()));
4327 VisitExpressions(expr->arguments()); 4430 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4328 CHECK_BAILOUT;
4329 4431
4330 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4432 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4331 4433
4332 expr->RecordTypeFeedback(oracle()); 4434 expr->RecordTypeFeedback(oracle());
4333 ZoneMapList* types = expr->GetReceiverTypes(); 4435 ZoneMapList* types = expr->GetReceiverTypes();
4334 4436
4335 HValue* receiver = 4437 HValue* receiver =
4336 environment()->ExpressionStackAt(expr->arguments()->length()); 4438 environment()->ExpressionStackAt(expr->arguments()->length());
4337 if (expr->IsMonomorphic()) { 4439 if (expr->IsMonomorphic()) {
4338 Handle<Map> receiver_map = 4440 Handle<Map> receiver_map =
4339 (types == NULL) ? Handle<Map>::null() : types->first(); 4441 (types == NULL) ? Handle<Map>::null() : types->first();
4340 if (TryInlineBuiltinFunction(expr, 4442 if (TryInlineBuiltinFunction(expr,
4341 receiver, 4443 receiver,
4342 receiver_map, 4444 receiver_map,
4343 expr->check_type())) { 4445 expr->check_type())) {
4446 ASSERT(current_block() == NULL || current_block()->HasPredecessor());
4344 return; 4447 return;
4345 } 4448 }
4346 4449
4347 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || 4450 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) ||
4348 expr->check_type() != RECEIVER_MAP_CHECK) { 4451 expr->check_type() != RECEIVER_MAP_CHECK) {
4349 // When the target has a custom call IC generator, use the IC, 4452 // When the target has a custom call IC generator, use the IC,
4350 // because it is likely to generate better code. Also use the IC 4453 // because it is likely to generate better code. Also use the IC
4351 // when a primitive receiver check is required. 4454 // when a primitive receiver check is required.
4352 HContext* context = new(zone()) HContext; 4455 HContext* context = new(zone()) HContext;
4353 AddInstruction(context); 4456 AddInstruction(context);
4354 call = PreProcessCall( 4457 call = PreProcessCall(
4355 new(zone()) HCallNamed(context, name, argument_count)); 4458 new(zone()) HCallNamed(context, name, argument_count));
4356 } else { 4459 } else {
4357 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4460 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4358 4461
4359 if (TryInline(expr)) { 4462 if (TryInline(expr)) {
4463 ASSERT(current_block() == NULL || current_block()->HasPredecessor());
4360 return; 4464 return;
4361 } else { 4465 } else {
4362 // Check for bailout, as the TryInline call in the if condition above
4363 // might return false due to bailout during hydrogen processing.
4364 CHECK_BAILOUT;
4365 call = PreProcessCall( 4466 call = PreProcessCall(
4366 new(zone()) HCallConstantFunction(expr->target(), 4467 new(zone()) HCallConstantFunction(expr->target(),
4367 argument_count)); 4468 argument_count));
4368 } 4469 }
4369 } 4470 }
4370 } else if (types != NULL && types->length() > 1) { 4471 } else if (types != NULL && types->length() > 1) {
4371 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 4472 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
4372 HandlePolymorphicCallNamed(expr, receiver, types, name); 4473 HandlePolymorphicCallNamed(expr, receiver, types, name);
4474 ASSERT(current_block() == NULL || current_block()->HasPredecessor());
4373 return; 4475 return;
4374 4476
4375 } else { 4477 } else {
4376 HContext* context = new(zone()) HContext; 4478 HContext* context = new(zone()) HContext;
4377 AddInstruction(context); 4479 AddInstruction(context);
4378 call = PreProcessCall( 4480 call = PreProcessCall(
4379 new(zone()) HCallNamed(context, name, argument_count)); 4481 new(zone()) HCallNamed(context, name, argument_count));
4380 } 4482 }
4381 4483
4382 } else { 4484 } else {
4383 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4485 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4384 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); 4486 bool global_call = (var != NULL) && var->is_global() && !var->is_this();
4385 4487
4386 if (!global_call) { 4488 if (!global_call) {
4387 ++argument_count; 4489 ++argument_count;
4388 VISIT_FOR_VALUE(expr->expression()); 4490 CHECK_ALIVE(VisitForValue(expr->expression()));
4389 } 4491 }
4390 4492
4391 if (global_call) { 4493 if (global_call) {
4392 bool known_global_function = false; 4494 bool known_global_function = false;
4393 // If there is a global property cell for the name at compile time and 4495 // If there is a global property cell for the name at compile time and
4394 // access check is not enabled we assume that the function will not change 4496 // access check is not enabled we assume that the function will not change
4395 // and generate optimized code for calling the function. 4497 // and generate optimized code for calling the function.
4396 LookupResult lookup; 4498 LookupResult lookup;
4397 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); 4499 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
4398 if (type == kUseCell && 4500 if (type == kUseCell &&
4399 !info()->global_object()->IsAccessCheckNeeded()) { 4501 !info()->global_object()->IsAccessCheckNeeded()) {
4400 Handle<GlobalObject> global(info()->global_object()); 4502 Handle<GlobalObject> global(info()->global_object());
4401 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 4503 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
4402 } 4504 }
4403 if (known_global_function) { 4505 if (known_global_function) {
4404 // Push the global object instead of the global receiver because 4506 // Push the global object instead of the global receiver because
4405 // code generated by the full code generator expects it. 4507 // code generated by the full code generator expects it.
4406 HContext* context = new(zone()) HContext; 4508 HContext* context = new(zone()) HContext;
4407 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 4509 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4408 AddInstruction(context); 4510 AddInstruction(context);
4409 PushAndAdd(global_object); 4511 PushAndAdd(global_object);
4410 VisitExpressions(expr->arguments()); 4512 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4411 CHECK_BAILOUT;
4412 4513
4413 VISIT_FOR_VALUE(expr->expression()); 4514 CHECK_ALIVE(VisitForValue(expr->expression()));
4414 HValue* function = Pop(); 4515 HValue* function = Pop();
4415 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); 4516 AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
4416 4517
4417 // Replace the global object with the global receiver. 4518 // Replace the global object with the global receiver.
4418 HGlobalReceiver* global_receiver = 4519 HGlobalReceiver* global_receiver =
4419 new(zone()) HGlobalReceiver(global_object); 4520 new(zone()) HGlobalReceiver(global_object);
4420 // Index of the receiver from the top of the expression stack. 4521 // Index of the receiver from the top of the expression stack.
4421 const int receiver_index = argument_count - 1; 4522 const int receiver_index = argument_count - 1;
4422 AddInstruction(global_receiver); 4523 AddInstruction(global_receiver);
4423 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4524 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4424 IsGlobalObject()); 4525 IsGlobalObject());
4425 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4526 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4426 4527
4427 if (TryInline(expr)) { 4528 if (TryInline(expr)) {
4428 return; 4529 return;
4429 } 4530 }
4430 // Check for bailout, as trying to inline might fail due to bailout
4431 // during hydrogen processing.
4432 CHECK_BAILOUT;
4433
4434 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 4531 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
4435 argument_count)); 4532 argument_count));
4436 } else { 4533 } else {
4437 HContext* context = new(zone()) HContext; 4534 HContext* context = new(zone()) HContext;
4438 AddInstruction(context); 4535 AddInstruction(context);
4439 PushAndAdd(new(zone()) HGlobalObject(context)); 4536 PushAndAdd(new(zone()) HGlobalObject(context));
4440 VisitExpressions(expr->arguments()); 4537 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4441 CHECK_BAILOUT;
4442 4538
4443 call = PreProcessCall(new(zone()) HCallGlobal(context, 4539 call = PreProcessCall(new(zone()) HCallGlobal(context,
4444 var->name(), 4540 var->name(),
4445 argument_count)); 4541 argument_count));
4446 } 4542 }
4447 4543
4448 } else { 4544 } else {
4449 HContext* context = new(zone()) HContext; 4545 HContext* context = new(zone()) HContext;
4450 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 4546 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4451 AddInstruction(context); 4547 AddInstruction(context);
4452 AddInstruction(global_object); 4548 AddInstruction(global_object);
4453 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); 4549 PushAndAdd(new(zone()) HGlobalReceiver(global_object));
4454 VisitExpressions(expr->arguments()); 4550 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4455 CHECK_BAILOUT;
4456 4551
4457 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); 4552 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count));
4458 } 4553 }
4459 } 4554 }
4460 4555
4461 call->set_position(expr->position()); 4556 call->set_position(expr->position());
4557 ASSERT(current_block() == NULL || current_block()->HasPredecessor());
4462 ast_context()->ReturnInstruction(call, expr->id()); 4558 ast_context()->ReturnInstruction(call, expr->id());
4463 } 4559 }
4464 4560
4465 4561
4466 void HGraphBuilder::VisitCallNew(CallNew* expr) { 4562 void HGraphBuilder::VisitCallNew(CallNew* expr) {
4563 ASSERT(!HasStackOverflow());
4564 ASSERT(current_block() != NULL);
4565 ASSERT(current_block()->HasPredecessor());
4467 // The constructor function is also used as the receiver argument to the 4566 // The constructor function is also used as the receiver argument to the
4468 // JS construct call builtin. 4567 // JS construct call builtin.
4469 VISIT_FOR_VALUE(expr->expression()); 4568 CHECK_ALIVE(VisitForValue(expr->expression()));
4470 VisitExpressions(expr->arguments()); 4569 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4471 CHECK_BAILOUT;
4472 4570
4473 HContext* context = new(zone()) HContext; 4571 HContext* context = new(zone()) HContext;
4474 AddInstruction(context); 4572 AddInstruction(context);
4475 4573
4476 // The constructor is both an operand to the instruction and an argument 4574 // The constructor is both an operand to the instruction and an argument
4477 // to the construct call. 4575 // to the construct call.
4478 int arg_count = expr->arguments()->length() + 1; // Plus constructor. 4576 int arg_count = expr->arguments()->length() + 1; // Plus constructor.
4479 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); 4577 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
4480 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); 4578 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count);
4481 call->set_position(expr->position()); 4579 call->set_position(expr->position());
(...skipping 11 matching lines...) Expand all
4493 4591
4494 const HGraphBuilder::InlineFunctionGenerator 4592 const HGraphBuilder::InlineFunctionGenerator
4495 HGraphBuilder::kInlineFunctionGenerators[] = { 4593 HGraphBuilder::kInlineFunctionGenerators[] = {
4496 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 4594 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
4497 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 4595 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
4498 }; 4596 };
4499 #undef INLINE_FUNCTION_GENERATOR_ADDRESS 4597 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
4500 4598
4501 4599
4502 void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 4600 void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
4601 ASSERT(!HasStackOverflow());
4602 ASSERT(current_block() != NULL);
4603 ASSERT(current_block()->HasPredecessor());
4503 if (expr->is_jsruntime()) { 4604 if (expr->is_jsruntime()) {
4504 BAILOUT("call to a JavaScript runtime function"); 4605 return Bailout("call to a JavaScript runtime function");
4505 } 4606 }
4506 4607
4507 const Runtime::Function* function = expr->function(); 4608 const Runtime::Function* function = expr->function();
4508 ASSERT(function != NULL); 4609 ASSERT(function != NULL);
4509 if (function->intrinsic_type == Runtime::INLINE) { 4610 if (function->intrinsic_type == Runtime::INLINE) {
4510 ASSERT(expr->name()->length() > 0); 4611 ASSERT(expr->name()->length() > 0);
4511 ASSERT(expr->name()->Get(0) == '_'); 4612 ASSERT(expr->name()->Get(0) == '_');
4512 // Call to an inline function. 4613 // Call to an inline function.
4513 int lookup_index = static_cast<int>(function->function_id) - 4614 int lookup_index = static_cast<int>(function->function_id) -
4514 static_cast<int>(Runtime::kFirstInlineFunction); 4615 static_cast<int>(Runtime::kFirstInlineFunction);
4515 ASSERT(lookup_index >= 0); 4616 ASSERT(lookup_index >= 0);
4516 ASSERT(static_cast<size_t>(lookup_index) < 4617 ASSERT(static_cast<size_t>(lookup_index) <
4517 ARRAY_SIZE(kInlineFunctionGenerators)); 4618 ARRAY_SIZE(kInlineFunctionGenerators));
4518 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 4619 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
4519 4620
4520 // Call the inline code generator using the pointer-to-member. 4621 // Call the inline code generator using the pointer-to-member.
4521 (this->*generator)(expr); 4622 (this->*generator)(expr);
4522 } else { 4623 } else {
4523 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 4624 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
4524 VisitArgumentList(expr->arguments()); 4625 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4525 CHECK_BAILOUT;
4526 4626
4527 Handle<String> name = expr->name(); 4627 Handle<String> name = expr->name();
4528 int argument_count = expr->arguments()->length(); 4628 int argument_count = expr->arguments()->length();
4529 HCallRuntime* call = 4629 HCallRuntime* call =
4530 new(zone()) HCallRuntime(name, function, argument_count); 4630 new(zone()) HCallRuntime(name, function, argument_count);
4531 call->set_position(RelocInfo::kNoPosition); 4631 call->set_position(RelocInfo::kNoPosition);
4532 Drop(argument_count); 4632 Drop(argument_count);
4533 ast_context()->ReturnInstruction(call, expr->id()); 4633 ast_context()->ReturnInstruction(call, expr->id());
4534 } 4634 }
4535 } 4635 }
4536 4636
4537 4637
4538 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 4638 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
4639 ASSERT(!HasStackOverflow());
4640 ASSERT(current_block() != NULL);
4641 ASSERT(current_block()->HasPredecessor());
4539 Token::Value op = expr->op(); 4642 Token::Value op = expr->op();
4540 if (op == Token::VOID) { 4643 if (op == Token::VOID) {
4541 VISIT_FOR_EFFECT(expr->expression()); 4644 CHECK_ALIVE(VisitForEffect(expr->expression()));
4542 ast_context()->ReturnValue(graph()->GetConstantUndefined()); 4645 ast_context()->ReturnValue(graph()->GetConstantUndefined());
4543 } else if (op == Token::DELETE) { 4646 } else if (op == Token::DELETE) {
4544 Property* prop = expr->expression()->AsProperty(); 4647 Property* prop = expr->expression()->AsProperty();
4545 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4648 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4546 if (prop == NULL && var == NULL) { 4649 if (prop == NULL && var == NULL) {
4547 // Result of deleting non-property, non-variable reference is true. 4650 // Result of deleting non-property, non-variable reference is true.
4548 // Evaluate the subexpression for side effects. 4651 // Evaluate the subexpression for side effects.
4549 VISIT_FOR_EFFECT(expr->expression()); 4652 CHECK_ALIVE(VisitForEffect(expr->expression()));
4550 ast_context()->ReturnValue(graph()->GetConstantTrue()); 4653 ast_context()->ReturnValue(graph()->GetConstantTrue());
4551 } else if (var != NULL && 4654 } else if (var != NULL &&
4552 !var->is_global() && 4655 !var->is_global() &&
4553 var->AsSlot() != NULL && 4656 var->AsSlot() != NULL &&
4554 var->AsSlot()->type() != Slot::LOOKUP) { 4657 var->AsSlot()->type() != Slot::LOOKUP) {
4555 // Result of deleting non-global, non-dynamic variables is false. 4658 // Result of deleting non-global, non-dynamic variables is false.
4556 // The subexpression does not have side effects. 4659 // The subexpression does not have side effects.
4557 ast_context()->ReturnValue(graph()->GetConstantFalse()); 4660 ast_context()->ReturnValue(graph()->GetConstantFalse());
4558 } else if (prop != NULL) { 4661 } else if (prop != NULL) {
4559 if (prop->is_synthetic()) { 4662 if (prop->is_synthetic()) {
4560 // Result of deleting parameters is false, even when they rewrite 4663 // Result of deleting parameters is false, even when they rewrite
4561 // to accesses on the arguments object. 4664 // to accesses on the arguments object.
4562 ast_context()->ReturnValue(graph()->GetConstantFalse()); 4665 ast_context()->ReturnValue(graph()->GetConstantFalse());
4563 } else { 4666 } else {
4564 VISIT_FOR_VALUE(prop->obj()); 4667 CHECK_ALIVE(VisitForValue(prop->obj()));
4565 VISIT_FOR_VALUE(prop->key()); 4668 CHECK_ALIVE(VisitForValue(prop->key()));
4566 HValue* key = Pop(); 4669 HValue* key = Pop();
4567 HValue* obj = Pop(); 4670 HValue* obj = Pop();
4568 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); 4671 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key);
4569 ast_context()->ReturnInstruction(instr, expr->id()); 4672 ast_context()->ReturnInstruction(instr, expr->id());
4570 } 4673 }
4571 } else if (var->is_global()) { 4674 } else if (var->is_global()) {
4572 BAILOUT("delete with global variable"); 4675 return Bailout("delete with global variable");
4573 } else { 4676 } else {
4574 BAILOUT("delete with non-global variable"); 4677 return Bailout("delete with non-global variable");
4575 } 4678 }
4576 } else if (op == Token::NOT) { 4679 } else if (op == Token::NOT) {
4577 if (ast_context()->IsTest()) { 4680 if (ast_context()->IsTest()) {
4578 TestContext* context = TestContext::cast(ast_context()); 4681 TestContext* context = TestContext::cast(ast_context());
4579 VisitForControl(expr->expression(), 4682 VisitForControl(expr->expression(),
4580 context->if_false(), 4683 context->if_false(),
4581 context->if_true()); 4684 context->if_true());
4582 } else if (ast_context()->IsValue()) { 4685 } else if (ast_context()->IsValue()) {
4583 HBasicBlock* materialize_false = graph()->CreateBasicBlock(); 4686 HBasicBlock* materialize_false = graph()->CreateBasicBlock();
4584 HBasicBlock* materialize_true = graph()->CreateBasicBlock(); 4687 HBasicBlock* materialize_true = graph()->CreateBasicBlock();
4585 VISIT_FOR_CONTROL(expr->expression(), 4688 CHECK_BAILOUT(VisitForControl(expr->expression(),
4586 materialize_false, 4689 materialize_false,
4587 materialize_true); 4690 materialize_true));
4588 materialize_false->SetJoinId(expr->expression()->id());
4589 materialize_true->SetJoinId(expr->expression()->id());
4590 4691
4591 set_current_block(materialize_false); 4692 if (materialize_false->HasPredecessor()) {
4592 Push(graph()->GetConstantFalse()); 4693 materialize_false->SetJoinId(expr->expression()->id());
4593 set_current_block(materialize_true); 4694 set_current_block(materialize_false);
4594 Push(graph()->GetConstantTrue()); 4695 Push(graph()->GetConstantFalse());
4696 } else {
4697 materialize_false = NULL;
4698 }
4699
4700 if (materialize_true->HasPredecessor()) {
4701 materialize_true->SetJoinId(expr->expression()->id());
4702 set_current_block(materialize_true);
4703 Push(graph()->GetConstantTrue());
4704 } else {
4705 materialize_true = NULL;
4706 }
4595 4707
4596 HBasicBlock* join = 4708 HBasicBlock* join =
4597 CreateJoin(materialize_false, materialize_true, expr->id()); 4709 CreateJoin(materialize_false, materialize_true, expr->id());
4598 set_current_block(join); 4710 set_current_block(join);
4599 ast_context()->ReturnValue(Pop()); 4711 if (join != NULL) ast_context()->ReturnValue(Pop());
4600 } else { 4712 } else {
4601 ASSERT(ast_context()->IsEffect()); 4713 ASSERT(ast_context()->IsEffect());
4602 VisitForEffect(expr->expression()); 4714 VisitForEffect(expr->expression());
4603 } 4715 }
4604 4716
4605 } else if (op == Token::TYPEOF) { 4717 } else if (op == Token::TYPEOF) {
4606 VisitForTypeOf(expr->expression()); 4718 VisitForTypeOf(expr->expression());
fschneider 2011/04/13 11:20:16 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
4607 if (HasStackOverflow()) return; 4719 if (HasStackOverflow() || current_block() == NULL) return;
4608 HValue* value = Pop(); 4720 HValue* value = Pop();
4609 ast_context()->ReturnInstruction(new(zone()) HTypeof(value), expr->id()); 4721 ast_context()->ReturnInstruction(new(zone()) HTypeof(value), expr->id());
4610 4722
4611 } else { 4723 } else {
4612 VISIT_FOR_VALUE(expr->expression()); 4724 CHECK_ALIVE(VisitForValue(expr->expression()));
4613 HValue* value = Pop(); 4725 HValue* value = Pop();
4614 HInstruction* instr = NULL; 4726 HInstruction* instr = NULL;
4615 switch (op) { 4727 switch (op) {
4616 case Token::BIT_NOT: 4728 case Token::BIT_NOT:
4617 instr = new(zone()) HBitNot(value); 4729 instr = new(zone()) HBitNot(value);
4618 break; 4730 break;
4619 case Token::SUB: 4731 case Token::SUB:
4620 instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); 4732 instr = new(zone()) HMul(value, graph_->GetConstantMinus1());
4621 break; 4733 break;
4622 case Token::ADD: 4734 case Token::ADD:
4623 instr = new(zone()) HMul(value, graph_->GetConstant1()); 4735 instr = new(zone()) HMul(value, graph_->GetConstant1());
4624 break; 4736 break;
4625 default: 4737 default:
4626 BAILOUT("Value: unsupported unary operation"); 4738 return Bailout("Value: unsupported unary operation");
4627 break; 4739 break;
4628 } 4740 }
4629 ast_context()->ReturnInstruction(instr, expr->id()); 4741 ast_context()->ReturnInstruction(instr, expr->id());
4630 } 4742 }
4631 } 4743 }
4632 4744
4633 4745
4634 HInstruction* HGraphBuilder::BuildIncrement(HValue* value, bool increment) { 4746 HInstruction* HGraphBuilder::BuildIncrement(HValue* value, bool increment) {
4635 HConstant* delta = increment 4747 HConstant* delta = increment
4636 ? graph_->GetConstant1() 4748 ? graph_->GetConstant1()
4637 : graph_->GetConstantMinus1(); 4749 : graph_->GetConstantMinus1();
4638 HInstruction* instr = new(zone()) HAdd(value, delta); 4750 HInstruction* instr = new(zone()) HAdd(value, delta);
4639 AssumeRepresentation(instr, Representation::Integer32()); 4751 AssumeRepresentation(instr, Representation::Integer32());
4640 return instr; 4752 return instr;
4641 } 4753 }
4642 4754
4643 4755
4644 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { 4756 void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
4757 ASSERT(!HasStackOverflow());
4758 ASSERT(current_block() != NULL);
4759 ASSERT(current_block()->HasPredecessor());
4645 Expression* target = expr->expression(); 4760 Expression* target = expr->expression();
4646 VariableProxy* proxy = target->AsVariableProxy(); 4761 VariableProxy* proxy = target->AsVariableProxy();
4647 Variable* var = proxy->AsVariable(); 4762 Variable* var = proxy->AsVariable();
4648 Property* prop = target->AsProperty(); 4763 Property* prop = target->AsProperty();
4649 ASSERT(var == NULL || prop == NULL); 4764 ASSERT(var == NULL || prop == NULL);
4650 bool inc = expr->op() == Token::INC; 4765 bool inc = expr->op() == Token::INC;
4651 4766
4652 if (var != NULL) { 4767 if (var != NULL) {
4653 VISIT_FOR_VALUE(target); 4768 CHECK_ALIVE(VisitForValue(target));
4654 4769
4655 // Match the full code generator stack by simulating an extra stack 4770 // Match the full code generator stack by simulating an extra stack
4656 // element for postfix operations in a non-effect context. 4771 // element for postfix operations in a non-effect context.
4657 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); 4772 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
4658 HValue* before = has_extra ? Top() : Pop(); 4773 HValue* before = has_extra ? Top() : Pop();
4659 HInstruction* after = BuildIncrement(before, inc); 4774 HInstruction* after = BuildIncrement(before, inc);
4660 AddInstruction(after); 4775 AddInstruction(after);
4661 Push(after); 4776 Push(after);
4662 4777
4663 if (var->is_global()) { 4778 if (var->is_global()) {
4664 HandleGlobalVariableAssignment(var, 4779 HandleGlobalVariableAssignment(var,
4665 after, 4780 after,
4666 expr->position(), 4781 expr->position(),
4667 expr->AssignmentId()); 4782 expr->AssignmentId());
4668 } else if (var->IsStackAllocated()) { 4783 } else if (var->IsStackAllocated()) {
4669 Bind(var, after); 4784 Bind(var, after);
4670 } else if (var->IsContextSlot()) { 4785 } else if (var->IsContextSlot()) {
4671 HValue* context = BuildContextChainWalk(var); 4786 HValue* context = BuildContextChainWalk(var);
4672 int index = var->AsSlot()->index(); 4787 int index = var->AsSlot()->index();
4673 HStoreContextSlot* instr = 4788 HStoreContextSlot* instr =
4674 new(zone()) HStoreContextSlot(context, index, after); 4789 new(zone()) HStoreContextSlot(context, index, after);
4675 AddInstruction(instr); 4790 AddInstruction(instr);
4676 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 4791 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
4677 } else { 4792 } else {
4678 BAILOUT("lookup variable in count operation"); 4793 return Bailout("lookup variable in count operation");
4679 } 4794 }
4680 Drop(has_extra ? 2 : 1); 4795 Drop(has_extra ? 2 : 1);
4681 ast_context()->ReturnValue(expr->is_postfix() ? before : after); 4796 ast_context()->ReturnValue(expr->is_postfix() ? before : after);
4682 4797
4683 } else if (prop != NULL) { 4798 } else if (prop != NULL) {
4684 prop->RecordTypeFeedback(oracle()); 4799 prop->RecordTypeFeedback(oracle());
4685 4800
4686 if (prop->key()->IsPropertyName()) { 4801 if (prop->key()->IsPropertyName()) {
4687 // Named property. 4802 // Named property.
4688 4803
4689 // Match the full code generator stack by simulating an extra stack 4804 // Match the full code generator stack by simulating an extra stack
4690 // element for postfix operations in a non-effect context. 4805 // element for postfix operations in a non-effect context.
4691 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); 4806 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
4692 if (has_extra) Push(graph_->GetConstantUndefined()); 4807 if (has_extra) Push(graph_->GetConstantUndefined());
4693 4808
4694 VISIT_FOR_VALUE(prop->obj()); 4809 CHECK_ALIVE(VisitForValue(prop->obj()));
4695 HValue* obj = Top(); 4810 HValue* obj = Top();
4696 4811
4697 HInstruction* load = NULL; 4812 HInstruction* load = NULL;
4698 if (prop->IsMonomorphic()) { 4813 if (prop->IsMonomorphic()) {
4699 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4814 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4700 Handle<Map> map = prop->GetReceiverTypes()->first(); 4815 Handle<Map> map = prop->GetReceiverTypes()->first();
4701 load = BuildLoadNamed(obj, prop, map, name); 4816 load = BuildLoadNamed(obj, prop, map, name);
4702 } else { 4817 } else {
4703 load = BuildLoadNamedGeneric(obj, prop); 4818 load = BuildLoadNamedGeneric(obj, prop);
4704 } 4819 }
(...skipping 20 matching lines...) Expand all
4725 ast_context()->ReturnValue(expr->is_postfix() ? before : after); 4840 ast_context()->ReturnValue(expr->is_postfix() ? before : after);
4726 4841
4727 } else { 4842 } else {
4728 // Keyed property. 4843 // Keyed property.
4729 4844
4730 // Match the full code generator stack by simulate an extra stack element 4845 // Match the full code generator stack by simulate an extra stack element
4731 // for postfix operations in a non-effect context. 4846 // for postfix operations in a non-effect context.
4732 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); 4847 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
4733 if (has_extra) Push(graph_->GetConstantUndefined()); 4848 if (has_extra) Push(graph_->GetConstantUndefined());
4734 4849
4735 VISIT_FOR_VALUE(prop->obj()); 4850 CHECK_ALIVE(VisitForValue(prop->obj()));
4736 VISIT_FOR_VALUE(prop->key()); 4851 CHECK_ALIVE(VisitForValue(prop->key()));
4737 HValue* obj = environment()->ExpressionStackAt(1); 4852 HValue* obj = environment()->ExpressionStackAt(1);
4738 HValue* key = environment()->ExpressionStackAt(0); 4853 HValue* key = environment()->ExpressionStackAt(0);
4739 4854
4740 HInstruction* load = BuildLoadKeyed(obj, key, prop); 4855 HInstruction* load = BuildLoadKeyed(obj, key, prop);
4741 PushAndAdd(load); 4856 PushAndAdd(load);
4742 if (load->HasSideEffects()) AddSimulate(expr->CountId()); 4857 if (load->HasSideEffects()) AddSimulate(expr->CountId());
4743 4858
4744 HValue* before = Pop(); 4859 HValue* before = Pop();
4745 // There is no deoptimization to after the increment, so we don't need 4860 // There is no deoptimization to after the increment, so we don't need
4746 // to simulate the expression stack after this instruction. 4861 // to simulate the expression stack after this instruction.
(...skipping 10 matching lines...) Expand all
4757 Drop(1); 4872 Drop(1);
4758 environment()->SetExpressionStackAt(0, after); 4873 environment()->SetExpressionStackAt(0, after);
4759 if (has_extra) environment()->SetExpressionStackAt(1, before); 4874 if (has_extra) environment()->SetExpressionStackAt(1, before);
4760 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); 4875 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
4761 Drop(has_extra ? 2 : 1); 4876 Drop(has_extra ? 2 : 1);
4762 4877
4763 ast_context()->ReturnValue(expr->is_postfix() ? before : after); 4878 ast_context()->ReturnValue(expr->is_postfix() ? before : after);
4764 } 4879 }
4765 4880
4766 } else { 4881 } else {
4767 BAILOUT("invalid lhs in count operation"); 4882 return Bailout("invalid lhs in count operation");
4768 } 4883 }
4769 } 4884 }
4770 4885
4771 4886
4772 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, 4887 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string,
4773 HValue* index) { 4888 HValue* index) {
4774 AddInstruction(new(zone()) HCheckNonSmi(string)); 4889 AddInstruction(new(zone()) HCheckNonSmi(string));
4775 AddInstruction(new(zone()) HCheckInstanceType( 4890 AddInstruction(new(zone()) HCheckInstanceType(
4776 string, FIRST_STRING_TYPE, LAST_STRING_TYPE)); 4891 string, FIRST_STRING_TYPE, LAST_STRING_TYPE));
4777 HStringLength* length = new(zone()) HStringLength(string); 4892 HStringLength* length = new(zone()) HStringLength(string);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4852 Literal* literal = expr->right()->AsLiteral(); 4967 Literal* literal = expr->right()->AsLiteral();
4853 if (literal == NULL) return false; 4968 if (literal == NULL) return false;
4854 if (!literal->handle()->IsString()) return false; 4969 if (!literal->handle()->IsString()) return false;
4855 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false; 4970 if (!call->name()->IsEqualTo(CStrVector("_ClassOf"))) return false;
4856 ASSERT(call->arguments()->length() == 1); 4971 ASSERT(call->arguments()->length() == 1);
4857 return true; 4972 return true;
4858 } 4973 }
4859 4974
4860 4975
4861 void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 4976 void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
4977 ASSERT(!HasStackOverflow());
4978 ASSERT(current_block() != NULL);
4979 ASSERT(current_block()->HasPredecessor());
4862 if (expr->op() == Token::COMMA) { 4980 if (expr->op() == Token::COMMA) {
4863 VISIT_FOR_EFFECT(expr->left()); 4981 CHECK_ALIVE(VisitForEffect(expr->left()));
4864 // Visit the right subexpression in the same AST context as the entire 4982 // Visit the right subexpression in the same AST context as the entire
4865 // expression. 4983 // expression.
4866 Visit(expr->right()); 4984 Visit(expr->right());
4867 4985
4868 } else if (expr->op() == Token::AND || expr->op() == Token::OR) { 4986 } else if (expr->op() == Token::AND || expr->op() == Token::OR) {
4869 bool is_logical_and = (expr->op() == Token::AND); 4987 bool is_logical_and = (expr->op() == Token::AND);
4870 if (ast_context()->IsTest()) { 4988 if (ast_context()->IsTest()) {
4871 TestContext* context = TestContext::cast(ast_context()); 4989 TestContext* context = TestContext::cast(ast_context());
4872 // Translate left subexpression. 4990 // Translate left subexpression.
4873 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 4991 HBasicBlock* eval_right = graph()->CreateBasicBlock();
4874 if (is_logical_and) { 4992 if (is_logical_and) {
4875 VISIT_FOR_CONTROL(expr->left(), eval_right, context->if_false()); 4993 CHECK_BAILOUT(VisitForControl(expr->left(),
4994 eval_right,
4995 context->if_false()));
4876 } else { 4996 } else {
4877 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right); 4997 CHECK_BAILOUT(VisitForControl(expr->left(),
4998 context->if_true(),
4999 eval_right));
4878 } 5000 }
4879 eval_right->SetJoinId(expr->RightId());
4880 5001
4881 // Translate right subexpression by visiting it in the same AST 5002 // Translate right subexpression by visiting it in the same AST
4882 // context as the entire expression. 5003 // context as the entire expression.
4883 set_current_block(eval_right); 5004 if (eval_right->HasPredecessor()) {
4884 Visit(expr->right()); 5005 eval_right->SetJoinId(expr->RightId());
5006 set_current_block(eval_right);
5007 Visit(expr->right());
5008 }
4885 5009
4886 } else if (ast_context()->IsValue()) { 5010 } else if (ast_context()->IsValue()) {
4887 VISIT_FOR_VALUE(expr->left()); 5011 CHECK_ALIVE(VisitForValue(expr->left()));
4888 ASSERT(current_block() != NULL); 5012 ASSERT(current_block() != NULL);
4889 5013
4890 // We need an extra block to maintain edge-split form. 5014 // We need an extra block to maintain edge-split form.
4891 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 5015 HBasicBlock* empty_block = graph()->CreateBasicBlock();
4892 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 5016 HBasicBlock* eval_right = graph()->CreateBasicBlock();
4893 HTest* test = is_logical_and 5017 HTest* test = is_logical_and
4894 ? new(zone()) HTest(Top(), eval_right, empty_block) 5018 ? new(zone()) HTest(Top(), eval_right, empty_block)
4895 : new(zone()) HTest(Top(), empty_block, eval_right); 5019 : new(zone()) HTest(Top(), empty_block, eval_right);
4896 current_block()->Finish(test); 5020 current_block()->Finish(test);
4897 5021
4898 set_current_block(eval_right); 5022 set_current_block(eval_right);
4899 Drop(1); // Value of the left subexpression. 5023 Drop(1); // Value of the left subexpression.
4900 VISIT_FOR_VALUE(expr->right()); 5024 CHECK_BAILOUT(VisitForValue(expr->right()));
4901 5025
4902 HBasicBlock* join_block = 5026 HBasicBlock* join_block =
4903 CreateJoin(empty_block, current_block(), expr->id()); 5027 CreateJoin(empty_block, current_block(), expr->id());
4904 set_current_block(join_block); 5028 set_current_block(join_block);
4905 ast_context()->ReturnValue(Pop()); 5029 ast_context()->ReturnValue(Pop());
4906 5030
4907 } else { 5031 } else {
4908 ASSERT(ast_context()->IsEffect()); 5032 ASSERT(ast_context()->IsEffect());
4909 // In an effect context, we don't need the value of the left 5033 // In an effect context, we don't need the value of the left
4910 // subexpression, only its control flow and side effects. We need an 5034 // subexpression, only its control flow and side effects. We need an
4911 // extra block to maintain edge-split form. 5035 // extra block to maintain edge-split form.
4912 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 5036 HBasicBlock* empty_block = graph()->CreateBasicBlock();
4913 HBasicBlock* right_block = graph()->CreateBasicBlock(); 5037 HBasicBlock* right_block = graph()->CreateBasicBlock();
4914 HBasicBlock* join_block = graph()->CreateBasicBlock();
4915 if (is_logical_and) { 5038 if (is_logical_and) {
4916 VISIT_FOR_CONTROL(expr->left(), right_block, empty_block); 5039 CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block));
4917 } else { 5040 } else {
4918 VISIT_FOR_CONTROL(expr->left(), empty_block, right_block); 5041 CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block));
4919 } 5042 }
5043
4920 // TODO(kmillikin): Find a way to fix this. It's ugly that there are 5044 // TODO(kmillikin): Find a way to fix this. It's ugly that there are
4921 // actually two empty blocks (one here and one inserted by 5045 // actually two empty blocks (one here and one inserted by
4922 // TestContext::BuildBranch, and that they both have an HSimulate 5046 // TestContext::BuildBranch, and that they both have an HSimulate
4923 // though the second one is not a merge node, and that we really have 5047 // though the second one is not a merge node, and that we really have
4924 // no good AST ID to put on that first HSimulate. 5048 // no good AST ID to put on that first HSimulate.
4925 empty_block->SetJoinId(expr->id()); 5049 if (empty_block->HasPredecessor()) {
4926 right_block->SetJoinId(expr->RightId()); 5050 empty_block->SetJoinId(expr->id());
4927 set_current_block(right_block); 5051 } else {
4928 VISIT_FOR_EFFECT(expr->right()); 5052 empty_block = NULL;
5053 }
4929 5054
4930 empty_block->Goto(join_block); 5055 if (right_block->HasPredecessor()) {
4931 current_block()->Goto(join_block); 5056 right_block->SetJoinId(expr->RightId());
4932 join_block->SetJoinId(expr->id()); 5057 set_current_block(right_block);
5058 CHECK_BAILOUT(VisitForEffect(expr->right()));
5059 right_block = current_block();
5060 } else {
5061 right_block = NULL;
5062 }
5063
5064 HBasicBlock* join_block =
5065 CreateJoin(empty_block, right_block, expr->id());
4933 set_current_block(join_block); 5066 set_current_block(join_block);
4934 // We did not materialize any value in the predecessor environments, 5067 // We did not materialize any value in the predecessor environments,
4935 // so there is no need to handle it here. 5068 // so there is no need to handle it here.
4936 } 5069 }
4937 5070
4938 } else { 5071 } else {
4939 VISIT_FOR_VALUE(expr->left()); 5072 CHECK_ALIVE(VisitForValue(expr->left()));
4940 VISIT_FOR_VALUE(expr->right()); 5073 CHECK_ALIVE(VisitForValue(expr->right()));
4941 5074
4942 HValue* right = Pop(); 5075 HValue* right = Pop();
4943 HValue* left = Pop(); 5076 HValue* left = Pop();
4944 HInstruction* instr = BuildBinaryOperation(expr, left, right); 5077 HInstruction* instr = BuildBinaryOperation(expr, left, right);
4945 instr->set_position(expr->position()); 5078 instr->set_position(expr->position());
4946 ast_context()->ReturnInstruction(instr, expr->id()); 5079 ast_context()->ReturnInstruction(instr, expr->id());
4947 } 5080 }
4948 } 5081 }
4949 5082
4950 5083
(...skipping 18 matching lines...) Expand all
4969 Representation HGraphBuilder::ToRepresentation(TypeInfo info) { 5102 Representation HGraphBuilder::ToRepresentation(TypeInfo info) {
4970 if (info.IsSmi()) return Representation::Integer32(); 5103 if (info.IsSmi()) return Representation::Integer32();
4971 if (info.IsInteger32()) return Representation::Integer32(); 5104 if (info.IsInteger32()) return Representation::Integer32();
4972 if (info.IsDouble()) return Representation::Double(); 5105 if (info.IsDouble()) return Representation::Double();
4973 if (info.IsNumber()) return Representation::Double(); 5106 if (info.IsNumber()) return Representation::Double();
4974 return Representation::Tagged(); 5107 return Representation::Tagged();
4975 } 5108 }
4976 5109
4977 5110
4978 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 5111 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
5112 ASSERT(!HasStackOverflow());
5113 ASSERT(current_block() != NULL);
5114 ASSERT(current_block()->HasPredecessor());
4979 if (IsClassOfTest(expr)) { 5115 if (IsClassOfTest(expr)) {
4980 CallRuntime* call = expr->left()->AsCallRuntime(); 5116 CallRuntime* call = expr->left()->AsCallRuntime();
4981 VISIT_FOR_VALUE(call->arguments()->at(0)); 5117 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
4982 HValue* value = Pop(); 5118 HValue* value = Pop();
4983 Literal* literal = expr->right()->AsLiteral(); 5119 Literal* literal = expr->right()->AsLiteral();
4984 Handle<String> rhs = Handle<String>::cast(literal->handle()); 5120 Handle<String> rhs = Handle<String>::cast(literal->handle());
4985 HInstruction* instr = new(zone()) HClassOfTest(value, rhs); 5121 HInstruction* instr = new(zone()) HClassOfTest(value, rhs);
4986 instr->set_position(expr->position()); 5122 instr->set_position(expr->position());
4987 ast_context()->ReturnInstruction(instr, expr->id()); 5123 ast_context()->ReturnInstruction(instr, expr->id());
4988 return; 5124 return;
4989 } 5125 }
4990 5126
4991 // Check for the pattern: typeof <expression> == <string literal>. 5127 // Check for the pattern: typeof <expression> == <string literal>.
4992 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); 5128 UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
4993 Literal* right_literal = expr->right()->AsLiteral(); 5129 Literal* right_literal = expr->right()->AsLiteral();
4994 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && 5130 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
4995 left_unary != NULL && left_unary->op() == Token::TYPEOF && 5131 left_unary != NULL && left_unary->op() == Token::TYPEOF &&
4996 right_literal != NULL && right_literal->handle()->IsString()) { 5132 right_literal != NULL && right_literal->handle()->IsString()) {
4997 VisitForTypeOf(left_unary->expression()); 5133 VisitForTypeOf(left_unary->expression());
fschneider 2011/04/13 11:20:16 CHECK_ALIVE(left_unary->expression());
4998 if (HasStackOverflow()) return; 5134 if (HasStackOverflow() || current_block() == NULL) return;
4999 HValue* left = Pop(); 5135 HValue* left = Pop();
5000 HInstruction* instr = new(zone()) HTypeofIs(left, 5136 HInstruction* instr = new(zone()) HTypeofIs(left,
5001 Handle<String>::cast(right_literal->handle())); 5137 Handle<String>::cast(right_literal->handle()));
5002 instr->set_position(expr->position()); 5138 instr->set_position(expr->position());
5003 ast_context()->ReturnInstruction(instr, expr->id()); 5139 ast_context()->ReturnInstruction(instr, expr->id());
5004 return; 5140 return;
5005 } 5141 }
5006 5142
5007 VISIT_FOR_VALUE(expr->left()); 5143 CHECK_ALIVE(VisitForValue(expr->left()));
5008 VISIT_FOR_VALUE(expr->right()); 5144 CHECK_ALIVE(VisitForValue(expr->right()));
5009 5145
5010 HValue* right = Pop(); 5146 HValue* right = Pop();
5011 HValue* left = Pop(); 5147 HValue* left = Pop();
5012 Token::Value op = expr->op(); 5148 Token::Value op = expr->op();
5013 5149
5014 TypeInfo type_info = oracle()->CompareType(expr); 5150 TypeInfo type_info = oracle()->CompareType(expr);
5015 HInstruction* instr = NULL; 5151 HInstruction* instr = NULL;
5016 if (op == Token::INSTANCEOF) { 5152 if (op == Token::INSTANCEOF) {
5017 // Check to see if the rhs of the instanceof is a global function not 5153 // Check to see if the rhs of the instanceof is a global function not
5018 // residing in new space. If it is we assume that the function will stay the 5154 // residing in new space. If it is we assume that the function will stay the
(...skipping 24 matching lines...) Expand all
5043 // assumed to stay the same for this instanceof. 5179 // assumed to stay the same for this instanceof.
5044 if (target.is_null()) { 5180 if (target.is_null()) {
5045 HContext* context = new(zone()) HContext; 5181 HContext* context = new(zone()) HContext;
5046 AddInstruction(context); 5182 AddInstruction(context);
5047 instr = new(zone()) HInstanceOf(context, left, right); 5183 instr = new(zone()) HInstanceOf(context, left, right);
5048 } else { 5184 } else {
5049 AddInstruction(new(zone()) HCheckFunction(right, target)); 5185 AddInstruction(new(zone()) HCheckFunction(right, target));
5050 instr = new(zone()) HInstanceOfKnownGlobal(left, target); 5186 instr = new(zone()) HInstanceOfKnownGlobal(left, target);
5051 } 5187 }
5052 } else if (op == Token::IN) { 5188 } else if (op == Token::IN) {
5053 BAILOUT("Unsupported comparison: in"); 5189 return Bailout("Unsupported comparison: in");
5054 } else if (type_info.IsNonPrimitive()) { 5190 } else if (type_info.IsNonPrimitive()) {
5055 switch (op) { 5191 switch (op) {
5056 case Token::EQ: 5192 case Token::EQ:
5057 case Token::EQ_STRICT: { 5193 case Token::EQ_STRICT: {
5058 AddInstruction(new(zone()) HCheckNonSmi(left)); 5194 AddInstruction(new(zone()) HCheckNonSmi(left));
5059 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left)); 5195 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
5060 AddInstruction(new(zone()) HCheckNonSmi(right)); 5196 AddInstruction(new(zone()) HCheckNonSmi(right));
5061 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right)); 5197 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
5062 instr = new(zone()) HCompareJSObjectEq(left, right); 5198 instr = new(zone()) HCompareJSObjectEq(left, right);
5063 break; 5199 break;
5064 } 5200 }
5065 default: 5201 default:
5066 BAILOUT("Unsupported non-primitive compare"); 5202 return Bailout("Unsupported non-primitive compare");
5067 break; 5203 break;
5068 } 5204 }
5069 } else { 5205 } else {
5070 HCompare* compare = new(zone()) HCompare(left, right, op); 5206 HCompare* compare = new(zone()) HCompare(left, right, op);
5071 Representation r = ToRepresentation(type_info); 5207 Representation r = ToRepresentation(type_info);
5072 compare->SetInputRepresentation(r); 5208 compare->SetInputRepresentation(r);
5073 instr = compare; 5209 instr = compare;
5074 } 5210 }
5075 instr->set_position(expr->position()); 5211 instr->set_position(expr->position());
5076 ast_context()->ReturnInstruction(instr, expr->id()); 5212 ast_context()->ReturnInstruction(instr, expr->id());
5077 } 5213 }
5078 5214
5079 5215
5080 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) { 5216 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) {
5081 VISIT_FOR_VALUE(expr->expression()); 5217 ASSERT(!HasStackOverflow());
5218 ASSERT(current_block() != NULL);
5219 ASSERT(current_block()->HasPredecessor());
5220 CHECK_ALIVE(VisitForValue(expr->expression()));
5082 5221
5083 HValue* value = Pop(); 5222 HValue* value = Pop();
5084 HIsNull* compare = new(zone()) HIsNull(value, expr->is_strict()); 5223 HIsNull* compare = new(zone()) HIsNull(value, expr->is_strict());
5085 ast_context()->ReturnInstruction(compare, expr->id()); 5224 ast_context()->ReturnInstruction(compare, expr->id());
5086 } 5225 }
5087 5226
5088 5227
5089 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 5228 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5090 BAILOUT("ThisFunction"); 5229 ASSERT(!HasStackOverflow());
5230 ASSERT(current_block() != NULL);
5231 ASSERT(current_block()->HasPredecessor());
5232 return Bailout("ThisFunction");
5091 } 5233 }
5092 5234
5093 5235
5094 void HGraphBuilder::VisitDeclaration(Declaration* decl) { 5236 void HGraphBuilder::VisitDeclaration(Declaration* decl) {
5095 // We allow only declarations that do not require code generation. 5237 // We allow only declarations that do not require code generation.
5096 // The following all require code generation: global variables and 5238 // The following all require code generation: global variables and
5097 // functions, variables with slot type LOOKUP, declarations with 5239 // functions, variables with slot type LOOKUP, declarations with
5098 // mode CONST, and functions. 5240 // mode CONST, and functions.
5099 Variable* var = decl->proxy()->var(); 5241 Variable* var = decl->proxy()->var();
5100 Slot* slot = var->AsSlot(); 5242 Slot* slot = var->AsSlot();
5101 if (var->is_global() || 5243 if (var->is_global() ||
5102 (slot != NULL && slot->type() == Slot::LOOKUP) || 5244 (slot != NULL && slot->type() == Slot::LOOKUP) ||
5103 decl->mode() == Variable::CONST || 5245 decl->mode() == Variable::CONST ||
5104 decl->fun() != NULL) { 5246 decl->fun() != NULL) {
5105 BAILOUT("unsupported declaration"); 5247 return Bailout("unsupported declaration");
5106 } 5248 }
5107 } 5249 }
5108 5250
5109 5251
5110 // Generators for inline runtime functions. 5252 // Generators for inline runtime functions.
5111 // Support for types. 5253 // Support for types.
5112 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) { 5254 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) {
5113 ASSERT(call->arguments()->length() == 1); 5255 ASSERT(call->arguments()->length() == 1);
5114 VISIT_FOR_VALUE(call->arguments()->at(0)); 5256 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5115 HValue* value = Pop(); 5257 HValue* value = Pop();
5116 HIsSmi* result = new(zone()) HIsSmi(value); 5258 HIsSmi* result = new(zone()) HIsSmi(value);
5117 ast_context()->ReturnInstruction(result, call->id()); 5259 ast_context()->ReturnInstruction(result, call->id());
5118 } 5260 }
5119 5261
5120 5262
5121 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 5263 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
5122 ASSERT(call->arguments()->length() == 1); 5264 ASSERT(call->arguments()->length() == 1);
5123 VISIT_FOR_VALUE(call->arguments()->at(0)); 5265 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5124 HValue* value = Pop(); 5266 HValue* value = Pop();
5125 HHasInstanceType* result = 5267 HHasInstanceType* result =
5126 new(zone()) HHasInstanceType(value, FIRST_JS_OBJECT_TYPE, LAST_TYPE); 5268 new(zone()) HHasInstanceType(value, FIRST_JS_OBJECT_TYPE, LAST_TYPE);
5127 ast_context()->ReturnInstruction(result, call->id()); 5269 ast_context()->ReturnInstruction(result, call->id());
5128 } 5270 }
5129 5271
5130 5272
5131 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) { 5273 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) {
5132 ASSERT(call->arguments()->length() == 1); 5274 ASSERT(call->arguments()->length() == 1);
5133 VISIT_FOR_VALUE(call->arguments()->at(0)); 5275 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5134 HValue* value = Pop(); 5276 HValue* value = Pop();
5135 HHasInstanceType* result = 5277 HHasInstanceType* result =
5136 new(zone()) HHasInstanceType(value, JS_FUNCTION_TYPE); 5278 new(zone()) HHasInstanceType(value, JS_FUNCTION_TYPE);
5137 ast_context()->ReturnInstruction(result, call->id()); 5279 ast_context()->ReturnInstruction(result, call->id());
5138 } 5280 }
5139 5281
5140 5282
5141 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 5283 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
5142 ASSERT(call->arguments()->length() == 1); 5284 ASSERT(call->arguments()->length() == 1);
5143 VISIT_FOR_VALUE(call->arguments()->at(0)); 5285 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5144 HValue* value = Pop(); 5286 HValue* value = Pop();
5145 HHasCachedArrayIndex* result = new(zone()) HHasCachedArrayIndex(value); 5287 HHasCachedArrayIndex* result = new(zone()) HHasCachedArrayIndex(value);
5146 ast_context()->ReturnInstruction(result, call->id()); 5288 ast_context()->ReturnInstruction(result, call->id());
5147 } 5289 }
5148 5290
5149 5291
5150 void HGraphBuilder::GenerateIsArray(CallRuntime* call) { 5292 void HGraphBuilder::GenerateIsArray(CallRuntime* call) {
5151 ASSERT(call->arguments()->length() == 1); 5293 ASSERT(call->arguments()->length() == 1);
5152 VISIT_FOR_VALUE(call->arguments()->at(0)); 5294 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5153 HValue* value = Pop(); 5295 HValue* value = Pop();
5154 HHasInstanceType* result = new(zone()) HHasInstanceType(value, JS_ARRAY_TYPE); 5296 HHasInstanceType* result = new(zone()) HHasInstanceType(value, JS_ARRAY_TYPE);
5155 ast_context()->ReturnInstruction(result, call->id()); 5297 ast_context()->ReturnInstruction(result, call->id());
5156 } 5298 }
5157 5299
5158 5300
5159 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 5301 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
5160 ASSERT(call->arguments()->length() == 1); 5302 ASSERT(call->arguments()->length() == 1);
5161 VISIT_FOR_VALUE(call->arguments()->at(0)); 5303 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5162 HValue* value = Pop(); 5304 HValue* value = Pop();
5163 HHasInstanceType* result = 5305 HHasInstanceType* result =
5164 new(zone()) HHasInstanceType(value, JS_REGEXP_TYPE); 5306 new(zone()) HHasInstanceType(value, JS_REGEXP_TYPE);
5165 ast_context()->ReturnInstruction(result, call->id()); 5307 ast_context()->ReturnInstruction(result, call->id());
5166 } 5308 }
5167 5309
5168 5310
5169 void HGraphBuilder::GenerateIsObject(CallRuntime* call) { 5311 void HGraphBuilder::GenerateIsObject(CallRuntime* call) {
5170 ASSERT(call->arguments()->length() == 1); 5312 ASSERT(call->arguments()->length() == 1);
5171 VISIT_FOR_VALUE(call->arguments()->at(0)); 5313 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5172 HValue* value = Pop(); 5314 HValue* value = Pop();
5173 HIsObject* test = new(zone()) HIsObject(value); 5315 HIsObject* test = new(zone()) HIsObject(value);
5174 ast_context()->ReturnInstruction(test, call->id()); 5316 ast_context()->ReturnInstruction(test, call->id());
5175 } 5317 }
5176 5318
5177 5319
5178 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 5320 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
5179 BAILOUT("inlined runtime function: IsNonNegativeSmi"); 5321 return Bailout("inlined runtime function: IsNonNegativeSmi");
5180 } 5322 }
5181 5323
5182 5324
5183 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 5325 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
5184 BAILOUT("inlined runtime function: IsUndetectableObject"); 5326 return Bailout("inlined runtime function: IsUndetectableObject");
5185 } 5327 }
5186 5328
5187 5329
5188 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 5330 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
5189 CallRuntime* call) { 5331 CallRuntime* call) {
5190 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); 5332 return Bailout(
5333 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
5191 } 5334 }
5192 5335
5193 5336
5194 // Support for construct call checks. 5337 // Support for construct call checks.
5195 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 5338 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
5196 ASSERT(call->arguments()->length() == 0); 5339 ASSERT(call->arguments()->length() == 0);
5197 if (function_state()->outer() != NULL) { 5340 if (function_state()->outer() != NULL) {
5198 // We are generating graph for inlined function. Currently 5341 // We are generating graph for inlined function. Currently
5199 // constructor inlining is not supported and we can just return 5342 // constructor inlining is not supported and we can just return
5200 // false from %_IsConstructCall(). 5343 // false from %_IsConstructCall().
5201 ast_context()->ReturnValue(graph()->GetConstantFalse()); 5344 ast_context()->ReturnValue(graph()->GetConstantFalse());
5202 } else { 5345 } else {
5203 ast_context()->ReturnInstruction(new(zone()) HIsConstructCall, call->id()); 5346 ast_context()->ReturnInstruction(new(zone()) HIsConstructCall, call->id());
5204 } 5347 }
5205 } 5348 }
5206 5349
5207 5350
5208 // Support for arguments.length and arguments[?]. 5351 // Support for arguments.length and arguments[?].
5209 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 5352 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
5210 ASSERT(call->arguments()->length() == 0); 5353 ASSERT(call->arguments()->length() == 0);
5211 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 5354 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
5212 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); 5355 HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
5213 ast_context()->ReturnInstruction(result, call->id()); 5356 ast_context()->ReturnInstruction(result, call->id());
5214 } 5357 }
5215 5358
5216 5359
5217 void HGraphBuilder::GenerateArguments(CallRuntime* call) { 5360 void HGraphBuilder::GenerateArguments(CallRuntime* call) {
5218 ASSERT(call->arguments()->length() == 1); 5361 ASSERT(call->arguments()->length() == 1);
5219 VISIT_FOR_VALUE(call->arguments()->at(0)); 5362 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5220 HValue* index = Pop(); 5363 HValue* index = Pop();
5221 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 5364 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
5222 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 5365 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
5223 HAccessArgumentsAt* result = 5366 HAccessArgumentsAt* result =
5224 new(zone()) HAccessArgumentsAt(elements, length, index); 5367 new(zone()) HAccessArgumentsAt(elements, length, index);
5225 ast_context()->ReturnInstruction(result, call->id()); 5368 ast_context()->ReturnInstruction(result, call->id());
5226 } 5369 }
5227 5370
5228 5371
5229 // Support for accessing the class and value fields of an object. 5372 // Support for accessing the class and value fields of an object.
5230 void HGraphBuilder::GenerateClassOf(CallRuntime* call) { 5373 void HGraphBuilder::GenerateClassOf(CallRuntime* call) {
5231 // The special form detected by IsClassOfTest is detected before we get here 5374 // The special form detected by IsClassOfTest is detected before we get here
5232 // and does not cause a bailout. 5375 // and does not cause a bailout.
5233 BAILOUT("inlined runtime function: ClassOf"); 5376 return Bailout("inlined runtime function: ClassOf");
5234 } 5377 }
5235 5378
5236 5379
5237 void HGraphBuilder::GenerateValueOf(CallRuntime* call) { 5380 void HGraphBuilder::GenerateValueOf(CallRuntime* call) {
5238 ASSERT(call->arguments()->length() == 1); 5381 ASSERT(call->arguments()->length() == 1);
5239 VISIT_FOR_VALUE(call->arguments()->at(0)); 5382 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5240 HValue* value = Pop(); 5383 HValue* value = Pop();
5241 HValueOf* result = new(zone()) HValueOf(value); 5384 HValueOf* result = new(zone()) HValueOf(value);
5242 ast_context()->ReturnInstruction(result, call->id()); 5385 ast_context()->ReturnInstruction(result, call->id());
5243 } 5386 }
5244 5387
5245 5388
5246 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 5389 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
5247 BAILOUT("inlined runtime function: SetValueOf"); 5390 return Bailout("inlined runtime function: SetValueOf");
5248 } 5391 }
5249 5392
5250 5393
5251 // Fast support for charCodeAt(n). 5394 // Fast support for charCodeAt(n).
5252 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 5395 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
5253 ASSERT(call->arguments()->length() == 2); 5396 ASSERT(call->arguments()->length() == 2);
5254 VISIT_FOR_VALUE(call->arguments()->at(0)); 5397 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5255 VISIT_FOR_VALUE(call->arguments()->at(1)); 5398 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5256 HValue* index = Pop(); 5399 HValue* index = Pop();
5257 HValue* string = Pop(); 5400 HValue* string = Pop();
5258 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); 5401 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index);
5259 ast_context()->ReturnInstruction(result, call->id()); 5402 ast_context()->ReturnInstruction(result, call->id());
5260 } 5403 }
5261 5404
5262 5405
5263 // Fast support for string.charAt(n) and string[n]. 5406 // Fast support for string.charAt(n) and string[n].
5264 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 5407 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
5265 ASSERT(call->arguments()->length() == 1); 5408 ASSERT(call->arguments()->length() == 1);
5266 VISIT_FOR_VALUE(call->arguments()->at(0)); 5409 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5267 HValue* char_code = Pop(); 5410 HValue* char_code = Pop();
5268 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); 5411 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
5269 ast_context()->ReturnInstruction(result, call->id()); 5412 ast_context()->ReturnInstruction(result, call->id());
5270 } 5413 }
5271 5414
5272 5415
5273 // Fast support for string.charAt(n) and string[n]. 5416 // Fast support for string.charAt(n) and string[n].
5274 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 5417 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
5275 ASSERT(call->arguments()->length() == 2); 5418 ASSERT(call->arguments()->length() == 2);
5276 VISIT_FOR_VALUE(call->arguments()->at(0)); 5419 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5277 VISIT_FOR_VALUE(call->arguments()->at(1)); 5420 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5278 HValue* index = Pop(); 5421 HValue* index = Pop();
5279 HValue* string = Pop(); 5422 HValue* string = Pop();
5280 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); 5423 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
5281 AddInstruction(char_code); 5424 AddInstruction(char_code);
5282 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); 5425 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
5283 ast_context()->ReturnInstruction(result, call->id()); 5426 ast_context()->ReturnInstruction(result, call->id());
5284 } 5427 }
5285 5428
5286 5429
5287 // Fast support for object equality testing. 5430 // Fast support for object equality testing.
5288 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 5431 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
5289 ASSERT(call->arguments()->length() == 2); 5432 ASSERT(call->arguments()->length() == 2);
5290 VISIT_FOR_VALUE(call->arguments()->at(0)); 5433 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5291 VISIT_FOR_VALUE(call->arguments()->at(1)); 5434 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5292 HValue* right = Pop(); 5435 HValue* right = Pop();
5293 HValue* left = Pop(); 5436 HValue* left = Pop();
5294 HCompareJSObjectEq* result = new(zone()) HCompareJSObjectEq(left, right); 5437 HCompareJSObjectEq* result = new(zone()) HCompareJSObjectEq(left, right);
5295 ast_context()->ReturnInstruction(result, call->id()); 5438 ast_context()->ReturnInstruction(result, call->id());
5296 } 5439 }
5297 5440
5298 5441
5299 void HGraphBuilder::GenerateLog(CallRuntime* call) { 5442 void HGraphBuilder::GenerateLog(CallRuntime* call) {
5300 // %_Log is ignored in optimized code. 5443 // %_Log is ignored in optimized code.
5301 ast_context()->ReturnValue(graph()->GetConstantUndefined()); 5444 ast_context()->ReturnValue(graph()->GetConstantUndefined());
5302 } 5445 }
5303 5446
5304 5447
5305 // Fast support for Math.random(). 5448 // Fast support for Math.random().
5306 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { 5449 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
5307 BAILOUT("inlined runtime function: RandomHeapNumber"); 5450 return Bailout("inlined runtime function: RandomHeapNumber");
5308 } 5451 }
5309 5452
5310 5453
5311 // Fast support for StringAdd. 5454 // Fast support for StringAdd.
5312 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { 5455 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) {
5313 ASSERT_EQ(2, call->arguments()->length()); 5456 ASSERT_EQ(2, call->arguments()->length());
5314 VisitArgumentList(call->arguments()); 5457 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5315 CHECK_BAILOUT;
5316 HContext* context = new(zone()) HContext; 5458 HContext* context = new(zone()) HContext;
5317 AddInstruction(context); 5459 AddInstruction(context);
5318 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); 5460 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2);
5319 Drop(2); 5461 Drop(2);
5320 ast_context()->ReturnInstruction(result, call->id()); 5462 ast_context()->ReturnInstruction(result, call->id());
5321 } 5463 }
5322 5464
5323 5465
5324 // Fast support for SubString. 5466 // Fast support for SubString.
5325 void HGraphBuilder::GenerateSubString(CallRuntime* call) { 5467 void HGraphBuilder::GenerateSubString(CallRuntime* call) {
5326 ASSERT_EQ(3, call->arguments()->length()); 5468 ASSERT_EQ(3, call->arguments()->length());
5327 VisitArgumentList(call->arguments()); 5469 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5328 CHECK_BAILOUT;
5329 HContext* context = new(zone()) HContext; 5470 HContext* context = new(zone()) HContext;
5330 AddInstruction(context); 5471 AddInstruction(context);
5331 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); 5472 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
5332 Drop(3); 5473 Drop(3);
5333 ast_context()->ReturnInstruction(result, call->id()); 5474 ast_context()->ReturnInstruction(result, call->id());
5334 } 5475 }
5335 5476
5336 5477
5337 // Fast support for StringCompare. 5478 // Fast support for StringCompare.
5338 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { 5479 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) {
5339 ASSERT_EQ(2, call->arguments()->length()); 5480 ASSERT_EQ(2, call->arguments()->length());
5340 VisitArgumentList(call->arguments()); 5481 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5341 CHECK_BAILOUT;
5342 HContext* context = new(zone()) HContext; 5482 HContext* context = new(zone()) HContext;
5343 AddInstruction(context); 5483 AddInstruction(context);
5344 HCallStub* result = 5484 HCallStub* result =
5345 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); 5485 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
5346 Drop(2); 5486 Drop(2);
5347 ast_context()->ReturnInstruction(result, call->id()); 5487 ast_context()->ReturnInstruction(result, call->id());
5348 } 5488 }
5349 5489
5350 5490
5351 // Support for direct calls from JavaScript to native RegExp code. 5491 // Support for direct calls from JavaScript to native RegExp code.
5352 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 5492 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
5353 ASSERT_EQ(4, call->arguments()->length()); 5493 ASSERT_EQ(4, call->arguments()->length());
5354 VisitArgumentList(call->arguments()); 5494 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5355 CHECK_BAILOUT;
5356 HContext* context = new(zone()) HContext; 5495 HContext* context = new(zone()) HContext;
5357 AddInstruction(context); 5496 AddInstruction(context);
5358 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); 5497 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
5359 Drop(4); 5498 Drop(4);
5360 ast_context()->ReturnInstruction(result, call->id()); 5499 ast_context()->ReturnInstruction(result, call->id());
5361 } 5500 }
5362 5501
5363 5502
5364 // Construct a RegExp exec result with two in-object properties. 5503 // Construct a RegExp exec result with two in-object properties.
5365 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 5504 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
5366 ASSERT_EQ(3, call->arguments()->length()); 5505 ASSERT_EQ(3, call->arguments()->length());
5367 VisitArgumentList(call->arguments()); 5506 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5368 CHECK_BAILOUT;
5369 HContext* context = new(zone()) HContext; 5507 HContext* context = new(zone()) HContext;
5370 AddInstruction(context); 5508 AddInstruction(context);
5371 HCallStub* result = 5509 HCallStub* result =
5372 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); 5510 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
5373 Drop(3); 5511 Drop(3);
5374 ast_context()->ReturnInstruction(result, call->id()); 5512 ast_context()->ReturnInstruction(result, call->id());
5375 } 5513 }
5376 5514
5377 5515
5378 // Support for fast native caches. 5516 // Support for fast native caches.
5379 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 5517 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
5380 BAILOUT("inlined runtime function: GetFromCache"); 5518 return Bailout("inlined runtime function: GetFromCache");
5381 } 5519 }
5382 5520
5383 5521
5384 // Fast support for number to string. 5522 // Fast support for number to string.
5385 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { 5523 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) {
5386 ASSERT_EQ(1, call->arguments()->length()); 5524 ASSERT_EQ(1, call->arguments()->length());
5387 VisitArgumentList(call->arguments()); 5525 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5388 CHECK_BAILOUT;
5389 HContext* context = new(zone()) HContext; 5526 HContext* context = new(zone()) HContext;
5390 AddInstruction(context); 5527 AddInstruction(context);
5391 HCallStub* result = 5528 HCallStub* result =
5392 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 5529 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
5393 Drop(1); 5530 Drop(1);
5394 ast_context()->ReturnInstruction(result, call->id()); 5531 ast_context()->ReturnInstruction(result, call->id());
5395 } 5532 }
5396 5533
5397 5534
5398 // Fast swapping of elements. Takes three expressions, the object and two 5535 // Fast swapping of elements. Takes three expressions, the object and two
5399 // indices. This should only be used if the indices are known to be 5536 // indices. This should only be used if the indices are known to be
5400 // non-negative and within bounds of the elements array at the call site. 5537 // non-negative and within bounds of the elements array at the call site.
5401 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { 5538 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) {
5402 BAILOUT("inlined runtime function: SwapElements"); 5539 return Bailout("inlined runtime function: SwapElements");
5403 } 5540 }
5404 5541
5405 5542
5406 // Fast call for custom callbacks. 5543 // Fast call for custom callbacks.
5407 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { 5544 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) {
5408 BAILOUT("inlined runtime function: CallFunction"); 5545 return Bailout("inlined runtime function: CallFunction");
5409 } 5546 }
5410 5547
5411 5548
5412 // Fast call to math functions. 5549 // Fast call to math functions.
5413 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { 5550 void HGraphBuilder::GenerateMathPow(CallRuntime* call) {
5414 ASSERT_EQ(2, call->arguments()->length()); 5551 ASSERT_EQ(2, call->arguments()->length());
5415 VISIT_FOR_VALUE(call->arguments()->at(0)); 5552 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5416 VISIT_FOR_VALUE(call->arguments()->at(1)); 5553 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5417 HValue* right = Pop(); 5554 HValue* right = Pop();
5418 HValue* left = Pop(); 5555 HValue* left = Pop();
5419 HPower* result = new(zone()) HPower(left, right); 5556 HPower* result = new(zone()) HPower(left, right);
5420 ast_context()->ReturnInstruction(result, call->id()); 5557 ast_context()->ReturnInstruction(result, call->id());
5421 } 5558 }
5422 5559
5423 5560
5424 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { 5561 void HGraphBuilder::GenerateMathSin(CallRuntime* call) {
5425 ASSERT_EQ(1, call->arguments()->length()); 5562 ASSERT_EQ(1, call->arguments()->length());
5426 VisitArgumentList(call->arguments()); 5563 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5427 CHECK_BAILOUT;
5428 HContext* context = new(zone()) HContext; 5564 HContext* context = new(zone()) HContext;
5429 AddInstruction(context); 5565 AddInstruction(context);
5430 HCallStub* result = 5566 HCallStub* result =
5431 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 5567 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
5432 result->set_transcendental_type(TranscendentalCache::SIN); 5568 result->set_transcendental_type(TranscendentalCache::SIN);
5433 Drop(1); 5569 Drop(1);
5434 ast_context()->ReturnInstruction(result, call->id()); 5570 ast_context()->ReturnInstruction(result, call->id());
5435 } 5571 }
5436 5572
5437 5573
5438 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { 5574 void HGraphBuilder::GenerateMathCos(CallRuntime* call) {
5439 ASSERT_EQ(1, call->arguments()->length()); 5575 ASSERT_EQ(1, call->arguments()->length());
5440 VisitArgumentList(call->arguments()); 5576 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5441 CHECK_BAILOUT;
5442 HContext* context = new(zone()) HContext; 5577 HContext* context = new(zone()) HContext;
5443 AddInstruction(context); 5578 AddInstruction(context);
5444 HCallStub* result = 5579 HCallStub* result =
5445 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 5580 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
5446 result->set_transcendental_type(TranscendentalCache::COS); 5581 result->set_transcendental_type(TranscendentalCache::COS);
5447 Drop(1); 5582 Drop(1);
5448 ast_context()->ReturnInstruction(result, call->id()); 5583 ast_context()->ReturnInstruction(result, call->id());
5449 } 5584 }
5450 5585
5451 5586
5452 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { 5587 void HGraphBuilder::GenerateMathLog(CallRuntime* call) {
5453 ASSERT_EQ(1, call->arguments()->length()); 5588 ASSERT_EQ(1, call->arguments()->length());
5454 VisitArgumentList(call->arguments()); 5589 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5455 CHECK_BAILOUT;
5456 HContext* context = new(zone()) HContext; 5590 HContext* context = new(zone()) HContext;
5457 AddInstruction(context); 5591 AddInstruction(context);
5458 HCallStub* result = 5592 HCallStub* result =
5459 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 5593 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
5460 result->set_transcendental_type(TranscendentalCache::LOG); 5594 result->set_transcendental_type(TranscendentalCache::LOG);
5461 Drop(1); 5595 Drop(1);
5462 ast_context()->ReturnInstruction(result, call->id()); 5596 ast_context()->ReturnInstruction(result, call->id());
5463 } 5597 }
5464 5598
5465 5599
5466 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 5600 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
5467 BAILOUT("inlined runtime function: MathSqrt"); 5601 return Bailout("inlined runtime function: MathSqrt");
5468 } 5602 }
5469 5603
5470 5604
5471 // Check whether two RegExps are equivalent 5605 // Check whether two RegExps are equivalent
5472 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 5606 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
5473 BAILOUT("inlined runtime function: IsRegExpEquivalent"); 5607 return Bailout("inlined runtime function: IsRegExpEquivalent");
5474 } 5608 }
5475 5609
5476 5610
5477 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 5611 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
5478 ASSERT(call->arguments()->length() == 1); 5612 ASSERT(call->arguments()->length() == 1);
5479 VISIT_FOR_VALUE(call->arguments()->at(0)); 5613 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5480 HValue* value = Pop(); 5614 HValue* value = Pop();
5481 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); 5615 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value);
5482 ast_context()->ReturnInstruction(result, call->id()); 5616 ast_context()->ReturnInstruction(result, call->id());
5483 } 5617 }
5484 5618
5485 5619
5486 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 5620 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
5487 BAILOUT("inlined runtime function: FastAsciiArrayJoin"); 5621 return Bailout("inlined runtime function: FastAsciiArrayJoin");
5488 } 5622 }
5489 5623
5490 5624
5491 #undef BAILOUT
5492 #undef CHECK_BAILOUT 5625 #undef CHECK_BAILOUT
5493 #undef VISIT_FOR_EFFECT 5626 #undef CHECK_ALIVE
5494 #undef VISIT_FOR_VALUE
5495 #undef ADD_TO_SUBGRAPH
5496 5627
5497 5628
5498 HEnvironment::HEnvironment(HEnvironment* outer, 5629 HEnvironment::HEnvironment(HEnvironment* outer,
5499 Scope* scope, 5630 Scope* scope,
5500 Handle<JSFunction> closure) 5631 Handle<JSFunction> closure)
5501 : closure_(closure), 5632 : closure_(closure),
5502 values_(0), 5633 values_(0),
5503 assigned_variables_(4), 5634 assigned_variables_(4),
5504 parameter_count_(0), 5635 parameter_count_(0),
5505 local_count_(0), 5636 local_count_(0),
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
6007 } 6138 }
6008 } 6139 }
6009 6140
6010 #ifdef DEBUG 6141 #ifdef DEBUG
6011 if (graph_ != NULL) graph_->Verify(); 6142 if (graph_ != NULL) graph_->Verify();
6012 if (allocator_ != NULL) allocator_->Verify(); 6143 if (allocator_ != NULL) allocator_->Verify();
6013 #endif 6144 #endif
6014 } 6145 }
6015 6146
6016 } } // namespace v8::internal 6147 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698