| 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,
|
|
|