Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc |
| index ee53c720bc33e2349c786fe03aa3ced02a6bd3c2..8dc704804c721a7acc95e39be83101eb1f8ded9b 100644 |
| --- a/runtime/vm/flow_graph_optimizer.cc |
| +++ b/runtime/vm/flow_graph_optimizer.cc |
| @@ -6,6 +6,7 @@ |
| #include "vm/bit_vector.h" |
| #include "vm/cha.h" |
| +#include "vm/compiler.h" |
| #include "vm/cpu.h" |
| #include "vm/dart_entry.h" |
| #include "vm/exceptions.h" |
| @@ -87,6 +88,34 @@ void FlowGraphOptimizer::ApplyICData() { |
| } |
| +void FlowGraphOptimizer::PopulateWithICData() { |
| + ASSERT(current_iterator_ == NULL); |
| + for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| + BlockEntryInstr* entry = block_order_[i]; |
| + ForwardInstructionIterator it(entry); |
| + current_iterator_ = ⁢ |
|
Florian Schneider
2015/05/21 14:51:05
I don't think you need to use the current_iterator
srdjan
2015/05/21 17:27:07
Done.
|
| + for (; !it.Done(); it.Advance()) { |
| + Instruction* instr = it.Current(); |
| + if (instr->IsInstanceCall()) { |
| + InstanceCallInstr* call = instr->AsInstanceCall(); |
| + if (!call->HasICData()) { |
| + const Array& arguments_descriptor = |
| + Array::Handle(zone(), |
| + ArgumentsDescriptor::New(call->ArgumentCount(), |
| + call->argument_names())); |
| + const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New( |
| + function(), call->function_name(), |
| + arguments_descriptor, call->deopt_id(), |
| + call->checked_argument_count())); |
| + call->set_ic_data(&ic_data); |
| + } |
| + } |
| + } |
| + current_iterator_ = NULL; |
| + } |
| +} |
| + |
| + |
| // Optimize instance calls using cid. This is called after optimizer |
| // converted instance calls to instructions. Any remaining |
| // instance calls are either megamorphic calls, cannot be optimized or |
| @@ -162,12 +191,14 @@ bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { |
| Token::IsBinaryOperator(op_kind)) { |
| // Guess cid: if one of the inputs is a number assume that the other |
| // is a number of same type. |
| - const intptr_t cid_0 = class_ids[0]; |
| - const intptr_t cid_1 = class_ids[1]; |
| - if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { |
| - class_ids[0] = cid_1; |
| - } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { |
| - class_ids[1] = cid_0; |
| + if (Compiler::guess_other_cid()) { |
| + const intptr_t cid_0 = class_ids[0]; |
| + const intptr_t cid_1 = class_ids[1]; |
| + if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { |
| + class_ids[0] = cid_1; |
| + } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { |
| + class_ids[1] = cid_0; |
| + } |
| } |
| } |
| @@ -4169,6 +4200,15 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| } |
| const Token::Kind op_kind = instr->token_kind(); |
| + if (Compiler::always_optimize()) { |
| + // TODO(srdjan): Investigate other attempts, as they are not allowed to |
| + // deoptimize. |
| + if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) { |
|
Florian Schneider
2015/05/21 14:51:05
How do we guarantee that TryInline... does not int
srdjan
2015/05/21 17:27:07
Every check adds a deopt stub in case of failure;
|
| + return; |
| + } |
| + return; |
| + } |
| + |
| // Type test is special as it always gets converted into inlined code. |
| if (Token::IsTypeTestOperator(op_kind)) { |
| ReplaceWithInstanceOf(instr); |