| 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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 String& function_name = String::Handle(ic_data.target_name()); | 740 String& function_name = String::Handle(ic_data.target_name()); |
| 741 ASSERT(function_name.IsSymbol()); | 741 ASSERT(function_name.IsSymbol()); |
| 742 Function& target_function = Function::Handle( | 742 Function& target_function = Function::Handle( |
| 743 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); | 743 Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor)); |
| 744 if (target_function.IsNull()) { | 744 if (target_function.IsNull()) { |
| 745 if (FLAG_trace_ic) { | 745 if (FLAG_trace_ic) { |
| 746 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", | 746 OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n", |
| 747 String::Handle(ic_data.target_name()).ToCString(), | 747 String::Handle(ic_data.target_name()).ToCString(), |
| 748 receiver.ToCString()); | 748 receiver.ToCString()); |
| 749 } | 749 } |
| 750 ic_data.set_is_closure_call(true); | 750 ic_data.SetIsClosureCall(); |
| 751 target_function = InlineCacheMissHelper(receiver, ic_data); | 751 target_function = InlineCacheMissHelper(receiver, ic_data); |
| 752 } | 752 } |
| 753 ASSERT(!target_function.IsNull()); | 753 ASSERT(!target_function.IsNull()); |
| 754 if (args.length() == 1) { | 754 if (args.length() == 1) { |
| 755 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); | 755 ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function); |
| 756 } else { | 756 } else { |
| 757 GrowableArray<intptr_t> class_ids(args.length()); | 757 GrowableArray<intptr_t> class_ids(args.length()); |
| 758 ASSERT(ic_data.num_args_tested() == args.length()); | 758 ASSERT(ic_data.NumArgsTested() == args.length()); |
| 759 for (intptr_t i = 0; i < args.length(); i++) { | 759 for (intptr_t i = 0; i < args.length(); i++) { |
| 760 class_ids.Add(args[i]->GetClassId()); | 760 class_ids.Add(args[i]->GetClassId()); |
| 761 } | 761 } |
| 762 ic_data.AddCheck(class_ids, target_function); | 762 ic_data.AddCheck(class_ids, target_function); |
| 763 } | 763 } |
| 764 if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) { | 764 if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) { |
| 765 DartFrameIterator iterator; | 765 DartFrameIterator iterator; |
| 766 StackFrame* caller_frame = iterator.NextFrame(); | 766 StackFrame* caller_frame = iterator.NextFrame(); |
| 767 ASSERT(caller_frame != NULL); | 767 ASSERT(caller_frame != NULL); |
| 768 if (FLAG_trace_ic_miss_in_optimized) { | 768 if (FLAG_trace_ic_miss_in_optimized) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", | 901 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", |
| 902 cls.ToCString(), name.ToCString()); | 902 cls.ToCString(), name.ToCString()); |
| 903 } | 903 } |
| 904 | 904 |
| 905 ArgumentsDescriptor args_desc(descriptor); | 905 ArgumentsDescriptor args_desc(descriptor); |
| 906 Function& target_function = Function::Handle( | 906 Function& target_function = Function::Handle( |
| 907 Resolver::ResolveDynamicForReceiverClass(cls, | 907 Resolver::ResolveDynamicForReceiverClass(cls, |
| 908 name, | 908 name, |
| 909 args_desc)); | 909 args_desc)); |
| 910 if (target_function.IsNull()) { | 910 if (target_function.IsNull()) { |
| 911 ic_data.set_is_closure_call(true); | 911 ic_data.SetIsClosureCall(); |
| 912 target_function = InlineCacheMissHelper(receiver, ic_data); | 912 target_function = InlineCacheMissHelper(receiver, ic_data); |
| 913 } | 913 } |
| 914 | 914 |
| 915 ASSERT(!target_function.IsNull()); | 915 ASSERT(!target_function.IsNull()); |
| 916 // Insert function found into cache and return it. | 916 // Insert function found into cache and return it. |
| 917 cache.EnsureCapacity(); | 917 cache.EnsureCapacity(); |
| 918 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); | 918 const Smi& class_id = Smi::Handle(Smi::New(cls.id())); |
| 919 cache.Insert(class_id, target_function); | 919 cache.Insert(class_id, target_function); |
| 920 arguments.SetReturn(target_function); | 920 arguments.SetReturn(target_function); |
| 921 } | 921 } |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); | 1180 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); |
| 1181 DartFrameIterator iterator; | 1181 DartFrameIterator iterator; |
| 1182 StackFrame* frame = iterator.NextFrame(); | 1182 StackFrame* frame = iterator.NextFrame(); |
| 1183 ASSERT(frame != NULL); | 1183 ASSERT(frame != NULL); |
| 1184 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd | 1184 OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd |
| 1185 " %s %s\n", | 1185 " %s %s\n", |
| 1186 frame->pc(), | 1186 frame->pc(), |
| 1187 ic_data.raw(), | 1187 ic_data.raw(), |
| 1188 function.usage_counter(), | 1188 function.usage_counter(), |
| 1189 ic_data.NumberOfChecks(), | 1189 ic_data.NumberOfChecks(), |
| 1190 ic_data.is_closure_call() ? "closure" : "", | 1190 ic_data.IsClosureCall() ? "closure" : "", |
| 1191 function.ToFullyQualifiedCString()); | 1191 function.ToFullyQualifiedCString()); |
| 1192 } | 1192 } |
| 1193 | 1193 |
| 1194 | 1194 |
| 1195 // This is called from function that needs to be optimized. | 1195 // This is called from function that needs to be optimized. |
| 1196 // The requesting function can be already optimized (reoptimization). | 1196 // The requesting function can be already optimized (reoptimization). |
| 1197 // Returns the Code object where to continue execution. | 1197 // Returns the Code object where to continue execution. |
| 1198 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1198 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1199 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 1199 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 1200 ASSERT(!function.IsNull()); | 1200 ASSERT(!function.IsNull()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 if (FLAG_trace_patching) { | 1262 if (FLAG_trace_patching) { |
| 1263 OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n", | 1263 OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n", |
| 1264 frame->pc(), | 1264 frame->pc(), |
| 1265 target_function.ToFullyQualifiedCString(), | 1265 target_function.ToFullyQualifiedCString(), |
| 1266 current_target_code.EntryPoint()); | 1266 current_target_code.EntryPoint()); |
| 1267 } | 1267 } |
| 1268 arguments.SetReturn(current_target_code); | 1268 arguments.SetReturn(current_target_code); |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 | 1271 |
| 1272 const char* DeoptReasonToText(intptr_t deopt_id) { | 1272 const char* DeoptReasonToCString(ICData::ICData::DeoptReasonId deopt_reason) { |
| 1273 switch (deopt_id) { | 1273 switch (deopt_reason) { |
| 1274 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; | 1274 #define DEOPT_REASON_TO_TEXT(name) case ICData::kDeopt##name: return #name; |
| 1275 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) | 1275 DEOPT_REASONS(DEOPT_REASON_TO_TEXT) |
| 1276 #undef DEOPT_REASON_ID_TO_TEXT | 1276 #undef DEOPT_REASON_TO_TEXT |
| 1277 default: | 1277 default: |
| 1278 UNREACHABLE(); | 1278 UNREACHABLE(); |
| 1279 return ""; | 1279 return ""; |
| 1280 } | 1280 } |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 | 1283 |
| 1284 void DeoptimizeAt(const Code& optimized_code, uword pc) { | 1284 void DeoptimizeAt(const Code& optimized_code, uword pc) { |
| 1285 ASSERT(optimized_code.is_optimized()); | 1285 ASSERT(optimized_code.is_optimized()); |
| 1286 intptr_t deopt_reason = kDeoptUnknown; | 1286 ICData::DeoptReasonId deopt_reason = ICData::kDeoptUnknown; |
| 1287 const DeoptInfo& deopt_info = | 1287 const DeoptInfo& deopt_info = |
| 1288 DeoptInfo::Handle(optimized_code.GetDeoptInfoAtPc(pc, &deopt_reason)); | 1288 DeoptInfo::Handle(optimized_code.GetDeoptInfoAtPc(pc, &deopt_reason)); |
| 1289 ASSERT(!deopt_info.IsNull()); | 1289 ASSERT(!deopt_info.IsNull()); |
| 1290 const Function& function = Function::Handle(optimized_code.function()); | 1290 const Function& function = Function::Handle(optimized_code.function()); |
| 1291 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | 1291 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); |
| 1292 ASSERT(!unoptimized_code.IsNull()); | 1292 ASSERT(!unoptimized_code.IsNull()); |
| 1293 // The switch to unoptimized code may have already occurred. | 1293 // The switch to unoptimized code may have already occurred. |
| 1294 if (function.HasOptimizedCode()) { | 1294 if (function.HasOptimizedCode()) { |
| 1295 function.SwitchToUnoptimizedCode(); | 1295 function.SwitchToUnoptimizedCode(); |
| 1296 } | 1296 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 // of the given value. | 1497 // of the given value. |
| 1498 // Arg0: Field object; | 1498 // Arg0: Field object; |
| 1499 // Arg1: Value that is being stored. | 1499 // Arg1: Value that is being stored. |
| 1500 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1500 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 1501 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1501 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1502 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1502 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 1503 field.UpdateGuardedCidAndLength(value); | 1503 field.UpdateGuardedCidAndLength(value); |
| 1504 } | 1504 } |
| 1505 | 1505 |
| 1506 } // namespace dart | 1506 } // namespace dart |
| OLD | NEW |