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

Side by Side Diff: src/profiler/tick-sample.cc

Issue 2138643003: Revert three commits due to cpu-profiler failures (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « src/profiler/tick-sample.h ('k') | test/cctest/libsampler/test-sampler.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/profiler/tick-sample.h" 5 #include "src/profiler/tick-sample.h"
6 6
7 #include "include/v8-profiler.h" 7 #include "include/v8-profiler.h"
8 #include "src/frames-inl.h" 8 #include "src/frames-inl.h"
9 #include "src/msan.h" 9 #include "src/msan.h"
10 #include "src/simulator.h" 10 #include "src/simulator.h"
11 #include "src/vm-state-inl.h" 11 #include "src/vm-state-inl.h"
12 12
13 namespace v8 { 13 namespace v8 {
14
14 namespace { 15 namespace {
15 16
16 bool IsSamePage(i::byte* ptr1, i::byte* ptr2) { 17 bool IsSamePage(i::byte* ptr1, i::byte* ptr2) {
17 const uint32_t kPageSize = 4096; 18 const uint32_t kPageSize = 4096;
18 uintptr_t mask = ~static_cast<uintptr_t>(kPageSize - 1); 19 uintptr_t mask = ~static_cast<uintptr_t>(kPageSize - 1);
19 return (reinterpret_cast<uintptr_t>(ptr1) & mask) == 20 return (reinterpret_cast<uintptr_t>(ptr1) & mask) ==
20 (reinterpret_cast<uintptr_t>(ptr2) & mask); 21 (reinterpret_cast<uintptr_t>(ptr2) & mask);
21 } 22 }
22 23
23 // Check if the code at specified address could potentially be a 24 // Check if the code at specified address could potentially be a
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 if (!memcmp(pc, pattern->bytes + offset, pattern->bytes_count - offset)) 70 if (!memcmp(pc, pattern->bytes + offset, pattern->bytes_count - offset))
70 return true; 71 return true;
71 } 72 }
72 } 73 }
73 } 74 }
74 return false; 75 return false;
75 } 76 }
76 77
77 } // namespace 78 } // namespace
78 79
79 namespace internal {
80 namespace {
81
82 #if defined(USE_SIMULATOR)
83 class SimulatorHelper {
84 public:
85 // Returns true if register values were successfully retrieved
86 // from the simulator, otherwise returns false.
87 static bool FillRegisters(Isolate* isolate, v8::RegisterState* state);
88 };
89
90 bool SimulatorHelper::FillRegisters(Isolate* isolate, RegisterState* state) {
91 Simulator* simulator = isolate->thread_local_top()->simulator_;
92 // Check if there is active simulator.
93 if (simulator == nullptr) return false;
94 #if V8_TARGET_ARCH_ARM
95 if (simulator->has_bad_pc()) return false;
96 state->pc = reinterpret_cast<void*>(simulator->get_pc());
97 state->sp = reinterpret_cast<void*>(simulator->get_register(Simulator::sp));
98 state->fp = reinterpret_cast<void*>(simulator->get_register(Simulator::r11));
99 #elif V8_TARGET_ARCH_ARM64
100 state->pc = reinterpret_cast<void*>(simulator->pc());
101 state->sp = reinterpret_cast<void*>(simulator->sp());
102 state->fp = reinterpret_cast<void*>(simulator->fp());
103 #elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
104 if (simulator->has_bad_pc()) return false;
105 state->pc = reinterpret_cast<void*>(simulator->get_pc());
106 state->sp = reinterpret_cast<void*>(simulator->get_register(Simulator::sp));
107 state->fp = reinterpret_cast<void*>(simulator->get_register(Simulator::fp));
108 #elif V8_TARGET_ARCH_PPC
109 if (simulator->has_bad_pc()) return false;
110 state->pc = reinterpret_cast<void*>(simulator->get_pc());
111 state->sp = reinterpret_cast<void*>(simulator->get_register(Simulator::sp));
112 state->fp = reinterpret_cast<void*>(simulator->get_register(Simulator::fp));
113 #elif V8_TARGET_ARCH_S390
114 if (simulator->has_bad_pc()) return false;
115 state->pc = reinterpret_cast<void*>(simulator->get_pc());
116 state->sp = reinterpret_cast<void*>(simulator->get_register(Simulator::sp));
117 state->fp = reinterpret_cast<void*>(simulator->get_register(Simulator::fp));
118 #endif
119 if (state->sp == 0 || state->fp == 0) {
120 // It possible that the simulator is interrupted while it is updating
121 // the sp or fp register. ARM64 simulator does this in two steps:
122 // first setting it to zero and then setting it to the new value.
123 // Bailout if sp/fp doesn't contain the new value.
124 //
125 // TODO(alph): The above doesn't really solve the issue.
126 // If a 64-bit target is executed on a 32-bit host even the final
127 // write is non-atomic, so it might obtain a half of the result.
128 // Moreover as long as the register set code uses memcpy (as of now),
129 // it is not guaranteed to be atomic even when both host and target
130 // are of same bitness.
131 return false;
132 }
133 return true;
134 }
135 #endif // USE_SIMULATOR
136
137 } // namespace
138 } // namespace internal
139
140 // 80 //
141 // StackTracer implementation 81 // StackTracer implementation
142 // 82 //
143 DISABLE_ASAN void TickSample::Init(Isolate* v8_isolate, 83 DISABLE_ASAN void TickSample::Init(Isolate* v8_isolate,
144 const RegisterState& regs, 84 const RegisterState& regs,
145 RecordCEntryFrame record_c_entry_frame, 85 RecordCEntryFrame record_c_entry_frame,
146 bool update_stats) { 86 bool update_stats) {
147 this->update_stats = update_stats; 87 this->update_stats = update_stats;
88
148 SampleInfo info; 89 SampleInfo info;
149 if (!GetStackSample(v8_isolate, regs, record_c_entry_frame, stack, 90 if (GetStackSample(v8_isolate, const_cast<RegisterState&>(regs),
150 kMaxFramesCount, &info)) { 91 record_c_entry_frame, reinterpret_cast<void**>(&stack[0]),
92 kMaxFramesCount, &info)) {
93 state = info.vm_state;
94 pc = regs.pc;
95 frames_count = static_cast<unsigned>(info.frames_count);
96 has_external_callback = info.external_callback_entry != nullptr;
97 if (has_external_callback) {
98 external_callback_entry = info.external_callback_entry;
99 } else if (frames_count) {
100 // sp register may point at an arbitrary place in memory, make
101 // sure MSAN doesn't complain about it.
102 MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(void*));
103 // Sample potential return address value for frameless invocation of
104 // stubs (we'll figure out later, if this value makes sense).
105 tos = i::Memory::Address_at(reinterpret_cast<i::Address>(regs.sp));
106 } else {
107 tos = nullptr;
108 }
109 } else {
151 // It is executing JS but failed to collect a stack trace. 110 // It is executing JS but failed to collect a stack trace.
152 // Mark the sample as spoiled. 111 // Mark the sample as spoiled.
153 pc = nullptr; 112 pc = nullptr;
154 return;
155 }
156 state = info.vm_state;
157 pc = regs.pc;
158 frames_count = static_cast<unsigned>(info.frames_count);
159 has_external_callback = info.external_callback_entry != nullptr;
160 if (has_external_callback) {
161 external_callback_entry = info.external_callback_entry;
162 } else if (frames_count) {
163 // sp register may point at an arbitrary place in memory, make
164 // sure MSAN doesn't complain about it.
165 MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(void*));
166 // Sample potential return address value for frameless invocation of
167 // stubs (we'll figure out later, if this value makes sense).
168 tos = i::Memory::Address_at(reinterpret_cast<i::Address>(regs.sp));
169 } else {
170 tos = nullptr;
171 } 113 }
172 } 114 }
173 115
174 bool TickSample::GetStackSample(Isolate* v8_isolate, const RegisterState& state, 116 bool TickSample::GetStackSample(Isolate* v8_isolate, const RegisterState& regs,
175 RecordCEntryFrame record_c_entry_frame, 117 RecordCEntryFrame record_c_entry_frame,
176 void** frames, size_t frames_limit, 118 void** frames, size_t frames_limit,
177 v8::SampleInfo* sample_info) { 119 v8::SampleInfo* sample_info) {
178 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 120 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
179 sample_info->frames_count = 0; 121 sample_info->frames_count = 0;
180 sample_info->vm_state = isolate->current_vm_state(); 122 sample_info->vm_state = isolate->current_vm_state();
181 sample_info->external_callback_entry = nullptr; 123 sample_info->external_callback_entry = nullptr;
182 if (sample_info->vm_state == GC) return true; 124 if (sample_info->vm_state == GC) return true;
183 125
184 i::Address js_entry_sp = isolate->js_entry_sp(); 126 i::Address js_entry_sp = isolate->js_entry_sp();
185 if (js_entry_sp == nullptr) return true; // Not executing JS now. 127 if (js_entry_sp == nullptr) return true; // Not executing JS now.
186
187 #if defined(USE_SIMULATOR)
188 v8::RegisterState regs;
189 if (!i::SimulatorHelper::FillRegisters(isolate, &regs)) return false;
190 #else
191 const v8::RegisterState& regs = state;
192 #endif
193 DCHECK(regs.sp); 128 DCHECK(regs.sp);
194 129
195 if (regs.pc && IsNoFrameRegion(static_cast<i::Address>(regs.pc))) { 130 if (regs.pc && IsNoFrameRegion(static_cast<i::Address>(regs.pc))) {
196 // The frame is not setup, so it'd be hard to iterate the stack. Bailout. 131 // Can't collect stack.
197 return false; 132 return false;
198 } 133 }
199 134
200 i::ExternalCallbackScope* scope = isolate->external_callback_scope(); 135 i::ExternalCallbackScope* scope = isolate->external_callback_scope();
201 i::Address handler = i::Isolate::handler(isolate->thread_local_top()); 136 i::Address handler = i::Isolate::handler(isolate->thread_local_top());
202 // If there is a handler on top of the external callback scope then 137 // If there is a handler on top of the external callback scope then
203 // we have already entrered JavaScript again and the external callback 138 // we have already entrered JavaScript again and the external callback
204 // is not the top function. 139 // is not the top function.
205 if (scope && scope->scope_address() < handler) { 140 if (scope && scope->scope_address() < handler) {
206 sample_info->external_callback_entry = 141 sample_info->external_callback_entry =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 176
242 void TickSample::Init(Isolate* isolate, const v8::RegisterState& state, 177 void TickSample::Init(Isolate* isolate, const v8::RegisterState& state,
243 RecordCEntryFrame record_c_entry_frame, 178 RecordCEntryFrame record_c_entry_frame,
244 bool update_stats) { 179 bool update_stats) {
245 v8::TickSample::Init(reinterpret_cast<v8::Isolate*>(isolate), state, 180 v8::TickSample::Init(reinterpret_cast<v8::Isolate*>(isolate), state,
246 record_c_entry_frame, update_stats); 181 record_c_entry_frame, update_stats);
247 if (pc == nullptr) return; 182 if (pc == nullptr) return;
248 timestamp = base::TimeTicks::HighResolutionNow(); 183 timestamp = base::TimeTicks::HighResolutionNow();
249 } 184 }
250 185
186 #if defined(USE_SIMULATOR)
187 bool SimulatorHelper::FillRegisters(Isolate* isolate,
188 v8::RegisterState* state) {
189 Simulator* simulator = isolate->thread_local_top()->simulator_;
190 // Check if there is active simulator.
191 if (simulator == NULL) return false;
192 #if V8_TARGET_ARCH_ARM
193 if (!simulator->has_bad_pc()) {
194 state->pc = reinterpret_cast<Address>(simulator->get_pc());
195 }
196 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
197 state->fp =
198 reinterpret_cast<Address>(simulator->get_register(Simulator::r11));
199 #elif V8_TARGET_ARCH_ARM64
200 state->pc = reinterpret_cast<Address>(simulator->pc());
201 state->sp = reinterpret_cast<Address>(simulator->sp());
202 state->fp = reinterpret_cast<Address>(simulator->fp());
203 #elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
204 if (!simulator->has_bad_pc()) {
205 state->pc = reinterpret_cast<Address>(simulator->get_pc());
206 }
207 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
208 state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
209 #elif V8_TARGET_ARCH_PPC
210 if (!simulator->has_bad_pc()) {
211 state->pc = reinterpret_cast<Address>(simulator->get_pc());
212 }
213 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
214 state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
215 #elif V8_TARGET_ARCH_S390
216 if (!simulator->has_bad_pc()) {
217 state->pc = reinterpret_cast<Address>(simulator->get_pc());
218 }
219 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
220 state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
221 #endif
222 if (state->sp == 0 || state->fp == 0) {
223 // It possible that the simulator is interrupted while it is updating
224 // the sp or fp register. ARM64 simulator does this in two steps:
225 // first setting it to zero and then setting it to the new value.
226 // Bailout if sp/fp doesn't contain the new value.
227 //
228 // FIXME: The above doesn't really solve the issue.
229 // If a 64-bit target is executed on a 32-bit host even the final
230 // write is non-atomic, so it might obtain a half of the result.
231 // Moreover as long as the register set code uses memcpy (as of now),
232 // it is not guaranteed to be atomic even when both host and target
233 // are of same bitness.
234 return false;
235 }
236 return true;
237 }
238 #endif // USE_SIMULATOR
239
251 } // namespace internal 240 } // namespace internal
252 } // namespace v8 241 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/tick-sample.h ('k') | test/cctest/libsampler/test-sampler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698