| Index: src/x64/codegen-x64.cc
 | 
| ===================================================================
 | 
| --- src/x64/codegen-x64.cc	(revision 4632)
 | 
| +++ src/x64/codegen-x64.cc	(working copy)
 | 
| @@ -2867,12 +2867,12 @@
 | 
|      // ----------------------------------
 | 
|      // JavaScript examples:
 | 
|      //
 | 
| -    //  with (obj) foo(1, 2, 3)  // foo is in obj
 | 
| +    //  with (obj) foo(1, 2, 3)  // foo may be in obj.
 | 
|      //
 | 
|      //  function f() {};
 | 
|      //  function g() {
 | 
|      //    eval(...);
 | 
| -    //    f();  // f could be in extension object
 | 
| +    //    f();  // f could be in extension object.
 | 
|      //  }
 | 
|      // ----------------------------------
 | 
|  
 | 
| @@ -2895,10 +2895,9 @@
 | 
|  
 | 
|      } else if (var->mode() == Variable::DYNAMIC_LOCAL) {
 | 
|        Slot* potential_slot = var->local_if_not_shadowed()->slot();
 | 
| -      // Only generate the fast case for locals that rewrite to slots.
 | 
| -      // This rules out argument loads because eval forces arguments
 | 
| -      // access to be through the arguments object.
 | 
| +      Expression* rewrite = var->local_if_not_shadowed()->rewrite();
 | 
|        if (potential_slot != NULL) {
 | 
| +        // Generate fast case for locals that rewrite to slots.
 | 
|          // Allocate a fresh register to use as a temp in
 | 
|          // ContextSlotOperandCheckExtensions and to hold the result
 | 
|          // value.
 | 
| @@ -2918,6 +2917,34 @@
 | 
|          frame_->Push(&function);
 | 
|          LoadGlobalReceiver();
 | 
|          done.Jump();
 | 
| +      } else if (rewrite != NULL) {
 | 
| +        // Generate fast case for calls of an argument function.
 | 
| +        Property* property = rewrite->AsProperty();
 | 
| +        if (property != NULL) {
 | 
| +          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
 | 
| +          Literal* key_literal = property->key()->AsLiteral();
 | 
| +          if (obj_proxy != NULL &&
 | 
| +              key_literal != NULL &&
 | 
| +              obj_proxy->IsArguments() &&
 | 
| +              key_literal->handle()->IsSmi()) {
 | 
| +            // Load arguments object if there are no eval-introduced
 | 
| +            // variables. Then load the argument from the arguments
 | 
| +            // object using keyed load.
 | 
| +            Result arguments = allocator()->Allocate();
 | 
| +            ASSERT(arguments.is_valid());
 | 
| +            __ movq(arguments.reg(),
 | 
| +                    ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
 | 
| +                                                      arguments,
 | 
| +                                                      &slow));
 | 
| +            frame_->Push(&arguments);
 | 
| +            frame_->Push(key_literal->handle());
 | 
| +            Result value = EmitKeyedLoad(false);
 | 
| +            frame_->Drop(2);  // Drop key and receiver.
 | 
| +            frame_->Push(&value);
 | 
| +            LoadGlobalReceiver();
 | 
| +            done.Jump();
 | 
| +          }
 | 
| +        }
 | 
|        }
 | 
|      }
 | 
|  
 | 
| @@ -5342,20 +5369,13 @@
 | 
|      // containing the eval.
 | 
|      if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
 | 
|        value = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow);
 | 
| -      // If there was no control flow to slow, we can exit early.
 | 
| -      if (!slow.is_linked()) {
 | 
| -        frame_->Push(&value);
 | 
| -        return;
 | 
| -      }
 | 
| -
 | 
|        done.Jump(&value);
 | 
|  
 | 
|      } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
 | 
|        Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
 | 
| -      // Only generate the fast case for locals that rewrite to slots.
 | 
| -      // This rules out argument loads because eval forces arguments
 | 
| -      // access to be through the arguments object.
 | 
| +      Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
 | 
|        if (potential_slot != NULL) {
 | 
| +        // Generate fast case for locals that rewrite to slots.
 | 
|          // Allocate a fresh register to use as a temp in
 | 
|          // ContextSlotOperandCheckExtensions and to hold the result
 | 
|          // value.
 | 
| @@ -5370,10 +5390,33 @@
 | 
|            done.Branch(not_equal, &value);
 | 
|            __ LoadRoot(value.reg(), Heap::kUndefinedValueRootIndex);
 | 
|          }
 | 
| -        // There is always control flow to slow from
 | 
| -        // ContextSlotOperandCheckExtensions so we have to jump around
 | 
| -        // it.
 | 
|          done.Jump(&value);
 | 
| +      } else if (rewrite != NULL) {
 | 
| +        // Generate fast case for argument loads.
 | 
| +        Property* property = rewrite->AsProperty();
 | 
| +        if (property != NULL) {
 | 
| +          VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
 | 
| +          Literal* key_literal = property->key()->AsLiteral();
 | 
| +          if (obj_proxy != NULL &&
 | 
| +              key_literal != NULL &&
 | 
| +              obj_proxy->IsArguments() &&
 | 
| +              key_literal->handle()->IsSmi()) {
 | 
| +            // Load arguments object if there are no eval-introduced
 | 
| +            // variables. Then load the argument from the arguments
 | 
| +            // object using keyed load.
 | 
| +            Result arguments = allocator()->Allocate();
 | 
| +            ASSERT(arguments.is_valid());
 | 
| +            __ movq(arguments.reg(),
 | 
| +                    ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
 | 
| +                                                      arguments,
 | 
| +                                                      &slow));
 | 
| +            frame_->Push(&arguments);
 | 
| +            frame_->Push(key_literal->handle());
 | 
| +            value = EmitKeyedLoad(false);
 | 
| +            frame_->Drop(2);  // Drop key and receiver.
 | 
| +            done.Jump(&value);
 | 
| +          }
 | 
| +        }
 | 
|        }
 | 
|      }
 | 
|  
 | 
| 
 |