説明を見る。00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_FRAMES_H_
00029 #define V8_FRAMES_H_
00030
00031 namespace v8 { namespace internal {
00032
00033 typedef uint32_t RegList;
00034
00035
00036 int NumRegs(RegList list);
00037
00038
00039 int JSCallerSavedCode(int n);
00040
00041
00042
00043 class StackFrameIterator;
00044 class Top;
00045 class ThreadLocalTop;
00046
00047
00048 class StackHandler BASE_EMBEDDED {
00049 public:
00050 enum State {
00051 ENTRY,
00052 TRY_CATCH,
00053 TRY_FINALLY
00054 };
00055
00056
00057 inline Address address() const;
00058
00059
00060 inline StackHandler* next() const;
00061
00062
00063 inline bool includes(Address address) const;
00064
00065
00066 inline void Iterate(ObjectVisitor* v) const;
00067
00068
00069 static inline StackHandler* FromAddress(Address address);
00070
00071
00072 bool is_entry() { return state() == ENTRY; }
00073 bool is_try_catch() { return state() == TRY_CATCH; }
00074 bool is_try_finally() { return state() == TRY_FINALLY; }
00075
00076
00077 void Cook(Code* code);
00078 void Uncook(Code* code);
00079
00080
00081 static const int kCodeNotPresent = 0;
00082
00083 private:
00084
00085 inline State state() const;
00086
00087 inline Address pc() const;
00088 inline void set_pc(Address value);
00089
00090 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
00091 };
00092
00093
00094 #define STACK_FRAME_TYPE_LIST(V) \
00095 V(ENTRY, EntryFrame) \
00096 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
00097 V(EXIT, ExitFrame) \
00098 V(EXIT_DEBUG, ExitDebugFrame) \
00099 V(JAVA_SCRIPT, JavaScriptFrame) \
00100 V(INTERNAL, InternalFrame) \
00101 V(CONSTRUCT, ConstructFrame) \
00102 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
00103
00104
00105
00106 class StackFrame BASE_EMBEDDED {
00107 public:
00108 #define DECLARE_TYPE(type, ignore) type,
00109 enum Type {
00110 NONE = 0,
00111 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
00112 NUMBER_OF_TYPES
00113 };
00114 #undef DECLARE_TYPE
00115
00116
00117
00118 enum Id { NO_ID = 0 };
00119
00120
00121 bool is_entry() const { return type() == ENTRY; }
00122 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
00123 bool is_exit() const { return type() == EXIT; }
00124 bool is_exit_debug() const { return type() == EXIT_DEBUG; }
00125 bool is_java_script() const { return type() == JAVA_SCRIPT; }
00126 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
00127 bool is_internal() const { return type() == INTERNAL; }
00128 bool is_construct() const { return type() == CONSTRUCT; }
00129 virtual bool is_standard() const { return false; }
00130
00131
00132 Address sp() const { return state_.sp; }
00133 Address fp() const { return state_.fp; }
00134 Address pp() const { return GetCallerStackPointer(); }
00135
00136 Address pc() const { return *pc_address(); }
00137 void set_pc(Address pc) { *pc_address() = pc; }
00138
00139 Address* pc_address() const { return state_.pc_address; }
00140
00141
00142 Id id() const { return static_cast<Id>(OffsetFrom(pp())); }
00143
00144
00145 bool HasHandler() const;
00146
00147
00148 virtual Type type() const = 0;
00149
00150
00151 virtual Code* FindCode() const = 0;
00152
00153
00154 static void CookFramesForThread(ThreadLocalTop* thread);
00155 static void UncookFramesForThread(ThreadLocalTop* thread);
00156
00157 virtual void Iterate(ObjectVisitor* v) const { }
00158
00159
00160 enum PrintMode { OVERVIEW, DETAILS };
00161 virtual void Print(StringStream* accumulator,
00162 PrintMode mode,
00163 int index) const { }
00164
00165 protected:
00166 struct State {
00167 Address sp;
00168 Address fp;
00169 Address* pc_address;
00170 };
00171
00172 explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { }
00173 virtual ~StackFrame() { }
00174
00175
00176 virtual Address GetCallerStackPointer() const = 0;
00177
00178
00179 static void PrintIndex(StringStream* accumulator,
00180 PrintMode mode,
00181 int index);
00182
00183
00184 inline StackHandler* top_handler() const;
00185
00186
00187 static Type ComputeType(State* state);
00188
00189 private:
00190 const StackFrameIterator* iterator_;
00191 State state_;
00192
00193
00194 virtual Type GetCallerState(State* state) const = 0;
00195
00196
00197 void Cook();
00198 void Uncook();
00199
00200 friend class StackFrameIterator;
00201 friend class StackHandlerIterator;
00202
00203 DISALLOW_IMPLICIT_CONSTRUCTORS(StackFrame);
00204 };
00205
00206
00207
00208 class EntryFrame: public StackFrame {
00209 public:
00210 virtual Type type() const { return ENTRY; }
00211
00212 virtual Code* FindCode() const;
00213
00214
00215 virtual void Iterate(ObjectVisitor* v) const;
00216
00217 static EntryFrame* cast(StackFrame* frame) {
00218 ASSERT(frame->is_entry());
00219 return static_cast<EntryFrame*>(frame);
00220 }
00221
00222 protected:
00223 explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
00224
00225
00226
00227
00228 virtual Address GetCallerStackPointer() const { return 0; }
00229
00230 private:
00231 virtual Type GetCallerState(State* state) const;
00232
00233 friend class StackFrameIterator;
00234 };
00235
00236
00237 class EntryConstructFrame: public EntryFrame {
00238 public:
00239 virtual Type type() const { return ENTRY_CONSTRUCT; }
00240
00241 virtual Code* FindCode() const;
00242
00243 static EntryConstructFrame* cast(StackFrame* frame) {
00244 ASSERT(frame->is_entry_construct());
00245 return static_cast<EntryConstructFrame*>(frame);
00246 }
00247
00248 protected:
00249 explicit EntryConstructFrame(StackFrameIterator* iterator)
00250 : EntryFrame(iterator) { }
00251
00252 private:
00253 friend class StackFrameIterator;
00254 };
00255
00256
00257
00258 class ExitFrame: public StackFrame {
00259 public:
00260 virtual Type type() const { return EXIT; }
00261
00262 virtual Code* FindCode() const;
00263
00264
00265 virtual void Iterate(ObjectVisitor* v) const;
00266
00267 static ExitFrame* cast(StackFrame* frame) {
00268 ASSERT(frame->is_exit());
00269 return static_cast<ExitFrame*>(frame);
00270 }
00271
00272
00273
00274
00275 static Type GetStateForFramePointer(Address fp, State* state);
00276
00277 protected:
00278 explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
00279
00280 virtual Address GetCallerStackPointer() const;
00281
00282 private:
00283 virtual Type GetCallerState(State* state) const;
00284
00285 friend class StackFrameIterator;
00286 };
00287
00288
00289 class ExitDebugFrame: public ExitFrame {
00290 public:
00291 virtual Type type() const { return EXIT_DEBUG; }
00292
00293 virtual Code* FindCode() const;
00294
00295 static ExitDebugFrame* cast(StackFrame* frame) {
00296 ASSERT(frame->is_exit_debug());
00297 return static_cast<ExitDebugFrame*>(frame);
00298 }
00299
00300 protected:
00301 explicit ExitDebugFrame(StackFrameIterator* iterator)
00302 : ExitFrame(iterator) { }
00303
00304 private:
00305 friend class StackFrameIterator;
00306 };
00307
00308
00309 class StandardFrame: public StackFrame {
00310 public:
00311
00312 virtual bool is_standard() const { return true; }
00313
00314
00315 inline Object* context() const;
00316
00317
00318 inline Object* GetExpression(int index) const;
00319 inline void SetExpression(int index, Object* value);
00320 int ComputeExpressionsCount() const;
00321
00322 static StandardFrame* cast(StackFrame* frame) {
00323 ASSERT(frame->is_standard());
00324 return static_cast<StandardFrame*>(frame);
00325 }
00326
00327 protected:
00328 explicit StandardFrame(StackFrameIterator* iterator)
00329 : StackFrame(iterator) { }
00330
00331 virtual Type GetCallerState(State* state) const;
00332
00333
00334 inline Address caller_sp() const;
00335 inline Address caller_fp() const;
00336 inline Address caller_pc() const;
00337
00338
00339
00340 static inline Address ComputePCAddress(Address fp);
00341
00342
00343
00344 void IterateExpressions(ObjectVisitor* v) const;
00345
00346
00347 Address GetExpressionAddress(int n) const;
00348
00349
00350
00351 bool IsExpressionInsideHandler(int n) const;
00352
00353
00354
00355 static inline bool IsArgumentsAdaptorFrame(Address fp);
00356
00357
00358
00359 static inline bool IsConstructFrame(Address fp);
00360
00361 private:
00362 friend class StackFrame;
00363 };
00364
00365
00366 class JavaScriptFrame: public StandardFrame {
00367 public:
00368 virtual Type type() const { return JAVA_SCRIPT; }
00369
00370
00371 inline Object* function() const;
00372 inline Object* receiver() const;
00373 inline void set_receiver(Object* value);
00374
00375
00376 Object* GetParameter(int index) const;
00377 int ComputeParametersCount() const;
00378
00379
00380
00381
00382
00383 int GetProvidedParametersCount() const;
00384
00385
00386 bool IsConstructor() const;
00387
00388
00389
00390
00391 inline bool has_adapted_arguments() const;
00392
00393
00394 virtual void Iterate(ObjectVisitor* v) const;
00395
00396
00397 virtual void Print(StringStream* accumulator,
00398 PrintMode mode,
00399 int index) const;
00400
00401
00402 virtual Code* FindCode() const;
00403
00404 static JavaScriptFrame* cast(StackFrame* frame) {
00405 ASSERT(frame->is_java_script());
00406 return static_cast<JavaScriptFrame*>(frame);
00407 }
00408
00409 protected:
00410 explicit JavaScriptFrame(StackFrameIterator* iterator)
00411 : StandardFrame(iterator) { }
00412
00413 virtual Address GetCallerStackPointer() const;
00414
00415 private:
00416 friend class StackFrameIterator;
00417 };
00418
00419
00420
00421
00422
00423 class ArgumentsAdaptorFrame: public JavaScriptFrame {
00424 public:
00425
00426
00427
00428
00429 enum {
00430 SENTINEL = (1 << kSmiTagSize) | kSmiTag
00431 };
00432
00433 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
00434
00435
00436 virtual Code* FindCode() const;
00437
00438 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
00439 ASSERT(frame->is_arguments_adaptor());
00440 return static_cast<ArgumentsAdaptorFrame*>(frame);
00441 }
00442
00443
00444 virtual void Print(StringStream* accumulator,
00445 PrintMode mode,
00446 int index) const;
00447 protected:
00448 explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator)
00449 : JavaScriptFrame(iterator) { }
00450
00451 virtual Address GetCallerStackPointer() const;
00452
00453 private:
00454 friend class StackFrameIterator;
00455 };
00456
00457
00458 class InternalFrame: public StandardFrame {
00459 public:
00460 virtual Type type() const { return INTERNAL; }
00461
00462
00463 virtual void Iterate(ObjectVisitor* v) const;
00464
00465
00466 virtual Code* FindCode() const;
00467
00468 static InternalFrame* cast(StackFrame* frame) {
00469 ASSERT(frame->is_internal());
00470 return static_cast<InternalFrame*>(frame);
00471 }
00472
00473 protected:
00474 explicit InternalFrame(StackFrameIterator* iterator)
00475 : StandardFrame(iterator) { }
00476
00477 virtual Address GetCallerStackPointer() const;
00478
00479 private:
00480 friend class StackFrameIterator;
00481 };
00482
00483
00484
00485
00486 class ConstructFrame: public InternalFrame {
00487 public:
00488 virtual Type type() const { return CONSTRUCT; }
00489
00490 static ConstructFrame* cast(StackFrame* frame) {
00491 ASSERT(frame->is_construct());
00492 return static_cast<ConstructFrame*>(frame);
00493 }
00494
00495 protected:
00496 explicit ConstructFrame(StackFrameIterator* iterator)
00497 : InternalFrame(iterator) { }
00498
00499 private:
00500 friend class StackFrameIterator;
00501 };
00502
00503
00504 class StackFrameIterator BASE_EMBEDDED {
00505 public:
00506
00507 StackFrameIterator();
00508
00509
00510 explicit StackFrameIterator(ThreadLocalTop* thread);
00511
00512 StackFrame* frame() const {
00513 ASSERT(!done());
00514 return frame_;
00515 }
00516
00517 bool done() const { return frame_ == NULL; }
00518 void Advance();
00519
00520
00521 void Reset();
00522
00523 private:
00524 #define DECLARE_SINGLETON(ignore, type) type type##_;
00525 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
00526 #undef DECLARE_SINGLETON
00527 StackFrame* frame_;
00528 StackHandler* handler_;
00529 ThreadLocalTop* thread_;
00530
00531 StackHandler* handler() const {
00532 ASSERT(!done());
00533 return handler_;
00534 }
00535
00536
00537 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
00538
00539 friend class StackFrame;
00540 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
00541 };
00542
00543
00544
00545 class JavaScriptFrameIterator BASE_EMBEDDED {
00546 public:
00547 JavaScriptFrameIterator() { if (!done()) Advance(); }
00548
00549 explicit JavaScriptFrameIterator(ThreadLocalTop* thread) : iterator_(thread) {
00550 if (!done()) Advance();
00551 }
00552
00553
00554 explicit JavaScriptFrameIterator(StackFrame::Id id);
00555
00556 inline JavaScriptFrame* frame() const;
00557
00558 bool done() const { return iterator_.done(); }
00559 void Advance();
00560
00561
00562
00563
00564 void AdvanceToArgumentsFrame();
00565
00566
00567 void Reset();
00568
00569 private:
00570 StackFrameIterator iterator_;
00571 };
00572
00573
00574 class StackFrameLocator BASE_EMBEDDED {
00575 public:
00576
00577
00578 JavaScriptFrame* FindJavaScriptFrame(int n);
00579
00580 private:
00581 StackFrameIterator iterator_;
00582 };
00583
00584
00585 } }
00586
00587 #endif // V8_FRAMES_H_