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 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1025 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { | 1025 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { |
| 1026 ASSERT(arguments.ArgCount() == | 1026 ASSERT(arguments.ArgCount() == |
| 1027 kMegamorphicCacheMissHandlerRuntimeEntry.argument_count()); | 1027 kMegamorphicCacheMissHandlerRuntimeEntry.argument_count()); |
| 1028 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1028 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1029 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 1029 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1030 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); | 1030 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1031 const String& name = String::Handle(ic_data.target_name()); | 1031 const String& name = String::Handle(ic_data.target_name()); |
| 1032 const MegamorphicCache& cache = MegamorphicCache::Handle( | 1032 const MegamorphicCache& cache = MegamorphicCache::Handle( |
| 1033 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); | 1033 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); |
| 1034 Class& cls = Class::Handle(receiver.clazz()); | 1034 Class& cls = Class::Handle(receiver.clazz()); |
| 1035 const bool is_null = cls.IsNullClass(); | |
| 1036 // For lookups treat null as an instance of class Object. | |
| 1037 if (is_null) { | |
| 1038 cls = isolate->object_store()->object_class(); | |
| 1039 } | |
| 1040 ASSERT(!cls.IsNull()); | 1035 ASSERT(!cls.IsNull()); |
| 1041 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { | 1036 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { |
| 1042 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", | 1037 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", |
| 1043 cls.ToCString(), name.ToCString()); | 1038 cls.ToCString(), name.ToCString()); |
| 1044 } | 1039 } |
| 1045 | 1040 |
| 1046 ArgumentsDescriptor args_desc(descriptor); | 1041 ArgumentsDescriptor args_desc(descriptor); |
| 1047 const Function& target = Function::Handle( | 1042 const Function& target = Function::Handle( |
| 1048 Resolver::ResolveDynamicForReceiverClass(cls, | 1043 Resolver::ResolveDynamicForReceiverClass(cls, |
| 1049 name, | 1044 name, |
| 1050 args_desc)); | 1045 args_desc)); |
| 1051 | 1046 |
| 1052 Instructions& instructions = Instructions::Handle(); | 1047 Instructions& instructions = Instructions::Handle(); |
| 1053 if (!target.IsNull()) { | 1048 if (!target.IsNull()) { |
| 1054 if (!target.HasCode()) { | 1049 if (!target.HasCode()) { |
| 1055 const Error& error = Error::Handle(Compiler::CompileFunction(target)); | 1050 const Error& error = Error::Handle(Compiler::CompileFunction(target)); |
| 1056 if (!error.IsNull()) { | 1051 if (!error.IsNull()) { |
| 1057 Exceptions::PropagateError(error); | 1052 Exceptions::PropagateError(error); |
| 1058 } | 1053 } |
| 1059 } | 1054 } |
| 1060 ASSERT(target.HasCode()); | 1055 ASSERT(target.HasCode()); |
| 1061 instructions = Code::Handle(target.CurrentCode()).instructions(); | 1056 instructions = Code::Handle(target.CurrentCode()).instructions(); |
| 1062 } | 1057 } |
| 1063 arguments.SetReturn(instructions); | 1058 arguments.SetReturn(instructions); |
| 1064 if (instructions.IsNull()) return; | 1059 if (instructions.IsNull()) return; |
| 1065 | 1060 |
| 1066 cache.EnsureCapacity(); | 1061 cache.EnsureCapacity(); |
| 1067 const Smi& class_id = Smi::Handle(Smi::New( | 1062 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); |
| 1068 is_null ? static_cast<intptr_t>(kNullCid) : cls.id())); | |
| 1069 cache.Insert(class_id, target); | 1063 cache.Insert(class_id, target); |
| 1070 return; | 1064 return; |
| 1071 } | 1065 } |
| 1072 | 1066 |
| 1073 | 1067 |
| 1074 // Updates IC data for two arguments. Used by the equality operation when | 1068 // Updates IC data for two arguments. Used by the equality operation when |
| 1075 // the control flow bypasses regular inline cache (null arguments). | 1069 // the control flow bypasses regular inline cache (null arguments). |
| 1076 // Arg0: Receiver object. | 1070 // Arg0: Receiver object. |
| 1077 // Arg1: Argument after receiver. | 1071 // Arg1: Argument after receiver. |
| 1078 // Arg2: Target's name. | 1072 // Arg2: Target's name. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1210 // | 1204 // |
| 1211 // 3. There is no such method. | 1205 // 3. There is no such method. |
| 1212 DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) { | 1206 DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) { |
| 1213 ASSERT(arguments.ArgCount() == | 1207 ASSERT(arguments.ArgCount() == |
| 1214 kInstanceFunctionLookupRuntimeEntry.argument_count()); | 1208 kInstanceFunctionLookupRuntimeEntry.argument_count()); |
| 1215 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1209 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1216 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 1210 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1217 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(2)); | 1211 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1218 const Array& args = Array::CheckedHandle(arguments.ArgAt(3)); | 1212 const Array& args = Array::CheckedHandle(arguments.ArgAt(3)); |
| 1219 | 1213 |
| 1220 Class& receiver_class = Class::Handle(receiver.clazz()); | 1214 const Class& receiver_class = Class::Handle(receiver.clazz()); |
|
Lasse Reichstein Nielsen
2013/08/16 08:04:13
I like how this change makes code *simpler*! :)
| |
| 1221 // For lookups treat null as an instance of class Object. | |
| 1222 if (receiver_class.IsNullClass()) { | |
| 1223 receiver_class = isolate->object_store()->object_class(); | |
| 1224 } | |
| 1225 const String& target_name = String::Handle(ic_data.target_name()); | 1215 const String& target_name = String::Handle(ic_data.target_name()); |
| 1226 | 1216 |
| 1227 Object& result = Object::Handle(); | 1217 Object& result = Object::Handle(); |
| 1228 if (!ResolveCallThroughGetter(receiver, | 1218 if (!ResolveCallThroughGetter(receiver, |
| 1229 receiver_class, | 1219 receiver_class, |
| 1230 target_name, | 1220 target_name, |
| 1231 args_descriptor, | 1221 args_descriptor, |
| 1232 args, | 1222 args, |
| 1233 ic_data, | 1223 ic_data, |
| 1234 &result)) { | 1224 &result)) { |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1867 // Arg1: Value that is being stored. | 1857 // Arg1: Value that is being stored. |
| 1868 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1858 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 1869 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | 1859 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); |
| 1870 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1860 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1871 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1861 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 1872 | 1862 |
| 1873 field.UpdateCid(value.GetClassId()); | 1863 field.UpdateCid(value.GetClassId()); |
| 1874 } | 1864 } |
| 1875 | 1865 |
| 1876 } // namespace dart | 1866 } // namespace dart |
| OLD | NEW |