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. This is usually dealt with by the | 582 // Visit the outgoing parameters. |
583 // callee, but while GC'ing we artificially lower the number of | |
584 // arguments to zero and let the caller deal with it. | |
585 Object** parameters_base = &Memory::Object_at(sp()); | 583 Object** parameters_base = &Memory::Object_at(sp()); |
586 Object** parameters_limit = &Memory::Object_at( | 584 Object** parameters_limit = &Memory::Object_at( |
587 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); | 585 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); |
588 | 586 |
589 // Visit the parameters that may be on top of the saved registers. | 587 // Visit the parameters that may be on top of the saved registers. |
590 if (safepoint_entry.argument_count() > 0) { | 588 if (safepoint_entry.argument_count() > 0) { |
591 v->VisitPointers(parameters_base, | 589 v->VisitPointers(parameters_base, |
592 parameters_base + safepoint_entry.argument_count()); | 590 parameters_base + safepoint_entry.argument_count()); |
593 parameters_base += safepoint_entry.argument_count(); | 591 parameters_base += safepoint_entry.argument_count(); |
594 } | 592 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 } | 626 } |
629 | 627 |
630 // Visit the context and the function. | 628 // Visit the context and the function. |
631 Object** fixed_base = &Memory::Object_at( | 629 Object** fixed_base = &Memory::Object_at( |
632 fp() + JavaScriptFrameConstants::kFunctionOffset); | 630 fp() + JavaScriptFrameConstants::kFunctionOffset); |
633 Object** fixed_limit = &Memory::Object_at(fp()); | 631 Object** fixed_limit = &Memory::Object_at(fp()); |
634 v->VisitPointers(fixed_base, fixed_limit); | 632 v->VisitPointers(fixed_base, fixed_limit); |
635 | 633 |
636 // Visit the return address in the callee and incoming arguments. | 634 // Visit the return address in the callee and incoming arguments. |
637 IteratePc(v, pc_address(), code); | 635 IteratePc(v, pc_address(), code); |
638 IterateArguments(v); | |
639 } | 636 } |
640 | 637 |
641 | 638 |
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); | |
653 } | |
654 | |
655 | |
656 bool JavaScriptFrame::IsConstructor() const { | 639 bool JavaScriptFrame::IsConstructor() const { |
657 Address fp = caller_fp(); | 640 Address fp = caller_fp(); |
658 if (has_adapted_arguments()) { | 641 if (has_adapted_arguments()) { |
659 // Skip the arguments adaptor frame and look at the real caller. | 642 // Skip the arguments adaptor frame and look at the real caller. |
660 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 643 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
661 } | 644 } |
662 return IsConstructFrame(fp); | 645 return IsConstructFrame(fp); |
663 } | 646 } |
664 | 647 |
665 | 648 |
666 Code* JavaScriptFrame::unchecked_code() const { | 649 Code* JavaScriptFrame::unchecked_code() const { |
667 JSFunction* function = JSFunction::cast(this->function()); | 650 JSFunction* function = JSFunction::cast(this->function()); |
668 return function->unchecked_code(); | 651 return function->unchecked_code(); |
669 } | 652 } |
670 | 653 |
671 | 654 |
| 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 |
672 Address JavaScriptFrame::GetCallerStackPointer() const { | 664 Address JavaScriptFrame::GetCallerStackPointer() const { |
673 int arguments; | 665 return fp() + StandardFrameConstants::kCallerSPOffset; |
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); | |
693 } | 666 } |
694 | 667 |
695 | 668 |
696 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { | 669 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { |
697 ASSERT(functions->length() == 0); | 670 ASSERT(functions->length() == 0); |
698 functions->Add(JSFunction::cast(function())); | 671 functions->Add(JSFunction::cast(function())); |
699 } | 672 } |
700 | 673 |
701 | 674 |
702 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 675 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 functions->Add(function); | 833 functions->Add(function); |
861 } else { | 834 } else { |
862 // Skip over operands to advance to the next opcode. | 835 // Skip over operands to advance to the next opcode. |
863 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 836 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
864 } | 837 } |
865 } | 838 } |
866 } | 839 } |
867 | 840 |
868 | 841 |
869 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { | 842 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { |
870 const int arguments = Smi::cast(GetExpression(0))->value(); | 843 return fp() + StandardFrameConstants::kCallerSPOffset; |
871 const int offset = StandardFrameConstants::kCallerSPOffset; | |
872 return fp() + offset + (arguments + 1) * kPointerSize; | |
873 } | 844 } |
874 | 845 |
875 | 846 |
876 Address InternalFrame::GetCallerStackPointer() const { | 847 Address InternalFrame::GetCallerStackPointer() const { |
877 // Internal frames have no arguments. The stack pointer of the | 848 // Internal frames have no arguments. The stack pointer of the |
878 // caller is at a fixed offset from the frame pointer. | 849 // caller is at a fixed offset from the frame pointer. |
879 return fp() + StandardFrameConstants::kCallerSPOffset; | 850 return fp() + StandardFrameConstants::kCallerSPOffset; |
880 } | 851 } |
881 | 852 |
882 | 853 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 // Traverse the pointers in the handler itself. | 1073 // Traverse the pointers in the handler itself. |
1103 handler->Iterate(v, LookupCode()); | 1074 handler->Iterate(v, LookupCode()); |
1104 } | 1075 } |
1105 v->VisitPointers(base, limit); | 1076 v->VisitPointers(base, limit); |
1106 } | 1077 } |
1107 | 1078 |
1108 | 1079 |
1109 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { | 1080 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { |
1110 IterateExpressions(v); | 1081 IterateExpressions(v); |
1111 IteratePc(v, pc_address(), LookupCode()); | 1082 IteratePc(v, pc_address(), LookupCode()); |
1112 IterateArguments(v); | |
1113 } | 1083 } |
1114 | 1084 |
1115 | 1085 |
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); | |
1123 } | |
1124 | |
1125 | |
1126 void InternalFrame::Iterate(ObjectVisitor* v) const { | 1086 void InternalFrame::Iterate(ObjectVisitor* v) const { |
1127 // Internal frames only have object pointers on the expression stack | 1087 // Internal frames only have object pointers on the expression stack |
1128 // as they never have any arguments. | 1088 // as they never have any arguments. |
1129 IterateExpressions(v); | 1089 IterateExpressions(v); |
1130 IteratePc(v, pc_address(), LookupCode()); | 1090 IteratePc(v, pc_address(), LookupCode()); |
1131 } | 1091 } |
1132 | 1092 |
1133 | 1093 |
1134 // ------------------------------------------------------------------------- | 1094 // ------------------------------------------------------------------------- |
1135 | 1095 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 ZoneList<StackFrame*> list(10); | 1224 ZoneList<StackFrame*> list(10); |
1265 for (StackFrameIterator it; !it.done(); it.Advance()) { | 1225 for (StackFrameIterator it; !it.done(); it.Advance()) { |
1266 StackFrame* frame = AllocateFrameCopy(it.frame()); | 1226 StackFrame* frame = AllocateFrameCopy(it.frame()); |
1267 list.Add(frame); | 1227 list.Add(frame); |
1268 } | 1228 } |
1269 return list.ToVector(); | 1229 return list.ToVector(); |
1270 } | 1230 } |
1271 | 1231 |
1272 | 1232 |
1273 } } // namespace v8::internal | 1233 } } // namespace v8::internal |
OLD | NEW |