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