Revision: 3537
Author: [email protected]
Date: Tue Jan  5 04:02:18 2010
Log: Use cmov instructions to avoid some conditional branches in stub code.

This change improves the ConstructStub and the ArgumentsAccessStub slightly
by using the cmov instruction (if available) to eliminate a
conditional branch. It only applies to the IA-32 and X64 platforms.


Review URL: http://codereview.chromium.org/519035
http://code.google.com/p/v8/source/detail?r=3537

Modified:
  /branches/bleeding_edge/src/ia32/codegen-ia32.cc
  /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
  /branches/bleeding_edge/src/x64/codegen-x64.cc
  /branches/bleeding_edge/src/x64/stub-cache-x64.cc

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Tue Jan  5 01:38:02  
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Tue Jan  5 04:02:18  
2010
@@ -7733,20 +7733,24 @@

  void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
    // Check if the calling frame is an arguments adaptor frame.
-  Label adaptor;
    __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
    __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
    __ cmp(Operand(ecx),  
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
-  __ j(equal, &adaptor);
-
-  // Nothing to do: The formal number of parameters has already been
-  // passed in register eax by calling function. Just return it.
-  __ ret(0);

    // Arguments adaptor case: Read the arguments length from the
    // adaptor frame and return it.
-  __ bind(&adaptor);
-  __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  // Otherwise nothing to do: The number of formal parameters has already  
been
+  // passed in register eax by calling function. Just return it.
+  if (CpuFeatures::IsSupported(CMOV)) {
+    CpuFeatures::Scope use_cmov(CMOV);
+    __ cmov(equal, eax,
+            Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  } else {
+    Label exit;
+    __ j(not_equal, &exit);
+    __ mov(eax, Operand(edx,  
ArgumentsAdaptorFrameConstants::kLengthOffset));
+    __ bind(&exit);
+  }
    __ ret(0);
  }

=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Sun Dec 20 00:40:13  
2009
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Jan  5 04:02:18  
2010
@@ -1900,17 +1900,23 @@
    // depending on the this.x = ...; assignment in the function.
    for (int i = 0; i < shared->this_property_assignments_count(); i++) {
      if (shared->IsThisPropertyAssignmentArgument(i)) {
-      Label not_passed;
-      // Set the property to undefined.
-      __ mov(Operand(edx, i * kPointerSize), edi);
        // Check if the argument assigned to the property is actually passed.
+      // If argument is not passed the property is set to undefined,
+      // otherwise find it on the stack.
        int arg_number = shared->GetThisPropertyAssignmentArgument(i);
+      __ mov(ebx, edi);
        __ cmp(eax, arg_number);
-      __ j(below_equal, &not_passed);
-      // Argument passed - find it on the stack.
-      __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
+      if (CpuFeatures::IsSupported(CMOV)) {
+        CpuFeatures::Scope use_cmov(CMOV);
+        __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
+      } else {
+        Label not_passed;
+        __ j(below_equal, &not_passed);
+        __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
+        __ bind(&not_passed);
+      }
+      // Store value in the property.
        __ mov(Operand(edx, i * kPointerSize), ebx);
-      __ bind(&not_passed);
      } else {
        // Set the property to the constant value.
        Handle<Object>  
constant(shared->GetThisPropertyAssignmentConstant(i));
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue Jan  5 01:38:02 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue Jan  5 04:02:18 2010
@@ -6594,16 +6594,13 @@
    __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
    __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
                  Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
-  __ j(equal, &adaptor);
-
-  // Nothing to do: The formal number of parameters has already been
-  // passed in register rax by calling function. Just return it.
-  __ ret(0);

    // Arguments adaptor case: Read the arguments length from the
    // adaptor frame and return it.
-  __ bind(&adaptor);
-  __ movq(rax, Operand(rdx,  
ArgumentsAdaptorFrameConstants::kLengthOffset));
+  // Otherwise nothing to do: The number of formal parameters has already  
been
+  // passed in register eax by calling function. Just return it.
+  __ cmovq(equal, rax,
+           Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
    __ ret(0);
  }

=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc   Wed Dec 16 23:35:12  
2009
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc   Tue Jan  5 04:02:18  
2010
@@ -1827,17 +1827,15 @@
    // depending on the this.x = ...; assignment in the function.
    for (int i = 0; i < shared->this_property_assignments_count(); i++) {
      if (shared->IsThisPropertyAssignmentArgument(i)) {
-      Label not_passed;
-      // Set the property to undefined.
-      __ movq(Operand(r9, i * kPointerSize), r8);
        // Check if the argument assigned to the property is actually passed.
+      // If argument is not passed the property is set to undefined,
+      // otherwise find it on the stack.
        int arg_number = shared->GetThisPropertyAssignmentArgument(i);
+      __ movq(rbx, r8);
        __ cmpq(rax, Immediate(arg_number));
-      __ j(below_equal, &not_passed);
-      // Argument passed - find it on the stack.
-      __ movq(rbx, Operand(rcx, arg_number * -kPointerSize));
+      __ cmovq(above, rbx, Operand(rcx, arg_number * -kPointerSize));
+      // Store value in the property.
        __ movq(Operand(r9, i * kPointerSize), rbx);
-      __ bind(&not_passed);
      } else {
        // Set the property to the constant value.
        Handle<Object>  
constant(shared->GetThisPropertyAssignmentConstant(i));

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

Reply via email to