Commit 0322be81 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[ic] Handle JSArray::length in CodeStubAssembler::CallGetterIfAccessor.

When accessing JSArray::length property from GenericPropertyLoad
(i.e. via a megamorphic KEYED_LOAD_IC), we'd always go to the runtime
at this point, because the CallGetterIfAccessor method didn't support
AccessorInfos at all. Now there's initial support for JSArray::length,
which reduces the number of %KeyedGetProperty calls we see in the
Speedometer/EmberJS test by 5000.

Also-By: ishell@chromium.org
BUG=v8:5269
R=ishell@chromium.org

Change-Id: I44ce7966f9b7257808110a24d95a8167ab035df9
Reviewed-on: https://chromium-review.googlesource.com/488224Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44915}
parent 0991f9d2
...@@ -3164,6 +3164,10 @@ Node* CodeStubAssembler::IsPropertyCell(Node* object) { ...@@ -3164,6 +3164,10 @@ Node* CodeStubAssembler::IsPropertyCell(Node* object) {
return IsPropertyCellMap(LoadMap(object)); return IsPropertyCellMap(LoadMap(object));
} }
Node* CodeStubAssembler::IsAccessorInfo(Node* object) {
return IsAccessorInfoMap(LoadMap(object));
}
Node* CodeStubAssembler::IsAccessorPair(Node* object) { Node* CodeStubAssembler::IsAccessorPair(Node* object) {
return IsAccessorPairMap(LoadMap(object)); return IsAccessorPairMap(LoadMap(object));
} }
...@@ -5322,18 +5326,17 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details, ...@@ -5322,18 +5326,17 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
Node* context, Node* receiver, Node* context, Node* receiver,
Label* if_bailout) { Label* if_bailout) {
VARIABLE(var_value, MachineRepresentation::kTagged, value); VARIABLE(var_value, MachineRepresentation::kTagged, value);
Label done(this); Label done(this), if_accessor_info(this, Label::kDeferred);
Node* kind = DecodeWord32<PropertyDetails::KindField>(details); Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
GotoIf(Word32Equal(kind, Int32Constant(kData)), &done); GotoIf(Word32Equal(kind, Int32Constant(kData)), &done);
// Accessor case. // Accessor case.
GotoIfNot(IsAccessorPair(value), &if_accessor_info);
// AccessorPair case.
{ {
Node* accessor_pair = value; Node* accessor_pair = value;
GotoIf(Word32Equal(LoadInstanceType(accessor_pair),
Int32Constant(ACCESSOR_INFO_TYPE)),
if_bailout);
CSA_ASSERT(this, IsAccessorPair(accessor_pair));
Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
Node* getter_map = LoadMap(getter); Node* getter_map = LoadMap(getter);
Node* instance_type = LoadMapInstanceType(getter_map); Node* instance_type = LoadMapInstanceType(getter_map);
...@@ -5353,6 +5356,21 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details, ...@@ -5353,6 +5356,21 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
Goto(&done); Goto(&done);
} }
// AccessorInfo case.
BIND(&if_accessor_info);
{
// TODO(ishell): Consider doing this for the Function.prototype and the
// String.length accessor infos as well.
CSA_ASSERT(this, IsAccessorInfo(value));
CSA_ASSERT(this, TaggedIsNotSmi(receiver));
GotoIfNot(IsJSArray(receiver), if_bailout);
// The only AccessorInfo on JSArray is the "length" property.
CSA_ASSERT(this, IsLengthString(
LoadObjectField(value, AccessorInfo::kNameOffset)));
var_value.Bind(LoadJSArrayLength(receiver));
Goto(&done);
}
BIND(&done); BIND(&done);
return var_value.value(); return var_value.value();
} }
......
...@@ -28,6 +28,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; ...@@ -28,6 +28,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(BooleanMap, BooleanMap) \ V(BooleanMap, BooleanMap) \
V(CodeMap, CodeMap) \ V(CodeMap, CodeMap) \
V(empty_string, EmptyString) \ V(empty_string, EmptyString) \
V(length_string, LengthString) \
V(EmptyFixedArray, EmptyFixedArray) \ V(EmptyFixedArray, EmptyFixedArray) \
V(FalseValue, False) \ V(FalseValue, False) \
V(FixedArrayMap, FixedArrayMap) \ V(FixedArrayMap, FixedArrayMap) \
...@@ -743,6 +744,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -743,6 +744,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsCallable(Node* object); Node* IsCallable(Node* object);
Node* IsBoolean(Node* object); Node* IsBoolean(Node* object);
Node* IsPropertyCell(Node* object); Node* IsPropertyCell(Node* object);
Node* IsAccessorInfo(Node* object);
Node* IsAccessorPair(Node* object); Node* IsAccessorPair(Node* object);
Node* IsHeapNumber(Node* object); Node* IsHeapNumber(Node* object);
Node* IsName(Node* object); Node* IsName(Node* object);
......
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