Commit 44aa135a authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[asm.js] Implement loads in terms of regular branches

This is the counterpart of https://crrev.com/c/822471.
It implements asm.js bounds checks for loads using normal branch nodes
and removes the need for CheckedLoad, improving maintainability at some
small cost to compilation time.

R=ahaas@chromium.org
CC=mstarzinger@chromium.org, titzer@chromium.org

Change-Id: I7a2716f364b9e4d7beb9cc460eb028c3bd1c3a99
Reviewed-on: https://chromium-review.googlesource.com/832457
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50192}
parent 5e18f849
......@@ -3724,23 +3724,58 @@ Node* WasmGraphBuilder::StoreMem(MachineRepresentation mem_rep, Node* index,
return store;
}
namespace {
Node* GetAsmJsOOBValue(MachineRepresentation rep, JSGraph* jsgraph) {
switch (rep) {
case MachineRepresentation::kWord8:
case MachineRepresentation::kWord16:
case MachineRepresentation::kWord32:
return jsgraph->Int32Constant(0);
case MachineRepresentation::kWord64:
return jsgraph->Int64Constant(0);
case MachineRepresentation::kFloat32:
return jsgraph->Float32Constant(std::numeric_limits<float>::quiet_NaN());
case MachineRepresentation::kFloat64:
return jsgraph->Float64Constant(std::numeric_limits<double>::quiet_NaN());
default:
UNREACHABLE();
}
}
} // namespace
Node* WasmGraphBuilder::BuildAsmjsLoadMem(MachineType type, Node* index) {
// TODO(turbofan): fold bounds checks for constant asm.js loads.
// asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish).
DCHECK_NOT_NULL(context_cache_);
Node* mem_start = context_cache_->mem_start;
Node* mem_size = context_cache_->mem_size;
DCHECK_NOT_NULL(mem_start);
DCHECK_NOT_NULL(mem_size);
// Asm.js semantics are defined along the lines of typed arrays, hence OOB
// reads return {undefined} coerced to the result type (0 for integers, NaN
// for float and double).
// Note that we check against the memory size ignoring the size of the
// stored value, which is conservative if misaligned. Technically, asm.js
// should never have misaligned accesses.
Diamond bounds_check(
graph(), jsgraph()->common(),
graph()->NewNode(jsgraph()->machine()->Uint32LessThan(), index, mem_size),
BranchHint::kTrue);
bounds_check.Chain(*control_);
if (jsgraph()->machine()->Is64()) {
index =
graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), index);
}
const Operator* op = jsgraph()->machine()->CheckedLoad(type);
Node* load =
graph()->NewNode(op, mem_start, index, mem_size, *effect_, *control_);
*effect_ = load;
return load;
Node* load = graph()->NewNode(jsgraph()->machine()->Load(type), mem_start,
index, *effect_, bounds_check.if_true);
Node* value_phi =
bounds_check.Phi(type.representation(), load,
GetAsmJsOOBValue(type.representation(), jsgraph()));
Node* effect_phi = graph()->NewNode(jsgraph()->common()->EffectPhi(2), load,
*effect_, bounds_check.merge);
*effect_ = effect_phi;
*control_ = bounds_check.merge;
return value_phi;
}
Node* WasmGraphBuilder::BuildAsmjsStoreMem(MachineType type, Node* index,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment