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 29 matching lines...) Expand all Loading... |
40 // Get the number of registers in a given register list. | 40 // Get the number of registers in a given register list. |
41 int NumRegs(RegList list); | 41 int NumRegs(RegList list); |
42 | 42 |
43 void SetUpJSCallerSavedCodeData(); | 43 void SetUpJSCallerSavedCodeData(); |
44 | 44 |
45 // Return the code of the n-th saved register available to JavaScript. | 45 // Return the code of the n-th saved register available to JavaScript. |
46 int JSCallerSavedCode(int n); | 46 int JSCallerSavedCode(int n); |
47 | 47 |
48 | 48 |
49 // Forward declarations. | 49 // Forward declarations. |
50 class StackFrameIterator; | 50 class StackFrameIteratorBase; |
51 class ThreadLocalTop; | 51 class ThreadLocalTop; |
52 class Isolate; | 52 class Isolate; |
53 | 53 |
54 class InnerPointerToCodeCache { | 54 class InnerPointerToCodeCache { |
55 public: | 55 public: |
56 struct InnerPointerToCodeCacheEntry { | 56 struct InnerPointerToCodeCacheEntry { |
57 Address inner_pointer; | 57 Address inner_pointer; |
58 Code* code; | 58 Code* code; |
59 SafepointEntry safepoint_entry; | 59 SafepointEntry safepoint_entry; |
60 }; | 60 }; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 | 299 |
300 // Printing support. | 300 // Printing support. |
301 enum PrintMode { OVERVIEW, DETAILS }; | 301 enum PrintMode { OVERVIEW, DETAILS }; |
302 virtual void Print(StringStream* accumulator, | 302 virtual void Print(StringStream* accumulator, |
303 PrintMode mode, | 303 PrintMode mode, |
304 int index) const { } | 304 int index) const { } |
305 | 305 |
306 Isolate* isolate() const { return isolate_; } | 306 Isolate* isolate() const { return isolate_; } |
307 | 307 |
308 protected: | 308 protected: |
309 inline explicit StackFrame(StackFrameIterator* iterator); | 309 inline explicit StackFrame(StackFrameIteratorBase* iterator); |
310 virtual ~StackFrame() { } | 310 virtual ~StackFrame() { } |
311 | 311 |
312 // Compute the stack pointer for the calling frame. | 312 // Compute the stack pointer for the calling frame. |
313 virtual Address GetCallerStackPointer() const = 0; | 313 virtual Address GetCallerStackPointer() const = 0; |
314 | 314 |
315 // Printing support. | 315 // Printing support. |
316 static void PrintIndex(StringStream* accumulator, | 316 static void PrintIndex(StringStream* accumulator, |
317 PrintMode mode, | 317 PrintMode mode, |
318 int index); | 318 int index); |
319 | 319 |
320 // Get the top handler from the current stack iterator. | 320 // Get the top handler from the current stack iterator. |
321 inline StackHandler* top_handler() const; | 321 inline StackHandler* top_handler() const; |
322 | 322 |
323 // Compute the stack frame type for the given state. | 323 // Compute the stack frame type for the given state. |
324 static Type ComputeType(const StackFrameIterator* iterator, State* state); | 324 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state); |
325 | 325 |
326 #ifdef DEBUG | 326 #ifdef DEBUG |
327 bool can_access_heap_objects() const; | 327 bool can_access_heap_objects() const; |
328 #endif | 328 #endif |
329 | 329 |
330 private: | 330 private: |
331 const StackFrameIterator* iterator_; | 331 const StackFrameIteratorBase* iterator_; |
332 Isolate* isolate_; | 332 Isolate* isolate_; |
333 State state_; | 333 State state_; |
334 | 334 |
335 // Fill in the state of the calling frame. | 335 // Fill in the state of the calling frame. |
336 virtual void ComputeCallerState(State* state) const = 0; | 336 virtual void ComputeCallerState(State* state) const = 0; |
337 | 337 |
338 // Get the type and the state of the calling frame. | 338 // Get the type and the state of the calling frame. |
339 virtual Type GetCallerState(State* state) const; | 339 virtual Type GetCallerState(State* state) const; |
340 | 340 |
341 static const intptr_t kIsolateTag = 1; | 341 static const intptr_t kIsolateTag = 1; |
342 | 342 |
343 friend class StackFrameIterator; | 343 friend class StackFrameIterator; |
| 344 friend class StackFrameIteratorBase; |
344 friend class StackHandlerIterator; | 345 friend class StackHandlerIterator; |
345 friend class SafeStackFrameIterator; | 346 friend class SafeStackFrameIterator; |
346 | 347 |
347 private: | 348 private: |
348 void operator=(const StackFrame& original); | 349 void operator=(const StackFrame& original); |
349 }; | 350 }; |
350 | 351 |
351 | 352 |
352 // Entry frames are used to enter JavaScript execution from C. | 353 // Entry frames are used to enter JavaScript execution from C. |
353 class EntryFrame: public StackFrame { | 354 class EntryFrame: public StackFrame { |
354 public: | 355 public: |
355 virtual Type type() const { return ENTRY; } | 356 virtual Type type() const { return ENTRY; } |
356 | 357 |
357 virtual Code* unchecked_code() const; | 358 virtual Code* unchecked_code() const; |
358 | 359 |
359 // Garbage collection support. | 360 // Garbage collection support. |
360 virtual void Iterate(ObjectVisitor* v) const; | 361 virtual void Iterate(ObjectVisitor* v) const; |
361 | 362 |
362 static EntryFrame* cast(StackFrame* frame) { | 363 static EntryFrame* cast(StackFrame* frame) { |
363 ASSERT(frame->is_entry()); | 364 ASSERT(frame->is_entry()); |
364 return static_cast<EntryFrame*>(frame); | 365 return static_cast<EntryFrame*>(frame); |
365 } | 366 } |
366 virtual void SetCallerFp(Address caller_fp); | 367 virtual void SetCallerFp(Address caller_fp); |
367 | 368 |
368 protected: | 369 protected: |
369 inline explicit EntryFrame(StackFrameIterator* iterator); | 370 inline explicit EntryFrame(StackFrameIteratorBase* iterator); |
370 | 371 |
371 // The caller stack pointer for entry frames is always zero. The | 372 // The caller stack pointer for entry frames is always zero. The |
372 // real information about the caller frame is available through the | 373 // real information about the caller frame is available through the |
373 // link to the top exit frame. | 374 // link to the top exit frame. |
374 virtual Address GetCallerStackPointer() const { return 0; } | 375 virtual Address GetCallerStackPointer() const { return 0; } |
375 | 376 |
376 private: | 377 private: |
377 virtual void ComputeCallerState(State* state) const; | 378 virtual void ComputeCallerState(State* state) const; |
378 virtual Type GetCallerState(State* state) const; | 379 virtual Type GetCallerState(State* state) const; |
379 | 380 |
380 friend class StackFrameIterator; | 381 friend class StackFrameIteratorBase; |
381 }; | 382 }; |
382 | 383 |
383 | 384 |
384 class EntryConstructFrame: public EntryFrame { | 385 class EntryConstructFrame: public EntryFrame { |
385 public: | 386 public: |
386 virtual Type type() const { return ENTRY_CONSTRUCT; } | 387 virtual Type type() const { return ENTRY_CONSTRUCT; } |
387 | 388 |
388 virtual Code* unchecked_code() const; | 389 virtual Code* unchecked_code() const; |
389 | 390 |
390 static EntryConstructFrame* cast(StackFrame* frame) { | 391 static EntryConstructFrame* cast(StackFrame* frame) { |
391 ASSERT(frame->is_entry_construct()); | 392 ASSERT(frame->is_entry_construct()); |
392 return static_cast<EntryConstructFrame*>(frame); | 393 return static_cast<EntryConstructFrame*>(frame); |
393 } | 394 } |
394 | 395 |
395 protected: | 396 protected: |
396 inline explicit EntryConstructFrame(StackFrameIterator* iterator); | 397 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator); |
397 | 398 |
398 private: | 399 private: |
399 friend class StackFrameIterator; | 400 friend class StackFrameIteratorBase; |
400 }; | 401 }; |
401 | 402 |
402 | 403 |
403 // Exit frames are used to exit JavaScript execution and go to C. | 404 // Exit frames are used to exit JavaScript execution and go to C. |
404 class ExitFrame: public StackFrame { | 405 class ExitFrame: public StackFrame { |
405 public: | 406 public: |
406 virtual Type type() const { return EXIT; } | 407 virtual Type type() const { return EXIT; } |
407 | 408 |
408 virtual Code* unchecked_code() const; | 409 virtual Code* unchecked_code() const; |
409 | 410 |
(...skipping 10 matching lines...) Expand all Loading... |
420 } | 421 } |
421 | 422 |
422 // Compute the state and type of an exit frame given a frame | 423 // Compute the state and type of an exit frame given a frame |
423 // pointer. Used when constructing the first stack frame seen by an | 424 // pointer. Used when constructing the first stack frame seen by an |
424 // iterator and the frames following entry frames. | 425 // iterator and the frames following entry frames. |
425 static Type GetStateForFramePointer(Address fp, State* state); | 426 static Type GetStateForFramePointer(Address fp, State* state); |
426 static Address ComputeStackPointer(Address fp); | 427 static Address ComputeStackPointer(Address fp); |
427 static void FillState(Address fp, Address sp, State* state); | 428 static void FillState(Address fp, Address sp, State* state); |
428 | 429 |
429 protected: | 430 protected: |
430 inline explicit ExitFrame(StackFrameIterator* iterator); | 431 inline explicit ExitFrame(StackFrameIteratorBase* iterator); |
431 | 432 |
432 virtual Address GetCallerStackPointer() const; | 433 virtual Address GetCallerStackPointer() const; |
433 | 434 |
434 private: | 435 private: |
435 virtual void ComputeCallerState(State* state) const; | 436 virtual void ComputeCallerState(State* state) const; |
436 | 437 |
437 friend class StackFrameIterator; | 438 friend class StackFrameIteratorBase; |
438 }; | 439 }; |
439 | 440 |
440 | 441 |
441 class StandardFrame: public StackFrame { | 442 class StandardFrame: public StackFrame { |
442 public: | 443 public: |
443 // Testers. | 444 // Testers. |
444 virtual bool is_standard() const { return true; } | 445 virtual bool is_standard() const { return true; } |
445 | 446 |
446 // Accessors. | 447 // Accessors. |
447 inline Object* context() const; | 448 inline Object* context() const; |
448 | 449 |
449 // Access the expressions in the stack frame including locals. | 450 // Access the expressions in the stack frame including locals. |
450 inline Object* GetExpression(int index) const; | 451 inline Object* GetExpression(int index) const; |
451 inline void SetExpression(int index, Object* value); | 452 inline void SetExpression(int index, Object* value); |
452 int ComputeExpressionsCount() const; | 453 int ComputeExpressionsCount() const; |
453 static Object* GetExpression(Address fp, int index); | 454 static Object* GetExpression(Address fp, int index); |
454 | 455 |
455 virtual void SetCallerFp(Address caller_fp); | 456 virtual void SetCallerFp(Address caller_fp); |
456 | 457 |
457 static StandardFrame* cast(StackFrame* frame) { | 458 static StandardFrame* cast(StackFrame* frame) { |
458 ASSERT(frame->is_standard()); | 459 ASSERT(frame->is_standard()); |
459 return static_cast<StandardFrame*>(frame); | 460 return static_cast<StandardFrame*>(frame); |
460 } | 461 } |
461 | 462 |
462 protected: | 463 protected: |
463 inline explicit StandardFrame(StackFrameIterator* iterator); | 464 inline explicit StandardFrame(StackFrameIteratorBase* iterator); |
464 | 465 |
465 virtual void ComputeCallerState(State* state) const; | 466 virtual void ComputeCallerState(State* state) const; |
466 | 467 |
467 // Accessors. | 468 // Accessors. |
468 inline Address caller_fp() const; | 469 inline Address caller_fp() const; |
469 inline Address caller_pc() const; | 470 inline Address caller_pc() const; |
470 | 471 |
471 // Computes the address of the PC field in the standard frame given | 472 // Computes the address of the PC field in the standard frame given |
472 // by the provided frame pointer. | 473 // by the provided frame pointer. |
473 static inline Address ComputePCAddress(Address fp); | 474 static inline Address ComputePCAddress(Address fp); |
(...skipping 16 matching lines...) Expand all Loading... |
490 | 491 |
491 // Determines if the standard frame for the given frame pointer is a | 492 // Determines if the standard frame for the given frame pointer is a |
492 // construct frame. | 493 // construct frame. |
493 static inline bool IsConstructFrame(Address fp); | 494 static inline bool IsConstructFrame(Address fp); |
494 | 495 |
495 // Used by OptimizedFrames and StubFrames. | 496 // Used by OptimizedFrames and StubFrames. |
496 void IterateCompiledFrame(ObjectVisitor* v) const; | 497 void IterateCompiledFrame(ObjectVisitor* v) const; |
497 | 498 |
498 private: | 499 private: |
499 friend class StackFrame; | 500 friend class StackFrame; |
500 friend class StackFrameIterator; | 501 friend class SafeStackFrameIterator; |
501 }; | 502 }; |
502 | 503 |
503 | 504 |
504 class FrameSummary BASE_EMBEDDED { | 505 class FrameSummary BASE_EMBEDDED { |
505 public: | 506 public: |
506 FrameSummary(Object* receiver, | 507 FrameSummary(Object* receiver, |
507 JSFunction* function, | 508 JSFunction* function, |
508 Code* code, | 509 Code* code, |
509 int offset, | 510 int offset, |
510 bool is_constructor) | 511 bool is_constructor) |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 ASSERT(frame->is_java_script()); | 597 ASSERT(frame->is_java_script()); |
597 return static_cast<JavaScriptFrame*>(frame); | 598 return static_cast<JavaScriptFrame*>(frame); |
598 } | 599 } |
599 | 600 |
600 static void PrintTop(Isolate* isolate, | 601 static void PrintTop(Isolate* isolate, |
601 FILE* file, | 602 FILE* file, |
602 bool print_args, | 603 bool print_args, |
603 bool print_line_number); | 604 bool print_line_number); |
604 | 605 |
605 protected: | 606 protected: |
606 inline explicit JavaScriptFrame(StackFrameIterator* iterator); | 607 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator); |
607 | 608 |
608 virtual Address GetCallerStackPointer() const; | 609 virtual Address GetCallerStackPointer() const; |
609 | 610 |
610 virtual int GetNumberOfIncomingArguments() const; | 611 virtual int GetNumberOfIncomingArguments() const; |
611 | 612 |
612 // Garbage collection support. Iterates over incoming arguments, | 613 // Garbage collection support. Iterates over incoming arguments, |
613 // receiver, and any callee-saved registers. | 614 // receiver, and any callee-saved registers. |
614 void IterateArguments(ObjectVisitor* v) const; | 615 void IterateArguments(ObjectVisitor* v) const; |
615 | 616 |
616 private: | 617 private: |
617 inline Object* function_slot_object() const; | 618 inline Object* function_slot_object() const; |
618 | 619 |
619 friend class StackFrameIterator; | 620 friend class StackFrameIteratorBase; |
620 }; | 621 }; |
621 | 622 |
622 | 623 |
623 class StubFrame : public StandardFrame { | 624 class StubFrame : public StandardFrame { |
624 public: | 625 public: |
625 virtual Type type() const { return STUB; } | 626 virtual Type type() const { return STUB; } |
626 | 627 |
627 // GC support. | 628 // GC support. |
628 virtual void Iterate(ObjectVisitor* v) const; | 629 virtual void Iterate(ObjectVisitor* v) const; |
629 | 630 |
630 // Determine the code for the frame. | 631 // Determine the code for the frame. |
631 virtual Code* unchecked_code() const; | 632 virtual Code* unchecked_code() const; |
632 | 633 |
633 protected: | 634 protected: |
634 inline explicit StubFrame(StackFrameIterator* iterator); | 635 inline explicit StubFrame(StackFrameIteratorBase* iterator); |
635 | 636 |
636 virtual Address GetCallerStackPointer() const; | 637 virtual Address GetCallerStackPointer() const; |
637 | 638 |
638 virtual int GetNumberOfIncomingArguments() const; | 639 virtual int GetNumberOfIncomingArguments() const; |
639 | 640 |
640 friend class StackFrameIterator; | 641 friend class StackFrameIteratorBase; |
641 }; | 642 }; |
642 | 643 |
643 | 644 |
644 class OptimizedFrame : public JavaScriptFrame { | 645 class OptimizedFrame : public JavaScriptFrame { |
645 public: | 646 public: |
646 virtual Type type() const { return OPTIMIZED; } | 647 virtual Type type() const { return OPTIMIZED; } |
647 | 648 |
648 // GC support. | 649 // GC support. |
649 virtual void Iterate(ObjectVisitor* v) const; | 650 virtual void Iterate(ObjectVisitor* v) const; |
650 | 651 |
651 virtual int GetInlineCount(); | 652 virtual int GetInlineCount(); |
652 | 653 |
653 // Return a list with JSFunctions of this frame. | 654 // Return a list with JSFunctions of this frame. |
654 // The functions are ordered bottom-to-top (i.e. functions.last() | 655 // The functions are ordered bottom-to-top (i.e. functions.last() |
655 // is the top-most activation) | 656 // is the top-most activation) |
656 virtual void GetFunctions(List<JSFunction*>* functions); | 657 virtual void GetFunctions(List<JSFunction*>* functions); |
657 | 658 |
658 virtual void Summarize(List<FrameSummary>* frames); | 659 virtual void Summarize(List<FrameSummary>* frames); |
659 | 660 |
660 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index); | 661 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index); |
661 | 662 |
662 protected: | 663 protected: |
663 inline explicit OptimizedFrame(StackFrameIterator* iterator); | 664 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator); |
664 | 665 |
665 private: | 666 private: |
666 JSFunction* LiteralAt(FixedArray* literal_array, int literal_id); | 667 JSFunction* LiteralAt(FixedArray* literal_array, int literal_id); |
667 | 668 |
668 friend class StackFrameIterator; | 669 friend class StackFrameIteratorBase; |
669 }; | 670 }; |
670 | 671 |
671 | 672 |
672 // Arguments adaptor frames are automatically inserted below | 673 // Arguments adaptor frames are automatically inserted below |
673 // JavaScript frames when the actual number of parameters does not | 674 // JavaScript frames when the actual number of parameters does not |
674 // match the formal number of parameters. | 675 // match the formal number of parameters. |
675 class ArgumentsAdaptorFrame: public JavaScriptFrame { | 676 class ArgumentsAdaptorFrame: public JavaScriptFrame { |
676 public: | 677 public: |
677 virtual Type type() const { return ARGUMENTS_ADAPTOR; } | 678 virtual Type type() const { return ARGUMENTS_ADAPTOR; } |
678 | 679 |
679 // Determine the code for the frame. | 680 // Determine the code for the frame. |
680 virtual Code* unchecked_code() const; | 681 virtual Code* unchecked_code() const; |
681 | 682 |
682 static ArgumentsAdaptorFrame* cast(StackFrame* frame) { | 683 static ArgumentsAdaptorFrame* cast(StackFrame* frame) { |
683 ASSERT(frame->is_arguments_adaptor()); | 684 ASSERT(frame->is_arguments_adaptor()); |
684 return static_cast<ArgumentsAdaptorFrame*>(frame); | 685 return static_cast<ArgumentsAdaptorFrame*>(frame); |
685 } | 686 } |
686 | 687 |
687 // Printing support. | 688 // Printing support. |
688 virtual void Print(StringStream* accumulator, | 689 virtual void Print(StringStream* accumulator, |
689 PrintMode mode, | 690 PrintMode mode, |
690 int index) const; | 691 int index) const; |
691 | 692 |
692 protected: | 693 protected: |
693 inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator); | 694 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator); |
694 | 695 |
695 virtual int GetNumberOfIncomingArguments() const; | 696 virtual int GetNumberOfIncomingArguments() const; |
696 | 697 |
697 virtual Address GetCallerStackPointer() const; | 698 virtual Address GetCallerStackPointer() const; |
698 | 699 |
699 private: | 700 private: |
700 friend class StackFrameIterator; | 701 friend class StackFrameIteratorBase; |
701 }; | 702 }; |
702 | 703 |
703 | 704 |
704 class InternalFrame: public StandardFrame { | 705 class InternalFrame: public StandardFrame { |
705 public: | 706 public: |
706 virtual Type type() const { return INTERNAL; } | 707 virtual Type type() const { return INTERNAL; } |
707 | 708 |
708 // Garbage collection support. | 709 // Garbage collection support. |
709 virtual void Iterate(ObjectVisitor* v) const; | 710 virtual void Iterate(ObjectVisitor* v) const; |
710 | 711 |
711 // Determine the code for the frame. | 712 // Determine the code for the frame. |
712 virtual Code* unchecked_code() const; | 713 virtual Code* unchecked_code() const; |
713 | 714 |
714 static InternalFrame* cast(StackFrame* frame) { | 715 static InternalFrame* cast(StackFrame* frame) { |
715 ASSERT(frame->is_internal()); | 716 ASSERT(frame->is_internal()); |
716 return static_cast<InternalFrame*>(frame); | 717 return static_cast<InternalFrame*>(frame); |
717 } | 718 } |
718 | 719 |
719 protected: | 720 protected: |
720 inline explicit InternalFrame(StackFrameIterator* iterator); | 721 inline explicit InternalFrame(StackFrameIteratorBase* iterator); |
721 | 722 |
722 virtual Address GetCallerStackPointer() const; | 723 virtual Address GetCallerStackPointer() const; |
723 | 724 |
724 private: | 725 private: |
725 friend class StackFrameIterator; | 726 friend class StackFrameIteratorBase; |
726 }; | 727 }; |
727 | 728 |
728 | 729 |
729 class StubFailureTrampolineFrame: public StandardFrame { | 730 class StubFailureTrampolineFrame: public StandardFrame { |
730 public: | 731 public: |
731 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the | 732 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the |
732 // presubmit script complains about using sizeof() on a type. | 733 // presubmit script complains about using sizeof() on a type. |
733 static const int kFirstRegisterParameterFrameOffset = | 734 static const int kFirstRegisterParameterFrameOffset = |
734 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize; | 735 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize; |
735 | 736 |
736 static const int kCallerStackParameterCountFrameOffset = | 737 static const int kCallerStackParameterCountFrameOffset = |
737 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize; | 738 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize; |
738 | 739 |
739 virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; } | 740 virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; } |
740 | 741 |
741 // Get the code associated with this frame. | 742 // Get the code associated with this frame. |
742 // This method could be called during marking phase of GC. | 743 // This method could be called during marking phase of GC. |
743 virtual Code* unchecked_code() const; | 744 virtual Code* unchecked_code() const; |
744 | 745 |
745 virtual void Iterate(ObjectVisitor* v) const; | 746 virtual void Iterate(ObjectVisitor* v) const; |
746 | 747 |
747 // Architecture-specific register description. | 748 // Architecture-specific register description. |
748 static Register fp_register(); | 749 static Register fp_register(); |
749 static Register context_register(); | 750 static Register context_register(); |
750 | 751 |
751 protected: | 752 protected: |
752 inline explicit StubFailureTrampolineFrame( | 753 inline explicit StubFailureTrampolineFrame( |
753 StackFrameIterator* iterator); | 754 StackFrameIteratorBase* iterator); |
754 | 755 |
755 virtual Address GetCallerStackPointer() const; | 756 virtual Address GetCallerStackPointer() const; |
756 | 757 |
757 private: | 758 private: |
758 friend class StackFrameIterator; | 759 friend class StackFrameIteratorBase; |
759 }; | 760 }; |
760 | 761 |
761 | 762 |
762 // Construct frames are special trampoline frames introduced to handle | 763 // Construct frames are special trampoline frames introduced to handle |
763 // function invocations through 'new'. | 764 // function invocations through 'new'. |
764 class ConstructFrame: public InternalFrame { | 765 class ConstructFrame: public InternalFrame { |
765 public: | 766 public: |
766 virtual Type type() const { return CONSTRUCT; } | 767 virtual Type type() const { return CONSTRUCT; } |
767 | 768 |
768 static ConstructFrame* cast(StackFrame* frame) { | 769 static ConstructFrame* cast(StackFrame* frame) { |
769 ASSERT(frame->is_construct()); | 770 ASSERT(frame->is_construct()); |
770 return static_cast<ConstructFrame*>(frame); | 771 return static_cast<ConstructFrame*>(frame); |
771 } | 772 } |
772 | 773 |
773 protected: | 774 protected: |
774 inline explicit ConstructFrame(StackFrameIterator* iterator); | 775 inline explicit ConstructFrame(StackFrameIteratorBase* iterator); |
775 | 776 |
776 private: | 777 private: |
777 friend class StackFrameIterator; | 778 friend class StackFrameIteratorBase; |
778 }; | 779 }; |
779 | 780 |
780 | 781 |
781 class StackFrameIterator BASE_EMBEDDED { | 782 class StackFrameIteratorBase BASE_EMBEDDED { |
782 public: | 783 public: |
783 // An iterator that iterates over the isolate's current thread's stack, | |
784 explicit StackFrameIterator(Isolate* isolate); | |
785 | |
786 // An iterator that iterates over a given thread's stack. | |
787 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t); | |
788 | |
789 StackFrame* frame() const { | |
790 ASSERT(!done()); | |
791 return frame_; | |
792 } | |
793 | |
794 Isolate* isolate() const { return isolate_; } | 784 Isolate* isolate() const { return isolate_; } |
795 | 785 |
796 bool done() const { return frame_ == NULL; } | 786 bool done() const { return frame_ == NULL; } |
797 void Advance() { (this->*advance_)(); } | |
798 | 787 |
799 private: | 788 protected: |
800 // An iterator that can start from a given FP address. | 789 // An iterator that iterates over a given thread's stack. |
801 // If use_top, then work as usual, if fp isn't NULL, use it, | 790 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects); |
802 // otherwise, do nothing. This constructor is used to create | |
803 // StackFrameIterator for "safe" stack iteration. | |
804 StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp); | |
805 | |
806 // Go back to the first frame. | |
807 void Reset(); | |
808 | 791 |
809 Isolate* isolate_; | 792 Isolate* isolate_; |
810 #define DECLARE_SINGLETON(ignore, type) type type##_; | 793 #define DECLARE_SINGLETON(ignore, type) type type##_; |
811 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) | 794 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON) |
812 #undef DECLARE_SINGLETON | 795 #undef DECLARE_SINGLETON |
813 StackFrame* frame_; | 796 StackFrame* frame_; |
814 StackHandler* handler_; | 797 StackHandler* handler_; |
815 ThreadLocalTop* thread_; | |
816 Address fp_; | |
817 Address sp_; | |
818 void (StackFrameIterator::*advance_)(); | |
819 const bool can_access_heap_objects_; | 798 const bool can_access_heap_objects_; |
820 | 799 |
821 StackHandler* handler() const { | 800 StackHandler* handler() const { |
822 ASSERT(!done()); | 801 ASSERT(!done()); |
823 return handler_; | 802 return handler_; |
824 } | 803 } |
825 | 804 |
826 // Get the type-specific frame singleton in a given state. | 805 // Get the type-specific frame singleton in a given state. |
827 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state); | 806 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state); |
828 // A helper function, can return a NULL pointer. | 807 // A helper function, can return a NULL pointer. |
829 StackFrame* SingletonFor(StackFrame::Type type); | 808 StackFrame* SingletonFor(StackFrame::Type type); |
830 | 809 |
831 void AdvanceWithHandler(); | 810 private: |
832 void AdvanceWithoutHandler(); | 811 friend class StackFrame; |
| 812 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase); |
| 813 }; |
833 | 814 |
834 friend class StackFrame; | 815 |
835 friend class SafeStackFrameIterator; | 816 class StackFrameIterator: public StackFrameIteratorBase { |
| 817 public: |
| 818 // An iterator that iterates over the isolate's current thread's stack, |
| 819 explicit StackFrameIterator(Isolate* isolate); |
| 820 // An iterator that iterates over a given thread's stack. |
| 821 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t); |
| 822 |
| 823 StackFrame* frame() const { |
| 824 ASSERT(!done()); |
| 825 return frame_; |
| 826 } |
| 827 void Advance(); |
| 828 |
| 829 private: |
| 830 // Go back to the first frame. |
| 831 void Reset(ThreadLocalTop* top); |
| 832 |
836 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); | 833 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); |
837 }; | 834 }; |
838 | 835 |
839 | 836 |
840 // Iterator that supports iterating through all JavaScript frames. | 837 // Iterator that supports iterating through all JavaScript frames. |
841 class JavaScriptFrameIterator BASE_EMBEDDED { | 838 class JavaScriptFrameIterator BASE_EMBEDDED { |
842 public: | 839 public: |
843 inline explicit JavaScriptFrameIterator(Isolate* isolate); | 840 inline explicit JavaScriptFrameIterator(Isolate* isolate); |
844 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top); | 841 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top); |
845 // Skip frames until the frame with the given id is reached. | 842 // Skip frames until the frame with the given id is reached. |
(...skipping 21 matching lines...) Expand all Loading... |
867 class StackTraceFrameIterator: public JavaScriptFrameIterator { | 864 class StackTraceFrameIterator: public JavaScriptFrameIterator { |
868 public: | 865 public: |
869 explicit StackTraceFrameIterator(Isolate* isolate); | 866 explicit StackTraceFrameIterator(Isolate* isolate); |
870 void Advance(); | 867 void Advance(); |
871 | 868 |
872 private: | 869 private: |
873 bool IsValidFrame(); | 870 bool IsValidFrame(); |
874 }; | 871 }; |
875 | 872 |
876 | 873 |
877 class SafeStackFrameIterator BASE_EMBEDDED { | 874 class SafeStackFrameIterator: public StackFrameIteratorBase { |
878 public: | 875 public: |
879 SafeStackFrameIterator(Isolate* isolate, | 876 SafeStackFrameIterator(Isolate* isolate, |
880 Address fp, Address sp, | 877 Address fp, Address sp, |
881 Address low_bound, Address high_bound); | 878 Address low_bound, Address high_bound); |
882 | 879 |
883 inline JavaScriptFrame* frame() const; | 880 inline JavaScriptFrame* frame() const; |
884 | |
885 bool done() const { return iteration_done_ || iterator_.done(); } | |
886 void Advance(); | 881 void Advance(); |
887 | 882 |
888 private: | 883 private: |
889 void AdvanceOneFrame(); | 884 void AdvanceOneFrame(); |
890 | 885 |
891 static bool IsWithinBounds( | |
892 Address low_bound, Address high_bound, Address addr) { | |
893 return low_bound <= addr && addr <= high_bound; | |
894 } | |
895 | |
896 class StackAddressValidator { | |
897 public: | |
898 StackAddressValidator(Address low_bound, Address high_bound) | |
899 : low_bound_(low_bound), high_bound_(high_bound) { } | |
900 bool IsValid(Address addr) const { | |
901 return IsWithinBounds(low_bound_, high_bound_, addr); | |
902 } | |
903 private: | |
904 Address low_bound_; | |
905 Address high_bound_; | |
906 }; | |
907 | |
908 class ExitFrameValidator { | |
909 public: | |
910 explicit ExitFrameValidator(const StackAddressValidator& validator) | |
911 : validator_(validator) { } | |
912 ExitFrameValidator(Address low_bound, Address high_bound) | |
913 : validator_(low_bound, high_bound) { } | |
914 bool IsValidFP(Address fp); | |
915 private: | |
916 StackAddressValidator validator_; | |
917 }; | |
918 | |
919 bool IsValidStackAddress(Address addr) const { | 886 bool IsValidStackAddress(Address addr) const { |
920 return stack_validator_.IsValid(addr); | 887 return low_bound_ <= addr && addr <= high_bound_; |
921 } | 888 } |
922 bool IsValidFrame(StackFrame* frame) const; | 889 bool IsValidFrame(StackFrame* frame) const; |
923 bool IsValidCaller(StackFrame* frame); | 890 bool IsValidCaller(StackFrame* frame); |
924 static bool IsValidTop(Isolate* isolate, | 891 bool IsValidExitFrame(Address fp) const; |
925 Address low_bound, Address high_bound); | 892 bool IsValidTop(ThreadLocalTop* top) const; |
926 | 893 |
927 StackAddressValidator stack_validator_; | 894 const Address low_bound_; |
928 const bool is_valid_top_; | 895 const Address high_bound_; |
929 const bool is_valid_fp_; | |
930 bool iteration_done_; | |
931 StackFrameIterator iterator_; | |
932 }; | 896 }; |
933 | 897 |
934 | 898 |
935 class StackFrameLocator BASE_EMBEDDED { | 899 class StackFrameLocator BASE_EMBEDDED { |
936 public: | 900 public: |
937 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {} | 901 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {} |
938 | 902 |
939 // Find the nth JavaScript frame on the stack. The caller must | 903 // Find the nth JavaScript frame on the stack. The caller must |
940 // guarantee that such a frame exists. | 904 // guarantee that such a frame exists. |
941 JavaScriptFrame* FindJavaScriptFrame(int n); | 905 JavaScriptFrame* FindJavaScriptFrame(int n); |
942 | 906 |
943 private: | 907 private: |
944 StackFrameIterator iterator_; | 908 StackFrameIterator iterator_; |
945 }; | 909 }; |
946 | 910 |
947 | 911 |
948 // Reads all frames on the current stack and copies them into the current | 912 // Reads all frames on the current stack and copies them into the current |
949 // zone memory. | 913 // zone memory. |
950 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone); | 914 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone); |
951 | 915 |
952 } } // namespace v8::internal | 916 } } // namespace v8::internal |
953 | 917 |
954 #endif // V8_FRAMES_H_ | 918 #endif // V8_FRAMES_H_ |
OLD | NEW |