Fixed the range information for string lengths.
Currently, this doesn't really help to generate better code, nevertheless this is the right thing to do. When our type system(s) are fixed, this should avoid falling back to floating point operations in various cases. Review URL: https://codereview.chromium.org/1057813002 Cr-Commit-Position: refs/heads/master@{#27578}
This commit is contained in:
parent
4977a4a83a
commit
1592870822
@ -59,10 +59,9 @@ FieldAccess AccessBuilder::ForMapInstanceType() {
|
||||
|
||||
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForStringLength() {
|
||||
FieldAccess AccessBuilder::ForStringLength(Zone* zone) {
|
||||
return {kTaggedBase, String::kLengthOffset, Handle<Name>(),
|
||||
Type::Intersect(Type::UnsignedSmall(), Type::TaggedSigned()),
|
||||
kMachAnyTagged};
|
||||
Type::Range(0, String::kMaxLength, zone), kMachAnyTagged};
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ class AccessBuilder FINAL : public AllStatic {
|
||||
static FieldAccess ForMapInstanceType();
|
||||
|
||||
// Provides access to String::length() field.
|
||||
static FieldAccess ForStringLength();
|
||||
static FieldAccess ForStringLength(Zone* zone);
|
||||
|
||||
// Provides access to JSValue::value() field.
|
||||
static FieldAccess ForValue();
|
||||
|
@ -294,7 +294,8 @@ Reduction JSIntrinsicLowering::ReduceStringGetLength(Node* node) {
|
||||
Node* value = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
return Change(node, simplified()->LoadField(AccessBuilder::ForStringLength()),
|
||||
return Change(node, simplified()->LoadField(
|
||||
AccessBuilder::ForStringLength(graph()->zone())),
|
||||
value, effect, control);
|
||||
}
|
||||
|
||||
|
@ -541,7 +541,7 @@ Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
|
||||
return Changed(node);
|
||||
} else if (input_type->Is(Type::String())) {
|
||||
// JSUnaryNot(x:string) => NumberEqual(x.length,#0)
|
||||
FieldAccess const access = AccessBuilder::ForStringLength();
|
||||
FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone());
|
||||
// It is safe for the load to be effect-free (i.e. not linked into effect
|
||||
// chain) because we assume String::length to be immutable.
|
||||
Node* length = graph()->NewNode(simplified()->LoadField(access), input,
|
||||
@ -572,7 +572,7 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
|
||||
return Changed(node);
|
||||
} else if (input_type->Is(Type::String())) {
|
||||
// JSToBoolean(x:string) => NumberLessThan(#0,x.length)
|
||||
FieldAccess const access = AccessBuilder::ForStringLength();
|
||||
FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone());
|
||||
// It is safe for the load to be effect-free (i.e. not linked into effect
|
||||
// chain) because we assume String::length to be immutable.
|
||||
Node* length = graph()->NewNode(simplified()->LoadField(access), input,
|
||||
|
@ -1580,9 +1580,7 @@ Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
|
||||
case Runtime::kInlineMathClz32:
|
||||
return Bounds(Type::None(), Type::Range(0, 32, zone()));
|
||||
case Runtime::kInlineStringGetLength:
|
||||
// The string::length property is always an unsigned smi.
|
||||
return Bounds(Type::None(), Type::Intersect(Type::UnsignedSmall(),
|
||||
Type::TaggedSigned()));
|
||||
return Bounds(Type::None(), Type::Range(0, String::kMaxLength, zone()));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -316,8 +316,9 @@ TEST_F(JSIntrinsicLoweringTest, InlineStringGetLength) {
|
||||
javascript()->CallRuntime(Runtime::kInlineStringGetLength, 1), input,
|
||||
context, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(),
|
||||
input, effect, control));
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsLoadField(AccessBuilder::ForStringLength(zone()), input, effect,
|
||||
control));
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,10 +190,11 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithString) {
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), input,
|
||||
graph()->start(), graph()->start()),
|
||||
IsNumberConstant(0.0)));
|
||||
EXPECT_THAT(
|
||||
r.replacement(),
|
||||
IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(zone()), input,
|
||||
graph()->start(), graph()->start()),
|
||||
IsNumberConstant(0.0)));
|
||||
}
|
||||
|
||||
|
||||
@ -392,8 +393,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
|
||||
EXPECT_THAT(
|
||||
r.replacement(),
|
||||
IsNumberLessThan(IsNumberConstant(0.0),
|
||||
IsLoadField(AccessBuilder::ForStringLength(), input,
|
||||
graph()->start(), graph()->start())));
|
||||
IsLoadField(AccessBuilder::ForStringLength(zone()),
|
||||
input, graph()->start(), graph()->start())));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user