Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: src/frames.cc

Issue 6677164: Always iterate outgoing arguments as a part of caller frame. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698