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

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

Issue 1735007: Inline keyed load on ARM... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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/ic-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 4509)
+++ src/arm/codegen-arm.cc (working copy)
@@ -3703,7 +3703,7 @@
LoadAndSpill(property->obj());
LoadAndSpill(property->key());
- EmitKeyedLoad(false);
+ EmitKeyedLoad();
frame_->Drop(); // key
// Put the function below the receiver.
if (property->is_synthetic()) {
@@ -5250,7 +5250,7 @@
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop(1) instruction to indicate that the
// in-object has been inlined.
- __ nop(NAMED_PROPERTY_LOAD_INLINED);
+ __ nop(PROPERTY_LOAD_INLINED);
// Block the constant pool for one more instruction after leaving this
// constant pool block scope to include the branch instruction ending the
@@ -5260,6 +5260,37 @@
}
+class DeferredReferenceGetKeyedValue: public DeferredCode {
+ public:
+ DeferredReferenceGetKeyedValue() {
+ set_comment("[ DeferredReferenceGetKeyedValue");
+ }
+
+ virtual void Generate();
+};
+
+
+void DeferredReferenceGetKeyedValue::Generate() {
+ __ DecrementCounter(&Counters::keyed_load_inline, 1, r1, r2);
+ __ IncrementCounter(&Counters::keyed_load_inline_miss, 1, r1, 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 all arguments on the stack.
+ Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
+ __ Call(ic, RelocInfo::CODE_TARGET);
+ // The call must be followed by a nop instruction to indicate that the
+ // keyed load has been inlined.
+ __ nop(PROPERTY_LOAD_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.
+ __ BlockConstPoolFor(1);
+ }
+}
+
+
void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
Comment cmnt(masm(), "[ Load from named Property");
@@ -5269,7 +5300,7 @@
? RelocInfo::CODE_TARGET_CONTEXT
: RelocInfo::CODE_TARGET);
} else {
- // Inline the inobject property case.
+ // Inline the in-object property case.
Comment cmnt(masm(), "[ Inlined named property load");
DeferredReferenceGetNamedValue* deferred =
@@ -5304,7 +5335,7 @@
__ cmp(r2, r3);
deferred->Branch(ne);
- // Use initially use an invalid index. The index will be patched by the
+ // Initially use an invalid index. The index will be patched by the
// inline cache code.
__ ldr(r0, MemOperand(r1, 0));
@@ -5318,13 +5349,81 @@
}
-void CodeGenerator::EmitKeyedLoad(bool is_global) {
- Comment cmnt(masm_, "[ Load from keyed Property");
- Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
- RelocInfo::Mode rmode = is_global
- ? RelocInfo::CODE_TARGET_CONTEXT
- : RelocInfo::CODE_TARGET;
- frame_->CallCodeObject(ic, rmode, 0);
+void CodeGenerator::EmitKeyedLoad() {
+ if (loop_nesting() == 0) {
+ Comment cmnt(masm_, "[ Load from keyed property");
+ frame_->CallKeyedLoadIC();
+ } else {
+ // Inline the keyed load.
+ Comment cmnt(masm_, "[ Inlined load from keyed property");
+
+ DeferredReferenceGetKeyedValue* deferred =
+ new DeferredReferenceGetKeyedValue();
+
+ // 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_load_inline, 1,
+ frame_->scratch0(), frame_->scratch1());
+
+ // Load the receiver from the stack.
+ __ ldr(r0, MemOperand(sp, kPointerSize));
+
+ // Check that the receiver is a heap object.
+ __ tst(r0, Operand(kSmiTagMask));
+ deferred->Branch(eq);
+
+ // The following instructions are the inlined load keyed property. Parts
+ // of this code are patched, so the exact number of instructions generated
+ // need to be fixed. Therefore the constant pool is blocked while generating
+ // this code.
+#ifdef DEBUG
+ int kInlinedKeyedLoadInstructions = 20;
+ Label check_inlined_codesize;
+ masm_->bind(&check_inlined_codesize);
+#endif
+ { Assembler::BlockConstPoolScope block_const_pool(masm_);
+ // Check the map. The null map used below is patched by the inline cache
+ // code.
+ __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
+ __ mov(r2, Operand(Factory::null_value()));
+ __ cmp(r1, r2);
+ deferred->Branch(ne);
+
+ // Load the key from the stack.
+ __ ldr(r1, MemOperand(sp, 0));
+
+ // Check that the key is a smi.
+ __ tst(r1, Operand(kSmiTagMask));
+ deferred->Branch(ne);
+
+ // Get the elements array from the receiver and check that it
+ // is not a dictionary.
+ __ ldr(r2, FieldMemOperand(r0, JSObject::kElementsOffset));
+ __ ldr(r3, FieldMemOperand(r2, JSObject::kMapOffset));
+ __ LoadRoot(r4, Heap::kFixedArrayMapRootIndex);
+ __ cmp(r3, r4);
+ deferred->Branch(ne);
+
+ // Check that key is within bounds.
+ __ ldr(r3, FieldMemOperand(r2, FixedArray::kLengthOffset));
+ __ cmp(r3, Operand(r1, ASR, kSmiTagSize));
+ deferred->Branch(ls); // Unsigned less equal.
+
+ // Load and check that the result is not the hole (r1 is a smi).
+ __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
+ __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ ldr(r0, MemOperand(r2, r1, LSL,
+ kPointerSizeLog2 - (kSmiTagSize + kSmiShiftSize)));
+ __ cmp(r0, r3);
+ deferred->Branch(eq);
+
+ // Make sure that the expected number of instructions are generated.
+ ASSERT_EQ(kInlinedKeyedLoadInstructions,
+ masm_->InstructionsGeneratedSince(&check_inlined_codesize));
+ }
+
+ deferred->BindExit();
+ }
}
@@ -5383,12 +5482,8 @@
}
case KEYED: {
- // TODO(181): Implement inlined version of array indexing once
- // loop nesting is properly tracked on ARM.
ASSERT(property != NULL);
- Variable* var = expression_->AsVariableProxy()->AsVariable();
- ASSERT(var == NULL || var->is_global());
- cgen_->EmitKeyedLoad(var != NULL);
+ cgen_->EmitKeyedLoad();
cgen_->frame()->EmitPush(r0);
break;
}
« no previous file with comments | « 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