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

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

Issue 2049903002: Revert of Move stack trace extraction code out of TickSample::Init (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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') | no next file » | 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 "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/vm-state-inl.h" 8 #include "src/vm-state-inl.h"
9 9
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 namespace { 14 namespace {
15 15
16 bool IsSamePage(byte* ptr1, byte* ptr2) { 16 bool IsSamePage(byte* ptr1, byte* ptr2) {
17 const uint32_t kPageSize = 4096; 17 const uint32_t kPageSize = 4096;
18 uintptr_t mask = ~static_cast<uintptr_t>(kPageSize - 1); 18 uintptr_t mask = ~static_cast<uintptr_t>(kPageSize - 1);
19 return (reinterpret_cast<uintptr_t>(ptr1) & mask) == 19 return (reinterpret_cast<uintptr_t>(ptr1) & mask) ==
20 (reinterpret_cast<uintptr_t>(ptr2) & mask); 20 (reinterpret_cast<uintptr_t>(ptr2) & mask);
21 } 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
24 // frame setup code. 25 // frame setup code.
25 bool IsNoFrameRegion(Address address) { 26 bool IsNoFrameRegion(Address address) {
26 struct Pattern { 27 struct Pattern {
27 int bytes_count; 28 int bytes_count;
28 byte bytes[8]; 29 byte bytes[8];
29 int offsets[4]; 30 int offsets[4];
30 }; 31 };
31 byte* pc = reinterpret_cast<byte*>(address); 32 byte* pc = reinterpret_cast<byte*>(address);
32 static Pattern patterns[] = { 33 static Pattern patterns[] = {
(...skipping 36 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
80
79 // 81 //
80 // StackTracer implementation 82 // StackTracer implementation
81 // 83 //
82 DISABLE_ASAN void TickSample::Init(Isolate* isolate, 84 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
83 const v8::RegisterState& regs, 85 const v8::RegisterState& regs,
84 RecordCEntryFrame record_c_entry_frame, 86 RecordCEntryFrame record_c_entry_frame,
85 bool update_stats) { 87 bool update_stats) {
86 timestamp = base::TimeTicks::HighResolutionNow(); 88 timestamp = base::TimeTicks::HighResolutionNow();
89 pc = reinterpret_cast<Address>(regs.pc);
90 state = isolate->current_vm_state();
87 this->update_stats = update_stats; 91 this->update_stats = update_stats;
88 92
89 SampleInfo info; 93 // Avoid collecting traces while doing GC.
90 if (GetStackSample(isolate, regs, record_c_entry_frame, 94 if (state == GC) return;
91 reinterpret_cast<void**>(&stack[0]), kMaxFramesCount,
92 &info)) {
93 state = info.vm_state;
94 pc = static_cast<Address>(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 =
99 static_cast<Address>(info.external_callback_entry);
100 } else if (frames_count) {
101 // sp register may point at an arbitrary place in memory, make
102 // sure MSAN doesn't complain about it.
103 MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(Address));
104 // Sample potential return address value for frameless invocation of
105 // stubs (we'll figure out later, if this value makes sense).
106 tos = Memory::Address_at(reinterpret_cast<Address>(regs.sp));
107 } else {
108 tos = nullptr;
109 }
110 } else {
111 // It is executing JS but failed to collect a stack trace.
112 // Mark the sample as spoiled.
113 timestamp = base::TimeTicks();
114 pc = nullptr;
115 }
116 }
117
118 bool TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs,
119 RecordCEntryFrame record_c_entry_frame,
120 void** frames, size_t frames_limit,
121 v8::SampleInfo* sample_info) {
122 sample_info->frames_count = 0;
123 sample_info->vm_state = isolate->current_vm_state();
124 sample_info->external_callback_entry = nullptr;
125 if (sample_info->vm_state == GC) return true;
126 95
127 Address js_entry_sp = isolate->js_entry_sp(); 96 Address js_entry_sp = isolate->js_entry_sp();
128 if (js_entry_sp == 0) return true; // Not executing JS now. 97 if (js_entry_sp == 0) return; // Not executing JS now.
129 98
130 if (regs.pc && IsNoFrameRegion(static_cast<Address>(regs.pc))) { 99 if (pc && IsNoFrameRegion(pc)) {
131 // Can't collect stack. 100 // Can't collect stack. Mark the sample as spoiled.
132 return false; 101 timestamp = base::TimeTicks();
102 pc = 0;
103 return;
133 } 104 }
134 105
135 ExternalCallbackScope* scope = isolate->external_callback_scope(); 106 ExternalCallbackScope* scope = isolate->external_callback_scope();
136 Address handler = Isolate::handler(isolate->thread_local_top()); 107 Address handler = Isolate::handler(isolate->thread_local_top());
137 // If there is a handler on top of the external callback scope then 108 // If there is a handler on top of the external callback scope then
138 // we have already entrered JavaScript again and the external callback 109 // we have already entrered JavaScript again and the external callback
139 // is not the top function. 110 // is not the top function.
140 if (scope && scope->scope_address() < handler) { 111 if (scope && scope->scope_address() < handler) {
141 sample_info->external_callback_entry = 112 external_callback_entry = *scope->callback_entrypoint_address();
142 *scope->callback_entrypoint_address(); 113 has_external_callback = true;
114 } else {
115 // sp register may point at an arbitrary place in memory, make
116 // sure MSAN doesn't complain about it.
117 MSAN_MEMORY_IS_INITIALIZED(regs.sp, sizeof(Address));
118 // Sample potential return address value for frameless invocation of
119 // stubs (we'll figure out later, if this value makes sense).
120 tos = Memory::Address_at(reinterpret_cast<Address>(regs.sp));
121 has_external_callback = false;
143 } 122 }
144 123
145 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp), 124 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
146 reinterpret_cast<Address>(regs.sp), js_entry_sp); 125 reinterpret_cast<Address>(regs.sp), js_entry_sp);
126 top_frame_type = it.top_frame_type();
127
128 SampleInfo info;
129 GetStackSample(isolate, regs, record_c_entry_frame,
130 reinterpret_cast<void**>(&stack[0]), kMaxFramesCount, &info);
131 frames_count = static_cast<unsigned>(info.frames_count);
132 if (!frames_count) {
133 // It is executing JS but failed to collect a stack trace.
134 // Mark the sample as spoiled.
135 timestamp = base::TimeTicks();
136 pc = 0;
137 }
138 }
139
140
141 void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs,
142 RecordCEntryFrame record_c_entry_frame,
143 void** frames, size_t frames_limit,
144 v8::SampleInfo* sample_info) {
145 sample_info->frames_count = 0;
146 sample_info->vm_state = isolate->current_vm_state();
147 if (sample_info->vm_state == GC) return;
148
149 Address js_entry_sp = isolate->js_entry_sp();
150 if (js_entry_sp == 0) return; // Not executing JS now.
151
152 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
153 reinterpret_cast<Address>(regs.sp), js_entry_sp);
147 size_t i = 0; 154 size_t i = 0;
148 if (record_c_entry_frame == kIncludeCEntryFrame && !it.done() && 155 if (record_c_entry_frame == kIncludeCEntryFrame && !it.done() &&
149 it.top_frame_type() == StackFrame::EXIT) { 156 it.top_frame_type() == StackFrame::EXIT) {
150 frames[i++] = isolate->c_function(); 157 frames[i++] = isolate->c_function();
151 } 158 }
152 while (!it.done() && i < frames_limit) { 159 while (!it.done() && i < frames_limit) {
153 if (it.frame()->is_interpreted()) { 160 if (it.frame()->is_interpreted()) {
154 // For interpreted frames use the bytecode array pointer as the pc. 161 // For interpreted frames use the bytecode array pointer as the pc.
155 InterpretedFrame* frame = static_cast<InterpretedFrame*>(it.frame()); 162 InterpretedFrame* frame = static_cast<InterpretedFrame*>(it.frame());
156 // Since the sampler can interrupt execution at any point the 163 // Since the sampler can interrupt execution at any point the
157 // bytecode_array might be garbage, so don't dereference it. 164 // bytecode_array might be garbage, so don't dereference it.
158 Address bytecode_array = 165 Address bytecode_array =
159 reinterpret_cast<Address>(frame->GetBytecodeArray()) - kHeapObjectTag; 166 reinterpret_cast<Address>(frame->GetBytecodeArray()) - kHeapObjectTag;
160 frames[i++] = bytecode_array + BytecodeArray::kHeaderSize + 167 frames[i++] = bytecode_array + BytecodeArray::kHeaderSize +
161 frame->GetBytecodeOffset(); 168 frame->GetBytecodeOffset();
162 } else { 169 } else {
163 frames[i++] = it.frame()->pc(); 170 frames[i++] = it.frame()->pc();
164 } 171 }
165 it.Advance(); 172 it.Advance();
166 } 173 }
167 sample_info->frames_count = i; 174 sample_info->frames_count = i;
168 return true;
169 } 175 }
170 176
177
171 #if defined(USE_SIMULATOR) 178 #if defined(USE_SIMULATOR)
172 bool SimulatorHelper::FillRegisters(Isolate* isolate, 179 bool SimulatorHelper::FillRegisters(Isolate* isolate,
173 v8::RegisterState* state) { 180 v8::RegisterState* state) {
174 Simulator *simulator = isolate->thread_local_top()->simulator_; 181 Simulator *simulator = isolate->thread_local_top()->simulator_;
175 // Check if there is active simulator. 182 // Check if there is active simulator.
176 if (simulator == NULL) return false; 183 if (simulator == NULL) return false;
177 #if V8_TARGET_ARCH_ARM 184 #if V8_TARGET_ARCH_ARM
178 if (!simulator->has_bad_pc()) { 185 if (!simulator->has_bad_pc()) {
179 state->pc = reinterpret_cast<Address>(simulator->get_pc()); 186 state->pc = reinterpret_cast<Address>(simulator->get_pc());
180 } 187 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // it is not guaranteed to be atomic even when both host and target 224 // it is not guaranteed to be atomic even when both host and target
218 // are of same bitness. 225 // are of same bitness.
219 return false; 226 return false;
220 } 227 }
221 return true; 228 return true;
222 } 229 }
223 #endif // USE_SIMULATOR 230 #endif // USE_SIMULATOR
224 231
225 } // namespace internal 232 } // namespace internal
226 } // namespace v8 233 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/tick-sample.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698