| OLD | NEW |
| 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 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 | 1339 |
| 1340 DISALLOW_COPY_AND_ASSIGN(SparseSet); | 1340 DISALLOW_COPY_AND_ASSIGN(SparseSet); |
| 1341 }; | 1341 }; |
| 1342 | 1342 |
| 1343 | 1343 |
| 1344 class HGlobalValueNumberer BASE_EMBEDDED { | 1344 class HGlobalValueNumberer BASE_EMBEDDED { |
| 1345 public: | 1345 public: |
| 1346 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | 1346 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
| 1347 : graph_(graph), | 1347 : graph_(graph), |
| 1348 info_(info), | 1348 info_(info), |
| 1349 removed_side_effects_(false), |
| 1349 block_side_effects_(graph->blocks()->length()), | 1350 block_side_effects_(graph->blocks()->length()), |
| 1350 loop_side_effects_(graph->blocks()->length()), | 1351 loop_side_effects_(graph->blocks()->length()), |
| 1351 visited_on_paths_(graph->zone(), graph->blocks()->length()) { | 1352 visited_on_paths_(graph->zone(), graph->blocks()->length()) { |
| 1352 ASSERT(info->isolate()->heap()->allow_allocation(false)); | 1353 ASSERT(info->isolate()->heap()->allow_allocation(false)); |
| 1353 block_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1354 block_side_effects_.AddBlock(0, graph_->blocks()->length()); |
| 1354 loop_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1355 loop_side_effects_.AddBlock(0, graph_->blocks()->length()); |
| 1355 } | 1356 } |
| 1356 ~HGlobalValueNumberer() { | 1357 ~HGlobalValueNumberer() { |
| 1357 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); | 1358 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); |
| 1358 } | 1359 } |
| 1359 | 1360 |
| 1360 void Analyze(); | 1361 // Returns true if values with side effects are removed. |
| 1362 bool Analyze(); |
| 1361 | 1363 |
| 1362 private: | 1364 private: |
| 1363 int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator, | 1365 int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator, |
| 1364 HBasicBlock* dominated); | 1366 HBasicBlock* dominated); |
| 1365 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); | 1367 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); |
| 1366 void ComputeBlockSideEffects(); | 1368 void ComputeBlockSideEffects(); |
| 1367 void LoopInvariantCodeMotion(); | 1369 void LoopInvariantCodeMotion(); |
| 1368 void ProcessLoopBlock(HBasicBlock* block, | 1370 void ProcessLoopBlock(HBasicBlock* block, |
| 1369 HBasicBlock* before_loop, | 1371 HBasicBlock* before_loop, |
| 1370 int loop_kills); | 1372 int loop_kills); |
| 1371 bool AllowCodeMotion(); | 1373 bool AllowCodeMotion(); |
| 1372 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1374 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
| 1373 | 1375 |
| 1374 HGraph* graph() { return graph_; } | 1376 HGraph* graph() { return graph_; } |
| 1375 CompilationInfo* info() { return info_; } | 1377 CompilationInfo* info() { return info_; } |
| 1376 Zone* zone() { return graph_->zone(); } | 1378 Zone* zone() { return graph_->zone(); } |
| 1377 | 1379 |
| 1378 HGraph* graph_; | 1380 HGraph* graph_; |
| 1379 CompilationInfo* info_; | 1381 CompilationInfo* info_; |
| 1382 bool removed_side_effects_; |
| 1380 | 1383 |
| 1381 // A map of block IDs to their side effects. | 1384 // A map of block IDs to their side effects. |
| 1382 ZoneList<int> block_side_effects_; | 1385 ZoneList<int> block_side_effects_; |
| 1383 | 1386 |
| 1384 // A map of loop header block IDs to their loop's side effects. | 1387 // A map of loop header block IDs to their loop's side effects. |
| 1385 ZoneList<int> loop_side_effects_; | 1388 ZoneList<int> loop_side_effects_; |
| 1386 | 1389 |
| 1387 // Used when collecting side effects on paths from dominator to | 1390 // Used when collecting side effects on paths from dominator to |
| 1388 // dominated. | 1391 // dominated. |
| 1389 SparseSet visited_on_paths_; | 1392 SparseSet visited_on_paths_; |
| 1390 }; | 1393 }; |
| 1391 | 1394 |
| 1392 | 1395 |
| 1393 void HGlobalValueNumberer::Analyze() { | 1396 bool HGlobalValueNumberer::Analyze() { |
| 1394 ComputeBlockSideEffects(); | 1397 ComputeBlockSideEffects(); |
| 1395 if (FLAG_loop_invariant_code_motion) { | 1398 if (FLAG_loop_invariant_code_motion) { |
| 1396 LoopInvariantCodeMotion(); | 1399 LoopInvariantCodeMotion(); |
| 1397 } | 1400 } |
| 1398 HValueMap* map = new(zone()) HValueMap(); | 1401 HValueMap* map = new(zone()) HValueMap(); |
| 1399 AnalyzeBlock(graph_->entry_block(), map); | 1402 AnalyzeBlock(graph_->entry_block(), map); |
| 1403 return removed_side_effects_; |
| 1400 } | 1404 } |
| 1401 | 1405 |
| 1402 | 1406 |
| 1403 void HGlobalValueNumberer::ComputeBlockSideEffects() { | 1407 void HGlobalValueNumberer::ComputeBlockSideEffects() { |
| 1404 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { | 1408 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { |
| 1405 // Compute side effects for the block. | 1409 // Compute side effects for the block. |
| 1406 HBasicBlock* block = graph_->blocks()->at(i); | 1410 HBasicBlock* block = graph_->blocks()->at(i); |
| 1407 HInstruction* instr = block->first(); | 1411 HInstruction* instr = block->first(); |
| 1408 int id = block->block_id(); | 1412 int id = block->block_id(); |
| 1409 int side_effects = 0; | 1413 int side_effects = 0; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 if (block->IsLoopHeader()) { | 1527 if (block->IsLoopHeader()) { |
| 1524 map->Kill(loop_side_effects_[block->block_id()]); | 1528 map->Kill(loop_side_effects_[block->block_id()]); |
| 1525 } | 1529 } |
| 1526 | 1530 |
| 1527 // Go through all instructions of the current block. | 1531 // Go through all instructions of the current block. |
| 1528 HInstruction* instr = block->first(); | 1532 HInstruction* instr = block->first(); |
| 1529 while (instr != NULL) { | 1533 while (instr != NULL) { |
| 1530 HInstruction* next = instr->next(); | 1534 HInstruction* next = instr->next(); |
| 1531 int flags = instr->ChangesFlags(); | 1535 int flags = instr->ChangesFlags(); |
| 1532 if (flags != 0) { | 1536 if (flags != 0) { |
| 1533 ASSERT(!instr->CheckFlag(HValue::kUseGVN)); | |
| 1534 // Clear all instructions in the map that are affected by side effects. | 1537 // Clear all instructions in the map that are affected by side effects. |
| 1535 map->Kill(flags); | 1538 map->Kill(flags); |
| 1536 TraceGVN("Instruction %d kills\n", instr->id()); | 1539 TraceGVN("Instruction %d kills\n", instr->id()); |
| 1537 } else if (instr->CheckFlag(HValue::kUseGVN)) { | 1540 } |
| 1541 if (instr->CheckFlag(HValue::kUseGVN)) { |
| 1542 ASSERT(!instr->HasObservableSideEffects()); |
| 1538 HValue* other = map->Lookup(instr); | 1543 HValue* other = map->Lookup(instr); |
| 1539 if (other != NULL) { | 1544 if (other != NULL) { |
| 1540 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1545 ASSERT(instr->Equals(other) && other->Equals(instr)); |
| 1541 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", | 1546 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", |
| 1542 instr->id(), | 1547 instr->id(), |
| 1543 instr->Mnemonic(), | 1548 instr->Mnemonic(), |
| 1544 other->id(), | 1549 other->id(), |
| 1545 other->Mnemonic()); | 1550 other->Mnemonic()); |
| 1551 if (instr->HasSideEffects()) removed_side_effects_ = true; |
| 1546 instr->DeleteAndReplaceWith(other); | 1552 instr->DeleteAndReplaceWith(other); |
| 1547 } else { | 1553 } else { |
| 1548 map->Add(instr); | 1554 map->Add(instr); |
| 1549 } | 1555 } |
| 1550 } | 1556 } |
| 1551 instr = next; | 1557 instr = next; |
| 1552 } | 1558 } |
| 1553 | 1559 |
| 1554 // Recursively continue analysis for all immediately dominated blocks. | 1560 // Recursively continue analysis for all immediately dominated blocks. |
| 1555 int length = block->dominated_blocks()->length(); | 1561 int length = block->dominated_blocks()->length(); |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2101 | 2107 |
| 2102 | 2108 |
| 2103 void TestContext::ReturnValue(HValue* value) { | 2109 void TestContext::ReturnValue(HValue* value) { |
| 2104 BuildBranch(value); | 2110 BuildBranch(value); |
| 2105 } | 2111 } |
| 2106 | 2112 |
| 2107 | 2113 |
| 2108 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 2114 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| 2109 ASSERT(!instr->IsControlInstruction()); | 2115 ASSERT(!instr->IsControlInstruction()); |
| 2110 owner()->AddInstruction(instr); | 2116 owner()->AddInstruction(instr); |
| 2111 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); | 2117 if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); |
| 2112 } | 2118 } |
| 2113 | 2119 |
| 2114 | 2120 |
| 2115 void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) { | 2121 void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| 2116 ASSERT(!instr->HasSideEffects()); | 2122 ASSERT(!instr->HasObservableSideEffects()); |
| 2117 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 2123 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 2118 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 2124 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 2119 instr->SetSuccessorAt(0, empty_true); | 2125 instr->SetSuccessorAt(0, empty_true); |
| 2120 instr->SetSuccessorAt(1, empty_false); | 2126 instr->SetSuccessorAt(1, empty_false); |
| 2121 owner()->current_block()->Finish(instr); | 2127 owner()->current_block()->Finish(instr); |
| 2122 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); | 2128 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); |
| 2123 owner()->set_current_block(join); | 2129 owner()->set_current_block(join); |
| 2124 } | 2130 } |
| 2125 | 2131 |
| 2126 | 2132 |
| 2127 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 2133 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| 2128 ASSERT(!instr->IsControlInstruction()); | 2134 ASSERT(!instr->IsControlInstruction()); |
| 2129 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 2135 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 2130 return owner()->Bailout("bad value context for arguments object value"); | 2136 return owner()->Bailout("bad value context for arguments object value"); |
| 2131 } | 2137 } |
| 2132 owner()->AddInstruction(instr); | 2138 owner()->AddInstruction(instr); |
| 2133 owner()->Push(instr); | 2139 owner()->Push(instr); |
| 2134 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); | 2140 if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); |
| 2135 } | 2141 } |
| 2136 | 2142 |
| 2137 | 2143 |
| 2138 void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) { | 2144 void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| 2139 ASSERT(!instr->HasSideEffects()); | 2145 ASSERT(!instr->HasObservableSideEffects()); |
| 2140 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 2146 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 2141 return owner()->Bailout("bad value context for arguments object value"); | 2147 return owner()->Bailout("bad value context for arguments object value"); |
| 2142 } | 2148 } |
| 2143 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); | 2149 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); |
| 2144 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); | 2150 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); |
| 2145 instr->SetSuccessorAt(0, materialize_true); | 2151 instr->SetSuccessorAt(0, materialize_true); |
| 2146 instr->SetSuccessorAt(1, materialize_false); | 2152 instr->SetSuccessorAt(1, materialize_false); |
| 2147 owner()->current_block()->Finish(instr); | 2153 owner()->current_block()->Finish(instr); |
| 2148 owner()->set_current_block(materialize_true); | 2154 owner()->set_current_block(materialize_true); |
| 2149 owner()->Push(owner()->graph()->GetConstantTrue()); | 2155 owner()->Push(owner()->graph()->GetConstantTrue()); |
| 2150 owner()->set_current_block(materialize_false); | 2156 owner()->set_current_block(materialize_false); |
| 2151 owner()->Push(owner()->graph()->GetConstantFalse()); | 2157 owner()->Push(owner()->graph()->GetConstantFalse()); |
| 2152 HBasicBlock* join = | 2158 HBasicBlock* join = |
| 2153 owner()->CreateJoin(materialize_true, materialize_false, ast_id); | 2159 owner()->CreateJoin(materialize_true, materialize_false, ast_id); |
| 2154 owner()->set_current_block(join); | 2160 owner()->set_current_block(join); |
| 2155 } | 2161 } |
| 2156 | 2162 |
| 2157 | 2163 |
| 2158 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 2164 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| 2159 ASSERT(!instr->IsControlInstruction()); | 2165 ASSERT(!instr->IsControlInstruction()); |
| 2160 HGraphBuilder* builder = owner(); | 2166 HGraphBuilder* builder = owner(); |
| 2161 builder->AddInstruction(instr); | 2167 builder->AddInstruction(instr); |
| 2162 // We expect a simulate after every expression with side effects, though | 2168 // We expect a simulate after every expression with side effects, though |
| 2163 // this one isn't actually needed (and wouldn't work if it were targeted). | 2169 // this one isn't actually needed (and wouldn't work if it were targeted). |
| 2164 if (instr->HasSideEffects()) { | 2170 if (instr->HasObservableSideEffects()) { |
| 2165 builder->Push(instr); | 2171 builder->Push(instr); |
| 2166 builder->AddSimulate(ast_id); | 2172 builder->AddSimulate(ast_id); |
| 2167 builder->Pop(); | 2173 builder->Pop(); |
| 2168 } | 2174 } |
| 2169 BuildBranch(instr); | 2175 BuildBranch(instr); |
| 2170 } | 2176 } |
| 2171 | 2177 |
| 2172 | 2178 |
| 2173 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { | 2179 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| 2174 ASSERT(!instr->HasSideEffects()); | 2180 ASSERT(!instr->HasObservableSideEffects()); |
| 2175 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 2181 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 2176 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 2182 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 2177 instr->SetSuccessorAt(0, empty_true); | 2183 instr->SetSuccessorAt(0, empty_true); |
| 2178 instr->SetSuccessorAt(1, empty_false); | 2184 instr->SetSuccessorAt(1, empty_false); |
| 2179 owner()->current_block()->Finish(instr); | 2185 owner()->current_block()->Finish(instr); |
| 2180 empty_true->Goto(if_true(), owner()->function_state()->drop_extra()); | 2186 empty_true->Goto(if_true(), owner()->function_state()->drop_extra()); |
| 2181 empty_false->Goto(if_false(), owner()->function_state()->drop_extra()); | 2187 empty_false->Goto(if_false(), owner()->function_state()->drop_extra()); |
| 2182 owner()->set_current_block(NULL); | 2188 owner()->set_current_block(NULL); |
| 2183 } | 2189 } |
| 2184 | 2190 |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 graph()->MarkDeoptimizeOnUndefined(); | 2372 graph()->MarkDeoptimizeOnUndefined(); |
| 2367 graph()->InsertRepresentationChanges(); | 2373 graph()->InsertRepresentationChanges(); |
| 2368 | 2374 |
| 2369 graph()->InitializeInferredTypes(); | 2375 graph()->InitializeInferredTypes(); |
| 2370 graph()->Canonicalize(); | 2376 graph()->Canonicalize(); |
| 2371 | 2377 |
| 2372 // Perform common subexpression elimination and loop-invariant code motion. | 2378 // Perform common subexpression elimination and loop-invariant code motion. |
| 2373 if (FLAG_use_gvn) { | 2379 if (FLAG_use_gvn) { |
| 2374 HPhase phase("Global value numbering", graph()); | 2380 HPhase phase("Global value numbering", graph()); |
| 2375 HGlobalValueNumberer gvn(graph(), info()); | 2381 HGlobalValueNumberer gvn(graph(), info()); |
| 2376 gvn.Analyze(); | 2382 bool removed_side_effects = gvn.Analyze(); |
| 2383 // Trigger a second analysis pass to further eliminate duplicate values that |
| 2384 // could only be discovered by removing side-effect-generating instructions |
| 2385 // during the first pass. |
| 2386 if (FLAG_smi_only_arrays && removed_side_effects) { |
| 2387 gvn.Analyze(); |
| 2388 } |
| 2377 } | 2389 } |
| 2378 | 2390 |
| 2379 if (FLAG_use_range) { | 2391 if (FLAG_use_range) { |
| 2380 HRangeAnalysis rangeAnalysis(graph()); | 2392 HRangeAnalysis rangeAnalysis(graph()); |
| 2381 rangeAnalysis.Analyze(); | 2393 rangeAnalysis.Analyze(); |
| 2382 } | 2394 } |
| 2383 graph()->ComputeMinusZeroChecks(); | 2395 graph()->ComputeMinusZeroChecks(); |
| 2384 | 2396 |
| 2385 // Eliminate redundant stack checks on backwards branches. | 2397 // Eliminate redundant stack checks on backwards branches. |
| 2386 HStackCheckEliminator sce(graph()); | 2398 HStackCheckEliminator sce(graph()); |
| (...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3539 instr->set_position(expr->position()); | 3551 instr->set_position(expr->position()); |
| 3540 AddInstruction(instr); | 3552 AddInstruction(instr); |
| 3541 | 3553 |
| 3542 if (join != NULL) { | 3554 if (join != NULL) { |
| 3543 if (!ast_context()->IsEffect()) Push(value); | 3555 if (!ast_context()->IsEffect()) Push(value); |
| 3544 current_block()->Goto(join); | 3556 current_block()->Goto(join); |
| 3545 } else { | 3557 } else { |
| 3546 // The HSimulate for the store should not see the stored value in | 3558 // The HSimulate for the store should not see the stored value in |
| 3547 // effect contexts (it is not materialized at expr->id() in the | 3559 // effect contexts (it is not materialized at expr->id() in the |
| 3548 // unoptimized code). | 3560 // unoptimized code). |
| 3549 if (instr->HasSideEffects()) { | 3561 if (instr->HasObservableSideEffects()) { |
| 3550 if (ast_context()->IsEffect()) { | 3562 if (ast_context()->IsEffect()) { |
| 3551 AddSimulate(expr->id()); | 3563 AddSimulate(expr->id()); |
| 3552 } else { | 3564 } else { |
| 3553 Push(value); | 3565 Push(value); |
| 3554 AddSimulate(expr->id()); | 3566 AddSimulate(expr->id()); |
| 3555 Drop(1); | 3567 Drop(1); |
| 3556 } | 3568 } |
| 3557 } | 3569 } |
| 3558 return ast_context()->ReturnValue(value); | 3570 return ast_context()->ReturnValue(value); |
| 3559 } | 3571 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3612 true, // is_store | 3624 true, // is_store |
| 3613 &has_side_effects); | 3625 &has_side_effects); |
| 3614 Push(value); | 3626 Push(value); |
| 3615 ASSERT(has_side_effects); // Stores always have side effects. | 3627 ASSERT(has_side_effects); // Stores always have side effects. |
| 3616 AddSimulate(expr->AssignmentId()); | 3628 AddSimulate(expr->AssignmentId()); |
| 3617 return ast_context()->ReturnValue(Pop()); | 3629 return ast_context()->ReturnValue(Pop()); |
| 3618 } | 3630 } |
| 3619 Push(value); | 3631 Push(value); |
| 3620 instr->set_position(expr->position()); | 3632 instr->set_position(expr->position()); |
| 3621 AddInstruction(instr); | 3633 AddInstruction(instr); |
| 3622 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3634 if (instr->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3623 return ast_context()->ReturnValue(Pop()); | 3635 return ast_context()->ReturnValue(Pop()); |
| 3624 } | 3636 } |
| 3625 | 3637 |
| 3626 | 3638 |
| 3627 // Because not every expression has a position and there is not common | 3639 // Because not every expression has a position and there is not common |
| 3628 // superclass of Assignment and CountOperation, we cannot just pass the | 3640 // superclass of Assignment and CountOperation, we cannot just pass the |
| 3629 // owning expression instead of position and ast_id separately. | 3641 // owning expression instead of position and ast_id separately. |
| 3630 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3642 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| 3631 HValue* value, | 3643 HValue* value, |
| 3632 int position, | 3644 int position, |
| 3633 int ast_id) { | 3645 int ast_id) { |
| 3634 LookupResult lookup(isolate()); | 3646 LookupResult lookup(isolate()); |
| 3635 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 3647 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 3636 if (type == kUseCell) { | 3648 if (type == kUseCell) { |
| 3637 Handle<GlobalObject> global(info()->global_object()); | 3649 Handle<GlobalObject> global(info()->global_object()); |
| 3638 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3650 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 3639 HInstruction* instr = | 3651 HInstruction* instr = |
| 3640 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 3652 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| 3641 instr->set_position(position); | 3653 instr->set_position(position); |
| 3642 AddInstruction(instr); | 3654 AddInstruction(instr); |
| 3643 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3655 if (instr->HasObservableSideEffects()) AddSimulate(ast_id); |
| 3644 } else { | 3656 } else { |
| 3645 HValue* context = environment()->LookupContext(); | 3657 HValue* context = environment()->LookupContext(); |
| 3646 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 3658 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 3647 AddInstruction(global_object); | 3659 AddInstruction(global_object); |
| 3648 HStoreGlobalGeneric* instr = | 3660 HStoreGlobalGeneric* instr = |
| 3649 new(zone()) HStoreGlobalGeneric(context, | 3661 new(zone()) HStoreGlobalGeneric(context, |
| 3650 global_object, | 3662 global_object, |
| 3651 var->name(), | 3663 var->name(), |
| 3652 value, | 3664 value, |
| 3653 function_strict_mode_flag()); | 3665 function_strict_mode_flag()); |
| 3654 instr->set_position(position); | 3666 instr->set_position(position); |
| 3655 AddInstruction(instr); | 3667 AddInstruction(instr); |
| 3656 ASSERT(instr->HasSideEffects()); | 3668 ASSERT(instr->HasObservableSideEffects()); |
| 3657 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3669 if (instr->HasObservableSideEffects()) AddSimulate(ast_id); |
| 3658 } | 3670 } |
| 3659 } | 3671 } |
| 3660 | 3672 |
| 3661 | 3673 |
| 3662 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 3674 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 3663 Expression* target = expr->target(); | 3675 Expression* target = expr->target(); |
| 3664 VariableProxy* proxy = target->AsVariableProxy(); | 3676 VariableProxy* proxy = target->AsVariableProxy(); |
| 3665 Property* prop = target->AsProperty(); | 3677 Property* prop = target->AsProperty(); |
| 3666 ASSERT(proxy == NULL || prop == NULL); | 3678 ASSERT(proxy == NULL || prop == NULL); |
| 3667 | 3679 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3704 Bailout( | 3716 Bailout( |
| 3705 "assignment to parameter, function uses arguments object"); | 3717 "assignment to parameter, function uses arguments object"); |
| 3706 } | 3718 } |
| 3707 } | 3719 } |
| 3708 } | 3720 } |
| 3709 | 3721 |
| 3710 HValue* context = BuildContextChainWalk(var); | 3722 HValue* context = BuildContextChainWalk(var); |
| 3711 HStoreContextSlot* instr = | 3723 HStoreContextSlot* instr = |
| 3712 new(zone()) HStoreContextSlot(context, var->index(), Top()); | 3724 new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| 3713 AddInstruction(instr); | 3725 AddInstruction(instr); |
| 3714 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3726 if (instr->HasObservableSideEffects()) { |
| 3727 AddSimulate(expr->AssignmentId()); |
| 3728 } |
| 3715 break; | 3729 break; |
| 3716 } | 3730 } |
| 3717 | 3731 |
| 3718 case Variable::LOOKUP: | 3732 case Variable::LOOKUP: |
| 3719 return Bailout("compound assignment to lookup slot"); | 3733 return Bailout("compound assignment to lookup slot"); |
| 3720 } | 3734 } |
| 3721 return ast_context()->ReturnValue(Pop()); | 3735 return ast_context()->ReturnValue(Pop()); |
| 3722 | 3736 |
| 3723 } else if (prop != NULL) { | 3737 } else if (prop != NULL) { |
| 3724 prop->RecordTypeFeedback(oracle()); | 3738 prop->RecordTypeFeedback(oracle()); |
| 3725 | 3739 |
| 3726 if (prop->key()->IsPropertyName()) { | 3740 if (prop->key()->IsPropertyName()) { |
| 3727 // Named property. | 3741 // Named property. |
| 3728 CHECK_ALIVE(VisitForValue(prop->obj())); | 3742 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 3729 HValue* obj = Top(); | 3743 HValue* obj = Top(); |
| 3730 | 3744 |
| 3731 HInstruction* load = NULL; | 3745 HInstruction* load = NULL; |
| 3732 if (prop->IsMonomorphic()) { | 3746 if (prop->IsMonomorphic()) { |
| 3733 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 3747 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 3734 Handle<Map> map = prop->GetReceiverTypes()->first(); | 3748 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| 3735 load = BuildLoadNamed(obj, prop, map, name); | 3749 load = BuildLoadNamed(obj, prop, map, name); |
| 3736 } else { | 3750 } else { |
| 3737 load = BuildLoadNamedGeneric(obj, prop); | 3751 load = BuildLoadNamedGeneric(obj, prop); |
| 3738 } | 3752 } |
| 3739 PushAndAdd(load); | 3753 PushAndAdd(load); |
| 3740 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); | 3754 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); |
| 3741 | 3755 |
| 3742 CHECK_ALIVE(VisitForValue(expr->value())); | 3756 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3743 HValue* right = Pop(); | 3757 HValue* right = Pop(); |
| 3744 HValue* left = Pop(); | 3758 HValue* left = Pop(); |
| 3745 | 3759 |
| 3746 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3760 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 3747 PushAndAdd(instr); | 3761 PushAndAdd(instr); |
| 3748 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3762 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 3749 | 3763 |
| 3750 HInstruction* store = BuildStoreNamed(obj, instr, prop); | 3764 HInstruction* store = BuildStoreNamed(obj, instr, prop); |
| 3751 AddInstruction(store); | 3765 AddInstruction(store); |
| 3752 // Drop the simulated receiver and value. Return the value. | 3766 // Drop the simulated receiver and value. Return the value. |
| 3753 Drop(2); | 3767 Drop(2); |
| 3754 Push(instr); | 3768 Push(instr); |
| 3755 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3769 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3756 return ast_context()->ReturnValue(Pop()); | 3770 return ast_context()->ReturnValue(Pop()); |
| 3757 | 3771 |
| 3758 } else { | 3772 } else { |
| 3759 // Keyed property. | 3773 // Keyed property. |
| 3760 CHECK_ALIVE(VisitForValue(prop->obj())); | 3774 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 3761 CHECK_ALIVE(VisitForValue(prop->key())); | 3775 CHECK_ALIVE(VisitForValue(prop->key())); |
| 3762 HValue* obj = environment()->ExpressionStackAt(1); | 3776 HValue* obj = environment()->ExpressionStackAt(1); |
| 3763 HValue* key = environment()->ExpressionStackAt(0); | 3777 HValue* key = environment()->ExpressionStackAt(0); |
| 3764 | 3778 |
| 3765 bool has_side_effects = false; | 3779 bool has_side_effects = false; |
| 3766 HValue* load = HandleKeyedElementAccess( | 3780 HValue* load = HandleKeyedElementAccess( |
| 3767 obj, key, NULL, prop, expr->CompoundLoadId(), RelocInfo::kNoPosition, | 3781 obj, key, NULL, prop, expr->CompoundLoadId(), RelocInfo::kNoPosition, |
| 3768 false, // is_store | 3782 false, // is_store |
| 3769 &has_side_effects); | 3783 &has_side_effects); |
| 3770 Push(load); | 3784 Push(load); |
| 3771 if (has_side_effects) AddSimulate(expr->CompoundLoadId()); | 3785 if (has_side_effects) AddSimulate(expr->CompoundLoadId()); |
| 3772 | 3786 |
| 3773 | 3787 |
| 3774 CHECK_ALIVE(VisitForValue(expr->value())); | 3788 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3775 HValue* right = Pop(); | 3789 HValue* right = Pop(); |
| 3776 HValue* left = Pop(); | 3790 HValue* left = Pop(); |
| 3777 | 3791 |
| 3778 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3792 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 3779 PushAndAdd(instr); | 3793 PushAndAdd(instr); |
| 3780 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3794 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 3781 | 3795 |
| 3782 expr->RecordTypeFeedback(oracle()); | 3796 expr->RecordTypeFeedback(oracle()); |
| 3783 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 3797 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| 3784 RelocInfo::kNoPosition, | 3798 RelocInfo::kNoPosition, |
| 3785 true, // is_store | 3799 true, // is_store |
| 3786 &has_side_effects); | 3800 &has_side_effects); |
| 3787 | 3801 |
| 3788 // Drop the simulated receiver, key, and value. Return the value. | 3802 // Drop the simulated receiver, key, and value. Return the value. |
| 3789 Drop(3); | 3803 Drop(3); |
| 3790 Push(instr); | 3804 Push(instr); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3868 return Bailout("assignment to parameter in arguments object"); | 3882 return Bailout("assignment to parameter in arguments object"); |
| 3869 } | 3883 } |
| 3870 } | 3884 } |
| 3871 } | 3885 } |
| 3872 | 3886 |
| 3873 CHECK_ALIVE(VisitForValue(expr->value())); | 3887 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3874 HValue* context = BuildContextChainWalk(var); | 3888 HValue* context = BuildContextChainWalk(var); |
| 3875 HStoreContextSlot* instr = | 3889 HStoreContextSlot* instr = |
| 3876 new(zone()) HStoreContextSlot(context, var->index(), Top()); | 3890 new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| 3877 AddInstruction(instr); | 3891 AddInstruction(instr); |
| 3878 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3892 if (instr->HasObservableSideEffects()) { |
| 3893 AddSimulate(expr->AssignmentId()); |
| 3894 } |
| 3879 return ast_context()->ReturnValue(Pop()); | 3895 return ast_context()->ReturnValue(Pop()); |
| 3880 } | 3896 } |
| 3881 | 3897 |
| 3882 case Variable::LOOKUP: | 3898 case Variable::LOOKUP: |
| 3883 return Bailout("assignment to LOOKUP variable"); | 3899 return Bailout("assignment to LOOKUP variable"); |
| 3884 } | 3900 } |
| 3885 } else { | 3901 } else { |
| 3886 return Bailout("invalid left-hand side in assignment"); | 3902 return Bailout("invalid left-hand side in assignment"); |
| 3887 } | 3903 } |
| 3888 } | 3904 } |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4141 num_untransitionable_maps++; | 4157 num_untransitionable_maps++; |
| 4142 untransitionable_map = map; | 4158 untransitionable_map = map; |
| 4143 } | 4159 } |
| 4144 } | 4160 } |
| 4145 | 4161 |
| 4146 // If only one map is left after transitioning, handle this case | 4162 // If only one map is left after transitioning, handle this case |
| 4147 // monomorphically. | 4163 // monomorphically. |
| 4148 if (num_untransitionable_maps == 1) { | 4164 if (num_untransitionable_maps == 1) { |
| 4149 HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( | 4165 HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( |
| 4150 object, key, val, untransitionable_map, is_store)); | 4166 object, key, val, untransitionable_map, is_store)); |
| 4151 *has_side_effects |= instr->HasSideEffects(); | 4167 *has_side_effects |= instr->HasObservableSideEffects(); |
| 4152 instr->set_position(position); | 4168 instr->set_position(position); |
| 4153 return is_store ? NULL : instr; | 4169 return is_store ? NULL : instr; |
| 4154 } | 4170 } |
| 4155 | 4171 |
| 4156 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 4172 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); |
| 4157 HBasicBlock* join = graph()->CreateBasicBlock(); | 4173 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 4158 | 4174 |
| 4159 HInstruction* elements_kind_instr = | 4175 HInstruction* elements_kind_instr = |
| 4160 AddInstruction(new(zone()) HElementsKind(object)); | 4176 AddInstruction(new(zone()) HElementsKind(object)); |
| 4161 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 4177 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4228 set_current_block(if_jsarray); | 4244 set_current_block(if_jsarray); |
| 4229 HInstruction* length; | 4245 HInstruction* length; |
| 4230 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck)); | 4246 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck)); |
| 4231 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4247 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4232 access = AddInstruction(BuildFastElementAccess( | 4248 access = AddInstruction(BuildFastElementAccess( |
| 4233 elements, checked_key, val, elements_kind, is_store)); | 4249 elements, checked_key, val, elements_kind, is_store)); |
| 4234 if (!is_store) { | 4250 if (!is_store) { |
| 4235 Push(access); | 4251 Push(access); |
| 4236 } | 4252 } |
| 4237 | 4253 |
| 4238 *has_side_effects |= access->HasSideEffects(); | 4254 *has_side_effects |= access->HasObservableSideEffects(); |
| 4239 if (position != -1) { | 4255 if (position != -1) { |
| 4240 access->set_position(position); | 4256 access->set_position(position); |
| 4241 } | 4257 } |
| 4242 if_jsarray->Goto(join); | 4258 if_jsarray->Goto(join); |
| 4243 | 4259 |
| 4244 set_current_block(if_fastobject); | 4260 set_current_block(if_fastobject); |
| 4245 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4261 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 4246 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4262 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4247 access = AddInstruction(BuildFastElementAccess( | 4263 access = AddInstruction(BuildFastElementAccess( |
| 4248 elements, checked_key, val, elements_kind, is_store)); | 4264 elements, checked_key, val, elements_kind, is_store)); |
| 4249 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 4265 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
| 4250 if (is_store) { | 4266 if (is_store) { |
| 4251 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 4267 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| 4252 } else { | 4268 } else { |
| 4253 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 4269 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
| 4254 } | 4270 } |
| 4255 } else { // External array elements. | 4271 } else { // External array elements. |
| 4256 access = AddInstruction(BuildExternalArrayElementAccess( | 4272 access = AddInstruction(BuildExternalArrayElementAccess( |
| 4257 external_elements, checked_key, val, elements_kind, is_store)); | 4273 external_elements, checked_key, val, elements_kind, is_store)); |
| 4258 } | 4274 } |
| 4259 *has_side_effects |= access->HasSideEffects(); | 4275 *has_side_effects |= access->HasObservableSideEffects(); |
| 4260 access->set_position(position); | 4276 access->set_position(position); |
| 4261 if (!is_store) { | 4277 if (!is_store) { |
| 4262 Push(access); | 4278 Push(access); |
| 4263 } | 4279 } |
| 4264 current_block()->Goto(join); | 4280 current_block()->Goto(join); |
| 4265 set_current_block(if_false); | 4281 set_current_block(if_false); |
| 4266 } | 4282 } |
| 4267 } | 4283 } |
| 4268 | 4284 |
| 4269 // Deopt if none of the cases matched. | 4285 // Deopt if none of the cases matched. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4294 obj, key, val, expr, ast_id, position, is_store, has_side_effects); | 4310 obj, key, val, expr, ast_id, position, is_store, has_side_effects); |
| 4295 } else { | 4311 } else { |
| 4296 if (is_store) { | 4312 if (is_store) { |
| 4297 instr = BuildStoreKeyedGeneric(obj, key, val); | 4313 instr = BuildStoreKeyedGeneric(obj, key, val); |
| 4298 } else { | 4314 } else { |
| 4299 instr = BuildLoadKeyedGeneric(obj, key); | 4315 instr = BuildLoadKeyedGeneric(obj, key); |
| 4300 } | 4316 } |
| 4301 } | 4317 } |
| 4302 instr->set_position(position); | 4318 instr->set_position(position); |
| 4303 AddInstruction(instr); | 4319 AddInstruction(instr); |
| 4304 *has_side_effects = instr->HasSideEffects(); | 4320 *has_side_effects = instr->HasObservableSideEffects(); |
| 4305 return instr; | 4321 return instr; |
| 4306 } | 4322 } |
| 4307 | 4323 |
| 4308 | 4324 |
| 4309 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 4325 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
| 4310 HValue* key, | 4326 HValue* key, |
| 4311 HValue* value) { | 4327 HValue* value) { |
| 4312 HValue* context = environment()->LookupContext(); | 4328 HValue* context = environment()->LookupContext(); |
| 4313 return new(zone()) HStoreKeyedGeneric( | 4329 return new(zone()) HStoreKeyedGeneric( |
| 4314 context, | 4330 context, |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4893 } else if (exponent == -0.5) { | 4909 } else if (exponent == -0.5) { |
| 4894 HConstant* double_one = | 4910 HConstant* double_one = |
| 4895 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 4911 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), |
| 4896 Representation::Double()); | 4912 Representation::Double()); |
| 4897 AddInstruction(double_one); | 4913 AddInstruction(double_one); |
| 4898 HUnaryMathOperation* square_root = | 4914 HUnaryMathOperation* square_root = |
| 4899 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); | 4915 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); |
| 4900 AddInstruction(square_root); | 4916 AddInstruction(square_root); |
| 4901 // MathPowHalf doesn't have side effects so there's no need for | 4917 // MathPowHalf doesn't have side effects so there's no need for |
| 4902 // an environment simulation here. | 4918 // an environment simulation here. |
| 4903 ASSERT(!square_root->HasSideEffects()); | 4919 ASSERT(!square_root->HasObservableSideEffects()); |
| 4904 result = new(zone()) HDiv(context, double_one, square_root); | 4920 result = new(zone()) HDiv(context, double_one, square_root); |
| 4905 } else if (exponent == 2.0) { | 4921 } else if (exponent == 2.0) { |
| 4906 result = new(zone()) HMul(context, left, left); | 4922 result = new(zone()) HMul(context, left, left); |
| 4907 } | 4923 } |
| 4908 } else if (right->IsConstant() && | 4924 } else if (right->IsConstant() && |
| 4909 HConstant::cast(right)->HasInteger32Value() && | 4925 HConstant::cast(right)->HasInteger32Value() && |
| 4910 HConstant::cast(right)->Integer32Value() == 2) { | 4926 HConstant::cast(right)->Integer32Value() == 2) { |
| 4911 result = new(zone()) HMul(context, left, left); | 4927 result = new(zone()) HMul(context, left, left); |
| 4912 } | 4928 } |
| 4913 | 4929 |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5477 if (var == info()->scope()->parameter(i)) { | 5493 if (var == info()->scope()->parameter(i)) { |
| 5478 return Bailout("assignment to parameter in arguments object"); | 5494 return Bailout("assignment to parameter in arguments object"); |
| 5479 } | 5495 } |
| 5480 } | 5496 } |
| 5481 } | 5497 } |
| 5482 | 5498 |
| 5483 HValue* context = BuildContextChainWalk(var); | 5499 HValue* context = BuildContextChainWalk(var); |
| 5484 HStoreContextSlot* instr = | 5500 HStoreContextSlot* instr = |
| 5485 new(zone()) HStoreContextSlot(context, var->index(), after); | 5501 new(zone()) HStoreContextSlot(context, var->index(), after); |
| 5486 AddInstruction(instr); | 5502 AddInstruction(instr); |
| 5487 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 5503 if (instr->HasObservableSideEffects()) { |
| 5504 AddSimulate(expr->AssignmentId()); |
| 5505 } |
| 5488 break; | 5506 break; |
| 5489 } | 5507 } |
| 5490 | 5508 |
| 5491 case Variable::LOOKUP: | 5509 case Variable::LOOKUP: |
| 5492 return Bailout("lookup variable in count operation"); | 5510 return Bailout("lookup variable in count operation"); |
| 5493 } | 5511 } |
| 5494 | 5512 |
| 5495 } else { | 5513 } else { |
| 5496 // Argument of the count operation is a property. | 5514 // Argument of the count operation is a property. |
| 5497 ASSERT(prop != NULL); | 5515 ASSERT(prop != NULL); |
| 5498 prop->RecordTypeFeedback(oracle()); | 5516 prop->RecordTypeFeedback(oracle()); |
| 5499 | 5517 |
| 5500 if (prop->key()->IsPropertyName()) { | 5518 if (prop->key()->IsPropertyName()) { |
| 5501 // Named property. | 5519 // Named property. |
| 5502 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 5520 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
| 5503 | 5521 |
| 5504 CHECK_ALIVE(VisitForValue(prop->obj())); | 5522 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5505 HValue* obj = Top(); | 5523 HValue* obj = Top(); |
| 5506 | 5524 |
| 5507 HInstruction* load = NULL; | 5525 HInstruction* load = NULL; |
| 5508 if (prop->IsMonomorphic()) { | 5526 if (prop->IsMonomorphic()) { |
| 5509 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5527 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 5510 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5528 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| 5511 load = BuildLoadNamed(obj, prop, map, name); | 5529 load = BuildLoadNamed(obj, prop, map, name); |
| 5512 } else { | 5530 } else { |
| 5513 load = BuildLoadNamedGeneric(obj, prop); | 5531 load = BuildLoadNamedGeneric(obj, prop); |
| 5514 } | 5532 } |
| 5515 PushAndAdd(load); | 5533 PushAndAdd(load); |
| 5516 if (load->HasSideEffects()) AddSimulate(expr->CountId()); | 5534 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
| 5517 | 5535 |
| 5518 after = BuildIncrement(returns_original_input, expr); | 5536 after = BuildIncrement(returns_original_input, expr); |
| 5519 input = Pop(); | 5537 input = Pop(); |
| 5520 | 5538 |
| 5521 HInstruction* store = BuildStoreNamed(obj, after, prop); | 5539 HInstruction* store = BuildStoreNamed(obj, after, prop); |
| 5522 AddInstruction(store); | 5540 AddInstruction(store); |
| 5523 | 5541 |
| 5524 // Overwrite the receiver in the bailout environment with the result | 5542 // Overwrite the receiver in the bailout environment with the result |
| 5525 // of the operation, and the placeholder with the original value if | 5543 // of the operation, and the placeholder with the original value if |
| 5526 // necessary. | 5544 // necessary. |
| 5527 environment()->SetExpressionStackAt(0, after); | 5545 environment()->SetExpressionStackAt(0, after); |
| 5528 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 5546 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| 5529 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 5547 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| 5530 | 5548 |
| 5531 } else { | 5549 } else { |
| 5532 // Keyed property. | 5550 // Keyed property. |
| 5533 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 5551 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
| 5534 | 5552 |
| 5535 CHECK_ALIVE(VisitForValue(prop->obj())); | 5553 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5536 CHECK_ALIVE(VisitForValue(prop->key())); | 5554 CHECK_ALIVE(VisitForValue(prop->key())); |
| 5537 HValue* obj = environment()->ExpressionStackAt(1); | 5555 HValue* obj = environment()->ExpressionStackAt(1); |
| 5538 HValue* key = environment()->ExpressionStackAt(0); | 5556 HValue* key = environment()->ExpressionStackAt(0); |
| 5539 | 5557 |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6073 value = graph()->GetConstantHole(); | 6091 value = graph()->GetConstantHole(); |
| 6074 } else { | 6092 } else { |
| 6075 VisitForValue(function); | 6093 VisitForValue(function); |
| 6076 value = Pop(); | 6094 value = Pop(); |
| 6077 } | 6095 } |
| 6078 if (var->IsContextSlot()) { | 6096 if (var->IsContextSlot()) { |
| 6079 HValue* context = environment()->LookupContext(); | 6097 HValue* context = environment()->LookupContext(); |
| 6080 HStoreContextSlot* store = | 6098 HStoreContextSlot* store = |
| 6081 new HStoreContextSlot(context, var->index(), value); | 6099 new HStoreContextSlot(context, var->index(), value); |
| 6082 AddInstruction(store); | 6100 AddInstruction(store); |
| 6083 if (store->HasSideEffects()) AddSimulate(proxy->id()); | 6101 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| 6084 } else { | 6102 } else { |
| 6085 environment()->Bind(var, value); | 6103 environment()->Bind(var, value); |
| 6086 } | 6104 } |
| 6087 } | 6105 } |
| 6088 break; | 6106 break; |
| 6089 case Variable::LOOKUP: | 6107 case Variable::LOOKUP: |
| 6090 return Bailout("unsupported lookup slot in declaration"); | 6108 return Bailout("unsupported lookup slot in declaration"); |
| 6091 } | 6109 } |
| 6092 } | 6110 } |
| 6093 | 6111 |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7019 } | 7037 } |
| 7020 } | 7038 } |
| 7021 | 7039 |
| 7022 #ifdef DEBUG | 7040 #ifdef DEBUG |
| 7023 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7041 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 7024 if (allocator_ != NULL) allocator_->Verify(); | 7042 if (allocator_ != NULL) allocator_->Verify(); |
| 7025 #endif | 7043 #endif |
| 7026 } | 7044 } |
| 7027 | 7045 |
| 7028 } } // namespace v8::internal | 7046 } } // namespace v8::internal |
| OLD | NEW |