Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language.cc (revision 39307) |
| +++ runtime/vm/intermediate_language.cc (working copy) |
| @@ -2391,23 +2391,35 @@ |
| } |
| +static uword TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { |
| + StubCode* stub_code = Isolate::Current()->stub_code(); |
| + switch (kind) { |
| + case Token::kADD: return stub_code->SmiAddInlineCacheEntryPoint(); |
| + case Token::kSUB: return stub_code->SmiSubInlineCacheEntryPoint(); |
| + case Token::kEQ: return stub_code->SmiEqualInlineCacheEntryPoint(); |
| + default: return 0; |
| + } |
| +} |
| + |
| + |
| void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| + Isolate* isolate = compiler->isolate(); |
| const ICData* call_ic_data = NULL; |
| if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { |
| const Array& arguments_descriptor = |
| - Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), |
| - argument_names())); |
| + Array::Handle(isolate, ArgumentsDescriptor::New(ArgumentCount(), |
| + argument_names())); |
| call_ic_data = compiler->GetOrAddInstanceCallICData( |
| deopt_id(), function_name(), arguments_descriptor, |
| checked_argument_count()); |
| } else { |
| - call_ic_data = &ICData::ZoneHandle(ic_data()->raw()); |
| + call_ic_data = &ICData::ZoneHandle(isolate, ic_data()->raw()); |
| } |
| if (compiler->is_optimizing()) { |
| ASSERT(HasICData()); |
| if (ic_data()->NumberOfChecks() > 0) { |
| const ICData& unary_ic_data = |
| - ICData::ZoneHandle(ic_data()->AsUnaryClassChecks()); |
| + ICData::ZoneHandle(isolate, ic_data()->AsUnaryClassChecks()); |
| compiler->GenerateInstanceCall(deopt_id(), |
| token_pos(), |
| ArgumentCount(), |
| @@ -2427,11 +2439,46 @@ |
| compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
| deopt_id(), |
| token_pos()); |
| - compiler->GenerateInstanceCall(deopt_id(), |
| - token_pos(), |
| - ArgumentCount(), |
| - locs(), |
| - *call_ic_data); |
| + bool is_smi_two_args_op = false; |
| + const uword label_address = TwoArgsSmiOpInlineCacheEntry(token_kind()); |
| + if (label_address != 0) { |
|
Cutch
2014/08/15 21:23:28
!= NULL ?
Ivan Posva
2014/08/15 21:32:34
uword is an integer type.
|
| + // We have a dedicated inline cache stub for this operation, add an |
| + // an initial Smi/Smi check with count 0. |
| + ASSERT(call_ic_data->NumArgsTested() == 2); |
| + const String& name = String::Handle(isolate, call_ic_data->target_name()); |
| + const Class& smi_class = Class::Handle(isolate, Smi::Class()); |
| + const Function& smi_op_target = |
| + Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name)); |
| + if (call_ic_data->NumberOfChecks() == 0) { |
| + GrowableArray<intptr_t> class_ids(2); |
| + class_ids.Add(kSmiCid); |
| + class_ids.Add(kSmiCid); |
| + call_ic_data->AddCheck(class_ids, smi_op_target); |
| + // 'AddCheck' sets the initial count to 1. |
| + call_ic_data->SetCountAt(0, 0); |
| + is_smi_two_args_op = true; |
| + } else if (call_ic_data->NumberOfChecks() == 1) { |
| + GrowableArray<intptr_t> class_ids(2); |
| + Function& target = Function::Handle(isolate); |
| + call_ic_data->GetCheckAt(0, &class_ids, &target); |
| + if ((target.raw() == smi_op_target.raw()) && |
| + (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { |
| + is_smi_two_args_op = true; |
| + } |
| + } |
| + } |
| + if (is_smi_two_args_op) { |
| + ASSERT(ArgumentCount() == 2); |
| + ExternalLabel target_label(label_address); |
| + compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(), |
| + deopt_id(), token_pos(), locs()); |
| + } else { |
| + compiler->GenerateInstanceCall(deopt_id(), |
| + token_pos(), |
| + ArgumentCount(), |
| + locs(), |
| + *call_ic_data); |
| + } |
| } |
| } |