| 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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 // possibly find pointers in optimized frames in that state. | 533 // possibly find pointers in optimized frames in that state. |
| 534 ASSERT(!SafeStackFrameIterator::is_active()); | 534 ASSERT(!SafeStackFrameIterator::is_active()); |
| 535 | 535 |
| 536 // Compute the safepoint information. | 536 // Compute the safepoint information. |
| 537 unsigned stack_slots = 0; | 537 unsigned stack_slots = 0; |
| 538 SafepointEntry safepoint_entry; | 538 SafepointEntry safepoint_entry; |
| 539 Code* code = StackFrame::GetSafepointData( | 539 Code* code = StackFrame::GetSafepointData( |
| 540 pc(), &safepoint_entry, &stack_slots); | 540 pc(), &safepoint_entry, &stack_slots); |
| 541 unsigned slot_space = stack_slots * kPointerSize; | 541 unsigned slot_space = stack_slots * kPointerSize; |
| 542 | 542 |
| 543 // Visit the outgoing parameters. This is usually dealt with by the | 543 // Visit the outgoing parameters. |
| 544 // callee, but while GC'ing we artificially lower the number of | |
| 545 // arguments to zero and let the caller deal with it. | |
| 546 Object** parameters_base = &Memory::Object_at(sp()); | 544 Object** parameters_base = &Memory::Object_at(sp()); |
| 547 Object** parameters_limit = &Memory::Object_at( | 545 Object** parameters_limit = &Memory::Object_at( |
| 548 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); | 546 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); |
| 549 | 547 |
| 550 // Visit the parameters that may be on top of the saved registers. | 548 // Visit the parameters that may be on top of the saved registers. |
| 551 if (safepoint_entry.argument_count() > 0) { | 549 if (safepoint_entry.argument_count() > 0) { |
| 552 v->VisitPointers(parameters_base, | 550 v->VisitPointers(parameters_base, |
| 553 parameters_base + safepoint_entry.argument_count()); | 551 parameters_base + safepoint_entry.argument_count()); |
| 554 parameters_base += safepoint_entry.argument_count(); | 552 parameters_base += safepoint_entry.argument_count(); |
| 555 } | 553 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 } | 587 } |
| 590 | 588 |
| 591 // Visit the context and the function. | 589 // Visit the context and the function. |
| 592 Object** fixed_base = &Memory::Object_at( | 590 Object** fixed_base = &Memory::Object_at( |
| 593 fp() + JavaScriptFrameConstants::kFunctionOffset); | 591 fp() + JavaScriptFrameConstants::kFunctionOffset); |
| 594 Object** fixed_limit = &Memory::Object_at(fp()); | 592 Object** fixed_limit = &Memory::Object_at(fp()); |
| 595 v->VisitPointers(fixed_base, fixed_limit); | 593 v->VisitPointers(fixed_base, fixed_limit); |
| 596 | 594 |
| 597 // Visit the return address in the callee and incoming arguments. | 595 // Visit the return address in the callee and incoming arguments. |
| 598 IteratePc(v, pc_address(), code); | 596 IteratePc(v, pc_address(), code); |
| 599 IterateArguments(v); | |
| 600 } | |
| 601 | |
| 602 | |
| 603 Object* JavaScriptFrame::GetParameter(int index) const { | |
| 604 ASSERT(index >= 0 && index < ComputeParametersCount()); | |
| 605 const int offset = JavaScriptFrameConstants::kParam0Offset; | |
| 606 return Memory::Object_at(caller_sp() + offset - (index * kPointerSize)); | |
| 607 } | |
| 608 | |
| 609 | |
| 610 int JavaScriptFrame::ComputeParametersCount() const { | |
| 611 Address base = caller_sp() + JavaScriptFrameConstants::kReceiverOffset; | |
| 612 Address limit = fp() + JavaScriptFrameConstants::kSavedRegistersOffset; | |
| 613 return static_cast<int>((base - limit) / kPointerSize); | |
| 614 } | 597 } |
| 615 | 598 |
| 616 | 599 |
| 617 bool JavaScriptFrame::IsConstructor() const { | 600 bool JavaScriptFrame::IsConstructor() const { |
| 618 Address fp = caller_fp(); | 601 Address fp = caller_fp(); |
| 619 if (has_adapted_arguments()) { | 602 if (has_adapted_arguments()) { |
| 620 // Skip the arguments adaptor frame and look at the real caller. | 603 // Skip the arguments adaptor frame and look at the real caller. |
| 621 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 604 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
| 622 } | 605 } |
| 623 return IsConstructFrame(fp); | 606 return IsConstructFrame(fp); |
| 624 } | 607 } |
| 625 | 608 |
| 626 | 609 |
| 627 Code* JavaScriptFrame::unchecked_code() const { | 610 Code* JavaScriptFrame::unchecked_code() const { |
| 628 JSFunction* function = JSFunction::cast(this->function()); | 611 JSFunction* function = JSFunction::cast(this->function()); |
| 629 return function->unchecked_code(); | 612 return function->unchecked_code(); |
| 630 } | 613 } |
| 631 | 614 |
| 632 | 615 |
| 633 int JavaScriptFrame::GetProvidedParametersCount() const { | 616 int JavaScriptFrame::GetNumberOfIncomingArguments() const { |
| 634 return ComputeParametersCount(); | 617 ASSERT(!SafeStackFrameIterator::is_active() && |
| 618 Heap::gc_state() == Heap::NOT_IN_GC); |
| 619 |
| 620 JSFunction* function = JSFunction::cast(this->function()); |
| 621 return function->shared()->formal_parameter_count(); |
| 635 } | 622 } |
| 636 | 623 |
| 637 | 624 |
| 638 Address JavaScriptFrame::GetCallerStackPointer() const { | 625 Address JavaScriptFrame::GetCallerStackPointer() const { |
| 639 int arguments; | 626 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 640 if (Heap::gc_state() != Heap::NOT_IN_GC || | |
| 641 SafeStackFrameIterator::is_active()) { | |
| 642 // If the we are currently iterating the safe stack the | |
| 643 // arguments for frames are traversed as if they were | |
| 644 // expression stack elements of the calling frame. The reason for | |
| 645 // this rather strange decision is that we cannot access the | |
| 646 // function during mark-compact GCs when objects may have been marked. | |
| 647 // In fact accessing heap objects (like function->shared() below) | |
| 648 // at all during GC is problematic. | |
| 649 arguments = 0; | |
| 650 } else { | |
| 651 // Compute the number of arguments by getting the number of formal | |
| 652 // parameters of the function. We must remember to take the | |
| 653 // receiver into account (+1). | |
| 654 JSFunction* function = JSFunction::cast(this->function()); | |
| 655 arguments = function->shared()->formal_parameter_count() + 1; | |
| 656 } | |
| 657 const int offset = StandardFrameConstants::kCallerSPOffset; | |
| 658 return fp() + offset + (arguments * kPointerSize); | |
| 659 } | 627 } |
| 660 | 628 |
| 661 | 629 |
| 662 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { | 630 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { |
| 663 ASSERT(functions->length() == 0); | 631 ASSERT(functions->length() == 0); |
| 664 functions->Add(JSFunction::cast(function())); | 632 functions->Add(JSFunction::cast(function())); |
| 665 } | 633 } |
| 666 | 634 |
| 667 | 635 |
| 668 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 636 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 functions->Add(function); | 794 functions->Add(function); |
| 827 } else { | 795 } else { |
| 828 // Skip over operands to advance to the next opcode. | 796 // Skip over operands to advance to the next opcode. |
| 829 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 797 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 830 } | 798 } |
| 831 } | 799 } |
| 832 } | 800 } |
| 833 | 801 |
| 834 | 802 |
| 835 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { | 803 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { |
| 836 const int arguments = Smi::cast(GetExpression(0))->value(); | 804 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 837 const int offset = StandardFrameConstants::kCallerSPOffset; | |
| 838 return fp() + offset + (arguments + 1) * kPointerSize; | |
| 839 } | 805 } |
| 840 | 806 |
| 841 | 807 |
| 842 Address InternalFrame::GetCallerStackPointer() const { | 808 Address InternalFrame::GetCallerStackPointer() const { |
| 843 // Internal frames have no arguments. The stack pointer of the | 809 // Internal frames have no arguments. The stack pointer of the |
| 844 // caller is at a fixed offset from the frame pointer. | 810 // caller is at a fixed offset from the frame pointer. |
| 845 return fp() + StandardFrameConstants::kCallerSPOffset; | 811 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 846 } | 812 } |
| 847 | 813 |
| 848 | 814 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 // Traverse the pointers in the handler itself. | 1033 // Traverse the pointers in the handler itself. |
| 1068 handler->Iterate(v, code()); | 1034 handler->Iterate(v, code()); |
| 1069 } | 1035 } |
| 1070 v->VisitPointers(base, limit); | 1036 v->VisitPointers(base, limit); |
| 1071 } | 1037 } |
| 1072 | 1038 |
| 1073 | 1039 |
| 1074 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { | 1040 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { |
| 1075 IterateExpressions(v); | 1041 IterateExpressions(v); |
| 1076 IteratePc(v, pc_address(), code()); | 1042 IteratePc(v, pc_address(), code()); |
| 1077 IterateArguments(v); | |
| 1078 } | |
| 1079 | |
| 1080 | |
| 1081 void JavaScriptFrame::IterateArguments(ObjectVisitor* v) const { | |
| 1082 // Traverse callee-saved registers, receiver, and parameters. | |
| 1083 const int kBaseOffset = JavaScriptFrameConstants::kSavedRegistersOffset; | |
| 1084 const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset; | |
| 1085 Object** base = &Memory::Object_at(fp() + kBaseOffset); | |
| 1086 Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1; | |
| 1087 v->VisitPointers(base, limit); | |
| 1088 } | 1043 } |
| 1089 | 1044 |
| 1090 | 1045 |
| 1091 void InternalFrame::Iterate(ObjectVisitor* v) const { | 1046 void InternalFrame::Iterate(ObjectVisitor* v) const { |
| 1092 // Internal frames only have object pointers on the expression stack | 1047 // Internal frames only have object pointers on the expression stack |
| 1093 // as they never have any arguments. | 1048 // as they never have any arguments. |
| 1094 IterateExpressions(v); | 1049 IterateExpressions(v); |
| 1095 IteratePc(v, pc_address(), code()); | 1050 IteratePc(v, pc_address(), code()); |
| 1096 } | 1051 } |
| 1097 | 1052 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 ZoneList<StackFrame*> list(10); | 1178 ZoneList<StackFrame*> list(10); |
| 1224 for (StackFrameIterator it; !it.done(); it.Advance()) { | 1179 for (StackFrameIterator it; !it.done(); it.Advance()) { |
| 1225 StackFrame* frame = AllocateFrameCopy(it.frame()); | 1180 StackFrame* frame = AllocateFrameCopy(it.frame()); |
| 1226 list.Add(frame); | 1181 list.Add(frame); |
| 1227 } | 1182 } |
| 1228 return list.ToVector(); | 1183 return list.ToVector(); |
| 1229 } | 1184 } |
| 1230 | 1185 |
| 1231 | 1186 |
| 1232 } } // namespace v8::internal | 1187 } } // namespace v8::internal |
| OLD | NEW |