OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 #include "ast.h" | 30 #include "ast.h" |
31 #include "deoptimizer.h" | 31 #include "deoptimizer.h" |
32 #include "frames-inl.h" | 32 #include "frames-inl.h" |
33 #include "full-codegen.h" | 33 #include "full-codegen.h" |
34 #include "lazy-instance.h" | 34 #include "lazy-instance.h" |
35 #include "mark-compact.h" | 35 #include "mark-compact.h" |
36 #include "safepoint-table.h" | 36 #include "safepoint-table.h" |
37 #include "scopeinfo.h" | 37 #include "scopeinfo.h" |
38 #include "string-stream.h" | 38 #include "string-stream.h" |
| 39 #include "vm-state-inl.h" |
39 | 40 |
40 #include "allocation-inl.h" | 41 #include "allocation-inl.h" |
41 | 42 |
42 namespace v8 { | 43 namespace v8 { |
43 namespace internal { | 44 namespace internal { |
44 | 45 |
45 | 46 |
46 ReturnAddressLocationResolver | 47 ReturnAddressLocationResolver |
47 StackFrame::return_address_location_resolver_ = NULL; | 48 StackFrame::return_address_location_resolver_ = NULL; |
48 | 49 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 215 |
215 // ------------------------------------------------------------------------- | 216 // ------------------------------------------------------------------------- |
216 | 217 |
217 | 218 |
218 SafeStackFrameIterator::SafeStackFrameIterator( | 219 SafeStackFrameIterator::SafeStackFrameIterator( |
219 Isolate* isolate, | 220 Isolate* isolate, |
220 Address fp, Address sp, Address js_entry_sp) | 221 Address fp, Address sp, Address js_entry_sp) |
221 : StackFrameIteratorBase(isolate, false), | 222 : StackFrameIteratorBase(isolate, false), |
222 low_bound_(sp), | 223 low_bound_(sp), |
223 high_bound_(js_entry_sp), | 224 high_bound_(js_entry_sp), |
224 top_frame_type_(StackFrame::NONE) { | 225 top_frame_type_(StackFrame::NONE), |
| 226 external_callback_scope_(isolate->external_callback_scope()) { |
225 StackFrame::State state; | 227 StackFrame::State state; |
226 StackFrame::Type type; | 228 StackFrame::Type type; |
227 ThreadLocalTop* top = isolate->thread_local_top(); | 229 ThreadLocalTop* top = isolate->thread_local_top(); |
228 if (IsValidTop(top)) { | 230 if (IsValidTop(top)) { |
229 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); | 231 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); |
230 top_frame_type_ = type; | 232 top_frame_type_ = type; |
231 } else if (IsValidStackAddress(fp)) { | 233 } else if (IsValidStackAddress(fp)) { |
232 ASSERT(fp != NULL); | 234 ASSERT(fp != NULL); |
233 state.fp = fp; | 235 state.fp = fp; |
234 state.sp = sp; | 236 state.sp = sp; |
(...skipping 14 matching lines...) Expand all Loading... |
249 // The frame anyways will be skipped. | 251 // The frame anyways will be skipped. |
250 type = StackFrame::JAVA_SCRIPT; | 252 type = StackFrame::JAVA_SCRIPT; |
251 // Top frame is incomplete so we cannot reliably determine its type. | 253 // Top frame is incomplete so we cannot reliably determine its type. |
252 top_frame_type_ = StackFrame::NONE; | 254 top_frame_type_ = StackFrame::NONE; |
253 } | 255 } |
254 } else { | 256 } else { |
255 return; | 257 return; |
256 } | 258 } |
257 if (SingletonFor(type) == NULL) return; | 259 if (SingletonFor(type) == NULL) return; |
258 frame_ = SingletonFor(type, &state); | 260 frame_ = SingletonFor(type, &state); |
| 261 if (frame_ == NULL) return; |
259 | 262 |
260 if (!done()) Advance(); | 263 Advance(); |
| 264 |
| 265 if (frame_ != NULL && !frame_->is_exit() && |
| 266 external_callback_scope_ != NULL && |
| 267 external_callback_scope_->scope_address() < frame_->fp()) { |
| 268 // Skip top ExternalCallbackScope if we already advanced to a JS frame |
| 269 // under it. Sampler will anyways take this top external callback. |
| 270 external_callback_scope_ = external_callback_scope_->previous(); |
| 271 } |
261 } | 272 } |
262 | 273 |
263 | 274 |
264 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { | 275 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { |
265 Address fp = Isolate::c_entry_fp(top); | 276 Address c_entry_fp = Isolate::c_entry_fp(top); |
266 if (!IsValidExitFrame(fp)) return false; | 277 if (!IsValidExitFrame(c_entry_fp)) return false; |
267 // There should be at least one JS_ENTRY stack handler. | 278 // There should be at least one JS_ENTRY stack handler. |
268 return Isolate::handler(top) != NULL; | 279 Address handler = Isolate::handler(top); |
| 280 if (handler == NULL) return false; |
| 281 // Check that there are no js frames on top of the native frames. |
| 282 return c_entry_fp < handler; |
269 } | 283 } |
270 | 284 |
271 | 285 |
272 void SafeStackFrameIterator::AdvanceOneFrame() { | 286 void SafeStackFrameIterator::AdvanceOneFrame() { |
273 ASSERT(!done()); | 287 ASSERT(!done()); |
274 StackFrame* last_frame = frame_; | 288 StackFrame* last_frame = frame_; |
275 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); | 289 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); |
276 // Before advancing to the next stack frame, perform pointer validity tests. | 290 // Before advancing to the next stack frame, perform pointer validity tests. |
277 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) { | 291 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) { |
278 frame_ = NULL; | 292 frame_ = NULL; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 } | 347 } |
334 return *state.pc_address != NULL; | 348 return *state.pc_address != NULL; |
335 } | 349 } |
336 | 350 |
337 | 351 |
338 void SafeStackFrameIterator::Advance() { | 352 void SafeStackFrameIterator::Advance() { |
339 while (true) { | 353 while (true) { |
340 AdvanceOneFrame(); | 354 AdvanceOneFrame(); |
341 if (done()) return; | 355 if (done()) return; |
342 if (frame_->is_java_script()) return; | 356 if (frame_->is_java_script()) return; |
| 357 if (frame_->is_exit() && external_callback_scope_) { |
| 358 // Some of the EXIT frames may have ExternalCallbackScope allocated on |
| 359 // top of them. In that case the scope corresponds to the first EXIT |
| 360 // frame beneath it. There may be other EXIT frames on top of the |
| 361 // ExternalCallbackScope, just skip them as we cannot collect any useful |
| 362 // information about them. |
| 363 if (external_callback_scope_->scope_address() < frame_->fp()) { |
| 364 Address* callback_address = |
| 365 external_callback_scope_->callback_address(); |
| 366 if (*callback_address != NULL) { |
| 367 frame_->state_.pc_address = callback_address; |
| 368 } |
| 369 external_callback_scope_ = external_callback_scope_->previous(); |
| 370 ASSERT(external_callback_scope_ == NULL || |
| 371 external_callback_scope_->scope_address() > frame_->fp()); |
| 372 return; |
| 373 } |
| 374 } |
343 } | 375 } |
344 } | 376 } |
345 | 377 |
346 | 378 |
347 // ------------------------------------------------------------------------- | 379 // ------------------------------------------------------------------------- |
348 | 380 |
349 | 381 |
350 Code* StackFrame::GetSafepointData(Isolate* isolate, | 382 Code* StackFrame::GetSafepointData(Isolate* isolate, |
351 Address inner_pointer, | 383 Address inner_pointer, |
352 SafepointEntry* safepoint_entry, | 384 SafepointEntry* safepoint_entry, |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 ZoneList<StackFrame*> list(10, zone); | 1628 ZoneList<StackFrame*> list(10, zone); |
1597 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1629 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1598 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1630 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1599 list.Add(frame, zone); | 1631 list.Add(frame, zone); |
1600 } | 1632 } |
1601 return list.ToVector(); | 1633 return list.ToVector(); |
1602 } | 1634 } |
1603 | 1635 |
1604 | 1636 |
1605 } } // namespace v8::internal | 1637 } } // namespace v8::internal |
OLD | NEW |