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

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

Issue 122035: Inline keyed stores if the code is in a loop and the key is likely to... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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 | « no previous file | src/objects.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc (revision 2140)
+++ src/ia32/codegen-ia32.cc (working copy)
@@ -5738,9 +5738,46 @@
}
+class DeferredReferenceSetKeyedValue: public DeferredCode {
+ public:
+ 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_;
+};
+
+
+void DeferredReferenceSetKeyedValue::Generate() {
+ __ IncrementCounter(&Counters::keyed_store_inline_miss, 1);
+ // Push receiver and key arguments on the stack.
+ __ push(receiver_);
+ __ push(key_);
+ // Move value argument to eax as expected by the IC stub.
+ if (!value_.is(eax)) __ mov(eax, value_);
+ // Call the IC stub.
+ Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
+ __ call(ic, RelocInfo::CODE_TARGET);
+ // Restore value (returned from store IC), key and receiver
+ // registers.
+ if (!value_.is(eax)) __ mov(value_, eax);
+ __ pop(key_);
+ __ pop(receiver_);
+}
+
+
#undef __
#define __ ACCESS_MASM(masm)
+
Handle<String> Reference::GetName() {
ASSERT(type_ == NAMED);
Property* property = expression_->AsProperty();
@@ -5859,7 +5896,7 @@
// a check against an invalid map. In the inline cache code, we
// patch the map check if appropriate.
if (cgen_->loop_nesting() > 0) {
- Comment cmnt(masm, "[ Inlined array index load");
+ Comment cmnt(masm, "[ Inlined load from keyed Property");
Result key = cgen_->frame()->Pop();
Result receiver = cgen_->frame()->Pop();
@@ -6000,9 +6037,10 @@
void Reference::SetValue(InitState init_state) {
ASSERT(cgen_->HasValidEntryRegisters());
ASSERT(!is_illegal());
+ MacroAssembler* masm = cgen_->masm();
switch (type_) {
case SLOT: {
- Comment cmnt(cgen_->masm(), "[ Store to Slot");
+ Comment cmnt(masm, "[ Store to Slot");
Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
ASSERT(slot != NULL);
cgen_->StoreToSlot(slot, init_state);
@@ -6010,7 +6048,7 @@
}
case NAMED: {
- Comment cmnt(cgen_->masm(), "[ Store to named Property");
+ Comment cmnt(masm, "[ Store to named Property");
cgen_->frame()->Push(GetName());
Result answer = cgen_->frame()->CallStoreIC();
cgen_->frame()->Push(&answer);
@@ -6018,9 +6056,93 @@
}
case KEYED: {
- Comment cmnt(cgen_->masm(), "[ Store to keyed Property");
- Result answer = cgen_->frame()->CallKeyedStoreIC();
- cgen_->frame()->Push(&answer);
+ Comment cmnt(masm, "[ Store to keyed Property");
+
+ // Generate inlined version of the keyed store if the code is in
+ // a loop and the key is likely to be a smi.
+ Property* property = expression()->AsProperty();
+ ASSERT(property != NULL);
+ SmiAnalysis* key_smi_analysis = property->key()->type();
+
+ if (cgen_->loop_nesting() > 0 && key_smi_analysis->IsLikelySmi()) {
+ Comment cmnt(masm, "[ Inlined store to keyed Property");
+
+ // Get the receiver, key and value into registers.
+ Result value = cgen_->frame()->Pop();
+ Result key = cgen_->frame()->Pop();
+ Result receiver = cgen_->frame()->Pop();
+
+ Result tmp = cgen_->allocator_->Allocate();
+ ASSERT(tmp.is_valid());
+
+ // Determine whether the value is a constant before putting it
+ // in a register.
+ bool value_is_constant = value.is_constant();
+
+ // Make sure that value, key and receiver are in registers.
+ value.ToRegister();
+ key.ToRegister();
+ receiver.ToRegister();
+
+ DeferredReferenceSetKeyedValue* deferred =
+ new DeferredReferenceSetKeyedValue(value.reg(),
+ key.reg(),
+ receiver.reg());
+
+ // Check that the value is a smi if it is not a constant. We
+ // can skip the write barrier for smis and constants.
+ if (!value_is_constant) {
+ __ test(value.reg(), Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ }
+
+ // Check that the key is a non-negative smi.
+ __ test(key.reg(), Immediate(kSmiTagMask | 0x80000000));
+ deferred->Branch(not_zero);
+
+ // Check that the receiver is not a smi.
+ __ test(receiver.reg(), Immediate(kSmiTagMask));
+ deferred->Branch(zero);
+
+ // Check that the receiver is a JSArray.
+ __ mov(tmp.reg(),
+ FieldOperand(receiver.reg(), HeapObject::kMapOffset));
+ __ movzx_b(tmp.reg(),
+ FieldOperand(tmp.reg(), Map::kInstanceTypeOffset));
+ __ cmp(tmp.reg(), JS_ARRAY_TYPE);
+ deferred->Branch(not_equal);
+
+ // Check that the key is within bounds. Both the key and the
+ // length of the JSArray are smis.
+ __ cmp(key.reg(),
+ FieldOperand(receiver.reg(), JSArray::kLengthOffset));
+ deferred->Branch(greater_equal);
+
+ // Get the elements array from the receiver and check that it
+ // is not a dictionary.
+ __ mov(tmp.reg(),
+ FieldOperand(receiver.reg(), JSObject::kElementsOffset));
+ __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
+ Immediate(Factory::hash_table_map()));
+ deferred->Branch(equal);
+
+ // Store the value.
+ __ mov(Operand(tmp.reg(),
+ key.reg(),
+ times_2,
+ Array::kHeaderSize - kHeapObjectTag),
+ value.reg());
+ __ IncrementCounter(&Counters::keyed_store_inline, 1);
+
+ deferred->BindExit();
+
+ cgen_->frame()->Push(&receiver);
+ cgen_->frame()->Push(&key);
+ cgen_->frame()->Push(&value);
+ } else {
+ Result answer = cgen_->frame()->CallKeyedStoreIC();
+ cgen_->frame()->Push(&answer);
+ }
break;
}
« no previous file with comments | « no previous file | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698