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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 if (thread_ != NULL) { | 136 if (thread_ != NULL) { |
137 type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state); | 137 type = ExitFrame::GetStateForFramePointer(Top::c_entry_fp(thread_), &state); |
138 handler_ = StackHandler::FromAddress(Top::handler(thread_)); | 138 handler_ = StackHandler::FromAddress(Top::handler(thread_)); |
139 } else { | 139 } else { |
140 ASSERT(fp_ != NULL); | 140 ASSERT(fp_ != NULL); |
141 state.fp = fp_; | 141 state.fp = fp_; |
142 state.sp = sp_; | 142 state.sp = sp_; |
143 state.pc_address = | 143 state.pc_address = |
144 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); | 144 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); |
145 type = StackFrame::ComputeType(&state); | 145 type = StackFrame::ComputeType(&state); |
146 if (SingletonFor(type) == NULL) return; | |
147 } | 146 } |
| 147 if (SingletonFor(type) == NULL) return; |
148 frame_ = SingletonFor(type, &state); | 148 frame_ = SingletonFor(type, &state); |
149 } | 149 } |
150 | 150 |
151 | 151 |
152 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, | 152 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, |
153 StackFrame::State* state) { | 153 StackFrame::State* state) { |
154 if (type == StackFrame::NONE) return NULL; | 154 if (type == StackFrame::NONE) return NULL; |
155 StackFrame* result = SingletonFor(type); | 155 StackFrame* result = SingletonFor(type); |
156 ASSERT(result != NULL); | 156 ASSERT(result != NULL); |
157 result->state_ = *state; | 157 result->state_ = *state; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 Object* script = JSFunction::cast(frame()->function())->shared()->script(); | 196 Object* script = JSFunction::cast(frame()->function())->shared()->script(); |
197 // Don't show functions from native scripts to user. | 197 // Don't show functions from native scripts to user. |
198 return (script->IsScript() && | 198 return (script->IsScript() && |
199 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); | 199 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 // ------------------------------------------------------------------------- | 203 // ------------------------------------------------------------------------- |
204 | 204 |
205 | 205 |
| 206 bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) { |
| 207 if (!validator_.IsValid(fp)) return false; |
| 208 Address sp = ExitFrame::ComputeStackPointer(fp); |
| 209 if (!validator_.IsValid(sp)) return false; |
| 210 StackFrame::State state; |
| 211 ExitFrame::FillState(fp, sp, &state); |
| 212 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { |
| 213 return false; |
| 214 } |
| 215 return *state.pc_address != NULL; |
| 216 } |
| 217 |
| 218 |
206 SafeStackFrameIterator::SafeStackFrameIterator( | 219 SafeStackFrameIterator::SafeStackFrameIterator( |
207 Address fp, Address sp, Address low_bound, Address high_bound) : | 220 Address fp, Address sp, Address low_bound, Address high_bound) : |
208 maintainer_(), low_bound_(low_bound), high_bound_(high_bound), | 221 maintainer_(), |
209 is_valid_top_( | 222 stack_validator_(low_bound, high_bound), |
210 IsWithinBounds(low_bound, high_bound, | 223 is_valid_top_(IsValidTop(low_bound, high_bound)), |
211 Top::c_entry_fp(Top::GetCurrentThread())) && | |
212 Top::handler(Top::GetCurrentThread()) != NULL), | |
213 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), | 224 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), |
214 is_working_iterator_(is_valid_top_ || is_valid_fp_), | 225 is_working_iterator_(is_valid_top_ || is_valid_fp_), |
215 iteration_done_(!is_working_iterator_), | 226 iteration_done_(!is_working_iterator_), |
216 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { | 227 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { |
217 } | 228 } |
218 | 229 |
219 | 230 |
| 231 bool SafeStackFrameIterator::IsValidTop(Address low_bound, Address high_bound) { |
| 232 Address fp = Top::c_entry_fp(Top::GetCurrentThread()); |
| 233 ExitFrameValidator validator(low_bound, high_bound); |
| 234 if (!validator.IsValidFP(fp)) return false; |
| 235 return Top::handler(Top::GetCurrentThread()) != NULL; |
| 236 } |
| 237 |
| 238 |
220 void SafeStackFrameIterator::Advance() { | 239 void SafeStackFrameIterator::Advance() { |
221 ASSERT(is_working_iterator_); | 240 ASSERT(is_working_iterator_); |
222 ASSERT(!done()); | 241 ASSERT(!done()); |
223 StackFrame* last_frame = iterator_.frame(); | 242 StackFrame* last_frame = iterator_.frame(); |
224 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); | 243 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); |
225 // Before advancing to the next stack frame, perform pointer validity tests | 244 // Before advancing to the next stack frame, perform pointer validity tests |
226 iteration_done_ = !IsValidFrame(last_frame) || | 245 iteration_done_ = !IsValidFrame(last_frame) || |
227 !CanIterateHandles(last_frame, iterator_.handler()) || | 246 !CanIterateHandles(last_frame, iterator_.handler()) || |
228 !IsValidCaller(last_frame); | 247 !IsValidCaller(last_frame); |
229 if (iteration_done_) return; | 248 if (iteration_done_) return; |
(...skipping 21 matching lines...) Expand all Loading... |
251 | 270 |
252 | 271 |
253 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { | 272 bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { |
254 StackFrame::State state; | 273 StackFrame::State state; |
255 if (frame->is_entry() || frame->is_entry_construct()) { | 274 if (frame->is_entry() || frame->is_entry_construct()) { |
256 // See EntryFrame::GetCallerState. It computes the caller FP address | 275 // See EntryFrame::GetCallerState. It computes the caller FP address |
257 // and calls ExitFrame::GetStateForFramePointer on it. We need to be | 276 // and calls ExitFrame::GetStateForFramePointer on it. We need to be |
258 // sure that caller FP address is valid. | 277 // sure that caller FP address is valid. |
259 Address caller_fp = Memory::Address_at( | 278 Address caller_fp = Memory::Address_at( |
260 frame->fp() + EntryFrameConstants::kCallerFPOffset); | 279 frame->fp() + EntryFrameConstants::kCallerFPOffset); |
261 if (!IsValidStackAddress(caller_fp)) { | 280 ExitFrameValidator validator(stack_validator_); |
262 return false; | 281 if (!validator.IsValidFP(caller_fp)) return false; |
263 } | |
264 } else if (frame->is_arguments_adaptor()) { | 282 } else if (frame->is_arguments_adaptor()) { |
265 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that | 283 // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that |
266 // the number of arguments is stored on stack as Smi. We need to check | 284 // the number of arguments is stored on stack as Smi. We need to check |
267 // that it really an Smi. | 285 // that it really an Smi. |
268 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> | 286 Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> |
269 GetExpression(0); | 287 GetExpression(0); |
270 if (!number_of_args->IsSmi()) { | 288 if (!number_of_args->IsSmi()) { |
271 return false; | 289 return false; |
272 } | 290 } |
273 } | 291 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 IteratePc(v, pc_address(), code()); | 426 IteratePc(v, pc_address(), code()); |
409 v->VisitPointer(&code_slot()); | 427 v->VisitPointer(&code_slot()); |
410 } | 428 } |
411 | 429 |
412 | 430 |
413 Address ExitFrame::GetCallerStackPointer() const { | 431 Address ExitFrame::GetCallerStackPointer() const { |
414 return fp() + ExitFrameConstants::kCallerSPDisplacement; | 432 return fp() + ExitFrameConstants::kCallerSPDisplacement; |
415 } | 433 } |
416 | 434 |
417 | 435 |
| 436 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
| 437 if (fp == 0) return NONE; |
| 438 Address sp = ComputeStackPointer(fp); |
| 439 FillState(fp, sp, state); |
| 440 ASSERT(*state->pc_address != NULL); |
| 441 return EXIT; |
| 442 } |
| 443 |
| 444 |
| 445 void ExitFrame::FillState(Address fp, Address sp, State* state) { |
| 446 state->sp = sp; |
| 447 state->fp = fp; |
| 448 state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); |
| 449 } |
| 450 |
| 451 |
418 Address StandardFrame::GetExpressionAddress(int n) const { | 452 Address StandardFrame::GetExpressionAddress(int n) const { |
419 const int offset = StandardFrameConstants::kExpressionsOffset; | 453 const int offset = StandardFrameConstants::kExpressionsOffset; |
420 return fp() + offset - n * kPointerSize; | 454 return fp() + offset - n * kPointerSize; |
421 } | 455 } |
422 | 456 |
423 | 457 |
424 int StandardFrame::ComputeExpressionsCount() const { | 458 int StandardFrame::ComputeExpressionsCount() const { |
425 const int offset = | 459 const int offset = |
426 StandardFrameConstants::kExpressionsOffset + kPointerSize; | 460 StandardFrameConstants::kExpressionsOffset + kPointerSize; |
427 Address base = fp() + offset; | 461 Address base = fp() + offset; |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 ZoneList<StackFrame*> list(10); | 932 ZoneList<StackFrame*> list(10); |
899 for (StackFrameIterator it; !it.done(); it.Advance()) { | 933 for (StackFrameIterator it; !it.done(); it.Advance()) { |
900 StackFrame* frame = AllocateFrameCopy(it.frame()); | 934 StackFrame* frame = AllocateFrameCopy(it.frame()); |
901 list.Add(frame); | 935 list.Add(frame); |
902 } | 936 } |
903 return list.ToVector(); | 937 return list.ToVector(); |
904 } | 938 } |
905 | 939 |
906 | 940 |
907 } } // namespace v8::internal | 941 } } // namespace v8::internal |
OLD | NEW |