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 |