Chromium Code Reviews| 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 | |
| 45 // Iterator that supports traversing the stack handlers of a | 42 // Iterator that supports traversing the stack handlers of a |
| 46 // particular frame. Needs to know the top of the handler chain. | 43 // particular frame. Needs to know the top of the handler chain. |
| 47 class StackHandlerIterator BASE_EMBEDDED { | 44 class StackHandlerIterator BASE_EMBEDDED { |
| 48 public: | 45 public: |
| 49 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) | 46 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) |
| 50 : limit_(frame->fp()), handler_(handler) { | 47 : limit_(frame->fp()), handler_(handler) { |
| 51 // Make sure the handler has already been unwound to this frame. | 48 // Make sure the handler has already been unwound to this frame. |
| 52 ASSERT(frame->sp() <= handler->address()); | 49 ASSERT(frame->sp() <= handler->address()); |
| 53 } | 50 } |
| 54 | 51 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 68 }; | 65 }; |
| 69 | 66 |
| 70 | 67 |
| 71 // ------------------------------------------------------------------------- | 68 // ------------------------------------------------------------------------- |
| 72 | 69 |
| 73 | 70 |
| 74 #define INITIALIZE_SINGLETON(type, field) field##_(this), | 71 #define INITIALIZE_SINGLETON(type, field) field##_(this), |
| 75 StackFrameIterator::StackFrameIterator() | 72 StackFrameIterator::StackFrameIterator() |
| 76 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | 73 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) |
| 77 frame_(NULL), handler_(NULL), | 74 frame_(NULL), handler_(NULL), |
| 78 thread_(Isolate::Current()->thread_local_top()), | 75 isolate_(Isolate::Current()), |
| 76 thread_(isolate_->thread_local_top()), | |
| 79 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { | 77 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { |
| 80 Reset(); | 78 Reset(); |
| 81 } | 79 } |
| 82 StackFrameIterator::StackFrameIterator(ThreadLocalTop* t) | 80 StackFrameIterator::StackFrameIterator(Isolate* isolate) |
| 83 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | 81 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) |
| 84 frame_(NULL), handler_(NULL), thread_(t), | 82 frame_(NULL), handler_(NULL), |
| 83 isolate_(isolate), thread_(isolate_->thread_local_top()), | |
| 85 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { | 84 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { |
| 86 Reset(); | 85 Reset(); |
| 87 } | 86 } |
| 87 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) | |
| 88 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | |
| 89 frame_(NULL), handler_(NULL), isolate_(isolate), thread_(t), | |
| 90 fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { | |
| 91 Reset(); | |
| 92 } | |
| 88 StackFrameIterator::StackFrameIterator(Isolate* isolate, | 93 StackFrameIterator::StackFrameIterator(Isolate* isolate, |
| 89 bool use_top, Address fp, Address sp) | 94 bool use_top, Address fp, Address sp) |
| 90 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) | 95 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) |
| 91 frame_(NULL), handler_(NULL), | 96 frame_(NULL), handler_(NULL), |
| 92 thread_(use_top ? isolate->thread_local_top() : NULL), | 97 isolate_(isolate), |
| 98 thread_(use_top ? isolate_->thread_local_top() : NULL), | |
| 93 fp_(use_top ? NULL : fp), sp_(sp), | 99 fp_(use_top ? NULL : fp), sp_(sp), |
| 94 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : | 100 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : |
| 95 &StackFrameIterator::AdvanceWithoutHandler) { | 101 &StackFrameIterator::AdvanceWithoutHandler) { |
| 96 if (use_top || fp != NULL) { | 102 if (use_top || fp != NULL) { |
| 97 Reset(); | 103 Reset(); |
| 98 } | 104 } |
| 99 } | 105 } |
| 100 | 106 |
| 101 #undef INITIALIZE_SINGLETON | 107 #undef INITIALIZE_SINGLETON |
| 102 | 108 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 type = ExitFrame::GetStateForFramePointer( | 146 type = ExitFrame::GetStateForFramePointer( |
| 141 Isolate::c_entry_fp(thread_), &state); | 147 Isolate::c_entry_fp(thread_), &state); |
| 142 handler_ = StackHandler::FromAddress( | 148 handler_ = StackHandler::FromAddress( |
| 143 Isolate::handler(thread_)); | 149 Isolate::handler(thread_)); |
| 144 } else { | 150 } else { |
| 145 ASSERT(fp_ != NULL); | 151 ASSERT(fp_ != NULL); |
| 146 state.fp = fp_; | 152 state.fp = fp_; |
| 147 state.sp = sp_; | 153 state.sp = sp_; |
| 148 state.pc_address = | 154 state.pc_address = |
| 149 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); | 155 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); |
| 150 type = StackFrame::ComputeType(&state); | 156 type = StackFrame::ComputeType(isolate(), &state); |
| 151 } | 157 } |
| 152 if (SingletonFor(type) == NULL) return; | 158 if (SingletonFor(type) == NULL) return; |
| 153 frame_ = SingletonFor(type, &state); | 159 frame_ = SingletonFor(type, &state); |
| 154 } | 160 } |
| 155 | 161 |
| 156 | 162 |
| 157 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, | 163 StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, |
| 158 StackFrame::State* state) { | 164 StackFrame::State* state) { |
| 159 if (type == StackFrame::NONE) return NULL; | 165 if (type == StackFrame::NONE) return NULL; |
| 160 StackFrame* result = SingletonFor(type); | 166 StackFrame* result = SingletonFor(type); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 181 | 187 |
| 182 | 188 |
| 183 // ------------------------------------------------------------------------- | 189 // ------------------------------------------------------------------------- |
| 184 | 190 |
| 185 | 191 |
| 186 StackTraceFrameIterator::StackTraceFrameIterator() { | 192 StackTraceFrameIterator::StackTraceFrameIterator() { |
| 187 if (!done() && !IsValidFrame()) Advance(); | 193 if (!done() && !IsValidFrame()) Advance(); |
| 188 } | 194 } |
| 189 | 195 |
| 190 | 196 |
| 197 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) | |
| 198 : JavaScriptFrameIterator(isolate) { | |
| 199 if (!done() && !IsValidFrame()) Advance(); | |
| 200 } | |
| 201 | |
| 202 | |
| 191 void StackTraceFrameIterator::Advance() { | 203 void StackTraceFrameIterator::Advance() { |
| 192 while (true) { | 204 while (true) { |
| 193 JavaScriptFrameIterator::Advance(); | 205 JavaScriptFrameIterator::Advance(); |
| 194 if (done()) return; | 206 if (done()) return; |
| 195 if (IsValidFrame()) return; | 207 if (IsValidFrame()) return; |
| 196 } | 208 } |
| 197 } | 209 } |
| 198 | 210 |
| 199 bool StackTraceFrameIterator::IsValidFrame() { | 211 bool StackTraceFrameIterator::IsValidFrame() { |
| 200 if (!frame()->function()->IsJSFunction()) return false; | 212 if (!frame()->function()->IsJSFunction()) return false; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 214 if (!validator_.IsValid(sp)) return false; | 226 if (!validator_.IsValid(sp)) return false; |
| 215 StackFrame::State state; | 227 StackFrame::State state; |
| 216 ExitFrame::FillState(fp, sp, &state); | 228 ExitFrame::FillState(fp, sp, &state); |
| 217 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { | 229 if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { |
| 218 return false; | 230 return false; |
| 219 } | 231 } |
| 220 return *state.pc_address != NULL; | 232 return *state.pc_address != NULL; |
| 221 } | 233 } |
| 222 | 234 |
| 223 | 235 |
| 236 SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer( | |
| 237 Isolate* isolate) | |
| 238 : isolate_(isolate) { | |
| 239 isolate_->set_safe_stack_iterator_counter( | |
| 240 isolate_->safe_stack_iterator_counter() + 1); | |
| 241 } | |
| 242 | |
| 243 | |
| 244 SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() { | |
| 245 isolate_->set_safe_stack_iterator_counter( | |
| 246 isolate_->safe_stack_iterator_counter() - 1); | |
| 247 } | |
| 248 | |
| 249 | |
| 224 SafeStackFrameIterator::SafeStackFrameIterator( | 250 SafeStackFrameIterator::SafeStackFrameIterator( |
| 225 Isolate* isolate, | 251 Isolate* isolate, |
| 226 Address fp, Address sp, Address low_bound, Address high_bound) : | 252 Address fp, Address sp, Address low_bound, Address high_bound) : |
| 227 maintainer_(), | 253 maintainer_(isolate), |
| 228 stack_validator_(low_bound, high_bound), | 254 stack_validator_(low_bound, high_bound), |
| 229 is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), | 255 is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), |
| 230 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), | 256 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), |
| 231 is_working_iterator_(is_valid_top_ || is_valid_fp_), | 257 is_working_iterator_(is_valid_top_ || is_valid_fp_), |
| 232 iteration_done_(!is_working_iterator_), | 258 iteration_done_(!is_working_iterator_), |
| 233 iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { | 259 iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { |
| 234 } | 260 } |
| 235 | 261 |
| 262 bool SafeStackFrameIterator::is_active(Isolate* isolate) { | |
| 263 return isolate->safe_stack_iterator_counter() > 0; | |
| 264 } | |
| 265 | |
| 236 | 266 |
| 237 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, | 267 bool SafeStackFrameIterator::IsValidTop(Isolate* isolate, |
| 238 Address low_bound, Address high_bound) { | 268 Address low_bound, Address high_bound) { |
| 239 ThreadLocalTop* top = isolate->thread_local_top(); | 269 ThreadLocalTop* top = isolate->thread_local_top(); |
| 240 Address fp = Isolate::c_entry_fp(top); | 270 Address fp = Isolate::c_entry_fp(top); |
| 241 ExitFrameValidator validator(low_bound, high_bound); | 271 ExitFrameValidator validator(low_bound, high_bound); |
| 242 if (!validator.IsValidFP(fp)) return false; | 272 if (!validator.IsValidFP(fp)) return false; |
| 243 return Isolate::handler(top) != NULL; | 273 return Isolate::handler(top) != NULL; |
| 244 } | 274 } |
| 245 | 275 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 void SafeStackTraceFrameIterator::Advance() { | 356 void SafeStackTraceFrameIterator::Advance() { |
| 327 while (true) { | 357 while (true) { |
| 328 SafeJavaScriptFrameIterator::Advance(); | 358 SafeJavaScriptFrameIterator::Advance(); |
| 329 if (done()) return; | 359 if (done()) return; |
| 330 if (frame()->is_java_script()) return; | 360 if (frame()->is_java_script()) return; |
| 331 } | 361 } |
| 332 } | 362 } |
| 333 #endif | 363 #endif |
| 334 | 364 |
| 335 | 365 |
| 336 Code* StackFrame::GetSafepointData(Address pc, | 366 Code* StackFrame::GetSafepointData(Isolate* isolate, |
| 367 Address pc, | |
| 337 SafepointEntry* safepoint_entry, | 368 SafepointEntry* safepoint_entry, |
| 338 unsigned* stack_slots) { | 369 unsigned* stack_slots) { |
| 339 Isolate* isolate = Isolate::Current(); | |
| 340 PcToCodeCache::PcToCodeCacheEntry* entry = | 370 PcToCodeCache::PcToCodeCacheEntry* entry = |
| 341 isolate->pc_to_code_cache()->GetCacheEntry(pc); | 371 isolate->pc_to_code_cache()->GetCacheEntry(pc); |
| 342 SafepointEntry cached_safepoint_entry = entry->safepoint_entry; | 372 SafepointEntry cached_safepoint_entry = entry->safepoint_entry; |
| 343 if (!entry->safepoint_entry.is_valid()) { | 373 if (!entry->safepoint_entry.is_valid()) { |
| 344 entry->safepoint_entry = entry->code->GetSafepointEntry(pc); | 374 entry->safepoint_entry = entry->code->GetSafepointEntry(pc); |
| 345 ASSERT(entry->safepoint_entry.is_valid()); | 375 ASSERT(entry->safepoint_entry.is_valid()); |
| 346 } else { | 376 } else { |
| 347 ASSERT(entry->safepoint_entry.Equals(entry->code->GetSafepointEntry(pc))); | 377 ASSERT(entry->safepoint_entry.Equals(entry->code->GetSafepointEntry(pc))); |
| 348 } | 378 } |
| 349 | 379 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 370 Object* code = holder; | 400 Object* code = holder; |
| 371 v->VisitPointer(&code); | 401 v->VisitPointer(&code); |
| 372 if (code != holder) { | 402 if (code != holder) { |
| 373 holder = reinterpret_cast<Code*>(code); | 403 holder = reinterpret_cast<Code*>(code); |
| 374 pc = holder->instruction_start() + pc_offset; | 404 pc = holder->instruction_start() + pc_offset; |
| 375 *pc_address = pc; | 405 *pc_address = pc; |
| 376 } | 406 } |
| 377 } | 407 } |
| 378 | 408 |
| 379 | 409 |
| 380 StackFrame::Type StackFrame::ComputeType(State* state) { | 410 StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) { |
| 381 ASSERT(state->fp != NULL); | 411 ASSERT(state->fp != NULL); |
| 382 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { | 412 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
| 383 return ARGUMENTS_ADAPTOR; | 413 return ARGUMENTS_ADAPTOR; |
| 384 } | 414 } |
| 385 // The marker and function offsets overlap. If the marker isn't a | 415 // The marker and function offsets overlap. If the marker isn't a |
| 386 // smi then the frame is a JavaScript frame -- and the marker is | 416 // smi then the frame is a JavaScript frame -- and the marker is |
| 387 // really the function. | 417 // really the function. |
| 388 const int offset = StandardFrameConstants::kMarkerOffset; | 418 const int offset = StandardFrameConstants::kMarkerOffset; |
| 389 Object* marker = Memory::Object_at(state->fp + offset); | 419 Object* marker = Memory::Object_at(state->fp + offset); |
| 390 if (!marker->IsSmi()) { | 420 if (!marker->IsSmi()) { |
| 391 // If we're using a "safe" stack iterator, we treat optimized | 421 // If we're using a "safe" stack iterator, we treat optimized |
| 392 // frames as normal JavaScript frames to avoid having to look | 422 // frames as normal JavaScript frames to avoid having to look |
| 393 // into the heap to determine the state. This is safe as long | 423 // into the heap to determine the state. This is safe as long |
| 394 // as nobody tries to GC... | 424 // as nobody tries to GC... |
| 395 if (SafeStackFrameIterator::is_active()) return JAVA_SCRIPT; | 425 if (SafeStackFrameIterator::is_active(isolate)) |
|
Vitaly Repeshko
2011/04/04 20:37:08
nit: Format one a single line if fits, use {} othe
mnaganov (inactive)
2011/04/05 08:28:23
Done.
| |
| 396 Code::Kind kind = GetContainingCode(Isolate::Current(), | 426 return JAVA_SCRIPT; |
| 397 *(state->pc_address))->kind(); | 427 Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind(); |
| 398 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); | 428 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); |
| 399 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; | 429 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; |
| 400 } | 430 } |
| 401 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 431 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
| 402 } | 432 } |
| 403 | 433 |
| 404 | 434 |
| 405 | 435 |
| 406 StackFrame::Type StackFrame::GetCallerState(State* state) const { | 436 StackFrame::Type StackFrame::GetCallerState(State* state) const { |
| 407 ComputeCallerState(state); | 437 ComputeCallerState(state); |
| 408 return ComputeType(state); | 438 return ComputeType(isolate(), state); |
| 409 } | 439 } |
| 410 | 440 |
| 411 | 441 |
| 412 Code* EntryFrame::unchecked_code() const { | 442 Code* EntryFrame::unchecked_code() const { |
| 413 return HEAP->raw_unchecked_js_entry_code(); | 443 return HEAP->raw_unchecked_js_entry_code(); |
| 414 } | 444 } |
| 415 | 445 |
| 416 | 446 |
| 417 void EntryFrame::ComputeCallerState(State* state) const { | 447 void EntryFrame::ComputeCallerState(State* state) const { |
| 418 GetCallerState(state); | 448 GetCallerState(state); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 458 | 488 |
| 459 | 489 |
| 460 void ExitFrame::SetCallerFp(Address caller_fp) { | 490 void ExitFrame::SetCallerFp(Address caller_fp) { |
| 461 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; | 491 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; |
| 462 } | 492 } |
| 463 | 493 |
| 464 | 494 |
| 465 void ExitFrame::Iterate(ObjectVisitor* v) const { | 495 void ExitFrame::Iterate(ObjectVisitor* v) const { |
| 466 // The arguments are traversed as part of the expression stack of | 496 // The arguments are traversed as part of the expression stack of |
| 467 // the calling frame. | 497 // the calling frame. |
| 468 IteratePc(v, pc_address(), LookupCode(Isolate::Current())); | 498 IteratePc(v, pc_address(), LookupCode()); |
| 469 v->VisitPointer(&code_slot()); | 499 v->VisitPointer(&code_slot()); |
| 470 } | 500 } |
| 471 | 501 |
| 472 | 502 |
| 473 Address ExitFrame::GetCallerStackPointer() const { | 503 Address ExitFrame::GetCallerStackPointer() const { |
| 474 return fp() + ExitFrameConstants::kCallerSPDisplacement; | 504 return fp() + ExitFrameConstants::kCallerSPDisplacement; |
| 475 } | 505 } |
| 476 | 506 |
| 477 | 507 |
| 478 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { | 508 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 | 562 |
| 533 void OptimizedFrame::Iterate(ObjectVisitor* v) const { | 563 void OptimizedFrame::Iterate(ObjectVisitor* v) const { |
| 534 #ifdef DEBUG | 564 #ifdef DEBUG |
| 535 // Make sure that optimized frames do not contain any stack handlers. | 565 // Make sure that optimized frames do not contain any stack handlers. |
| 536 StackHandlerIterator it(this, top_handler()); | 566 StackHandlerIterator it(this, top_handler()); |
| 537 ASSERT(it.done()); | 567 ASSERT(it.done()); |
| 538 #endif | 568 #endif |
| 539 | 569 |
| 540 // Make sure that we're not doing "safe" stack frame iteration. We cannot | 570 // Make sure that we're not doing "safe" stack frame iteration. We cannot |
| 541 // possibly find pointers in optimized frames in that state. | 571 // possibly find pointers in optimized frames in that state. |
| 542 ASSERT(!SafeStackFrameIterator::is_active()); | 572 ASSERT(!SafeStackFrameIterator::is_active(isolate())); |
| 543 | 573 |
| 544 // Compute the safepoint information. | 574 // Compute the safepoint information. |
| 545 unsigned stack_slots = 0; | 575 unsigned stack_slots = 0; |
| 546 SafepointEntry safepoint_entry; | 576 SafepointEntry safepoint_entry; |
| 547 Code* code = StackFrame::GetSafepointData( | 577 Code* code = StackFrame::GetSafepointData( |
| 548 pc(), &safepoint_entry, &stack_slots); | 578 isolate(), pc(), &safepoint_entry, &stack_slots); |
| 549 unsigned slot_space = stack_slots * kPointerSize; | 579 unsigned slot_space = stack_slots * kPointerSize; |
| 550 | 580 |
| 551 // Visit the outgoing parameters. This is usually dealt with by the | 581 // Visit the outgoing parameters. This is usually dealt with by the |
| 552 // callee, but while GC'ing we artificially lower the number of | 582 // callee, but while GC'ing we artificially lower the number of |
| 553 // arguments to zero and let the caller deal with it. | 583 // arguments to zero and let the caller deal with it. |
| 554 Object** parameters_base = &Memory::Object_at(sp()); | 584 Object** parameters_base = &Memory::Object_at(sp()); |
| 555 Object** parameters_limit = &Memory::Object_at( | 585 Object** parameters_limit = &Memory::Object_at( |
| 556 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); | 586 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); |
| 557 | 587 |
| 558 // Visit the parameters that may be on top of the saved registers. | 588 // Visit the parameters that may be on top of the saved registers. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 | 663 |
| 634 | 664 |
| 635 Code* JavaScriptFrame::unchecked_code() const { | 665 Code* JavaScriptFrame::unchecked_code() const { |
| 636 JSFunction* function = JSFunction::cast(this->function()); | 666 JSFunction* function = JSFunction::cast(this->function()); |
| 637 return function->unchecked_code(); | 667 return function->unchecked_code(); |
| 638 } | 668 } |
| 639 | 669 |
| 640 | 670 |
| 641 Address JavaScriptFrame::GetCallerStackPointer() const { | 671 Address JavaScriptFrame::GetCallerStackPointer() const { |
| 642 int arguments; | 672 int arguments; |
| 643 if (SafeStackFrameIterator::is_active() || | 673 if (SafeStackFrameIterator::is_active(isolate()) || |
| 644 HEAP->gc_state() != Heap::NOT_IN_GC) { | 674 isolate()->heap()->gc_state() != Heap::NOT_IN_GC) { |
| 645 // If the we are currently iterating the safe stack the | 675 // If the we are currently iterating the safe stack the |
| 646 // arguments for frames are traversed as if they were | 676 // arguments for frames are traversed as if they were |
| 647 // expression stack elements of the calling frame. The reason for | 677 // expression stack elements of the calling frame. The reason for |
| 648 // this rather strange decision is that we cannot access the | 678 // this rather strange decision is that we cannot access the |
| 649 // function during mark-compact GCs when objects may have been marked. | 679 // function during mark-compact GCs when objects may have been marked. |
| 650 // In fact accessing heap objects (like function->shared() below) | 680 // In fact accessing heap objects (like function->shared() below) |
| 651 // at all during GC is problematic. | 681 // at all during GC is problematic. |
| 652 arguments = 0; | 682 arguments = 0; |
| 653 } else { | 683 } else { |
| 654 // Compute the number of arguments by getting the number of formal | 684 // Compute the number of arguments by getting the number of formal |
| 655 // parameters of the function. We must remember to take the | 685 // parameters of the function. We must remember to take the |
| 656 // receiver into account (+1). | 686 // receiver into account (+1). |
| 657 JSFunction* function = JSFunction::cast(this->function()); | 687 JSFunction* function = JSFunction::cast(this->function()); |
| 658 arguments = function->shared()->formal_parameter_count() + 1; | 688 arguments = function->shared()->formal_parameter_count() + 1; |
| 659 } | 689 } |
| 660 const int offset = StandardFrameConstants::kCallerSPOffset; | 690 const int offset = StandardFrameConstants::kCallerSPOffset; |
| 661 return fp() + offset + (arguments * kPointerSize); | 691 return fp() + offset + (arguments * kPointerSize); |
| 662 } | 692 } |
| 663 | 693 |
| 664 | 694 |
| 665 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { | 695 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { |
| 666 ASSERT(functions->length() == 0); | 696 ASSERT(functions->length() == 0); |
| 667 functions->Add(JSFunction::cast(function())); | 697 functions->Add(JSFunction::cast(function())); |
| 668 } | 698 } |
| 669 | 699 |
| 670 | 700 |
| 671 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 701 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
| 672 ASSERT(functions->length() == 0); | 702 ASSERT(functions->length() == 0); |
| 673 Code* code_pointer = LookupCode(Isolate::Current()); | 703 Code* code_pointer = LookupCode(); |
| 674 int offset = static_cast<int>(pc() - code_pointer->address()); | 704 int offset = static_cast<int>(pc() - code_pointer->address()); |
| 675 FrameSummary summary(receiver(), | 705 FrameSummary summary(receiver(), |
| 676 JSFunction::cast(function()), | 706 JSFunction::cast(function()), |
| 677 code_pointer, | 707 code_pointer, |
| 678 offset, | 708 offset, |
| 679 IsConstructor()); | 709 IsConstructor()); |
| 680 functions->Add(summary); | 710 functions->Add(summary); |
| 681 } | 711 } |
| 682 | 712 |
| 683 | 713 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 int* deopt_index) { | 812 int* deopt_index) { |
| 783 ASSERT(is_optimized()); | 813 ASSERT(is_optimized()); |
| 784 | 814 |
| 785 JSFunction* opt_function = JSFunction::cast(function()); | 815 JSFunction* opt_function = JSFunction::cast(function()); |
| 786 Code* code = opt_function->code(); | 816 Code* code = opt_function->code(); |
| 787 | 817 |
| 788 // The code object may have been replaced by lazy deoptimization. Fall | 818 // The code object may have been replaced by lazy deoptimization. Fall |
| 789 // back to a slow search in this case to find the original optimized | 819 // back to a slow search in this case to find the original optimized |
| 790 // code object. | 820 // code object. |
| 791 if (!code->contains(pc())) { | 821 if (!code->contains(pc())) { |
| 792 code = Isolate::Current()->pc_to_code_cache()->GcSafeFindCodeForPc(pc()); | 822 code = isolate()->pc_to_code_cache()->GcSafeFindCodeForPc(pc()); |
| 793 } | 823 } |
| 794 ASSERT(code != NULL); | 824 ASSERT(code != NULL); |
| 795 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); | 825 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); |
| 796 | 826 |
| 797 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); | 827 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); |
| 798 *deopt_index = safepoint_entry.deoptimization_index(); | 828 *deopt_index = safepoint_entry.deoptimization_index(); |
| 799 ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); | 829 ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); |
| 800 | 830 |
| 801 return DeoptimizationInputData::cast(code->deoptimization_data()); | 831 return DeoptimizationInputData::cast(code->deoptimization_data()); |
| 802 } | 832 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 | 873 |
| 844 | 874 |
| 845 Address InternalFrame::GetCallerStackPointer() const { | 875 Address InternalFrame::GetCallerStackPointer() const { |
| 846 // Internal frames have no arguments. The stack pointer of the | 876 // Internal frames have no arguments. The stack pointer of the |
| 847 // caller is at a fixed offset from the frame pointer. | 877 // caller is at a fixed offset from the frame pointer. |
| 848 return fp() + StandardFrameConstants::kCallerSPOffset; | 878 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 849 } | 879 } |
| 850 | 880 |
| 851 | 881 |
| 852 Code* ArgumentsAdaptorFrame::unchecked_code() const { | 882 Code* ArgumentsAdaptorFrame::unchecked_code() const { |
| 853 return Isolate::Current()->builtins()->builtin( | 883 return isolate()->builtins()->builtin( |
| 854 Builtins::kArgumentsAdaptorTrampoline); | 884 Builtins::kArgumentsAdaptorTrampoline); |
| 855 } | 885 } |
| 856 | 886 |
| 857 | 887 |
| 858 Code* InternalFrame::unchecked_code() const { | 888 Code* InternalFrame::unchecked_code() const { |
| 859 const int offset = InternalFrameConstants::kCodeOffset; | 889 const int offset = InternalFrameConstants::kCodeOffset; |
| 860 Object* code = Memory::Object_at(fp() + offset); | 890 Object* code = Memory::Object_at(fp() + offset); |
| 861 ASSERT(code != NULL); | 891 ASSERT(code != NULL); |
| 862 return reinterpret_cast<Code*>(code); | 892 return reinterpret_cast<Code*>(code); |
| 863 } | 893 } |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1038 | 1068 |
| 1039 accumulator->Add("}\n\n"); | 1069 accumulator->Add("}\n\n"); |
| 1040 } | 1070 } |
| 1041 | 1071 |
| 1042 | 1072 |
| 1043 void EntryFrame::Iterate(ObjectVisitor* v) const { | 1073 void EntryFrame::Iterate(ObjectVisitor* v) const { |
| 1044 StackHandlerIterator it(this, top_handler()); | 1074 StackHandlerIterator it(this, top_handler()); |
| 1045 ASSERT(!it.done()); | 1075 ASSERT(!it.done()); |
| 1046 StackHandler* handler = it.handler(); | 1076 StackHandler* handler = it.handler(); |
| 1047 ASSERT(handler->is_entry()); | 1077 ASSERT(handler->is_entry()); |
| 1048 handler->Iterate(v, LookupCode(Isolate::Current())); | 1078 handler->Iterate(v, LookupCode()); |
| 1049 #ifdef DEBUG | 1079 #ifdef DEBUG |
| 1050 // Make sure that the entry frame does not contain more than one | 1080 // Make sure that the entry frame does not contain more than one |
| 1051 // stack handler. | 1081 // stack handler. |
| 1052 it.Advance(); | 1082 it.Advance(); |
| 1053 ASSERT(it.done()); | 1083 ASSERT(it.done()); |
| 1054 #endif | 1084 #endif |
| 1055 IteratePc(v, pc_address(), LookupCode(Isolate::Current())); | 1085 IteratePc(v, pc_address(), LookupCode()); |
| 1056 } | 1086 } |
| 1057 | 1087 |
| 1058 | 1088 |
| 1059 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { | 1089 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { |
| 1060 const int offset = StandardFrameConstants::kContextOffset; | 1090 const int offset = StandardFrameConstants::kContextOffset; |
| 1061 Object** base = &Memory::Object_at(sp()); | 1091 Object** base = &Memory::Object_at(sp()); |
| 1062 Object** limit = &Memory::Object_at(fp() + offset) + 1; | 1092 Object** limit = &Memory::Object_at(fp() + offset) + 1; |
| 1063 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { | 1093 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { |
| 1064 StackHandler* handler = it.handler(); | 1094 StackHandler* handler = it.handler(); |
| 1065 // Traverse pointers down to - but not including - the next | 1095 // Traverse pointers down to - but not including - the next |
| 1066 // handler in the handler chain. Update the base to skip the | 1096 // handler in the handler chain. Update the base to skip the |
| 1067 // handler and allow the handler to traverse its own pointers. | 1097 // handler and allow the handler to traverse its own pointers. |
| 1068 const Address address = handler->address(); | 1098 const Address address = handler->address(); |
| 1069 v->VisitPointers(base, reinterpret_cast<Object**>(address)); | 1099 v->VisitPointers(base, reinterpret_cast<Object**>(address)); |
| 1070 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize); | 1100 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize); |
| 1071 // Traverse the pointers in the handler itself. | 1101 // Traverse the pointers in the handler itself. |
| 1072 handler->Iterate(v, LookupCode(Isolate::Current())); | 1102 handler->Iterate(v, LookupCode()); |
| 1073 } | 1103 } |
| 1074 v->VisitPointers(base, limit); | 1104 v->VisitPointers(base, limit); |
| 1075 } | 1105 } |
| 1076 | 1106 |
| 1077 | 1107 |
| 1078 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { | 1108 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { |
| 1079 IterateExpressions(v); | 1109 IterateExpressions(v); |
| 1080 IteratePc(v, pc_address(), LookupCode(Isolate::Current())); | 1110 IteratePc(v, pc_address(), LookupCode()); |
| 1081 IterateArguments(v); | 1111 IterateArguments(v); |
| 1082 } | 1112 } |
| 1083 | 1113 |
| 1084 | 1114 |
| 1085 void JavaScriptFrame::IterateArguments(ObjectVisitor* v) const { | 1115 void JavaScriptFrame::IterateArguments(ObjectVisitor* v) const { |
| 1086 // Traverse callee-saved registers, receiver, and parameters. | 1116 // Traverse callee-saved registers, receiver, and parameters. |
| 1087 const int kBaseOffset = JavaScriptFrameConstants::kLastParameterOffset; | 1117 const int kBaseOffset = JavaScriptFrameConstants::kLastParameterOffset; |
| 1088 const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset; | 1118 const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset; |
| 1089 Object** base = &Memory::Object_at(fp() + kBaseOffset); | 1119 Object** base = &Memory::Object_at(fp() + kBaseOffset); |
| 1090 Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1; | 1120 Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1; |
| 1091 v->VisitPointers(base, limit); | 1121 v->VisitPointers(base, limit); |
| 1092 } | 1122 } |
| 1093 | 1123 |
| 1094 | 1124 |
| 1095 void InternalFrame::Iterate(ObjectVisitor* v) const { | 1125 void InternalFrame::Iterate(ObjectVisitor* v) const { |
| 1096 // Internal frames only have object pointers on the expression stack | 1126 // Internal frames only have object pointers on the expression stack |
| 1097 // as they never have any arguments. | 1127 // as they never have any arguments. |
| 1098 IterateExpressions(v); | 1128 IterateExpressions(v); |
| 1099 IteratePc(v, pc_address(), LookupCode(Isolate::Current())); | 1129 IteratePc(v, pc_address(), LookupCode()); |
| 1100 } | 1130 } |
| 1101 | 1131 |
| 1102 | 1132 |
| 1103 // ------------------------------------------------------------------------- | 1133 // ------------------------------------------------------------------------- |
| 1104 | 1134 |
| 1105 | 1135 |
| 1106 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { | 1136 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { |
| 1107 ASSERT(n >= 0); | 1137 ASSERT(n >= 0); |
| 1108 for (int i = 0; i <= n; i++) { | 1138 for (int i = 0; i <= n; i++) { |
| 1109 while (!iterator_.frame()->is_java_script()) iterator_.Advance(); | 1139 while (!iterator_.frame()->is_java_script()) iterator_.Advance(); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1233 ZoneList<StackFrame*> list(10); | 1263 ZoneList<StackFrame*> list(10); |
| 1234 for (StackFrameIterator it; !it.done(); it.Advance()) { | 1264 for (StackFrameIterator it; !it.done(); it.Advance()) { |
| 1235 StackFrame* frame = AllocateFrameCopy(it.frame()); | 1265 StackFrame* frame = AllocateFrameCopy(it.frame()); |
| 1236 list.Add(frame); | 1266 list.Add(frame); |
| 1237 } | 1267 } |
| 1238 return list.ToVector(); | 1268 return list.ToVector(); |
| 1239 } | 1269 } |
| 1240 | 1270 |
| 1241 | 1271 |
| 1242 } } // namespace v8::internal | 1272 } } // namespace v8::internal |
| OLD | NEW |