Author: [email protected]
Date: Fri May 15 05:43:00 2009
New Revision: 1968

Modified:
    branches/bleeding_edge/src/codegen-inl.h
    branches/bleeding_edge/src/codegen.h
    branches/bleeding_edge/src/ia32/codegen-ia32.cc

Log:
Try to preallocate the scratch registers used for inlined keyed loads
to allow fast entry to the deferred code if possible.

Review URL: http://codereview.chromium.org/113457

Modified: branches/bleeding_edge/src/codegen-inl.h
==============================================================================
--- branches/bleeding_edge/src/codegen-inl.h    (original)
+++ branches/bleeding_edge/src/codegen-inl.h    Fri May 15 05:43:00 2009
@@ -43,6 +43,16 @@
  }


+void DeferredCode::SetEntryFrame(Result* arg0, Result* arg1) {
+  ASSERT(generator()->has_valid_frame());
+  generator()->frame()->Push(arg0);
+  generator()->frame()->Push(arg1);
+  enter()->set_entry_frame(new VirtualFrame(generator()->frame()));
+  *arg1 = generator()->frame()->Pop();
+  *arg0 = generator()->frame()->Pop();
+}
+
+
  //  
-----------------------------------------------------------------------------
  // Support for "structured" code comments.
  //

Modified: branches/bleeding_edge/src/codegen.h
==============================================================================
--- branches/bleeding_edge/src/codegen.h        (original)
+++ branches/bleeding_edge/src/codegen.h        Fri May 15 05:43:00 2009
@@ -148,6 +148,7 @@
    // results).  This is optional, but should be done before branching
    // or jumping to the deferred code.
    inline void SetEntryFrame(Result* arg);
+  inline void SetEntryFrame(Result* arg0, Result* arg1);

    JumpTarget* enter() { return &enter_; }


Modified: branches/bleeding_edge/src/ia32/codegen-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/codegen-ia32.cc     (original)
+++ branches/bleeding_edge/src/ia32/codegen-ia32.cc     Fri May 15 05:43:00 2009
@@ -5415,24 +5415,30 @@
        } 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();
+        if (value.is_valid()) {
+          deferred->SetEntryFrame(&receiver);
+        }

          // Check that the receiver is a heap object.
          __ test(receiver.reg(), Immediate(kSmiTagMask));
-
-        DeferredReferenceGetNamedValue* deferred =
-            new DeferredReferenceGetNamedValue(cgen_, GetName());
-        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 +5488,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 +5519,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 +5531,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(),

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to