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

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

Issue 2878043: Port inlined in-object property stores to ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 5 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
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 5104)
+++ src/arm/codegen-arm.cc (working copy)
@@ -6207,6 +6207,48 @@
}
+class DeferredReferenceSetNamedValue: public DeferredCode {
+ public:
+ DeferredReferenceSetNamedValue(Register value,
+ Register receiver,
+ Handle<String> name)
+ : value_(value), receiver_(receiver), name_(name) {
+ set_comment("[ DeferredReferenceSetNamedValue");
+ }
+
+ virtual void Generate();
+
+ private:
+ Register value_;
+ Register receiver_;
+ Handle<String> name_;
+};
+
+
+void DeferredReferenceSetNamedValue::Generate() {
+ // Ensure value in r0, receiver in r1 to match store ic calling
+ // convention.
+ ASSERT(value_.is(r0) && receiver_.is(r1));
+ __ mov(r2, Operand(name_));
+
+ // The rest of the instructions in the deferred code must be together.
+ { Assembler::BlockConstPoolScope block_const_pool(masm_);
+ // Call keyed store IC. It has the arguments value, key and receiver in r0,
+ // r1 and r2.
+ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+ __ Call(ic, RelocInfo::CODE_TARGET);
+ // The call must be followed by a nop instruction to indicate that the
+ // named store has been inlined.
+ __ nop(PROPERTY_ACCESS_INLINED);
+
+ // Block the constant pool for one more instruction after leaving this
+ // constant pool block scope to include the branch instruction ending the
+ // deferred code.
William Hesse 2010/07/22 08:11:23 It looked like some support for register allocatio
Mads Ager (chromium) 2010/07/22 08:28:53 That is a good question. This follows the pattern
+ __ BlockConstPoolFor(1);
+ }
+}
+
+
// Consumes the top of stack (the receiver) and pushes the result instead.
void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
@@ -6277,11 +6319,61 @@
void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
#ifdef DEBUG
- int expected_height = frame_->height() - (is_contextual ? 1 : 2);
+ int expected_height = frame()->height() - (is_contextual ? 1 : 2);
#endif
- frame_->CallStoreIC(name, is_contextual);
- ASSERT_EQ(expected_height, frame_->height());
+ Result result;
+ if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
+ frame()->CallStoreIC(name, is_contextual);
+ } else {
+ // Inline the in-object property case.
+ JumpTarget slow, done;
+
+ // Get the value and receiver from the stack.
+ frame()->PopToR0();
+ Register value = r0;
+ frame()->PopToR1();
+ Register receiver = r1;
+
+ DeferredReferenceSetNamedValue* deferred =
+ new DeferredReferenceSetNamedValue(value, receiver, name);
+
+ // Check that the receiver is a heap object.
+ __ tst(receiver, Operand(kSmiTagMask));
+ deferred->Branch(eq);
+
+ // The following instructions are the part of the inlined
+ // in-object property store code which can be patched. Therefore
+ // the exact number of instructions generated must be fixed, so
+ // the constant pool is blocked while generating this code.
+ { Assembler::BlockConstPoolScope block_const_pool(masm_);
+ Register scratch0 = VirtualFrame::scratch0();
+ Register scratch1 = VirtualFrame::scratch1();
+
+ // Check the map. Initially use an invalid map to force a
+ // failure. The map check will be patched in the runtime system.
+ __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
+
+#ifdef DEBUG
+ Label check_inlined_codesize;
+ masm_->bind(&check_inlined_codesize);
+#endif
+ __ mov(scratch0, Operand(Factory::null_value()));
Rodolph Perfetta 2010/07/21 14:51:15 On ARM it should probably be LoadRoot(scratch0, He
Mads Ager (chromium) 2010/07/22 07:29:54 Normally, yes. In this specific case I actually wa
+ __ cmp(scratch0, scratch1);
+ deferred->Branch(ne);
+
+ int offset = 0;
+ __ str(value, MemOperand(receiver, offset));
+
+ // Update the write barrier.
+ __ RecordWrite(receiver, Operand(offset), scratch0, scratch1);
+ // Make sure that the expected number of instructions are generated.
+ ASSERT_EQ(GetInlinedNamedStoreInstructionsAfterPatch(),
+ masm_->InstructionsGeneratedSince(&check_inlined_codesize));
+ }
+ deferred->BindExit();
+ }
+ ASSERT_EQ(expected_height, frame()->height());
}
« src/arm/assembler-arm.cc ('K') | « src/arm/codegen-arm.h ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698