Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: runtime/vm/flow_graph_compiler.cc

Issue 2856543002: Use off-heap data for class check instructions (Closed)
Patch Set: Feedback from Slava: rejig inheritance of CallTargets Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/globals.h" // Needed here to get TARGET_ARCH_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/cha.h" 10 #include "vm/cha.h"
(...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1627 } 1627 }
1628 1628
1629 1629
1630 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() { 1630 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() {
1631 if (spilled_) { 1631 if (spilled_) {
1632 resolver_->RestoreScratch(reg_); 1632 resolver_->RestoreScratch(reg_);
1633 } 1633 }
1634 } 1634 }
1635 1635
1636 1636
1637 template <typename T>
1638 static int HighestCountFirst(const T* a, const T* b) {
1639 // Negative if 'a' should sort before 'b'.
1640 return b->count - a->count;
1641 }
1642
1643
1644 static int LowestCidFirst(const CidRangeTarget* a, const CidRangeTarget* b) {
1645 // Negative if 'a' should sort before 'b'.
1646 return a->cid_start - b->cid_start;
1647 }
1648
1649
1650 // Returns 'sorted' array in decreasing count order.
1651 // The expected number of elements to sort is less than 10.
1652 void FlowGraphCompiler::SortICDataByCount(
1653 const ICData& ic_data,
1654 GrowableArray<CidRangeTarget>* sorted_arg,
1655 bool drop_smi) {
1656 GrowableArray<CidRangeTarget>& sorted = *sorted_arg;
1657 ASSERT(ic_data.NumArgsTested() == 1);
1658 const intptr_t len = ic_data.NumberOfChecks();
1659 sorted.Clear();
1660
1661 for (int i = 0; i < len; i++) {
1662 intptr_t receiver_cid = ic_data.GetReceiverClassIdAt(i);
1663 if (drop_smi && (receiver_cid == kSmiCid)) continue;
1664 Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
1665 sorted.Add(CidRangeTarget(receiver_cid, receiver_cid, &target,
1666 ic_data.GetCountAt(i)));
1667 }
1668 sorted.Sort(LowestCidFirst);
1669 int dest = 0;
1670
1671 // Merge adjacent ranges.
1672 for (int src = 0; src < sorted.length(); src++) {
1673 if (src > 0 && sorted[src - 1].cid_end + 1 == sorted[src].cid_start &&
1674 sorted[src - 1].target->raw() == sorted[src].target->raw()) {
1675 sorted[dest - 1].cid_end++;
1676 sorted[dest - 1].count += sorted[dest].count;
1677 } else {
1678 sorted[dest++] = sorted[src];
1679 }
1680 }
1681
1682 sorted.SetLength(dest);
1683 sorted.Sort(HighestCountFirst);
1684 }
1685
1686
1687 const ICData* FlowGraphCompiler::GetOrAddInstanceCallICData( 1637 const ICData* FlowGraphCompiler::GetOrAddInstanceCallICData(
1688 intptr_t deopt_id, 1638 intptr_t deopt_id,
1689 const String& target_name, 1639 const String& target_name,
1690 const Array& arguments_descriptor, 1640 const Array& arguments_descriptor,
1691 intptr_t num_args_tested) { 1641 intptr_t num_args_tested) {
1692 if ((deopt_id_to_ic_data_ != NULL) && 1642 if ((deopt_id_to_ic_data_ != NULL) &&
1693 ((*deopt_id_to_ic_data_)[deopt_id] != NULL)) { 1643 ((*deopt_id_to_ic_data_)[deopt_id] != NULL)) {
1694 const ICData* res = (*deopt_id_to_ic_data_)[deopt_id]; 1644 const ICData* res = (*deopt_id_to_ic_data_)[deopt_id];
1695 ASSERT(res->deopt_id() == deopt_id); 1645 ASSERT(res->deopt_id() == deopt_id);
1696 ASSERT(res->target_name() == target_name.raw()); 1646 ASSERT(res->target_name() == target_name.raw());
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 intptr_t cid, 1746 intptr_t cid,
1797 const String& selector, 1747 const String& selector,
1798 const Array& args_desc_array) { 1748 const Array& args_desc_array) {
1799 Zone* zone = Thread::Current()->zone(); 1749 Zone* zone = Thread::Current()->zone();
1800 1750
1801 ArgumentsDescriptor args_desc(args_desc_array); 1751 ArgumentsDescriptor args_desc(args_desc_array);
1802 1752
1803 Function& fn = Function::ZoneHandle(zone); 1753 Function& fn = Function::ZoneHandle(zone);
1804 if (!LookupMethodFor(cid, selector, args_desc, &fn)) return NULL; 1754 if (!LookupMethodFor(cid, selector, args_desc, &fn)) return NULL;
1805 1755
1806 CallTargets* targets = new (zone) CallTargets(); 1756 CallTargets* targets = new (zone) CallTargets(zone);
1807 targets->Add(CidRangeTarget(cid, cid, &fn, /* count = */ 1)); 1757 targets->Add(new (zone) TargetInfo(cid, cid, &fn, /* count = */ 1));
1808 1758
1809 return targets; 1759 return targets;
1810 } 1760 }
1811 1761
1812 1762
1813 bool FlowGraphCompiler::LookupMethodFor(int class_id, 1763 bool FlowGraphCompiler::LookupMethodFor(int class_id,
1814 const String& name, 1764 const String& name,
1815 const ArgumentsDescriptor& args_desc, 1765 const ArgumentsDescriptor& args_desc,
1816 Function* fn_return) { 1766 Function* fn_return) {
1817 Thread* thread = Thread::Current(); 1767 Thread* thread = Thread::Current();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 } 1874 }
1925 } 1875 }
1926 1876
1927 if (smi_case != kNoCase) { 1877 if (smi_case != kNoCase) {
1928 Label after_smi_test; 1878 Label after_smi_test;
1929 EmitTestAndCallSmiBranch(non_smi_length == 0 ? failed : &after_smi_test, 1879 EmitTestAndCallSmiBranch(non_smi_length == 0 ? failed : &after_smi_test,
1930 /* jump_if_smi= */ false); 1880 /* jump_if_smi= */ false);
1931 1881
1932 // Do not use the code from the function, but let the code be patched so 1882 // Do not use the code from the function, but let the code be patched so
1933 // that we can record the outgoing edges to other code. 1883 // that we can record the outgoing edges to other code.
1934 const Function& function = *targets[smi_case].target; 1884 const Function& function = *targets.TargetAt(smi_case)->target;
1935 GenerateStaticDartCall(deopt_id, token_index, 1885 GenerateStaticDartCall(deopt_id, token_index,
1936 *StubCode::CallStaticFunction_entry(), 1886 *StubCode::CallStaticFunction_entry(),
1937 RawPcDescriptors::kOther, locs, function); 1887 RawPcDescriptors::kOther, locs, function);
1938 __ Drop(argument_count); 1888 __ Drop(argument_count);
1939 if (match_found != NULL) { 1889 if (match_found != NULL) {
1940 __ Jump(match_found); 1890 __ Jump(match_found);
1941 } 1891 }
1942 __ Bind(&after_smi_test); 1892 __ Bind(&after_smi_test);
1943 } else { 1893 } else {
1944 if (!complete) { 1894 if (!complete) {
(...skipping 12 matching lines...) Expand all
1957 int bias = 0; 1907 int bias = 0;
1958 1908
1959 // Value is not Smi. 1909 // Value is not Smi.
1960 EmitTestAndCallLoadCid(); 1910 EmitTestAndCallLoadCid();
1961 1911
1962 int last_check = which_case_to_skip == length - 1 ? length - 2 : length - 1; 1912 int last_check = which_case_to_skip == length - 1 ? length - 2 : length - 1;
1963 1913
1964 for (intptr_t i = 0; i < length; i++) { 1914 for (intptr_t i = 0; i < length; i++) {
1965 if (i == which_case_to_skip) continue; 1915 if (i == which_case_to_skip) continue;
1966 const bool is_last_check = (i == last_check); 1916 const bool is_last_check = (i == last_check);
1967 const int count = targets[i].count; 1917 const int count = targets.TargetAt(i)->count;
1968 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) { 1918 if (!is_last_check && !complete && count < (total_ic_calls >> 5)) {
1969 // This case is hit too rarely to be worth writing class-id checks inline 1919 // This case is hit too rarely to be worth writing class-id checks inline
1970 // for. Note that we can't do this for calls with only one target because 1920 // for. Note that we can't do this for calls with only one target because
1971 // the type propagator may have made use of that and expects a deopt if 1921 // the type propagator may have made use of that and expects a deopt if
1972 // a new class is seen at this calls site. See IsMonomorphic. 1922 // a new class is seen at this calls site. See IsMonomorphic.
1973 add_megamorphic_call = true; 1923 add_megamorphic_call = true;
1974 break; 1924 break;
1975 } 1925 }
1976 Label next_test; 1926 Label next_test;
1977 if (!complete || !is_last_check) { 1927 if (!complete || !is_last_check) {
1978 bias = EmitTestAndCallCheckCid(is_last_check ? failed : &next_test, 1928 bias = EmitTestAndCallCheckCid(is_last_check ? failed : &next_test,
1979 targets[i], bias); 1929 targets[i], bias);
1980 } 1930 }
1981 // Do not use the code from the function, but let the code be patched so 1931 // Do not use the code from the function, but let the code be patched so
1982 // that we can record the outgoing edges to other code. 1932 // that we can record the outgoing edges to other code.
1983 const Function& function = *targets[i].target; 1933 const Function& function = *targets.TargetAt(i)->target;
1984 GenerateStaticDartCall(deopt_id, token_index, 1934 GenerateStaticDartCall(deopt_id, token_index,
1985 *StubCode::CallStaticFunction_entry(), 1935 *StubCode::CallStaticFunction_entry(),
1986 RawPcDescriptors::kOther, locs, function); 1936 RawPcDescriptors::kOther, locs, function);
1987 __ Drop(argument_count); 1937 __ Drop(argument_count);
1988 if (!is_last_check || add_megamorphic_call) { 1938 if (!is_last_check || add_megamorphic_call) {
1989 __ Jump(match_found); 1939 __ Jump(match_found);
1990 } 1940 }
1991 __ Bind(&next_test); 1941 __ Bind(&next_test);
1992 } 1942 }
1993 if (add_megamorphic_call) { 1943 if (add_megamorphic_call) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2069 2019
2070 2020
2071 void FlowGraphCompiler::FrameStateClear() { 2021 void FlowGraphCompiler::FrameStateClear() {
2072 ASSERT(!is_optimizing()); 2022 ASSERT(!is_optimizing());
2073 frame_state_.TruncateTo(0); 2023 frame_state_.TruncateTo(0);
2074 } 2024 }
2075 #endif // defined(DEBUG) && !defined(TARGET_ARCH_DBC) 2025 #endif // defined(DEBUG) && !defined(TARGET_ARCH_DBC)
2076 2026
2077 2027
2078 } // namespace dart 2028 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698