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