Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 1961) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -5415,24 +5415,29 @@ |
} else { |
// Inline the inobject property case. |
Comment cmnt(masm, "[ Inlined named property load"); |
+ DeferredReferenceGetNamedValue* deferred = |
+ new DeferredReferenceGetNamedValue(cgen_, GetName()); |
Result receiver = cgen_->frame()->Pop(); |
receiver.ToRegister(); |
- // Preallocate the value register to ensure that there is no |
- // spill emitted between the patch site label and the offset in |
- // the load instruction and that all frames reaching the |
- // deferred code are identical. |
- Result value = cgen_->allocator()->Allocate(); |
- ASSERT(value.is_valid()); |
+ // Try to preallocate the value register so that all frames |
+ // reaching the deferred code are identical. |
+ Result value = cgen_->allocator()->AllocateWithoutSpilling(); |
// Check that the receiver is a heap object. |
__ test(receiver.reg(), Immediate(kSmiTagMask)); |
- DeferredReferenceGetNamedValue* deferred = |
- new DeferredReferenceGetNamedValue(cgen_, GetName()); |
- deferred->SetEntryFrame(&receiver); |
+ if (value.is_valid()) deferred->SetEntryFrame(&receiver); |
deferred->enter()->Branch(zero, &receiver, not_taken); |
+ // Do not allocate the value register after binding the patch |
+ // site label. The distance from the patch site to the offset |
+ // must be constant. |
+ if (!value.is_valid()) { |
+ value = cgen_->allocator()->Allocate(); |
+ ASSERT(value.is_valid()); |
+ } |
+ |
__ bind(deferred->patch_site()); |
// This is the map check instruction that will be patched (so we can't |
// use the double underscore macro that may insert instructions). |
@@ -5482,6 +5487,14 @@ |
key.ToRegister(); |
receiver.ToRegister(); |
+ // Try to preallocate the elements and index scratch registers |
+ // so that all frames reaching the deferred code are identical. |
+ Result elements = cgen_->allocator()->AllocateWithoutSpilling(); |
+ Result index = cgen_->allocator()->AllocateWithoutSpilling(); |
+ if (elements.is_valid() && index.is_valid()) { |
+ deferred->SetEntryFrame(&receiver, &key); |
+ } |
+ |
// Check that the receiver is not a smi (only needed if this |
// is not a load from the global context) and that it has the |
// expected map. |
@@ -5505,8 +5518,10 @@ |
// Get the elements array from the receiver and check that it |
// is not a dictionary. |
- Result elements = cgen_->allocator()->Allocate(); |
- ASSERT(elements.is_valid()); |
+ if (!elements.is_valid()) { |
+ elements = cgen_->allocator()->Allocate(); |
+ ASSERT(elements.is_valid()); |
+ } |
__ mov(elements.reg(), |
FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
__ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
@@ -5515,8 +5530,10 @@ |
// Shift the key to get the actual index value and check that |
// it is within bounds. |
- Result index = cgen_->allocator()->Allocate(); |
- ASSERT(index.is_valid()); |
+ if (!index.is_valid()) { |
+ index = cgen_->allocator()->Allocate(); |
+ ASSERT(index.is_valid()); |
+ } |
__ mov(index.reg(), key.reg()); |
__ sar(index.reg(), kSmiTagSize); |
__ cmp(index.reg(), |