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 |