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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 "Maximum number of subtype cache entries (number of checks cached)."); | 55 "Maximum number of subtype cache entries (number of checks cached)."); |
56 | 56 |
57 | 57 |
58 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { | 58 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { |
59 ASSERT(arguments.ArgCount() == | 59 ASSERT(arguments.ArgCount() == |
60 kTraceFunctionEntryRuntimeEntry.argument_count()); | 60 kTraceFunctionEntryRuntimeEntry.argument_count()); |
61 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 61 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
62 const String& function_name = String::Handle(function.name()); | 62 const String& function_name = String::Handle(function.name()); |
63 const String& class_name = | 63 const String& class_name = |
64 String::Handle(Class::Handle(function.Owner()).Name()); | 64 String::Handle(Class::Handle(function.Owner()).Name()); |
65 OS::Print("> Entering '%s.%s'\n", | 65 OS::PrintErr("> Entering '%s.%s'\n", |
66 class_name.ToCString(), function_name.ToCString()); | 66 class_name.ToCString(), function_name.ToCString()); |
67 } | 67 } |
68 | 68 |
69 | 69 |
70 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { | 70 DEFINE_RUNTIME_ENTRY(TraceFunctionExit, 1) { |
71 ASSERT(arguments.ArgCount() == | 71 ASSERT(arguments.ArgCount() == |
72 kTraceFunctionExitRuntimeEntry.argument_count()); | 72 kTraceFunctionExitRuntimeEntry.argument_count()); |
73 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 73 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
74 const String& function_name = String::Handle(function.name()); | 74 const String& function_name = String::Handle(function.name()); |
75 const String& class_name = | 75 const String& class_name = |
76 String::Handle(Class::Handle(function.Owner()).Name()); | 76 String::Handle(Class::Handle(function.Owner()).Name()); |
77 OS::Print("< Exiting '%s.%s'\n", | 77 OS::PrintErr("< Exiting '%s.%s'\n", |
78 class_name.ToCString(), function_name.ToCString()); | 78 class_name.ToCString(), function_name.ToCString()); |
79 } | 79 } |
80 | 80 |
81 | 81 |
82 // Allocation of a fixed length array of given element type. | 82 // Allocation of a fixed length array of given element type. |
83 // This runtime entry is never called for allocating a List of a generic type, | 83 // This runtime entry is never called for allocating a List of a generic type, |
84 // because a prior run time call instantiates the element type if necessary. | 84 // because a prior run time call instantiates the element type if necessary. |
85 // Arg0: array length. | 85 // Arg0: array length. |
86 // Arg1: array type arguments, i.e. vector of 1 type, the element type. | 86 // Arg1: array type arguments, i.e. vector of 1 type, the element type. |
87 // Return value: newly allocated array of length arg0. | 87 // Return value: newly allocated array of length arg0. |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 const AbstractType& type, | 356 const AbstractType& type, |
357 const AbstractTypeArguments& instantiator_type_arguments, | 357 const AbstractTypeArguments& instantiator_type_arguments, |
358 const Bool& result) { | 358 const Bool& result) { |
359 DartFrameIterator iterator; | 359 DartFrameIterator iterator; |
360 StackFrame* caller_frame = iterator.NextFrame(); | 360 StackFrame* caller_frame = iterator.NextFrame(); |
361 ASSERT(caller_frame != NULL); | 361 ASSERT(caller_frame != NULL); |
362 | 362 |
363 const Type& instance_type = Type::Handle(instance.GetType()); | 363 const Type& instance_type = Type::Handle(instance.GetType()); |
364 ASSERT(instance_type.IsInstantiated()); | 364 ASSERT(instance_type.IsInstantiated()); |
365 if (type.IsInstantiated()) { | 365 if (type.IsInstantiated()) { |
366 OS::Print("%s: '%s' %"Pd" %s '%s' %"Pd" (pc: %#"Px").\n", | 366 OS::PrintErr("%s: '%s' %"Pd" %s '%s' %"Pd" (pc: %#"Px").\n", |
367 message, | 367 message, |
368 String::Handle(instance_type.Name()).ToCString(), | 368 String::Handle(instance_type.Name()).ToCString(), |
369 Class::Handle(instance_type.type_class()).id(), | 369 Class::Handle(instance_type.type_class()).id(), |
370 (result.raw() == Bool::True().raw()) ? "is" : "is !", | 370 (result.raw() == Bool::True().raw()) ? "is" : "is !", |
371 String::Handle(type.Name()).ToCString(), | 371 String::Handle(type.Name()).ToCString(), |
372 Class::Handle(type.type_class()).id(), | 372 Class::Handle(type.type_class()).id(), |
373 caller_frame->pc()); | 373 caller_frame->pc()); |
374 } else { | 374 } else { |
375 // Instantiate type before printing. | 375 // Instantiate type before printing. |
376 const AbstractType& instantiated_type = | 376 const AbstractType& instantiated_type = |
377 AbstractType::Handle(type.InstantiateFrom(instantiator_type_arguments)); | 377 AbstractType::Handle(type.InstantiateFrom(instantiator_type_arguments)); |
378 OS::Print("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n", | 378 OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n", |
379 message, | 379 message, |
380 String::Handle(instance_type.Name()).ToCString(), | 380 String::Handle(instance_type.Name()).ToCString(), |
381 (result.raw() == Bool::True().raw()) ? "is" : "is !", | 381 (result.raw() == Bool::True().raw()) ? "is" : "is !", |
382 String::Handle(instantiated_type.Name()).ToCString(), | 382 String::Handle(instantiated_type.Name()).ToCString(), |
383 String::Handle(type.Name()).ToCString(), | 383 String::Handle(type.Name()).ToCString(), |
384 caller_frame->pc()); | 384 caller_frame->pc()); |
385 } | 385 } |
386 const Function& function = Function::Handle( | 386 const Function& function = Function::Handle( |
387 caller_frame->LookupDartFunction()); | 387 caller_frame->LookupDartFunction()); |
388 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString()); | 388 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString()); |
389 } | 389 } |
390 | 390 |
391 | 391 |
392 // Converts InstantiatedTypeArguments to TypeArguments and stores it | 392 // Converts InstantiatedTypeArguments to TypeArguments and stores it |
393 // into the instance. The assembly code can handle only type arguments of | 393 // into the instance. The assembly code can handle only type arguments of |
394 // class TypeArguments. Because of the overhead, do it only when needed. | 394 // class TypeArguments. Because of the overhead, do it only when needed. |
395 // Return true if type arguments have been replaced, false otherwise. | 395 // Return true if type arguments have been replaced, false otherwise. |
396 static bool OptimizeTypeArguments(const Instance& instance) { | 396 static bool OptimizeTypeArguments(const Instance& instance) { |
397 const Class& type_class = Class::ZoneHandle(instance.clazz()); | 397 const Class& type_class = Class::ZoneHandle(instance.clazz()); |
398 if (!type_class.HasTypeArguments()) { | 398 if (!type_class.HasTypeArguments()) { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 i, | 485 i, |
486 &last_instance_class_id, | 486 &last_instance_class_id, |
487 &last_instance_type_arguments, | 487 &last_instance_type_arguments, |
488 &last_instantiator_type_arguments, | 488 &last_instantiator_type_arguments, |
489 &last_result); | 489 &last_result); |
490 if ((last_instance_class_id == instance_class.id()) && | 490 if ((last_instance_class_id == instance_class.id()) && |
491 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) && | 491 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) && |
492 (last_instantiator_type_arguments.raw() == | 492 (last_instantiator_type_arguments.raw() == |
493 instantiator_type_arguments.raw())) { | 493 instantiator_type_arguments.raw())) { |
494 if (FLAG_trace_type_checks) { | 494 if (FLAG_trace_type_checks) { |
495 OS::Print("%"Pd" ", i); | 495 OS::PrintErr("%"Pd" ", i); |
496 if (type_arguments_replaced) { | 496 if (type_arguments_replaced) { |
497 PrintTypeCheck("Duplicate cache entry (canonical.)", instance, type, | 497 PrintTypeCheck("Duplicate cache entry (canonical.)", instance, type, |
498 instantiator_type_arguments, result); | 498 instantiator_type_arguments, result); |
499 } else { | 499 } else { |
500 PrintTypeCheck("WARNING Duplicate cache entry", instance, type, | 500 PrintTypeCheck("WARNING Duplicate cache entry", instance, type, |
501 instantiator_type_arguments, result); | 501 instantiator_type_arguments, result); |
502 } | 502 } |
503 } | 503 } |
504 // Can occur if we have canonicalized arguments. | 504 // Can occur if we have canonicalized arguments. |
505 // TODO(srdjan): Investigate why this assert can fail. | 505 // TODO(srdjan): Investigate why this assert can fail. |
506 // ASSERT(type_arguments_replaced); | 506 // ASSERT(type_arguments_replaced); |
507 return; | 507 return; |
508 } | 508 } |
509 } | 509 } |
510 if (!instantiator_type_arguments.IsInstantiatedTypeArguments()) { | 510 if (!instantiator_type_arguments.IsInstantiatedTypeArguments()) { |
511 new_cache.AddCheck(instance_class.id(), | 511 new_cache.AddCheck(instance_class.id(), |
512 instance_type_arguments, | 512 instance_type_arguments, |
513 instantiator_type_arguments, | 513 instantiator_type_arguments, |
514 result); | 514 result); |
515 } | 515 } |
516 if (FLAG_trace_type_checks) { | 516 if (FLAG_trace_type_checks) { |
517 AbstractType& test_type = AbstractType::Handle(type.raw()); | 517 AbstractType& test_type = AbstractType::Handle(type.raw()); |
518 if (!test_type.IsInstantiated()) { | 518 if (!test_type.IsInstantiated()) { |
519 test_type = type.InstantiateFrom(instantiator_type_arguments); | 519 test_type = type.InstantiateFrom(instantiator_type_arguments); |
520 } | 520 } |
521 OS::Print(" Updated test cache %p ix: %"Pd" with (%"Pd", %p, %p, %s)\n" | 521 OS::PrintErr(" Updated test cache %p ix: %"Pd" with (%"Pd", %p, %p, %s)\n" |
522 " [%p %s %"Pd", %p %s]\n" | 522 " [%p %s %"Pd", %p %s]\n" |
523 " [%p %s %"Pd", %p %s] %s\n", | 523 " [%p %s %"Pd", %p %s] %s\n", |
524 new_cache.raw(), | 524 new_cache.raw(), |
525 len, | 525 len, |
526 instance_class.id(), | 526 instance_class.id(), |
527 | 527 |
528 instance_type_arguments.raw(), | 528 instance_type_arguments.raw(), |
529 instantiator_type_arguments.raw(), | 529 instantiator_type_arguments.raw(), |
530 result.ToCString(), | 530 result.ToCString(), |
531 | 531 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 } | 759 } |
760 } | 760 } |
761 const Code& target_code = Code::Handle(target_function.CurrentCode()); | 761 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
762 // Before patching verify that we are not repeatedly patching to the same | 762 // Before patching verify that we are not repeatedly patching to the same |
763 // target. | 763 // target. |
764 ASSERT(target_code.EntryPoint() != | 764 ASSERT(target_code.EntryPoint() != |
765 CodePatcher::GetStaticCallTargetAt(caller_frame->pc())); | 765 CodePatcher::GetStaticCallTargetAt(caller_frame->pc())); |
766 CodePatcher::PatchStaticCallAt(caller_frame->pc(), target_code.EntryPoint()); | 766 CodePatcher::PatchStaticCallAt(caller_frame->pc(), target_code.EntryPoint()); |
767 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); | 767 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); |
768 if (FLAG_trace_patching) { | 768 if (FLAG_trace_patching) { |
769 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", | 769 OS::PrintErr("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
770 caller_frame->pc(), | 770 caller_frame->pc(), |
771 target_function.ToFullyQualifiedCString(), | 771 target_function.ToFullyQualifiedCString(), |
772 target_code.EntryPoint()); | 772 target_code.EntryPoint()); |
773 } | 773 } |
774 arguments.SetReturn(target_code); | 774 arguments.SetReturn(target_code); |
775 } | 775 } |
776 | 776 |
777 | 777 |
778 // Resolves and compiles the target function of an instance call, updates | 778 // Resolves and compiles the target function of an instance call, updates |
779 // function cache of the receiver's class and returns the compiled code or null. | 779 // function cache of the receiver's class and returns the compiled code or null. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 const Array& arg_descriptor_array) { | 867 const Array& arg_descriptor_array) { |
868 const Instance& receiver = *args[0]; | 868 const Instance& receiver = *args[0]; |
869 const Code& target_code = | 869 const Code& target_code = |
870 Code::Handle(ResolveCompileInstanceCallTarget(receiver, | 870 Code::Handle(ResolveCompileInstanceCallTarget(receiver, |
871 ic_data, | 871 ic_data, |
872 arg_descriptor_array)); | 872 arg_descriptor_array)); |
873 if (target_code.IsNull()) { | 873 if (target_code.IsNull()) { |
874 // Let the megamorphic stub handle special cases: NoSuchMethod, | 874 // Let the megamorphic stub handle special cases: NoSuchMethod, |
875 // closure calls. | 875 // closure calls. |
876 if (FLAG_trace_ic) { | 876 if (FLAG_trace_ic) { |
877 OS::Print("InlineCacheMissHandler NULL code for receiver: %s\n", | 877 OS::PrintErr("InlineCacheMissHandler NULL code for receiver: %s\n", |
878 receiver.ToCString()); | 878 receiver.ToCString()); |
879 } | 879 } |
880 return Function::null(); | 880 return Function::null(); |
881 } | 881 } |
882 const Function& target_function = | 882 const Function& target_function = |
883 Function::Handle(target_code.function()); | 883 Function::Handle(target_code.function()); |
884 ASSERT(!target_function.IsNull()); | 884 ASSERT(!target_function.IsNull()); |
885 if (args.length() == 1) { | 885 if (args.length() == 1) { |
886 ic_data.AddReceiverCheck(Class::Handle(args[0]->clazz()).id(), | 886 ic_data.AddReceiverCheck(Class::Handle(args[0]->clazz()).id(), |
887 target_function); | 887 target_function); |
888 } else { | 888 } else { |
889 GrowableArray<intptr_t> class_ids(args.length()); | 889 GrowableArray<intptr_t> class_ids(args.length()); |
890 ASSERT(ic_data.num_args_tested() == args.length()); | 890 ASSERT(ic_data.num_args_tested() == args.length()); |
891 for (intptr_t i = 0; i < args.length(); i++) { | 891 for (intptr_t i = 0; i < args.length(); i++) { |
892 class_ids.Add(Class::Handle(args[i]->clazz()).id()); | 892 class_ids.Add(Class::Handle(args[i]->clazz()).id()); |
893 } | 893 } |
894 ic_data.AddCheck(class_ids, target_function); | 894 ic_data.AddCheck(class_ids, target_function); |
895 } | 895 } |
896 if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) { | 896 if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) { |
897 DartFrameIterator iterator; | 897 DartFrameIterator iterator; |
898 StackFrame* caller_frame = iterator.NextFrame(); | 898 StackFrame* caller_frame = iterator.NextFrame(); |
899 ASSERT(caller_frame != NULL); | 899 ASSERT(caller_frame != NULL); |
900 if (FLAG_trace_ic_miss_in_optimized) { | 900 if (FLAG_trace_ic_miss_in_optimized) { |
901 const Code& caller = Code::Handle(Code::LookupCode(caller_frame->pc())); | 901 const Code& caller = Code::Handle(Code::LookupCode(caller_frame->pc())); |
902 if (caller.is_optimized()) { | 902 if (caller.is_optimized()) { |
903 OS::Print("IC miss in optimized code; call %s -> %s\n", | 903 OS::PrintErr("IC miss in optimized code; call %s -> %s\n", |
904 Function::Handle(caller.function()).ToCString(), | 904 Function::Handle(caller.function()).ToCString(), |
905 target_function.ToCString()); | 905 target_function.ToCString()); |
906 } | 906 } |
907 } | 907 } |
908 if (FLAG_trace_ic) { | 908 if (FLAG_trace_ic) { |
909 OS::Print("InlineCacheMissHandler %d call at %#"Px"' " | 909 OS::PrintErr("InlineCacheMissHandler %d call at %#"Px"' " |
910 "adding <%s> id:%"Pd" -> <%s>\n", | 910 "adding <%s> id:%"Pd" -> <%s>\n", |
911 args.length(), | 911 args.length(), |
912 caller_frame->pc(), | 912 caller_frame->pc(), |
913 Class::Handle(receiver.clazz()).ToCString(), | 913 Class::Handle(receiver.clazz()).ToCString(), |
914 Class::Handle(receiver.clazz()).id(), | 914 Class::Handle(receiver.clazz()).id(), |
915 target_function.ToCString()); | 915 target_function.ToCString()); |
916 } | 916 } |
917 } | 917 } |
918 return target_function.raw(); | 918 return target_function.raw(); |
919 } | 919 } |
920 | 920 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 const String& name = String::Handle(ic_data.target_name()); | 1008 const String& name = String::Handle(ic_data.target_name()); |
1009 const MegamorphicCache& cache = MegamorphicCache::Handle( | 1009 const MegamorphicCache& cache = MegamorphicCache::Handle( |
1010 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); | 1010 isolate->megamorphic_cache_table()->Lookup(name, descriptor)); |
1011 Class& cls = Class::Handle(receiver.clazz()); | 1011 Class& cls = Class::Handle(receiver.clazz()); |
1012 // For lookups treat null as an instance of class Object. | 1012 // For lookups treat null as an instance of class Object. |
1013 if (cls.IsNullClass()) { | 1013 if (cls.IsNullClass()) { |
1014 cls = isolate->object_store()->object_class(); | 1014 cls = isolate->object_store()->object_class(); |
1015 } | 1015 } |
1016 ASSERT(!cls.IsNull()); | 1016 ASSERT(!cls.IsNull()); |
1017 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { | 1017 if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) { |
1018 OS::Print("Megamorphic IC miss, class=%s, function=%s\n", | 1018 OS::PrintErr("Megamorphic IC miss, class=%s, function=%s\n", |
1019 cls.ToCString(), name.ToCString()); | 1019 cls.ToCString(), name.ToCString()); |
1020 } | 1020 } |
1021 | 1021 |
1022 intptr_t arg_count = | 1022 intptr_t arg_count = |
1023 Smi::Cast(Object::Handle(descriptor.At(0))).Value(); | 1023 Smi::Cast(Object::Handle(descriptor.At(0))).Value(); |
1024 intptr_t named_arg_count = | 1024 intptr_t named_arg_count = |
1025 arg_count - Smi::Cast(Object::Handle(descriptor.At(1))).Value(); | 1025 arg_count - Smi::Cast(Object::Handle(descriptor.At(1))).Value(); |
1026 const Function& target = Function::Handle( | 1026 const Function& target = Function::Handle( |
1027 Resolver::ResolveDynamicForReceiverClass(cls, | 1027 Resolver::ResolveDynamicForReceiverClass(cls, |
1028 name, | 1028 name, |
1029 arg_count, | 1029 arg_count, |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 } | 1298 } |
1299 } | 1299 } |
1300 | 1300 |
1301 | 1301 |
1302 static void PrintCaller(const char* msg) { | 1302 static void PrintCaller(const char* msg) { |
1303 DartFrameIterator iterator; | 1303 DartFrameIterator iterator; |
1304 StackFrame* top_frame = iterator.NextFrame(); | 1304 StackFrame* top_frame = iterator.NextFrame(); |
1305 ASSERT(top_frame != NULL); | 1305 ASSERT(top_frame != NULL); |
1306 const Function& top_function = Function::Handle( | 1306 const Function& top_function = Function::Handle( |
1307 top_frame->LookupDartFunction()); | 1307 top_frame->LookupDartFunction()); |
1308 OS::Print("Failed: '%s' %s @ %#"Px"\n", | 1308 OS::PrintErr("Failed: '%s' %s @ %#"Px"\n", |
1309 msg, top_function.ToFullyQualifiedCString(), top_frame->pc()); | 1309 msg, top_function.ToFullyQualifiedCString(), top_frame->pc()); |
1310 StackFrame* caller_frame = iterator.NextFrame(); | 1310 StackFrame* caller_frame = iterator.NextFrame(); |
1311 if (caller_frame != NULL) { | 1311 if (caller_frame != NULL) { |
1312 const Function& caller_function = Function::Handle( | 1312 const Function& caller_function = Function::Handle( |
1313 caller_frame->LookupDartFunction()); | 1313 caller_frame->LookupDartFunction()); |
1314 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 1314 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
1315 OS::Print(" -> caller: %s (%s)\n", | 1315 OS::PrintErr(" -> caller: %s (%s)\n", |
1316 caller_function.ToFullyQualifiedCString(), | 1316 caller_function.ToFullyQualifiedCString(), |
1317 code.is_optimized() ? "optimized" : "unoptimized"); | 1317 code.is_optimized() ? "optimized" : "unoptimized"); |
1318 } | 1318 } |
1319 } | 1319 } |
1320 | 1320 |
1321 | 1321 |
1322 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { | 1322 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { |
1323 ASSERT(arguments.ArgCount() == | 1323 ASSERT(arguments.ArgCount() == |
1324 kTraceICCallRuntimeEntry.argument_count()); | 1324 kTraceICCallRuntimeEntry.argument_count()); |
1325 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); | 1325 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); |
1326 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); | 1326 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); |
1327 DartFrameIterator iterator; | 1327 DartFrameIterator iterator; |
1328 StackFrame* frame = iterator.NextFrame(); | 1328 StackFrame* frame = iterator.NextFrame(); |
1329 ASSERT(frame != NULL); | 1329 ASSERT(frame != NULL); |
1330 OS::Print("IC call @%#"Px": ICData: %p cnt:%"Pd" nchecks: %"Pd" %s %s\n", | 1330 OS::PrintErr("IC call @%#"Px": ICData: %p cnt:%"Pd" nchecks: %"Pd" %s %s\n", |
1331 frame->pc(), | 1331 frame->pc(), |
1332 ic_data.raw(), | 1332 ic_data.raw(), |
1333 function.usage_counter(), | 1333 function.usage_counter(), |
1334 ic_data.NumberOfChecks(), | 1334 ic_data.NumberOfChecks(), |
1335 ic_data.is_closure_call() ? "closure" : "", | 1335 ic_data.is_closure_call() ? "closure" : "", |
1336 function.ToFullyQualifiedCString()); | 1336 function.ToFullyQualifiedCString()); |
1337 } | 1337 } |
1338 | 1338 |
1339 | 1339 |
1340 // This is called from function that needs to be optimized. | 1340 // This is called from function that needs to be optimized. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 if (!error.IsNull()) { | 1376 if (!error.IsNull()) { |
1377 Exceptions::PropagateError(error); | 1377 Exceptions::PropagateError(error); |
1378 } | 1378 } |
1379 const Code& optimized_code = Code::Handle(function.CurrentCode()); | 1379 const Code& optimized_code = Code::Handle(function.CurrentCode()); |
1380 ASSERT(!optimized_code.IsNull()); | 1380 ASSERT(!optimized_code.IsNull()); |
1381 // Set usage counter for reoptimization. | 1381 // Set usage counter for reoptimization. |
1382 function.set_usage_counter( | 1382 function.set_usage_counter( |
1383 function.usage_counter() - FLAG_reoptimization_counter_threshold); | 1383 function.usage_counter() - FLAG_reoptimization_counter_threshold); |
1384 } else { | 1384 } else { |
1385 if (FLAG_trace_failed_optimization_attempts) { | 1385 if (FLAG_trace_failed_optimization_attempts) { |
1386 PrintCaller("Not Optimizable"); | 1386 OS::PrintErr("Not Optimizable: %s\n", function.ToFullyQualifiedCString()); |
1387 } | 1387 } |
1388 // TODO(5442338): Abort as this should not happen. | 1388 // TODO(5442338): Abort as this should not happen. |
1389 function.set_usage_counter(kLowInvocationCount); | 1389 function.set_usage_counter(kLowInvocationCount); |
1390 } | 1390 } |
1391 arguments.SetReturn(Code::Handle(function.CurrentCode())); | 1391 arguments.SetReturn(Code::Handle(function.CurrentCode())); |
1392 } | 1392 } |
1393 | 1393 |
1394 | 1394 |
1395 // The caller must be a static call in a Dart frame, or an entry frame. | 1395 // The caller must be a static call in a Dart frame, or an entry frame. |
1396 // Patch static call to point to valid code's entry point. | 1396 // Patch static call to point to valid code's entry point. |
(...skipping 13 matching lines...) Expand all Loading... |
1410 UNREACHABLE(); | 1410 UNREACHABLE(); |
1411 } | 1411 } |
1412 ASSERT(frame->IsDartFrame()); | 1412 ASSERT(frame->IsDartFrame()); |
1413 const Code& caller_code = Code::Handle(frame->LookupDartCode()); | 1413 const Code& caller_code = Code::Handle(frame->LookupDartCode()); |
1414 const Function& target_function = Function::Handle( | 1414 const Function& target_function = Function::Handle( |
1415 caller_code.GetStaticCallTargetFunctionAt(frame->pc())); | 1415 caller_code.GetStaticCallTargetFunctionAt(frame->pc())); |
1416 const Code& target_code = Code::Handle(target_function.CurrentCode()); | 1416 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
1417 CodePatcher::PatchStaticCallAt(frame->pc(), target_code.EntryPoint()); | 1417 CodePatcher::PatchStaticCallAt(frame->pc(), target_code.EntryPoint()); |
1418 caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code); | 1418 caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code); |
1419 if (FLAG_trace_patching) { | 1419 if (FLAG_trace_patching) { |
1420 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", | 1420 OS::PrintErr("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
1421 frame->pc(), | 1421 frame->pc(), |
1422 Function::Handle(target_code.function()).ToFullyQualifiedCString(), | 1422 Function::Handle(target_code.function()).ToFullyQualifiedCString(), |
1423 target_code.EntryPoint()); | 1423 target_code.EntryPoint()); |
1424 } | 1424 } |
1425 arguments.SetReturn(target_code); | 1425 arguments.SetReturn(target_code); |
1426 } | 1426 } |
1427 | 1427 |
1428 | 1428 |
1429 const char* DeoptReasonToText(intptr_t deopt_id) { | 1429 const char* DeoptReasonToText(intptr_t deopt_id) { |
1430 switch (deopt_id) { | 1430 switch (deopt_id) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 | 1601 |
1602 DeoptInfo& deopt_info = DeoptInfo::Handle(); | 1602 DeoptInfo& deopt_info = DeoptInfo::Handle(); |
1603 DeoptReasonId deopt_reason = kDeoptUnknown; | 1603 DeoptReasonId deopt_reason = kDeoptUnknown; |
1604 GetDeoptInfoAtPc(optimized_code, caller_frame->pc(), &deopt_info, | 1604 GetDeoptInfoAtPc(optimized_code, caller_frame->pc(), &deopt_info, |
1605 &deopt_reason); | 1605 &deopt_reason); |
1606 ASSERT(!deopt_info.IsNull()); | 1606 ASSERT(!deopt_info.IsNull()); |
1607 | 1607 |
1608 CopyFrame(optimized_code, *caller_frame); | 1608 CopyFrame(optimized_code, *caller_frame); |
1609 if (FLAG_trace_deoptimization) { | 1609 if (FLAG_trace_deoptimization) { |
1610 Function& function = Function::Handle(optimized_code.function()); | 1610 Function& function = Function::Handle(optimized_code.function()); |
1611 OS::Print("Deoptimizing (reason %d '%s') at pc %#"Px" '%s' (count %d)\n", | 1611 OS::PrintErr("Deoptimizing (reason %d '%s') at pc %#"Px" '%s' (count %d)\n", |
1612 deopt_reason, | 1612 deopt_reason, |
1613 DeoptReasonToText(deopt_reason), | 1613 DeoptReasonToText(deopt_reason), |
1614 caller_frame->pc(), | 1614 caller_frame->pc(), |
1615 function.ToFullyQualifiedCString(), | 1615 function.ToFullyQualifiedCString(), |
1616 function.deoptimization_counter()); | 1616 function.deoptimization_counter()); |
1617 } | 1617 } |
1618 | 1618 |
1619 // Compute the stack size of the unoptimized frame. For functions with | 1619 // Compute the stack size of the unoptimized frame. For functions with |
1620 // optional arguments the deoptimization info does not describe the | 1620 // optional arguments the deoptimization info does not describe the |
1621 // incoming arguments. | 1621 // incoming arguments. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 DeoptimizationContext deopt_context(start, | 1653 DeoptimizationContext deopt_context(start, |
1654 to_frame_size, | 1654 to_frame_size, |
1655 Array::Handle(code.object_table()), | 1655 Array::Handle(code.object_table()), |
1656 num_args, | 1656 num_args, |
1657 deopt_reason); | 1657 deopt_reason); |
1658 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { | 1658 for (intptr_t to_index = len - 1; to_index >= 0; to_index--) { |
1659 deopt_instructions[to_index]->Execute(&deopt_context, to_index); | 1659 deopt_instructions[to_index]->Execute(&deopt_context, to_index); |
1660 } | 1660 } |
1661 if (FLAG_trace_deoptimization_verbose) { | 1661 if (FLAG_trace_deoptimization_verbose) { |
1662 for (intptr_t i = 0; i < len; i++) { | 1662 for (intptr_t i = 0; i < len; i++) { |
1663 OS::Print("*%"Pd". [%p] %#014"Px" [%s]\n", | 1663 OS::PrintErr("*%"Pd". [%p] %#014"Px" [%s]\n", |
1664 i, | 1664 i, |
1665 &start[i], | 1665 &start[i], |
1666 start[i], | 1666 start[i], |
1667 deopt_instructions[i]->ToCString()); | 1667 deopt_instructions[i]->ToCString()); |
1668 } | 1668 } |
1669 } | 1669 } |
1670 return deopt_context.GetCallerFp(); | 1670 return deopt_context.GetCallerFp(); |
1671 } | 1671 } |
1672 | 1672 |
1673 | 1673 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 DeferredDouble* deferred_double = Isolate::Current()->DetachDeferredDoubles(); | 1719 DeferredDouble* deferred_double = Isolate::Current()->DetachDeferredDoubles(); |
1720 | 1720 |
1721 while (deferred_double != NULL) { | 1721 while (deferred_double != NULL) { |
1722 DeferredDouble* current = deferred_double; | 1722 DeferredDouble* current = deferred_double; |
1723 deferred_double = deferred_double->next(); | 1723 deferred_double = deferred_double->next(); |
1724 | 1724 |
1725 RawDouble** slot = current->slot(); | 1725 RawDouble** slot = current->slot(); |
1726 *slot = Double::New(current->value()); | 1726 *slot = Double::New(current->value()); |
1727 | 1727 |
1728 if (FLAG_trace_deoptimization_verbose) { | 1728 if (FLAG_trace_deoptimization_verbose) { |
1729 OS::Print("materializing double at %"Px": %g\n", | 1729 OS::PrintErr("materializing double at %"Px": %g\n", |
1730 reinterpret_cast<uword>(current->slot()), | 1730 reinterpret_cast<uword>(current->slot()), |
1731 current->value()); | 1731 current->value()); |
1732 } | 1732 } |
1733 | 1733 |
1734 delete current; | 1734 delete current; |
1735 } | 1735 } |
1736 | 1736 |
1737 DeferredMint* deferred_mint = Isolate::Current()->DetachDeferredMints(); | 1737 DeferredMint* deferred_mint = Isolate::Current()->DetachDeferredMints(); |
1738 | 1738 |
1739 while (deferred_mint != NULL) { | 1739 while (deferred_mint != NULL) { |
1740 DeferredMint* current = deferred_mint; | 1740 DeferredMint* current = deferred_mint; |
1741 deferred_mint = deferred_mint->next(); | 1741 deferred_mint = deferred_mint->next(); |
1742 | 1742 |
1743 RawMint** slot = current->slot(); | 1743 RawMint** slot = current->slot(); |
1744 ASSERT(!Smi::IsValid64(current->value())); | 1744 ASSERT(!Smi::IsValid64(current->value())); |
1745 *slot = Mint::New(current->value()); | 1745 *slot = Mint::New(current->value()); |
1746 | 1746 |
1747 if (FLAG_trace_deoptimization_verbose) { | 1747 if (FLAG_trace_deoptimization_verbose) { |
1748 OS::Print("materializing mint at %"Px": %"Pd64"\n", | 1748 OS::PrintErr("materializing mint at %"Px": %"Pd64"\n", |
1749 reinterpret_cast<uword>(current->slot()), | 1749 reinterpret_cast<uword>(current->slot()), |
1750 current->value()); | 1750 current->value()); |
1751 } | 1751 } |
1752 | 1752 |
1753 delete current; | 1753 delete current; |
1754 } | 1754 } |
1755 // Since this is the only step where GC can occur during deoptimization, | 1755 // Since this is the only step where GC can occur during deoptimization, |
1756 // use it to report the source line where deoptimization occured. | 1756 // use it to report the source line where deoptimization occured. |
1757 if (FLAG_trace_deoptimization) { | 1757 if (FLAG_trace_deoptimization) { |
1758 DartFrameIterator iterator; | 1758 DartFrameIterator iterator; |
1759 StackFrame* top_frame = iterator.NextFrame(); | 1759 StackFrame* top_frame = iterator.NextFrame(); |
1760 ASSERT(top_frame != NULL); | 1760 ASSERT(top_frame != NULL); |
1761 const Code& code = Code::Handle(top_frame->LookupDartCode()); | 1761 const Code& code = Code::Handle(top_frame->LookupDartCode()); |
1762 const Function& top_function = Function::Handle(code.function()); | 1762 const Function& top_function = Function::Handle(code.function()); |
1763 const Script& script = Script::Handle(top_function.script()); | 1763 const Script& script = Script::Handle(top_function.script()); |
1764 const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc()); | 1764 const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc()); |
1765 intptr_t line, column; | 1765 intptr_t line, column; |
1766 script.GetTokenLocation(token_pos, &line, &column); | 1766 script.GetTokenLocation(token_pos, &line, &column); |
1767 String& line_string = String::Handle(script.GetLine(line)); | 1767 String& line_string = String::Handle(script.GetLine(line)); |
1768 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1768 OS::PrintErr(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
1769 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1769 OS::PrintErr(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
1770 } | 1770 } |
1771 } | 1771 } |
1772 | 1772 |
1773 | 1773 |
1774 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, | 1774 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, |
1775 BigintCompare, | 1775 BigintCompare, |
1776 RawBigint* left, | 1776 RawBigint* left, |
1777 RawBigint* right) { | 1777 RawBigint* right) { |
1778 Isolate* isolate = Isolate::Current(); | 1778 Isolate* isolate = Isolate::Current(); |
1779 StackZone zone(isolate); | 1779 StackZone zone(isolate); |
(...skipping 14 matching lines...) Expand all Loading... |
1794 return; | 1794 return; |
1795 } | 1795 } |
1796 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); | 1796 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); |
1797 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), | 1797 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), |
1798 field_addr, | 1798 field_addr, |
1799 RawObject::ToAddr(value)); | 1799 RawObject::ToAddr(value)); |
1800 } | 1800 } |
1801 END_LEAF_RUNTIME_ENTRY | 1801 END_LEAF_RUNTIME_ENTRY |
1802 | 1802 |
1803 } // namespace dart | 1803 } // namespace dart |
OLD | NEW |