| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/constant_propagator.h" | 10 #include "vm/constant_propagator.h" |
| (...skipping 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3259 } | 3259 } |
| 3260 } | 3260 } |
| 3261 #endif | 3261 #endif |
| 3262 | 3262 |
| 3263 | 3263 |
| 3264 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3264 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3265 Zone* zone = compiler->zone(); | 3265 Zone* zone = compiler->zone(); |
| 3266 const ICData* call_ic_data = NULL; | 3266 const ICData* call_ic_data = NULL; |
| 3267 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || | 3267 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || |
| 3268 (ic_data() == NULL)) { | 3268 (ic_data() == NULL)) { |
| 3269 const Array& arguments_descriptor = Array::Handle( | 3269 const Array& arguments_descriptor = |
| 3270 zone, ArgumentsDescriptor::New(ArgumentCount(), argument_names())); | 3270 Array::Handle(zone, GetArgumentsDescriptor()); |
| 3271 call_ic_data = compiler->GetOrAddInstanceCallICData( | 3271 call_ic_data = compiler->GetOrAddInstanceCallICData( |
| 3272 deopt_id(), function_name(), arguments_descriptor, | 3272 deopt_id(), function_name(), arguments_descriptor, |
| 3273 checked_argument_count()); | 3273 checked_argument_count()); |
| 3274 } else { | 3274 } else { |
| 3275 call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw()); | 3275 call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw()); |
| 3276 } | 3276 } |
| 3277 | 3277 |
| 3278 #if !defined(TARGET_ARCH_DBC) | 3278 #if !defined(TARGET_ARCH_DBC) |
| 3279 if (compiler->is_optimizing() && HasICData()) { | 3279 if (compiler->is_optimizing() && HasICData()) { |
| 3280 ASSERT(HasICData()); | 3280 ASSERT(HasICData()); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3350 } | 3350 } |
| 3351 #endif // !defined(TARGET_ARCH_DBC) | 3351 #endif // !defined(TARGET_ARCH_DBC) |
| 3352 } | 3352 } |
| 3353 | 3353 |
| 3354 | 3354 |
| 3355 bool InstanceCallInstr::MatchesCoreName(const String& name) { | 3355 bool InstanceCallInstr::MatchesCoreName(const String& name) { |
| 3356 return function_name().raw() == Library::PrivateCoreLibName(name).raw(); | 3356 return function_name().raw() == Library::PrivateCoreLibName(name).raw(); |
| 3357 } | 3357 } |
| 3358 | 3358 |
| 3359 | 3359 |
| 3360 RawFunction* InstanceCallInstr::ResolveForReceiverClass(const Class& cls) { |
| 3361 const Array& args_desc_array = Array::Handle(GetArgumentsDescriptor()); |
| 3362 ArgumentsDescriptor args_desc(args_desc_array); |
| 3363 return Resolver::ResolveDynamicForReceiverClass(cls, function_name(), |
| 3364 args_desc); |
| 3365 } |
| 3366 |
| 3367 |
| 3360 bool CallTargets::HasSingleRecognizedTarget() const { | 3368 bool CallTargets::HasSingleRecognizedTarget() const { |
| 3361 if (!HasSingleTarget()) return false; | 3369 if (!HasSingleTarget()) return false; |
| 3362 return MethodRecognizer::RecognizeKind(FirstTarget()) != | 3370 return MethodRecognizer::RecognizeKind(FirstTarget()) != |
| 3363 MethodRecognizer::kUnknown; | 3371 MethodRecognizer::kUnknown; |
| 3364 } | 3372 } |
| 3365 | 3373 |
| 3366 | 3374 |
| 3367 bool CallTargets::HasSingleTarget() const { | 3375 bool CallTargets::HasSingleTarget() const { |
| 3368 ASSERT(length() != 0); | 3376 ASSERT(length() != 0); |
| 3369 for (int i = 0; i < length(); i++) { | 3377 for (int i = 0; i < length(); i++) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3415 | 3423 |
| 3416 intptr_t PolymorphicInstanceCallInstr::CallCount() const { | 3424 intptr_t PolymorphicInstanceCallInstr::CallCount() const { |
| 3417 return targets().AggregateCallCount(); | 3425 return targets().AggregateCallCount(); |
| 3418 } | 3426 } |
| 3419 | 3427 |
| 3420 | 3428 |
| 3421 // DBC does not support optimizing compiler and thus doesn't emit | 3429 // DBC does not support optimizing compiler and thus doesn't emit |
| 3422 // PolymorphicInstanceCallInstr. | 3430 // PolymorphicInstanceCallInstr. |
| 3423 #if !defined(TARGET_ARCH_DBC) | 3431 #if !defined(TARGET_ARCH_DBC) |
| 3424 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3432 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3433 ArgumentsInfo args_info(instance_call()->type_args_len(), |
| 3434 instance_call()->ArgumentCount(), |
| 3435 instance_call()->argument_names()); |
| 3425 if (!with_checks()) { | 3436 if (!with_checks()) { |
| 3426 ASSERT(targets().HasSingleTarget()); | 3437 ASSERT(targets().HasSingleTarget()); |
| 3427 const Function& target = targets().FirstTarget(); | 3438 const Function& target = targets().FirstTarget(); |
| 3428 compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), | 3439 compiler->GenerateStaticCall(deopt_id(), instance_call()->token_pos(), |
| 3429 target, instance_call()->ArgumentCount(), | 3440 target, args_info, locs(), ICData::Handle()); |
| 3430 instance_call()->argument_names(), locs(), | |
| 3431 ICData::Handle()); | |
| 3432 return; | 3441 return; |
| 3433 } | 3442 } |
| 3434 | 3443 |
| 3435 compiler->EmitPolymorphicInstanceCall( | 3444 compiler->EmitPolymorphicInstanceCall( |
| 3436 targets_, *instance_call(), instance_call()->ArgumentCount(), | 3445 targets_, *instance_call(), args_info, deopt_id(), |
| 3437 instance_call()->argument_names(), deopt_id(), | |
| 3438 instance_call()->token_pos(), locs(), complete(), total_call_count()); | 3446 instance_call()->token_pos(), locs(), complete(), total_call_count()); |
| 3439 } | 3447 } |
| 3440 #endif | 3448 #endif |
| 3441 | 3449 |
| 3442 | 3450 |
| 3443 RawType* PolymorphicInstanceCallInstr::ComputeRuntimeType( | 3451 RawType* PolymorphicInstanceCallInstr::ComputeRuntimeType( |
| 3444 const CallTargets& targets) { | 3452 const CallTargets& targets) { |
| 3445 bool is_string = true; | 3453 bool is_string = true; |
| 3446 bool is_integer = true; | 3454 bool is_integer = true; |
| 3447 bool is_double = true; | 3455 bool is_double = true; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3543 } | 3551 } |
| 3544 | 3552 |
| 3545 | 3553 |
| 3546 LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone, | 3554 LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone, |
| 3547 bool optimizing) const { | 3555 bool optimizing) const { |
| 3548 return MakeCallSummary(zone); | 3556 return MakeCallSummary(zone); |
| 3549 } | 3557 } |
| 3550 | 3558 |
| 3551 | 3559 |
| 3552 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3560 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3561 Zone* zone = compiler->zone(); |
| 3553 const ICData* call_ic_data = NULL; | 3562 const ICData* call_ic_data = NULL; |
| 3554 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || | 3563 if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || |
| 3555 (ic_data() == NULL)) { | 3564 (ic_data() == NULL)) { |
| 3556 const Array& arguments_descriptor = Array::Handle( | 3565 const Array& arguments_descriptor = |
| 3557 ArgumentsDescriptor::New(ArgumentCount(), argument_names())); | 3566 Array::Handle(zone, GetArgumentsDescriptor()); |
| 3558 MethodRecognizer::Kind recognized_kind = | 3567 MethodRecognizer::Kind recognized_kind = |
| 3559 MethodRecognizer::RecognizeKind(function()); | 3568 MethodRecognizer::RecognizeKind(function()); |
| 3560 int num_args_checked = 0; | 3569 int num_args_checked = 0; |
| 3561 switch (recognized_kind) { | 3570 switch (recognized_kind) { |
| 3562 case MethodRecognizer::kDoubleFromInteger: | 3571 case MethodRecognizer::kDoubleFromInteger: |
| 3563 case MethodRecognizer::kMathMin: | 3572 case MethodRecognizer::kMathMin: |
| 3564 case MethodRecognizer::kMathMax: | 3573 case MethodRecognizer::kMathMax: |
| 3565 num_args_checked = 2; | 3574 num_args_checked = 2; |
| 3566 break; | 3575 break; |
| 3567 default: | 3576 default: |
| 3568 break; | 3577 break; |
| 3569 } | 3578 } |
| 3570 call_ic_data = compiler->GetOrAddStaticCallICData( | 3579 call_ic_data = compiler->GetOrAddStaticCallICData( |
| 3571 deopt_id(), function(), arguments_descriptor, num_args_checked); | 3580 deopt_id(), function(), arguments_descriptor, num_args_checked); |
| 3572 } else { | 3581 } else { |
| 3573 call_ic_data = &ICData::ZoneHandle(ic_data()->raw()); | 3582 call_ic_data = &ICData::ZoneHandle(ic_data()->raw()); |
| 3574 } | 3583 } |
| 3575 | 3584 |
| 3576 #if !defined(TARGET_ARCH_DBC) | 3585 #if !defined(TARGET_ARCH_DBC) |
| 3577 compiler->GenerateStaticCall(deopt_id(), token_pos(), function(), | 3586 ArgumentsInfo args_info(type_args_len(), ArgumentCount(), argument_names()); |
| 3578 ArgumentCount(), argument_names(), locs(), | 3587 compiler->GenerateStaticCall(deopt_id(), token_pos(), function(), args_info, |
| 3579 *call_ic_data); | 3588 locs(), *call_ic_data); |
| 3580 #else | 3589 #else |
| 3581 const Array& arguments_descriptor = | 3590 const Array& arguments_descriptor = Array::Handle( |
| 3582 (ic_data() == NULL) ? Array::Handle(ArgumentsDescriptor::New( | 3591 zone, (ic_data() == NULL) ? GetArgumentsDescriptor() |
| 3583 ArgumentCount(), argument_names())) | 3592 : ic_data()->arguments_descriptor()); |
| 3584 : Array::Handle(ic_data()->arguments_descriptor()); | |
| 3585 const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor); | 3593 const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor); |
| 3586 | 3594 |
| 3587 compiler->AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id(), | 3595 compiler->AddCurrentDescriptor(RawPcDescriptors::kRewind, deopt_id(), |
| 3588 token_pos()); | 3596 token_pos()); |
| 3589 if (compiler->is_optimizing()) { | 3597 if (compiler->is_optimizing()) { |
| 3590 __ PushConstant(function()); | 3598 __ PushConstant(function()); |
| 3591 __ StaticCall(ArgumentCount(), argdesc_kidx); | 3599 __ StaticCall(ArgumentCount(), argdesc_kidx); |
| 3592 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(), | 3600 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(), |
| 3593 token_pos()); | 3601 token_pos()); |
| 3594 compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult); | 3602 compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult); |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3901 return Array::length_offset(); | 3909 return Array::length_offset(); |
| 3902 default: | 3910 default: |
| 3903 UNREACHABLE(); | 3911 UNREACHABLE(); |
| 3904 return -1; | 3912 return -1; |
| 3905 } | 3913 } |
| 3906 } | 3914 } |
| 3907 | 3915 |
| 3908 | 3916 |
| 3909 const Function& StringInterpolateInstr::CallFunction() const { | 3917 const Function& StringInterpolateInstr::CallFunction() const { |
| 3910 if (function_.IsNull()) { | 3918 if (function_.IsNull()) { |
| 3919 const int kTypeArgsLen = 0; |
| 3911 const int kNumberOfArguments = 1; | 3920 const int kNumberOfArguments = 1; |
| 3912 const Array& kNoArgumentNames = Object::null_array(); | 3921 const Array& kNoArgumentNames = Object::null_array(); |
| 3913 const Class& cls = | 3922 const Class& cls = |
| 3914 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); | 3923 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); |
| 3915 ASSERT(!cls.IsNull()); | 3924 ASSERT(!cls.IsNull()); |
| 3916 function_ = Resolver::ResolveStatic( | 3925 function_ = Resolver::ResolveStatic( |
| 3917 cls, Library::PrivateCoreLibName(Symbols::Interpolate()), | 3926 cls, Library::PrivateCoreLibName(Symbols::Interpolate()), kTypeArgsLen, |
| 3918 kNumberOfArguments, kNoArgumentNames); | 3927 kNumberOfArguments, kNoArgumentNames); |
| 3919 } | 3928 } |
| 3920 ASSERT(!function_.IsNull()); | 3929 ASSERT(!function_.IsNull()); |
| 3921 return function_; | 3930 return function_; |
| 3922 } | 3931 } |
| 3923 | 3932 |
| 3924 | 3933 |
| 3925 // Replace StringInterpolateInstr with a constant string if all inputs are | 3934 // Replace StringInterpolateInstr with a constant string if all inputs are |
| 3926 // constant of [string, number, boolean, null]. | 3935 // constant of [string, number, boolean, null]. |
| 3927 // Leave the CreateArrayInstr and StoreIndexedInstr in the stream in case | 3936 // Leave the CreateArrayInstr and StoreIndexedInstr in the stream in case |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4308 "native function '%s' (%" Pd " arguments) cannot be found", | 4317 "native function '%s' (%" Pd " arguments) cannot be found", |
| 4309 native_name().ToCString(), function().NumParameters()); | 4318 native_name().ToCString(), function().NumParameters()); |
| 4310 } | 4319 } |
| 4311 set_is_auto_scope(auto_setup_scope); | 4320 set_is_auto_scope(auto_setup_scope); |
| 4312 set_native_c_function(native_function); | 4321 set_native_c_function(native_function); |
| 4313 } | 4322 } |
| 4314 | 4323 |
| 4315 #undef __ | 4324 #undef __ |
| 4316 | 4325 |
| 4317 } // namespace dart | 4326 } // namespace dart |
| OLD | NEW |