Version 2.4.0.

Fix bug in Object.freeze and Object.seal when Array.prototype or Object.prototype is changed (issue 842).

Update Array.splice to follow Safari and Firefox when called with zero arguments.

Fix a missing live register when breaking at keyed loads on ARM.

Performance improvements on all platforms.


git-svn-id: http://v8.googlecode.com/svn/trunk@5388 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 65c1e2a..59cbad9 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -30,6 +30,7 @@
 #include "codegen-inl.h"
 #include "compiler.h"
 #include "full-codegen.h"
+#include "macro-assembler.h"
 #include "scopes.h"
 #include "stub-cache.h"
 #include "debug.h"
@@ -516,18 +517,21 @@
 
 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
   Comment cmnt(masm_, "[ BinaryOperation");
+  Token::Value op = expr->op();
+  Expression* left = expr->left();
+  Expression* right = expr->right();
 
-  OverwriteMode overwrite_mode = NO_OVERWRITE;
-  if (expr->left()->ResultOverwriteAllowed()) {
-    overwrite_mode = OVERWRITE_LEFT;
-  } else if (expr->right()->ResultOverwriteAllowed()) {
-    overwrite_mode = OVERWRITE_RIGHT;
+  OverwriteMode mode = NO_OVERWRITE;
+  if (left->ResultOverwriteAllowed()) {
+    mode = OVERWRITE_LEFT;
+  } else if (right->ResultOverwriteAllowed()) {
+    mode = OVERWRITE_RIGHT;
   }
 
-  switch (expr->op()) {
+  switch (op) {
     case Token::COMMA:
-      VisitForEffect(expr->left());
-      Visit(expr->right());
+      VisitForEffect(left);
+      Visit(right);
       break;
 
     case Token::OR:
@@ -545,12 +549,31 @@
     case Token::BIT_XOR:
     case Token::SHL:
     case Token::SHR:
-    case Token::SAR:
-      VisitForValue(expr->left(), kStack);
-      VisitForValue(expr->right(), kAccumulator);
+    case Token::SAR: {
+      // Figure out if either of the operands is a constant.
+      ConstantOperand constant = ShouldInlineSmiCase(op)
+          ? GetConstantOperand(op, left, right)
+          : kNoConstants;
+
+      // Load only the operands that we need to materialize.
+      if (constant == kNoConstants) {
+        VisitForValue(left, kStack);
+        VisitForValue(right, kAccumulator);
+      } else if (constant == kRightConstant) {
+        VisitForValue(left, kAccumulator);
+      } else {
+        ASSERT(constant == kLeftConstant);
+        VisitForValue(right, kAccumulator);
+      }
+
       SetSourcePosition(expr->position());
-      EmitBinaryOp(expr->op(), context_, overwrite_mode);
+      if (ShouldInlineSmiCase(op)) {
+        EmitInlineSmiBinaryOp(expr, op, context_, mode, left, right, constant);
+      } else {
+        EmitBinaryOp(op, context_, mode);
+      }
       break;
+    }
 
     default:
       UNREACHABLE();