| 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(),
|
|
|