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 |