OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/frames.h" | 5 #include "src/frames.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 SingletonFor(frame->GetCallerState(&state)) != NULL; | 314 SingletonFor(frame->GetCallerState(&state)) != NULL; |
315 } | 315 } |
316 | 316 |
317 | 317 |
318 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const { | 318 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const { |
319 if (!IsValidStackAddress(fp)) return false; | 319 if (!IsValidStackAddress(fp)) return false; |
320 Address sp = ExitFrame::ComputeStackPointer(fp); | 320 Address sp = ExitFrame::ComputeStackPointer(fp); |
321 if (!IsValidStackAddress(sp)) return false; | 321 if (!IsValidStackAddress(sp)) return false; |
322 StackFrame::State state; | 322 StackFrame::State state; |
323 ExitFrame::FillState(fp, sp, &state); | 323 ExitFrame::FillState(fp, sp, &state); |
| 324 if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) { |
| 325 return false; |
| 326 } |
324 return *state.pc_address != NULL; | 327 return *state.pc_address != NULL; |
325 } | 328 } |
326 | 329 |
327 | 330 |
328 void SafeStackFrameIterator::Advance() { | 331 void SafeStackFrameIterator::Advance() { |
329 while (true) { | 332 while (true) { |
330 AdvanceOneFrame(); | 333 AdvanceOneFrame(); |
331 if (done()) return; | 334 if (done()) return; |
332 if (frame_->is_java_script()) return; | 335 if (frame_->is_java_script()) return; |
333 if (frame_->is_exit() && external_callback_scope_) { | 336 if (frame_->is_exit() && external_callback_scope_) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 *stack_slots = code->stack_slots(); | 378 *stack_slots = code->stack_slots(); |
376 return code; | 379 return code; |
377 } | 380 } |
378 | 381 |
379 | 382 |
380 #ifdef DEBUG | 383 #ifdef DEBUG |
381 static bool GcSafeCodeContains(HeapObject* object, Address addr); | 384 static bool GcSafeCodeContains(HeapObject* object, Address addr); |
382 #endif | 385 #endif |
383 | 386 |
384 | 387 |
385 void StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address, | 388 void StackFrame::IteratePc(ObjectVisitor* v, |
386 Address* constant_pool_address, Code* holder) { | 389 Address* pc_address, |
| 390 Code* holder) { |
387 Address pc = *pc_address; | 391 Address pc = *pc_address; |
388 DCHECK(GcSafeCodeContains(holder, pc)); | 392 DCHECK(GcSafeCodeContains(holder, pc)); |
389 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); | 393 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); |
390 Object* code = holder; | 394 Object* code = holder; |
391 v->VisitPointer(&code); | 395 v->VisitPointer(&code); |
392 if (code != holder) { | 396 if (code != holder) { |
393 holder = reinterpret_cast<Code*>(code); | 397 holder = reinterpret_cast<Code*>(code); |
394 pc = holder->instruction_start() + pc_offset; | 398 pc = holder->instruction_start() + pc_offset; |
395 *pc_address = pc; | 399 *pc_address = pc; |
396 if (FLAG_enable_embedded_constant_pool && constant_pool_address) { | |
397 *constant_pool_address = holder->constant_pool(); | |
398 } | |
399 } | 400 } |
400 } | 401 } |
401 | 402 |
402 | 403 |
403 void StackFrame::SetReturnAddressLocationResolver( | 404 void StackFrame::SetReturnAddressLocationResolver( |
404 ReturnAddressLocationResolver resolver) { | 405 ReturnAddressLocationResolver resolver) { |
405 DCHECK(return_address_location_resolver_ == NULL); | 406 DCHECK(return_address_location_resolver_ == NULL); |
406 return_address_location_resolver_ = resolver; | 407 return_address_location_resolver_ = resolver; |
407 } | 408 } |
408 | 409 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 return reinterpret_cast<Code*>(code_slot()); | 499 return reinterpret_cast<Code*>(code_slot()); |
499 } | 500 } |
500 | 501 |
501 | 502 |
502 void ExitFrame::ComputeCallerState(State* state) const { | 503 void ExitFrame::ComputeCallerState(State* state) const { |
503 // Set up the caller state. | 504 // Set up the caller state. |
504 state->sp = caller_sp(); | 505 state->sp = caller_sp(); |
505 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); | 506 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); |
506 state->pc_address = ResolveReturnAddressLocation( | 507 state->pc_address = ResolveReturnAddressLocation( |
507 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); | 508 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); |
508 if (FLAG_enable_embedded_constant_pool) { | 509 if (FLAG_enable_ool_constant_pool) { |
509 state->constant_pool_address = reinterpret_cast<Address*>( | 510 state->constant_pool_address = reinterpret_cast<Address*>( |
510 fp() + ExitFrameConstants::kConstantPoolOffset); | 511 fp() + ExitFrameConstants::kConstantPoolOffset); |
511 } | 512 } |
512 } | 513 } |
513 | 514 |
514 | 515 |
515 void ExitFrame::SetCallerFp(Address caller_fp) { | 516 void ExitFrame::SetCallerFp(Address caller_fp) { |
516 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; | 517 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; |
517 } | 518 } |
518 | 519 |
519 | 520 |
520 void ExitFrame::Iterate(ObjectVisitor* v) const { | 521 void ExitFrame::Iterate(ObjectVisitor* v) const { |
521 // The arguments are traversed as part of the expression stack of | 522 // The arguments are traversed as part of the expression stack of |
522 // the calling frame. | 523 // the calling frame. |
523 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); | 524 IteratePc(v, pc_address(), LookupCode()); |
524 v->VisitPointer(&code_slot()); | 525 v->VisitPointer(&code_slot()); |
| 526 if (FLAG_enable_ool_constant_pool) { |
| 527 v->VisitPointer(&constant_pool_slot()); |
| 528 } |
525 } | 529 } |
526 | 530 |
527 | 531 |
528 Address ExitFrame::GetCallerStackPointer() const { | 532 Address ExitFrame::GetCallerStackPointer() const { |
529 return fp() + ExitFrameConstants::kCallerSPDisplacement; | 533 return fp() + ExitFrameConstants::kCallerSPDisplacement; |
530 } | 534 } |
531 | 535 |
532 | 536 |
533 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { | 537 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
534 if (fp == 0) return NONE; | 538 if (fp == 0) return NONE; |
535 Address sp = ComputeStackPointer(fp); | 539 Address sp = ComputeStackPointer(fp); |
536 FillState(fp, sp, state); | 540 FillState(fp, sp, state); |
537 DCHECK(*state->pc_address != NULL); | 541 DCHECK(*state->pc_address != NULL); |
538 return EXIT; | 542 return EXIT; |
539 } | 543 } |
540 | 544 |
541 | 545 |
542 Address ExitFrame::ComputeStackPointer(Address fp) { | 546 Address ExitFrame::ComputeStackPointer(Address fp) { |
543 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); | 547 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); |
544 } | 548 } |
545 | 549 |
546 | 550 |
547 void ExitFrame::FillState(Address fp, Address sp, State* state) { | 551 void ExitFrame::FillState(Address fp, Address sp, State* state) { |
548 state->sp = sp; | 552 state->sp = sp; |
549 state->fp = fp; | 553 state->fp = fp; |
550 state->pc_address = ResolveReturnAddressLocation( | 554 state->pc_address = ResolveReturnAddressLocation( |
551 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); | 555 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); |
552 // The constant pool recorded in the exit frame is not associated | 556 state->constant_pool_address = |
553 // with the pc in this state (the return address into a C entry | 557 reinterpret_cast<Address*>(fp + ExitFrameConstants::kConstantPoolOffset); |
554 // stub). ComputeCallerState will retrieve the constant pool | |
555 // together with the associated caller pc. | |
556 state->constant_pool_address = NULL; | |
557 } | 558 } |
558 | 559 |
559 | 560 |
560 Address StandardFrame::GetExpressionAddress(int n) const { | 561 Address StandardFrame::GetExpressionAddress(int n) const { |
561 const int offset = StandardFrameConstants::kExpressionsOffset; | 562 const int offset = StandardFrameConstants::kExpressionsOffset; |
562 return fp() + offset - n * kPointerSize; | 563 return fp() + offset - n * kPointerSize; |
563 } | 564 } |
564 | 565 |
565 | 566 |
566 Object* StandardFrame::GetExpression(Address fp, int index) { | 567 Object* StandardFrame::GetExpression(Address fp, int index) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 // Visit pointer spill slots and locals. | 656 // Visit pointer spill slots and locals. |
656 for (unsigned index = 0; index < stack_slots; index++) { | 657 for (unsigned index = 0; index < stack_slots; index++) { |
657 int byte_index = index >> kBitsPerByteLog2; | 658 int byte_index = index >> kBitsPerByteLog2; |
658 int bit_index = index & (kBitsPerByte - 1); | 659 int bit_index = index & (kBitsPerByte - 1); |
659 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { | 660 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { |
660 v->VisitPointer(parameters_limit + index); | 661 v->VisitPointer(parameters_limit + index); |
661 } | 662 } |
662 } | 663 } |
663 | 664 |
664 // Visit the return address in the callee and incoming arguments. | 665 // Visit the return address in the callee and incoming arguments. |
665 IteratePc(v, pc_address(), constant_pool_address(), code); | 666 IteratePc(v, pc_address(), code); |
666 | 667 |
667 // Visit the context in stub frame and JavaScript frame. | 668 // Visit the context in stub frame and JavaScript frame. |
668 // Visit the function in JavaScript frame. | 669 // Visit the function in JavaScript frame. |
669 Object** fixed_base = &Memory::Object_at( | 670 Object** fixed_base = &Memory::Object_at( |
670 fp() + StandardFrameConstants::kMarkerOffset); | 671 fp() + StandardFrameConstants::kMarkerOffset); |
671 Object** fixed_limit = &Memory::Object_at(fp()); | 672 Object** fixed_limit = &Memory::Object_at(fp()); |
672 v->VisitPointers(fixed_base, fixed_limit); | 673 v->VisitPointers(fixed_base, fixed_limit); |
673 } | 674 } |
674 | 675 |
675 | 676 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 accumulator->Add(" // not passed to callee"); | 1283 accumulator->Add(" // not passed to callee"); |
1283 } | 1284 } |
1284 accumulator->Add("\n"); | 1285 accumulator->Add("\n"); |
1285 } | 1286 } |
1286 | 1287 |
1287 accumulator->Add("}\n\n"); | 1288 accumulator->Add("}\n\n"); |
1288 } | 1289 } |
1289 | 1290 |
1290 | 1291 |
1291 void EntryFrame::Iterate(ObjectVisitor* v) const { | 1292 void EntryFrame::Iterate(ObjectVisitor* v) const { |
1292 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); | 1293 IteratePc(v, pc_address(), LookupCode()); |
1293 } | 1294 } |
1294 | 1295 |
1295 | 1296 |
1296 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { | 1297 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { |
1297 const int offset = StandardFrameConstants::kLastObjectOffset; | 1298 const int offset = StandardFrameConstants::kLastObjectOffset; |
1298 Object** base = &Memory::Object_at(sp()); | 1299 Object** base = &Memory::Object_at(sp()); |
1299 Object** limit = &Memory::Object_at(fp() + offset) + 1; | 1300 Object** limit = &Memory::Object_at(fp() + offset) + 1; |
1300 v->VisitPointers(base, limit); | 1301 v->VisitPointers(base, limit); |
1301 } | 1302 } |
1302 | 1303 |
1303 | 1304 |
1304 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { | 1305 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { |
1305 IterateExpressions(v); | 1306 IterateExpressions(v); |
1306 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); | 1307 IteratePc(v, pc_address(), LookupCode()); |
1307 } | 1308 } |
1308 | 1309 |
1309 | 1310 |
1310 void InternalFrame::Iterate(ObjectVisitor* v) const { | 1311 void InternalFrame::Iterate(ObjectVisitor* v) const { |
1311 // Internal frames only have object pointers on the expression stack | 1312 // Internal frames only have object pointers on the expression stack |
1312 // as they never have any arguments. | 1313 // as they never have any arguments. |
1313 IterateExpressions(v); | 1314 IterateExpressions(v); |
1314 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); | 1315 IteratePc(v, pc_address(), LookupCode()); |
1315 } | 1316 } |
1316 | 1317 |
1317 | 1318 |
1318 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { | 1319 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { |
1319 Object** base = &Memory::Object_at(sp()); | 1320 Object** base = &Memory::Object_at(sp()); |
1320 Object** limit = &Memory::Object_at(fp() + | 1321 Object** limit = &Memory::Object_at(fp() + |
1321 kFirstRegisterParameterFrameOffset); | 1322 kFirstRegisterParameterFrameOffset); |
1322 v->VisitPointers(base, limit); | 1323 v->VisitPointers(base, limit); |
1323 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); | 1324 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); |
1324 const int offset = StandardFrameConstants::kLastObjectOffset; | 1325 const int offset = StandardFrameConstants::kLastObjectOffset; |
1325 limit = &Memory::Object_at(fp() + offset) + 1; | 1326 limit = &Memory::Object_at(fp() + offset) + 1; |
1326 v->VisitPointers(base, limit); | 1327 v->VisitPointers(base, limit); |
1327 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); | 1328 IteratePc(v, pc_address(), LookupCode()); |
1328 } | 1329 } |
1329 | 1330 |
1330 | 1331 |
1331 Address StubFailureTrampolineFrame::GetCallerStackPointer() const { | 1332 Address StubFailureTrampolineFrame::GetCallerStackPointer() const { |
1332 return fp() + StandardFrameConstants::kCallerSPOffset; | 1333 return fp() + StandardFrameConstants::kCallerSPOffset; |
1333 } | 1334 } |
1334 | 1335 |
1335 | 1336 |
1336 Code* StubFailureTrampolineFrame::unchecked_code() const { | 1337 Code* StubFailureTrampolineFrame::unchecked_code() const { |
1337 Code* trampoline; | 1338 Code* trampoline; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1520 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1520 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1521 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1521 list.Add(frame, zone); | 1522 list.Add(frame, zone); |
1522 } | 1523 } |
1523 return list.ToVector(); | 1524 return list.ToVector(); |
1524 } | 1525 } |
1525 | 1526 |
1526 | 1527 |
1527 } // namespace internal | 1528 } // namespace internal |
1528 } // namespace v8 | 1529 } // namespace v8 |
OLD | NEW |