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:
svenpanne 2015-04-02 01:32:48 -07:00 committed by Commit bot
parent 4977a4a83a
commit 1592870822
7 changed files with 18 additions and 18 deletions

View File

@ -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};
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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())));
}