| Index: src/frames.cc | 
| diff --git a/src/frames.cc b/src/frames.cc | 
| index 76a441b64d8ec84d70804dff4852e8f128edc3cb..3cdb0157e7d9acbfbbe91cc9d6f41c8ab47e4a59 100644 | 
| --- a/src/frames.cc | 
| +++ b/src/frames.cc | 
| @@ -143,8 +143,8 @@ void StackFrameIterator::Reset() { | 
| state.pc_address = | 
| reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); | 
| type = StackFrame::ComputeType(&state); | 
| -    if (SingletonFor(type) == NULL) return; | 
| } | 
| +  if (SingletonFor(type) == NULL) return; | 
| frame_ = SingletonFor(type, &state); | 
| } | 
|  | 
| @@ -203,13 +203,24 @@ bool StackTraceFrameIterator::IsValidFrame() { | 
| // ------------------------------------------------------------------------- | 
|  | 
|  | 
| +bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) { | 
| +  if (!validator_.IsValid(fp)) return false; | 
| +  Address sp = ExitFrame::ComputeStackPointer(fp); | 
| +  if (!validator_.IsValid(sp)) return false; | 
| +  StackFrame::State state; | 
| +  ExitFrame::FillState(fp, sp, &state); | 
| +  if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { | 
| +    return false; | 
| +  } | 
| +  return *state.pc_address != NULL; | 
| +} | 
| + | 
| + | 
| SafeStackFrameIterator::SafeStackFrameIterator( | 
| Address fp, Address sp, Address low_bound, Address high_bound) : | 
| -    maintainer_(), low_bound_(low_bound), high_bound_(high_bound), | 
| -    is_valid_top_( | 
| -        IsWithinBounds(low_bound, high_bound, | 
| -                       Top::c_entry_fp(Top::GetCurrentThread())) && | 
| -        Top::handler(Top::GetCurrentThread()) != NULL), | 
| +    maintainer_(), | 
| +    stack_validator_(low_bound, high_bound), | 
| +    is_valid_top_(IsValidTop(low_bound, high_bound)), | 
| is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), | 
| is_working_iterator_(is_valid_top_ || is_valid_fp_), | 
| iteration_done_(!is_working_iterator_), | 
| @@ -217,6 +228,14 @@ SafeStackFrameIterator::SafeStackFrameIterator( | 
| } | 
|  | 
|  | 
| +bool SafeStackFrameIterator::IsValidTop(Address low_bound, Address high_bound) { | 
| +  Address fp = Top::c_entry_fp(Top::GetCurrentThread()); | 
| +  ExitFrameValidator validator(low_bound, high_bound); | 
| +  if (!validator.IsValidFP(fp)) return false; | 
| +  return Top::handler(Top::GetCurrentThread()) != NULL; | 
| +} | 
| + | 
| + | 
| void SafeStackFrameIterator::Advance() { | 
| ASSERT(is_working_iterator_); | 
| ASSERT(!done()); | 
| @@ -258,9 +277,8 @@ bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { | 
| // sure that caller FP address is valid. | 
| Address caller_fp = Memory::Address_at( | 
| frame->fp() + EntryFrameConstants::kCallerFPOffset); | 
| -    if (!IsValidStackAddress(caller_fp)) { | 
| -      return false; | 
| -    } | 
| +    ExitFrameValidator validator(stack_validator_); | 
| +    if (!validator.IsValidFP(caller_fp)) return false; | 
| } else if (frame->is_arguments_adaptor()) { | 
| // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that | 
| // the number of arguments is stored on stack as Smi. We need to check | 
| @@ -415,6 +433,22 @@ Address ExitFrame::GetCallerStackPointer() const { | 
| } | 
|  | 
|  | 
| +StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { | 
| +  if (fp == 0) return NONE; | 
| +  Address sp = ComputeStackPointer(fp); | 
| +  FillState(fp, sp, state); | 
| +  ASSERT(*state->pc_address != NULL); | 
| +  return EXIT; | 
| +} | 
| + | 
| + | 
| +void ExitFrame::FillState(Address fp, Address sp, State* state) { | 
| +  state->sp = sp; | 
| +  state->fp = fp; | 
| +  state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); | 
| +} | 
| + | 
| + | 
| Address StandardFrame::GetExpressionAddress(int n) const { | 
| const int offset = StandardFrameConstants::kExpressionsOffset; | 
| return fp() + offset - n * kPointerSize; | 
|  |