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

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

Issue 1435533003: Make profiler work without Instructions -> Code pointer (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « runtime/vm/profiler.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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/profiler_service.h" 5 #include "vm/profiler_service.h"
6 6
7 #include "vm/growable_array.h" 7 #include "vm/growable_array.h"
8 #include "vm/native_symbol.h" 8 #include "vm/native_symbol.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/os.h" 10 #include "vm/os.h"
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 1068
1069 void SanitizeMinMaxTimes() { 1069 void SanitizeMinMaxTimes() {
1070 if ((profile_->min_time_ == kMaxInt64) && (profile_->max_time_ == 0)) { 1070 if ((profile_->min_time_ == kMaxInt64) && (profile_->max_time_ == 0)) {
1071 profile_->min_time_ = 0; 1071 profile_->min_time_ = 0;
1072 profile_->max_time_ = 0; 1072 profile_->max_time_ = 0;
1073 } 1073 }
1074 } 1074 }
1075 1075
1076 void BuildCodeTable() { 1076 void BuildCodeTable() {
1077 ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler); 1077 ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler);
1078
1079 Isolate* isolate = thread_->isolate();
1080 ASSERT(isolate != NULL);
1081
1082 // Build the live code table eagerly by populating it with code objects
1083 // from the processed sample buffer.
1084 const CodeLookupTable& code_lookup_table = samples_->code_lookup_table();
1085 for (intptr_t i = 0; i < code_lookup_table.length(); i++) {
1086 const CodeDescriptor* descriptor = code_lookup_table.At(i);
1087 ASSERT(descriptor != NULL);
1088 const Code& code = Code::Handle(descriptor->code());
1089 ASSERT(!code.IsNull());
1090 RegisterLiveProfileCode(
1091 new ProfileCode(ProfileCode::kDartCode,
1092 code.EntryPoint(),
1093 code.EntryPoint() + code.Size(),
1094 code.compile_timestamp(),
1095 code));
1096 }
1097
1098 // Iterate over samples.
1078 for (intptr_t sample_index = 0; 1099 for (intptr_t sample_index = 0;
1079 sample_index < samples_->length(); 1100 sample_index < samples_->length();
1080 sample_index++) { 1101 sample_index++) {
1081 ProcessedSample* sample = samples_->At(sample_index); 1102 ProcessedSample* sample = samples_->At(sample_index);
1082 const int64_t timestamp = sample->timestamp(); 1103 const int64_t timestamp = sample->timestamp();
1083 1104
1084 // This is our first pass over the sample buffer, use this as an 1105 // This is our first pass over the sample buffer, use this as an
1085 // opportunity to determine the min and max time ranges of this profile. 1106 // opportunity to determine the min and max time ranges of this profile.
1086 UpdateMinMaxTimes(timestamp); 1107 UpdateMinMaxTimes(timestamp);
1087 1108
1088 // Make sure VM tag exists. 1109 // Make sure VM tag exists.
1089 if (VMTag::IsNativeEntryTag(sample->vm_tag())) { 1110 if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
1090 RegisterProfileCodeTag(VMTag::kNativeTagId); 1111 RegisterProfileCodeTag(VMTag::kNativeTagId);
1091 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) { 1112 } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
1092 RegisterProfileCodeTag(VMTag::kRuntimeTagId); 1113 RegisterProfileCodeTag(VMTag::kRuntimeTagId);
1093 } 1114 }
1094 RegisterProfileCodeTag(sample->vm_tag()); 1115 RegisterProfileCodeTag(sample->vm_tag());
1095 // Make sure user tag exists. 1116 // Make sure user tag exists.
1096 RegisterProfileCodeTag(sample->user_tag()); 1117 RegisterProfileCodeTag(sample->user_tag());
1097 1118
1098 // Make sure that a ProfileCode objects exist for all pcs in the sample 1119 // Make sure that a ProfileCode objects exist for all pcs in the sample
1099 // and tick each one. 1120 // and tick each one.
1100 for (intptr_t frame_index = 0; 1121 for (intptr_t frame_index = 0;
1101 frame_index < sample->length(); 1122 frame_index < sample->length();
1102 frame_index++) { 1123 frame_index++) {
1103 const uword pc = sample->At(frame_index); 1124 const uword pc = sample->At(frame_index);
1104 ASSERT(pc != 0); 1125 ASSERT(pc != 0);
1105 ProfileCode* code = RegisterProfileCode(pc, timestamp); 1126 ProfileCode* code = FindOrRegisterProfileCode(pc, timestamp);
1106 ASSERT(code != NULL); 1127 ASSERT(code != NULL);
1107 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index); 1128 code->Tick(pc, IsExecutingFrame(sample, frame_index), sample_index);
1108 } 1129 }
1109 } 1130 }
1110 SanitizeMinMaxTimes(); 1131 SanitizeMinMaxTimes();
1111 } 1132 }
1112 1133
1113 void FinalizeCodeIndexes() { 1134 void FinalizeCodeIndexes() {
1114 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler); 1135 ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler);
1115 ProfileCodeTable* live_table = profile_->live_code_; 1136 ProfileCodeTable* live_table = profile_->live_code_;
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 1851
1831 ProfileCode* CreateProfileCodeReused(uword pc) { 1852 ProfileCode* CreateProfileCodeReused(uword pc) {
1832 ProfileCode* code = new ProfileCode(ProfileCode::kReusedCode, 1853 ProfileCode* code = new ProfileCode(ProfileCode::kReusedCode,
1833 pc, 1854 pc,
1834 pc + 1, 1855 pc + 1,
1835 0, 1856 0,
1836 null_code_); 1857 null_code_);
1837 return code; 1858 return code;
1838 } 1859 }
1839 1860
1840 ProfileCode* CreateProfileCode(uword pc) { 1861 bool IsPCInDartHeap(uword pc) {
1841 const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment(); 1862 return vm_isolate_->heap()->CodeContains(pc) ||
1842 const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1); 1863 thread_->isolate()->heap()->CodeContains(pc);
1843 Code& code = Code::Handle(thread_->zone()); 1864 }
1844 1865
1845 // Check current isolate for pc. 1866
1846 if (thread_->isolate()->heap()->CodeContains(pc)) { 1867 ProfileCode* FindOrRegisterNativeProfileCode(uword pc) {
1847 code ^= Code::LookupCode(pc); 1868 // Check if |pc| is already known in the live code table.
1848 if (!code.IsNull()) { 1869 ProfileCodeTable* live_table = profile_->live_code_;
1849 deoptimized_code_->Add(code); 1870 ProfileCode* profile_code = live_table->FindCodeForPC(pc);
1850 return new ProfileCode(ProfileCode::kDartCode, 1871 if (profile_code != NULL) {
1851 code.EntryPoint(), 1872 return profile_code;
1852 code.EntryPoint() + code.Size(),
1853 code.compile_timestamp(),
1854 code);
1855 }
1856 return new ProfileCode(ProfileCode::kCollectedCode,
1857 pc,
1858 (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
1859 0,
1860 code);
1861 } 1873 }
1862 1874
1863 // Check VM isolate for pc. 1875 // We haven't seen this pc yet.
1864 if (vm_isolate_->heap()->CodeContains(pc)) { 1876 Code& code = Code::Handle(thread_->zone());
1865 code ^= Code::LookupCodeInVmIsolate(pc);
1866 if (!code.IsNull()) {
1867 return new ProfileCode(ProfileCode::kDartCode,
1868 code.EntryPoint(),
1869 code.EntryPoint() + code.Size(),
1870 code.compile_timestamp(),
1871 code);
1872 }
1873 // Precompiled instructions are in the VM isolate, but the code (except
1874 // stubs) is in the current isolate.
1875 code ^= Code::LookupCode(pc);
1876 if (!code.IsNull()) {
1877 return new ProfileCode(ProfileCode::kDartCode,
1878 code.EntryPoint(),
1879 code.EntryPoint() + code.Size(),
1880 code.compile_timestamp(),
1881 code);
1882 }
1883 return new ProfileCode(ProfileCode::kCollectedCode,
1884 pc,
1885 (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
1886 0,
1887 code);
1888 }
1889 1877
1890 // Check NativeSymbolResolver for pc. 1878 // Check NativeSymbolResolver for pc.
1891 uintptr_t native_start = 0; 1879 uintptr_t native_start = 0;
1892 char* native_name = NativeSymbolResolver::LookupSymbolName(pc, 1880 char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
1893 &native_start); 1881 &native_start);
1894 if (native_name == NULL) { 1882 if (native_name == NULL) {
1895 // No native name found. 1883 // Failed to find a native symbol for pc.
1896 return new ProfileCode(ProfileCode::kNativeCode, 1884 native_start = pc;
1897 pc,
1898 pc + 1,
1899 0,
1900 code);
1901 } 1885 }
1902 1886
1903 #if defined(HOST_ARCH_ARM) 1887 #if defined(HOST_ARCH_ARM)
1904 // The symbol for a Thumb function will be xxx1, but we may have samples 1888 // The symbol for a Thumb function will be xxx1, but we may have samples
1905 // at function entry which will have pc xxx0. 1889 // at function entry which will have pc xxx0.
1906 native_start &= ~1; 1890 native_start &= ~1;
1907 #endif 1891 #endif
1908 1892
1909 ASSERT(pc >= native_start); 1893 ASSERT(pc >= native_start);
1910 ProfileCode* profile_code = 1894 profile_code = new ProfileCode(ProfileCode::kNativeCode,
1911 new ProfileCode(ProfileCode::kNativeCode, 1895 native_start,
1912 native_start, 1896 pc + 1,
1913 pc + 1, 1897 0,
1914 0, 1898 code);
1915 code); 1899 if (native_name != NULL) {
1916 profile_code->SetName(native_name); 1900 profile_code->SetName(native_name);
1917 NativeSymbolResolver::FreeSymbolName(native_name); 1901 NativeSymbolResolver::FreeSymbolName(native_name);
1902 }
1903
1904 RegisterLiveProfileCode(profile_code);
1918 return profile_code; 1905 return profile_code;
1919 } 1906 }
1920 1907
1921 ProfileCode* RegisterProfileCode(uword pc, int64_t timestamp) { 1908 void RegisterLiveProfileCode(ProfileCode* code) {
1922 ProfileCodeTable* live_table = profile_->live_code_; 1909 ProfileCodeTable* live_table = profile_->live_code_;
1910 intptr_t index = live_table->InsertCode(code);
1911 ASSERT(index >= 0);
1912 }
1913
1914 ProfileCode* FindOrRegisterDeadProfileCode(uword pc) {
1923 ProfileCodeTable* dead_table = profile_->dead_code_; 1915 ProfileCodeTable* dead_table = profile_->dead_code_;
1924 1916
1925 ProfileCode* code = live_table->FindCodeForPC(pc); 1917 ProfileCode* code = dead_table->FindCodeForPC(pc);
1926 if (code == NULL) {
1927 // Code not found.
1928 intptr_t index = live_table->InsertCode(CreateProfileCode(pc));
1929 ASSERT(index >= 0);
1930 code = live_table->At(index);
1931 if (code->compile_timestamp() <= timestamp) {
1932 // Code was compiled before sample was taken.
1933 return code;
1934 }
1935 // Code was compiled after the sample was taken. Insert code object into
1936 // the dead code table.
1937 index = dead_table->InsertCode(CreateProfileCodeReused(pc));
1938 ASSERT(index >= 0);
1939 return dead_table->At(index);
1940 }
1941 // Existing code found.
1942 if (code->compile_timestamp() <= timestamp) {
1943 // Code was compiled before sample was taken.
1944 return code;
1945 }
1946 // Code was compiled after the sample was taken. Check if we have an entry
1947 // in the dead code table.
1948 code = dead_table->FindCodeForPC(pc);
1949 if (code != NULL) { 1918 if (code != NULL) {
1950 return code; 1919 return code;
1951 } 1920 }
1921
1952 // Create a new dead code entry. 1922 // Create a new dead code entry.
1953 intptr_t index = dead_table->InsertCode(CreateProfileCodeReused(pc)); 1923 intptr_t index = dead_table->InsertCode(CreateProfileCodeReused(pc));
1954 ASSERT(index >= 0); 1924 ASSERT(index >= 0);
1955 return dead_table->At(index); 1925 return dead_table->At(index);
1956 } 1926 }
1957 1927
1928 ProfileCode* FindOrRegisterProfileCode(uword pc, int64_t timestamp) {
1929 ProfileCodeTable* live_table = profile_->live_code_;
1930 ProfileCode* code = live_table->FindCodeForPC(pc);
1931 if ((code != NULL) && (code->compile_timestamp() <= timestamp)) {
1932 // Code was compiled before sample was taken.
1933 return code;
1934 }
1935 if ((code == NULL) && !IsPCInDartHeap(pc)) {
1936 // Not a PC from Dart code. Check with native code.
1937 return FindOrRegisterNativeProfileCode(pc);
1938 }
1939 // We either didn't find the code or it was compiled after the sample.
1940 return FindOrRegisterDeadProfileCode(pc);
1941 }
1942
1958 Profile::TagOrder tag_order() const { 1943 Profile::TagOrder tag_order() const {
1959 return tag_order_; 1944 return tag_order_;
1960 } 1945 }
1961 1946
1962 bool vm_tags_emitted() const { 1947 bool vm_tags_emitted() const {
1963 return (tag_order_ == Profile::kUserVM) || 1948 return (tag_order_ == Profile::kUserVM) ||
1964 (tag_order_ == Profile::kVMUser) || 1949 (tag_order_ == Profile::kVMUser) ||
1965 (tag_order_ == Profile::kVM); 1950 (tag_order_ == Profile::kVM);
1966 } 1951 }
1967 1952
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 Isolate* isolate = thread->isolate(); 2277 Isolate* isolate = thread->isolate();
2293 2278
2294 // Disable thread interrupts while processing the buffer. 2279 // Disable thread interrupts while processing the buffer.
2295 DisableThreadInterruptsScope dtis(thread); 2280 DisableThreadInterruptsScope dtis(thread);
2296 2281
2297 ClearProfileVisitor clear_profile(isolate); 2282 ClearProfileVisitor clear_profile(isolate);
2298 sample_buffer->VisitSamples(&clear_profile); 2283 sample_buffer->VisitSamples(&clear_profile);
2299 } 2284 }
2300 2285
2301 } // namespace dart 2286 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698