Treat HArgumentsObject as a safe use during Uint32 analysis phase.
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}
This commit is contained in:
parent
0f432ebb76
commit
021f738127
@ -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) {
|
||||
|
@ -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()) {
|
||||
|
@ -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];
|
||||
}));
|
||||
|
Loading…
Reference in New Issue
Block a user