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

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

Issue 2027002: Implement fast calls of functions in the presence of eval (if the eval... (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 | « no previous file | src/ia32/codegen-ia32.cc » ('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 2769 matching lines...) Expand 10 before | Expand all | Expand 10 after
2780 return; 2780 return;
2781 } 2781 }
2782 frame_->SpillAll(); 2782 frame_->SpillAll();
2783 2783
2784 done.Jump(); 2784 done.Jump();
2785 2785
2786 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 2786 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
2787 frame_->SpillAll(); 2787 frame_->SpillAll();
2788 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); 2788 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
2789 // Only generate the fast case for locals that rewrite to slots. 2789 // Only generate the fast case for locals that rewrite to slots.
2790 // This rules out argument loads. 2790 // This rules out argument loads because eval forces arguments
2791 // access to be through the arguments object.
2791 if (potential_slot != NULL) { 2792 if (potential_slot != NULL) {
2792 __ ldr(r0, 2793 __ ldr(r0,
2793 ContextSlotOperandCheckExtensions(potential_slot, 2794 ContextSlotOperandCheckExtensions(potential_slot,
2794 r1, 2795 r1,
2795 r2, 2796 r2,
2796 &slow)); 2797 &slow));
2797 if (potential_slot->var()->mode() == Variable::CONST) { 2798 if (potential_slot->var()->mode() == Variable::CONST) {
2798 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 2799 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
2799 __ cmp(r0, ip); 2800 __ cmp(r0, ip);
2800 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 2801 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
3695 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 3696 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
3696 CodeForSourcePosition(node->position()); 3697 CodeForSourcePosition(node->position());
3697 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, 3698 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
3698 arg_count + 1); 3699 arg_count + 1);
3699 __ ldr(cp, frame_->Context()); 3700 __ ldr(cp, frame_->Context());
3700 frame_->EmitPush(r0); 3701 frame_->EmitPush(r0);
3701 3702
3702 } else if (var != NULL && var->slot() != NULL && 3703 } else if (var != NULL && var->slot() != NULL &&
3703 var->slot()->type() == Slot::LOOKUP) { 3704 var->slot()->type() == Slot::LOOKUP) {
3704 // ---------------------------------- 3705 // ----------------------------------
3705 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj 3706 // JavaScript examples:
3707 //
3708 // with (obj) foo(1, 2, 3) // foo is in obj
Erik Corry 2010/05/07 10:38:31 As I understand it the point of this code is to go
3709 //
3710 // function f() {};
3711 // function g() {
3712 // eval(...);
3713 // f(); // f could be in extension object
Erik Corry 2010/05/07 10:38:31 Full stop.
3714 // }
3706 // ---------------------------------- 3715 // ----------------------------------
3707 3716
3717 // JumpTargets do not yet support merging frames so the frame must be
3718 // spilled when jumping to these targets.
3719 JumpTarget slow;
3720 JumpTarget done;
3721
3722 // Generate fast-case code for variables that might be shadowed by
3723 // eval-introduced variables. Eval is used a lot without
3724 // introducing variables. In those cases, we do not want to
3725 // perform a runtime call for all variables in the scope
3726 // containing the eval.
3727 if (var->mode() == Variable::DYNAMIC_GLOBAL) {
3728 LoadFromGlobalSlotCheckExtensions(var->slot(), NOT_INSIDE_TYPEOF, &slow);
3729 frame_->EmitPush(r0);
3730 LoadGlobalReceiver(r1);
3731 done.Jump();
3732
3733 } else if (var->mode() == Variable::DYNAMIC_LOCAL) {
3734 Slot* potential_slot = var->local_if_not_shadowed()->slot();
3735 // Only generate the fast case for locals that rewrite to slots.
3736 // This rules out argument loads because eval forces arguments
3737 // access to be through the arguments object.
3738 if (potential_slot != NULL) {
3739 __ ldr(r0,
3740 ContextSlotOperandCheckExtensions(potential_slot,
3741 r1,
3742 r2,
3743 &slow));
3744 if (potential_slot->var()->mode() == Variable::CONST) {
3745 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
3746 __ cmp(r0, ip);
3747 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
3748 }
3749 frame_->EmitPush(r0);
3750 LoadGlobalReceiver(r1);
3751 done.Jump();
3752 }
3753 }
3754
3755 slow.Bind();
3708 // Load the function 3756 // Load the function
3709 frame_->EmitPush(cp); 3757 frame_->EmitPush(cp);
3710 __ mov(r0, Operand(var->name())); 3758 __ mov(r0, Operand(var->name()));
3711 frame_->EmitPush(r0); 3759 frame_->EmitPush(r0);
3712 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); 3760 frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
3713 // r0: slot value; r1: receiver 3761 // r0: slot value; r1: receiver
3714 3762
3715 // Load the receiver. 3763 // Load the receiver.
3716 frame_->EmitPush(r0); // function 3764 frame_->EmitPush(r0); // function
3717 frame_->EmitPush(r1); // receiver 3765 frame_->EmitPush(r1); // receiver
3718 3766
3719 // Call the function. 3767 done.Bind();
3768 // Call the function. At this point, everything is spilled but the
3769 // function and receiver are in r0 and r1.
3720 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); 3770 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
3721 frame_->EmitPush(r0); 3771 frame_->EmitPush(r0);
3722 3772
3723 } else if (property != NULL) { 3773 } else if (property != NULL) {
3724 // Check if the key is a literal string. 3774 // Check if the key is a literal string.
3725 Literal* literal = property->key()->AsLiteral(); 3775 Literal* literal = property->key()->AsLiteral();
3726 3776
3727 if (literal != NULL && literal->handle()->IsSymbol()) { 3777 if (literal != NULL && literal->handle()->IsSymbol()) {
3728 // ------------------------------------------------------------------ 3778 // ------------------------------------------------------------------
3729 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' 3779 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
(...skipping 6171 matching lines...) Expand 10 before | Expand all | Expand 10 after
9901 9951
9902 // Just jump to runtime to add the two strings. 9952 // Just jump to runtime to add the two strings.
9903 __ bind(&string_add_runtime); 9953 __ bind(&string_add_runtime);
9904 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 9954 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
9905 } 9955 }
9906 9956
9907 9957
9908 #undef __ 9958 #undef __
9909 9959
9910 } } // namespace v8::internal 9960 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698