| Index: src/arm/stub-cache-arm.cc
 | 
| ===================================================================
 | 
| --- src/arm/stub-cache-arm.cc	(revision 2285)
 | 
| +++ src/arm/stub-cache-arm.cc	(working copy)
 | 
| @@ -648,6 +648,7 @@
 | 
|    __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
 | 
|  
 | 
|    // Jump to the cached code (tail call).
 | 
| +  ASSERT(function->is_compiled());
 | 
|    Handle<Code> code(function->code());
 | 
|    ParameterCount expected(function->shared()->formal_parameter_count());
 | 
|    __ InvokeCode(code, expected, arguments(),
 | 
| @@ -687,6 +688,61 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +Object* CallStubCompiler::CompileCallGlobal(JSGlobalObject* object,
 | 
| +                                            JSGlobalPropertyCell* cell,
 | 
| +                                            JSFunction* function,
 | 
| +                                            String* name) {
 | 
| +  // ----------- S t a t e -------------
 | 
| +  //  -- lr: return address
 | 
| +  // -----------------------------------
 | 
| +  Label miss;
 | 
| +
 | 
| +  __ IncrementCounter(&Counters::call_global_inline, 1, r1, r3);
 | 
| +
 | 
| +  // Get the number of arguments.
 | 
| +  const int argc = arguments().immediate();
 | 
| +
 | 
| +  // Check that the map of the global has not changed.
 | 
| +  __ ldr(r2, MemOperand(sp, argc * kPointerSize));
 | 
| +  __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
 | 
| +  __ cmp(r3, Operand(Handle<Map>(object->map())));
 | 
| +  __ b(ne, &miss);
 | 
| +
 | 
| +  // Get the value from the cell.
 | 
| +  __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell)));
 | 
| +  __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
 | 
| +
 | 
| +  // Check that the cell contains the same function.
 | 
| +  __ cmp(r1, Operand(Handle<JSFunction>(function)));
 | 
| +  __ b(ne, &miss);
 | 
| +
 | 
| +  // Patch the receiver on the stack with the global proxy if
 | 
| +  // necessary.
 | 
| +  __ ldr(r3, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
 | 
| +  __ str(r3, MemOperand(sp, argc * kPointerSize));
 | 
| +
 | 
| +  // Setup the context (function already in r1).
 | 
| +  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
 | 
| +
 | 
| +  // Jump to the cached code (tail call).
 | 
| +  ASSERT(function->is_compiled());
 | 
| +  Handle<Code> code(function->code());
 | 
| +  ParameterCount expected(function->shared()->formal_parameter_count());
 | 
| +  __ InvokeCode(code, expected, arguments(),
 | 
| +                RelocInfo::CODE_TARGET, JUMP_FUNCTION);
 | 
| +
 | 
| +  // Handle call cache miss.
 | 
| +  __ bind(&miss);
 | 
| +  __ DecrementCounter(&Counters::call_global_inline, 1, r1, r3);
 | 
| +  __ IncrementCounter(&Counters::call_global_inline_miss, 1, r1, r3);
 | 
| +  Handle<Code> ic = ComputeCallMiss(arguments().immediate());
 | 
| +  __ Jump(ic, RelocInfo::CODE_TARGET);
 | 
| +
 | 
| +  // Return the generated code.
 | 
| +  return GetCode(NORMAL, name);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  Object* StoreStubCompiler::CompileStoreField(JSObject* object,
 | 
|                                               int index,
 | 
|                                               Map* transition,
 | 
| @@ -827,6 +883,45 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +Object* StoreStubCompiler::CompileStoreGlobal(JSGlobalObject* object,
 | 
| +                                              JSGlobalPropertyCell* cell,
 | 
| +                                              String* name) {
 | 
| +  // ----------- S t a t e -------------
 | 
| +  //  -- r0    : value
 | 
| +  //  -- r2    : name
 | 
| +  //  -- lr    : return address
 | 
| +  //  -- [sp]  : receiver
 | 
| +  // -----------------------------------
 | 
| +  Label miss;
 | 
| +
 | 
| +  __ IncrementCounter(&Counters::named_store_global_inline, 1, r1, r3);
 | 
| +
 | 
| +  // Check that the map of the global has not changed.
 | 
| +  __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
 | 
| +  __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
 | 
| +  __ cmp(r3, Operand(Handle<Map>(object->map())));
 | 
| +  __ b(ne, &miss);
 | 
| +
 | 
| +  // Store the value in the cell.
 | 
| +  __ mov(r2, Operand(Handle<JSGlobalPropertyCell>(cell)));
 | 
| +  __ str(r0, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
 | 
| +  __ mov(r1, Operand(JSGlobalPropertyCell::kValueOffset));
 | 
| +  __ RecordWrite(r2, r1, r3);
 | 
| +
 | 
| +  __ Ret();
 | 
| +
 | 
| +  // Handle store cache miss.
 | 
| +  __ bind(&miss);
 | 
| +  __ DecrementCounter(&Counters::named_store_global_inline, 1, r1, r3);
 | 
| +  __ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r1, r3);
 | 
| +  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
 | 
| +  __ Jump(ic, RelocInfo::CODE_TARGET);
 | 
| +
 | 
| +  // Return the generated code.
 | 
| +  return GetCode(NORMAL, name);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  Object* LoadStubCompiler::CompileLoadField(JSObject* object,
 | 
|                                             JSObject* holder,
 | 
|                                             int index,
 | 
| @@ -921,6 +1016,44 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +Object* LoadStubCompiler::CompileLoadGlobal(JSGlobalObject* object,
 | 
| +                                            JSGlobalPropertyCell* cell,
 | 
| +                                            String* name) {
 | 
| +  // ----------- S t a t e -------------
 | 
| +  //  -- r2    : name
 | 
| +  //  -- lr    : return address
 | 
| +  //  -- [sp]  : receiver
 | 
| +  // -----------------------------------
 | 
| +  Label miss;
 | 
| +
 | 
| +  __ IncrementCounter(&Counters::named_load_global_inline, 1, r1, r3);
 | 
| +
 | 
| +  // Check that the map of the global has not changed.
 | 
| +  __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
 | 
| +  __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
 | 
| +  __ cmp(r3, Operand(Handle<Map>(object->map())));
 | 
| +  __ b(ne, &miss);
 | 
| +
 | 
| +  // Get the value from the cell.
 | 
| +  __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell)));
 | 
| +  __ ldr(r0, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
 | 
| +
 | 
| +  // Check for deleted property.
 | 
| +  __ cmp(r0, Operand(Factory::the_hole_value()));
 | 
| +  __ b(eq, &miss);
 | 
| +
 | 
| +  __ Ret();
 | 
| +
 | 
| +  __ bind(&miss);
 | 
| +  __ DecrementCounter(&Counters::named_load_global_inline, 1, r1, r3);
 | 
| +  __ IncrementCounter(&Counters::named_load_global_inline_miss, 1, r1, r3);
 | 
| +  GenerateLoadMiss(masm(), Code::LOAD_IC);
 | 
| +
 | 
| +  // Return the generated code.
 | 
| +  return GetCode(NORMAL, name);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // TODO(1224671): IC stubs for keyed loads have not been implemented
 | 
|  // for ARM.
 | 
|  Object* KeyedLoadStubCompiler::CompileLoadField(String* name,
 | 
| 
 |