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}
" 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 =
" 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) {
// 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()) {
%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];
+}));