Commit 9344612b authored by whesse@chromium.org's avatar whesse@chromium.org

Change StoreIC interface on ARM platform

Review URL: http://codereview.chromium.org/554152

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3830 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5ecfd4bf
......@@ -2718,9 +2718,9 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
}
frame_->EmitPush(r0); // save the result
// r0: created object literal
for (int i = 0; i < node->properties()->length(); i++) {
// At the start of each iteration, the top of stack contains
// the newly created object literal.
ObjectLiteral::Property* property = node->properties()->at(i);
Literal* key = property->key();
Expression* value = property->value();
......@@ -2730,34 +2730,43 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
case ObjectLiteral::Property::MATERIALIZED_LITERAL:
if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
// else fall through
case ObjectLiteral::Property::COMPUTED: // fall through
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
LoadAndSpill(value);
frame_->EmitPop(r0);
__ mov(r2, Operand(key->handle()));
__ ldr(r1, frame_->Top()); // Load the receiver.
frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
break;
}
// else fall through
case ObjectLiteral::Property::PROTOTYPE: {
__ ldr(r0, frame_->Top());
frame_->EmitPush(r0); // dup the result
LoadAndSpill(key);
LoadAndSpill(value);
frame_->CallRuntime(Runtime::kSetProperty, 3);
// restore r0
__ ldr(r0, frame_->Top());
break;
}
case ObjectLiteral::Property::SETTER: {
__ ldr(r0, frame_->Top());
frame_->EmitPush(r0);
LoadAndSpill(key);
__ mov(r0, Operand(Smi::FromInt(1)));
frame_->EmitPush(r0);
LoadAndSpill(value);
frame_->CallRuntime(Runtime::kDefineAccessor, 4);
__ ldr(r0, frame_->Top());
break;
}
case ObjectLiteral::Property::GETTER: {
__ ldr(r0, frame_->Top());
frame_->EmitPush(r0);
LoadAndSpill(key);
__ mov(r0, Operand(Smi::FromInt(0)));
frame_->EmitPush(r0);
LoadAndSpill(value);
frame_->CallRuntime(Runtime::kDefineAccessor, 4);
__ ldr(r0, frame_->Top());
break;
}
}
......@@ -4388,11 +4397,11 @@ void Reference::SetValue(InitState init_state) {
Handle<String> name(GetName());
frame->EmitPop(r0);
// Setup the name register.
frame->EmitPop(r1);
__ mov(r2, Operand(name));
frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
frame->EmitPush(r0);
cgen_->UnloadReference(this);
set_unloaded();
break;
}
......
......@@ -128,7 +128,7 @@ void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
// Registers r0 and r2 contain objects that needs to be pushed on the
// Registers r0 and r2 contain objects that need to be pushed on the
// expression stack of the fake JS frame.
Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit());
}
......@@ -137,14 +137,14 @@ void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-arm.cc).
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
// Registers r0 and r2 contain objects that needs to be pushed on the
// Registers r0, r1, and r2 contain objects that need to be pushed on the
// expression stack of the fake JS frame.
Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit());
Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit());
}
......
......@@ -816,9 +816,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
if (key->handle()->IsSymbol()) {
VisitForValue(value, kAccumulator);
__ mov(r2, Operand(key->handle()));
__ ldr(r1, MemOperand(sp));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// StoreIC leaves the receiver on the stack.
break;
}
// Fall through.
......@@ -945,21 +945,17 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
ASSERT(!var->is_this());
// Assignment to a global variable. Use inline caching for the
// assignment. Right-hand-side value is passed in r0, variable name in
// r2, and the global object on the stack.
// r2, and the global object in r1.
__ mov(r2, Operand(var->name()));
__ ldr(ip, CodeGenerator::GlobalObject());
__ push(ip);
__ ldr(r1, CodeGenerator::GlobalObject());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
DropAndApply(1, context, r0);
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
__ push(result_register()); // Value.
__ mov(r1, Operand(var->name()));
__ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name.
__ CallRuntime(Runtime::kStoreContextSlot, 3);
Apply(context, r0);
} else if (var->slot() != NULL) {
Slot* slot = var->slot();
......@@ -986,13 +982,13 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
UNREACHABLE();
break;
}
Apply(context, result_register());
} else {
// Variables rewritten as properties are not treated as variables in
// assignments.
UNREACHABLE();
}
Apply(context, result_register());
}
......@@ -1016,6 +1012,12 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
if (expr->ends_initialization_block()) {
__ ldr(r1, MemOperand(sp));
} else {
__ pop(r1);
}
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
......@@ -1026,9 +1028,10 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
__ push(ip);
__ CallRuntime(Runtime::kToFastProperties, 1);
__ pop(r0);
DropAndApply(1, context_, r0);
} else {
Apply(context_, r0);
}
DropAndApply(1, context_, r0);
}
......@@ -1548,15 +1551,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
case NAMED_PROPERTY: {
__ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
__ pop(r1);
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
if (expr->is_postfix()) {
__ Drop(1); // Result is on the stack under the receiver.
if (context_ != Expression::kEffect) {
ApplyTOS(context_);
}
} else {
DropAndApply(1, context_, r0);
Apply(context_, r0);
}
break;
}
......
......@@ -791,13 +791,12 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
// Get the receiver from the stack and probe the stub cache.
__ ldr(r1, MemOperand(sp));
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
NOT_IN_LOOP,
MONOMORPHIC);
......@@ -811,13 +810,13 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
void StoreIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
__ ldr(r3, MemOperand(sp)); // copy receiver
__ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
__ push(r1);
__ stm(db_w, sp, r2.bit() | r0.bit());
// Perform tail call to the entry.
__ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1);
......
......@@ -258,8 +258,9 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
// Generate StoreField code, value is passed in r0 register.
// After executing generated code, the receiver_reg and name_reg
// may be clobbered.
// When leaving generated code after success, the receiver_reg and name_reg
// may be clobbered. Upon branch to miss_label, the receiver and name
// registers have their original values.
void StubCompiler::GenerateStoreField(MacroAssembler* masm,
JSObject* object,
int index,
......@@ -525,9 +526,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
// Note: starting a frame here makes GC aware of pointers pushed below.
__ EnterInternalFrame();
if (lookup->type() == CALLBACKS) {
__ push(receiver);
}
__ push(receiver);
__ push(holder);
__ push(name_);
......@@ -548,10 +547,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
__ bind(&interceptor_failed);
__ pop(name_);
__ pop(holder);
if (lookup->type() == CALLBACKS) {
__ pop(receiver);
}
__ pop(receiver);
__ LeaveInternalFrame();
......@@ -1208,24 +1204,19 @@ Object* StoreStubCompiler::CompileStoreField(JSObject* object,
String* name) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
Label miss;
// Get the receiver from the stack.
__ ldr(r3, MemOperand(sp, 0 * kPointerSize));
// name register might be clobbered.
GenerateStoreField(masm(),
object,
index,
transition,
r3, r2, r1,
r1, r2, r3,
&miss);
__ bind(&miss);
__ mov(r2, Operand(Handle<String>(name))); // restore name
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
__ Jump(ic, RelocInfo::CODE_TARGET);
......@@ -1239,39 +1230,33 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
String* name) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
Label miss;
// Get the object from the stack.
__ ldr(r3, MemOperand(sp, 0 * kPointerSize));
// Check that the object isn't a smi.
__ tst(r3, Operand(kSmiTagMask));
__ tst(r1, Operand(kSmiTagMask));
__ b(eq, &miss);
// Check that the map of the object hasn't changed.
__ ldr(r1, FieldMemOperand(r3, HeapObject::kMapOffset));
__ cmp(r1, Operand(Handle<Map>(object->map())));
__ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
__ cmp(r3, Operand(Handle<Map>(object->map())));
__ b(ne, &miss);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(r3, r1, &miss);
__ CheckAccessGlobalProxy(r1, r3, &miss);
}
// Stub never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
__ ldr(ip, MemOperand(sp)); // receiver
__ push(ip);
__ push(r1); // receiver
__ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback info
__ push(ip);
__ push(r2); // name
__ push(r0); // value
__ stm(db_w, sp, ip.bit() | r2.bit() | r0.bit());
// Do tail-call to the runtime system.
ExternalReference store_callback_property =
......@@ -1292,37 +1277,33 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
String* name) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
Label miss;
// Get the object from the stack.
__ ldr(r3, MemOperand(sp, 0 * kPointerSize));
// Check that the object isn't a smi.
__ tst(r3, Operand(kSmiTagMask));
__ tst(r1, Operand(kSmiTagMask));
__ b(eq, &miss);
// Check that the map of the object hasn't changed.
__ ldr(r1, FieldMemOperand(r3, HeapObject::kMapOffset));
__ cmp(r1, Operand(Handle<Map>(receiver->map())));
__ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
__ cmp(r3, Operand(Handle<Map>(receiver->map())));
__ b(ne, &miss);
// Perform global security token check if needed.
if (receiver->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(r3, r1, &miss);
__ CheckAccessGlobalProxy(r1, r3, &miss);
}
// Stub never generated for non-global objects that require access
// Stub is never generated for non-global objects that require access
// checks.
ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
__ ldr(ip, MemOperand(sp)); // receiver
__ push(ip);
__ push(r2); // name
__ push(r0); // value
__ push(r1); // receiver.
__ push(r2); // name.
__ push(r0); // value.
// Do tail-call to the runtime system.
ExternalReference store_ic_property =
......@@ -1344,14 +1325,13 @@ Object* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
String* name) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
// -- r2 : name
// -- lr : return address
// -- [sp] : receiver
// -----------------------------------
Label miss;
// 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);
......@@ -1360,12 +1340,12 @@ Object* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
__ mov(r2, Operand(Handle<JSGlobalPropertyCell>(cell)));
__ str(r0, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset));
__ IncrementCounter(&Counters::named_store_global_inline, 1, r1, r3);
__ IncrementCounter(&Counters::named_store_global_inline, 1, r4, r3);
__ Ret();
// Handle store cache miss.
__ bind(&miss);
__ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r1, r3);
__ IncrementCounter(&Counters::named_store_global_inline_miss, 1, r4, r3);
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
__ Jump(ic, RelocInfo::CODE_TARGET);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment