[turbofan] Harden BuildElementAccess against potential typer bugs
Bug: chromium:1051017 Change-Id: Id300c6d5f88b762e465383ac78ed037d3bc958d5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2089938 Commit-Queue: Georg Neis <neis@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#66627}
This commit is contained in:
parent
18b4b6b93c
commit
fa5fc748e5
@ -2636,6 +2636,15 @@ JSNativeContextSpecialization::BuildElementAccess(
|
|||||||
Node* etrue = effect;
|
Node* etrue = effect;
|
||||||
Node* vtrue;
|
Node* vtrue;
|
||||||
{
|
{
|
||||||
|
// Do a real bounds check against {length}. This is in order to
|
||||||
|
// protect against a potential typer bug leading to the elimination
|
||||||
|
// of the NumberLessThan above.
|
||||||
|
index = etrue = graph()->NewNode(
|
||||||
|
simplified()->CheckBounds(
|
||||||
|
FeedbackSource(),
|
||||||
|
CheckBoundsParameters::kAbortOnOutOfBounds),
|
||||||
|
index, length, etrue, if_true);
|
||||||
|
|
||||||
// Perform the actual load
|
// Perform the actual load
|
||||||
vtrue = etrue = graph()->NewNode(
|
vtrue = etrue = graph()->NewNode(
|
||||||
simplified()->LoadTypedElement(external_array_type),
|
simplified()->LoadTypedElement(external_array_type),
|
||||||
@ -2697,6 +2706,15 @@ JSNativeContextSpecialization::BuildElementAccess(
|
|||||||
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
||||||
Node* etrue = effect;
|
Node* etrue = effect;
|
||||||
{
|
{
|
||||||
|
// Do a real bounds check against {length}. This is in order to
|
||||||
|
// protect against a potential typer bug leading to the elimination
|
||||||
|
// of the NumberLessThan above.
|
||||||
|
index = etrue = graph()->NewNode(
|
||||||
|
simplified()->CheckBounds(
|
||||||
|
FeedbackSource(),
|
||||||
|
CheckBoundsParameters::kAbortOnOutOfBounds),
|
||||||
|
index, length, etrue, if_true);
|
||||||
|
|
||||||
// Perform the actual store.
|
// Perform the actual store.
|
||||||
etrue = graph()->NewNode(
|
etrue = graph()->NewNode(
|
||||||
simplified()->StoreTypedElement(external_array_type),
|
simplified()->StoreTypedElement(external_array_type),
|
||||||
@ -2829,6 +2847,14 @@ JSNativeContextSpecialization::BuildElementAccess(
|
|||||||
Node* etrue = effect;
|
Node* etrue = effect;
|
||||||
Node* vtrue;
|
Node* vtrue;
|
||||||
{
|
{
|
||||||
|
// Do a real bounds check against {length}. This is in order to
|
||||||
|
// protect against a potential typer bug leading to the elimination of
|
||||||
|
// the NumberLessThan above.
|
||||||
|
index = etrue = graph()->NewNode(
|
||||||
|
simplified()->CheckBounds(
|
||||||
|
FeedbackSource(), CheckBoundsParameters::kAbortOnOutOfBounds),
|
||||||
|
index, length, etrue, if_true);
|
||||||
|
|
||||||
// Perform the actual load
|
// Perform the actual load
|
||||||
vtrue = etrue =
|
vtrue = etrue =
|
||||||
graph()->NewNode(simplified()->LoadElement(element_access),
|
graph()->NewNode(simplified()->LoadElement(element_access),
|
||||||
@ -3097,13 +3123,18 @@ Node* JSNativeContextSpecialization::BuildIndexedStringLoad(
|
|||||||
IsSafetyCheck::kCriticalSafetyCheck),
|
IsSafetyCheck::kCriticalSafetyCheck),
|
||||||
check, *control);
|
check, *control);
|
||||||
|
|
||||||
Node* masked_index = graph()->NewNode(simplified()->PoisonIndex(), index);
|
|
||||||
|
|
||||||
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
||||||
Node* etrue;
|
// Do a real bounds check against {length}. This is in order to protect
|
||||||
|
// against a potential typer bug leading to the elimination of the
|
||||||
|
// NumberLessThan above.
|
||||||
|
Node* etrue = index = graph()->NewNode(
|
||||||
|
simplified()->CheckBounds(FeedbackSource(),
|
||||||
|
CheckBoundsParameters::kAbortOnOutOfBounds),
|
||||||
|
index, length, *effect, if_true);
|
||||||
|
Node* masked_index = graph()->NewNode(simplified()->PoisonIndex(), index);
|
||||||
Node* vtrue = etrue =
|
Node* vtrue = etrue =
|
||||||
graph()->NewNode(simplified()->StringCharCodeAt(), receiver,
|
graph()->NewNode(simplified()->StringCharCodeAt(), receiver,
|
||||||
masked_index, *effect, if_true);
|
masked_index, etrue, if_true);
|
||||||
vtrue = graph()->NewNode(simplified()->StringFromSingleCharCode(), vtrue);
|
vtrue = graph()->NewNode(simplified()->StringFromSingleCharCode(), vtrue);
|
||||||
|
|
||||||
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
||||||
|
@ -1687,7 +1687,7 @@ class RepresentationSelector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DCHECK(length_type.Is(type_cache_->kPositiveSafeInteger));
|
CHECK(length_type.Is(type_cache_->kPositiveSafeInteger));
|
||||||
VisitBinop(node,
|
VisitBinop(node,
|
||||||
UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, p.feedback()),
|
UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, p.feedback()),
|
||||||
UseInfo::Word64(), MachineRepresentation::kWord64);
|
UseInfo::Word64(), MachineRepresentation::kWord64);
|
||||||
|
@ -822,7 +822,6 @@ bool operator==(CheckMinusZeroParameters const& lhs,
|
|||||||
V(CheckedUint32Mod, 2, 1)
|
V(CheckedUint32Mod, 2, 1)
|
||||||
|
|
||||||
#define CHECKED_WITH_FEEDBACK_OP_LIST(V) \
|
#define CHECKED_WITH_FEEDBACK_OP_LIST(V) \
|
||||||
V(CheckBounds, 2, 1) \
|
|
||||||
V(CheckNumber, 1, 1) \
|
V(CheckNumber, 1, 1) \
|
||||||
V(CheckSmi, 1, 1) \
|
V(CheckSmi, 1, 1) \
|
||||||
V(CheckString, 1, 1) \
|
V(CheckString, 1, 1) \
|
||||||
@ -840,7 +839,9 @@ bool operator==(CheckMinusZeroParameters const& lhs,
|
|||||||
V(CheckedUint64ToInt32, 1, 1) \
|
V(CheckedUint64ToInt32, 1, 1) \
|
||||||
V(CheckedUint64ToTaggedSigned, 1, 1)
|
V(CheckedUint64ToTaggedSigned, 1, 1)
|
||||||
|
|
||||||
#define CHECKED_BOUNDS_OP_LIST(V) V(CheckedUint32Bounds)
|
#define CHECKED_BOUNDS_OP_LIST(V) \
|
||||||
|
V(CheckBounds) \
|
||||||
|
V(CheckedUint32Bounds)
|
||||||
|
|
||||||
struct SimplifiedOperatorGlobalCache final {
|
struct SimplifiedOperatorGlobalCache final {
|
||||||
#define PURE(Name, properties, value_input_count, control_input_count) \
|
#define PURE(Name, properties, value_input_count, control_input_count) \
|
||||||
@ -1616,7 +1617,8 @@ std::ostream& operator<<(std::ostream& os, CheckParameters const& p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckParameters const& CheckParametersOf(Operator const* op) {
|
CheckParameters const& CheckParametersOf(Operator const* op) {
|
||||||
if (op->opcode() == IrOpcode::kCheckedUint32Bounds) {
|
if (op->opcode() == IrOpcode::kCheckBounds ||
|
||||||
|
op->opcode() == IrOpcode::kCheckedUint32Bounds) {
|
||||||
return OpParameter<CheckBoundsParameters>(op).check_parameters();
|
return OpParameter<CheckBoundsParameters>(op).check_parameters();
|
||||||
}
|
}
|
||||||
#define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
|
#define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
|
||||||
|
@ -781,7 +781,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
|
|||||||
const Operator* CompareMaps(ZoneHandleSet<Map>);
|
const Operator* CompareMaps(ZoneHandleSet<Map>);
|
||||||
const Operator* MapGuard(ZoneHandleSet<Map> maps);
|
const Operator* MapGuard(ZoneHandleSet<Map> maps);
|
||||||
|
|
||||||
const Operator* CheckBounds(const FeedbackSource& feedback);
|
const Operator* CheckBounds(const FeedbackSource& feedback,
|
||||||
|
CheckBoundsParameters::Mode mode =
|
||||||
|
CheckBoundsParameters::kDeoptOnOutOfBounds);
|
||||||
const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell);
|
const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell);
|
||||||
const Operator* CheckEqualsInternalizedString();
|
const Operator* CheckEqualsInternalizedString();
|
||||||
const Operator* CheckEqualsSymbol();
|
const Operator* CheckEqualsSymbol();
|
||||||
|
Loading…
Reference in New Issue
Block a user