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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 2053003: Refactor the fast-case code for loading local/global variables and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after
2784 2784
2785 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { 2785 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
2786 if (slot->type() == Slot::LOOKUP) { 2786 if (slot->type() == Slot::LOOKUP) {
2787 ASSERT(slot->var()->is_dynamic()); 2787 ASSERT(slot->var()->is_dynamic());
2788 2788
2789 // JumpTargets do not yet support merging frames so the frame must be 2789 // JumpTargets do not yet support merging frames so the frame must be
2790 // spilled when jumping to these targets. 2790 // spilled when jumping to these targets.
2791 JumpTarget slow; 2791 JumpTarget slow;
2792 JumpTarget done; 2792 JumpTarget done;
2793 2793
2794 // Generate fast-case code for variables that might be shadowed by 2794 // Generate fast case for loading from slots that correspond to
2795 // eval-introduced variables. Eval is used a lot without 2795 // local/global variables or arguments unless they are shadowed by
2796 // introducing variables. In those cases, we do not want to 2796 // eval-introduced bindings.
2797 // perform a runtime call for all variables in the scope 2797 EmitDynamicLoadFromSlotFastCase(slot,
2798 // containing the eval. 2798 typeof_state,
2799 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 2799 &slow,
2800 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow); 2800 &done);
2801 frame_->SpillAll();
2802 done.Jump();
2803
2804 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
2805 frame_->SpillAll();
2806 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
2807 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
2808 if (potential_slot != NULL) {
2809 // Generate fast case for locals that rewrite to slots.
2810 __ ldr(r0,
2811 ContextSlotOperandCheckExtensions(potential_slot,
2812 r1,
2813 r2,
2814 &slow));
2815 if (potential_slot->var()->mode() == Variable::CONST) {
2816 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
2817 __ cmp(r0, ip);
2818 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
2819 }
2820 done.Jump();
2821 } else if (rewrite != NULL) {
2822 // Generate fast case for argument loads.
2823 Property* property = rewrite->AsProperty();
2824 if (property != NULL) {
2825 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
2826 Literal* key_literal = property->key()->AsLiteral();
2827 if (obj_proxy != NULL &&
2828 key_literal != NULL &&
2829 obj_proxy->IsArguments() &&
2830 key_literal->handle()->IsSmi()) {
2831 // Load arguments object if there are no eval-introduced
2832 // variables. Then load the argument from the arguments
2833 // object using keyed load.
2834 __ ldr(r0,
2835 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
2836 r1,
2837 r2,
2838 &slow));
2839 frame_->EmitPush(r0);
2840 __ mov(r1, Operand(key_literal->handle()));
2841 frame_->EmitPush(r1);
2842 EmitKeyedLoad();
2843 done.Jump();
2844 }
2845 }
2846 }
2847 }
2848 2801
2849 slow.Bind(); 2802 slow.Bind();
2850 VirtualFrame::SpilledScope spilled_scope(frame_); 2803 VirtualFrame::SpilledScope spilled_scope(frame_);
2851 frame_->EmitPush(cp); 2804 frame_->EmitPush(cp);
2852 __ mov(r0, Operand(slot->var()->name())); 2805 __ mov(r0, Operand(slot->var()->name()));
2853 frame_->EmitPush(r0); 2806 frame_->EmitPush(r0);
2854 2807
2855 if (typeof_state == INSIDE_TYPEOF) { 2808 if (typeof_state == INSIDE_TYPEOF) {
2856 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 2809 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
2857 } else { 2810 } else {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
3052 // Setup the name register and call load IC. 3005 // Setup the name register and call load IC.
3053 frame_->CallLoadIC(slot->var()->name(), 3006 frame_->CallLoadIC(slot->var()->name(),
3054 typeof_state == INSIDE_TYPEOF 3007 typeof_state == INSIDE_TYPEOF
3055 ? RelocInfo::CODE_TARGET 3008 ? RelocInfo::CODE_TARGET
3056 : RelocInfo::CODE_TARGET_CONTEXT); 3009 : RelocInfo::CODE_TARGET_CONTEXT);
3057 // Drop the global object. The result is in r0. 3010 // Drop the global object. The result is in r0.
3058 frame_->Drop(); 3011 frame_->Drop();
3059 } 3012 }
3060 3013
3061 3014
3015 void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot,
3016 TypeofState typeof_state,
3017 JumpTarget* slow,
3018 JumpTarget* done) {
3019 // Generate fast-case code for variables that might be shadowed by
3020 // eval-introduced variables. Eval is used a lot without
3021 // introducing variables. In those cases, we do not want to
3022 // perform a runtime call for all variables in the scope
3023 // containing the eval.
3024 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
3025 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, slow);
3026 frame_->SpillAll();
3027 done->Jump();
3028
3029 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
3030 frame_->SpillAll();
3031 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
3032 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
3033 if (potential_slot != NULL) {
3034 // Generate fast case for locals that rewrite to slots.
3035 __ ldr(r0,
3036 ContextSlotOperandCheckExtensions(potential_slot,
3037 r1,
3038 r2,
3039 slow));
3040 if (potential_slot->var()->mode() == Variable::CONST) {
3041 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
3042 __ cmp(r0, ip);
3043 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
3044 }
3045 done->Jump();
3046 } else if (rewrite != NULL) {
3047 // Generate fast case for argument loads.
3048 Property* property = rewrite->AsProperty();
3049 if (property != NULL) {
3050 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
3051 Literal* key_literal = property->key()->AsLiteral();
3052 if (obj_proxy != NULL &&
3053 key_literal != NULL &&
3054 obj_proxy->IsArguments() &&
3055 key_literal->handle()->IsSmi()) {
3056 // Load arguments object if there are no eval-introduced
3057 // variables. Then load the argument from the arguments
3058 // object using keyed load.
3059 __ ldr(r0,
3060 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
3061 r1,
3062 r2,
3063 slow));
3064 frame_->EmitPush(r0);
3065 __ mov(r1, Operand(key_literal->handle()));
3066 frame_->EmitPush(r1);
3067 EmitKeyedLoad();
3068 done->Jump();
3069 }
3070 }
3071 }
3072 }
3073 }
3074
3075
3062 void CodeGenerator::VisitSlot(Slot* node) { 3076 void CodeGenerator::VisitSlot(Slot* node) {
3063 #ifdef DEBUG 3077 #ifdef DEBUG
3064 int original_height = frame_->height(); 3078 int original_height = frame_->height();
3065 #endif 3079 #endif
3066 Comment cmnt(masm_, "[ Slot"); 3080 Comment cmnt(masm_, "[ Slot");
3067 LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF); 3081 LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF);
3068 ASSERT_EQ(original_height + 1, frame_->height()); 3082 ASSERT_EQ(original_height + 1, frame_->height());
3069 } 3083 }
3070 3084
3071 3085
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
3749 // 3763 //
3750 // function f() {}; 3764 // function f() {};
3751 // function g() { 3765 // function g() {
3752 // eval(...); 3766 // eval(...);
3753 // f(); // f could be in extension object. 3767 // f(); // f could be in extension object.
3754 // } 3768 // }
3755 // ---------------------------------- 3769 // ----------------------------------
3756 3770
3757 // JumpTargets do not yet support merging frames so the frame must be 3771 // JumpTargets do not yet support merging frames so the frame must be
3758 // spilled when jumping to these targets. 3772 // spilled when jumping to these targets.
3759 JumpTarget slow; 3773 JumpTarget slow, done;
3760 JumpTarget done;
3761 3774
3762 // Generate fast-case code for variables that might be shadowed by 3775 // Generate fast case for loading functions from slots that
3763 // eval-introduced variables. Eval is used a lot without 3776 // correspond to local/global variables or arguments unless they
3764 // introducing variables. In those cases, we do not want to 3777 // are shadowed by eval-introduced bindings.
3765 // perform a runtime call for all variables in the scope 3778 EmitDynamicLoadFromSlotFastCase(var->slot(),
3766 // containing the eval. 3779 NOT_INSIDE_TYPEOF,
3767 if (var->mode() == Variable::DYNAMIC_GLOBAL) { 3780 &slow,
3768 LoadFromGlobalSlotCheckExtensions(var->slot(), NOT_INSIDE_TYPEOF, &slow); 3781 &done);
3769 frame_->EmitPush(r0);
3770 LoadGlobalReceiver(r1);
3771 done.Jump();
3772
3773 } else if (var->mode() == Variable::DYNAMIC_LOCAL) {
3774 Slot* potential_slot = var->local_if_not_shadowed()->slot();
3775 Expression* rewrite = var->local_if_not_shadowed()->rewrite();
3776 if (potential_slot != NULL) {
3777 // Generate fast case for locals that rewrite to slots.
3778 __ ldr(r0,
3779 ContextSlotOperandCheckExtensions(potential_slot,
3780 r1,
3781 r2,
3782 &slow));
3783 if (potential_slot->var()->mode() == Variable::CONST) {
3784 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
3785 __ cmp(r0, ip);
3786 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
3787 }
3788 frame_->EmitPush(r0);
3789 LoadGlobalReceiver(r1);
3790 done.Jump();
3791 } else if (rewrite != NULL) {
3792 // Generate fast case for calls of an argument function.
3793 Property* property = rewrite->AsProperty();
3794 if (property != NULL) {
3795 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
3796 Literal* key_literal = property->key()->AsLiteral();
3797 if (obj_proxy != NULL &&
3798 key_literal != NULL &&
3799 obj_proxy->IsArguments() &&
3800 key_literal->handle()->IsSmi()) {
3801 // Load arguments object if there are no eval-introduced
3802 // variables. Then load the argument from the arguments
3803 // object using keyed load.
3804 __ ldr(r0,
3805 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
3806 r1,
3807 r2,
3808 &slow));
3809 frame_->EmitPush(r0);
3810 __ mov(r1, Operand(key_literal->handle()));
3811 frame_->EmitPush(r1);
3812 EmitKeyedLoad();
3813 frame_->EmitPush(r0);
3814 LoadGlobalReceiver(r1);
3815 done.Jump();
3816 }
3817 }
3818 }
3819 }
3820 3782
3821 slow.Bind(); 3783 slow.Bind();
3822 // Load the function 3784 // Load the function
3823 frame_->EmitPush(cp); 3785 frame_->EmitPush(cp);
3824 __ mov(r0, Operand(var->name())); 3786 __ mov(r0, Operand(var->name()));
3825 frame_->EmitPush(r0); 3787 frame_->EmitPush(r0);
3826 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); 3788 frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
3827 // r0: slot value; r1: receiver 3789 // r0: slot value; r1: receiver
3828 3790
3829 // Load the receiver. 3791 // Load the receiver.
3830 frame_->EmitPush(r0); // function 3792 frame_->EmitPush(r0); // function
3831 frame_->EmitPush(r1); // receiver 3793 frame_->EmitPush(r1); // receiver
3832 3794
3833 done.Bind(); 3795 // If fast case code has been generated, emit code to push the
3796 // function and receiver and have the slow path jump around this
3797 // code.
3798 if (done.is_linked()) {
3799 JumpTarget call;
3800 call.Jump();
3801 done.Bind();
3802 frame_->EmitPush(r0); // function
3803 LoadGlobalReceiver(r1); // receiver
3804 call.Bind();
3805 }
3806
3834 // Call the function. At this point, everything is spilled but the 3807 // Call the function. At this point, everything is spilled but the
3835 // function and receiver are in r0 and r1. 3808 // function and receiver are in r0 and r1.
3836 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); 3809 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
3837 frame_->EmitPush(r0); 3810 frame_->EmitPush(r0);
3838 3811
3839 } else if (property != NULL) { 3812 } else if (property != NULL) {
3840 // Check if the key is a literal string. 3813 // Check if the key is a literal string.
3841 Literal* literal = property->key()->AsLiteral(); 3814 Literal* literal = property->key()->AsLiteral();
3842 3815
3843 if (literal != NULL && literal->handle()->IsSymbol()) { 3816 if (literal != NULL && literal->handle()->IsSymbol()) {
(...skipping 6196 matching lines...) Expand 10 before | Expand all | Expand 10 after
10040 10013
10041 // Just jump to runtime to add the two strings. 10014 // Just jump to runtime to add the two strings.
10042 __ bind(&string_add_runtime); 10015 __ bind(&string_add_runtime);
10043 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 10016 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
10044 } 10017 }
10045 10018
10046 10019
10047 #undef __ 10020 #undef __
10048 10021
10049 } } // namespace v8::internal 10022 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698