Treat HArgumentsObject as a safe use during Uint32 analysis phase.
authorvegorov <vegorov@google.com>
Mon, 13 Apr 2015 10:47:19 +0000 (03:47 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 13 Apr 2015 10:47:15 +0000 (10:47 +0000)
Deoptimization infrastructure already handles it correctly.

This change fixes repetitive deoptimizations in the code like this:

    var u32 = new Uint32Array(1);
    u32[0] = -1;

    function tr(x) { return x|0; }
    function ld() { return tr(u32[0]); }

    while (true) ld();

Currently inlined tr will contain HArgumentsObject that is considered uint32-unsafe use and prevents u32[0] from becoming uint32 load - instead a speculative int32 load is generated which just deopts.

BUG=

Review URL: https://codereview.chromium.org/1077113002

Cr-Commit-Position: refs/heads/master@{#27781}

src/deoptimizer.cc
src/hydrogen-uint32-analysis.cc
test/mjsunit/compiler/uint32.js

index a8de06e..075a51f 100644 (file)
@@ -2223,10 +2223,8 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
                "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF(trace_scope_->file(),
-               "%" V8PRIdPTR " ; uint %s (%s)\n", value,
-               converter.NameOfCPURegister(input_reg),
-               TraceValueType(is_smi));
+        PrintF(trace_scope_->file(), "%" V8PRIuPTR " ; uint %s (%s)\n", value,
+               converter.NameOfCPURegister(input_reg), TraceValueType(is_smi));
       }
       if (is_smi) {
         intptr_t tagged_value =
@@ -2311,8 +2309,7 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
                "      object @0x%08" V8PRIxPTR ": [field #%d] <- ",
                reinterpret_cast<intptr_t>(object_slot),
                field_index);
-        PrintF(trace_scope_->file(),
-               "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
+        PrintF(trace_scope_->file(), "%" V8PRIuPTR " ; [sp + %d] (uint %s)\n",
                value, input_offset, TraceValueType(is_smi));
       }
       if (is_smi) {
index 585a706..8507584 100644 (file)
@@ -36,7 +36,7 @@ bool HUint32AnalysisPhase::IsSafeUint32Use(HValue* val, HValue* use) {
   // Operations that operate on bits are safe.
   if (use->IsBitwise() || use->IsShl() || use->IsSar() || use->IsShr()) {
     return true;
-  } else if (use->IsSimulate()) {
+  } else if (use->IsSimulate() || use->IsArgumentsObject()) {
     // Deoptimization has special support for uint32.
     return true;
   } else if (use->IsChange()) {
index abed285..3568e27 100644 (file)
@@ -171,3 +171,34 @@ FillOldArrayWithHeapNumbers(1);
 %OptimizeFunctionOnNextCall(FillOldArrayWithHeapNumbers);
 FillOldArrayWithHeapNumbers(old_array.length);
 gc();
+
+// Test that HArgumentsObject does not prevent uint32 optimization and
+// that arguments object with uint32 values inside is correctly materialized.
+function Pack(x, y) {
+  try {  // Prevent inlining.
+    return [x, y];
+  } catch (e) {
+  }
+}
+
+function InnerWithArguments(x, f) {
+  "use strict";
+  x >>>= 8;
+  return f(arguments[0], x|0);
+}
+
+function Outer(v, f) {
+  return InnerWithArguments(v >>> 0, f);
+}
+
+assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack));
+assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack));
+assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack));
+%OptimizeFunctionOnNextCall(Outer);
+assertArrayEquals([0x0100, 0x01], Outer(0x0100, Pack));
+assertArrayEquals([0xFFFFFFFF, 0x00FFFFFF], Outer(-1, Pack));
+
+// Cause deopt inside InnerWithArguments by passing different pack function.
+assertArrayEquals([0xFFFFFFFF, 0x00FFFFFF], Outer(-1, function (x, y) {
+  return [x, y];
+}));