| 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 21 matching lines...) Expand all  Loading... | 
|    32 #include "frames-inl.h" |    32 #include "frames-inl.h" | 
|    33 #include "full-codegen.h" |    33 #include "full-codegen.h" | 
|    34 #include "mark-compact.h" |    34 #include "mark-compact.h" | 
|    35 #include "safepoint-table.h" |    35 #include "safepoint-table.h" | 
|    36 #include "scopeinfo.h" |    36 #include "scopeinfo.h" | 
|    37 #include "string-stream.h" |    37 #include "string-stream.h" | 
|    38  |    38  | 
|    39 namespace v8 { |    39 namespace v8 { | 
|    40 namespace internal { |    40 namespace internal { | 
|    41  |    41  | 
 |    42  | 
 |    43 int SafeStackFrameIterator::active_count_ = 0; | 
 |    44  | 
|    42 // Iterator that supports traversing the stack handlers of a |    45 // Iterator that supports traversing the stack handlers of a | 
|    43 // particular frame. Needs to know the top of the handler chain. |    46 // particular frame. Needs to know the top of the handler chain. | 
|    44 class StackHandlerIterator BASE_EMBEDDED { |    47 class StackHandlerIterator BASE_EMBEDDED { | 
|    45  public: |    48  public: | 
|    46   StackHandlerIterator(const StackFrame* frame, StackHandler* handler) |    49   StackHandlerIterator(const StackFrame* frame, StackHandler* handler) | 
|    47       : limit_(frame->fp()), handler_(handler) { |    50       : limit_(frame->fp()), handler_(handler) { | 
|    48     // Make sure the handler has already been unwound to this frame. |    51     // Make sure the handler has already been unwound to this frame. | 
|    49     ASSERT(frame->sp() <= handler->address()); |    52     ASSERT(frame->sp() <= handler->address()); | 
|    50   } |    53   } | 
|    51  |    54  | 
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   211   if (!validator_.IsValid(sp)) return false; |   214   if (!validator_.IsValid(sp)) return false; | 
|   212   StackFrame::State state; |   215   StackFrame::State state; | 
|   213   ExitFrame::FillState(fp, sp, &state); |   216   ExitFrame::FillState(fp, sp, &state); | 
|   214   if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { |   217   if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { | 
|   215     return false; |   218     return false; | 
|   216   } |   219   } | 
|   217   return *state.pc_address != NULL; |   220   return *state.pc_address != NULL; | 
|   218 } |   221 } | 
|   219  |   222  | 
|   220  |   223  | 
|   221 SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer( |  | 
|   222     Isolate* isolate) |  | 
|   223     : isolate_(isolate) { |  | 
|   224   isolate_->set_safe_stack_iterator_counter( |  | 
|   225       isolate_->safe_stack_iterator_counter() + 1); |  | 
|   226 } |  | 
|   227  |  | 
|   228  |  | 
|   229 SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() { |  | 
|   230   isolate_->set_safe_stack_iterator_counter( |  | 
|   231       isolate_->safe_stack_iterator_counter() - 1); |  | 
|   232 } |  | 
|   233  |  | 
|   234  |  | 
|   235 SafeStackFrameIterator::SafeStackFrameIterator( |   224 SafeStackFrameIterator::SafeStackFrameIterator( | 
|   236     Isolate* isolate, |   225     Isolate* isolate, | 
|   237     Address fp, Address sp, Address low_bound, Address high_bound) : |   226     Address fp, Address sp, Address low_bound, Address high_bound) : | 
|   238     maintainer_(isolate), |   227     maintainer_(), | 
|   239     stack_validator_(low_bound, high_bound), |   228     stack_validator_(low_bound, high_bound), | 
|   240     is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), |   229     is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), | 
|   241     is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), |   230     is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), | 
|   242     is_working_iterator_(is_valid_top_ || is_valid_fp_), |   231     is_working_iterator_(is_valid_top_ || is_valid_fp_), | 
|   243     iteration_done_(!is_working_iterator_), |   232     iteration_done_(!is_working_iterator_), | 
|   244     iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { |   233     iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { | 
|   245 } |   234 } | 
|   246  |   235  | 
|   247 bool SafeStackFrameIterator::is_active(Isolate* isolate) { |  | 
|   248   return isolate->safe_stack_iterator_counter() > 0; |  | 
|   249 } |  | 
|   250  |  | 
|   251  |   236  | 
|   252 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, |   237 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, | 
|   253                                         Address low_bound, Address high_bound) { |   238                                         Address low_bound, Address high_bound) { | 
|   254   ThreadLocalTop* top = isolate->thread_local_top(); |   239   ThreadLocalTop* top = isolate->thread_local_top(); | 
|   255   Address fp = Isolate::c_entry_fp(top); |   240   Address fp = Isolate::c_entry_fp(top); | 
|   256   ExitFrameValidator validator(low_bound, high_bound); |   241   ExitFrameValidator validator(low_bound, high_bound); | 
|   257   if (!validator.IsValidFP(fp)) return false; |   242   if (!validator.IsValidFP(fp)) return false; | 
|   258   return Isolate::handler(top) != NULL; |   243   return Isolate::handler(top) != NULL; | 
|   259 } |   244 } | 
|   260  |   245  | 
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   396   ASSERT(state->fp != NULL); |   381   ASSERT(state->fp != NULL); | 
|   397   if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |   382   if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { | 
|   398     return ARGUMENTS_ADAPTOR; |   383     return ARGUMENTS_ADAPTOR; | 
|   399   } |   384   } | 
|   400   // The marker and function offsets overlap. If the marker isn't a |   385   // The marker and function offsets overlap. If the marker isn't a | 
|   401   // smi then the frame is a JavaScript frame -- and the marker is |   386   // smi then the frame is a JavaScript frame -- and the marker is | 
|   402   // really the function. |   387   // really the function. | 
|   403   const int offset = StandardFrameConstants::kMarkerOffset; |   388   const int offset = StandardFrameConstants::kMarkerOffset; | 
|   404   Object* marker = Memory::Object_at(state->fp + offset); |   389   Object* marker = Memory::Object_at(state->fp + offset); | 
|   405   if (!marker->IsSmi()) { |   390   if (!marker->IsSmi()) { | 
|   406     Isolate* isolate = Isolate::Current(); |  | 
|   407     // If we're using a "safe" stack iterator, we treat optimized |   391     // If we're using a "safe" stack iterator, we treat optimized | 
|   408     // frames as normal JavaScript frames to avoid having to look |   392     // frames as normal JavaScript frames to avoid having to look | 
|   409     // into the heap to determine the state. This is safe as long |   393     // into the heap to determine the state. This is safe as long | 
|   410     // as nobody tries to GC... |   394     // as nobody tries to GC... | 
|   411     if (SafeStackFrameIterator::is_active(isolate)) |   395     if (SafeStackFrameIterator::is_active()) return JAVA_SCRIPT; | 
|   412       return JAVA_SCRIPT; |   396     Code::Kind kind = GetContainingCode(Isolate::Current(), | 
|   413     Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind(); |   397                                         *(state->pc_address))->kind(); | 
|   414     ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); |   398     ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); | 
|   415     return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; |   399     return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; | 
|   416   } |   400   } | 
|   417   return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |   401   return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 
|   418 } |   402 } | 
|   419  |   403  | 
|   420  |   404  | 
|   421  |   405  | 
|   422 StackFrame::Type StackFrame::GetCallerState(State* state) const { |   406 StackFrame::Type StackFrame::GetCallerState(State* state) const { | 
|   423   ComputeCallerState(state); |   407   ComputeCallerState(state); | 
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   548  |   532  | 
|   549 void OptimizedFrame::Iterate(ObjectVisitor* v) const { |   533 void OptimizedFrame::Iterate(ObjectVisitor* v) const { | 
|   550 #ifdef DEBUG |   534 #ifdef DEBUG | 
|   551   // Make sure that optimized frames do not contain any stack handlers. |   535   // Make sure that optimized frames do not contain any stack handlers. | 
|   552   StackHandlerIterator it(this, top_handler()); |   536   StackHandlerIterator it(this, top_handler()); | 
|   553   ASSERT(it.done()); |   537   ASSERT(it.done()); | 
|   554 #endif |   538 #endif | 
|   555  |   539  | 
|   556   // Make sure that we're not doing "safe" stack frame iteration. We cannot |   540   // Make sure that we're not doing "safe" stack frame iteration. We cannot | 
|   557   // possibly find pointers in optimized frames in that state. |   541   // possibly find pointers in optimized frames in that state. | 
|   558   ASSERT(!SafeStackFrameIterator::is_active(Isolate::Current())); |   542   ASSERT(!SafeStackFrameIterator::is_active()); | 
|   559  |   543  | 
|   560   // Compute the safepoint information. |   544   // Compute the safepoint information. | 
|   561   unsigned stack_slots = 0; |   545   unsigned stack_slots = 0; | 
|   562   SafepointEntry safepoint_entry; |   546   SafepointEntry safepoint_entry; | 
|   563   Code* code = StackFrame::GetSafepointData( |   547   Code* code = StackFrame::GetSafepointData( | 
|   564       pc(), &safepoint_entry, &stack_slots); |   548       pc(), &safepoint_entry, &stack_slots); | 
|   565   unsigned slot_space = stack_slots * kPointerSize; |   549   unsigned slot_space = stack_slots * kPointerSize; | 
|   566  |   550  | 
|   567   // Visit the outgoing parameters. This is usually dealt with by the |   551   // Visit the outgoing parameters. This is usually dealt with by the | 
|   568   // callee, but while GC'ing we artificially lower the number of |   552   // callee, but while GC'ing we artificially lower the number of | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   649  |   633  | 
|   650  |   634  | 
|   651 Code* JavaScriptFrame::unchecked_code() const { |   635 Code* JavaScriptFrame::unchecked_code() const { | 
|   652   JSFunction* function = JSFunction::cast(this->function()); |   636   JSFunction* function = JSFunction::cast(this->function()); | 
|   653   return function->unchecked_code(); |   637   return function->unchecked_code(); | 
|   654 } |   638 } | 
|   655  |   639  | 
|   656  |   640  | 
|   657 Address JavaScriptFrame::GetCallerStackPointer() const { |   641 Address JavaScriptFrame::GetCallerStackPointer() const { | 
|   658   int arguments; |   642   int arguments; | 
|   659   Isolate* isolate = Isolate::Current(); |   643   if (SafeStackFrameIterator::is_active() || | 
|   660   if (SafeStackFrameIterator::is_active(isolate) || |   644       HEAP->gc_state() != Heap::NOT_IN_GC) { | 
|   661       isolate->heap()->gc_state() != Heap::NOT_IN_GC) { |  | 
|   662     // If the we are currently iterating the safe stack the |   645     // If the we are currently iterating the safe stack the | 
|   663     // arguments for frames are traversed as if they were |   646     // arguments for frames are traversed as if they were | 
|   664     // expression stack elements of the calling frame. The reason for |   647     // expression stack elements of the calling frame. The reason for | 
|   665     // this rather strange decision is that we cannot access the |   648     // this rather strange decision is that we cannot access the | 
|   666     // function during mark-compact GCs when objects may have been marked. |   649     // function during mark-compact GCs when objects may have been marked. | 
|   667     // In fact accessing heap objects (like function->shared() below) |   650     // In fact accessing heap objects (like function->shared() below) | 
|   668     // at all during GC is problematic. |   651     // at all during GC is problematic. | 
|   669     arguments = 0; |   652     arguments = 0; | 
|   670   } else { |   653   } else { | 
|   671     // Compute the number of arguments by getting the number of formal |   654     // Compute the number of arguments by getting the number of formal | 
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1250   ZoneList<StackFrame*> list(10); |  1233   ZoneList<StackFrame*> list(10); | 
|  1251   for (StackFrameIterator it; !it.done(); it.Advance()) { |  1234   for (StackFrameIterator it; !it.done(); it.Advance()) { | 
|  1252     StackFrame* frame = AllocateFrameCopy(it.frame()); |  1235     StackFrame* frame = AllocateFrameCopy(it.frame()); | 
|  1253     list.Add(frame); |  1236     list.Add(frame); | 
|  1254   } |  1237   } | 
|  1255   return list.ToVector(); |  1238   return list.ToVector(); | 
|  1256 } |  1239 } | 
|  1257  |  1240  | 
|  1258  |  1241  | 
|  1259 } }  // namespace v8::internal |  1242 } }  // namespace v8::internal | 
| OLD | NEW |