| 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 | 931 |
| 932 | 932 |
| 933 // Handles a static call in unoptimized code that has one argument type not | 933 // Handles a static call in unoptimized code that has one argument type not |
| 934 // seen before. Compile the target if necessary and update the ICData. | 934 // seen before. Compile the target if necessary and update the ICData. |
| 935 // Arg0: argument. | 935 // Arg0: argument. |
| 936 // Arg1: IC data object. | 936 // Arg1: IC data object. |
| 937 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) { | 937 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) { |
| 938 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0)); | 938 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 939 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 939 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 940 // IC data for static call is prepopulated with the statically known target. | 940 // IC data for static call is prepopulated with the statically known target. |
| 941 ASSERT(ic_data.NumberOfChecks() == 1); | 941 ASSERT(ic_data.NumberOfChecksIs(1)); |
| 942 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); | 942 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); |
| 943 if (!target.HasCode()) { | 943 if (!target.HasCode()) { |
| 944 const Error& error = | 944 const Error& error = |
| 945 Error::Handle(Compiler::CompileFunction(thread, target)); | 945 Error::Handle(Compiler::CompileFunction(thread, target)); |
| 946 if (!error.IsNull()) { | 946 if (!error.IsNull()) { |
| 947 Exceptions::PropagateError(error); | 947 Exceptions::PropagateError(error); |
| 948 } | 948 } |
| 949 } | 949 } |
| 950 ASSERT(!target.IsNull() && target.HasCode()); | 950 ASSERT(!target.IsNull() && target.HasCode()); |
| 951 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1); | 951 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 963 // Handles a static call in unoptimized code that has two argument types not | 963 // Handles a static call in unoptimized code that has two argument types not |
| 964 // seen before. Compile the target if necessary and update the ICData. | 964 // seen before. Compile the target if necessary and update the ICData. |
| 965 // Arg0: argument 0. | 965 // Arg0: argument 0. |
| 966 // Arg1: argument 1. | 966 // Arg1: argument 1. |
| 967 // Arg2: IC data object. | 967 // Arg2: IC data object. |
| 968 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { | 968 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { |
| 969 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); | 969 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 970 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 970 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 971 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); | 971 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); |
| 972 // IC data for static call is prepopulated with the statically known target. | 972 // IC data for static call is prepopulated with the statically known target. |
| 973 ASSERT(ic_data.NumberOfChecks() > 0); | 973 ASSERT(!ic_data.NumberOfChecksIs(0)); |
| 974 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); | 974 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); |
| 975 if (!target.HasCode()) { | 975 if (!target.HasCode()) { |
| 976 const Error& error = | 976 const Error& error = |
| 977 Error::Handle(Compiler::CompileFunction(thread, target)); | 977 Error::Handle(Compiler::CompileFunction(thread, target)); |
| 978 if (!error.IsNull()) { | 978 if (!error.IsNull()) { |
| 979 Exceptions::PropagateError(error); | 979 Exceptions::PropagateError(error); |
| 980 } | 980 } |
| 981 } | 981 } |
| 982 ASSERT(!target.IsNull() && target.HasCode()); | 982 ASSERT(!target.IsNull() && target.HasCode()); |
| 983 GrowableArray<intptr_t> cids(2); | 983 GrowableArray<intptr_t> cids(2); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 target_function = InlineCacheMissHelper(receiver, descriptor, name); | 1303 target_function = InlineCacheMissHelper(receiver, descriptor, name); |
| 1304 } | 1304 } |
| 1305 if (target_function.IsNull()) { | 1305 if (target_function.IsNull()) { |
| 1306 ASSERT(!FLAG_lazy_dispatchers); | 1306 ASSERT(!FLAG_lazy_dispatchers); |
| 1307 arguments.SetReturn(target_function); | 1307 arguments.SetReturn(target_function); |
| 1308 return; | 1308 return; |
| 1309 } | 1309 } |
| 1310 | 1310 |
| 1311 if (ic_data_or_cache.IsICData()) { | 1311 if (ic_data_or_cache.IsICData()) { |
| 1312 const ICData& ic_data = ICData::Cast(ic_data_or_cache); | 1312 const ICData& ic_data = ICData::Cast(ic_data_or_cache); |
| 1313 const intptr_t number_of_checks = ic_data.NumberOfChecks(); |
| 1313 | 1314 |
| 1314 if ((ic_data.NumberOfChecks() == 0) && | 1315 if (number_of_checks == 0 && !target_function.HasOptionalParameters() && |
| 1315 !target_function.HasOptionalParameters() && | |
| 1316 !Isolate::Current()->compilation_allowed()) { | 1316 !Isolate::Current()->compilation_allowed()) { |
| 1317 // This call site is unlinked: transition to a monomorphic direct call. | 1317 // This call site is unlinked: transition to a monomorphic direct call. |
| 1318 // Note we cannot do this if the target has optional parameters because | 1318 // Note we cannot do this if the target has optional parameters because |
| 1319 // the monomorphic direct call does not load the arguments descriptor. | 1319 // the monomorphic direct call does not load the arguments descriptor. |
| 1320 // We cannot do this if we are still in the middle of precompiling because | 1320 // We cannot do this if we are still in the middle of precompiling because |
| 1321 // the monomorphic case hides an live instance selector from the | 1321 // the monomorphic case hides an live instance selector from the |
| 1322 // treeshaker. | 1322 // treeshaker. |
| 1323 | 1323 |
| 1324 if (!target_function.HasCode()) { | 1324 if (!target_function.HasCode()) { |
| 1325 const Error& error = | 1325 const Error& error = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1338 Code::Handle(zone, caller_frame->LookupDartCode()); | 1338 Code::Handle(zone, caller_frame->LookupDartCode()); |
| 1339 const Code& target_code = | 1339 const Code& target_code = |
| 1340 Code::Handle(zone, target_function.CurrentCode()); | 1340 Code::Handle(zone, target_function.CurrentCode()); |
| 1341 const Smi& expected_cid = | 1341 const Smi& expected_cid = |
| 1342 Smi::Handle(zone, Smi::New(receiver.GetClassId())); | 1342 Smi::Handle(zone, Smi::New(receiver.GetClassId())); |
| 1343 | 1343 |
| 1344 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, | 1344 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, |
| 1345 expected_cid, target_code); | 1345 expected_cid, target_code); |
| 1346 } else { | 1346 } else { |
| 1347 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); | 1347 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); |
| 1348 if (ic_data.NumberOfChecks() > FLAG_max_polymorphic_checks) { | 1348 if (number_of_checks > FLAG_max_polymorphic_checks) { |
| 1349 // Switch to megamorphic call. | 1349 // Switch to megamorphic call. |
| 1350 const MegamorphicCache& cache = MegamorphicCache::Handle( | 1350 const MegamorphicCache& cache = MegamorphicCache::Handle( |
| 1351 zone, MegamorphicCacheTable::Lookup(isolate, name, descriptor)); | 1351 zone, MegamorphicCacheTable::Lookup(isolate, name, descriptor)); |
| 1352 DartFrameIterator iterator; | 1352 DartFrameIterator iterator; |
| 1353 StackFrame* miss_function_frame = iterator.NextFrame(); | 1353 StackFrame* miss_function_frame = iterator.NextFrame(); |
| 1354 ASSERT(miss_function_frame->IsDartFrame()); | 1354 ASSERT(miss_function_frame->IsDartFrame()); |
| 1355 StackFrame* caller_frame = iterator.NextFrame(); | 1355 StackFrame* caller_frame = iterator.NextFrame(); |
| 1356 ASSERT(caller_frame->IsDartFrame()); | 1356 ASSERT(caller_frame->IsDartFrame()); |
| 1357 const Code& caller_code = | 1357 const Code& caller_code = |
| 1358 Code::Handle(zone, caller_frame->LookupDartCode()); | 1358 Code::Handle(zone, caller_frame->LookupDartCode()); |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2261 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 2261 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
| 2262 const TypedData& new_data = | 2262 const TypedData& new_data = |
| 2263 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 2263 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
| 2264 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 2264 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
| 2265 typed_data_cell.SetAt(0, new_data); | 2265 typed_data_cell.SetAt(0, new_data); |
| 2266 arguments.SetReturn(new_data); | 2266 arguments.SetReturn(new_data); |
| 2267 } | 2267 } |
| 2268 | 2268 |
| 2269 | 2269 |
| 2270 } // namespace dart | 2270 } // namespace dart |
| OLD | NEW |