| 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 |