| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 return succ_state->Merge(succ_block, pred_state, pred_block, zone); | 130 return succ_state->Merge(succ_block, pred_state, pred_block, zone); |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Support for global analysis with HFlowEngine: Given state merged with all | 134 // Support for global analysis with HFlowEngine: Given state merged with all |
| 135 // the other incoming states, prepare it for use. | 135 // the other incoming states, prepare it for use. |
| 136 static HCheckTable* Finish(HCheckTable* state, HBasicBlock* block, | 136 static HCheckTable* Finish(HCheckTable* state, HBasicBlock* block, |
| 137 Zone* zone) { | 137 Zone* zone) { |
| 138 if (state == NULL) { | 138 if (state == NULL) { |
| 139 block->MarkUnreachable(); | 139 block->MarkUnreachable(); |
| 140 } else if (block->IsUnreachable()) { |
| 141 state = NULL; |
| 142 } |
| 143 if (FLAG_trace_check_elimination) { |
| 144 PrintF("Processing B%d, checkmaps-table:\n", block->block_id()); |
| 145 Print(state); |
| 140 } | 146 } |
| 141 return state; | 147 return state; |
| 142 } | 148 } |
| 143 | 149 |
| 144 private: | 150 private: |
| 145 // Copy state to successor block. | 151 // Copy state to successor block. |
| 146 HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone* zone) { | 152 HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone* zone) { |
| 147 HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_); | 153 HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_); |
| 148 for (int i = 0; i < size_; i++) { | 154 for (int i = 0; i < size_; i++) { |
| 149 HCheckTableEntry* old_entry = &entries_[i]; | 155 HCheckTableEntry* old_entry = &entries_[i]; |
| 156 ASSERT(old_entry->maps_->size() > 0); |
| 150 HCheckTableEntry* new_entry = ©->entries_[i]; | 157 HCheckTableEntry* new_entry = ©->entries_[i]; |
| 151 new_entry->object_ = old_entry->object_; | 158 new_entry->object_ = old_entry->object_; |
| 152 new_entry->maps_ = old_entry->maps_->Copy(phase_->zone()); | 159 new_entry->maps_ = old_entry->maps_->Copy(phase_->zone()); |
| 153 // Keep the check if the existing check's block dominates the successor. | 160 // Keep the check if the existing check's block dominates the successor. |
| 154 if (old_entry->check_ != NULL && | 161 if (old_entry->check_ != NULL && |
| 155 old_entry->check_->block()->Dominates(succ)) { | 162 old_entry->check_->block()->Dominates(succ)) { |
| 156 new_entry->check_ = old_entry->check_; | 163 new_entry->check_ = old_entry->check_; |
| 157 } else { | 164 } else { |
| 158 // Leave it NULL till we meet a new check instruction for this object | 165 // Leave it NULL till we meet a new check instruction for this object |
| 159 // in the control flow. | 166 // in the control flow. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 learned = true; | 236 learned = true; |
| 230 } | 237 } |
| 231 // Learning on false branches requires storing negative facts. | 238 // Learning on false branches requires storing negative facts. |
| 232 } | 239 } |
| 233 | 240 |
| 234 if (FLAG_trace_check_elimination) { | 241 if (FLAG_trace_check_elimination) { |
| 235 PrintF("B%d checkmaps-table %s from B%d:\n", | 242 PrintF("B%d checkmaps-table %s from B%d:\n", |
| 236 succ->block_id(), | 243 succ->block_id(), |
| 237 learned ? "learned" : "copied", | 244 learned ? "learned" : "copied", |
| 238 from_block->block_id()); | 245 from_block->block_id()); |
| 239 copy->Print(); | 246 Print(copy); |
| 240 } | 247 } |
| 241 | 248 |
| 242 return copy; | 249 return copy; |
| 243 } | 250 } |
| 244 | 251 |
| 245 // Merge this state with the other incoming state. | 252 // Merge this state with the other incoming state. |
| 246 HCheckTable* Merge(HBasicBlock* succ, HCheckTable* that, | 253 HCheckTable* Merge(HBasicBlock* succ, HCheckTable* that, |
| 247 HBasicBlock* pred_block, Zone* zone) { | 254 HBasicBlock* pred_block, Zone* zone) { |
| 248 if (that->size_ == 0) { | 255 if (that->size_ == 0) { |
| 249 // If the other state is empty, simply reset. | 256 // If the other state is empty, simply reset. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 276 } | 283 } |
| 277 ASSERT(this_entry->maps_->size() > 0); | 284 ASSERT(this_entry->maps_->size() > 0); |
| 278 } | 285 } |
| 279 } | 286 } |
| 280 if (compact) Compact(); | 287 if (compact) Compact(); |
| 281 } | 288 } |
| 282 | 289 |
| 283 if (FLAG_trace_check_elimination) { | 290 if (FLAG_trace_check_elimination) { |
| 284 PrintF("B%d checkmaps-table merged with B%d table:\n", | 291 PrintF("B%d checkmaps-table merged with B%d table:\n", |
| 285 succ->block_id(), pred_block->block_id()); | 292 succ->block_id(), pred_block->block_id()); |
| 286 Print(); | 293 Print(this); |
| 287 } | 294 } |
| 288 return this; | 295 return this; |
| 289 } | 296 } |
| 290 | 297 |
| 291 void ReduceCheckMaps(HCheckMaps* instr) { | 298 void ReduceCheckMaps(HCheckMaps* instr) { |
| 292 HValue* object = instr->value()->ActualValue(); | 299 HValue* object = instr->value()->ActualValue(); |
| 293 HCheckTableEntry* entry = Find(object); | 300 HCheckTableEntry* entry = Find(object); |
| 294 if (entry != NULL) { | 301 if (entry != NULL) { |
| 295 // entry found; | 302 // entry found; |
| 296 MapSet a = entry->maps_; | 303 MapSet a = entry->maps_; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 instr->id(), instr->block()->block_id(), entry->check_->id())); | 346 instr->id(), instr->block()->block_id(), entry->check_->id())); |
| 340 instr->DeleteAndReplaceWith(entry->check_); | 347 instr->DeleteAndReplaceWith(entry->check_); |
| 341 } else { | 348 } else { |
| 342 TRACE(("CheckMaps #%d at B%d narrowed\n", instr->id(), | 349 TRACE(("CheckMaps #%d at B%d narrowed\n", instr->id(), |
| 343 instr->block()->block_id())); | 350 instr->block()->block_id())); |
| 344 instr->set_map_set(intersection, graph->zone()); | 351 instr->set_map_set(intersection, graph->zone()); |
| 345 entry->check_ = instr; | 352 entry->check_ = instr; |
| 346 } | 353 } |
| 347 | 354 |
| 348 if (FLAG_trace_check_elimination) { | 355 if (FLAG_trace_check_elimination) { |
| 349 Print(); | 356 Print(this); |
| 350 } | 357 } |
| 351 INC_STAT(narrowed_); | 358 INC_STAT(narrowed_); |
| 352 } | 359 } |
| 353 } | 360 } |
| 354 } else { | 361 } else { |
| 355 // No entry; insert a new one. | 362 // No entry; insert a new one. |
| 356 Insert(object, instr, instr->map_set().Copy(phase_->zone())); | 363 Insert(object, instr, instr->map_set().Copy(phase_->zone())); |
| 357 } | 364 } |
| 358 } | 365 } |
| 359 | 366 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 int R = size_ - cursor_; | 540 int R = size_ - cursor_; |
| 534 | 541 |
| 535 OS::MemMove(&tmp_entries[0], &entries_[0], L * sizeof(HCheckTableEntry)); | 542 OS::MemMove(&tmp_entries[0], &entries_[0], L * sizeof(HCheckTableEntry)); |
| 536 OS::MemMove(&entries_[0], &entries_[L], R * sizeof(HCheckTableEntry)); | 543 OS::MemMove(&entries_[0], &entries_[L], R * sizeof(HCheckTableEntry)); |
| 537 OS::MemMove(&entries_[R], &tmp_entries[0], L * sizeof(HCheckTableEntry)); | 544 OS::MemMove(&entries_[R], &tmp_entries[0], L * sizeof(HCheckTableEntry)); |
| 538 } | 545 } |
| 539 | 546 |
| 540 cursor_ = size_; // Move cursor to end. | 547 cursor_ = size_; // Move cursor to end. |
| 541 } | 548 } |
| 542 | 549 |
| 543 void Print() { | 550 static void Print(HCheckTable* table) { |
| 544 for (int i = 0; i < size_; i++) { | 551 if (table == NULL) { |
| 545 HCheckTableEntry* entry = &entries_[i]; | 552 PrintF(" unreachable\n"); |
| 553 return; |
| 554 } |
| 555 |
| 556 for (int i = 0; i < table->size_; i++) { |
| 557 HCheckTableEntry* entry = &table->entries_[i]; |
| 546 ASSERT(entry->object_ != NULL); | 558 ASSERT(entry->object_ != NULL); |
| 547 PrintF(" checkmaps-table @%d: %s #%d ", i, | 559 PrintF(" checkmaps-table @%d: %s #%d ", i, |
| 548 entry->object_->IsPhi() ? "phi" : "object", entry->object_->id()); | 560 entry->object_->IsPhi() ? "phi" : "object", entry->object_->id()); |
| 549 if (entry->check_ != NULL) { | 561 if (entry->check_ != NULL) { |
| 550 PrintF("check #%d ", entry->check_->id()); | 562 PrintF("check #%d ", entry->check_->id()); |
| 551 } | 563 } |
| 552 MapSet list = entry->maps_; | 564 MapSet list = entry->maps_; |
| 553 PrintF("%d maps { ", list->size()); | 565 PrintF("%d maps { ", list->size()); |
| 554 for (int j = 0; j < list->size(); j++) { | 566 for (int j = 0; j < list->size(); j++) { |
| 555 if (j > 0) PrintF(", "); | 567 if (j > 0) PrintF(", "); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 PRINT_STAT(removed_cho); | 715 PRINT_STAT(removed_cho); |
| 704 PRINT_STAT(narrowed); | 716 PRINT_STAT(narrowed); |
| 705 PRINT_STAT(loads); | 717 PRINT_STAT(loads); |
| 706 PRINT_STAT(empty); | 718 PRINT_STAT(empty); |
| 707 PRINT_STAT(compares_true); | 719 PRINT_STAT(compares_true); |
| 708 PRINT_STAT(compares_false); | 720 PRINT_STAT(compares_false); |
| 709 PRINT_STAT(transitions); | 721 PRINT_STAT(transitions); |
| 710 } | 722 } |
| 711 | 723 |
| 712 } } // namespace v8::internal | 724 } } // namespace v8::internal |
| OLD | NEW |