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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 // ------------------------------------------------------------------------- | 87 // ------------------------------------------------------------------------- |
88 | 88 |
89 | 89 |
90 #define INITIALIZE_SINGLETON(type, field) field##_(this), | 90 #define INITIALIZE_SINGLETON(type, field) field##_(this), |
91 StackFrameIterator::StackFrameIterator(Isolate* isolate) | 91 StackFrameIterator::StackFrameIterator(Isolate* isolate) |
92 : isolate_(isolate), | 92 : isolate_(isolate), |
93 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | 93 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) |
94 frame_(NULL), handler_(NULL), | 94 frame_(NULL), handler_(NULL), |
95 thread_(isolate_->thread_local_top()), | 95 thread_(isolate_->thread_local_top()), |
96 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { | 96 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler), |
| 97 can_access_heap_objects_(true) { |
97 Reset(); | 98 Reset(); |
98 } | 99 } |
99 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) | 100 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) |
100 : isolate_(isolate), | 101 : isolate_(isolate), |
101 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | 102 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) |
102 frame_(NULL), handler_(NULL), thread_(t), | 103 frame_(NULL), handler_(NULL), thread_(t), |
103 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { | 104 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler), |
| 105 can_access_heap_objects_(true) { |
104 Reset(); | 106 Reset(); |
105 } | 107 } |
106 StackFrameIterator::StackFrameIterator(Isolate* isolate, | 108 StackFrameIterator::StackFrameIterator(Isolate* isolate, |
107 bool use_top, Address fp, Address sp) | 109 bool use_top, Address fp, Address sp) |
108 : isolate_(isolate), | 110 : isolate_(isolate), |
109 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | 111 STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) |
110 frame_(NULL), handler_(NULL), | 112 frame_(NULL), handler_(NULL), |
111 thread_(use_top ? isolate_->thread_local_top() : NULL), | 113 thread_(use_top ? isolate_->thread_local_top() : NULL), |
112 fp_(use_top ? NULL : fp), sp_(sp), | 114 fp_(use_top ? NULL : fp), sp_(sp), |
113 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : | 115 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : |
114 &StackFrameIterator::AdvanceWithoutHandler) { | 116 &StackFrameIterator::AdvanceWithoutHandler), |
| 117 can_access_heap_objects_(false) { |
115 if (use_top || fp != NULL) { | 118 if (use_top || fp != NULL) { |
116 Reset(); | 119 Reset(); |
117 } | 120 } |
118 } | 121 } |
119 | 122 |
120 #undef INITIALIZE_SINGLETON | 123 #undef INITIALIZE_SINGLETON |
121 | 124 |
122 | 125 |
123 void StackFrameIterator::AdvanceWithHandler() { | 126 void StackFrameIterator::AdvanceWithHandler() { |
124 ASSERT(!done()); | 127 ASSERT(!done()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 type = ExitFrame::GetStateForFramePointer( | 162 type = ExitFrame::GetStateForFramePointer( |
160 Isolate::c_entry_fp(thread_), &state); | 163 Isolate::c_entry_fp(thread_), &state); |
161 handler_ = StackHandler::FromAddress( | 164 handler_ = StackHandler::FromAddress( |
162 Isolate::handler(thread_)); | 165 Isolate::handler(thread_)); |
163 } else { | 166 } else { |
164 ASSERT(fp_ != NULL); | 167 ASSERT(fp_ != NULL); |
165 state.fp = fp_; | 168 state.fp = fp_; |
166 state.sp = sp_; | 169 state.sp = sp_; |
167 state.pc_address = ResolveReturnAddressLocation( | 170 state.pc_address = ResolveReturnAddressLocation( |
168 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_))); | 171 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_))); |
169 type = StackFrame::ComputeType(isolate(), &state); | 172 type = StackFrame::ComputeType(this, &state); |
170 } | 173 } |
171 if (SingletonFor(type) == NULL) return; | 174 if (SingletonFor(type) == NULL) return; |
172 frame_ = SingletonFor(type, &state); | 175 frame_ = SingletonFor(type, &state); |
173 } | 176 } |
174 | 177 |
175 | 178 |
176 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, | 179 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, |
177 StackFrame::State* state) { | 180 StackFrame::State* state) { |
178 if (type == StackFrame::NONE) return NULL; | 181 if (type == StackFrame::NONE) return NULL; |
179 StackFrame* result = SingletonFor(type); | 182 StackFrame* result = SingletonFor(type); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 if (!validator_.IsValid(sp)) return false; | 264 if (!validator_.IsValid(sp)) return false; |
262 StackFrame::State state; | 265 StackFrame::State state; |
263 ExitFrame::FillState(fp, sp, &state); | 266 ExitFrame::FillState(fp, sp, &state); |
264 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { | 267 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { |
265 return false; | 268 return false; |
266 } | 269 } |
267 return *state.pc_address != NULL; | 270 return *state.pc_address != NULL; |
268 } | 271 } |
269 | 272 |
270 | 273 |
271 SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer( | |
272 Isolate* isolate) | |
273 : isolate_(isolate) { | |
274 isolate_->set_safe_stack_iterator_counter( | |
275 isolate_->safe_stack_iterator_counter() + 1); | |
276 } | |
277 | |
278 | |
279 SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() { | |
280 isolate_->set_safe_stack_iterator_counter( | |
281 isolate_->safe_stack_iterator_counter() - 1); | |
282 } | |
283 | |
284 | |
285 SafeStackFrameIterator::SafeStackFrameIterator( | 274 SafeStackFrameIterator::SafeStackFrameIterator( |
286 Isolate* isolate, | 275 Isolate* isolate, |
287 Address fp, Address sp, Address low_bound, Address high_bound) : | 276 Address fp, Address sp, Address low_bound, Address high_bound) : |
288 maintainer_(isolate), | |
289 stack_validator_(low_bound, high_bound), | 277 stack_validator_(low_bound, high_bound), |
290 is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), | 278 is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), |
291 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), | 279 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), |
292 iteration_done_(!is_valid_top_ && !is_valid_fp_), | 280 iteration_done_(!is_valid_top_ && !is_valid_fp_), |
293 iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { | 281 iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { |
294 if (!done()) Advance(); | 282 if (!done()) Advance(); |
295 } | 283 } |
296 | 284 |
297 bool SafeStackFrameIterator::is_active(Isolate* isolate) { | |
298 return isolate->safe_stack_iterator_counter() > 0; | |
299 } | |
300 | |
301 | 285 |
302 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, | 286 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, |
303 Address low_bound, Address high_bound) { | 287 Address low_bound, Address high_bound) { |
304 ThreadLocalTop* top = isolate->thread_local_top(); | 288 ThreadLocalTop* top = isolate->thread_local_top(); |
305 Address fp = Isolate::c_entry_fp(top); | 289 Address fp = Isolate::c_entry_fp(top); |
306 ExitFrameValidator validator(low_bound, high_bound); | 290 ExitFrameValidator validator(low_bound, high_bound); |
307 if (!validator.IsValidFP(fp)) return false; | 291 if (!validator.IsValidFP(fp)) return false; |
308 return Isolate::handler(top) != NULL; | 292 return Isolate::handler(top) != NULL; |
309 } | 293 } |
310 | 294 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 } | 412 } |
429 | 413 |
430 | 414 |
431 void StackFrame::SetReturnAddressLocationResolver( | 415 void StackFrame::SetReturnAddressLocationResolver( |
432 ReturnAddressLocationResolver resolver) { | 416 ReturnAddressLocationResolver resolver) { |
433 ASSERT(return_address_location_resolver == NULL); | 417 ASSERT(return_address_location_resolver == NULL); |
434 return_address_location_resolver = resolver; | 418 return_address_location_resolver = resolver; |
435 } | 419 } |
436 | 420 |
437 | 421 |
438 StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) { | 422 StackFrame::Type StackFrame::ComputeType(const StackFrameIterator* iterator, |
| 423 State* state) { |
439 ASSERT(state->fp != NULL); | 424 ASSERT(state->fp != NULL); |
440 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { | 425 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
441 return ARGUMENTS_ADAPTOR; | 426 return ARGUMENTS_ADAPTOR; |
442 } | 427 } |
443 // The marker and function offsets overlap. If the marker isn't a | 428 // The marker and function offsets overlap. If the marker isn't a |
444 // smi then the frame is a JavaScript frame -- and the marker is | 429 // smi then the frame is a JavaScript frame -- and the marker is |
445 // really the function. | 430 // really the function. |
446 const int offset = StandardFrameConstants::kMarkerOffset; | 431 const int offset = StandardFrameConstants::kMarkerOffset; |
447 Object* marker = Memory::Object_at(state->fp + offset); | 432 Object* marker = Memory::Object_at(state->fp + offset); |
448 if (!marker->IsSmi()) { | 433 if (!marker->IsSmi()) { |
449 // If we're using a "safe" stack iterator, we treat optimized | 434 // If we're using a "safe" stack iterator, we treat optimized |
450 // frames as normal JavaScript frames to avoid having to look | 435 // frames as normal JavaScript frames to avoid having to look |
451 // into the heap to determine the state. This is safe as long | 436 // into the heap to determine the state. This is safe as long |
452 // as nobody tries to GC... | 437 // as nobody tries to GC... |
453 if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT; | 438 if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT; |
454 Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind(); | 439 Code::Kind kind = GetContainingCode(iterator->isolate(), |
| 440 *(state->pc_address))->kind(); |
455 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); | 441 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); |
456 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; | 442 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; |
457 } | 443 } |
458 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 444 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
459 } | 445 } |
460 | 446 |
461 | 447 |
| 448 #ifdef DEBUG |
| 449 bool StackFrame::can_access_heap_objects() const { |
| 450 return iterator_->can_access_heap_objects_; |
| 451 } |
| 452 #endif |
| 453 |
462 | 454 |
463 StackFrame::Type StackFrame::GetCallerState(State* state) const { | 455 StackFrame::Type StackFrame::GetCallerState(State* state) const { |
464 ComputeCallerState(state); | 456 ComputeCallerState(state); |
465 return ComputeType(isolate(), state); | 457 return ComputeType(iterator_, state); |
466 } | 458 } |
467 | 459 |
468 | 460 |
469 Address StackFrame::UnpaddedFP() const { | 461 Address StackFrame::UnpaddedFP() const { |
470 #if defined(V8_TARGET_ARCH_IA32) | 462 #if defined(V8_TARGET_ARCH_IA32) |
471 if (!is_optimized()) return fp(); | 463 if (!is_optimized()) return fp(); |
472 int32_t alignment_state = Memory::int32_at( | 464 int32_t alignment_state = Memory::int32_at( |
473 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset); | 465 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset); |
474 | 466 |
475 return (alignment_state == kAlignmentPaddingPushed) ? | 467 return (alignment_state == kAlignmentPaddingPushed) ? |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { | 607 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { |
616 if (it.handler()->includes(address)) return true; | 608 if (it.handler()->includes(address)) return true; |
617 } | 609 } |
618 return false; | 610 return false; |
619 } | 611 } |
620 | 612 |
621 | 613 |
622 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { | 614 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { |
623 // Make sure that we're not doing "safe" stack frame iteration. We cannot | 615 // Make sure that we're not doing "safe" stack frame iteration. We cannot |
624 // possibly find pointers in optimized frames in that state. | 616 // possibly find pointers in optimized frames in that state. |
625 ASSERT(!SafeStackFrameIterator::is_active(isolate())); | 617 ASSERT(can_access_heap_objects()); |
626 | 618 |
627 // Compute the safepoint information. | 619 // Compute the safepoint information. |
628 unsigned stack_slots = 0; | 620 unsigned stack_slots = 0; |
629 SafepointEntry safepoint_entry; | 621 SafepointEntry safepoint_entry; |
630 Code* code = StackFrame::GetSafepointData( | 622 Code* code = StackFrame::GetSafepointData( |
631 isolate(), pc(), &safepoint_entry, &stack_slots); | 623 isolate(), pc(), &safepoint_entry, &stack_slots); |
632 unsigned slot_space = stack_slots * kPointerSize; | 624 unsigned slot_space = stack_slots * kPointerSize; |
633 | 625 |
634 // Visit the outgoing parameters. | 626 // Visit the outgoing parameters. |
635 Object** parameters_base = &Memory::Object_at(sp()); | 627 Object** parameters_base = &Memory::Object_at(sp()); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 } | 739 } |
748 | 740 |
749 | 741 |
750 Code* JavaScriptFrame::unchecked_code() const { | 742 Code* JavaScriptFrame::unchecked_code() const { |
751 JSFunction* function = JSFunction::cast(this->function()); | 743 JSFunction* function = JSFunction::cast(this->function()); |
752 return function->unchecked_code(); | 744 return function->unchecked_code(); |
753 } | 745 } |
754 | 746 |
755 | 747 |
756 int JavaScriptFrame::GetNumberOfIncomingArguments() const { | 748 int JavaScriptFrame::GetNumberOfIncomingArguments() const { |
757 ASSERT(!SafeStackFrameIterator::is_active(isolate()) && | 749 ASSERT(can_access_heap_objects() && |
758 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); | 750 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); |
759 | 751 |
760 JSFunction* function = JSFunction::cast(this->function()); | 752 JSFunction* function = JSFunction::cast(this->function()); |
761 return function->shared()->formal_parameter_count(); | 753 return function->shared()->formal_parameter_count(); |
762 } | 754 } |
763 | 755 |
764 | 756 |
765 Address JavaScriptFrame::GetCallerStackPointer() const { | 757 Address JavaScriptFrame::GetCallerStackPointer() const { |
766 return fp() + StandardFrameConstants::kCallerSPOffset; | 758 return fp() + StandardFrameConstants::kCallerSPOffset; |
767 } | 759 } |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 ZoneList<StackFrame*> list(10, zone); | 1621 ZoneList<StackFrame*> list(10, zone); |
1630 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1622 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1631 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1623 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1632 list.Add(frame, zone); | 1624 list.Add(frame, zone); |
1633 } | 1625 } |
1634 return list.ToVector(); | 1626 return list.ToVector(); |
1635 } | 1627 } |
1636 | 1628 |
1637 | 1629 |
1638 } } // namespace v8::internal | 1630 } } // namespace v8::internal |
OLD | NEW |