OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 count_(other->count_), | 1103 count_(other->count_), |
1104 present_flags_(other->present_flags_), | 1104 present_flags_(other->present_flags_), |
1105 array_(zone->NewArray<HValueMapListElement>(other->array_size_)), | 1105 array_(zone->NewArray<HValueMapListElement>(other->array_size_)), |
1106 lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)), | 1106 lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)), |
1107 free_list_head_(other->free_list_head_) { | 1107 free_list_head_(other->free_list_head_) { |
1108 memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement)); | 1108 memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement)); |
1109 memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement)); | 1109 memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement)); |
1110 } | 1110 } |
1111 | 1111 |
1112 | 1112 |
1113 void HValueMap::Kill(int flags) { | 1113 void HValueMap::Kill(GVNFlagSet flags) { |
1114 int depends_flags = HValue::ConvertChangesToDependsFlags(flags); | 1114 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(flags); |
1115 if ((present_flags_ & depends_flags) == 0) return; | 1115 if (!present_flags_.ContainsAnyOf(depends_flags)) return; |
1116 present_flags_ = 0; | 1116 present_flags_.RemoveAll(); |
1117 for (int i = 0; i < array_size_; ++i) { | 1117 for (int i = 0; i < array_size_; ++i) { |
1118 HValue* value = array_[i].value; | 1118 HValue* value = array_[i].value; |
1119 if (value != NULL) { | 1119 if (value != NULL) { |
1120 // Clear list of collisions first, so we know if it becomes empty. | 1120 // Clear list of collisions first, so we know if it becomes empty. |
1121 int kept = kNil; // List of kept elements. | 1121 int kept = kNil; // List of kept elements. |
1122 int next; | 1122 int next; |
1123 for (int current = array_[i].next; current != kNil; current = next) { | 1123 for (int current = array_[i].next; current != kNil; current = next) { |
1124 next = lists_[current].next; | 1124 next = lists_[current].next; |
1125 if ((lists_[current].value->flags() & depends_flags) != 0) { | 1125 HValue* value = lists_[current].value; |
| 1126 if (value->gvn_flags().ContainsAnyOf(depends_flags)) { |
1126 // Drop it. | 1127 // Drop it. |
1127 count_--; | 1128 count_--; |
1128 lists_[current].next = free_list_head_; | 1129 lists_[current].next = free_list_head_; |
1129 free_list_head_ = current; | 1130 free_list_head_ = current; |
1130 } else { | 1131 } else { |
1131 // Keep it. | 1132 // Keep it. |
1132 lists_[current].next = kept; | 1133 lists_[current].next = kept; |
1133 kept = current; | 1134 kept = current; |
1134 present_flags_ |= lists_[current].value->flags(); | 1135 present_flags_.Add(value->gvn_flags()); |
1135 } | 1136 } |
1136 } | 1137 } |
1137 array_[i].next = kept; | 1138 array_[i].next = kept; |
1138 | 1139 |
1139 // Now possibly drop directly indexed element. | 1140 // Now possibly drop directly indexed element. |
1140 if ((array_[i].value->flags() & depends_flags) != 0) { // Drop it. | 1141 value = array_[i].value; |
| 1142 if (value->gvn_flags().ContainsAnyOf(depends_flags)) { // Drop it. |
1141 count_--; | 1143 count_--; |
1142 int head = array_[i].next; | 1144 int head = array_[i].next; |
1143 if (head == kNil) { | 1145 if (head == kNil) { |
1144 array_[i].value = NULL; | 1146 array_[i].value = NULL; |
1145 } else { | 1147 } else { |
1146 array_[i].value = lists_[head].value; | 1148 array_[i].value = lists_[head].value; |
1147 array_[i].next = lists_[head].next; | 1149 array_[i].next = lists_[head].next; |
1148 lists_[head].next = free_list_head_; | 1150 lists_[head].next = free_list_head_; |
1149 free_list_head_ = head; | 1151 free_list_head_ = head; |
1150 } | 1152 } |
1151 } else { | 1153 } else { |
1152 present_flags_ |= array_[i].value->flags(); // Keep it. | 1154 present_flags_.Add(value->gvn_flags()); // Keep it. |
1153 } | 1155 } |
1154 } | 1156 } |
1155 } | 1157 } |
1156 } | 1158 } |
1157 | 1159 |
1158 | 1160 |
1159 HValue* HValueMap::Lookup(HValue* value) const { | 1161 HValue* HValueMap::Lookup(HValue* value) const { |
1160 uint32_t hash = static_cast<uint32_t>(value->Hashcode()); | 1162 uint32_t hash = static_cast<uint32_t>(value->Hashcode()); |
1161 uint32_t pos = Bound(hash); | 1163 uint32_t pos = Bound(hash); |
1162 if (array_[pos].value != NULL) { | 1164 if (array_[pos].value != NULL) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 class HGlobalValueNumberer BASE_EMBEDDED { | 1351 class HGlobalValueNumberer BASE_EMBEDDED { |
1350 public: | 1352 public: |
1351 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | 1353 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
1352 : graph_(graph), | 1354 : graph_(graph), |
1353 info_(info), | 1355 info_(info), |
1354 removed_side_effects_(false), | 1356 removed_side_effects_(false), |
1355 block_side_effects_(graph->blocks()->length()), | 1357 block_side_effects_(graph->blocks()->length()), |
1356 loop_side_effects_(graph->blocks()->length()), | 1358 loop_side_effects_(graph->blocks()->length()), |
1357 visited_on_paths_(graph->zone(), graph->blocks()->length()) { | 1359 visited_on_paths_(graph->zone(), graph->blocks()->length()) { |
1358 ASSERT(info->isolate()->heap()->allow_allocation(false)); | 1360 ASSERT(info->isolate()->heap()->allow_allocation(false)); |
1359 block_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1361 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length()); |
1360 loop_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1362 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length()); |
1361 } | 1363 } |
1362 ~HGlobalValueNumberer() { | 1364 ~HGlobalValueNumberer() { |
1363 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); | 1365 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); |
1364 } | 1366 } |
1365 | 1367 |
1366 // Returns true if values with side effects are removed. | 1368 // Returns true if values with side effects are removed. |
1367 bool Analyze(); | 1369 bool Analyze(); |
1368 | 1370 |
1369 private: | 1371 private: |
1370 int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator, | 1372 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( |
1371 HBasicBlock* dominated); | 1373 HBasicBlock* dominator, |
| 1374 HBasicBlock* dominated); |
1372 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); | 1375 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); |
1373 void ComputeBlockSideEffects(); | 1376 void ComputeBlockSideEffects(); |
1374 void LoopInvariantCodeMotion(); | 1377 void LoopInvariantCodeMotion(); |
1375 void ProcessLoopBlock(HBasicBlock* block, | 1378 void ProcessLoopBlock(HBasicBlock* block, |
1376 HBasicBlock* before_loop, | 1379 HBasicBlock* before_loop, |
1377 int loop_kills); | 1380 GVNFlagSet loop_kills); |
1378 bool AllowCodeMotion(); | 1381 bool AllowCodeMotion(); |
1379 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1382 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
1380 | 1383 |
1381 HGraph* graph() { return graph_; } | 1384 HGraph* graph() { return graph_; } |
1382 CompilationInfo* info() { return info_; } | 1385 CompilationInfo* info() { return info_; } |
1383 Zone* zone() { return graph_->zone(); } | 1386 Zone* zone() { return graph_->zone(); } |
1384 | 1387 |
1385 HGraph* graph_; | 1388 HGraph* graph_; |
1386 CompilationInfo* info_; | 1389 CompilationInfo* info_; |
1387 bool removed_side_effects_; | 1390 bool removed_side_effects_; |
1388 | 1391 |
1389 // A map of block IDs to their side effects. | 1392 // A map of block IDs to their side effects. |
1390 ZoneList<int> block_side_effects_; | 1393 ZoneList<GVNFlagSet> block_side_effects_; |
1391 | 1394 |
1392 // A map of loop header block IDs to their loop's side effects. | 1395 // A map of loop header block IDs to their loop's side effects. |
1393 ZoneList<int> loop_side_effects_; | 1396 ZoneList<GVNFlagSet> loop_side_effects_; |
1394 | 1397 |
1395 // Used when collecting side effects on paths from dominator to | 1398 // Used when collecting side effects on paths from dominator to |
1396 // dominated. | 1399 // dominated. |
1397 SparseSet visited_on_paths_; | 1400 SparseSet visited_on_paths_; |
1398 }; | 1401 }; |
1399 | 1402 |
1400 | 1403 |
1401 bool HGlobalValueNumberer::Analyze() { | 1404 bool HGlobalValueNumberer::Analyze() { |
1402 ComputeBlockSideEffects(); | 1405 ComputeBlockSideEffects(); |
1403 if (FLAG_loop_invariant_code_motion) { | 1406 if (FLAG_loop_invariant_code_motion) { |
1404 LoopInvariantCodeMotion(); | 1407 LoopInvariantCodeMotion(); |
1405 } | 1408 } |
1406 HValueMap* map = new(zone()) HValueMap(); | 1409 HValueMap* map = new(zone()) HValueMap(); |
1407 AnalyzeBlock(graph_->entry_block(), map); | 1410 AnalyzeBlock(graph_->entry_block(), map); |
1408 return removed_side_effects_; | 1411 return removed_side_effects_; |
1409 } | 1412 } |
1410 | 1413 |
1411 | 1414 |
1412 void HGlobalValueNumberer::ComputeBlockSideEffects() { | 1415 void HGlobalValueNumberer::ComputeBlockSideEffects() { |
1413 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { | 1416 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { |
1414 // Compute side effects for the block. | 1417 // Compute side effects for the block. |
1415 HBasicBlock* block = graph_->blocks()->at(i); | 1418 HBasicBlock* block = graph_->blocks()->at(i); |
1416 HInstruction* instr = block->first(); | 1419 HInstruction* instr = block->first(); |
1417 int id = block->block_id(); | 1420 int id = block->block_id(); |
1418 int side_effects = 0; | 1421 GVNFlagSet side_effects; |
1419 while (instr != NULL) { | 1422 while (instr != NULL) { |
1420 side_effects |= instr->ChangesFlags(); | 1423 side_effects.Add(instr->ChangesFlags()); |
1421 instr = instr->next(); | 1424 instr = instr->next(); |
1422 } | 1425 } |
1423 block_side_effects_[id] |= side_effects; | 1426 block_side_effects_[id].Add(side_effects); |
1424 | 1427 |
1425 // Loop headers are part of their loop. | 1428 // Loop headers are part of their loop. |
1426 if (block->IsLoopHeader()) { | 1429 if (block->IsLoopHeader()) { |
1427 loop_side_effects_[id] |= side_effects; | 1430 loop_side_effects_[id].Add(side_effects); |
1428 } | 1431 } |
1429 | 1432 |
1430 // Propagate loop side effects upwards. | 1433 // Propagate loop side effects upwards. |
1431 if (block->HasParentLoopHeader()) { | 1434 if (block->HasParentLoopHeader()) { |
1432 int header_id = block->parent_loop_header()->block_id(); | 1435 int header_id = block->parent_loop_header()->block_id(); |
1433 loop_side_effects_[header_id] |= | 1436 loop_side_effects_[header_id].Add(block->IsLoopHeader() |
1434 block->IsLoopHeader() ? loop_side_effects_[id] : side_effects; | 1437 ? loop_side_effects_[id] |
| 1438 : side_effects); |
1435 } | 1439 } |
1436 } | 1440 } |
1437 } | 1441 } |
1438 | 1442 |
1439 | 1443 |
1440 void HGlobalValueNumberer::LoopInvariantCodeMotion() { | 1444 void HGlobalValueNumberer::LoopInvariantCodeMotion() { |
1441 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { | 1445 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { |
1442 HBasicBlock* block = graph_->blocks()->at(i); | 1446 HBasicBlock* block = graph_->blocks()->at(i); |
1443 if (block->IsLoopHeader()) { | 1447 if (block->IsLoopHeader()) { |
1444 int side_effects = loop_side_effects_[block->block_id()]; | 1448 GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; |
1445 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", | 1449 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", |
1446 block->block_id(), | 1450 block->block_id(), |
1447 side_effects); | 1451 side_effects.ToIntegral()); |
1448 | 1452 |
1449 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); | 1453 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); |
1450 for (int j = block->block_id(); j <= last->block_id(); ++j) { | 1454 for (int j = block->block_id(); j <= last->block_id(); ++j) { |
1451 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects); | 1455 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects); |
1452 } | 1456 } |
1453 } | 1457 } |
1454 } | 1458 } |
1455 } | 1459 } |
1456 | 1460 |
1457 | 1461 |
1458 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block, | 1462 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block, |
1459 HBasicBlock* loop_header, | 1463 HBasicBlock* loop_header, |
1460 int loop_kills) { | 1464 GVNFlagSet loop_kills) { |
1461 HBasicBlock* pre_header = loop_header->predecessors()->at(0); | 1465 HBasicBlock* pre_header = loop_header->predecessors()->at(0); |
1462 int depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); | 1466 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); |
1463 TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", | 1467 TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", |
1464 block->block_id(), | 1468 block->block_id(), |
1465 depends_flags); | 1469 depends_flags.ToIntegral()); |
1466 HInstruction* instr = block->first(); | 1470 HInstruction* instr = block->first(); |
1467 while (instr != NULL) { | 1471 while (instr != NULL) { |
1468 HInstruction* next = instr->next(); | 1472 HInstruction* next = instr->next(); |
1469 if (instr->CheckFlag(HValue::kUseGVN) && | 1473 if (instr->CheckFlag(HValue::kUseGVN) && |
1470 (instr->flags() & depends_flags) == 0) { | 1474 !instr->gvn_flags().ContainsAnyOf(depends_flags)) { |
1471 TraceGVN("Checking instruction %d (%s)\n", | 1475 TraceGVN("Checking instruction %d (%s)\n", |
1472 instr->id(), | 1476 instr->id(), |
1473 instr->Mnemonic()); | 1477 instr->Mnemonic()); |
1474 bool inputs_loop_invariant = true; | 1478 bool inputs_loop_invariant = true; |
1475 for (int i = 0; i < instr->OperandCount(); ++i) { | 1479 for (int i = 0; i < instr->OperandCount(); ++i) { |
1476 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { | 1480 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { |
1477 inputs_loop_invariant = false; | 1481 inputs_loop_invariant = false; |
1478 } | 1482 } |
1479 } | 1483 } |
1480 | 1484 |
(...skipping 15 matching lines...) Expand all Loading... |
1496 | 1500 |
1497 | 1501 |
1498 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, | 1502 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, |
1499 HBasicBlock* loop_header) { | 1503 HBasicBlock* loop_header) { |
1500 // If we've disabled code motion or we're in a block that unconditionally | 1504 // If we've disabled code motion or we're in a block that unconditionally |
1501 // deoptimizes, don't move any instructions. | 1505 // deoptimizes, don't move any instructions. |
1502 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); | 1506 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); |
1503 } | 1507 } |
1504 | 1508 |
1505 | 1509 |
1506 int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( | 1510 GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( |
1507 HBasicBlock* dominator, HBasicBlock* dominated) { | 1511 HBasicBlock* dominator, HBasicBlock* dominated) { |
1508 int side_effects = 0; | 1512 GVNFlagSet side_effects; |
1509 for (int i = 0; i < dominated->predecessors()->length(); ++i) { | 1513 for (int i = 0; i < dominated->predecessors()->length(); ++i) { |
1510 HBasicBlock* block = dominated->predecessors()->at(i); | 1514 HBasicBlock* block = dominated->predecessors()->at(i); |
1511 if (dominator->block_id() < block->block_id() && | 1515 if (dominator->block_id() < block->block_id() && |
1512 block->block_id() < dominated->block_id() && | 1516 block->block_id() < dominated->block_id() && |
1513 visited_on_paths_.Add(block->block_id())) { | 1517 visited_on_paths_.Add(block->block_id())) { |
1514 side_effects |= block_side_effects_[block->block_id()]; | 1518 side_effects.Add(block_side_effects_[block->block_id()]); |
1515 if (block->IsLoopHeader()) { | 1519 if (block->IsLoopHeader()) { |
1516 side_effects |= loop_side_effects_[block->block_id()]; | 1520 side_effects.Add(loop_side_effects_[block->block_id()]); |
1517 } | 1521 } |
1518 side_effects |= CollectSideEffectsOnPathsToDominatedBlock( | 1522 side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock( |
1519 dominator, block); | 1523 dominator, block)); |
1520 } | 1524 } |
1521 } | 1525 } |
1522 return side_effects; | 1526 return side_effects; |
1523 } | 1527 } |
1524 | 1528 |
1525 | 1529 |
1526 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { | 1530 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { |
1527 TraceGVN("Analyzing block B%d%s\n", | 1531 TraceGVN("Analyzing block B%d%s\n", |
1528 block->block_id(), | 1532 block->block_id(), |
1529 block->IsLoopHeader() ? " (loop header)" : ""); | 1533 block->IsLoopHeader() ? " (loop header)" : ""); |
1530 | 1534 |
1531 // If this is a loop header kill everything killed by the loop. | 1535 // If this is a loop header kill everything killed by the loop. |
1532 if (block->IsLoopHeader()) { | 1536 if (block->IsLoopHeader()) { |
1533 map->Kill(loop_side_effects_[block->block_id()]); | 1537 map->Kill(loop_side_effects_[block->block_id()]); |
1534 } | 1538 } |
1535 | 1539 |
1536 // Go through all instructions of the current block. | 1540 // Go through all instructions of the current block. |
1537 HInstruction* instr = block->first(); | 1541 HInstruction* instr = block->first(); |
1538 while (instr != NULL) { | 1542 while (instr != NULL) { |
1539 HInstruction* next = instr->next(); | 1543 HInstruction* next = instr->next(); |
1540 int flags = instr->ChangesFlags(); | 1544 GVNFlagSet flags = instr->ChangesFlags(); |
1541 if (flags != 0) { | 1545 if (!flags.IsEmpty()) { |
1542 // Clear all instructions in the map that are affected by side effects. | 1546 // Clear all instructions in the map that are affected by side effects. |
1543 map->Kill(flags); | 1547 map->Kill(flags); |
1544 TraceGVN("Instruction %d kills\n", instr->id()); | 1548 TraceGVN("Instruction %d kills\n", instr->id()); |
1545 } | 1549 } |
1546 if (instr->CheckFlag(HValue::kUseGVN)) { | 1550 if (instr->CheckFlag(HValue::kUseGVN)) { |
1547 ASSERT(!instr->HasObservableSideEffects()); | 1551 ASSERT(!instr->HasObservableSideEffects()); |
1548 HValue* other = map->Lookup(instr); | 1552 HValue* other = map->Lookup(instr); |
1549 if (other != NULL) { | 1553 if (other != NULL) { |
1550 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1554 ASSERT(instr->Equals(other) && other->Equals(instr)); |
1551 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", | 1555 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", |
(...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3590 } else { | 3594 } else { |
3591 offset += FixedArray::kHeaderSize; | 3595 offset += FixedArray::kHeaderSize; |
3592 } | 3596 } |
3593 HStoreNamedField* instr = | 3597 HStoreNamedField* instr = |
3594 new(zone()) HStoreNamedField(object, name, value, is_in_object, offset); | 3598 new(zone()) HStoreNamedField(object, name, value, is_in_object, offset); |
3595 if (lookup->type() == MAP_TRANSITION) { | 3599 if (lookup->type() == MAP_TRANSITION) { |
3596 Handle<Map> transition(lookup->GetTransitionMapFromMap(*type)); | 3600 Handle<Map> transition(lookup->GetTransitionMapFromMap(*type)); |
3597 instr->set_transition(transition); | 3601 instr->set_transition(transition); |
3598 // TODO(fschneider): Record the new map type of the object in the IR to | 3602 // TODO(fschneider): Record the new map type of the object in the IR to |
3599 // enable elimination of redundant checks after the transition store. | 3603 // enable elimination of redundant checks after the transition store. |
3600 instr->SetFlag(HValue::kChangesMaps); | 3604 instr->SetGVNFlag(kChangesMaps); |
3601 } | 3605 } |
3602 return instr; | 3606 return instr; |
3603 } | 3607 } |
3604 | 3608 |
3605 | 3609 |
3606 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, | 3610 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, |
3607 Handle<String> name, | 3611 Handle<String> name, |
3608 HValue* value) { | 3612 HValue* value) { |
3609 HValue* context = environment()->LookupContext(); | 3613 HValue* context = environment()->LookupContext(); |
3610 return new(zone()) HStoreNamedGeneric( | 3614 return new(zone()) HStoreNamedGeneric( |
(...skipping 3797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7408 } | 7412 } |
7409 } | 7413 } |
7410 | 7414 |
7411 #ifdef DEBUG | 7415 #ifdef DEBUG |
7412 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7416 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
7413 if (allocator_ != NULL) allocator_->Verify(); | 7417 if (allocator_ != NULL) allocator_->Verify(); |
7414 #endif | 7418 #endif |
7415 } | 7419 } |
7416 | 7420 |
7417 } } // namespace v8::internal | 7421 } } // namespace v8::internal |
OLD | NEW |