| 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 |