OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/runtime_entry.h" | 5 #include "vm/runtime_entry.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 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
851 // there is a getter with the same name. If so, invoke it. If the value is | 851 // there is a getter with the same name. If so, invoke it. If the value is |
852 // a closure, invoke it with the given arguments. If the value is a | 852 // a closure, invoke it with the given arguments. If the value is a |
853 // non-closure, attempt to invoke "call" on it. | 853 // non-closure, attempt to invoke "call" on it. |
854 static bool ResolveCallThroughGetter(const Instance& receiver, | 854 static bool ResolveCallThroughGetter(const Instance& receiver, |
855 const Class& receiver_class, | 855 const Class& receiver_class, |
856 const String& target_name, | 856 const String& target_name, |
857 const Array& arguments_descriptor, | 857 const Array& arguments_descriptor, |
858 Function* result) { | 858 Function* result) { |
859 // 1. Check if there is a getter with the same name. | 859 // 1. Check if there is a getter with the same name. |
860 const String& getter_name = String::Handle(Field::GetterName(target_name)); | 860 const String& getter_name = String::Handle(Field::GetterName(target_name)); |
861 const int kTypeArgsLen = 0; | |
861 const int kNumArguments = 1; | 862 const int kNumArguments = 1; |
862 ArgumentsDescriptor args_desc( | 863 ArgumentsDescriptor args_desc( |
863 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 864 Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, kNumArguments))); |
864 const Function& getter = | 865 const Function& getter = |
865 Function::Handle(Resolver::ResolveDynamicForReceiverClass( | 866 Function::Handle(Resolver::ResolveDynamicForReceiverClass( |
866 receiver_class, getter_name, args_desc)); | 867 receiver_class, getter_name, args_desc)); |
867 if (getter.IsNull() || getter.IsMethodExtractor()) { | 868 if (getter.IsNull() || getter.IsMethodExtractor()) { |
868 return false; | 869 return false; |
869 } | 870 } |
870 const Function& target_function = | 871 const Function& target_function = |
871 Function::Handle(receiver_class.GetInvocationDispatcher( | 872 Function::Handle(receiver_class.GetInvocationDispatcher( |
872 target_name, arguments_descriptor, | 873 target_name, arguments_descriptor, |
873 RawFunction::kInvokeFieldDispatcher, FLAG_lazy_dispatchers)); | 874 RawFunction::kInvokeFieldDispatcher, FLAG_lazy_dispatchers)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
923 ObjectStore* store = Isolate::Current()->object_store(); | 924 ObjectStore* store = Isolate::Current()->object_store(); |
924 const Function& target = | 925 const Function& target = |
925 Function::Handle(result ? store->simple_instance_of_true_function() | 926 Function::Handle(result ? store->simple_instance_of_true_function() |
926 : store->simple_instance_of_false_function()); | 927 : store->simple_instance_of_false_function()); |
927 ASSERT(!target.IsNull()); | 928 ASSERT(!target.IsNull()); |
928 return target.raw(); | 929 return target.raw(); |
929 } | 930 } |
930 | 931 |
931 | 932 |
932 static RawFunction* InlineCacheMissHandler( | 933 static RawFunction* InlineCacheMissHandler( |
933 const GrowableArray<const Instance*>& args, | 934 const GrowableArray<const Instance*>& args, // Checked arguments only. |
934 const ICData& ic_data) { | 935 const ICData& ic_data) { |
935 const Instance& receiver = *args[0]; | 936 const Instance& receiver = *args[0]; |
936 ArgumentsDescriptor arguments_descriptor( | 937 ArgumentsDescriptor arguments_descriptor( |
937 Array::Handle(ic_data.arguments_descriptor())); | 938 Array::Handle(ic_data.arguments_descriptor())); |
938 String& function_name = String::Handle(ic_data.target_name()); | 939 String& function_name = String::Handle(ic_data.target_name()); |
939 ASSERT(function_name.IsSymbol()); | 940 ASSERT(function_name.IsSymbol()); |
940 | 941 |
941 Function& target_function = Function::Handle( | 942 Function& target_function = Function::Handle( |
942 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); | 943 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); |
943 | 944 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1137 SingleTargetCache& cache = SingleTargetCache::Handle(zone); | 1138 SingleTargetCache& cache = SingleTargetCache::Handle(zone); |
1138 cache ^= | 1139 cache ^= |
1139 CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code); | 1140 CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code); |
1140 Code& old_target_code = Code::Handle(zone, cache.target()); | 1141 Code& old_target_code = Code::Handle(zone, cache.target()); |
1141 Function& old_target = Function::Handle(zone); | 1142 Function& old_target = Function::Handle(zone); |
1142 old_target ^= old_target_code.owner(); | 1143 old_target ^= old_target_code.owner(); |
1143 | 1144 |
1144 // We lost the original ICData when we patched to the monomorphic case. | 1145 // We lost the original ICData when we patched to the monomorphic case. |
1145 const String& name = String::Handle(zone, old_target.name()); | 1146 const String& name = String::Handle(zone, old_target.name()); |
1146 ASSERT(!old_target.HasOptionalParameters()); | 1147 ASSERT(!old_target.HasOptionalParameters()); |
1147 const Array& descriptor = Array::Handle( | 1148 ASSERT(!old_target.IsGeneric()); |
Vyacheslav Egorov (Google)
2017/05/13 22:20:14
I think to guarantee this assertion we need to hav
regis
2017/05/18 21:02:13
Oops. Done. Thanks.
| |
1148 zone, ArgumentsDescriptor::New(old_target.num_fixed_parameters())); | 1149 const int kTypeArgsLen = 0; |
1150 const Array& descriptor = | |
1151 Array::Handle(zone, ArgumentsDescriptor::New( | |
1152 kTypeArgsLen, old_target.num_fixed_parameters())); | |
1149 const ICData& ic_data = | 1153 const ICData& ic_data = |
1150 ICData::Handle(zone, ICData::New(caller_function, name, descriptor, | 1154 ICData::Handle(zone, ICData::New(caller_function, name, descriptor, |
1151 Thread::kNoDeoptId, 1, /* args_tested */ | 1155 Thread::kNoDeoptId, 1, /* args_tested */ |
1152 false /* static_call */)); | 1156 false /* static_call */)); |
1153 | 1157 |
1154 // Maybe add the new target. | 1158 // Maybe add the new target. |
1155 Class& cls = Class::Handle(zone, receiver.clazz()); | 1159 Class& cls = Class::Handle(zone, receiver.clazz()); |
1156 ArgumentsDescriptor args_desc(descriptor); | 1160 ArgumentsDescriptor args_desc(descriptor); |
1157 Function& target_function = Function::Handle( | 1161 Function& target_function = Function::Handle( |
1158 zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc)); | 1162 zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc)); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1234 zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc)); | 1238 zone, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc)); |
1235 if (target_function.IsNull()) { | 1239 if (target_function.IsNull()) { |
1236 target_function = InlineCacheMissHelper(receiver, descriptor, name); | 1240 target_function = InlineCacheMissHelper(receiver, descriptor, name); |
1237 } | 1241 } |
1238 if (target_function.IsNull()) { | 1242 if (target_function.IsNull()) { |
1239 ASSERT(!FLAG_lazy_dispatchers); | 1243 ASSERT(!FLAG_lazy_dispatchers); |
1240 } else { | 1244 } else { |
1241 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); | 1245 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); |
1242 } | 1246 } |
1243 | 1247 |
1244 if (!target_function.IsNull() && !target_function.HasOptionalParameters()) { | 1248 if (!target_function.IsNull() && !target_function.HasOptionalParameters()) { |
Vyacheslav Egorov (Google)
2017/05/13 22:20:14
I think this needs to check for !target_function.I
regis
2017/05/18 21:02:12
Done.
| |
1245 // Patch to monomorphic call. | 1249 // Patch to monomorphic call. |
1246 ASSERT(target_function.HasCode()); | 1250 ASSERT(target_function.HasCode()); |
1247 const Code& target_code = Code::Handle(zone, target_function.CurrentCode()); | 1251 const Code& target_code = Code::Handle(zone, target_function.CurrentCode()); |
1248 const Smi& expected_cid = | 1252 const Smi& expected_cid = |
1249 Smi::Handle(zone, Smi::New(receiver.GetClassId())); | 1253 Smi::Handle(zone, Smi::New(receiver.GetClassId())); |
1250 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, | 1254 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, |
1251 expected_cid, target_code); | 1255 expected_cid, target_code); |
1252 | 1256 |
1253 // Return the ICData. The miss stub will jump to continue in the IC call | 1257 // Return the ICData. The miss stub will jump to continue in the IC call |
1254 // stub. | 1258 // stub. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1292 old_expected_cid ^= | 1296 old_expected_cid ^= |
1293 CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code); | 1297 CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code); |
1294 const Code& old_target_code = Code::Handle( | 1298 const Code& old_target_code = Code::Handle( |
1295 CodePatcher::GetSwitchableCallTargetAt(caller_frame->pc(), caller_code)); | 1299 CodePatcher::GetSwitchableCallTargetAt(caller_frame->pc(), caller_code)); |
1296 Function& old_target = Function::Handle(zone); | 1300 Function& old_target = Function::Handle(zone); |
1297 old_target ^= old_target_code.owner(); | 1301 old_target ^= old_target_code.owner(); |
1298 | 1302 |
1299 // We lost the original ICData when we patched to the monomorphic case. | 1303 // We lost the original ICData when we patched to the monomorphic case. |
1300 const String& name = String::Handle(zone, old_target.name()); | 1304 const String& name = String::Handle(zone, old_target.name()); |
1301 ASSERT(!old_target.HasOptionalParameters()); | 1305 ASSERT(!old_target.HasOptionalParameters()); |
1302 const Array& descriptor = Array::Handle( | 1306 ASSERT(!old_target.IsGeneric()); |
1303 zone, ArgumentsDescriptor::New(old_target.num_fixed_parameters())); | 1307 const int kTypeArgsLen = 0; |
1308 const Array& descriptor = | |
1309 Array::Handle(zone, ArgumentsDescriptor::New( | |
1310 kTypeArgsLen, old_target.num_fixed_parameters())); | |
1304 const ICData& ic_data = | 1311 const ICData& ic_data = |
1305 ICData::Handle(zone, ICData::New(caller_function, name, descriptor, | 1312 ICData::Handle(zone, ICData::New(caller_function, name, descriptor, |
1306 Thread::kNoDeoptId, 1, /* args_tested */ | 1313 Thread::kNoDeoptId, 1, /* args_tested */ |
1307 false /* static_call */)); | 1314 false /* static_call */)); |
1308 | 1315 |
1309 // Add the first target. | 1316 // Add the first target. |
1310 ic_data.AddReceiverCheck(old_expected_cid.Value(), old_target); | 1317 ic_data.AddReceiverCheck(old_expected_cid.Value(), old_target); |
1311 | 1318 |
1312 // Maybe add the new target. | 1319 // Maybe add the new target. |
1313 Class& cls = Class::Handle(zone, receiver.clazz()); | 1320 Class& cls = Class::Handle(zone, receiver.clazz()); |
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2345 const intptr_t new_size = 2 * old_size; | 2352 const intptr_t new_size = 2 * old_size; |
2346 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 2353 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
2347 const TypedData& new_data = | 2354 const TypedData& new_data = |
2348 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 2355 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
2349 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 2356 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
2350 typed_data_cell.SetAt(0, new_data); | 2357 typed_data_cell.SetAt(0, new_data); |
2351 arguments.SetReturn(new_data); | 2358 arguments.SetReturn(new_data); |
2352 } | 2359 } |
2353 | 2360 |
2354 } // namespace dart | 2361 } // namespace dart |
OLD | NEW |