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 |