Chromium Code Reviews| 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/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1247 receiver_class, | 1247 receiver_class, |
| 1248 target_name, | 1248 target_name, |
| 1249 args_descriptor, | 1249 args_descriptor, |
| 1250 args, | 1250 args, |
| 1251 &result)) { | 1251 &result)) { |
| 1252 ArgumentsDescriptor desc(args_descriptor); | 1252 ArgumentsDescriptor desc(args_descriptor); |
| 1253 const Function& target_function = Function::Handle( | 1253 const Function& target_function = Function::Handle( |
| 1254 receiver_class.GetNoSuchMethodDispatcher(target_name, args_descriptor)); | 1254 receiver_class.GetNoSuchMethodDispatcher(target_name, args_descriptor)); |
| 1255 // Update IC data. | 1255 // Update IC data. |
| 1256 ASSERT(!target_function.IsNull()); | 1256 ASSERT(!target_function.IsNull()); |
| 1257 intptr_t receiver_cid = receiver.GetClassId(); | |
| 1257 if (ic_data.num_args_tested() == 1) { | 1258 if (ic_data.num_args_tested() == 1) { |
|
srdjan
2013/07/12 14:45:12
Add a TODO as discussed in the the CL text.
Florian Schneider
2013/07/12 15:43:59
Done. There is a TODO below about that.
| |
| 1258 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); | 1259 // In optimized code we may enter into here via the |
| 1260 // MegamorphicCacheMissHandler since noSuchMethod dispatchers are not | |
| 1261 // inserted into the megamorphic cache. Therefore, we need to guard | |
| 1262 // against entering the same check twice into the ICData. | |
| 1263 // Note that num_args_tested == 1 in optimized code. | |
| 1264 // TODO(fschneider): Handle extraordinary cases like noSuchMethod and | |
| 1265 // implicit closure invocation properly in the megamorphic cache. | |
| 1266 const Function& target = | |
| 1267 Function::Handle(ic_data.GetTargetForReceiverClassId(receiver_cid)); | |
| 1268 if (target.IsNull()) { | |
| 1269 ic_data.AddReceiverCheck(receiver_cid, target_function); | |
| 1270 } | |
| 1259 } else { | 1271 } else { |
| 1260 // Operators calls have two or three arguments tested ([], []=, etc.) | 1272 // Operators calls have two or three arguments tested ([], []=, etc.) |
| 1261 ASSERT(ic_data.num_args_tested() > 1); | 1273 ASSERT(ic_data.num_args_tested() > 1); |
| 1262 GrowableArray<intptr_t> class_ids(ic_data.num_args_tested()); | 1274 GrowableArray<intptr_t> class_ids(ic_data.num_args_tested()); |
| 1263 class_ids.Add(receiver.GetClassId()); | 1275 class_ids.Add(receiver_cid); |
| 1264 for (intptr_t i = 1; i < ic_data.num_args_tested(); ++i) { | 1276 for (intptr_t i = 1; i < ic_data.num_args_tested(); ++i) { |
| 1265 class_ids.Add(Object::Handle(args.At(i)).GetClassId()); | 1277 class_ids.Add(Object::Handle(args.At(i)).GetClassId()); |
| 1266 } | 1278 } |
| 1267 ic_data.AddCheck(class_ids, target_function); | 1279 ic_data.AddCheck(class_ids, target_function); |
| 1268 } | 1280 } |
| 1269 if (FLAG_trace_ic) { | 1281 if (FLAG_trace_ic) { |
| 1270 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n", | 1282 OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n", |
| 1271 Class::Handle(receiver.clazz()).ToCString(), | 1283 Class::Handle(receiver.clazz()).ToCString(), |
| 1272 receiver.GetClassId(), | 1284 receiver_cid, |
| 1273 target_function.ToCString()); | 1285 target_function.ToCString()); |
| 1274 } | 1286 } |
| 1275 result = DartEntry::InvokeFunction(target_function, args, args_descriptor); | 1287 result = DartEntry::InvokeFunction(target_function, args, args_descriptor); |
| 1276 } | 1288 } |
| 1277 CheckResultError(result); | 1289 CheckResultError(result); |
| 1278 arguments.SetReturn(result); | 1290 arguments.SetReturn(result); |
| 1279 } | 1291 } |
| 1280 | 1292 |
| 1281 | 1293 |
| 1282 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) { | 1294 static bool CanOptimizeFunction(const Function& function, Isolate* isolate) { |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1869 // Arg1: Value that is being stored. | 1881 // Arg1: Value that is being stored. |
| 1870 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1882 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 1871 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | 1883 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); |
| 1872 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1884 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1873 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1885 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 1874 | 1886 |
| 1875 field.UpdateCid(value.GetClassId()); | 1887 field.UpdateCid(value.GetClassId()); |
| 1876 } | 1888 } |
| 1877 | 1889 |
| 1878 } // namespace dart | 1890 } // namespace dart |
| OLD | NEW |