Author: [email protected]
Date: Wed Feb 18 01:17:22 2009
New Revision: 1294

Modified:
    branches/experimental/toiger/src/codegen-ia32.cc
    branches/experimental/toiger/src/codegen-ia32.h
    branches/experimental/toiger/src/register-allocator-ia32.cc
    branches/experimental/toiger/src/virtual-frame-ia32.cc

Log:
Change compiler to safely write unsafe smis when they are spilled from
the frame, not when they are pushed onto frame.  Also fixes unrelated
flaw in virtual-frame.cc.

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

Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc    (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc    Wed Feb 18 01:17:22  
2009
@@ -1317,7 +1317,13 @@
        is_smi.Bind(&left_side, &right_side);
        left_side.ToRegister();
        // Test smi equality and comparison by signed int comparison.
+      if (IsUnsafeSmi(right_side.handle())) {
+        right_side.ToRegister();
+        ASSERT(right_side.is_valid());
+        __ cmp(left_side.reg(), Operand(right_side.reg()));
+      } else {
        __ cmp(Operand(left_side.reg()), Immediate(right_side.handle()));
+      }
        left_side.Unuse();
        right_side.Unuse();
        dest->Split(cc);
@@ -3045,18 +3051,23 @@

  void CodeGenerator::VisitLiteral(Literal* node) {
    Comment cmnt(masm_, "[ Literal");
-  if (node->handle()->IsSmi() && !IsInlineSmi(node)) {
-    // To prevent long attacker-controlled byte sequences in code, larger
-    // Smis are loaded in two steps via a temporary register.
-    Result temp = allocator_->Allocate();
-    ASSERT(temp.is_valid());
-    int bits = reinterpret_cast<int>(*node->handle());
-    __ Set(temp.reg(), Immediate(bits & 0x0000FFFF));
-    __ xor_(temp.reg(), bits & 0xFFFF0000);
-    frame_->Push(&temp);
-  } else {
      frame_->Push(node->handle());
    }
+
+
+void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) {
+  ASSERT(target.is_valid());
+  ASSERT(value->IsSmi());
+  int bits = reinterpret_cast<int>(*value);
+  __ Set(target, Immediate(bits & 0x0000FFFF));
+  __ xor_(target, bits & 0xFFFF0000);
+}
+
+
+bool CodeGenerator::IsUnsafeSmi(Handle<Object> value) {
+  if (!value->IsSmi()) return false;
+  int int_value = Smi::cast(*value)->value();
+  return !is_intn(int_value, kMaxSmiInlinedBits);
  }



Modified: branches/experimental/toiger/src/codegen-ia32.h
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.h     (original)
+++ branches/experimental/toiger/src/codegen-ia32.h     Wed Feb 18 01:17:22 2009
@@ -464,9 +464,15 @@
                    bool strict,
                    ControlDestination* destination);

-  // Inline small integer literals. To prevent long attacker-controlled  
byte
-  // sequences, we only inline small Smis.
+  // To prevent long attacker-controlled byte sequences, integer constants
+  // from the JavaScript source are loaded in two parts if they are larger
+  // than 16 bits.
    static const int kMaxSmiInlinedBits = 16;
+  bool IsUnsafeSmi(Handle<Object> value);
+  // Load an integer constant x into a register target using
+  // at most 16 bits of user-controlled data per assembly operation.
+  void LoadUnsafeSmi(Register target, Handle<Object> value);
+
    bool IsInlineSmi(Literal* literal);
    void SmiComparison(Condition cc,  Handle<Object> value, bool strict);
    void SmiOperation(Token::Value op,
@@ -615,6 +621,7 @@
    friend class VirtualFrame;
    friend class JumpTarget;
    friend class Reference;
+  friend class Result;

    DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
  };

Modified: branches/experimental/toiger/src/register-allocator-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/register-allocator-ia32.cc (original)
+++ branches/experimental/toiger/src/register-allocator-ia32.cc Wed Feb 18  
01:17:22 2009
@@ -40,7 +40,11 @@
    if (is_constant()) {
      Result fresh = cgen_->allocator()->Allocate();
      ASSERT(fresh.is_valid());
-    cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+    if (cgen_->IsUnsafeSmi(handle())) {
+      cgen_->LoadUnsafeSmi(fresh.reg(), handle());
+    } else {
+      cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+    }
      // This result becomes a copy of the fresh one.
      *this = fresh;
    }
@@ -57,7 +61,11 @@
        cgen_->masm()->mov(fresh.reg(), reg());
      } else {
        ASSERT(is_constant());
-      cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+      if (cgen_->IsUnsafeSmi(handle())) {
+        cgen_->LoadUnsafeSmi(fresh.reg(), handle());
+      } else {
+        cgen_->masm()->Set(fresh.reg(), Immediate(handle()));
+      }
      }
      *this = fresh;
    } else if (is_register() && reg().is(target)) {

Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc      (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc      Wed Feb 18  
01:17:22 2009
@@ -79,7 +79,15 @@
          break;

        case FrameElement::CONSTANT:
-        __ Set(Operand(ebp, fp_relative(index)),  
Immediate(element.handle()));
+        if (cgen_->IsUnsafeSmi(element.handle())) {
+          Result temp = cgen_->allocator()->Allocate();
+          ASSERT(temp.is_valid());
+          cgen_->LoadUnsafeSmi(temp.reg(), element.handle());
+          __ mov(Operand(ebp, fp_relative(index)), temp.reg());
+        } else {
+          __ Set(Operand(ebp, fp_relative(index)),
+                 Immediate(element.handle()));
+        }
          break;

        case FrameElement::COPY: {
@@ -117,7 +125,14 @@
          break;

        case FrameElement::CONSTANT:
-        __ push(Immediate(element.handle()));
+        if (cgen_->IsUnsafeSmi(element.handle())) {
+          Result temp = cgen_->allocator()->Allocate();
+          ASSERT(temp.is_valid());
+          cgen_->LoadUnsafeSmi(temp.reg(), element.handle());
+          __ push(temp.reg());
+        } else {
+          __ push(Immediate(element.handle()));
+        }
          break;

        case FrameElement::COPY: {
@@ -217,7 +232,13 @@

          case FrameElement::CONSTANT:
            if (!source.is_synced()) {
-            __ Set(Operand(ebp, fp_relative(i)),  
Immediate(source.handle()));
+            if (cgen_->IsUnsafeSmi(source.handle())) {
+              esi_caches = i;
+              cgen_->LoadUnsafeSmi(esi, source.handle());
+              __ mov(Operand(ebp, fp_relative(i)), esi);
+            } else {
+              __ Set(Operand(ebp, fp_relative(i)),  
Immediate(source.handle()));
+            }
            }
            break;

@@ -335,7 +356,11 @@
            break;

          case FrameElement::CONSTANT:
-          __ Set(target.reg(), Immediate(source.handle()));
+          if (cgen_->IsUnsafeSmi(source.handle())) {
+            cgen_->LoadUnsafeSmi(target.reg(), source.handle());
+          } else {
+           __ Set(target.reg(), Immediate(source.handle()));
+          }
            break;

          case FrameElement::COPY: {

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

Reply via email to