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 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 |