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 void FlowGraph::ComputeIsReceiverRecursive(PhiInstr* phi, | |
377 BitVector* processed) const { | |
378 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) return; | |
379 if (processed->Contains(phi->ssa_temp_index())) return; | |
380 processed->Add(phi->ssa_temp_index()); | |
381 for (intptr_t i = 0; i < phi->InputCount(); ++i) { | |
382 Definition* def = phi->InputAt(i)->definition(); | |
383 if (def->IsParameter() && (def->AsParameter()->index() == 0)) continue; | |
384 if (!def->IsPhi()) { | |
385 phi->set_is_receiver(PhiInstr::kNotReceiver); | |
386 return; | |
387 } | |
388 ComputeIsReceiverRecursive(def->AsPhi(), processed); | |
Vyacheslav Egorov (Google)
2016/03/31 05:00:58
Something is not right here. Imagine situation:
x
Florian Schneider
2016/03/31 17:13:54
You're right. The current way does not the compute
| |
389 if (def->AsPhi()->is_receiver() == PhiInstr::kNotReceiver) { | |
390 phi->set_is_receiver(PhiInstr::kNotReceiver); | |
391 return; | |
392 } | |
393 } | |
394 phi->set_is_receiver(PhiInstr::kReceiver); | |
395 } | |
396 | |
397 | |
398 bool FlowGraph::IsReceiver(Definition* def) const { | |
399 if (def->IsParameter()) return (def->AsParameter()->index() == 0); | |
400 if (!def->IsPhi()) return false; | |
401 PhiInstr* phi = def->AsPhi(); | |
402 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) { | |
403 return (phi->is_receiver() == PhiInstr::kReceiver); | |
404 } | |
405 // Not known if this phi is the receiver yet. Compute it now. | |
406 BitVector* processed = | |
407 new(zone()) BitVector(zone(), max_virtual_register_number()); | |
408 ComputeIsReceiverRecursive(phi, processed); | |
409 return (phi->is_receiver() == PhiInstr::kReceiver); | |
410 } | |
411 | |
412 | |
413 // Use CHA to determine if the call needs a class check: if the callee's | |
414 // receiver is the same as the caller's receiver and there are no overriden | |
415 // callee functions, then no class check is needed. | |
416 bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call, | |
417 RawFunction::Kind kind) const { | |
418 if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) { | |
419 // Even if class or function are private, lazy class finalization | |
420 // may later add overriding methods. | |
421 return true; | |
422 } | |
423 Definition* callee_receiver = call->ArgumentAt(0); | |
424 ASSERT(callee_receiver != NULL); | |
425 if (function().IsDynamicFunction() && IsReceiver(callee_receiver)) { | |
426 const String& name = (kind == RawFunction::kMethodExtractor) | |
427 ? String::Handle(zone(), Field::NameFromGetter(call->function_name())) | |
428 : call->function_name(); | |
429 const Class& cls = Class::Handle(zone(), function().Owner()); | |
430 if (!thread()->cha()->HasOverride(cls, name)) { | |
431 if (FLAG_trace_cha) { | |
432 THR_Print(" **(CHA) Instance call needs no check, " | |
433 "no overrides of '%s' '%s'\n", | |
434 name.ToCString(), cls.ToCString()); | |
435 } | |
436 thread()->cha()->AddToLeafClasses(cls); | |
437 return false; | |
438 } | |
439 } | |
440 return true; | |
441 } | |
442 | |
443 | |
444 | |
375 bool FlowGraph::VerifyUseLists() { | 445 bool FlowGraph::VerifyUseLists() { |
376 // Verify the initial definitions. | 446 // Verify the initial definitions. |
377 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { | 447 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
378 VerifyUseListsInInstruction((*graph_entry_->initial_definitions())[i]); | 448 VerifyUseListsInInstruction((*graph_entry_->initial_definitions())[i]); |
379 } | 449 } |
380 | 450 |
381 // Verify phis in join entries and the instructions in each block. | 451 // Verify phis in join entries and the instructions in each block. |
382 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 452 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
383 BlockEntryInstr* entry = preorder_[i]; | 453 BlockEntryInstr* entry = preorder_[i]; |
384 JoinEntryInstr* join = entry->AsJoinEntry(); | 454 JoinEntryInstr* join = entry->AsJoinEntry(); |
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1973 ReplaceCurrentInstruction(&it, current, replacement); | 2043 ReplaceCurrentInstruction(&it, current, replacement); |
1974 changed = true; | 2044 changed = true; |
1975 } | 2045 } |
1976 } | 2046 } |
1977 } | 2047 } |
1978 return changed; | 2048 return changed; |
1979 } | 2049 } |
1980 | 2050 |
1981 | 2051 |
1982 } // namespace dart | 2052 } // namespace dart |
OLD | NEW |