The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / frames.h @ f230a1cf

History | View | Annotate | Download (27.8 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_FRAMES_H_
29
#define V8_FRAMES_H_
30

    
31
#include "allocation.h"
32
#include "handles.h"
33
#include "safepoint-table.h"
34

    
35
namespace v8 {
36
namespace internal {
37

    
38
typedef uint32_t RegList;
39

    
40
// Get the number of registers in a given register list.
41
int NumRegs(RegList list);
42

    
43
void SetUpJSCallerSavedCodeData();
44

    
45
// Return the code of the n-th saved register available to JavaScript.
46
int JSCallerSavedCode(int n);
47

    
48

    
49
// Forward declarations.
50
class ExternalCallbackScope;
51
class StackFrameIteratorBase;
52
class ThreadLocalTop;
53
class Isolate;
54

    
55
class InnerPointerToCodeCache {
56
 public:
57
  struct InnerPointerToCodeCacheEntry {
58
    Address inner_pointer;
59
    Code* code;
60
    SafepointEntry safepoint_entry;
61
  };
62

    
63
  explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
64
    Flush();
65
  }
66

    
67
  Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
68
  Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
69

    
70
  void Flush() {
71
    memset(&cache_[0], 0, sizeof(cache_));
72
  }
73

    
74
  InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
75

    
76
 private:
77
  InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
78

    
79
  Isolate* isolate_;
80

    
81
  static const int kInnerPointerToCodeCacheSize = 1024;
82
  InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
83

    
84
  DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
85
};
86

    
87

    
88
class StackHandlerConstants : public AllStatic {
89
 public:
90
  static const int kNextOffset     = 0 * kPointerSize;
91
  static const int kCodeOffset     = 1 * kPointerSize;
92
  static const int kStateOffset    = 2 * kPointerSize;
93
  static const int kContextOffset  = 3 * kPointerSize;
94
  static const int kFPOffset       = 4 * kPointerSize;
95

    
96
  static const int kSize = kFPOffset + kFPOnStackSize;
97
  static const int kSlotCount = kSize >> kPointerSizeLog2;
98
};
99

    
100

    
101
class StackHandler BASE_EMBEDDED {
102
 public:
103
  enum Kind {
104
    JS_ENTRY,
105
    CATCH,
106
    FINALLY,
107
    LAST_KIND = FINALLY
108
  };
109

    
110
  static const int kKindWidth = 2;
111
  STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
112
  static const int kIndexWidth = 32 - kKindWidth;
113
  class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
114
  class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
115

    
116
  // Get the address of this stack handler.
117
  inline Address address() const;
118

    
119
  // Get the next stack handler in the chain.
120
  inline StackHandler* next() const;
121

    
122
  // Tells whether the given address is inside this handler.
123
  inline bool includes(Address address) const;
124

    
125
  // Garbage collection support.
126
  inline void Iterate(ObjectVisitor* v, Code* holder) const;
127

    
128
  // Conversion support.
129
  static inline StackHandler* FromAddress(Address address);
130

    
131
  // Testers
132
  inline bool is_js_entry() const;
133
  inline bool is_catch() const;
134
  inline bool is_finally() const;
135

    
136
  // Generator support to preserve stack handlers.
137
  void Unwind(Isolate* isolate, FixedArray* array, int offset,
138
              int previous_handler_offset) const;
139
  int Rewind(Isolate* isolate, FixedArray* array, int offset, Address fp);
140

    
141
 private:
142
  // Accessors.
143
  inline Kind kind() const;
144
  inline unsigned index() const;
145

    
146
  inline Object** context_address() const;
147
  inline Object** code_address() const;
148
  inline void SetFp(Address slot, Address fp);
149

    
150
  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
151
};
152

    
153

    
154
#define STACK_FRAME_TYPE_LIST(V)                         \
155
  V(ENTRY,                   EntryFrame)                 \
156
  V(ENTRY_CONSTRUCT,         EntryConstructFrame)        \
157
  V(EXIT,                    ExitFrame)                  \
158
  V(JAVA_SCRIPT,             JavaScriptFrame)            \
159
  V(OPTIMIZED,               OptimizedFrame)             \
160
  V(STUB,                    StubFrame)                  \
161
  V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
162
  V(INTERNAL,                InternalFrame)              \
163
  V(CONSTRUCT,               ConstructFrame)             \
164
  V(ARGUMENTS_ADAPTOR,       ArgumentsAdaptorFrame)
165

    
166

    
167
class StandardFrameConstants : public AllStatic {
168
 public:
169
  // Fixed part of the frame consists of return address, caller fp,
170
  // context and function.
171
  // StandardFrame::IterateExpressions assumes that kContextOffset is the last
172
  // object pointer.
173
  static const int kFixedFrameSize    =  kPCOnStackSize + kFPOnStackSize +
174
                                         2 * kPointerSize;
175
  static const int kExpressionsOffset = -3 * kPointerSize;
176
  static const int kMarkerOffset      = -2 * kPointerSize;
177
  static const int kContextOffset     = -1 * kPointerSize;
178
  static const int kCallerFPOffset    =  0 * kPointerSize;
179
  static const int kCallerPCOffset    = +1 * kFPOnStackSize;
180
  static const int kCallerSPOffset    =  kCallerPCOffset + 1 * kPCOnStackSize;
181
};
182

    
183

    
184
// Abstract base class for all stack frames.
185
class StackFrame BASE_EMBEDDED {
186
 public:
187
#define DECLARE_TYPE(type, ignore) type,
188
  enum Type {
189
    NONE = 0,
190
    STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
191
    NUMBER_OF_TYPES,
192
    // Used by FrameScope to indicate that the stack frame is constructed
193
    // manually and the FrameScope does not need to emit code.
194
    MANUAL
195
  };
196
#undef DECLARE_TYPE
197

    
198
  // Opaque data type for identifying stack frames. Used extensively
199
  // by the debugger.
200
  // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
201
  // has correct value range (see Issue 830 for more details).
202
  enum Id {
203
    ID_MIN_VALUE = kMinInt,
204
    ID_MAX_VALUE = kMaxInt,
205
    NO_ID = 0
206
  };
207

    
208
  // Used to mark the outermost JS entry frame.
209
  enum JsFrameMarker {
210
    INNER_JSENTRY_FRAME = 0,
211
    OUTERMOST_JSENTRY_FRAME = 1
212
  };
213

    
214
  struct State {
215
    State() : sp(NULL), fp(NULL), pc_address(NULL) { }
216
    Address sp;
217
    Address fp;
218
    Address* pc_address;
219
  };
220

    
221
  // Copy constructor; it breaks the connection to host iterator
222
  // (as an iterator usually lives on stack).
223
  StackFrame(const StackFrame& original) {
224
    this->state_ = original.state_;
225
    this->iterator_ = NULL;
226
    this->isolate_ = original.isolate_;
227
  }
228

    
229
  // Type testers.
230
  bool is_entry() const { return type() == ENTRY; }
231
  bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
232
  bool is_exit() const { return type() == EXIT; }
233
  bool is_optimized() const { return type() == OPTIMIZED; }
234
  bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
235
  bool is_internal() const { return type() == INTERNAL; }
236
  bool is_stub_failure_trampoline() const {
237
    return type() == STUB_FAILURE_TRAMPOLINE;
238
  }
239
  bool is_construct() const { return type() == CONSTRUCT; }
240
  virtual bool is_standard() const { return false; }
241

    
242
  bool is_java_script() const {
243
    Type type = this->type();
244
    return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
245
  }
246

    
247
  // Accessors.
248
  Address sp() const { return state_.sp; }
249
  Address fp() const { return state_.fp; }
250
  Address caller_sp() const { return GetCallerStackPointer(); }
251

    
252
  // If this frame is optimized and was dynamically aligned return its old
253
  // unaligned frame pointer.  When the frame is deoptimized its FP will shift
254
  // up one word and become unaligned.
255
  Address UnpaddedFP() const;
256

    
257
  Address pc() const { return *pc_address(); }
258
  void set_pc(Address pc) { *pc_address() = pc; }
259

    
260
  virtual void SetCallerFp(Address caller_fp) = 0;
261

    
262
  // Manually changes value of fp in this object.
263
  void UpdateFp(Address fp) { state_.fp = fp; }
264

    
265
  Address* pc_address() const { return state_.pc_address; }
266

    
267
  // Get the id of this stack frame.
268
  Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
269

    
270
  // Checks if this frame includes any stack handlers.
271
  bool HasHandler() const;
272

    
273
  // Get the type of this frame.
274
  virtual Type type() const = 0;
275

    
276
  // Get the code associated with this frame.
277
  // This method could be called during marking phase of GC.
278
  virtual Code* unchecked_code() const = 0;
279

    
280
  // Get the code associated with this frame.
281
  inline Code* LookupCode() const;
282

    
283
  // Get the code object that contains the given pc.
284
  static inline Code* GetContainingCode(Isolate* isolate, Address pc);
285

    
286
  // Get the code object containing the given pc and fill in the
287
  // safepoint entry and the number of stack slots. The pc must be at
288
  // a safepoint.
289
  static Code* GetSafepointData(Isolate* isolate,
290
                                Address pc,
291
                                SafepointEntry* safepoint_entry,
292
                                unsigned* stack_slots);
293

    
294
  virtual void Iterate(ObjectVisitor* v) const = 0;
295
  static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
296

    
297
  // Sets a callback function for return-address rewriting profilers
298
  // to resolve the location of a return address to the location of the
299
  // profiler's stashed return address.
300
  static void SetReturnAddressLocationResolver(
301
      ReturnAddressLocationResolver resolver);
302

    
303
  // Resolves pc_address through the resolution address function if one is set.
304
  static inline Address* ResolveReturnAddressLocation(Address* pc_address);
305

    
306

    
307
  // Printing support.
308
  enum PrintMode { OVERVIEW, DETAILS };
309
  virtual void Print(StringStream* accumulator,
310
                     PrintMode mode,
311
                     int index) const { }
312

    
313
  Isolate* isolate() const { return isolate_; }
314

    
315
 protected:
316
  inline explicit StackFrame(StackFrameIteratorBase* iterator);
317
  virtual ~StackFrame() { }
318

    
319
  // Compute the stack pointer for the calling frame.
320
  virtual Address GetCallerStackPointer() const = 0;
321

    
322
  // Printing support.
323
  static void PrintIndex(StringStream* accumulator,
324
                         PrintMode mode,
325
                         int index);
326

    
327
  // Get the top handler from the current stack iterator.
328
  inline StackHandler* top_handler() const;
329

    
330
  // Compute the stack frame type for the given state.
331
  static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
332

    
333
#ifdef DEBUG
334
  bool can_access_heap_objects() const;
335
#endif
336

    
337
 private:
338
  const StackFrameIteratorBase* iterator_;
339
  Isolate* isolate_;
340
  State state_;
341

    
342
  static ReturnAddressLocationResolver return_address_location_resolver_;
343

    
344
  // Fill in the state of the calling frame.
345
  virtual void ComputeCallerState(State* state) const = 0;
346

    
347
  // Get the type and the state of the calling frame.
348
  virtual Type GetCallerState(State* state) const;
349

    
350
  static const intptr_t kIsolateTag = 1;
351

    
352
  friend class StackFrameIterator;
353
  friend class StackFrameIteratorBase;
354
  friend class StackHandlerIterator;
355
  friend class SafeStackFrameIterator;
356

    
357
 private:
358
  void operator=(const StackFrame& original);
359
};
360

    
361

    
362
// Entry frames are used to enter JavaScript execution from C.
363
class EntryFrame: public StackFrame {
364
 public:
365
  virtual Type type() const { return ENTRY; }
366

    
367
  virtual Code* unchecked_code() const;
368

    
369
  // Garbage collection support.
370
  virtual void Iterate(ObjectVisitor* v) const;
371

    
372
  static EntryFrame* cast(StackFrame* frame) {
373
    ASSERT(frame->is_entry());
374
    return static_cast<EntryFrame*>(frame);
375
  }
376
  virtual void SetCallerFp(Address caller_fp);
377

    
378
 protected:
379
  inline explicit EntryFrame(StackFrameIteratorBase* iterator);
380

    
381
  // The caller stack pointer for entry frames is always zero. The
382
  // real information about the caller frame is available through the
383
  // link to the top exit frame.
384
  virtual Address GetCallerStackPointer() const { return 0; }
385

    
386
 private:
387
  virtual void ComputeCallerState(State* state) const;
388
  virtual Type GetCallerState(State* state) const;
389

    
390
  friend class StackFrameIteratorBase;
391
};
392

    
393

    
394
class EntryConstructFrame: public EntryFrame {
395
 public:
396
  virtual Type type() const { return ENTRY_CONSTRUCT; }
397

    
398
  virtual Code* unchecked_code() const;
399

    
400
  static EntryConstructFrame* cast(StackFrame* frame) {
401
    ASSERT(frame->is_entry_construct());
402
    return static_cast<EntryConstructFrame*>(frame);
403
  }
404

    
405
 protected:
406
  inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
407

    
408
 private:
409
  friend class StackFrameIteratorBase;
410
};
411

    
412

    
413
// Exit frames are used to exit JavaScript execution and go to C.
414
class ExitFrame: public StackFrame {
415
 public:
416
  virtual Type type() const { return EXIT; }
417

    
418
  virtual Code* unchecked_code() const;
419

    
420
  Object*& code_slot() const;
421

    
422
  // Garbage collection support.
423
  virtual void Iterate(ObjectVisitor* v) const;
424

    
425
  virtual void SetCallerFp(Address caller_fp);
426

    
427
  static ExitFrame* cast(StackFrame* frame) {
428
    ASSERT(frame->is_exit());
429
    return static_cast<ExitFrame*>(frame);
430
  }
431

    
432
  // Compute the state and type of an exit frame given a frame
433
  // pointer. Used when constructing the first stack frame seen by an
434
  // iterator and the frames following entry frames.
435
  static Type GetStateForFramePointer(Address fp, State* state);
436
  static Address ComputeStackPointer(Address fp);
437
  static void FillState(Address fp, Address sp, State* state);
438

    
439
 protected:
440
  inline explicit ExitFrame(StackFrameIteratorBase* iterator);
441

    
442
  virtual Address GetCallerStackPointer() const;
443

    
444
 private:
445
  virtual void ComputeCallerState(State* state) const;
446

    
447
  friend class StackFrameIteratorBase;
448
};
449

    
450

    
451
class StandardFrame: public StackFrame {
452
 public:
453
  // Testers.
454
  virtual bool is_standard() const { return true; }
455

    
456
  // Accessors.
457
  inline Object* context() const;
458

    
459
  // Access the expressions in the stack frame including locals.
460
  inline Object* GetExpression(int index) const;
461
  inline void SetExpression(int index, Object* value);
462
  int ComputeExpressionsCount() const;
463
  static Object* GetExpression(Address fp, int index);
464

    
465
  virtual void SetCallerFp(Address caller_fp);
466

    
467
  static StandardFrame* cast(StackFrame* frame) {
468
    ASSERT(frame->is_standard());
469
    return static_cast<StandardFrame*>(frame);
470
  }
471

    
472
 protected:
473
  inline explicit StandardFrame(StackFrameIteratorBase* iterator);
474

    
475
  virtual void ComputeCallerState(State* state) const;
476

    
477
  // Accessors.
478
  inline Address caller_fp() const;
479
  inline Address caller_pc() const;
480

    
481
  // Computes the address of the PC field in the standard frame given
482
  // by the provided frame pointer.
483
  static inline Address ComputePCAddress(Address fp);
484

    
485
  // Iterate over expression stack including stack handlers, locals,
486
  // and parts of the fixed part including context and code fields.
487
  void IterateExpressions(ObjectVisitor* v) const;
488

    
489
  // Returns the address of the n'th expression stack element.
490
  Address GetExpressionAddress(int n) const;
491
  static Address GetExpressionAddress(Address fp, int n);
492

    
493
  // Determines if the n'th expression stack element is in a stack
494
  // handler or not. Requires traversing all handlers in this frame.
495
  bool IsExpressionInsideHandler(int n) const;
496

    
497
  // Determines if the standard frame for the given frame pointer is
498
  // an arguments adaptor frame.
499
  static inline bool IsArgumentsAdaptorFrame(Address fp);
500

    
501
  // Determines if the standard frame for the given frame pointer is a
502
  // construct frame.
503
  static inline bool IsConstructFrame(Address fp);
504

    
505
  // Used by OptimizedFrames and StubFrames.
506
  void IterateCompiledFrame(ObjectVisitor* v) const;
507

    
508
 private:
509
  friend class StackFrame;
510
  friend class SafeStackFrameIterator;
511
};
512

    
513

    
514
class FrameSummary BASE_EMBEDDED {
515
 public:
516
  FrameSummary(Object* receiver,
517
               JSFunction* function,
518
               Code* code,
519
               int offset,
520
               bool is_constructor)
521
      : receiver_(receiver, function->GetIsolate()),
522
        function_(function),
523
        code_(code),
524
        offset_(offset),
525
        is_constructor_(is_constructor) { }
526
  Handle<Object> receiver() { return receiver_; }
527
  Handle<JSFunction> function() { return function_; }
528
  Handle<Code> code() { return code_; }
529
  Address pc() { return code_->address() + offset_; }
530
  int offset() { return offset_; }
531
  bool is_constructor() { return is_constructor_; }
532

    
533
  void Print();
534

    
535
 private:
536
  Handle<Object> receiver_;
537
  Handle<JSFunction> function_;
538
  Handle<Code> code_;
539
  int offset_;
540
  bool is_constructor_;
541
};
542

    
543

    
544
class JavaScriptFrame: public StandardFrame {
545
 public:
546
  virtual Type type() const { return JAVA_SCRIPT; }
547

    
548
  // Accessors.
549
  inline JSFunction* function() const;
550
  inline Object* receiver() const;
551
  inline void set_receiver(Object* value);
552

    
553
  // Access the parameters.
554
  inline Address GetParameterSlot(int index) const;
555
  inline Object* GetParameter(int index) const;
556
  inline int ComputeParametersCount() const {
557
    return GetNumberOfIncomingArguments();
558
  }
559

    
560
  // Access the operand stack.
561
  inline Address GetOperandSlot(int index) const;
562
  inline Object* GetOperand(int index) const;
563
  inline int ComputeOperandsCount() const;
564

    
565
  // Generator support to preserve operand stack and stack handlers.
566
  void SaveOperandStack(FixedArray* store, int* stack_handler_index) const;
567
  void RestoreOperandStack(FixedArray* store, int stack_handler_index);
568

    
569
  // Debugger access.
570
  void SetParameterValue(int index, Object* value) const;
571

    
572
  // Check if this frame is a constructor frame invoked through 'new'.
573
  bool IsConstructor() const;
574

    
575
  // Check if this frame has "adapted" arguments in the sense that the
576
  // actual passed arguments are available in an arguments adaptor
577
  // frame below it on the stack.
578
  inline bool has_adapted_arguments() const;
579
  int GetArgumentsLength() const;
580

    
581
  // Garbage collection support.
582
  virtual void Iterate(ObjectVisitor* v) const;
583

    
584
  // Printing support.
585
  virtual void Print(StringStream* accumulator,
586
                     PrintMode mode,
587
                     int index) const;
588

    
589
  // Determine the code for the frame.
590
  virtual Code* unchecked_code() const;
591

    
592
  // Returns the levels of inlining for this frame.
593
  virtual int GetInlineCount() { return 1; }
594

    
595
  // Return a list with JSFunctions of this frame.
596
  virtual void GetFunctions(List<JSFunction*>* functions);
597

    
598
  // Build a list with summaries for this frame including all inlined frames.
599
  virtual void Summarize(List<FrameSummary>* frames);
600

    
601
  // Architecture-specific register description.
602
  static Register fp_register();
603
  static Register context_register();
604

    
605
  static JavaScriptFrame* cast(StackFrame* frame) {
606
    ASSERT(frame->is_java_script());
607
    return static_cast<JavaScriptFrame*>(frame);
608
  }
609

    
610
  static void PrintTop(Isolate* isolate,
611
                       FILE* file,
612
                       bool print_args,
613
                       bool print_line_number);
614

    
615
 protected:
616
  inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
617

    
618
  virtual Address GetCallerStackPointer() const;
619

    
620
  virtual int GetNumberOfIncomingArguments() const;
621

    
622
  // Garbage collection support. Iterates over incoming arguments,
623
  // receiver, and any callee-saved registers.
624
  void IterateArguments(ObjectVisitor* v) const;
625

    
626
 private:
627
  inline Object* function_slot_object() const;
628

    
629
  friend class StackFrameIteratorBase;
630
};
631

    
632

    
633
class StubFrame : public StandardFrame {
634
 public:
635
  virtual Type type() const { return STUB; }
636

    
637
  // GC support.
638
  virtual void Iterate(ObjectVisitor* v) const;
639

    
640
  // Determine the code for the frame.
641
  virtual Code* unchecked_code() const;
642

    
643
 protected:
644
  inline explicit StubFrame(StackFrameIteratorBase* iterator);
645

    
646
  virtual Address GetCallerStackPointer() const;
647

    
648
  virtual int GetNumberOfIncomingArguments() const;
649

    
650
  friend class StackFrameIteratorBase;
651
};
652

    
653

    
654
class OptimizedFrame : public JavaScriptFrame {
655
 public:
656
  virtual Type type() const { return OPTIMIZED; }
657

    
658
  // GC support.
659
  virtual void Iterate(ObjectVisitor* v) const;
660

    
661
  virtual int GetInlineCount();
662

    
663
  // Return a list with JSFunctions of this frame.
664
  // The functions are ordered bottom-to-top (i.e. functions.last()
665
  // is the top-most activation)
666
  virtual void GetFunctions(List<JSFunction*>* functions);
667

    
668
  virtual void Summarize(List<FrameSummary>* frames);
669

    
670
  DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
671

    
672
 protected:
673
  inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
674

    
675
 private:
676
  JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
677

    
678
  friend class StackFrameIteratorBase;
679
};
680

    
681

    
682
// Arguments adaptor frames are automatically inserted below
683
// JavaScript frames when the actual number of parameters does not
684
// match the formal number of parameters.
685
class ArgumentsAdaptorFrame: public JavaScriptFrame {
686
 public:
687
  virtual Type type() const { return ARGUMENTS_ADAPTOR; }
688

    
689
  // Determine the code for the frame.
690
  virtual Code* unchecked_code() const;
691

    
692
  static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
693
    ASSERT(frame->is_arguments_adaptor());
694
    return static_cast<ArgumentsAdaptorFrame*>(frame);
695
  }
696

    
697
  // Printing support.
698
  virtual void Print(StringStream* accumulator,
699
                     PrintMode mode,
700
                     int index) const;
701

    
702
 protected:
703
  inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
704

    
705
  virtual int GetNumberOfIncomingArguments() const;
706

    
707
  virtual Address GetCallerStackPointer() const;
708

    
709
 private:
710
  friend class StackFrameIteratorBase;
711
};
712

    
713

    
714
class InternalFrame: public StandardFrame {
715
 public:
716
  virtual Type type() const { return INTERNAL; }
717

    
718
  // Garbage collection support.
719
  virtual void Iterate(ObjectVisitor* v) const;
720

    
721
  // Determine the code for the frame.
722
  virtual Code* unchecked_code() const;
723

    
724
  static InternalFrame* cast(StackFrame* frame) {
725
    ASSERT(frame->is_internal());
726
    return static_cast<InternalFrame*>(frame);
727
  }
728

    
729
 protected:
730
  inline explicit InternalFrame(StackFrameIteratorBase* iterator);
731

    
732
  virtual Address GetCallerStackPointer() const;
733

    
734
 private:
735
  friend class StackFrameIteratorBase;
736
};
737

    
738

    
739
class StubFailureTrampolineFrame: public StandardFrame {
740
 public:
741
  // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
742
  // presubmit script complains about using sizeof() on a type.
743
  static const int kFirstRegisterParameterFrameOffset =
744
      StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
745

    
746
  static const int kCallerStackParameterCountFrameOffset =
747
      StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
748

    
749
  virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; }
750

    
751
  // Get the code associated with this frame.
752
  // This method could be called during marking phase of GC.
753
  virtual Code* unchecked_code() const;
754

    
755
  virtual void Iterate(ObjectVisitor* v) const;
756

    
757
  // Architecture-specific register description.
758
  static Register fp_register();
759
  static Register context_register();
760

    
761
 protected:
762
  inline explicit StubFailureTrampolineFrame(
763
      StackFrameIteratorBase* iterator);
764

    
765
  virtual Address GetCallerStackPointer() const;
766

    
767
 private:
768
  friend class StackFrameIteratorBase;
769
};
770

    
771

    
772
// Construct frames are special trampoline frames introduced to handle
773
// function invocations through 'new'.
774
class ConstructFrame: public InternalFrame {
775
 public:
776
  virtual Type type() const { return CONSTRUCT; }
777

    
778
  static ConstructFrame* cast(StackFrame* frame) {
779
    ASSERT(frame->is_construct());
780
    return static_cast<ConstructFrame*>(frame);
781
  }
782

    
783
 protected:
784
  inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
785

    
786
 private:
787
  friend class StackFrameIteratorBase;
788
};
789

    
790

    
791
class StackFrameIteratorBase BASE_EMBEDDED {
792
 public:
793
  Isolate* isolate() const { return isolate_; }
794

    
795
  bool done() const { return frame_ == NULL; }
796

    
797
 protected:
798
  // An iterator that iterates over a given thread's stack.
799
  StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
800

    
801
  Isolate* isolate_;
802
#define DECLARE_SINGLETON(ignore, type) type type##_;
803
  STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
804
#undef DECLARE_SINGLETON
805
  StackFrame* frame_;
806
  StackHandler* handler_;
807
  const bool can_access_heap_objects_;
808

    
809
  StackHandler* handler() const {
810
    ASSERT(!done());
811
    return handler_;
812
  }
813

    
814
  // Get the type-specific frame singleton in a given state.
815
  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
816
  // A helper function, can return a NULL pointer.
817
  StackFrame* SingletonFor(StackFrame::Type type);
818

    
819
 private:
820
  friend class StackFrame;
821
  DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
822
};
823

    
824

    
825
class StackFrameIterator: public StackFrameIteratorBase {
826
 public:
827
  // An iterator that iterates over the isolate's current thread's stack,
828
  explicit StackFrameIterator(Isolate* isolate);
829
  // An iterator that iterates over a given thread's stack.
830
  StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
831

    
832
  StackFrame* frame() const {
833
    ASSERT(!done());
834
    return frame_;
835
  }
836
  void Advance();
837

    
838
 private:
839
  // Go back to the first frame.
840
  void Reset(ThreadLocalTop* top);
841

    
842
  DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
843
};
844

    
845

    
846
// Iterator that supports iterating through all JavaScript frames.
847
class JavaScriptFrameIterator BASE_EMBEDDED {
848
 public:
849
  inline explicit JavaScriptFrameIterator(Isolate* isolate);
850
  inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
851
  // Skip frames until the frame with the given id is reached.
852
  JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
853

    
854
  inline JavaScriptFrame* frame() const;
855

    
856
  bool done() const { return iterator_.done(); }
857
  void Advance();
858

    
859
  // Advance to the frame holding the arguments for the current
860
  // frame. This only affects the current frame if it has adapted
861
  // arguments.
862
  void AdvanceToArgumentsFrame();
863

    
864
 private:
865
  StackFrameIterator iterator_;
866
};
867

    
868

    
869
// NOTE: The stack trace frame iterator is an iterator that only
870
// traverse proper JavaScript frames; that is JavaScript frames that
871
// have proper JavaScript functions. This excludes the problematic
872
// functions in runtime.js.
873
class StackTraceFrameIterator: public JavaScriptFrameIterator {
874
 public:
875
  explicit StackTraceFrameIterator(Isolate* isolate);
876
  void Advance();
877

    
878
 private:
879
  bool IsValidFrame();
880
};
881

    
882

    
883
class SafeStackFrameIterator: public StackFrameIteratorBase {
884
 public:
885
  SafeStackFrameIterator(Isolate* isolate,
886
                         Address fp, Address sp,
887
                         Address js_entry_sp);
888

    
889
  inline StackFrame* frame() const;
890
  void Advance();
891

    
892
  StackFrame::Type top_frame_type() const { return top_frame_type_; }
893

    
894
 private:
895
  void AdvanceOneFrame();
896

    
897
  bool IsValidStackAddress(Address addr) const {
898
    return low_bound_ <= addr && addr <= high_bound_;
899
  }
900
  bool IsValidFrame(StackFrame* frame) const;
901
  bool IsValidCaller(StackFrame* frame);
902
  bool IsValidExitFrame(Address fp) const;
903
  bool IsValidTop(ThreadLocalTop* top) const;
904

    
905
  const Address low_bound_;
906
  const Address high_bound_;
907
  StackFrame::Type top_frame_type_;
908
  ExternalCallbackScope* external_callback_scope_;
909
};
910

    
911

    
912
class StackFrameLocator BASE_EMBEDDED {
913
 public:
914
  explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
915

    
916
  // Find the nth JavaScript frame on the stack. The caller must
917
  // guarantee that such a frame exists.
918
  JavaScriptFrame* FindJavaScriptFrame(int n);
919

    
920
 private:
921
  StackFrameIterator iterator_;
922
};
923

    
924

    
925
// Used specify the type of prologue to generate.
926
enum PrologueFrameMode {
927
  BUILD_FUNCTION_FRAME,
928
  BUILD_STUB_FRAME
929
};
930

    
931

    
932
// Reads all frames on the current stack and copies them into the current
933
// zone memory.
934
Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
935

    
936
} }  // namespace v8::internal
937

    
938
#endif  // V8_FRAMES_H_