Chromium Code Reviews| 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 done_(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 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1370 int loop_kills); | 1371 int loop_kills); |
| 1371 bool AllowCodeMotion(); | 1372 bool AllowCodeMotion(); |
| 1372 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1373 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
| 1373 | 1374 |
| 1374 HGraph* graph() { return graph_; } | 1375 HGraph* graph() { return graph_; } |
| 1375 CompilationInfo* info() { return info_; } | 1376 CompilationInfo* info() { return info_; } |
| 1376 Zone* zone() { return graph_->zone(); } | 1377 Zone* zone() { return graph_->zone(); } |
| 1377 | 1378 |
| 1378 HGraph* graph_; | 1379 HGraph* graph_; |
| 1379 CompilationInfo* info_; | 1380 CompilationInfo* info_; |
| 1381 bool done_; | |
| 1380 | 1382 |
| 1381 // A map of block IDs to their side effects. | 1383 // A map of block IDs to their side effects. |
| 1382 ZoneList<int> block_side_effects_; | 1384 ZoneList<int> block_side_effects_; |
| 1383 | 1385 |
| 1384 // A map of loop header block IDs to their loop's side effects. | 1386 // A map of loop header block IDs to their loop's side effects. |
| 1385 ZoneList<int> loop_side_effects_; | 1387 ZoneList<int> loop_side_effects_; |
| 1386 | 1388 |
| 1387 // Used when collecting side effects on paths from dominator to | 1389 // Used when collecting side effects on paths from dominator to |
| 1388 // dominated. | 1390 // dominated. |
| 1389 SparseSet visited_on_paths_; | 1391 SparseSet visited_on_paths_; |
| 1390 }; | 1392 }; |
| 1391 | 1393 |
| 1392 | 1394 |
| 1393 void HGlobalValueNumberer::Analyze() { | 1395 void HGlobalValueNumberer::Analyze() { |
| 1394 ComputeBlockSideEffects(); | 1396 while (!done_) { |
|
fschneider
2011/10/27 15:58:22
Couldn't you just do 2 rounds at most? First you h
danno
2011/10/28 07:29:52
Done, although I don't know if the more general ap
| |
| 1395 if (FLAG_loop_invariant_code_motion) { | 1397 done_ = true; |
| 1396 LoopInvariantCodeMotion(); | 1398 ComputeBlockSideEffects(); |
| 1399 if (FLAG_loop_invariant_code_motion) { | |
| 1400 LoopInvariantCodeMotion(); | |
| 1401 } | |
| 1402 HValueMap* map = new(zone()) HValueMap(); | |
| 1403 AnalyzeBlock(graph_->entry_block(), map); | |
| 1397 } | 1404 } |
| 1398 HValueMap* map = new(zone()) HValueMap(); | |
| 1399 AnalyzeBlock(graph_->entry_block(), map); | |
| 1400 } | 1405 } |
| 1401 | 1406 |
| 1402 | 1407 |
| 1403 void HGlobalValueNumberer::ComputeBlockSideEffects() { | 1408 void HGlobalValueNumberer::ComputeBlockSideEffects() { |
| 1404 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { | 1409 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { |
| 1405 // Compute side effects for the block. | 1410 // Compute side effects for the block. |
| 1406 HBasicBlock* block = graph_->blocks()->at(i); | 1411 HBasicBlock* block = graph_->blocks()->at(i); |
| 1407 HInstruction* instr = block->first(); | 1412 HInstruction* instr = block->first(); |
| 1408 int id = block->block_id(); | 1413 int id = block->block_id(); |
| 1409 int side_effects = 0; | 1414 int side_effects = 0; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1520 if (block->IsLoopHeader()) { | 1525 if (block->IsLoopHeader()) { |
| 1521 map->Kill(loop_side_effects_[block->block_id()]); | 1526 map->Kill(loop_side_effects_[block->block_id()]); |
| 1522 } | 1527 } |
| 1523 | 1528 |
| 1524 // Go through all instructions of the current block. | 1529 // Go through all instructions of the current block. |
| 1525 HInstruction* instr = block->first(); | 1530 HInstruction* instr = block->first(); |
| 1526 while (instr != NULL) { | 1531 while (instr != NULL) { |
| 1527 HInstruction* next = instr->next(); | 1532 HInstruction* next = instr->next(); |
| 1528 int flags = instr->ChangesFlags(); | 1533 int flags = instr->ChangesFlags(); |
| 1529 if (flags != 0) { | 1534 if (flags != 0) { |
| 1530 ASSERT(!instr->CheckFlag(HValue::kUseGVN)); | |
| 1531 // Clear all instructions in the map that are affected by side effects. | 1535 // Clear all instructions in the map that are affected by side effects. |
| 1532 map->Kill(flags); | 1536 map->Kill(flags); |
| 1533 TraceGVN("Instruction %d kills\n", instr->id()); | 1537 TraceGVN("Instruction %d kills\n", instr->id()); |
| 1534 } else if (instr->CheckFlag(HValue::kUseGVN)) { | 1538 } |
| 1539 if (instr->CheckFlag(HValue::kUseGVN)) { | |
| 1540 ASSERT(!instr->HasObservableSideEffects()); | |
| 1535 HValue* other = map->Lookup(instr); | 1541 HValue* other = map->Lookup(instr); |
| 1536 if (other != NULL) { | 1542 if (other != NULL) { |
| 1537 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1543 ASSERT(instr->Equals(other) && other->Equals(instr)); |
| 1538 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", | 1544 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", |
| 1539 instr->id(), | 1545 instr->id(), |
| 1540 instr->Mnemonic(), | 1546 instr->Mnemonic(), |
| 1541 other->id(), | 1547 other->id(), |
| 1542 other->Mnemonic()); | 1548 other->Mnemonic()); |
| 1549 if (instr->HasSideEffects()) done_ = false; | |
| 1543 instr->DeleteAndReplaceWith(other); | 1550 instr->DeleteAndReplaceWith(other); |
| 1544 } else { | 1551 } else { |
| 1545 map->Add(instr); | 1552 map->Add(instr); |
| 1546 } | 1553 } |
| 1547 } | 1554 } |
| 1548 instr = next; | 1555 instr = next; |
| 1549 } | 1556 } |
| 1550 | 1557 |
| 1551 // Recursively continue analysis for all immediately dominated blocks. | 1558 // Recursively continue analysis for all immediately dominated blocks. |
| 1552 int length = block->dominated_blocks()->length(); | 1559 int length = block->dominated_blocks()->length(); |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2098 | 2105 |
| 2099 | 2106 |
| 2100 void TestContext::ReturnValue(HValue* value) { | 2107 void TestContext::ReturnValue(HValue* value) { |
| 2101 BuildBranch(value); | 2108 BuildBranch(value); |
| 2102 } | 2109 } |
| 2103 | 2110 |
| 2104 | 2111 |
| 2105 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 2112 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| 2106 ASSERT(!instr->IsControlInstruction()); | 2113 ASSERT(!instr->IsControlInstruction()); |
| 2107 owner()->AddInstruction(instr); | 2114 owner()->AddInstruction(instr); |
| 2108 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); | 2115 if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); |
| 2109 } | 2116 } |
| 2110 | 2117 |
| 2111 | 2118 |
| 2112 void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) { | 2119 void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| 2113 ASSERT(!instr->HasSideEffects()); | 2120 ASSERT(!instr->HasObservableSideEffects()); |
| 2114 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 2121 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 2115 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 2122 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 2116 instr->SetSuccessorAt(0, empty_true); | 2123 instr->SetSuccessorAt(0, empty_true); |
| 2117 instr->SetSuccessorAt(1, empty_false); | 2124 instr->SetSuccessorAt(1, empty_false); |
| 2118 owner()->current_block()->Finish(instr); | 2125 owner()->current_block()->Finish(instr); |
| 2119 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); | 2126 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); |
| 2120 owner()->set_current_block(join); | 2127 owner()->set_current_block(join); |
| 2121 } | 2128 } |
| 2122 | 2129 |
| 2123 | 2130 |
| 2124 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 2131 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| 2125 ASSERT(!instr->IsControlInstruction()); | 2132 ASSERT(!instr->IsControlInstruction()); |
| 2126 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 2133 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 2127 return owner()->Bailout("bad value context for arguments object value"); | 2134 return owner()->Bailout("bad value context for arguments object value"); |
| 2128 } | 2135 } |
| 2129 owner()->AddInstruction(instr); | 2136 owner()->AddInstruction(instr); |
| 2130 owner()->Push(instr); | 2137 owner()->Push(instr); |
| 2131 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); | 2138 if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); |
| 2132 } | 2139 } |
| 2133 | 2140 |
| 2134 | 2141 |
| 2135 void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) { | 2142 void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| 2136 ASSERT(!instr->HasSideEffects()); | 2143 ASSERT(!instr->HasObservableSideEffects()); |
| 2137 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 2144 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 2138 return owner()->Bailout("bad value context for arguments object value"); | 2145 return owner()->Bailout("bad value context for arguments object value"); |
| 2139 } | 2146 } |
| 2140 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); | 2147 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); |
| 2141 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); | 2148 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); |
| 2142 instr->SetSuccessorAt(0, materialize_true); | 2149 instr->SetSuccessorAt(0, materialize_true); |
| 2143 instr->SetSuccessorAt(1, materialize_false); | 2150 instr->SetSuccessorAt(1, materialize_false); |
| 2144 owner()->current_block()->Finish(instr); | 2151 owner()->current_block()->Finish(instr); |
| 2145 owner()->set_current_block(materialize_true); | 2152 owner()->set_current_block(materialize_true); |
| 2146 owner()->Push(owner()->graph()->GetConstantTrue()); | 2153 owner()->Push(owner()->graph()->GetConstantTrue()); |
| 2147 owner()->set_current_block(materialize_false); | 2154 owner()->set_current_block(materialize_false); |
| 2148 owner()->Push(owner()->graph()->GetConstantFalse()); | 2155 owner()->Push(owner()->graph()->GetConstantFalse()); |
| 2149 HBasicBlock* join = | 2156 HBasicBlock* join = |
| 2150 owner()->CreateJoin(materialize_true, materialize_false, ast_id); | 2157 owner()->CreateJoin(materialize_true, materialize_false, ast_id); |
| 2151 owner()->set_current_block(join); | 2158 owner()->set_current_block(join); |
| 2152 } | 2159 } |
| 2153 | 2160 |
| 2154 | 2161 |
| 2155 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { | 2162 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| 2156 ASSERT(!instr->IsControlInstruction()); | 2163 ASSERT(!instr->IsControlInstruction()); |
| 2157 HGraphBuilder* builder = owner(); | 2164 HGraphBuilder* builder = owner(); |
| 2158 builder->AddInstruction(instr); | 2165 builder->AddInstruction(instr); |
| 2159 // We expect a simulate after every expression with side effects, though | 2166 // We expect a simulate after every expression with side effects, though |
| 2160 // this one isn't actually needed (and wouldn't work if it were targeted). | 2167 // this one isn't actually needed (and wouldn't work if it were targeted). |
| 2161 if (instr->HasSideEffects()) { | 2168 if (instr->HasObservableSideEffects()) { |
| 2162 builder->Push(instr); | 2169 builder->Push(instr); |
| 2163 builder->AddSimulate(ast_id); | 2170 builder->AddSimulate(ast_id); |
| 2164 builder->Pop(); | 2171 builder->Pop(); |
| 2165 } | 2172 } |
| 2166 BuildBranch(instr); | 2173 BuildBranch(instr); |
| 2167 } | 2174 } |
| 2168 | 2175 |
| 2169 | 2176 |
| 2170 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { | 2177 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| 2171 ASSERT(!instr->HasSideEffects()); | 2178 ASSERT(!instr->HasObservableSideEffects()); |
| 2172 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 2179 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 2173 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 2180 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 2174 instr->SetSuccessorAt(0, empty_true); | 2181 instr->SetSuccessorAt(0, empty_true); |
| 2175 instr->SetSuccessorAt(1, empty_false); | 2182 instr->SetSuccessorAt(1, empty_false); |
| 2176 owner()->current_block()->Finish(instr); | 2183 owner()->current_block()->Finish(instr); |
| 2177 empty_true->Goto(if_true(), owner()->function_state()->drop_extra()); | 2184 empty_true->Goto(if_true(), owner()->function_state()->drop_extra()); |
| 2178 empty_false->Goto(if_false(), owner()->function_state()->drop_extra()); | 2185 empty_false->Goto(if_false(), owner()->function_state()->drop_extra()); |
| 2179 owner()->set_current_block(NULL); | 2186 owner()->set_current_block(NULL); |
| 2180 } | 2187 } |
| 2181 | 2188 |
| (...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3536 instr->set_position(expr->position()); | 3543 instr->set_position(expr->position()); |
| 3537 AddInstruction(instr); | 3544 AddInstruction(instr); |
| 3538 | 3545 |
| 3539 if (join != NULL) { | 3546 if (join != NULL) { |
| 3540 if (!ast_context()->IsEffect()) Push(value); | 3547 if (!ast_context()->IsEffect()) Push(value); |
| 3541 current_block()->Goto(join); | 3548 current_block()->Goto(join); |
| 3542 } else { | 3549 } else { |
| 3543 // The HSimulate for the store should not see the stored value in | 3550 // The HSimulate for the store should not see the stored value in |
| 3544 // effect contexts (it is not materialized at expr->id() in the | 3551 // effect contexts (it is not materialized at expr->id() in the |
| 3545 // unoptimized code). | 3552 // unoptimized code). |
| 3546 if (instr->HasSideEffects()) { | 3553 if (instr->HasObservableSideEffects()) { |
| 3547 if (ast_context()->IsEffect()) { | 3554 if (ast_context()->IsEffect()) { |
| 3548 AddSimulate(expr->id()); | 3555 AddSimulate(expr->id()); |
| 3549 } else { | 3556 } else { |
| 3550 Push(value); | 3557 Push(value); |
| 3551 AddSimulate(expr->id()); | 3558 AddSimulate(expr->id()); |
| 3552 Drop(1); | 3559 Drop(1); |
| 3553 } | 3560 } |
| 3554 } | 3561 } |
| 3555 return ast_context()->ReturnValue(value); | 3562 return ast_context()->ReturnValue(value); |
| 3556 } | 3563 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3609 true, // is_store | 3616 true, // is_store |
| 3610 &has_side_effects); | 3617 &has_side_effects); |
| 3611 Push(value); | 3618 Push(value); |
| 3612 ASSERT(has_side_effects); // Stores always have side effects. | 3619 ASSERT(has_side_effects); // Stores always have side effects. |
| 3613 AddSimulate(expr->AssignmentId()); | 3620 AddSimulate(expr->AssignmentId()); |
| 3614 return ast_context()->ReturnValue(Pop()); | 3621 return ast_context()->ReturnValue(Pop()); |
| 3615 } | 3622 } |
| 3616 Push(value); | 3623 Push(value); |
| 3617 instr->set_position(expr->position()); | 3624 instr->set_position(expr->position()); |
| 3618 AddInstruction(instr); | 3625 AddInstruction(instr); |
| 3619 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3626 if (instr->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3620 return ast_context()->ReturnValue(Pop()); | 3627 return ast_context()->ReturnValue(Pop()); |
| 3621 } | 3628 } |
| 3622 | 3629 |
| 3623 | 3630 |
| 3624 // Because not every expression has a position and there is not common | 3631 // Because not every expression has a position and there is not common |
| 3625 // superclass of Assignment and CountOperation, we cannot just pass the | 3632 // superclass of Assignment and CountOperation, we cannot just pass the |
| 3626 // owning expression instead of position and ast_id separately. | 3633 // owning expression instead of position and ast_id separately. |
| 3627 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3634 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| 3628 HValue* value, | 3635 HValue* value, |
| 3629 int position, | 3636 int position, |
| 3630 int ast_id) { | 3637 int ast_id) { |
| 3631 LookupResult lookup(isolate()); | 3638 LookupResult lookup(isolate()); |
| 3632 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 3639 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 3633 if (type == kUseCell) { | 3640 if (type == kUseCell) { |
| 3634 Handle<GlobalObject> global(info()->global_object()); | 3641 Handle<GlobalObject> global(info()->global_object()); |
| 3635 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3642 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 3636 HInstruction* instr = | 3643 HInstruction* instr = |
| 3637 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 3644 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| 3638 instr->set_position(position); | 3645 instr->set_position(position); |
| 3639 AddInstruction(instr); | 3646 AddInstruction(instr); |
| 3640 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3647 if (instr->HasObservableSideEffects()) AddSimulate(ast_id); |
| 3641 } else { | 3648 } else { |
| 3642 HValue* context = environment()->LookupContext(); | 3649 HValue* context = environment()->LookupContext(); |
| 3643 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 3650 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 3644 AddInstruction(global_object); | 3651 AddInstruction(global_object); |
| 3645 HStoreGlobalGeneric* instr = | 3652 HStoreGlobalGeneric* instr = |
| 3646 new(zone()) HStoreGlobalGeneric(context, | 3653 new(zone()) HStoreGlobalGeneric(context, |
| 3647 global_object, | 3654 global_object, |
| 3648 var->name(), | 3655 var->name(), |
| 3649 value, | 3656 value, |
| 3650 function_strict_mode_flag()); | 3657 function_strict_mode_flag()); |
| 3651 instr->set_position(position); | 3658 instr->set_position(position); |
| 3652 AddInstruction(instr); | 3659 AddInstruction(instr); |
| 3653 ASSERT(instr->HasSideEffects()); | 3660 ASSERT(instr->HasObservableSideEffects()); |
| 3654 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3661 if (instr->HasObservableSideEffects()) AddSimulate(ast_id); |
| 3655 } | 3662 } |
| 3656 } | 3663 } |
| 3657 | 3664 |
| 3658 | 3665 |
| 3659 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 3666 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 3660 Expression* target = expr->target(); | 3667 Expression* target = expr->target(); |
| 3661 VariableProxy* proxy = target->AsVariableProxy(); | 3668 VariableProxy* proxy = target->AsVariableProxy(); |
| 3662 Property* prop = target->AsProperty(); | 3669 Property* prop = target->AsProperty(); |
| 3663 ASSERT(proxy == NULL || prop == NULL); | 3670 ASSERT(proxy == NULL || prop == NULL); |
| 3664 | 3671 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3701 Bailout( | 3708 Bailout( |
| 3702 "assignment to parameter, function uses arguments object"); | 3709 "assignment to parameter, function uses arguments object"); |
| 3703 } | 3710 } |
| 3704 } | 3711 } |
| 3705 } | 3712 } |
| 3706 | 3713 |
| 3707 HValue* context = BuildContextChainWalk(var); | 3714 HValue* context = BuildContextChainWalk(var); |
| 3708 HStoreContextSlot* instr = | 3715 HStoreContextSlot* instr = |
| 3709 new(zone()) HStoreContextSlot(context, var->index(), Top()); | 3716 new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| 3710 AddInstruction(instr); | 3717 AddInstruction(instr); |
| 3711 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3718 if (instr->HasObservableSideEffects()) { |
| 3719 AddSimulate(expr->AssignmentId()); | |
| 3720 } | |
| 3712 break; | 3721 break; |
| 3713 } | 3722 } |
| 3714 | 3723 |
| 3715 case Variable::LOOKUP: | 3724 case Variable::LOOKUP: |
| 3716 return Bailout("compound assignment to lookup slot"); | 3725 return Bailout("compound assignment to lookup slot"); |
| 3717 } | 3726 } |
| 3718 return ast_context()->ReturnValue(Pop()); | 3727 return ast_context()->ReturnValue(Pop()); |
| 3719 | 3728 |
| 3720 } else if (prop != NULL) { | 3729 } else if (prop != NULL) { |
| 3721 prop->RecordTypeFeedback(oracle()); | 3730 prop->RecordTypeFeedback(oracle()); |
| 3722 | 3731 |
| 3723 if (prop->key()->IsPropertyName()) { | 3732 if (prop->key()->IsPropertyName()) { |
| 3724 // Named property. | 3733 // Named property. |
| 3725 CHECK_ALIVE(VisitForValue(prop->obj())); | 3734 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 3726 HValue* obj = Top(); | 3735 HValue* obj = Top(); |
| 3727 | 3736 |
| 3728 HInstruction* load = NULL; | 3737 HInstruction* load = NULL; |
| 3729 if (prop->IsMonomorphic()) { | 3738 if (prop->IsMonomorphic()) { |
| 3730 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 3739 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 3731 Handle<Map> map = prop->GetReceiverTypes()->first(); | 3740 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| 3732 load = BuildLoadNamed(obj, prop, map, name); | 3741 load = BuildLoadNamed(obj, prop, map, name); |
| 3733 } else { | 3742 } else { |
| 3734 load = BuildLoadNamedGeneric(obj, prop); | 3743 load = BuildLoadNamedGeneric(obj, prop); |
| 3735 } | 3744 } |
| 3736 PushAndAdd(load); | 3745 PushAndAdd(load); |
| 3737 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); | 3746 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); |
| 3738 | 3747 |
| 3739 CHECK_ALIVE(VisitForValue(expr->value())); | 3748 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3740 HValue* right = Pop(); | 3749 HValue* right = Pop(); |
| 3741 HValue* left = Pop(); | 3750 HValue* left = Pop(); |
| 3742 | 3751 |
| 3743 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3752 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 3744 PushAndAdd(instr); | 3753 PushAndAdd(instr); |
| 3745 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3754 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 3746 | 3755 |
| 3747 HInstruction* store = BuildStoreNamed(obj, instr, prop); | 3756 HInstruction* store = BuildStoreNamed(obj, instr, prop); |
| 3748 AddInstruction(store); | 3757 AddInstruction(store); |
| 3749 // Drop the simulated receiver and value. Return the value. | 3758 // Drop the simulated receiver and value. Return the value. |
| 3750 Drop(2); | 3759 Drop(2); |
| 3751 Push(instr); | 3760 Push(instr); |
| 3752 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3761 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3753 return ast_context()->ReturnValue(Pop()); | 3762 return ast_context()->ReturnValue(Pop()); |
| 3754 | 3763 |
| 3755 } else { | 3764 } else { |
| 3756 // Keyed property. | 3765 // Keyed property. |
| 3757 CHECK_ALIVE(VisitForValue(prop->obj())); | 3766 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 3758 CHECK_ALIVE(VisitForValue(prop->key())); | 3767 CHECK_ALIVE(VisitForValue(prop->key())); |
| 3759 HValue* obj = environment()->ExpressionStackAt(1); | 3768 HValue* obj = environment()->ExpressionStackAt(1); |
| 3760 HValue* key = environment()->ExpressionStackAt(0); | 3769 HValue* key = environment()->ExpressionStackAt(0); |
| 3761 | 3770 |
| 3762 bool has_side_effects = false; | 3771 bool has_side_effects = false; |
| 3763 HValue* load = HandleKeyedElementAccess( | 3772 HValue* load = HandleKeyedElementAccess( |
| 3764 obj, key, NULL, prop, expr->CompoundLoadId(), RelocInfo::kNoPosition, | 3773 obj, key, NULL, prop, expr->CompoundLoadId(), RelocInfo::kNoPosition, |
| 3765 false, // is_store | 3774 false, // is_store |
| 3766 &has_side_effects); | 3775 &has_side_effects); |
| 3767 Push(load); | 3776 Push(load); |
| 3768 if (has_side_effects) AddSimulate(expr->CompoundLoadId()); | 3777 if (has_side_effects) AddSimulate(expr->CompoundLoadId()); |
| 3769 | 3778 |
| 3770 | 3779 |
| 3771 CHECK_ALIVE(VisitForValue(expr->value())); | 3780 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3772 HValue* right = Pop(); | 3781 HValue* right = Pop(); |
| 3773 HValue* left = Pop(); | 3782 HValue* left = Pop(); |
| 3774 | 3783 |
| 3775 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3784 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 3776 PushAndAdd(instr); | 3785 PushAndAdd(instr); |
| 3777 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3786 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 3778 | 3787 |
| 3779 expr->RecordTypeFeedback(oracle()); | 3788 expr->RecordTypeFeedback(oracle()); |
| 3780 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 3789 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| 3781 RelocInfo::kNoPosition, | 3790 RelocInfo::kNoPosition, |
| 3782 true, // is_store | 3791 true, // is_store |
| 3783 &has_side_effects); | 3792 &has_side_effects); |
| 3784 | 3793 |
| 3785 // Drop the simulated receiver, key, and value. Return the value. | 3794 // Drop the simulated receiver, key, and value. Return the value. |
| 3786 Drop(3); | 3795 Drop(3); |
| 3787 Push(instr); | 3796 Push(instr); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3865 return Bailout("assignment to parameter in arguments object"); | 3874 return Bailout("assignment to parameter in arguments object"); |
| 3866 } | 3875 } |
| 3867 } | 3876 } |
| 3868 } | 3877 } |
| 3869 | 3878 |
| 3870 CHECK_ALIVE(VisitForValue(expr->value())); | 3879 CHECK_ALIVE(VisitForValue(expr->value())); |
| 3871 HValue* context = BuildContextChainWalk(var); | 3880 HValue* context = BuildContextChainWalk(var); |
| 3872 HStoreContextSlot* instr = | 3881 HStoreContextSlot* instr = |
| 3873 new(zone()) HStoreContextSlot(context, var->index(), Top()); | 3882 new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| 3874 AddInstruction(instr); | 3883 AddInstruction(instr); |
| 3875 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3884 if (instr->HasObservableSideEffects()) { |
| 3885 AddSimulate(expr->AssignmentId()); | |
| 3886 } | |
| 3876 return ast_context()->ReturnValue(Pop()); | 3887 return ast_context()->ReturnValue(Pop()); |
| 3877 } | 3888 } |
| 3878 | 3889 |
| 3879 case Variable::LOOKUP: | 3890 case Variable::LOOKUP: |
| 3880 return Bailout("assignment to LOOKUP variable"); | 3891 return Bailout("assignment to LOOKUP variable"); |
| 3881 } | 3892 } |
| 3882 } else { | 3893 } else { |
| 3883 return Bailout("invalid left-hand side in assignment"); | 3894 return Bailout("invalid left-hand side in assignment"); |
| 3884 } | 3895 } |
| 3885 } | 3896 } |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4121 map->FindTransitionedMap(&possible_transitioned_maps); | 4132 map->FindTransitionedMap(&possible_transitioned_maps); |
| 4122 transition_target.Add(transitioned_map); | 4133 transition_target.Add(transitioned_map); |
| 4123 } | 4134 } |
| 4124 | 4135 |
| 4125 int num_untransitionable_maps = 0; | 4136 int num_untransitionable_maps = 0; |
| 4126 Handle<Map> untransitionable_map; | 4137 Handle<Map> untransitionable_map; |
| 4127 for (int i = 0; i < maps->length(); ++i) { | 4138 for (int i = 0; i < maps->length(); ++i) { |
| 4128 Handle<Map> map = maps->at(i); | 4139 Handle<Map> map = maps->at(i); |
| 4129 ASSERT(map->IsMap()); | 4140 ASSERT(map->IsMap()); |
| 4130 if (!transition_target.at(i).is_null()) { | 4141 if (!transition_target.at(i).is_null()) { |
| 4131 object = AddInstruction(new(zone()) HTransitionElementsKind( | 4142 object = AddInstruction(new(zone()) HTransitionElementsKind( |
|
fschneider
2011/10/27 15:58:22
I'm not sure, if it ther is any benefit to emit a
danno
2011/10/28 07:29:52
I don't think this is necessarily a good idea. If
| |
| 4132 object, map, transition_target.at(i))); | 4143 object, map, transition_target.at(i))); |
| 4133 } else { | 4144 } else { |
| 4134 type_todo[map->elements_kind()] = true; | 4145 type_todo[map->elements_kind()] = true; |
| 4135 if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { | 4146 if (map->elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { |
| 4136 todo_external_array = true; | 4147 todo_external_array = true; |
| 4137 } | 4148 } |
| 4138 num_untransitionable_maps++; | 4149 num_untransitionable_maps++; |
| 4139 untransitionable_map = map; | 4150 untransitionable_map = map; |
| 4140 } | 4151 } |
| 4141 } | 4152 } |
| 4142 | 4153 |
| 4143 // If only one map is left after transitioning, handle this case | 4154 // If only one map is left after transitioning, handle this case |
| 4144 // monomorphically. | 4155 // monomorphically. |
| 4145 if (num_untransitionable_maps == 1) { | 4156 if (num_untransitionable_maps == 1) { |
| 4146 HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( | 4157 HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( |
| 4147 object, key, val, untransitionable_map, is_store)); | 4158 object, key, val, untransitionable_map, is_store)); |
| 4148 *has_side_effects |= instr->HasSideEffects(); | 4159 *has_side_effects |= instr->HasObservableSideEffects(); |
| 4149 instr->set_position(position); | 4160 instr->set_position(position); |
| 4150 return is_store ? NULL : instr; | 4161 return is_store ? NULL : instr; |
| 4151 } | 4162 } |
| 4152 | 4163 |
| 4153 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 4164 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); |
| 4154 HBasicBlock* join = graph()->CreateBasicBlock(); | 4165 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 4155 | 4166 |
| 4156 HInstruction* elements_kind_instr = | 4167 HInstruction* elements_kind_instr = |
| 4157 AddInstruction(new(zone()) HElementsKind(object)); | 4168 AddInstruction(new(zone()) HElementsKind(object)); |
| 4158 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 4169 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4225 set_current_block(if_jsarray); | 4236 set_current_block(if_jsarray); |
| 4226 HInstruction* length; | 4237 HInstruction* length; |
| 4227 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck)); | 4238 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck)); |
| 4228 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4239 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4229 access = AddInstruction(BuildFastElementAccess( | 4240 access = AddInstruction(BuildFastElementAccess( |
| 4230 elements, checked_key, val, elements_kind, is_store)); | 4241 elements, checked_key, val, elements_kind, is_store)); |
| 4231 if (!is_store) { | 4242 if (!is_store) { |
| 4232 Push(access); | 4243 Push(access); |
| 4233 } | 4244 } |
| 4234 | 4245 |
| 4235 *has_side_effects |= access->HasSideEffects(); | 4246 *has_side_effects |= access->HasObservableSideEffects(); |
| 4236 if (position != -1) { | 4247 if (position != -1) { |
| 4237 access->set_position(position); | 4248 access->set_position(position); |
| 4238 } | 4249 } |
| 4239 if_jsarray->Goto(join); | 4250 if_jsarray->Goto(join); |
| 4240 | 4251 |
| 4241 set_current_block(if_fastobject); | 4252 set_current_block(if_fastobject); |
| 4242 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4253 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 4243 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4254 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4244 access = AddInstruction(BuildFastElementAccess( | 4255 access = AddInstruction(BuildFastElementAccess( |
| 4245 elements, checked_key, val, elements_kind, is_store)); | 4256 elements, checked_key, val, elements_kind, is_store)); |
| 4246 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 4257 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
| 4247 if (is_store) { | 4258 if (is_store) { |
| 4248 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 4259 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| 4249 } else { | 4260 } else { |
| 4250 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 4261 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
| 4251 } | 4262 } |
| 4252 } else { // External array elements. | 4263 } else { // External array elements. |
| 4253 access = AddInstruction(BuildExternalArrayElementAccess( | 4264 access = AddInstruction(BuildExternalArrayElementAccess( |
| 4254 external_elements, checked_key, val, elements_kind, is_store)); | 4265 external_elements, checked_key, val, elements_kind, is_store)); |
| 4255 } | 4266 } |
| 4256 *has_side_effects |= access->HasSideEffects(); | 4267 *has_side_effects |= access->HasObservableSideEffects(); |
| 4257 access->set_position(position); | 4268 access->set_position(position); |
| 4258 if (!is_store) { | 4269 if (!is_store) { |
| 4259 Push(access); | 4270 Push(access); |
| 4260 } | 4271 } |
| 4261 current_block()->Goto(join); | 4272 current_block()->Goto(join); |
| 4262 set_current_block(if_false); | 4273 set_current_block(if_false); |
| 4263 } | 4274 } |
| 4264 } | 4275 } |
| 4265 | 4276 |
| 4266 // Deopt if none of the cases matched. | 4277 // Deopt if none of the cases matched. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 4291 obj, key, val, expr, ast_id, position, is_store, has_side_effects); | 4302 obj, key, val, expr, ast_id, position, is_store, has_side_effects); |
| 4292 } else { | 4303 } else { |
| 4293 if (is_store) { | 4304 if (is_store) { |
| 4294 instr = BuildStoreKeyedGeneric(obj, key, val); | 4305 instr = BuildStoreKeyedGeneric(obj, key, val); |
| 4295 } else { | 4306 } else { |
| 4296 instr = BuildLoadKeyedGeneric(obj, key); | 4307 instr = BuildLoadKeyedGeneric(obj, key); |
| 4297 } | 4308 } |
| 4298 } | 4309 } |
| 4299 instr->set_position(position); | 4310 instr->set_position(position); |
| 4300 AddInstruction(instr); | 4311 AddInstruction(instr); |
| 4301 *has_side_effects = instr->HasSideEffects(); | 4312 *has_side_effects = instr->HasObservableSideEffects(); |
| 4302 return instr; | 4313 return instr; |
| 4303 } | 4314 } |
| 4304 | 4315 |
| 4305 | 4316 |
| 4306 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 4317 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
| 4307 HValue* key, | 4318 HValue* key, |
| 4308 HValue* value) { | 4319 HValue* value) { |
| 4309 HValue* context = environment()->LookupContext(); | 4320 HValue* context = environment()->LookupContext(); |
| 4310 return new(zone()) HStoreKeyedGeneric( | 4321 return new(zone()) HStoreKeyedGeneric( |
| 4311 context, | 4322 context, |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4884 } else if (exponent == -0.5) { | 4895 } else if (exponent == -0.5) { |
| 4885 HConstant* double_one = | 4896 HConstant* double_one = |
| 4886 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 4897 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), |
| 4887 Representation::Double()); | 4898 Representation::Double()); |
| 4888 AddInstruction(double_one); | 4899 AddInstruction(double_one); |
| 4889 HUnaryMathOperation* square_root = | 4900 HUnaryMathOperation* square_root = |
| 4890 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); | 4901 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); |
| 4891 AddInstruction(square_root); | 4902 AddInstruction(square_root); |
| 4892 // MathPowHalf doesn't have side effects so there's no need for | 4903 // MathPowHalf doesn't have side effects so there's no need for |
| 4893 // an environment simulation here. | 4904 // an environment simulation here. |
| 4894 ASSERT(!square_root->HasSideEffects()); | 4905 ASSERT(!square_root->HasObservableSideEffects()); |
| 4895 result = new(zone()) HDiv(context, double_one, square_root); | 4906 result = new(zone()) HDiv(context, double_one, square_root); |
| 4896 } else if (exponent == 2.0) { | 4907 } else if (exponent == 2.0) { |
| 4897 result = new(zone()) HMul(context, left, left); | 4908 result = new(zone()) HMul(context, left, left); |
| 4898 } | 4909 } |
| 4899 } else if (right->IsConstant() && | 4910 } else if (right->IsConstant() && |
| 4900 HConstant::cast(right)->HasInteger32Value() && | 4911 HConstant::cast(right)->HasInteger32Value() && |
| 4901 HConstant::cast(right)->Integer32Value() == 2) { | 4912 HConstant::cast(right)->Integer32Value() == 2) { |
| 4902 result = new(zone()) HMul(context, left, left); | 4913 result = new(zone()) HMul(context, left, left); |
| 4903 } | 4914 } |
| 4904 | 4915 |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5468 if (var == info()->scope()->parameter(i)) { | 5479 if (var == info()->scope()->parameter(i)) { |
| 5469 return Bailout("assignment to parameter in arguments object"); | 5480 return Bailout("assignment to parameter in arguments object"); |
| 5470 } | 5481 } |
| 5471 } | 5482 } |
| 5472 } | 5483 } |
| 5473 | 5484 |
| 5474 HValue* context = BuildContextChainWalk(var); | 5485 HValue* context = BuildContextChainWalk(var); |
| 5475 HStoreContextSlot* instr = | 5486 HStoreContextSlot* instr = |
| 5476 new(zone()) HStoreContextSlot(context, var->index(), after); | 5487 new(zone()) HStoreContextSlot(context, var->index(), after); |
| 5477 AddInstruction(instr); | 5488 AddInstruction(instr); |
| 5478 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 5489 if (instr->HasObservableSideEffects()) { |
| 5490 AddSimulate(expr->AssignmentId()); | |
| 5491 } | |
| 5479 break; | 5492 break; |
| 5480 } | 5493 } |
| 5481 | 5494 |
| 5482 case Variable::LOOKUP: | 5495 case Variable::LOOKUP: |
| 5483 return Bailout("lookup variable in count operation"); | 5496 return Bailout("lookup variable in count operation"); |
| 5484 } | 5497 } |
| 5485 | 5498 |
| 5486 } else { | 5499 } else { |
| 5487 // Argument of the count operation is a property. | 5500 // Argument of the count operation is a property. |
| 5488 ASSERT(prop != NULL); | 5501 ASSERT(prop != NULL); |
| 5489 prop->RecordTypeFeedback(oracle()); | 5502 prop->RecordTypeFeedback(oracle()); |
| 5490 | 5503 |
| 5491 if (prop->key()->IsPropertyName()) { | 5504 if (prop->key()->IsPropertyName()) { |
| 5492 // Named property. | 5505 // Named property. |
| 5493 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 5506 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
| 5494 | 5507 |
| 5495 CHECK_ALIVE(VisitForValue(prop->obj())); | 5508 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5496 HValue* obj = Top(); | 5509 HValue* obj = Top(); |
| 5497 | 5510 |
| 5498 HInstruction* load = NULL; | 5511 HInstruction* load = NULL; |
| 5499 if (prop->IsMonomorphic()) { | 5512 if (prop->IsMonomorphic()) { |
| 5500 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5513 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 5501 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5514 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| 5502 load = BuildLoadNamed(obj, prop, map, name); | 5515 load = BuildLoadNamed(obj, prop, map, name); |
| 5503 } else { | 5516 } else { |
| 5504 load = BuildLoadNamedGeneric(obj, prop); | 5517 load = BuildLoadNamedGeneric(obj, prop); |
| 5505 } | 5518 } |
| 5506 PushAndAdd(load); | 5519 PushAndAdd(load); |
| 5507 if (load->HasSideEffects()) AddSimulate(expr->CountId()); | 5520 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
| 5508 | 5521 |
| 5509 after = BuildIncrement(returns_original_input, expr); | 5522 after = BuildIncrement(returns_original_input, expr); |
| 5510 input = Pop(); | 5523 input = Pop(); |
| 5511 | 5524 |
| 5512 HInstruction* store = BuildStoreNamed(obj, after, prop); | 5525 HInstruction* store = BuildStoreNamed(obj, after, prop); |
| 5513 AddInstruction(store); | 5526 AddInstruction(store); |
| 5514 | 5527 |
| 5515 // Overwrite the receiver in the bailout environment with the result | 5528 // Overwrite the receiver in the bailout environment with the result |
| 5516 // of the operation, and the placeholder with the original value if | 5529 // of the operation, and the placeholder with the original value if |
| 5517 // necessary. | 5530 // necessary. |
| 5518 environment()->SetExpressionStackAt(0, after); | 5531 environment()->SetExpressionStackAt(0, after); |
| 5519 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 5532 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| 5520 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 5533 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| 5521 | 5534 |
| 5522 } else { | 5535 } else { |
| 5523 // Keyed property. | 5536 // Keyed property. |
| 5524 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 5537 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
| 5525 | 5538 |
| 5526 CHECK_ALIVE(VisitForValue(prop->obj())); | 5539 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5527 CHECK_ALIVE(VisitForValue(prop->key())); | 5540 CHECK_ALIVE(VisitForValue(prop->key())); |
| 5528 HValue* obj = environment()->ExpressionStackAt(1); | 5541 HValue* obj = environment()->ExpressionStackAt(1); |
| 5529 HValue* key = environment()->ExpressionStackAt(0); | 5542 HValue* key = environment()->ExpressionStackAt(0); |
| 5530 | 5543 |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6062 value = graph()->GetConstantHole(); | 6075 value = graph()->GetConstantHole(); |
| 6063 } else { | 6076 } else { |
| 6064 VisitForValue(function); | 6077 VisitForValue(function); |
| 6065 value = Pop(); | 6078 value = Pop(); |
| 6066 } | 6079 } |
| 6067 if (var->IsContextSlot()) { | 6080 if (var->IsContextSlot()) { |
| 6068 HValue* context = environment()->LookupContext(); | 6081 HValue* context = environment()->LookupContext(); |
| 6069 HStoreContextSlot* store = | 6082 HStoreContextSlot* store = |
| 6070 new HStoreContextSlot(context, var->index(), value); | 6083 new HStoreContextSlot(context, var->index(), value); |
| 6071 AddInstruction(store); | 6084 AddInstruction(store); |
| 6072 if (store->HasSideEffects()) AddSimulate(proxy->id()); | 6085 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| 6073 } else { | 6086 } else { |
| 6074 environment()->Bind(var, value); | 6087 environment()->Bind(var, value); |
| 6075 } | 6088 } |
| 6076 } | 6089 } |
| 6077 break; | 6090 break; |
| 6078 case Variable::LOOKUP: | 6091 case Variable::LOOKUP: |
| 6079 return Bailout("unsupported lookup slot in declaration"); | 6092 return Bailout("unsupported lookup slot in declaration"); |
| 6080 } | 6093 } |
| 6081 } | 6094 } |
| 6082 | 6095 |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7008 } | 7021 } |
| 7009 } | 7022 } |
| 7010 | 7023 |
| 7011 #ifdef DEBUG | 7024 #ifdef DEBUG |
| 7012 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7025 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 7013 if (allocator_ != NULL) allocator_->Verify(); | 7026 if (allocator_ != NULL) allocator_->Verify(); |
| 7014 #endif | 7027 #endif |
| 7015 } | 7028 } |
| 7016 | 7029 |
| 7017 } } // namespace v8::internal | 7030 } } // namespace v8::internal |
| OLD | NEW |