Commit bef67340 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[array] Add fastpath for dictionary elements to Array.p.sort

R=cbruni@chromium.org, jgruber@chromium.org

Bug: v8:7382
Change-Id: I45f2517afa8ecb3ddb1f77f845e9ce88f69d4eef
Reviewed-on: https://chromium-review.googlesource.com/1092500Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Simon Zünd <szuend@google.com>
Cr-Commit-Position: refs/heads/master@{#53788}
parent eaf03c0c
...@@ -10,6 +10,7 @@ module array { ...@@ -10,6 +10,7 @@ module array {
type FastPackedSmiElements; type FastPackedSmiElements;
type FastSmiOrObjectElements; type FastSmiOrObjectElements;
type FastDoubleElements; type FastDoubleElements;
type DictionaryElements;
macro Load<ElementsAccessor : type>( macro Load<ElementsAccessor : type>(
context: Context, receiver: Object, index: Smi): Object labels Bailout { context: Context, receiver: Object, index: Smi): Object labels Bailout {
...@@ -38,6 +39,16 @@ module array { ...@@ -38,6 +39,16 @@ module array {
return AllocateHeapNumberWithValue(value); return AllocateHeapNumberWithValue(value);
} }
Load<DictionaryElements>(
context: Context, elements: Object, index: Smi): Object labels Bailout {
let dictionary: NumberDictionary = unsafe_cast<NumberDictionary>(elements);
let intptr_index: intptr = convert<intptr>(index);
let value: Object =
BasicLoadNumberDictionaryElement(dictionary, intptr_index)
otherwise Bailout, Bailout;
return value;
}
macro Store<ElementsAccessor : type>( macro Store<ElementsAccessor : type>(
context: Context, receiver: Object, index: Smi, value: Object) { context: Context, receiver: Object, index: Smi, value: Object) {
SetProperty(context, receiver, index, value, kStrict); SetProperty(context, receiver, index, value, kStrict);
...@@ -70,6 +81,21 @@ module array { ...@@ -70,6 +81,21 @@ module array {
return UnsafeCastObjectToCompareBuiltinFn(o); return UnsafeCastObjectToCompareBuiltinFn(o);
} }
Store<DictionaryElements>(
context: Context, elements: Object, index: Smi, value: Object) {
try {
let dictionary: NumberDictionary =
unsafe_cast<NumberDictionary>(elements);
let intptr_index: intptr = convert<intptr>(index);
BasicStoreNumberDictionaryElement(dictionary, intptr_index, value)
otherwise Fail, Fail;
return;
}
label Fail {
unreachable;
}
}
builtin SortCompareDefault( builtin SortCompareDefault(
context: Context, comparefn: Object, x: Object, y: Object): Number { context: Context, comparefn: Object, x: Object, y: Object): Number {
assert(comparefn == Undefined); assert(comparefn == Undefined);
...@@ -136,6 +162,13 @@ module array { ...@@ -136,6 +162,13 @@ module array {
return true; return true;
} }
CanUseSameAccessor<DictionaryElements>(
context: Context, receiver: Object, initialReceiverMap: Object,
initialReceiverLength: Number): bool {
let obj: JSReceiver = unsafe_cast<JSReceiver>(receiver);
return obj.map == initialReceiverMap;
}
macro CallCompareFn<E : type>( macro CallCompareFn<E : type>(
context: Context, receiver: Object, initialReceiverMap: Object, context: Context, receiver: Object, initialReceiverMap: Object,
initialReceiverLength: Number, userCmpFn: Object, initialReceiverLength: Number, userCmpFn: Object,
...@@ -155,6 +188,9 @@ module array { ...@@ -155,6 +188,9 @@ module array {
to: Smi, userCmpFn: Object, sortCompare: CompareBuiltinFn) to: Smi, userCmpFn: Object, sortCompare: CompareBuiltinFn)
labels Bailout { labels Bailout {
for (let i: Smi = from + 1; i < to; ++i) { for (let i: Smi = from + 1; i < to; ++i) {
assert(CanUseSameAccessor<E>(
context, receiver, initialReceiverMap, initialReceiverLength));
let element: Object = Load<E>(context, elements, i) otherwise Bailout; let element: Object = Load<E>(context, elements, i) otherwise Bailout;
let j: Smi = i - 1; let j: Smi = i - 1;
for (; j >= from; --j) { for (; j >= from; --j) {
...@@ -282,6 +318,8 @@ module array { ...@@ -282,6 +318,8 @@ module array {
// Move pivot element to a place on the left. // Move pivot element to a place on the left.
Swap<E>(context, elements, from + 1, third_index, v1) otherwise Bailout; Swap<E>(context, elements, from + 1, third_index, v1) otherwise Bailout;
assert(CanUseSameAccessor<E>(
context, receiver, initialReceiverMap, initialReceiverLength));
return v1; return v1;
} }
...@@ -350,6 +388,9 @@ module array { ...@@ -350,6 +388,9 @@ module array {
// Start looking for high_start to find the first value that is // Start looking for high_start to find the first value that is
// smaller than pivot. // smaller than pivot.
while (order > 0) { while (order > 0) {
assert(CanUseSameAccessor<E>(
context, receiver, initialReceiverMap, initialReceiverLength));
high_start--; high_start--;
if (high_start == idx) { if (high_start == idx) {
break_for = true; break_for = true;
...@@ -475,6 +516,7 @@ module array { ...@@ -475,6 +516,7 @@ module array {
// TODO(szuend): Investigate performance tradeoff of skipping this step // TODO(szuend): Investigate performance tradeoff of skipping this step
// for PACKED_* and handling Undefineds during sorting. // for PACKED_* and handling Undefineds during sorting.
let nofNonUndefined: Smi = PrepareElementsForSort(context, obj, len); let nofNonUndefined: Smi = PrepareElementsForSort(context, obj, len);
assert(a.map == map);
sort_state[kInitialReceiverLengthIdx()] = len; sort_state[kInitialReceiverLengthIdx()] = len;
sort_state[kElementsIdx()] = a.elements; sort_state[kElementsIdx()] = a.elements;
...@@ -502,9 +544,22 @@ module array { ...@@ -502,9 +544,22 @@ module array {
let nofNonUndefined: Smi = PrepareElementsForSort(context, obj, len); let nofNonUndefined: Smi = PrepareElementsForSort(context, obj, len);
sort_state[kInitialReceiverLengthIdx()] = len; sort_state[kInitialReceiverLengthIdx()] = len;
sort_state[kElementsIdx()] = obj;
sort_state[kRandomStateIdx()] = nofNonUndefined; sort_state[kRandomStateIdx()] = nofNonUndefined;
// Reload the map, PrepareElementsForSort might have changed the
// elements kind.
map = obj.map;
if (map.elements_kind == DICTIONARY_ELEMENTS && IsExtensibleMap(map) &&
!IsCustomElementsReceiverInstanceType(map.instance_type)) {
let jsobj: JSObject = unsafe_cast<JSObject>(obj);
sort_state[kElementsIdx()] = jsobj.elements;
ArrayQuickSort<DictionaryElements>(
context, sort_state, 0, nofNonUndefined);
return receiver;
}
sort_state[kElementsIdx()] = obj;
ArrayQuickSort<GenericElementsAccessor>( ArrayQuickSort<GenericElementsAccessor>(
context, sort_state, 0, nofNonUndefined); context, sort_state, 0, nofNonUndefined);
} }
......
...@@ -48,6 +48,7 @@ type FixedTypedArrayBase extends FixedArrayBase generates ...@@ -48,6 +48,7 @@ type FixedTypedArrayBase extends FixedArrayBase generates
'TNode<FixedTypedArrayBase>'; 'TNode<FixedTypedArrayBase>';
type FixedTypedArray extends FixedTypedArrayBase generates type FixedTypedArray extends FixedTypedArrayBase generates
'TNode<FixedTypedArray>'; 'TNode<FixedTypedArray>';
type NumberDictionary extends HeapObject generates 'TNode<NumberDictionary>';
type JSArrayBuffer extends JSObject generates 'TNode<JSArrayBuffer>'; type JSArrayBuffer extends JSObject generates 'TNode<JSArrayBuffer>';
type JSArrayBufferView extends JSObject generates 'TNode<JSArrayBufferView>'; type JSArrayBufferView extends JSObject generates 'TNode<JSArrayBufferView>';
...@@ -73,6 +74,7 @@ const PACKED_ELEMENTS: constexpr ElementsKind = 'PACKED_ELEMENTS'; ...@@ -73,6 +74,7 @@ const PACKED_ELEMENTS: constexpr ElementsKind = 'PACKED_ELEMENTS';
const HOLEY_ELEMENTS: constexpr ElementsKind = 'HOLEY_ELEMENTS'; const HOLEY_ELEMENTS: constexpr ElementsKind = 'HOLEY_ELEMENTS';
const PACKED_DOUBLE_ELEMENTS: constexpr ElementsKind = 'PACKED_DOUBLE_ELEMENTS'; const PACKED_DOUBLE_ELEMENTS: constexpr ElementsKind = 'PACKED_DOUBLE_ELEMENTS';
const HOLEY_DOUBLE_ELEMENTS: constexpr ElementsKind = 'HOLEY_DOUBLE_ELEMENTS'; const HOLEY_DOUBLE_ELEMENTS: constexpr ElementsKind = 'HOLEY_DOUBLE_ELEMENTS';
const DICTIONARY_ELEMENTS: constexpr ElementsKind = 'DICTIONARY_ELEMENTS';
const UINT8_ELEMENTS: constexpr ElementsKind = 'UINT8_ELEMENTS'; const UINT8_ELEMENTS: constexpr ElementsKind = 'UINT8_ELEMENTS';
const INT8_ELEMENTS: constexpr ElementsKind = 'INT8_ELEMENTS'; const INT8_ELEMENTS: constexpr ElementsKind = 'INT8_ELEMENTS';
...@@ -279,7 +281,7 @@ extern macro ConvertFixedArrayBaseToFixedDoubleArray(FixedArrayBase): ...@@ -279,7 +281,7 @@ extern macro ConvertFixedArrayBaseToFixedDoubleArray(FixedArrayBase):
FixedDoubleArray labels CastError; FixedDoubleArray labels CastError;
extern macro TaggedToNumber(Object): Number labels CastError; extern macro TaggedToNumber(Object): Number labels CastError;
macro cast<A: type>(o: Object): A labels CastError; macro cast<A : type>(o: Object): A labels CastError;
cast<Number>(o: Object): Number labels CastError { cast<Number>(o: Object): Number labels CastError {
return TaggedToNumber(o) otherwise CastError; return TaggedToNumber(o) otherwise CastError;
} }
...@@ -298,7 +300,7 @@ cast<Callable>(o: Object): Callable labels CastError { ...@@ -298,7 +300,7 @@ cast<Callable>(o: Object): Callable labels CastError {
cast<JSArray>(o: Object): JSArray labels CastError { cast<JSArray>(o: Object): JSArray labels CastError {
return TaggedToJSArray(o) otherwise CastError; return TaggedToJSArray(o) otherwise CastError;
} }
macro cast<A: type>(o: FixedArrayBase): A labels CastError; macro cast<A : type>(o: FixedArrayBase): A labels CastError;
cast<FixedArray>(o: FixedArrayBase): FixedArray labels CastError { cast<FixedArray>(o: FixedArrayBase): FixedArray labels CastError {
return ConvertFixedArrayBaseToFixedArray(o) otherwise CastError; return ConvertFixedArrayBaseToFixedArray(o) otherwise CastError;
} }
...@@ -335,7 +337,7 @@ extern macro BoolConstant(constexpr bool): bool; ...@@ -335,7 +337,7 @@ extern macro BoolConstant(constexpr bool): bool;
extern macro LanguageModeConstant(constexpr LanguageMode): LanguageMode; extern macro LanguageModeConstant(constexpr LanguageMode): LanguageMode;
extern macro Int32Constant(constexpr ElementsKind): ElementsKind; extern macro Int32Constant(constexpr ElementsKind): ElementsKind;
macro from_constexpr<A: type>(o: constexpr int31): A; macro from_constexpr<A : type>(o: constexpr int31): A;
from_constexpr<intptr>(i: constexpr int31): intptr { from_constexpr<intptr>(i: constexpr int31): intptr {
return IntPtrConstant(i); return IntPtrConstant(i);
} }
...@@ -351,7 +353,7 @@ from_constexpr<Smi>(i: constexpr int31): Smi { ...@@ -351,7 +353,7 @@ from_constexpr<Smi>(i: constexpr int31): Smi {
from_constexpr<Number>(i: constexpr int31): Number { from_constexpr<Number>(i: constexpr int31): Number {
return SmiConstant(i); return SmiConstant(i);
} }
macro from_constexpr<A: type>(o: constexpr int32): A; macro from_constexpr<A : type>(o: constexpr int32): A;
from_constexpr<intptr>(i: constexpr int32): intptr { from_constexpr<intptr>(i: constexpr int32): intptr {
return IntPtrConstant(i); return IntPtrConstant(i);
} }
...@@ -364,24 +366,24 @@ from_constexpr<word32>(i: constexpr int32): word32 { ...@@ -364,24 +366,24 @@ from_constexpr<word32>(i: constexpr int32): word32 {
from_constexpr<Number>(i: constexpr int32): Number { from_constexpr<Number>(i: constexpr int32): Number {
return NumberConstant(i); return NumberConstant(i);
} }
macro from_constexpr<A: type>(o: constexpr float64): A; macro from_constexpr<A : type>(o: constexpr float64): A;
from_constexpr<Number>(f: constexpr float64): Number { from_constexpr<Number>(f: constexpr float64): Number {
return NumberConstant(f); return NumberConstant(f);
} }
macro from_constexpr<A: type>(b: constexpr bool): A; macro from_constexpr<A : type>(b: constexpr bool): A;
from_constexpr<bool>(b: constexpr bool): bool { from_constexpr<bool>(b: constexpr bool): bool {
return BoolConstant(b); return BoolConstant(b);
} }
macro from_constexpr<A: type>(l: constexpr LanguageMode): A; macro from_constexpr<A : type>(l: constexpr LanguageMode): A;
from_constexpr<LanguageMode>(b: constexpr LanguageMode): LanguageMode { from_constexpr<LanguageMode>(b: constexpr LanguageMode): LanguageMode {
return LanguageModeConstant(b); return LanguageModeConstant(b);
} }
macro from_constexpr<A: type>(e: constexpr ElementsKind): A; macro from_constexpr<A : type>(e: constexpr ElementsKind): A;
from_constexpr<ElementsKind>(e: constexpr ElementsKind): ElementsKind { from_constexpr<ElementsKind>(e: constexpr ElementsKind): ElementsKind {
return Int32Constant(e); return Int32Constant(e);
} }
macro convert<A: type>(i: int32): A; macro convert<A : type>(i: int32): A;
convert<Number>(i: int32): Number { convert<Number>(i: int32): Number {
return ChangeInt32ToTagged(i); return ChangeInt32ToTagged(i);
} }
...@@ -394,7 +396,7 @@ convert<intptr>(i: int32): intptr { ...@@ -394,7 +396,7 @@ convert<intptr>(i: int32): intptr {
convert<Smi>(i: int32): Smi { convert<Smi>(i: int32): Smi {
return SmiFromInt32(i); return SmiFromInt32(i);
} }
macro convert<A: type>(ui: uint32): A; macro convert<A : type>(ui: uint32): A;
convert<Number>(ui: uint32): Number { convert<Number>(ui: uint32): Number {
return ChangeUint32ToTagged(ui); return ChangeUint32ToTagged(ui);
} }
...@@ -408,7 +410,7 @@ convert<uint32>(word: word32): uint32 { ...@@ -408,7 +410,7 @@ convert<uint32>(word: word32): uint32 {
convert<uintptr>(word: word32): uintptr { convert<uintptr>(word: word32): uintptr {
return ChangeUint32ToWord(word); return ChangeUint32ToWord(word);
} }
macro convert<A: type>(i: intptr): A; macro convert<A : type>(i: intptr): A;
convert<int32>(i: intptr): int32 { convert<int32>(i: intptr): int32 {
return TruncateIntPtrToInt32(i); return TruncateIntPtrToInt32(i);
} }
...@@ -422,22 +424,22 @@ macro convert<A: type>(ui: uintptr): A; ...@@ -422,22 +424,22 @@ macro convert<A: type>(ui: uintptr): A;
convert<intptr>(ui: uintptr): intptr { convert<intptr>(ui: uintptr): intptr {
return Signed(ui); return Signed(ui);
} }
macro convert<A: type>(s: Smi): A; macro convert<A : type>(s: Smi): A;
convert<intptr>(s: Smi): intptr { convert<intptr>(s: Smi): intptr {
return SmiUntag(s); return SmiUntag(s);
} }
convert<int32>(s: Smi): int32 { convert<int32>(s: Smi): int32 {
return SmiToInt32(s); return SmiToInt32(s);
} }
macro convert<A: type>(h: HeapNumber): A; macro convert<A : type>(h: HeapNumber): A;
convert<float64>(h: HeapNumber): float64 { convert<float64>(h: HeapNumber): float64 {
return LoadHeapNumberValue(h); return LoadHeapNumberValue(h);
} }
macro convert<A: type>(n: Number): A; macro convert<A : type>(n: Number): A;
convert<float64>(n: Number): float64 { convert<float64>(n: Number): float64 {
return ChangeNumberToFloat64(n); return ChangeNumberToFloat64(n);
} }
macro convert<A: type>(f: float32): A; macro convert<A : type>(f: float32): A;
convert<float64>(f: float32): float64 { convert<float64>(f: float32): float64 {
return ChangeFloat32ToFloat64(f); return ChangeFloat32ToFloat64(f);
} }
...@@ -452,12 +454,15 @@ extern macro UnsafeCastObjectToNumber(Object): Number; ...@@ -452,12 +454,15 @@ extern macro UnsafeCastObjectToNumber(Object): Number;
extern macro UnsafeCastObjectToHeapObject(Object): HeapObject; extern macro UnsafeCastObjectToHeapObject(Object): HeapObject;
extern macro UnsafeCastObjectToJSArray(Object): JSArray; extern macro UnsafeCastObjectToJSArray(Object): JSArray;
extern macro UnsafeCastObjectToFixedTypedArrayBase(Object): FixedTypedArrayBase; extern macro UnsafeCastObjectToFixedTypedArrayBase(Object): FixedTypedArrayBase;
extern macro UnsafeCastObjectToNumberDictionary(Object): NumberDictionary;
extern macro UnsafeCastObjectToJSReceiver(Object): JSReceiver;
extern macro UnsafeCastObjectToJSObject(Object): JSObject;
macro unsafe_cast<A: type>(n: Number): A; macro unsafe_cast<A : type>(n: Number): A;
unsafe_cast<HeapNumber>(n: Number): HeapNumber { unsafe_cast<HeapNumber>(n: Number): HeapNumber {
return UnsafeCastNumberToHeapNumber(n); return UnsafeCastNumberToHeapNumber(n);
} }
macro unsafe_cast<A: type>(o: Object): A; macro unsafe_cast<A : type>(o: Object): A;
unsafe_cast<FixedArray>(o: Object): FixedArray { unsafe_cast<FixedArray>(o: Object): FixedArray {
return UnsafeCastObjectToFixedArray(o); return UnsafeCastObjectToFixedArray(o);
} }
...@@ -485,6 +490,15 @@ unsafe_cast<JSArray>(o: Object): JSArray { ...@@ -485,6 +490,15 @@ unsafe_cast<JSArray>(o: Object): JSArray {
unsafe_cast<FixedTypedArrayBase>(o: Object): FixedTypedArrayBase { unsafe_cast<FixedTypedArrayBase>(o: Object): FixedTypedArrayBase {
return UnsafeCastObjectToFixedTypedArrayBase(o); return UnsafeCastObjectToFixedTypedArrayBase(o);
} }
unsafe_cast<NumberDictionary>(o: Object): NumberDictionary {
return UnsafeCastObjectToNumberDictionary(o);
}
unsafe_cast<JSReceiver>(o: Object): JSReceiver {
return UnsafeCastObjectToJSReceiver(o);
}
unsafe_cast<JSObject>(o: Object): JSObject {
return UnsafeCastObjectToJSObject(o);
}
extern macro BranchIfFastJSArray(Object, Context): never labels Taken, NotTaken; extern macro BranchIfFastJSArray(Object, Context): never labels Taken, NotTaken;
extern macro BranchIfNotFastJSArray(Object, Context): never labels Taken, extern macro BranchIfNotFastJSArray(Object, Context): never labels Taken,
...@@ -526,6 +540,8 @@ extern operator ...@@ -526,6 +540,8 @@ extern operator
extern operator extern operator
'[]=' macro StoreFixedArrayElementSmi(FixedArray, Smi, Object): void; '[]=' macro StoreFixedArrayElementSmi(FixedArray, Smi, Object): void;
extern operator '.instance_type' macro LoadMapInstanceType(Map): int32;
extern macro LoadFixedDoubleArrayElement(FixedDoubleArray, Smi): float64; extern macro LoadFixedDoubleArrayElement(FixedDoubleArray, Smi): float64;
extern macro Float64SilenceNaN(float64): float64; extern macro Float64SilenceNaN(float64): float64;
...@@ -536,6 +552,13 @@ macro StoreFixedDoubleArrayElementWithSmiIndex( ...@@ -536,6 +552,13 @@ macro StoreFixedDoubleArrayElementWithSmiIndex(
StoreFixedDoubleArrayElement(array, index, value, SMI_PARAMETERS); StoreFixedDoubleArrayElement(array, index, value, SMI_PARAMETERS);
} }
extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr):
Object labels NotData,
IfHole;
extern macro BasicStoreNumberDictionaryElement(NumberDictionary, intptr, Object)
labels Fail,
IfHole;
extern macro IsFastElementsKind(ElementsKind): bool; extern macro IsFastElementsKind(ElementsKind): bool;
extern macro IsDoubleElementsKind(ElementsKind): bool; extern macro IsDoubleElementsKind(ElementsKind): bool;
extern macro IsFastSmiOrTaggedElementsKind(ElementsKind): bool; extern macro IsFastSmiOrTaggedElementsKind(ElementsKind): bool;
...@@ -613,6 +636,8 @@ extern macro IsJSArray(HeapObject): bool; ...@@ -613,6 +636,8 @@ extern macro IsJSArray(HeapObject): bool;
extern macro TaggedIsCallable(Object): bool; extern macro TaggedIsCallable(Object): bool;
extern macro IsDetachedBuffer(JSArrayBuffer): bool; extern macro IsDetachedBuffer(JSArrayBuffer): bool;
extern macro IsHeapNumber(HeapObject): bool; extern macro IsHeapNumber(HeapObject): bool;
extern macro IsExtensibleMap(Map): bool;
extern macro IsCustomElementsReceiverInstanceType(int32): bool;
// Return true iff number is NaN. // Return true iff number is NaN.
macro NumberIsNaN(number: Number): bool { macro NumberIsNaN(number: Number): bool {
......
...@@ -7331,7 +7331,7 @@ void CodeStubAssembler::NumberDictionaryLookup( ...@@ -7331,7 +7331,7 @@ void CodeStubAssembler::NumberDictionaryLookup(
} }
} }
TNode<Object> CodeStubAssembler::LoadNumberDictionaryElement( TNode<Object> CodeStubAssembler::BasicLoadNumberDictionaryElement(
TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index, TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
Label* not_data, Label* if_hole) { Label* not_data, Label* if_hole) {
TVARIABLE(IntPtrT, var_entry); TVARIABLE(IntPtrT, var_entry);
...@@ -7347,10 +7347,34 @@ TNode<Object> CodeStubAssembler::LoadNumberDictionaryElement( ...@@ -7347,10 +7347,34 @@ TNode<Object> CodeStubAssembler::LoadNumberDictionaryElement(
TNode<Uint32T> kind = DecodeWord32<PropertyDetails::KindField>(details); TNode<Uint32T> kind = DecodeWord32<PropertyDetails::KindField>(details);
// TODO(jkummerow): Support accessors without missing? // TODO(jkummerow): Support accessors without missing?
GotoIfNot(Word32Equal(kind, Int32Constant(kData)), not_data); GotoIfNot(Word32Equal(kind, Int32Constant(kData)), not_data);
// Finally, load athe value. // Finally, load the value.
return LoadValueByKeyIndex<NumberDictionary>(dictionary, index); return LoadValueByKeyIndex<NumberDictionary>(dictionary, index);
} }
void CodeStubAssembler::BasicStoreNumberDictionaryElement(
TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
TNode<Object> value, Label* fail, Label* if_hole) {
TVARIABLE(IntPtrT, var_entry);
Label if_found(this);
NumberDictionaryLookup(dictionary, intptr_index, &if_found, &var_entry,
if_hole);
BIND(&if_found);
// Check that the value is a data property.
TNode<IntPtrT> index = EntryToIndex<NumberDictionary>(var_entry.value());
TNode<Uint32T> details =
LoadDetailsByKeyIndex<NumberDictionary>(dictionary, index);
TNode<Uint32T> kind = DecodeWord32<PropertyDetails::KindField>(details);
// TODO(jkummerow): Support accessors without missing?
GotoIfNot(Word32Equal(kind, Int32Constant(kData)), fail);
// Check that the property is writeable.
GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask), fail);
// Finally, store the value.
StoreValueByKeyIndex<NumberDictionary>(dictionary, index, value);
}
template <class Dictionary> template <class Dictionary>
void CodeStubAssembler::FindInsertionEntry(TNode<Dictionary> dictionary, void CodeStubAssembler::FindInsertionEntry(TNode<Dictionary> dictionary,
TNode<Name> key, TNode<Name> key,
......
...@@ -354,6 +354,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -354,6 +354,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
return p_o; return p_o;
} }
TNode<NumberDictionary> UnsafeCastObjectToNumberDictionary(
TNode<Object> p_o) {
return CAST(p_o);
}
TNode<JSReceiver> UnsafeCastObjectToJSReceiver(TNode<Object> p_o) {
return CAST(p_o);
}
TNode<JSObject> UnsafeCastObjectToJSObject(TNode<Object> p_o) {
return CAST(p_o);
}
Node* MatchesParameterMode(Node* value, ParameterMode mode); Node* MatchesParameterMode(Node* value, ParameterMode mode);
#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \ #define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
...@@ -2127,9 +2140,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -2127,9 +2140,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TVariable<IntPtrT>* var_entry, TVariable<IntPtrT>* var_entry,
Label* if_not_found); Label* if_not_found);
TNode<Object> LoadNumberDictionaryElement(TNode<NumberDictionary> dictionary, TNode<Object> BasicLoadNumberDictionaryElement(
TNode<IntPtrT> intptr_index, TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
Label* not_data, Label* if_hole); Label* not_data, Label* if_hole);
void BasicStoreNumberDictionaryElement(TNode<NumberDictionary> dictionary,
TNode<IntPtrT> intptr_index,
TNode<Object> value, Label* fail,
Label* if_hole);
template <class Dictionary> template <class Dictionary>
void FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key, void FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key,
......
...@@ -1801,7 +1801,7 @@ void AccessorAssembler::EmitElementLoad( ...@@ -1801,7 +1801,7 @@ void AccessorAssembler::EmitElementLoad(
Comment("dictionary elements"); Comment("dictionary elements");
GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds); GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds);
TNode<Object> value = LoadNumberDictionaryElement( TNode<Object> value = BasicLoadNumberDictionaryElement(
CAST(elements), intptr_index, miss, if_hole); CAST(elements), intptr_index, miss, if_hole);
exit_point->Return(value); exit_point->Return(value);
} }
......
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