~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/frames.h

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 StackFrameIterator;
 
51
class ThreadLocalTop;
 
52
class Isolate;
 
53
 
 
54
class InnerPointerToCodeCache {
 
55
 public:
 
56
  struct InnerPointerToCodeCacheEntry {
 
57
    Address inner_pointer;
 
58
    Code* code;
 
59
    SafepointEntry safepoint_entry;
 
60
  };
 
61
 
 
62
  explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
 
63
    Flush();
 
64
  }
 
65
 
 
66
  Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
 
67
  Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
 
68
 
 
69
  void Flush() {
 
70
    memset(&cache_[0], 0, sizeof(cache_));
 
71
  }
 
72
 
 
73
  InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
 
74
 
 
75
 private:
 
76
  InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
 
77
 
 
78
  Isolate* isolate_;
 
79
 
 
80
  static const int kInnerPointerToCodeCacheSize = 1024;
 
81
  InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
 
82
 
 
83
  DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
 
84
};
 
85
 
 
86
 
 
87
class StackHandler BASE_EMBEDDED {
 
88
 public:
 
89
  enum Kind {
 
90
    JS_ENTRY,
 
91
    CATCH,
 
92
    FINALLY,
 
93
    LAST_KIND = FINALLY
 
94
  };
 
95
 
 
96
  static const int kKindWidth = 2;
 
97
  STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
 
98
  static const int kIndexWidth = 32 - kKindWidth;
 
99
  class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
 
100
  class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
 
101
 
 
102
  // Get the address of this stack handler.
 
103
  inline Address address() const;
 
104
 
 
105
  // Get the next stack handler in the chain.
 
106
  inline StackHandler* next() const;
 
107
 
 
108
  // Tells whether the given address is inside this handler.
 
109
  inline bool includes(Address address) const;
 
110
 
 
111
  // Garbage collection support.
 
112
  inline void Iterate(ObjectVisitor* v, Code* holder) const;
 
113
 
 
114
  // Conversion support.
 
115
  static inline StackHandler* FromAddress(Address address);
 
116
 
 
117
  // Testers
 
118
  inline bool is_js_entry() const;
 
119
  inline bool is_catch() const;
 
120
  inline bool is_finally() const;
 
121
 
 
122
 private:
 
123
  // Accessors.
 
124
  inline Kind kind() const;
 
125
 
 
126
  inline Object** context_address() const;
 
127
  inline Object** code_address() const;
 
128
 
 
129
  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
 
130
};
 
131
 
 
132
 
 
133
#define STACK_FRAME_TYPE_LIST(V)              \
 
134
  V(ENTRY,             EntryFrame)            \
 
135
  V(ENTRY_CONSTRUCT,   EntryConstructFrame)   \
 
136
  V(EXIT,              ExitFrame)             \
 
137
  V(JAVA_SCRIPT,       JavaScriptFrame)       \
 
138
  V(OPTIMIZED,         OptimizedFrame)        \
 
139
  V(INTERNAL,          InternalFrame)         \
 
140
  V(CONSTRUCT,         ConstructFrame)        \
 
141
  V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
 
142
 
 
143
 
 
144
// Abstract base class for all stack frames.
 
145
class StackFrame BASE_EMBEDDED {
 
146
 public:
 
147
#define DECLARE_TYPE(type, ignore) type,
 
148
  enum Type {
 
149
    NONE = 0,
 
150
    STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
 
151
    NUMBER_OF_TYPES,
 
152
    // Used by FrameScope to indicate that the stack frame is constructed
 
153
    // manually and the FrameScope does not need to emit code.
 
154
    MANUAL
 
155
  };
 
156
#undef DECLARE_TYPE
 
157
 
 
158
  // Opaque data type for identifying stack frames. Used extensively
 
159
  // by the debugger.
 
160
  // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
 
161
  // has correct value range (see Issue 830 for more details).
 
162
  enum Id {
 
163
    ID_MIN_VALUE = kMinInt,
 
164
    ID_MAX_VALUE = kMaxInt,
 
165
    NO_ID = 0
 
166
  };
 
167
 
 
168
  // Used to mark the outermost JS entry frame.
 
169
  enum JsFrameMarker {
 
170
    INNER_JSENTRY_FRAME = 0,
 
171
    OUTERMOST_JSENTRY_FRAME = 1
 
172
  };
 
173
 
 
174
  struct State {
 
175
    State() : sp(NULL), fp(NULL), pc_address(NULL) { }
 
176
    Address sp;
 
177
    Address fp;
 
178
    Address* pc_address;
 
179
  };
 
180
 
 
181
  // Copy constructor; it breaks the connection to host iterator
 
182
  // (as an iterator usually lives on stack).
 
183
  StackFrame(const StackFrame& original) {
 
184
    this->state_ = original.state_;
 
185
    this->iterator_ = NULL;
 
186
    this->isolate_ = original.isolate_;
 
187
  }
 
188
 
 
189
  // Type testers.
 
190
  bool is_entry() const { return type() == ENTRY; }
 
191
  bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
 
192
  bool is_exit() const { return type() == EXIT; }
 
193
  bool is_optimized() const { return type() == OPTIMIZED; }
 
194
  bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
 
195
  bool is_internal() const { return type() == INTERNAL; }
 
196
  bool is_construct() const { return type() == CONSTRUCT; }
 
197
  virtual bool is_standard() const { return false; }
 
198
 
 
199
  bool is_java_script() const {
 
200
    Type type = this->type();
 
201
    return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
 
202
  }
 
203
 
 
204
  // Accessors.
 
205
  Address sp() const { return state_.sp; }
 
206
  Address fp() const { return state_.fp; }
 
207
  Address caller_sp() const { return GetCallerStackPointer(); }
 
208
 
 
209
  // If this frame is optimized and was dynamically aligned return its old
 
210
  // unaligned frame pointer.  When the frame is deoptimized its FP will shift
 
211
  // up one word and become unaligned.
 
212
  Address UnpaddedFP() const;
 
213
 
 
214
  Address pc() const { return *pc_address(); }
 
215
  void set_pc(Address pc) { *pc_address() = pc; }
 
216
 
 
217
  virtual void SetCallerFp(Address caller_fp) = 0;
 
218
 
 
219
  // Manually changes value of fp in this object.
 
220
  void UpdateFp(Address fp) { state_.fp = fp; }
 
221
 
 
222
  Address* pc_address() const { return state_.pc_address; }
 
223
 
 
224
  // Get the id of this stack frame.
 
225
  Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
 
226
 
 
227
  // Checks if this frame includes any stack handlers.
 
228
  bool HasHandler() const;
 
229
 
 
230
  // Get the type of this frame.
 
231
  virtual Type type() const = 0;
 
232
 
 
233
  // Get the code associated with this frame.
 
234
  // This method could be called during marking phase of GC.
 
235
  virtual Code* unchecked_code() const = 0;
 
236
 
 
237
  // Get the code associated with this frame.
 
238
  inline Code* LookupCode() const;
 
239
 
 
240
  // Get the code object that contains the given pc.
 
241
  static inline Code* GetContainingCode(Isolate* isolate, Address pc);
 
242
 
 
243
  // Get the code object containing the given pc and fill in the
 
244
  // safepoint entry and the number of stack slots. The pc must be at
 
245
  // a safepoint.
 
246
  static Code* GetSafepointData(Isolate* isolate,
 
247
                                Address pc,
 
248
                                SafepointEntry* safepoint_entry,
 
249
                                unsigned* stack_slots);
 
250
 
 
251
  virtual void Iterate(ObjectVisitor* v) const = 0;
 
252
  static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
 
253
 
 
254
  // Sets a callback function for return-address rewriting profilers
 
255
  // to resolve the location of a return address to the location of the
 
256
  // profiler's stashed return address.
 
257
  static void SetReturnAddressLocationResolver(
 
258
      ReturnAddressLocationResolver resolver);
 
259
 
 
260
  // Printing support.
 
261
  enum PrintMode { OVERVIEW, DETAILS };
 
262
  virtual void Print(StringStream* accumulator,
 
263
                     PrintMode mode,
 
264
                     int index) const { }
 
265
 
 
266
 protected:
 
267
  inline explicit StackFrame(StackFrameIterator* iterator);
 
268
  virtual ~StackFrame() { }
 
269
 
 
270
  Isolate* isolate() const { return isolate_; }
 
271
 
 
272
  // Compute the stack pointer for the calling frame.
 
273
  virtual Address GetCallerStackPointer() const = 0;
 
274
 
 
275
  // Printing support.
 
276
  static void PrintIndex(StringStream* accumulator,
 
277
                         PrintMode mode,
 
278
                         int index);
 
279
 
 
280
  // Get the top handler from the current stack iterator.
 
281
  inline StackHandler* top_handler() const;
 
282
 
 
283
  // Compute the stack frame type for the given state.
 
284
  static Type ComputeType(Isolate* isolate, State* state);
 
285
 
 
286
 private:
 
287
  const StackFrameIterator* iterator_;
 
288
  Isolate* isolate_;
 
289
  State state_;
 
290
 
 
291
  // Fill in the state of the calling frame.
 
292
  virtual void ComputeCallerState(State* state) const = 0;
 
293
 
 
294
  // Get the type and the state of the calling frame.
 
295
  virtual Type GetCallerState(State* state) const;
 
296
 
 
297
  static const intptr_t kIsolateTag = 1;
 
298
 
 
299
  friend class StackFrameIterator;
 
300
  friend class StackHandlerIterator;
 
301
  friend class SafeStackFrameIterator;
 
302
 
 
303
 private:
 
304
  void operator=(const StackFrame& original);
 
305
};
 
306
 
 
307
 
 
308
// Entry frames are used to enter JavaScript execution from C.
 
309
class EntryFrame: public StackFrame {
 
310
 public:
 
311
  virtual Type type() const { return ENTRY; }
 
312
 
 
313
  virtual Code* unchecked_code() const;
 
314
 
 
315
  // Garbage collection support.
 
316
  virtual void Iterate(ObjectVisitor* v) const;
 
317
 
 
318
  static EntryFrame* cast(StackFrame* frame) {
 
319
    ASSERT(frame->is_entry());
 
320
    return static_cast<EntryFrame*>(frame);
 
321
  }
 
322
  virtual void SetCallerFp(Address caller_fp);
 
323
 
 
324
 protected:
 
325
  inline explicit EntryFrame(StackFrameIterator* iterator);
 
326
 
 
327
  // The caller stack pointer for entry frames is always zero. The
 
328
  // real information about the caller frame is available through the
 
329
  // link to the top exit frame.
 
330
  virtual Address GetCallerStackPointer() const { return 0; }
 
331
 
 
332
 private:
 
333
  virtual void ComputeCallerState(State* state) const;
 
334
  virtual Type GetCallerState(State* state) const;
 
335
 
 
336
  friend class StackFrameIterator;
 
337
};
 
338
 
 
339
 
 
340
class EntryConstructFrame: public EntryFrame {
 
341
 public:
 
342
  virtual Type type() const { return ENTRY_CONSTRUCT; }
 
343
 
 
344
  virtual Code* unchecked_code() const;
 
345
 
 
346
  static EntryConstructFrame* cast(StackFrame* frame) {
 
347
    ASSERT(frame->is_entry_construct());
 
348
    return static_cast<EntryConstructFrame*>(frame);
 
349
  }
 
350
 
 
351
 protected:
 
352
  inline explicit EntryConstructFrame(StackFrameIterator* iterator);
 
353
 
 
354
 private:
 
355
  friend class StackFrameIterator;
 
356
};
 
357
 
 
358
 
 
359
// Exit frames are used to exit JavaScript execution and go to C.
 
360
class ExitFrame: public StackFrame {
 
361
 public:
 
362
  virtual Type type() const { return EXIT; }
 
363
 
 
364
  virtual Code* unchecked_code() const;
 
365
 
 
366
  Object*& code_slot() const;
 
367
 
 
368
  // Garbage collection support.
 
369
  virtual void Iterate(ObjectVisitor* v) const;
 
370
 
 
371
  virtual void SetCallerFp(Address caller_fp);
 
372
 
 
373
  static ExitFrame* cast(StackFrame* frame) {
 
374
    ASSERT(frame->is_exit());
 
375
    return static_cast<ExitFrame*>(frame);
 
376
  }
 
377
 
 
378
  // Compute the state and type of an exit frame given a frame
 
379
  // pointer. Used when constructing the first stack frame seen by an
 
380
  // iterator and the frames following entry frames.
 
381
  static Type GetStateForFramePointer(Address fp, State* state);
 
382
  static Address ComputeStackPointer(Address fp);
 
383
  static void FillState(Address fp, Address sp, State* state);
 
384
 
 
385
 protected:
 
386
  inline explicit ExitFrame(StackFrameIterator* iterator);
 
387
 
 
388
  virtual Address GetCallerStackPointer() const;
 
389
 
 
390
 private:
 
391
  virtual void ComputeCallerState(State* state) const;
 
392
 
 
393
  friend class StackFrameIterator;
 
394
};
 
395
 
 
396
 
 
397
class StandardFrame: public StackFrame {
 
398
 public:
 
399
  // Testers.
 
400
  virtual bool is_standard() const { return true; }
 
401
 
 
402
  // Accessors.
 
403
  inline Object* context() const;
 
404
 
 
405
  // Access the expressions in the stack frame including locals.
 
406
  inline Object* GetExpression(int index) const;
 
407
  inline void SetExpression(int index, Object* value);
 
408
  int ComputeExpressionsCount() const;
 
409
  static Object* GetExpression(Address fp, int index);
 
410
 
 
411
  virtual void SetCallerFp(Address caller_fp);
 
412
 
 
413
  static StandardFrame* cast(StackFrame* frame) {
 
414
    ASSERT(frame->is_standard());
 
415
    return static_cast<StandardFrame*>(frame);
 
416
  }
 
417
 
 
418
 protected:
 
419
  inline explicit StandardFrame(StackFrameIterator* iterator);
 
420
 
 
421
  virtual void ComputeCallerState(State* state) const;
 
422
 
 
423
  // Accessors.
 
424
  inline Address caller_fp() const;
 
425
  inline Address caller_pc() const;
 
426
 
 
427
  // Computes the address of the PC field in the standard frame given
 
428
  // by the provided frame pointer.
 
429
  static inline Address ComputePCAddress(Address fp);
 
430
 
 
431
  // Iterate over expression stack including stack handlers, locals,
 
432
  // and parts of the fixed part including context and code fields.
 
433
  void IterateExpressions(ObjectVisitor* v) const;
 
434
 
 
435
  // Returns the address of the n'th expression stack element.
 
436
  Address GetExpressionAddress(int n) const;
 
437
  static Address GetExpressionAddress(Address fp, int n);
 
438
 
 
439
  // Determines if the n'th expression stack element is in a stack
 
440
  // handler or not. Requires traversing all handlers in this frame.
 
441
  bool IsExpressionInsideHandler(int n) const;
 
442
 
 
443
  // Determines if the standard frame for the given frame pointer is
 
444
  // an arguments adaptor frame.
 
445
  static inline bool IsArgumentsAdaptorFrame(Address fp);
 
446
 
 
447
  // Determines if the standard frame for the given frame pointer is a
 
448
  // construct frame.
 
449
  static inline bool IsConstructFrame(Address fp);
 
450
 
 
451
 private:
 
452
  friend class StackFrame;
 
453
  friend class StackFrameIterator;
 
454
};
 
455
 
 
456
 
 
457
class FrameSummary BASE_EMBEDDED {
 
458
 public:
 
459
  FrameSummary(Object* receiver,
 
460
               JSFunction* function,
 
461
               Code* code,
 
462
               int offset,
 
463
               bool is_constructor)
 
464
      : receiver_(receiver),
 
465
        function_(function),
 
466
        code_(code),
 
467
        offset_(offset),
 
468
        is_constructor_(is_constructor) { }
 
469
  Handle<Object> receiver() { return receiver_; }
 
470
  Handle<JSFunction> function() { return function_; }
 
471
  Handle<Code> code() { return code_; }
 
472
  Address pc() { return code_->address() + offset_; }
 
473
  int offset() { return offset_; }
 
474
  bool is_constructor() { return is_constructor_; }
 
475
 
 
476
  void Print();
 
477
 
 
478
 private:
 
479
  Handle<Object> receiver_;
 
480
  Handle<JSFunction> function_;
 
481
  Handle<Code> code_;
 
482
  int offset_;
 
483
  bool is_constructor_;
 
484
};
 
485
 
 
486
 
 
487
class JavaScriptFrame: public StandardFrame {
 
488
 public:
 
489
  virtual Type type() const { return JAVA_SCRIPT; }
 
490
 
 
491
  // Accessors.
 
492
  inline Object* function() const;
 
493
  inline Object* receiver() const;
 
494
  inline void set_receiver(Object* value);
 
495
 
 
496
  // Access the parameters.
 
497
  inline Address GetParameterSlot(int index) const;
 
498
  inline Object* GetParameter(int index) const;
 
499
  inline int ComputeParametersCount() const {
 
500
    return GetNumberOfIncomingArguments();
 
501
  }
 
502
 
 
503
  // Check if this frame is a constructor frame invoked through 'new'.
 
504
  bool IsConstructor() const;
 
505
 
 
506
  // Check if this frame has "adapted" arguments in the sense that the
 
507
  // actual passed arguments are available in an arguments adaptor
 
508
  // frame below it on the stack.
 
509
  inline bool has_adapted_arguments() const;
 
510
  int GetArgumentsLength() const;
 
511
 
 
512
  // Garbage collection support.
 
513
  virtual void Iterate(ObjectVisitor* v) const;
 
514
 
 
515
  // Printing support.
 
516
  virtual void Print(StringStream* accumulator,
 
517
                     PrintMode mode,
 
518
                     int index) const;
 
519
 
 
520
  // Determine the code for the frame.
 
521
  virtual Code* unchecked_code() const;
 
522
 
 
523
  // Returns the levels of inlining for this frame.
 
524
  virtual int GetInlineCount() { return 1; }
 
525
 
 
526
  // Return a list with JSFunctions of this frame.
 
527
  virtual void GetFunctions(List<JSFunction*>* functions);
 
528
 
 
529
  // Build a list with summaries for this frame including all inlined frames.
 
530
  virtual void Summarize(List<FrameSummary>* frames);
 
531
 
 
532
  static JavaScriptFrame* cast(StackFrame* frame) {
 
533
    ASSERT(frame->is_java_script());
 
534
    return static_cast<JavaScriptFrame*>(frame);
 
535
  }
 
536
 
 
537
  static void PrintTop(FILE* file, bool print_args, bool print_line_number);
 
538
 
 
539
 protected:
 
540
  inline explicit JavaScriptFrame(StackFrameIterator* iterator);
 
541
 
 
542
  virtual Address GetCallerStackPointer() const;
 
543
 
 
544
  virtual int GetNumberOfIncomingArguments() const;
 
545
 
 
546
  // Garbage collection support. Iterates over incoming arguments,
 
547
  // receiver, and any callee-saved registers.
 
548
  void IterateArguments(ObjectVisitor* v) const;
 
549
 
 
550
 private:
 
551
  inline Object* function_slot_object() const;
 
552
 
 
553
  friend class StackFrameIterator;
 
554
  friend class StackTracer;
 
555
};
 
556
 
 
557
 
 
558
class OptimizedFrame : public JavaScriptFrame {
 
559
 public:
 
560
  virtual Type type() const { return OPTIMIZED; }
 
561
 
 
562
  // GC support.
 
563
  virtual void Iterate(ObjectVisitor* v) const;
 
564
 
 
565
  virtual int GetInlineCount();
 
566
 
 
567
  // Return a list with JSFunctions of this frame.
 
568
  // The functions are ordered bottom-to-top (i.e. functions.last()
 
569
  // is the top-most activation)
 
570
  virtual void GetFunctions(List<JSFunction*>* functions);
 
571
 
 
572
  virtual void Summarize(List<FrameSummary>* frames);
 
573
 
 
574
  DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
 
575
 
 
576
 protected:
 
577
  inline explicit OptimizedFrame(StackFrameIterator* iterator);
 
578
 
 
579
 private:
 
580
  JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
 
581
 
 
582
  friend class StackFrameIterator;
 
583
};
 
584
 
 
585
 
 
586
// Arguments adaptor frames are automatically inserted below
 
587
// JavaScript frames when the actual number of parameters does not
 
588
// match the formal number of parameters.
 
589
class ArgumentsAdaptorFrame: public JavaScriptFrame {
 
590
 public:
 
591
  virtual Type type() const { return ARGUMENTS_ADAPTOR; }
 
592
 
 
593
  // Determine the code for the frame.
 
594
  virtual Code* unchecked_code() const;
 
595
 
 
596
  static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
 
597
    ASSERT(frame->is_arguments_adaptor());
 
598
    return static_cast<ArgumentsAdaptorFrame*>(frame);
 
599
  }
 
600
 
 
601
  // Printing support.
 
602
  virtual void Print(StringStream* accumulator,
 
603
                     PrintMode mode,
 
604
                     int index) const;
 
605
 
 
606
 protected:
 
607
  inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator);
 
608
 
 
609
  virtual int GetNumberOfIncomingArguments() const;
 
610
 
 
611
  virtual Address GetCallerStackPointer() const;
 
612
 
 
613
 private:
 
614
  friend class StackFrameIterator;
 
615
};
 
616
 
 
617
 
 
618
class InternalFrame: public StandardFrame {
 
619
 public:
 
620
  virtual Type type() const { return INTERNAL; }
 
621
 
 
622
  // Garbage collection support.
 
623
  virtual void Iterate(ObjectVisitor* v) const;
 
624
 
 
625
  // Determine the code for the frame.
 
626
  virtual Code* unchecked_code() const;
 
627
 
 
628
  static InternalFrame* cast(StackFrame* frame) {
 
629
    ASSERT(frame->is_internal());
 
630
    return static_cast<InternalFrame*>(frame);
 
631
  }
 
632
 
 
633
 protected:
 
634
  inline explicit InternalFrame(StackFrameIterator* iterator);
 
635
 
 
636
  virtual Address GetCallerStackPointer() const;
 
637
 
 
638
 private:
 
639
  friend class StackFrameIterator;
 
640
};
 
641
 
 
642
 
 
643
// Construct frames are special trampoline frames introduced to handle
 
644
// function invocations through 'new'.
 
645
class ConstructFrame: public InternalFrame {
 
646
 public:
 
647
  virtual Type type() const { return CONSTRUCT; }
 
648
 
 
649
  static ConstructFrame* cast(StackFrame* frame) {
 
650
    ASSERT(frame->is_construct());
 
651
    return static_cast<ConstructFrame*>(frame);
 
652
  }
 
653
 
 
654
 protected:
 
655
  inline explicit ConstructFrame(StackFrameIterator* iterator);
 
656
 
 
657
 private:
 
658
  friend class StackFrameIterator;
 
659
};
 
660
 
 
661
 
 
662
class StackFrameIterator BASE_EMBEDDED {
 
663
 public:
 
664
  // An iterator that iterates over the current thread's stack,
 
665
  // and uses current isolate.
 
666
  StackFrameIterator();
 
667
 
 
668
  // An iterator that iterates over the isolate's current thread's stack,
 
669
  explicit StackFrameIterator(Isolate* isolate);
 
670
 
 
671
  // An iterator that iterates over a given thread's stack.
 
672
  StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
 
673
 
 
674
  // An iterator that can start from a given FP address.
 
675
  // If use_top, then work as usual, if fp isn't NULL, use it,
 
676
  // otherwise, do nothing.
 
677
  StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
 
678
 
 
679
  StackFrame* frame() const {
 
680
    ASSERT(!done());
 
681
    return frame_;
 
682
  }
 
683
 
 
684
  Isolate* isolate() const { return isolate_; }
 
685
 
 
686
  bool done() const { return frame_ == NULL; }
 
687
  void Advance() { (this->*advance_)(); }
 
688
 
 
689
  // Go back to the first frame.
 
690
  void Reset();
 
691
 
 
692
 private:
 
693
  Isolate* isolate_;
 
694
#define DECLARE_SINGLETON(ignore, type) type type##_;
 
695
  STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
 
696
#undef DECLARE_SINGLETON
 
697
  StackFrame* frame_;
 
698
  StackHandler* handler_;
 
699
  ThreadLocalTop* thread_;
 
700
  Address fp_;
 
701
  Address sp_;
 
702
  void (StackFrameIterator::*advance_)();
 
703
 
 
704
  StackHandler* handler() const {
 
705
    ASSERT(!done());
 
706
    return handler_;
 
707
  }
 
708
 
 
709
  // Get the type-specific frame singleton in a given state.
 
710
  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
 
711
  // A helper function, can return a NULL pointer.
 
712
  StackFrame* SingletonFor(StackFrame::Type type);
 
713
 
 
714
  void AdvanceWithHandler();
 
715
  void AdvanceWithoutHandler();
 
716
 
 
717
  friend class StackFrame;
 
718
  friend class SafeStackFrameIterator;
 
719
  DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
 
720
};
 
721
 
 
722
 
 
723
// Iterator that supports iterating through all JavaScript frames.
 
724
template<typename Iterator>
 
725
class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
 
726
 public:
 
727
  JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
 
728
 
 
729
  inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate);
 
730
 
 
731
  inline JavaScriptFrameIteratorTemp(Isolate* isolate, ThreadLocalTop* top);
 
732
 
 
733
  // Skip frames until the frame with the given id is reached.
 
734
  explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); }
 
735
 
 
736
  inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id);
 
737
 
 
738
  JavaScriptFrameIteratorTemp(Address fp,
 
739
                              Address sp,
 
740
                              Address low_bound,
 
741
                              Address high_bound) :
 
742
      iterator_(fp, sp, low_bound, high_bound) {
 
743
    if (!done()) Advance();
 
744
  }
 
745
 
 
746
  JavaScriptFrameIteratorTemp(Isolate* isolate,
 
747
                              Address fp,
 
748
                              Address sp,
 
749
                              Address low_bound,
 
750
                              Address high_bound) :
 
751
      iterator_(isolate, fp, sp, low_bound, high_bound) {
 
752
    if (!done()) Advance();
 
753
  }
 
754
 
 
755
  inline JavaScriptFrame* frame() const;
 
756
 
 
757
  bool done() const { return iterator_.done(); }
 
758
  void Advance();
 
759
 
 
760
  // Advance to the frame holding the arguments for the current
 
761
  // frame. This only affects the current frame if it has adapted
 
762
  // arguments.
 
763
  void AdvanceToArgumentsFrame();
 
764
 
 
765
  // Go back to the first frame.
 
766
  void Reset();
 
767
 
 
768
 private:
 
769
  inline void AdvanceToId(StackFrame::Id id);
 
770
 
 
771
  Iterator iterator_;
 
772
};
 
773
 
 
774
 
 
775
typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
 
776
 
 
777
 
 
778
// NOTE: The stack trace frame iterator is an iterator that only
 
779
// traverse proper JavaScript frames; that is JavaScript frames that
 
780
// have proper JavaScript functions. This excludes the problematic
 
781
// functions in runtime.js.
 
782
class StackTraceFrameIterator: public JavaScriptFrameIterator {
 
783
 public:
 
784
  StackTraceFrameIterator();
 
785
  explicit StackTraceFrameIterator(Isolate* isolate);
 
786
  void Advance();
 
787
 
 
788
 private:
 
789
  bool IsValidFrame();
 
790
};
 
791
 
 
792
 
 
793
class SafeStackFrameIterator BASE_EMBEDDED {
 
794
 public:
 
795
  SafeStackFrameIterator(Isolate* isolate,
 
796
                         Address fp, Address sp,
 
797
                         Address low_bound, Address high_bound);
 
798
 
 
799
  StackFrame* frame() const {
 
800
    ASSERT(is_working_iterator_);
 
801
    return iterator_.frame();
 
802
  }
 
803
 
 
804
  bool done() const { return iteration_done_ ? true : iterator_.done(); }
 
805
 
 
806
  void Advance();
 
807
  void Reset();
 
808
 
 
809
  static bool is_active(Isolate* isolate);
 
810
 
 
811
  static bool IsWithinBounds(
 
812
      Address low_bound, Address high_bound, Address addr) {
 
813
    return low_bound <= addr && addr <= high_bound;
 
814
  }
 
815
 
 
816
 private:
 
817
  class StackAddressValidator {
 
818
   public:
 
819
    StackAddressValidator(Address low_bound, Address high_bound)
 
820
        : low_bound_(low_bound), high_bound_(high_bound) { }
 
821
    bool IsValid(Address addr) const {
 
822
      return IsWithinBounds(low_bound_, high_bound_, addr);
 
823
    }
 
824
   private:
 
825
    Address low_bound_;
 
826
    Address high_bound_;
 
827
  };
 
828
 
 
829
  class ExitFrameValidator {
 
830
   public:
 
831
    explicit ExitFrameValidator(const StackAddressValidator& validator)
 
832
        : validator_(validator) { }
 
833
    ExitFrameValidator(Address low_bound, Address high_bound)
 
834
        : validator_(low_bound, high_bound) { }
 
835
    bool IsValidFP(Address fp);
 
836
   private:
 
837
    StackAddressValidator validator_;
 
838
  };
 
839
 
 
840
  bool IsValidStackAddress(Address addr) const {
 
841
    return stack_validator_.IsValid(addr);
 
842
  }
 
843
  bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
 
844
  bool IsValidFrame(StackFrame* frame) const;
 
845
  bool IsValidCaller(StackFrame* frame);
 
846
  static bool IsValidTop(Isolate* isolate,
 
847
                         Address low_bound, Address high_bound);
 
848
 
 
849
  // This is a nasty hack to make sure the active count is incremented
 
850
  // before the constructor for the embedded iterator is invoked. This
 
851
  // is needed because the constructor will start looking at frames
 
852
  // right away and we need to make sure it doesn't start inspecting
 
853
  // heap objects.
 
854
  class ActiveCountMaintainer BASE_EMBEDDED {
 
855
   public:
 
856
    explicit ActiveCountMaintainer(Isolate* isolate);
 
857
    ~ActiveCountMaintainer();
 
858
   private:
 
859
    Isolate* isolate_;
 
860
  };
 
861
 
 
862
  ActiveCountMaintainer maintainer_;
 
863
  StackAddressValidator stack_validator_;
 
864
  const bool is_valid_top_;
 
865
  const bool is_valid_fp_;
 
866
  const bool is_working_iterator_;
 
867
  bool iteration_done_;
 
868
  StackFrameIterator iterator_;
 
869
};
 
870
 
 
871
 
 
872
typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
 
873
    SafeJavaScriptFrameIterator;
 
874
 
 
875
 
 
876
class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
 
877
 public:
 
878
  explicit SafeStackTraceFrameIterator(Isolate* isolate,
 
879
                                       Address fp, Address sp,
 
880
                                       Address low_bound, Address high_bound);
 
881
  void Advance();
 
882
};
 
883
 
 
884
 
 
885
class StackFrameLocator BASE_EMBEDDED {
 
886
 public:
 
887
  // Find the nth JavaScript frame on the stack. The caller must
 
888
  // guarantee that such a frame exists.
 
889
  JavaScriptFrame* FindJavaScriptFrame(int n);
 
890
 
 
891
 private:
 
892
  StackFrameIterator iterator_;
 
893
};
 
894
 
 
895
 
 
896
// Reads all frames on the current stack and copies them into the current
 
897
// zone memory.
 
898
Vector<StackFrame*> CreateStackMap(Zone* zone);
 
899
 
 
900
} }  // namespace v8::internal
 
901
 
 
902
#endif  // V8_FRAMES_H_