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

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