| OLD | NEW |
| 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 <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
| 10 #include "src/ast/scopeinfo.h" | 10 #include "src/ast/scopeinfo.h" |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 type = StackFrame::JAVA_SCRIPT; | 228 type = StackFrame::JAVA_SCRIPT; |
| 229 // Top frame is incomplete so we cannot reliably determine its type. | 229 // Top frame is incomplete so we cannot reliably determine its type. |
| 230 top_frame_type_ = StackFrame::NONE; | 230 top_frame_type_ = StackFrame::NONE; |
| 231 } | 231 } |
| 232 } else { | 232 } else { |
| 233 return; | 233 return; |
| 234 } | 234 } |
| 235 if (SingletonFor(type) == NULL) return; | 235 if (SingletonFor(type) == NULL) return; |
| 236 frame_ = SingletonFor(type, &state); | 236 frame_ = SingletonFor(type, &state); |
| 237 DCHECK(frame_); | 237 DCHECK(frame_); |
| 238 | |
| 239 Advance(); | 238 Advance(); |
| 240 | |
| 241 if (frame_ != NULL && !frame_->is_exit() && | |
| 242 external_callback_scope_ != NULL && | |
| 243 external_callback_scope_->scope_address() < frame_->fp()) { | |
| 244 // Skip top ExternalCallbackScope if we already advanced to a JS frame | |
| 245 // under it. Sampler will anyways take this top external callback. | |
| 246 external_callback_scope_ = external_callback_scope_->previous(); | |
| 247 } | |
| 248 } | 239 } |
| 249 | 240 |
| 250 | 241 |
| 251 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { | 242 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { |
| 252 Address c_entry_fp = Isolate::c_entry_fp(top); | 243 Address c_entry_fp = Isolate::c_entry_fp(top); |
| 253 if (!IsValidExitFrame(c_entry_fp)) return false; | 244 if (!IsValidExitFrame(c_entry_fp)) return false; |
| 254 // There should be at least one JS_ENTRY stack handler. | 245 // There should be at least one JS_ENTRY stack handler. |
| 255 Address handler = Isolate::handler(top); | 246 Address handler = Isolate::handler(top); |
| 256 if (handler == NULL) return false; | 247 if (handler == NULL) return false; |
| 257 // Check that there are no js frames on top of the native frames. | 248 // Check that there are no js frames on top of the native frames. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 if (!IsValidStackAddress(sp)) return false; | 313 if (!IsValidStackAddress(sp)) return false; |
| 323 StackFrame::State state; | 314 StackFrame::State state; |
| 324 ExitFrame::FillState(fp, sp, &state); | 315 ExitFrame::FillState(fp, sp, &state); |
| 325 return *state.pc_address != NULL; | 316 return *state.pc_address != NULL; |
| 326 } | 317 } |
| 327 | 318 |
| 328 | 319 |
| 329 void SafeStackFrameIterator::Advance() { | 320 void SafeStackFrameIterator::Advance() { |
| 330 while (true) { | 321 while (true) { |
| 331 AdvanceOneFrame(); | 322 AdvanceOneFrame(); |
| 332 if (done()) return; | 323 if (done()) break; |
| 333 if (frame_->is_java_script()) return; | 324 ExternalCallbackScope* last_callback_scope = NULL; |
| 334 if (frame_->is_exit() && external_callback_scope_) { | 325 while (external_callback_scope_ != NULL && |
| 326 external_callback_scope_->scope_address() < frame_->fp()) { |
| 327 // As long as the setup of a frame is not atomic, we may happen to be |
| 328 // in an interval where an ExternalCallbackScope is already created, |
| 329 // but the frame is not yet entered. So we are actually observing |
| 330 // the previous frame. |
| 331 // Skip all the ExternalCallbackScope's that are below the current fp. |
| 332 last_callback_scope = external_callback_scope_; |
| 333 external_callback_scope_ = external_callback_scope_->previous(); |
| 334 } |
| 335 if (frame_->is_java_script()) break; |
| 336 if (frame_->is_exit()) { |
| 335 // Some of the EXIT frames may have ExternalCallbackScope allocated on | 337 // Some of the EXIT frames may have ExternalCallbackScope allocated on |
| 336 // top of them. In that case the scope corresponds to the first EXIT | 338 // top of them. In that case the scope corresponds to the first EXIT |
| 337 // frame beneath it. There may be other EXIT frames on top of the | 339 // frame beneath it. There may be other EXIT frames on top of the |
| 338 // ExternalCallbackScope, just skip them as we cannot collect any useful | 340 // ExternalCallbackScope, just skip them as we cannot collect any useful |
| 339 // information about them. | 341 // information about them. |
| 340 if (external_callback_scope_->scope_address() < frame_->fp()) { | 342 if (last_callback_scope) { |
| 341 frame_->state_.pc_address = | 343 frame_->state_.pc_address = |
| 342 external_callback_scope_->callback_entrypoint_address(); | 344 last_callback_scope->callback_entrypoint_address(); |
| 343 external_callback_scope_ = external_callback_scope_->previous(); | |
| 344 DCHECK(external_callback_scope_ == NULL || | |
| 345 external_callback_scope_->scope_address() > frame_->fp()); | |
| 346 return; | |
| 347 } | 345 } |
| 346 break; |
| 348 } | 347 } |
| 349 } | 348 } |
| 350 } | 349 } |
| 351 | 350 |
| 352 | 351 |
| 353 // ------------------------------------------------------------------------- | 352 // ------------------------------------------------------------------------- |
| 354 | 353 |
| 355 | 354 |
| 356 Code* StackFrame::GetSafepointData(Isolate* isolate, | 355 Code* StackFrame::GetSafepointData(Isolate* isolate, |
| 357 Address inner_pointer, | 356 Address inner_pointer, |
| (...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1633 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 1635 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1634 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 1636 list.Add(frame, zone); | 1635 list.Add(frame, zone); |
| 1637 } | 1636 } |
| 1638 return list.ToVector(); | 1637 return list.ToVector(); |
| 1639 } | 1638 } |
| 1640 | 1639 |
| 1641 | 1640 |
| 1642 } // namespace internal | 1641 } // namespace internal |
| 1643 } // namespace v8 | 1642 } // namespace v8 |
| OLD | NEW |