Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph.h" | 5 #include "vm/flow_graph.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | |
| 8 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/flow_graph_range_analysis.h" | 11 #include "vm/flow_graph_range_analysis.h" |
| 11 #include "vm/il_printer.h" | 12 #include "vm/il_printer.h" |
| 12 #include "vm/intermediate_language.h" | 13 #include "vm/intermediate_language.h" |
| 13 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 14 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 15 | 16 |
| 16 namespace dart { | 17 namespace dart { |
| 17 | 18 |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 ASSERT(instr->IsBlockEntry() || | 366 ASSERT(instr->IsBlockEntry() || |
| 366 (instr->IsPhi() && instr->AsPhi()->is_alive()) || | 367 (instr->IsPhi() && instr->AsPhi()->is_alive()) || |
| 367 (instr->previous() != NULL)); | 368 (instr->previous() != NULL)); |
| 368 prev = curr; | 369 prev = curr; |
| 369 curr = curr->next_use(); | 370 curr = curr->next_use(); |
| 370 } | 371 } |
| 371 } | 372 } |
| 372 } | 373 } |
| 373 | 374 |
| 374 | 375 |
| 376 static bool IsReceiver(Definition* def, BitVector* processed) { | |
| 377 if (def->IsParameter() && (def->AsParameter()->index() == 0)) return true; | |
|
Vyacheslav Egorov (Google)
2016/03/30 16:59:20
Maybe
if (def->IsParameter() return (def->AsParam
Florian Schneider
2016/03/30 21:03:57
Done.
| |
| 378 if (!def->IsPhi()) return false; | |
| 379 PhiInstr* phi = def->AsPhi(); | |
| 380 if (processed->Contains(phi->ssa_temp_index())) return true; | |
| 381 processed->Add(phi->ssa_temp_index()); | |
| 382 for (intptr_t i = 0; i < phi->InputCount(); ++i) { | |
| 383 if (!IsReceiver(phi->InputAt(i)->definition(), processed)) return false; | |
|
Vyacheslav Egorov (Google)
2016/03/30 16:59:20
Please add a comment that we are not reusing proce
Florian Schneider
2016/03/30 21:03:57
Done. Rewrote computation to store the result at e
| |
| 384 } | |
| 385 return true; | |
| 386 } | |
| 387 | |
| 388 | |
| 389 // Use CHA to determine if the call needs a class check: if the callee's | |
| 390 // receiver is the same as the caller's receiver and there are no overriden | |
| 391 // callee functions, then no class check is needed. | |
| 392 bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call, | |
| 393 RawFunction::Kind kind) const { | |
| 394 if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) { | |
| 395 // Even if class or function are private, lazy class finalization | |
| 396 // may later add overriding methods. | |
| 397 return true; | |
| 398 } | |
| 399 Definition* callee_receiver = call->ArgumentAt(0); | |
| 400 ASSERT(callee_receiver != NULL); | |
| 401 if (function().IsDynamicFunction() && | |
| 402 IsReceiver(callee_receiver, | |
|
Vyacheslav Egorov (Google)
2016/03/30 16:59:20
I find it somewhat expensive not only to repeat th
Florian Schneider
2016/03/30 21:03:57
Good point. It should not take extra space anyway.
| |
| 403 new(zone()) BitVector(zone(), | |
| 404 max_virtual_register_number()))) { | |
| 405 const String& name = (kind == RawFunction::kMethodExtractor) | |
| 406 ? String::Handle(zone(), Field::NameFromGetter(call->function_name())) | |
| 407 : call->function_name(); | |
| 408 const Class& cls = Class::Handle(zone(), function().Owner()); | |
| 409 if (!thread()->cha()->HasOverride(cls, name)) { | |
| 410 if (FLAG_trace_cha) { | |
| 411 THR_Print(" **(CHA) Instance call needs no check, " | |
| 412 "no overrides of '%s' '%s'\n", | |
| 413 name.ToCString(), cls.ToCString()); | |
| 414 } | |
| 415 thread()->cha()->AddToLeafClasses(cls); | |
| 416 return false; | |
| 417 } | |
| 418 } | |
| 419 return true; | |
| 420 } | |
| 421 | |
| 422 | |
| 423 | |
| 375 bool FlowGraph::VerifyUseLists() { | 424 bool FlowGraph::VerifyUseLists() { |
| 376 // Verify the initial definitions. | 425 // Verify the initial definitions. |
| 377 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { | 426 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| 378 VerifyUseListsInInstruction((*graph_entry_->initial_definitions())[i]); | 427 VerifyUseListsInInstruction((*graph_entry_->initial_definitions())[i]); |
| 379 } | 428 } |
| 380 | 429 |
| 381 // Verify phis in join entries and the instructions in each block. | 430 // Verify phis in join entries and the instructions in each block. |
| 382 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 431 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 383 BlockEntryInstr* entry = preorder_[i]; | 432 BlockEntryInstr* entry = preorder_[i]; |
| 384 JoinEntryInstr* join = entry->AsJoinEntry(); | 433 JoinEntryInstr* join = entry->AsJoinEntry(); |
| (...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1973 ReplaceCurrentInstruction(&it, current, replacement); | 2022 ReplaceCurrentInstruction(&it, current, replacement); |
| 1974 changed = true; | 2023 changed = true; |
| 1975 } | 2024 } |
| 1976 } | 2025 } |
| 1977 } | 2026 } |
| 1978 return changed; | 2027 return changed; |
| 1979 } | 2028 } |
| 1980 | 2029 |
| 1981 | 2030 |
| 1982 } // namespace dart | 2031 } // namespace dart |
| OLD | NEW |