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

Unified Diff: src/arm/codegen-arm.cc

Issue 2116003: ARM: Pass arguments to keyed store IC in registers... (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/debug-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 4667)
+++ src/arm/codegen-arm.cc (working copy)
@@ -3563,9 +3563,7 @@
// Perform the assignment. It is safe to ignore constants here.
ASSERT(node->op() != Token::INIT_CONST);
CodeForSourcePosition(node->position());
- frame_->PopToR0();
EmitKeyedStore(prop->key()->type());
- frame_->Drop(2); // Key and receiver are left on the stack.
frame_->EmitPush(r0);
// Stack layout:
@@ -5519,11 +5517,19 @@
class DeferredReferenceSetKeyedValue: public DeferredCode {
public:
- DeferredReferenceSetKeyedValue() {
+ DeferredReferenceSetKeyedValue(Register value,
+ Register key,
+ Register receiver)
+ : value_(value), key_(key), receiver_(receiver) {
set_comment("[ DeferredReferenceSetKeyedValue");
}
virtual void Generate();
+
+ private:
+ Register value_;
+ Register key_;
+ Register receiver_;
};
@@ -5534,10 +5540,17 @@
__ IncrementCounter(
&Counters::keyed_store_inline_miss, 1, scratch1, scratch2);
+ // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic
+ // calling convention.
+ if (value_.is(r1)) {
+ __ Swap(r0, r1, ip);
+ }
+ ASSERT(receiver_.is(r2));
+
// The rest of the instructions in the deferred code must be together.
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
- // Call keyed load IC. It has receiver amd key on the stack and the value to
- // store in r0.
+ // Call keyed store IC. It has the arguments value, key and receiver in r0,
+ // r1 and r2.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
@@ -5697,7 +5710,7 @@
__ mov(r0, scratch1);
// Make sure that the expected number of instructions are generated.
- ASSERT_EQ(kInlinedKeyedLoadInstructionsAfterPatchSize,
+ ASSERT_EQ(kInlinedKeyedLoadInstructionsAfterPatch,
masm_->InstructionsGeneratedSince(&check_inlined_codesize));
}
@@ -5707,78 +5720,86 @@
void CodeGenerator::EmitKeyedStore(StaticType* key_type) {
- VirtualFrame::SpilledScope scope(frame_);
// Generate inlined version of the keyed store if the code is in a loop
// and the key is likely to be a smi.
if (loop_nesting() > 0 && key_type->IsLikelySmi()) {
// Inline the keyed store.
Comment cmnt(masm_, "[ Inlined store to keyed property");
- DeferredReferenceSetKeyedValue* deferred =
- new DeferredReferenceSetKeyedValue();
+ Register scratch1 = VirtualFrame::scratch0();
+ Register scratch2 = VirtualFrame::scratch1();
+ Register scratch3 = r3;
// Counter will be decremented in the deferred code. Placed here to avoid
// having it in the instruction stream below where patching will occur.
__ IncrementCounter(&Counters::keyed_store_inline, 1,
- frame_->scratch0(), frame_->scratch1());
+ scratch1, scratch2);
+ // Load the value, key and receiver from the stack.
+ Register value = frame_->PopToRegister();
+ Register key = frame_->PopToRegister(value);
+ Register receiver = r2;
+ frame_->EmitPop(receiver);
+ VirtualFrame::SpilledScope spilled(frame_);
+
+ // The deferred code expects value, key and receiver in registers.
+ DeferredReferenceSetKeyedValue* deferred =
+ new DeferredReferenceSetKeyedValue(value, key, receiver);
+
// Check that the value is a smi. As this inlined code does not set the
// write barrier it is only possible to store smi values.
- __ tst(r0, Operand(kSmiTagMask));
+ __ tst(value, Operand(kSmiTagMask));
deferred->Branch(ne);
- // Load the key and receiver from the stack.
- __ ldr(r1, MemOperand(sp, 0));
- __ ldr(r2, MemOperand(sp, kPointerSize));
-
// Check that the key is a smi.
- __ tst(r1, Operand(kSmiTagMask));
+ __ tst(key, Operand(kSmiTagMask));
deferred->Branch(ne);
// Check that the receiver is a heap object.
- __ tst(r2, Operand(kSmiTagMask));
+ __ tst(receiver, Operand(kSmiTagMask));
deferred->Branch(eq);
// Check that the receiver is a JSArray.
- __ CompareObjectType(r2, r3, r3, JS_ARRAY_TYPE);
+ __ CompareObjectType(receiver, scratch1, scratch1, JS_ARRAY_TYPE);
deferred->Branch(ne);
// Check that the key is within bounds. Both the key and the length of
// the JSArray are smis. Use unsigned comparison to handle negative keys.
- __ ldr(r3, FieldMemOperand(r2, JSArray::kLengthOffset));
- __ cmp(r3, r1);
+ __ ldr(scratch1, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ __ cmp(scratch1, key);
deferred->Branch(ls); // Unsigned less equal.
// The following instructions are the part of the inlined store keyed
// property code which can be patched. Therefore the exact number of
// instructions generated need to be fixed, so the constant pool is blocked
// while generating this code.
-#ifdef DEBUG
- int kInlinedKeyedStoreInstructions = 7;
- Label check_inlined_codesize;
- masm_->bind(&check_inlined_codesize);
-#endif
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
// Get the elements array from the receiver and check that it
// is not a dictionary.
- __ ldr(r3, FieldMemOperand(r2, JSObject::kElementsOffset));
- __ ldr(r4, FieldMemOperand(r3, JSObject::kMapOffset));
+ __ ldr(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ ldr(scratch2, FieldMemOperand(scratch1, JSObject::kMapOffset));
// Read the fixed array map from the constant pool (not from the root
// array) so that the value can be patched. When debugging, we patch this
// comparison to always fail so that we will hit the IC call in the
// deferred code which will allow the debugger to break for fast case
// stores.
- __ mov(r5, Operand(Factory::fixed_array_map()));
- __ cmp(r4, r5);
+#ifdef DEBUG
+ Label check_inlined_codesize;
+ masm_->bind(&check_inlined_codesize);
+#endif
+ __ mov(scratch3, Operand(Factory::fixed_array_map()));
+ __ cmp(scratch2, scratch3);
deferred->Branch(ne);
// Store the value.
- __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ str(r0, MemOperand(r3, r1, LSL,
- kPointerSizeLog2 - (kSmiTagSize + kSmiShiftSize)));
+ __ add(scratch1, scratch1,
+ Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ str(value,
+ MemOperand(scratch1, key, LSL,
+ kPointerSizeLog2 - (kSmiTagSize + kSmiShiftSize)));
// Make sure that the expected number of instructions are generated.
- ASSERT_EQ(kInlinedKeyedStoreInstructions,
+ ASSERT_EQ(kInlinedKeyedStoreInstructionsAfterPatch,
masm_->InstructionsGeneratedSince(&check_inlined_codesize));
}
@@ -5894,16 +5915,13 @@
}
case KEYED: {
- VirtualFrame::SpilledScope scope(frame);
Comment cmnt(masm, "[ Store to keyed Property");
Property* property = expression_->AsProperty();
ASSERT(property != NULL);
cgen_->CodeForSourcePosition(property->position());
-
- frame->EmitPop(r0); // Value.
cgen_->EmitKeyedStore(property->key()->type());
frame->EmitPush(r0);
- cgen_->UnloadReference(this);
+ set_unloaded();
break;
}
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698