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 15 matching lines...) Expand all Loading... | |
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); |
259 | 261 |
260 if (!done()) Advance(); | 262 if (!done()) Advance(); |
loislo
2013/07/22 14:18:54
if (frame_ == NULL) return;
Advance();
if (frame
yurys
2013/07/22 14:24:08
Done.
| |
263 | |
264 if (done() || frame_->is_exit() || external_callback_scope_ == NULL) return; | |
265 if (external_callback_scope_->scope_address() < frame_->fp()) { | |
266 // Skip top ExternalCallbackScope if we already advanced to a JS frame | |
267 // under it. Sampler will anyways take this top external callback. | |
268 external_callback_scope_ = external_callback_scope_->previous(); | |
269 } | |
261 } | 270 } |
262 | 271 |
263 | 272 |
264 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { | 273 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { |
265 Address fp = Isolate::c_entry_fp(top); | 274 Address c_entry_fp = Isolate::c_entry_fp(top); |
266 if (!IsValidExitFrame(fp)) return false; | 275 if (!IsValidExitFrame(c_entry_fp)) return false; |
267 // There should be at least one JS_ENTRY stack handler. | 276 // There should be at least one JS_ENTRY stack handler. |
268 return Isolate::handler(top) != NULL; | 277 Address handler = Isolate::handler(top); |
278 if (handler == NULL) return false; | |
279 // Check that there are no js frames on top of the native frames. | |
280 return c_entry_fp < handler; | |
269 } | 281 } |
270 | 282 |
271 | 283 |
272 void SafeStackFrameIterator::AdvanceOneFrame() { | 284 void SafeStackFrameIterator::AdvanceOneFrame() { |
273 ASSERT(!done()); | 285 ASSERT(!done()); |
274 StackFrame* last_frame = frame_; | 286 StackFrame* last_frame = frame_; |
275 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); | 287 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); |
276 // Before advancing to the next stack frame, perform pointer validity tests. | 288 // Before advancing to the next stack frame, perform pointer validity tests. |
277 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) { | 289 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) { |
278 frame_ = NULL; | 290 frame_ = NULL; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 } | 345 } |
334 return *state.pc_address != NULL; | 346 return *state.pc_address != NULL; |
335 } | 347 } |
336 | 348 |
337 | 349 |
338 void SafeStackFrameIterator::Advance() { | 350 void SafeStackFrameIterator::Advance() { |
339 while (true) { | 351 while (true) { |
340 AdvanceOneFrame(); | 352 AdvanceOneFrame(); |
341 if (done()) return; | 353 if (done()) return; |
342 if (frame_->is_java_script()) return; | 354 if (frame_->is_java_script()) return; |
355 if (frame_->is_exit() && external_callback_scope_) { | |
356 // Some of the EXIT frames may have ExternalCallbackScope allocated on | |
357 // top of them. In that case the scope corresponds to the first EXIT | |
358 // frame beneath it. There may be other EXIT frames on top of the | |
359 // ExternalCallbackScope, just skip them as we cannot collect any useful | |
360 // information about them. | |
361 if (external_callback_scope_->scope_address() < frame_->fp()) { | |
362 Address* callback_address = | |
363 external_callback_scope_->callback_address(); | |
364 if (*callback_address != NULL) { | |
365 frame_->state_.pc_address = callback_address; | |
366 } | |
367 external_callback_scope_ = external_callback_scope_->previous(); | |
368 return; | |
369 } | |
370 } | |
343 } | 371 } |
344 } | 372 } |
345 | 373 |
346 | 374 |
347 // ------------------------------------------------------------------------- | 375 // ------------------------------------------------------------------------- |
348 | 376 |
349 | 377 |
350 Code* StackFrame::GetSafepointData(Isolate* isolate, | 378 Code* StackFrame::GetSafepointData(Isolate* isolate, |
351 Address inner_pointer, | 379 Address inner_pointer, |
352 SafepointEntry* safepoint_entry, | 380 SafepointEntry* safepoint_entry, |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1596 ZoneList<StackFrame*> list(10, zone); | 1624 ZoneList<StackFrame*> list(10, zone); |
1597 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1625 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1598 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1626 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1599 list.Add(frame, zone); | 1627 list.Add(frame, zone); |
1600 } | 1628 } |
1601 return list.ToVector(); | 1629 return list.ToVector(); |
1602 } | 1630 } |
1603 | 1631 |
1604 | 1632 |
1605 } } // namespace v8::internal | 1633 } } // namespace v8::internal |
OLD | NEW |