| Index: src/frames.cc
|
| ===================================================================
|
| --- src/frames.cc (revision 5469)
|
| +++ src/frames.cc (working copy)
|
| @@ -139,8 +139,8 @@
|
| 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);
|
| }
|
|
|
| @@ -199,13 +199,23 @@
|
| // -------------------------------------------------------------------------
|
|
|
|
|
| +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) :
|
| - 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),
|
| + 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_),
|
| @@ -213,6 +223,14 @@
|
| }
|
|
|
|
|
| +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());
|
| @@ -254,9 +272,8 @@
|
| // 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
|
| @@ -430,6 +447,22 @@
|
| }
|
|
|
|
|
| +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;
|
|
|