Commit 0be5596c authored by bmeurer's avatar bmeurer 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
TBR=ishell@chromium.org

Review-Url: https://codereview.chromium.org/2842373005
Cr-Commit-Position: refs/heads/master@{#44957}
parent 874d77b9
......@@ -3179,6 +3179,10 @@ Node* CodeStubAssembler::IsPropertyCell(Node* object) {
return IsPropertyCellMap(LoadMap(object));
}
Node* CodeStubAssembler::IsAccessorInfo(Node* object) {
return IsAccessorInfoMap(LoadMap(object));
}
Node* CodeStubAssembler::IsAccessorPair(Node* object) {
return IsAccessorPairMap(LoadMap(object));
}
......@@ -5337,18 +5341,17 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
Node* context, Node* receiver,
Label* if_bailout) {
VARIABLE(var_value, MachineRepresentation::kTagged, value);
Label done(this);
Label done(this), if_accessor_info(this, Label::kDeferred);
Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
GotoIf(Word32Equal(kind, Int32Constant(kData)), &done);
// Accessor case.
GotoIfNot(IsAccessorPair(value), &if_accessor_info);
// AccessorPair case.
{
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_map = LoadMap(getter);
Node* instance_type = LoadMapInstanceType(getter_map);
......@@ -5368,6 +5371,21 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
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);
return var_value.value();
}
......
......@@ -28,6 +28,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(BooleanMap, BooleanMap) \
V(CodeMap, CodeMap) \
V(empty_string, EmptyString) \
V(length_string, LengthString) \
V(EmptyFixedArray, EmptyFixedArray) \
V(FalseValue, False) \
V(FixedArrayMap, FixedArrayMap) \
......@@ -744,6 +745,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsCallable(Node* object);
Node* IsBoolean(Node* object);
Node* IsPropertyCell(Node* object);
Node* IsAccessorInfo(Node* object);
Node* IsAccessorPair(Node* object);
Node* IsHeapNumber(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