OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_macros.h" | 7 #include "vm/assembler_macros.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 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 GrowableArray<const Instance*> args(3); | 1018 GrowableArray<const Instance*> args(3); |
1019 args.Add(&receiver); | 1019 args.Add(&receiver); |
1020 args.Add(&arg1); | 1020 args.Add(&arg1); |
1021 args.Add(&arg2); | 1021 args.Add(&arg2); |
1022 const Function& result = | 1022 const Function& result = |
1023 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); | 1023 Function::Handle(InlineCacheMissHandler(args, ic_data, arg_descriptor)); |
1024 arguments.SetReturn(result); | 1024 arguments.SetReturn(result); |
1025 } | 1025 } |
1026 | 1026 |
1027 | 1027 |
| 1028 // Handle a miss of a megamorphic cache. |
| 1029 // Arg0: Receiver. |
| 1030 // Arg1: ICData object. |
| 1031 // Arg2: Arguments descriptor array. |
| 1032 |
| 1033 // Returns: target instructions to call or null if the |
| 1034 // InstanceFunctionLookup stub should be used (e.g., to invoke no such |
| 1035 // method and implicit closures).. |
| 1036 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { |
| 1037 ASSERT(arguments.ArgCount() == |
| 1038 kMegamorphicCacheMissHandlerRuntimeEntry.argument_count()); |
| 1039 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 1040 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
| 1041 const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1042 const String& name = String::Handle(ic_data.target_name()); |
| 1043 const MegamorphicCache& cache = MegamorphicCache::Handle( |
| 1044 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); |
| 1045 Class& cls = Class::Handle(receiver.clazz()); |
| 1046 // For lookups treat null as an instance of class Object. |
| 1047 if (cls.IsNullClass()) { |
| 1048 cls = isolate->object_store()->object_class(); |
| 1049 } |
| 1050 ASSERT(!cls.IsNull()); |
| 1051 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { |
| 1052 OS::Print("Megamorphic IC miss, class=%s, function=%s\n", |
| 1053 cls.ToCString(), name.ToCString()); |
| 1054 } |
| 1055 |
| 1056 intptr_t arg_count = |
| 1057 Smi::Cast(Object::Handle(descriptor.At(0))).Value(); |
| 1058 intptr_t named_arg_count = |
| 1059 arg_count - Smi::Cast(Object::Handle(descriptor.At(1))).Value(); |
| 1060 const Function& target = Function::Handle( |
| 1061 Resolver::ResolveDynamicForReceiverClass(cls, |
| 1062 name, |
| 1063 arg_count, |
| 1064 named_arg_count)); |
| 1065 |
| 1066 Instructions& instructions = Instructions::Handle(); |
| 1067 if (!target.IsNull()) { |
| 1068 if (!target.HasCode()) { |
| 1069 const Error& error = |
| 1070 Error::Handle(Compiler::CompileFunction(target)); |
| 1071 if (!error.IsNull()) Exceptions::PropagateError(error); |
| 1072 } |
| 1073 ASSERT(target.HasCode()); |
| 1074 instructions = Code::Handle(target.CurrentCode()).instructions(); |
| 1075 } |
| 1076 arguments.SetReturn(instructions); |
| 1077 if (instructions.IsNull()) return; |
| 1078 |
| 1079 cache.EnsureCapacity(); |
| 1080 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); |
| 1081 cache.Insert(class_id, target); |
| 1082 return; |
| 1083 } |
| 1084 |
| 1085 |
1028 // Updates IC data for two arguments. Used by the equality operation when | 1086 // Updates IC data for two arguments. Used by the equality operation when |
1029 // the control flow bypasses regular inline cache (null arguments). | 1087 // the control flow bypasses regular inline cache (null arguments). |
1030 // Arg0: Receiver object. | 1088 // Arg0: Receiver object. |
1031 // Arg1: Argument after receiver. | 1089 // Arg1: Argument after receiver. |
1032 // Arg2: Target's name. | 1090 // Arg2: Target's name. |
1033 // Arg3: ICData. | 1091 // Arg3: ICData. |
1034 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { | 1092 DEFINE_RUNTIME_ENTRY(UpdateICDataTwoArgs, 4) { |
1035 ASSERT(arguments.ArgCount() == | 1093 ASSERT(arguments.ArgCount() == |
1036 kUpdateICDataTwoArgsRuntimeEntry.argument_count()); | 1094 kUpdateICDataTwoArgsRuntimeEntry.argument_count()); |
1037 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1095 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 Isolate* isolate = Isolate::Current(); | 1951 Isolate* isolate = Isolate::Current(); |
1894 StackZone zone(isolate); | 1952 StackZone zone(isolate); |
1895 HANDLESCOPE(isolate); | 1953 HANDLESCOPE(isolate); |
1896 const Bigint& big_left = Bigint::Handle(left); | 1954 const Bigint& big_left = Bigint::Handle(left); |
1897 const Bigint& big_right = Bigint::Handle(right); | 1955 const Bigint& big_right = Bigint::Handle(right); |
1898 return BigintOperations::Compare(big_left, big_right); | 1956 return BigintOperations::Compare(big_left, big_right); |
1899 } | 1957 } |
1900 END_LEAF_RUNTIME_ENTRY | 1958 END_LEAF_RUNTIME_ENTRY |
1901 | 1959 |
1902 } // namespace dart | 1960 } // namespace dart |
OLD | NEW |