| 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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 } | 669 } |
| 670 | 670 |
| 671 | 671 |
| 672 | 672 |
| 673 | 673 |
| 674 | 674 |
| 675 static void ComputeSlotMappingForArguments(JavaScriptFrame* frame, | 675 static void ComputeSlotMappingForArguments(JavaScriptFrame* frame, |
| 676 int inlined_frame_index, | 676 int inlined_frame_index, |
| 677 Vector<SlotRef>* args_slots) { | 677 Vector<SlotRef>* args_slots) { |
| 678 AssertNoAllocation no_gc; | 678 AssertNoAllocation no_gc; |
| 679 | |
| 680 int deopt_index = AstNode::kNoNumber; | 679 int deopt_index = AstNode::kNoNumber; |
| 681 | |
| 682 DeoptimizationInputData* data = | 680 DeoptimizationInputData* data = |
| 683 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); | 681 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
| 684 | |
| 685 TranslationIterator it(data->TranslationByteArray(), | 682 TranslationIterator it(data->TranslationByteArray(), |
| 686 data->TranslationIndex(deopt_index)->value()); | 683 data->TranslationIndex(deopt_index)->value()); |
| 687 | |
| 688 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); | 684 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
| 689 ASSERT(opcode == Translation::BEGIN); | 685 ASSERT(opcode == Translation::BEGIN); |
| 690 int frame_count = it.Next(); | 686 int frame_count = it.Next(); |
| 691 | |
| 692 USE(frame_count); | 687 USE(frame_count); |
| 693 ASSERT(frame_count > inlined_frame_index); | 688 ASSERT(frame_count > inlined_frame_index); |
| 694 | |
| 695 int frames_to_skip = inlined_frame_index; | 689 int frames_to_skip = inlined_frame_index; |
| 696 while (true) { | 690 while (true) { |
| 697 opcode = static_cast<Translation::Opcode>(it.Next()); | 691 opcode = static_cast<Translation::Opcode>(it.Next()); |
| 698 | |
| 699 // Skip over operands to advance to the next opcode. | 692 // Skip over operands to advance to the next opcode. |
| 700 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 693 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 701 | |
| 702 if (opcode == Translation::FRAME) { | 694 if (opcode == Translation::FRAME) { |
| 703 if (frames_to_skip == 0) { | 695 if (frames_to_skip == 0) { |
| 704 // We reached frame corresponding to inlined function in question. | 696 // We reached the frame corresponding to the inlined function |
| 705 // Process translation commands for arguments. | 697 // in question. Process the translation commands for the |
| 706 | 698 // arguments. |
| 707 // Skip translation command for receiver. | 699 // |
| 700 // Skip the translation command for the receiver. |
| 708 it.Skip(Translation::NumberOfOperandsFor( | 701 it.Skip(Translation::NumberOfOperandsFor( |
| 709 static_cast<Translation::Opcode>(it.Next()))); | 702 static_cast<Translation::Opcode>(it.Next()))); |
| 710 | |
| 711 // Compute slots for arguments. | 703 // Compute slots for arguments. |
| 712 for (int i = 0; i < args_slots->length(); ++i) { | 704 for (int i = 0; i < args_slots->length(); ++i) { |
| 713 (*args_slots)[i] = ComputeSlotForNextArgument(&it, data, frame); | 705 (*args_slots)[i] = ComputeSlotForNextArgument(&it, data, frame); |
| 714 } | 706 } |
| 715 | |
| 716 return; | 707 return; |
| 717 } | 708 } |
| 718 | |
| 719 frames_to_skip--; | 709 frames_to_skip--; |
| 720 } | 710 } |
| 721 } | 711 } |
| 722 | 712 |
| 723 UNREACHABLE(); | 713 UNREACHABLE(); |
| 724 } | 714 } |
| 725 | 715 |
| 726 | 716 |
| 727 static MaybeObject* ConstructArgumentsObjectForInlinedFunction( | 717 static MaybeObject* ConstructArgumentsObjectForInlinedFunction( |
| 728 JavaScriptFrame* frame, | 718 JavaScriptFrame* frame, |
| 729 Handle<JSFunction> inlined_function, | 719 Handle<JSFunction> inlined_function, |
| 730 int inlined_frame_index) { | 720 int inlined_frame_index) { |
| 731 Isolate* isolate = Isolate::Current(); | 721 Isolate* isolate = Isolate::Current(); |
| 732 Factory* factory = isolate->factory(); | 722 Factory* factory = isolate->factory(); |
| 733 | 723 |
| 734 int args_count = inlined_function->shared()->formal_parameter_count(); | 724 int args_count = inlined_function->shared()->formal_parameter_count(); |
| 735 | |
| 736 ScopedVector<SlotRef> args_slots(args_count); | 725 ScopedVector<SlotRef> args_slots(args_count); |
| 737 | |
| 738 ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots); | 726 ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots); |
| 739 | |
| 740 Handle<JSObject> arguments = | 727 Handle<JSObject> arguments = |
| 741 factory->NewArgumentsObject(inlined_function, args_count); | 728 factory->NewArgumentsObject(inlined_function, args_count); |
| 742 | 729 |
| 743 Handle<FixedArray> array = factory->NewFixedArray(args_count); | 730 Handle<FixedArray> array = factory->NewFixedArray(args_count); |
| 744 for (int i = 0; i < args_count; ++i) { | 731 for (int i = 0; i < args_count; ++i) { |
| 745 Handle<Object> value = args_slots[i].GetValue(); | 732 Handle<Object> value = args_slots[i].GetValue(); |
| 746 array->set(i, *value); | 733 array->set(i, *value); |
| 747 } | 734 } |
| 748 arguments->set_elements(*array); | 735 arguments->set_elements(*array); |
| 749 | 736 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 763 // Find the top invocation of the function by traversing frames. | 750 // Find the top invocation of the function by traversing frames. |
| 764 List<JSFunction*> functions(2); | 751 List<JSFunction*> functions(2); |
| 765 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { | 752 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { |
| 766 JavaScriptFrame* frame = it.frame(); | 753 JavaScriptFrame* frame = it.frame(); |
| 767 frame->GetFunctions(&functions); | 754 frame->GetFunctions(&functions); |
| 768 for (int i = functions.length() - 1; i >= 0; i--) { | 755 for (int i = functions.length() - 1; i >= 0; i--) { |
| 769 // Skip all frames that aren't invocations of the given function. | 756 // Skip all frames that aren't invocations of the given function. |
| 770 if (functions[i] != *function) continue; | 757 if (functions[i] != *function) continue; |
| 771 | 758 |
| 772 if (i > 0) { | 759 if (i > 0) { |
| 773 // Function in question was inlined. | 760 // The function in question was inlined. Inlined functions have the |
| 761 // correct number of arguments and no allocated arguments object, so |
| 762 // we can construct a fresh one by interpreting the function's |
| 763 // deoptimization input data. |
| 774 return ConstructArgumentsObjectForInlinedFunction(frame, function, i); | 764 return ConstructArgumentsObjectForInlinedFunction(frame, function, i); |
| 775 } else { | 765 } |
| 766 |
| 767 if (!frame->is_optimized()) { |
| 776 // If there is an arguments variable in the stack, we return that. | 768 // If there is an arguments variable in the stack, we return that. |
| 777 int index = function->shared()->scope_info()-> | 769 int index = function->shared()->scope_info()-> |
| 778 StackSlotIndex(isolate->heap()->arguments_symbol()); | 770 StackSlotIndex(isolate->heap()->arguments_symbol()); |
| 779 if (index >= 0) { | 771 if (index >= 0) { |
| 780 Handle<Object> arguments = | 772 Handle<Object> arguments = |
| 781 Handle<Object>(frame->GetExpression(index), isolate); | 773 Handle<Object>(frame->GetExpression(index), isolate); |
| 782 if (!arguments->IsArgumentsMarker()) return *arguments; | 774 if (!arguments->IsArgumentsMarker()) return *arguments; |
| 783 } | 775 } |
| 776 } |
| 784 | 777 |
| 785 // If there isn't an arguments variable in the stack, we need to | 778 // If there is no arguments variable in the stack or we have an |
| 786 // find the frame that holds the actual arguments passed to the | 779 // optimized frame, we find the frame that holds the actual arguments |
| 787 // function on the stack. | 780 // passed to the function. |
| 788 it.AdvanceToArgumentsFrame(); | 781 it.AdvanceToArgumentsFrame(); |
| 789 frame = it.frame(); | 782 frame = it.frame(); |
| 790 | 783 |
| 791 // Get the number of arguments and construct an arguments object | 784 // Get the number of arguments and construct an arguments object |
| 792 // mirror for the right frame. | 785 // mirror for the right frame. |
| 793 const int length = frame->GetProvidedParametersCount(); | 786 const int length = frame->GetProvidedParametersCount(); |
| 794 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject( | 787 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject( |
| 795 function, length); | 788 function, length); |
| 796 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); | 789 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
| 797 | 790 |
| 798 // Copy the parameters to the arguments object. | 791 // Copy the parameters to the arguments object. |
| 799 ASSERT(array->length() == length); | 792 ASSERT(array->length() == length); |
| 800 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); | 793 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); |
| 801 arguments->set_elements(*array); | 794 arguments->set_elements(*array); |
| 802 | 795 |
| 803 // Return the freshly allocated arguments object. | 796 // Return the freshly allocated arguments object. |
| 804 return *arguments; | 797 return *arguments; |
| 805 } | |
| 806 } | 798 } |
| 807 functions.Rewind(0); | 799 functions.Rewind(0); |
| 808 } | 800 } |
| 809 | 801 |
| 810 // No frame corresponding to the given function found. Return null. | 802 // No frame corresponding to the given function found. Return null. |
| 811 return isolate->heap()->null_value(); | 803 return isolate->heap()->null_value(); |
| 812 } | 804 } |
| 813 | 805 |
| 814 | 806 |
| 815 const AccessorDescriptor Accessors::FunctionArguments = { | 807 const AccessorDescriptor Accessors::FunctionArguments = { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 } | 891 } |
| 900 | 892 |
| 901 | 893 |
| 902 const AccessorDescriptor Accessors::ObjectPrototype = { | 894 const AccessorDescriptor Accessors::ObjectPrototype = { |
| 903 ObjectGetPrototype, | 895 ObjectGetPrototype, |
| 904 ObjectSetPrototype, | 896 ObjectSetPrototype, |
| 905 0 | 897 0 |
| 906 }; | 898 }; |
| 907 | 899 |
| 908 } } // namespace v8::internal | 900 } } // namespace v8::internal |
| OLD | NEW |