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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 "Trace IC miss in optimized code"); | 49 "Trace IC miss in optimized code"); |
50 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, | 50 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, |
51 "Trace IC calls in optimized code."); | 51 "Trace IC calls in optimized code."); |
52 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); | 52 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); |
53 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); | 53 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); |
54 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks."); | 54 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks."); |
55 | 55 |
56 DECLARE_FLAG(int, deoptimization_counter_threshold); | 56 DECLARE_FLAG(int, deoptimization_counter_threshold); |
57 DECLARE_FLAG(bool, enable_type_checks); | 57 DECLARE_FLAG(bool, enable_type_checks); |
58 DECLARE_FLAG(bool, report_usage_count); | 58 DECLARE_FLAG(bool, report_usage_count); |
| 59 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
59 | 60 |
60 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement."); | 61 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement."); |
61 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); | 62 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); |
62 | 63 |
63 DEFINE_FLAG(int, stacktrace_every, 0, | 64 DEFINE_FLAG(int, stacktrace_every, 0, |
64 "Compute debugger stacktrace on every N stack overflow checks"); | 65 "Compute debugger stacktrace on every N stack overflow checks"); |
65 DEFINE_FLAG(charp, stacktrace_filter, NULL, | 66 DEFINE_FLAG(charp, stacktrace_filter, NULL, |
66 "Compute stacktrace in named function on stack overflow checks"); | 67 "Compute stacktrace in named function on stack overflow checks"); |
67 DEFINE_FLAG(int, deoptimize_every, 0, | 68 DEFINE_FLAG(int, deoptimize_every, 0, |
68 "Deoptimize on every N stack overflow checks"); | 69 "Deoptimize on every N stack overflow checks"); |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 caller_frame->pc(), | 781 caller_frame->pc(), |
781 Class::Handle(receiver.clazz()).ToCString(), | 782 Class::Handle(receiver.clazz()).ToCString(), |
782 receiver.GetClassId(), | 783 receiver.GetClassId(), |
783 target_function.ToCString()); | 784 target_function.ToCString()); |
784 } | 785 } |
785 } | 786 } |
786 return target_function.raw(); | 787 return target_function.raw(); |
787 } | 788 } |
788 | 789 |
789 | 790 |
790 // Handles inline cache misses by updating the IC data array of the call | 791 static void JSWarning(const ICData& ic_data, const char* msg) { |
791 // site. | 792 DartFrameIterator iterator; |
| 793 StackFrame* caller_frame = iterator.NextFrame(); |
| 794 ASSERT(caller_frame != NULL); |
| 795 // Report warning only if not already reported at this location. |
| 796 if (!ic_data.IssuedJSWarning()) { |
| 797 ic_data.SetIssuedJSWarning(); |
| 798 Exceptions::JSWarning(caller_frame, "%s", msg); |
| 799 } |
| 800 } |
| 801 |
| 802 |
| 803 // Handles inline cache misses by updating the IC data array of the call site. |
792 // Arg0: Receiver object. | 804 // Arg0: Receiver object. |
793 // Arg1: IC data object. | 805 // Arg1: IC data object. |
794 // Returns: target function with compiled code or null. | 806 // Returns: target function with compiled code or null. |
795 // Modifies the instance call to hold the updated IC data array. | 807 // Modifies the instance call to hold the updated IC data array. |
796 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) { | 808 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg, 2) { |
797 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 809 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
798 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 810 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
799 GrowableArray<const Instance*> args(1); | 811 GrowableArray<const Instance*> args(1); |
800 args.Add(&receiver); | 812 args.Add(&receiver); |
| 813 if (FLAG_warn_on_javascript_compatibility) { |
| 814 if (receiver.IsDouble() && |
| 815 String::Handle(ic_data.target_name()).Equals(Symbols::toString())) { |
| 816 const double value = Double::Cast(receiver).value(); |
| 817 if (floor(value) == value) { |
| 818 JSWarning(ic_data, |
| 819 "string representation of an integral value of type " |
| 820 "'double' has no decimal mark and no fractional part"); |
| 821 } |
| 822 } |
| 823 } |
801 const Function& result = | 824 const Function& result = |
802 Function::Handle(InlineCacheMissHandler(args, ic_data)); | 825 Function::Handle(InlineCacheMissHandler(args, ic_data)); |
803 arguments.SetReturn(result); | 826 arguments.SetReturn(result); |
804 } | 827 } |
805 | 828 |
806 | 829 |
807 // Handles inline cache misses by updating the IC data array of the call | 830 // Handles inline cache misses by updating the IC data array of the call site. |
808 // site. | |
809 // Arg0: Receiver object. | 831 // Arg0: Receiver object. |
810 // Arg1: Argument after receiver. | 832 // Arg1: Argument after receiver. |
811 // Arg2: IC data object. | 833 // Arg2: IC data object. |
812 // Returns: target function with compiled code or null. | 834 // Returns: target function with compiled code or null. |
813 // Modifies the instance call to hold the updated IC data array. | 835 // Modifies the instance call to hold the updated IC data array. |
814 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) { | 836 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs, 3) { |
815 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 837 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
816 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); | 838 const Instance& other = Instance::CheckedHandle(arguments.ArgAt(1)); |
817 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); | 839 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); |
818 GrowableArray<const Instance*> args(2); | 840 GrowableArray<const Instance*> args(2); |
819 args.Add(&receiver); | 841 args.Add(&receiver); |
820 args.Add(&other); | 842 args.Add(&other); |
821 const Function& result = | 843 const Function& result = |
822 Function::Handle(InlineCacheMissHandler(args, ic_data)); | 844 Function::Handle(InlineCacheMissHandler(args, ic_data)); |
823 arguments.SetReturn(result); | 845 arguments.SetReturn(result); |
824 } | 846 } |
825 | 847 |
826 | 848 |
827 // Handles inline cache misses by updating the IC data array of the call | 849 // Handles inline cache misses by updating the IC data array of the call site. |
828 // site. | |
829 // Arg0: Receiver object. | 850 // Arg0: Receiver object. |
830 // Arg1: Argument after receiver. | 851 // Arg1: Argument after receiver. |
831 // Arg2: Second argument after receiver. | 852 // Arg2: Second argument after receiver. |
832 // Arg3: IC data object. | 853 // Arg3: IC data object. |
833 // Returns: target function with compiled code or null. | 854 // Returns: target function with compiled code or null. |
834 // Modifies the instance call to hold the updated IC data array. | 855 // Modifies the instance call to hold the updated IC data array. |
835 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 4) { | 856 DEFINE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs, 4) { |
836 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 857 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
837 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); | 858 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); |
838 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); | 859 const Instance& arg2 = Instance::CheckedHandle(arguments.ArgAt(2)); |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1497 // of the given value. | 1518 // of the given value. |
1498 // Arg0: Field object; | 1519 // Arg0: Field object; |
1499 // Arg1: Value that is being stored. | 1520 // Arg1: Value that is being stored. |
1500 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1521 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
1501 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1522 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
1502 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1523 const Object& value = Object::Handle(arguments.ArgAt(1)); |
1503 field.UpdateGuardedCidAndLength(value); | 1524 field.UpdateGuardedCidAndLength(value); |
1504 } | 1525 } |
1505 | 1526 |
1506 } // namespace dart | 1527 } // namespace dart |
OLD | NEW |