OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 }; | 91 }; |
92 | 92 |
93 | 93 |
94 #define STACK_FRAME_TYPE_LIST(V) \ | 94 #define STACK_FRAME_TYPE_LIST(V) \ |
95 V(ENTRY, EntryFrame) \ | 95 V(ENTRY, EntryFrame) \ |
96 V(ENTRY_CONSTRUCT, EntryConstructFrame) \ | 96 V(ENTRY_CONSTRUCT, EntryConstructFrame) \ |
97 V(EXIT, ExitFrame) \ | 97 V(EXIT, ExitFrame) \ |
98 V(EXIT_DEBUG, ExitDebugFrame) \ | 98 V(EXIT_DEBUG, ExitDebugFrame) \ |
99 V(JAVA_SCRIPT, JavaScriptFrame) \ | 99 V(JAVA_SCRIPT, JavaScriptFrame) \ |
100 V(INTERNAL, InternalFrame) \ | 100 V(INTERNAL, InternalFrame) \ |
| 101 V(CONSTRUCT, ConstructFrame) \ |
101 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) | 102 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) |
102 | 103 |
103 | 104 |
104 // Abstract base class for all stack frames. | 105 // Abstract base class for all stack frames. |
105 class StackFrame BASE_EMBEDDED { | 106 class StackFrame BASE_EMBEDDED { |
106 public: | 107 public: |
107 #define DECLARE_TYPE(type, ignore) type, | 108 #define DECLARE_TYPE(type, ignore) type, |
108 enum Type { | 109 enum Type { |
109 NONE = 0, | 110 NONE = 0, |
110 STACK_FRAME_TYPE_LIST(DECLARE_TYPE) | 111 STACK_FRAME_TYPE_LIST(DECLARE_TYPE) |
111 NUMBER_OF_TYPES | 112 NUMBER_OF_TYPES |
112 }; | 113 }; |
113 #undef DECLARE_TYPE | 114 #undef DECLARE_TYPE |
114 | 115 |
115 // Opaque data type for identifying stack frames. Used extensively | 116 // Opaque data type for identifying stack frames. Used extensively |
116 // by the debugger. | 117 // by the debugger. |
117 enum Id { NO_ID = 0 }; | 118 enum Id { NO_ID = 0 }; |
118 | 119 |
119 // Type testers. | 120 // Type testers. |
120 bool is_entry() const { return type() == ENTRY; } | 121 bool is_entry() const { return type() == ENTRY; } |
121 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } | 122 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; } |
122 bool is_exit() const { return type() == EXIT; } | 123 bool is_exit() const { return type() == EXIT; } |
123 bool is_exit_debug() const { return type() == EXIT_DEBUG; } | 124 bool is_exit_debug() const { return type() == EXIT_DEBUG; } |
124 bool is_java_script() const { return type() == JAVA_SCRIPT; } | 125 bool is_java_script() const { return type() == JAVA_SCRIPT; } |
125 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } | 126 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; } |
126 bool is_internal() const { return type() == INTERNAL; } | 127 bool is_internal() const { return type() == INTERNAL; } |
| 128 bool is_construct() const { return type() == CONSTRUCT; } |
127 virtual bool is_standard() const { return false; } | 129 virtual bool is_standard() const { return false; } |
128 | 130 |
129 // Accessors. | 131 // Accessors. |
130 Address sp() const { return state_.sp; } | 132 Address sp() const { return state_.sp; } |
131 Address fp() const { return state_.fp; } | 133 Address fp() const { return state_.fp; } |
132 Address pp() const { return GetCallerStackPointer(); } | 134 Address pp() const { return GetCallerStackPointer(); } |
133 | 135 |
134 Address pc() const { return *pc_address(); } | 136 Address pc() const { return *pc_address(); } |
135 void set_pc(Address pc) { *pc_address() = pc; } | 137 void set_pc(Address pc) { *pc_address() = pc; } |
136 | 138 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 Address GetExpressionAddress(int n) const; | 347 Address GetExpressionAddress(int n) const; |
346 | 348 |
347 // Determines if the n'th expression stack element is in a stack | 349 // Determines if the n'th expression stack element is in a stack |
348 // handler or not. Requires traversing all handlers in this frame. | 350 // handler or not. Requires traversing all handlers in this frame. |
349 bool IsExpressionInsideHandler(int n) const; | 351 bool IsExpressionInsideHandler(int n) const; |
350 | 352 |
351 // Determines if the standard frame for the given frame pointer is | 353 // Determines if the standard frame for the given frame pointer is |
352 // an arguments adaptor frame. | 354 // an arguments adaptor frame. |
353 static inline bool IsArgumentsAdaptorFrame(Address fp); | 355 static inline bool IsArgumentsAdaptorFrame(Address fp); |
354 | 356 |
355 // Determines if the standard frame for the given program counter is | 357 // Determines if the standard frame for the given frame pointer is a |
356 // a construct trampoline. | 358 // construct frame. |
357 static inline bool IsConstructTrampolineFrame(Address pc); | 359 static inline bool IsConstructFrame(Address fp); |
358 | 360 |
359 private: | 361 private: |
360 friend class StackFrame; | 362 friend class StackFrame; |
361 }; | 363 }; |
362 | 364 |
363 | 365 |
364 class JavaScriptFrame: public StandardFrame { | 366 class JavaScriptFrame: public StandardFrame { |
365 public: | 367 public: |
366 virtual Type type() const { return JAVA_SCRIPT; } | 368 virtual Type type() const { return JAVA_SCRIPT; } |
367 | 369 |
368 // Accessors. | 370 // Accessors. |
369 inline Object* function() const; | 371 inline Object* function() const; |
370 inline Object* receiver() const; | 372 inline Object* receiver() const; |
371 inline void set_receiver(Object* value); | 373 inline void set_receiver(Object* value); |
372 | 374 |
373 // Access the parameters. | 375 // Access the parameters. |
374 Object* GetParameter(int index) const; | 376 Object* GetParameter(int index) const; |
375 int ComputeParametersCount() const; | 377 int ComputeParametersCount() const; |
376 | 378 |
377 // Temporary way of getting access to the number of parameters | 379 // Temporary way of getting access to the number of parameters |
378 // passed on the stack by the caller. Once argument adaptor frames | 380 // passed on the stack by the caller. Once argument adaptor frames |
379 // has been introduced on ARM, this number will always match the | 381 // has been introduced on ARM, this number will always match the |
380 // computed parameters count. | 382 // computed parameters count. |
381 int GetProvidedParametersCount() const; | 383 int GetProvidedParametersCount() const; |
382 | 384 |
383 // Check if this frame is a constructor frame invoked through | 385 // Check if this frame is a constructor frame invoked through 'new'. |
384 // 'new'. The operation may involve digging through a few stack | |
385 // frames to account for arguments adaptors. | |
386 bool IsConstructor() const; | 386 bool IsConstructor() const; |
387 | 387 |
388 // Check if this frame has "adapted" arguments in the sense that the | 388 // Check if this frame has "adapted" arguments in the sense that the |
389 // actual passed arguments are available in an arguments adaptor | 389 // actual passed arguments are available in an arguments adaptor |
390 // frame below it on the stack. | 390 // frame below it on the stack. |
391 inline bool has_adapted_arguments() const; | 391 inline bool has_adapted_arguments() const; |
392 | 392 |
393 // Garbage colletion support. | 393 // Garbage colletion support. |
394 virtual void Iterate(ObjectVisitor* v) const; | 394 virtual void Iterate(ObjectVisitor* v) const; |
395 | 395 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 | 452 |
453 private: | 453 private: |
454 friend class StackFrameIterator; | 454 friend class StackFrameIterator; |
455 }; | 455 }; |
456 | 456 |
457 | 457 |
458 class InternalFrame: public StandardFrame { | 458 class InternalFrame: public StandardFrame { |
459 public: | 459 public: |
460 virtual Type type() const { return INTERNAL; } | 460 virtual Type type() const { return INTERNAL; } |
461 | 461 |
462 // Returns if this frame is a special trampoline frame introduced by | |
463 // the construct trampoline. NOTE: We should consider introducing a | |
464 // special stack frame type for this. | |
465 inline bool is_construct_trampoline() const; | |
466 | |
467 // Garbage colletion support. | 462 // Garbage colletion support. |
468 virtual void Iterate(ObjectVisitor* v) const; | 463 virtual void Iterate(ObjectVisitor* v) const; |
469 | 464 |
470 // Determine the code for the frame. | 465 // Determine the code for the frame. |
471 virtual Code* FindCode() const; | 466 virtual Code* FindCode() const; |
472 | 467 |
473 static InternalFrame* cast(StackFrame* frame) { | 468 static InternalFrame* cast(StackFrame* frame) { |
474 ASSERT(frame->is_internal()); | 469 ASSERT(frame->is_internal()); |
475 return static_cast<InternalFrame*>(frame); | 470 return static_cast<InternalFrame*>(frame); |
476 } | 471 } |
477 | 472 |
478 protected: | 473 protected: |
479 explicit InternalFrame(StackFrameIterator* iterator) | 474 explicit InternalFrame(StackFrameIterator* iterator) |
480 : StandardFrame(iterator) { } | 475 : StandardFrame(iterator) { } |
481 | 476 |
482 virtual Address GetCallerStackPointer() const; | 477 virtual Address GetCallerStackPointer() const; |
483 | 478 |
484 private: | 479 private: |
485 friend class StackFrameIterator; | 480 friend class StackFrameIterator; |
486 }; | 481 }; |
487 | 482 |
488 | 483 |
| 484 // Construct frames are special trampoline frames introduced to handle |
| 485 // function invocations through 'new'. |
| 486 class ConstructFrame: public InternalFrame { |
| 487 public: |
| 488 virtual Type type() const { return CONSTRUCT; } |
| 489 |
| 490 static ConstructFrame* cast(StackFrame* frame) { |
| 491 ASSERT(frame->is_construct()); |
| 492 return static_cast<ConstructFrame*>(frame); |
| 493 } |
| 494 |
| 495 protected: |
| 496 explicit ConstructFrame(StackFrameIterator* iterator) |
| 497 : InternalFrame(iterator) { } |
| 498 |
| 499 private: |
| 500 friend class StackFrameIterator; |
| 501 }; |
| 502 |
| 503 |
489 class StackFrameIterator BASE_EMBEDDED { | 504 class StackFrameIterator BASE_EMBEDDED { |
490 public: | 505 public: |
491 // An iterator that iterates over the current thread's stack. | 506 // An iterator that iterates over the current thread's stack. |
492 StackFrameIterator(); | 507 StackFrameIterator(); |
493 | 508 |
494 // An iterator that iterates over a given thread's stack. | 509 // An iterator that iterates over a given thread's stack. |
495 explicit StackFrameIterator(ThreadLocalTop* thread); | 510 explicit StackFrameIterator(ThreadLocalTop* thread); |
496 | 511 |
497 StackFrame* frame() const { | 512 StackFrame* frame() const { |
498 ASSERT(!done()); | 513 ASSERT(!done()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 JavaScriptFrame* FindJavaScriptFrame(int n); | 578 JavaScriptFrame* FindJavaScriptFrame(int n); |
564 | 579 |
565 private: | 580 private: |
566 StackFrameIterator iterator_; | 581 StackFrameIterator iterator_; |
567 }; | 582 }; |
568 | 583 |
569 | 584 |
570 } } // namespace v8::internal | 585 } } // namespace v8::internal |
571 | 586 |
572 #endif // V8_FRAMES_H_ | 587 #endif // V8_FRAMES_H_ |
OLD | NEW |