| 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 if (thread_ != NULL) { | 132 if (thread_ != NULL) { |
| 133 type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state); | 133 type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state); |
| 134 handler_ = StackHandler::FromAddress(Top::handler(thread_)); | 134 handler_ = StackHandler::FromAddress(Top::handler(thread_)); |
| 135 } else { | 135 } else { |
| 136 ASSERT(fp_ != NULL); | 136 ASSERT(fp_ != NULL); |
| 137 state.fp = fp_; | 137 state.fp = fp_; |
| 138 state.sp = sp_; | 138 state.sp = sp_; |
| 139 state.pc_address = | 139 state.pc_address = |
| 140 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); | 140 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); |
| 141 type = StackFrame::ComputeType(&state); | 141 type = StackFrame::ComputeType(&state); |
| 142 if (SingletonFor(type) == NULL) return; | |
| 143 } | 142 } |
| 143 if (SingletonFor(type) == NULL) return; |
| 144 frame_ = SingletonFor(type, &state); | 144 frame_ = SingletonFor(type, &state); |
| 145 } | 145 } |
| 146 | 146 |
| 147 | 147 |
| 148 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, | 148 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, |
| 149 StackFrame::State* state) { | 149 StackFrame::State* state) { |
| 150 if (type == StackFrame::NONE) return NULL; | 150 if (type == StackFrame::NONE) return NULL; |
| 151 StackFrame* result = SingletonFor(type); | 151 StackFrame* result = SingletonFor(type); |
| 152 ASSERT(result != NULL); | 152 ASSERT(result != NULL); |
| 153 result->state_ = *state; | 153 result->state_ = *state; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 Object* script = JSFunction::cast(frame()->function())->shared()->script(); | 192 Object* script = JSFunction::cast(frame()->function())->shared()->script(); |
| 193 // Don't show functions from native scripts to user. | 193 // Don't show functions from native scripts to user. |
| 194 return (script->IsScript() && | 194 return (script->IsScript() && |
| 195 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); | 195 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); |
| 196 } | 196 } |
| 197 | 197 |
| 198 | 198 |
| 199 // ------------------------------------------------------------------------- | 199 // ------------------------------------------------------------------------- |
| 200 | 200 |
| 201 | 201 |
| 202 bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) { |
| 203 if (!validator_.IsValid(fp)) return false; |
| 204 Address sp = ExitFrame::ComputeStackPointer(fp); |
| 205 if (!validator_.IsValid(sp)) return false; |
| 206 StackFrame::State state; |
| 207 ExitFrame::FillState(fp, sp, &state); |
| 208 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { |
| 209 return false; |
| 210 } |
| 211 return *state.pc_address != NULL; |
| 212 } |
| 213 |
| 214 |
| 202 SafeStackFrameIterator::SafeStackFrameIterator( | 215 SafeStackFrameIterator::SafeStackFrameIterator( |
| 203 Address fp, Address sp, Address low_bound, Address high_bound) : | 216 Address fp, Address sp, Address low_bound, Address high_bound) : |
| 204 low_bound_(low_bound), high_bound_(high_bound), | 217 stack_validator_(low_bound, high_bound), |
| 205 is_valid_top_( | 218 is_valid_top_(IsValidTop(low_bound, high_bound)), |
| 206 IsWithinBounds(low_bound, high_bound, | |
| 207 Top::c_entry_fp(Top::GetCurrentThread())) && | |
| 208 Top::handler(Top::GetCurrentThread()) != NULL), | |
| 209 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), | 219 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), |
| 210 is_working_iterator_(is_valid_top_ || is_valid_fp_), | 220 is_working_iterator_(is_valid_top_ || is_valid_fp_), |
| 211 iteration_done_(!is_working_iterator_), | 221 iteration_done_(!is_working_iterator_), |
| 212 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { | 222 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { |
| 213 } | 223 } |
| 214 | 224 |
| 215 | 225 |
| 226 bool SafeStackFrameIterator::IsValidTop(Address low_bound, Address high_bound) { |
| 227 Address fp = Top::c_entry_fp(Top::GetCurrentThread()); |
| 228 ExitFrameValidator validator(low_bound, high_bound); |
| 229 if (!validator.IsValidFP(fp)) return false; |
| 230 return Top::handler(Top::GetCurrentThread()) != NULL; |
| 231 } |
| 232 |
| 233 |
| 216 void SafeStackFrameIterator::Advance() { | 234 void SafeStackFrameIterator::Advance() { |
| 217 ASSERT(is_working_iterator_); | 235 ASSERT(is_working_iterator_); |
| 218 ASSERT(!done()); | 236 ASSERT(!done()); |
| 219 StackFrame* last_frame = iterator_.frame(); | 237 StackFrame* last_frame = iterator_.frame(); |
| 220 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); | 238 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); |
| 221 // Before advancing to the next stack frame, perform pointer validity tests | 239 // Before advancing to the next stack frame, perform pointer validity tests |
| 222 iteration_done_ = !IsValidFrame(last_frame) || | 240 iteration_done_ = !IsValidFrame(last_frame) || |
| 223 !CanIterateHandles(last_frame, iterator_.handler()) || | 241 !CanIterateHandles(last_frame, iterator_.handler()) || |
| 224 !IsValidCaller(last_frame); | 242 !IsValidCaller(last_frame); |
| 225 if (iteration_done_) return; | 243 if (iteration_done_) return; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 247 | 265 |
| 248 | 266 |
| 249 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { | 267 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { |
| 250 StackFrame::State state; | 268 StackFrame::State state; |
| 251 if (frame->is_entry() || frame->is_entry_construct()) { | 269 if (frame->is_entry() || frame->is_entry_construct()) { |
| 252 // See EntryFrame::GetCallerState. It computes the caller FP address | 270 // See EntryFrame::GetCallerState. It computes the caller FP address |
| 253 // and calls ExitFrame::GetStateForFramePointer on it. We need to be | 271 // and calls ExitFrame::GetStateForFramePointer on it. We need to be |
| 254 // sure that caller FP address is valid. | 272 // sure that caller FP address is valid. |
| 255 Address caller_fp = Memory::Address_at( | 273 Address caller_fp = Memory::Address_at( |
| 256 frame->fp() + EntryFrameConstants::kCallerFPOffset); | 274 frame->fp() + EntryFrameConstants::kCallerFPOffset); |
| 257 if (!IsValidStackAddress(caller_fp)) { | 275 ExitFrameValidator validator(stack_validator_); |
| 258 return false; | 276 if (!validator.IsValidFP(caller_fp)) return false; |
| 259 } | |
| 260 } else if (frame->is_arguments_adaptor()) { | 277 } else if (frame->is_arguments_adaptor()) { |
| 261 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that | 278 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that |
| 262 // the number of arguments is stored on stack as Smi. We need to check | 279 // the number of arguments is stored on stack as Smi. We need to check |
| 263 // that it really an Smi. | 280 // that it really an Smi. |
| 264 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> | 281 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> |
| 265 GetExpression(0); | 282 GetExpression(0); |
| 266 if (!number_of_args->IsSmi()) { | 283 if (!number_of_args->IsSmi()) { |
| 267 return false; | 284 return false; |
| 268 } | 285 } |
| 269 } | 286 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 void ExitFrame::SetCallerFp(Address caller_fp) { | 440 void ExitFrame::SetCallerFp(Address caller_fp) { |
| 424 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; | 441 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; |
| 425 } | 442 } |
| 426 | 443 |
| 427 | 444 |
| 428 Address ExitFrame::GetCallerStackPointer() const { | 445 Address ExitFrame::GetCallerStackPointer() const { |
| 429 return fp() + ExitFrameConstants::kCallerSPDisplacement; | 446 return fp() + ExitFrameConstants::kCallerSPDisplacement; |
| 430 } | 447 } |
| 431 | 448 |
| 432 | 449 |
| 450 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
| 451 if (fp == 0) return NONE; |
| 452 Address sp = ComputeStackPointer(fp); |
| 453 FillState(fp, sp, state); |
| 454 ASSERT(*state->pc_address != NULL); |
| 455 return EXIT; |
| 456 } |
| 457 |
| 458 |
| 459 void ExitFrame::FillState(Address fp, Address sp, State* state) { |
| 460 state->sp = sp; |
| 461 state->fp = fp; |
| 462 state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); |
| 463 } |
| 464 |
| 465 |
| 433 Address StandardFrame::GetExpressionAddress(int n) const { | 466 Address StandardFrame::GetExpressionAddress(int n) const { |
| 434 const int offset = StandardFrameConstants::kExpressionsOffset; | 467 const int offset = StandardFrameConstants::kExpressionsOffset; |
| 435 return fp() + offset - n * kPointerSize; | 468 return fp() + offset - n * kPointerSize; |
| 436 } | 469 } |
| 437 | 470 |
| 438 | 471 |
| 439 int StandardFrame::ComputeExpressionsCount() const { | 472 int StandardFrame::ComputeExpressionsCount() const { |
| 440 const int offset = | 473 const int offset = |
| 441 StandardFrameConstants::kExpressionsOffset + kPointerSize; | 474 StandardFrameConstants::kExpressionsOffset + kPointerSize; |
| 442 Address base = fp() + offset; | 475 Address base = fp() + offset; |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 ZoneList<StackFrame*> list(10); | 850 ZoneList<StackFrame*> list(10); |
| 818 for (StackFrameIterator it; !it.done(); it.Advance()) { | 851 for (StackFrameIterator it; !it.done(); it.Advance()) { |
| 819 StackFrame* frame = AllocateFrameCopy(it.frame()); | 852 StackFrame* frame = AllocateFrameCopy(it.frame()); |
| 820 list.Add(frame); | 853 list.Add(frame); |
| 821 } | 854 } |
| 822 return list.ToVector(); | 855 return list.ToVector(); |
| 823 } | 856 } |
| 824 | 857 |
| 825 | 858 |
| 826 } } // namespace v8::internal | 859 } } // namespace v8::internal |
| OLD | NEW |