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

Side by Side Diff: src/frames.cc

Issue 2667253004: [profiler] Fix attribution for the top-most interpreted frame. (Closed)
Patch Set: ASAN workaround Created 3 years, 10 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 | « no previous file | 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/frames.h" 5 #include "src/frames.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 175 }
176 176
177 void StackTraceFrameIterator::AdvanceToArgumentsFrame() { 177 void StackTraceFrameIterator::AdvanceToArgumentsFrame() {
178 if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return; 178 if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return;
179 iterator_.Advance(); 179 iterator_.Advance();
180 DCHECK(iterator_.frame()->is_arguments_adaptor()); 180 DCHECK(iterator_.frame()->is_arguments_adaptor());
181 } 181 }
182 182
183 // ------------------------------------------------------------------------- 183 // -------------------------------------------------------------------------
184 184
185 namespace {
186
187 bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
188 Code* interpreter_entry_trampoline =
189 isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
190 Code* interpreter_bytecode_advance =
191 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
192 Code* interpreter_bytecode_dispatch =
193 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
194
195 return (pc >= interpreter_entry_trampoline->instruction_start() &&
196 pc < interpreter_entry_trampoline->instruction_end()) ||
197 (pc >= interpreter_bytecode_advance->instruction_start() &&
198 pc < interpreter_bytecode_advance->instruction_end()) ||
199 (pc >= interpreter_bytecode_dispatch->instruction_start() &&
200 pc < interpreter_bytecode_dispatch->instruction_end());
201 }
202
203 DISABLE_ASAN Address ReadMemoryAt(Address address) {
204 return Memory::Address_at(address);
205 }
206
207 } // namespace
185 208
186 SafeStackFrameIterator::SafeStackFrameIterator( 209 SafeStackFrameIterator::SafeStackFrameIterator(
187 Isolate* isolate, 210 Isolate* isolate,
188 Address fp, Address sp, Address js_entry_sp) 211 Address fp, Address sp, Address js_entry_sp)
189 : StackFrameIteratorBase(isolate, false), 212 : StackFrameIteratorBase(isolate, false),
190 low_bound_(sp), 213 low_bound_(sp),
191 high_bound_(js_entry_sp), 214 high_bound_(js_entry_sp),
192 top_frame_type_(StackFrame::NONE), 215 top_frame_type_(StackFrame::NONE),
193 external_callback_scope_(isolate->external_callback_scope()) { 216 external_callback_scope_(isolate->external_callback_scope()) {
194 StackFrame::State state; 217 StackFrame::State state;
195 StackFrame::Type type; 218 StackFrame::Type type;
196 ThreadLocalTop* top = isolate->thread_local_top(); 219 ThreadLocalTop* top = isolate->thread_local_top();
220 bool advance_frame = true;
197 if (IsValidTop(top)) { 221 if (IsValidTop(top)) {
198 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); 222 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
199 top_frame_type_ = type; 223 top_frame_type_ = type;
200 } else if (IsValidStackAddress(fp)) { 224 } else if (IsValidStackAddress(fp)) {
201 DCHECK(fp != NULL); 225 DCHECK(fp != NULL);
202 state.fp = fp; 226 state.fp = fp;
203 state.sp = sp; 227 state.sp = sp;
204 state.pc_address = StackFrame::ResolveReturnAddressLocation( 228 state.pc_address = StackFrame::ResolveReturnAddressLocation(
205 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); 229 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
230
231 // If the top of stack is a return address to the interpreter trampoline,
232 // then we are likely in a bytecode handler with elided frame. In that
233 // case, set the PC properly and make sure we do not drop the frame.
234 if (IsValidStackAddress(sp)) {
235 MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
236 Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
237 if (IsInterpreterFramePc(isolate, tos)) {
238 state.pc_address = reinterpret_cast<Address*>(sp);
239 advance_frame = false;
240 }
241 }
242
206 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, 243 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
207 // we check only that kMarkerOffset is within the stack bounds and do 244 // we check only that kMarkerOffset is within the stack bounds and do
208 // compile time check that kContextOffset slot is pushed on the stack before 245 // compile time check that kContextOffset slot is pushed on the stack before
209 // kMarkerOffset. 246 // kMarkerOffset.
210 STATIC_ASSERT(StandardFrameConstants::kFunctionOffset < 247 STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
211 StandardFrameConstants::kContextOffset); 248 StandardFrameConstants::kContextOffset);
212 Address frame_marker = fp + StandardFrameConstants::kFunctionOffset; 249 Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
213 if (IsValidStackAddress(frame_marker)) { 250 if (IsValidStackAddress(frame_marker)) {
214 type = StackFrame::ComputeType(this, &state); 251 type = StackFrame::ComputeType(this, &state);
215 top_frame_type_ = type; 252 top_frame_type_ = type;
253 // We only keep the top frame if we believe it to be interpreted frame.
254 if (type != StackFrame::INTERPRETED) {
255 advance_frame = true;
256 }
216 } else { 257 } else {
217 // Mark the frame as JAVA_SCRIPT if we cannot determine its type. 258 // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
218 // The frame anyways will be skipped. 259 // The frame anyways will be skipped.
219 type = StackFrame::JAVA_SCRIPT; 260 type = StackFrame::JAVA_SCRIPT;
220 // Top frame is incomplete so we cannot reliably determine its type. 261 // Top frame is incomplete so we cannot reliably determine its type.
221 top_frame_type_ = StackFrame::NONE; 262 top_frame_type_ = StackFrame::NONE;
222 } 263 }
223 } else { 264 } else {
224 return; 265 return;
225 } 266 }
226 frame_ = SingletonFor(type, &state); 267 frame_ = SingletonFor(type, &state);
227 if (frame_) Advance(); 268 if (advance_frame && frame_) Advance();
228 } 269 }
229 270
230 271
231 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { 272 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
232 Address c_entry_fp = Isolate::c_entry_fp(top); 273 Address c_entry_fp = Isolate::c_entry_fp(top);
233 if (!IsValidExitFrame(c_entry_fp)) return false; 274 if (!IsValidExitFrame(c_entry_fp)) return false;
234 // There should be at least one JS_ENTRY stack handler. 275 // There should be at least one JS_ENTRY stack handler.
235 Address handler = Isolate::handler(top); 276 Address handler = Isolate::handler(top);
236 if (handler == NULL) return false; 277 if (handler == NULL) return false;
237 // Check that there are no js frames on top of the native frames. 278 // Check that there are no js frames on top of the native frames.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 } 423 }
383 } 424 }
384 425
385 426
386 void StackFrame::SetReturnAddressLocationResolver( 427 void StackFrame::SetReturnAddressLocationResolver(
387 ReturnAddressLocationResolver resolver) { 428 ReturnAddressLocationResolver resolver) {
388 DCHECK(return_address_location_resolver_ == NULL); 429 DCHECK(return_address_location_resolver_ == NULL);
389 return_address_location_resolver_ = resolver; 430 return_address_location_resolver_ = resolver;
390 } 431 }
391 432
392 static bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
393 Code* interpreter_entry_trampoline =
394 isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
395 Code* interpreter_bytecode_advance =
396 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance);
397 Code* interpreter_bytecode_dispatch =
398 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
399
400 return (pc >= interpreter_entry_trampoline->instruction_start() &&
401 pc < interpreter_entry_trampoline->instruction_end()) ||
402 (pc >= interpreter_bytecode_advance->instruction_start() &&
403 pc < interpreter_bytecode_advance->instruction_end()) ||
404 (pc >= interpreter_bytecode_dispatch->instruction_start() &&
405 pc < interpreter_bytecode_dispatch->instruction_end());
406 }
407
408 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, 433 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
409 State* state) { 434 State* state) {
410 DCHECK(state->fp != NULL); 435 DCHECK(state->fp != NULL);
411 436
412 MSAN_MEMORY_IS_INITIALIZED( 437 MSAN_MEMORY_IS_INITIALIZED(
413 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset, 438 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
414 kPointerSize); 439 kPointerSize);
415 Object* marker = Memory::Object_at( 440 Object* marker = Memory::Object_at(
416 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset); 441 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
417 if (!iterator->can_access_heap_objects_) { 442 if (!iterator->can_access_heap_objects_) {
(...skipping 1819 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 2262 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
2238 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 2263 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
2239 list.Add(frame, zone); 2264 list.Add(frame, zone);
2240 } 2265 }
2241 return list.ToVector(); 2266 return list.ToVector();
2242 } 2267 }
2243 2268
2244 2269
2245 } // namespace internal 2270 } // namespace internal
2246 } // namespace v8 2271 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698