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 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 // possibly find pointers in optimized frames in that state. | 572 // possibly find pointers in optimized frames in that state. |
573 ASSERT(!SafeStackFrameIterator::is_active(isolate())); | 573 ASSERT(!SafeStackFrameIterator::is_active(isolate())); |
574 | 574 |
575 // Compute the safepoint information. | 575 // Compute the safepoint information. |
576 unsigned stack_slots = 0; | 576 unsigned stack_slots = 0; |
577 SafepointEntry safepoint_entry; | 577 SafepointEntry safepoint_entry; |
578 Code* code = StackFrame::GetSafepointData( | 578 Code* code = StackFrame::GetSafepointData( |
579 isolate(), pc(), &safepoint_entry, &stack_slots); | 579 isolate(), pc(), &safepoint_entry, &stack_slots); |
580 unsigned slot_space = stack_slots * kPointerSize; | 580 unsigned slot_space = stack_slots * kPointerSize; |
581 | 581 |
582 // Visit the outgoing parameters. | 582 // Visit the outgoing parameters. This is usually dealt with by the |
| 583 // callee, but while GC'ing we artificially lower the number of |
| 584 // arguments to zero and let the caller deal with it. |
583 Object** parameters_base = &Memory::Object_at(sp()); | 585 Object** parameters_base = &Memory::Object_at(sp()); |
584 Object** parameters_limit = &Memory::Object_at( | 586 Object** parameters_limit = &Memory::Object_at( |
585 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); | 587 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); |
586 | 588 |
587 // Visit the parameters that may be on top of the saved registers. | 589 // Visit the parameters that may be on top of the saved registers. |
588 if (safepoint_entry.argument_count() > 0) { | 590 if (safepoint_entry.argument_count() > 0) { |
589 v->VisitPointers(parameters_base, | 591 v->VisitPointers(parameters_base, |
590 parameters_base + safepoint_entry.argument_count()); | 592 parameters_base + safepoint_entry.argument_count()); |
591 parameters_base += safepoint_entry.argument_count(); | 593 parameters_base += safepoint_entry.argument_count(); |
592 } | 594 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 } | 628 } |
627 | 629 |
628 // Visit the context and the function. | 630 // Visit the context and the function. |
629 Object** fixed_base = &Memory::Object_at( | 631 Object** fixed_base = &Memory::Object_at( |
630 fp() + JavaScriptFrameConstants::kFunctionOffset); | 632 fp() + JavaScriptFrameConstants::kFunctionOffset); |
631 Object** fixed_limit = &Memory::Object_at(fp()); | 633 Object** fixed_limit = &Memory::Object_at(fp()); |
632 v->VisitPointers(fixed_base, fixed_limit); | 634 v->VisitPointers(fixed_base, fixed_limit); |
633 | 635 |
634 // Visit the return address in the callee and incoming arguments. | 636 // Visit the return address in the callee and incoming arguments. |
635 IteratePc(v, pc_address(), code); | 637 IteratePc(v, pc_address(), code); |
| 638 IterateArguments(v); |
| 639 } |
| 640 |
| 641 |
| 642 Object* JavaScriptFrame::GetParameter(int index) const { |
| 643 ASSERT(index >= 0 && index < ComputeParametersCount()); |
| 644 const int offset = JavaScriptFrameConstants::kParam0Offset; |
| 645 return Memory::Object_at(caller_sp() + offset - (index * kPointerSize)); |
| 646 } |
| 647 |
| 648 |
| 649 int JavaScriptFrame::ComputeParametersCount() const { |
| 650 Address base = caller_sp() + JavaScriptFrameConstants::kReceiverOffset; |
| 651 Address limit = fp() + JavaScriptFrameConstants::kLastParameterOffset; |
| 652 return static_cast<int>((base - limit) / kPointerSize); |
636 } | 653 } |
637 | 654 |
638 | 655 |
639 bool JavaScriptFrame::IsConstructor() const { | 656 bool JavaScriptFrame::IsConstructor() const { |
640 Address fp = caller_fp(); | 657 Address fp = caller_fp(); |
641 if (has_adapted_arguments()) { | 658 if (has_adapted_arguments()) { |
642 // Skip the arguments adaptor frame and look at the real caller. | 659 // Skip the arguments adaptor frame and look at the real caller. |
643 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 660 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
644 } | 661 } |
645 return IsConstructFrame(fp); | 662 return IsConstructFrame(fp); |
646 } | 663 } |
647 | 664 |
648 | 665 |
649 Code* JavaScriptFrame::unchecked_code() const { | 666 Code* JavaScriptFrame::unchecked_code() const { |
650 JSFunction* function = JSFunction::cast(this->function()); | 667 JSFunction* function = JSFunction::cast(this->function()); |
651 return function->unchecked_code(); | 668 return function->unchecked_code(); |
652 } | 669 } |
653 | 670 |
654 | 671 |
655 int JavaScriptFrame::GetNumberOfIncomingArguments() const { | |
656 ASSERT(!SafeStackFrameIterator::is_active(isolate()) && | |
657 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); | |
658 | |
659 JSFunction* function = JSFunction::cast(this->function()); | |
660 return function->shared()->formal_parameter_count(); | |
661 } | |
662 | |
663 | |
664 Address JavaScriptFrame::GetCallerStackPointer() const { | 672 Address JavaScriptFrame::GetCallerStackPointer() const { |
665 return fp() + StandardFrameConstants::kCallerSPOffset; | 673 int arguments; |
| 674 if (SafeStackFrameIterator::is_active(isolate()) || |
| 675 isolate()->heap()->gc_state() != Heap::NOT_IN_GC) { |
| 676 // If the we are currently iterating the safe stack the |
| 677 // arguments for frames are traversed as if they were |
| 678 // expression stack elements of the calling frame. The reason for |
| 679 // this rather strange decision is that we cannot access the |
| 680 // function during mark-compact GCs when objects may have been marked. |
| 681 // In fact accessing heap objects (like function->shared() below) |
| 682 // at all during GC is problematic. |
| 683 arguments = 0; |
| 684 } else { |
| 685 // Compute the number of arguments by getting the number of formal |
| 686 // parameters of the function. We must remember to take the |
| 687 // receiver into account (+1). |
| 688 JSFunction* function = JSFunction::cast(this->function()); |
| 689 arguments = function->shared()->formal_parameter_count() + 1; |
| 690 } |
| 691 const int offset = StandardFrameConstants::kCallerSPOffset; |
| 692 return fp() + offset + (arguments * kPointerSize); |
666 } | 693 } |
667 | 694 |
668 | 695 |
669 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { | 696 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { |
670 ASSERT(functions->length() == 0); | 697 ASSERT(functions->length() == 0); |
671 functions->Add(JSFunction::cast(function())); | 698 functions->Add(JSFunction::cast(function())); |
672 } | 699 } |
673 | 700 |
674 | 701 |
675 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 702 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 functions->Add(function); | 860 functions->Add(function); |
834 } else { | 861 } else { |
835 // Skip over operands to advance to the next opcode. | 862 // Skip over operands to advance to the next opcode. |
836 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 863 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
837 } | 864 } |
838 } | 865 } |
839 } | 866 } |
840 | 867 |
841 | 868 |
842 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { | 869 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { |
843 return fp() + StandardFrameConstants::kCallerSPOffset; | 870 const int arguments = Smi::cast(GetExpression(0))->value(); |
| 871 const int offset = StandardFrameConstants::kCallerSPOffset; |
| 872 return fp() + offset + (arguments + 1) * kPointerSize; |
844 } | 873 } |
845 | 874 |
846 | 875 |
847 Address InternalFrame::GetCallerStackPointer() const { | 876 Address InternalFrame::GetCallerStackPointer() const { |
848 // Internal frames have no arguments. The stack pointer of the | 877 // Internal frames have no arguments. The stack pointer of the |
849 // caller is at a fixed offset from the frame pointer. | 878 // caller is at a fixed offset from the frame pointer. |
850 return fp() + StandardFrameConstants::kCallerSPOffset; | 879 return fp() + StandardFrameConstants::kCallerSPOffset; |
851 } | 880 } |
852 | 881 |
853 | 882 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 // Traverse the pointers in the handler itself. | 1102 // Traverse the pointers in the handler itself. |
1074 handler->Iterate(v, LookupCode()); | 1103 handler->Iterate(v, LookupCode()); |
1075 } | 1104 } |
1076 v->VisitPointers(base, limit); | 1105 v->VisitPointers(base, limit); |
1077 } | 1106 } |
1078 | 1107 |
1079 | 1108 |
1080 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { | 1109 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { |
1081 IterateExpressions(v); | 1110 IterateExpressions(v); |
1082 IteratePc(v, pc_address(), LookupCode()); | 1111 IteratePc(v, pc_address(), LookupCode()); |
| 1112 IterateArguments(v); |
| 1113 } |
| 1114 |
| 1115 |
| 1116 void JavaScriptFrame::IterateArguments(ObjectVisitor* v) const { |
| 1117 // Traverse callee-saved registers, receiver, and parameters. |
| 1118 const int kBaseOffset = JavaScriptFrameConstants::kLastParameterOffset; |
| 1119 const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset; |
| 1120 Object** base = &Memory::Object_at(fp() + kBaseOffset); |
| 1121 Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1; |
| 1122 v->VisitPointers(base, limit); |
1083 } | 1123 } |
1084 | 1124 |
1085 | 1125 |
1086 void InternalFrame::Iterate(ObjectVisitor* v) const { | 1126 void InternalFrame::Iterate(ObjectVisitor* v) const { |
1087 // Internal frames only have object pointers on the expression stack | 1127 // Internal frames only have object pointers on the expression stack |
1088 // as they never have any arguments. | 1128 // as they never have any arguments. |
1089 IterateExpressions(v); | 1129 IterateExpressions(v); |
1090 IteratePc(v, pc_address(), LookupCode()); | 1130 IteratePc(v, pc_address(), LookupCode()); |
1091 } | 1131 } |
1092 | 1132 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 ZoneList<StackFrame*> list(10); | 1264 ZoneList<StackFrame*> list(10); |
1225 for (StackFrameIterator it; !it.done(); it.Advance()) { | 1265 for (StackFrameIterator it; !it.done(); it.Advance()) { |
1226 StackFrame* frame = AllocateFrameCopy(it.frame()); | 1266 StackFrame* frame = AllocateFrameCopy(it.frame()); |
1227 list.Add(frame); | 1267 list.Add(frame); |
1228 } | 1268 } |
1229 return list.ToVector(); | 1269 return list.ToVector(); |
1230 } | 1270 } |
1231 | 1271 |
1232 | 1272 |
1233 } } // namespace v8::internal | 1273 } } // namespace v8::internal |
OLD | NEW |