| 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 |