Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Unified Diff: src/elements.cc

Issue 1221713003: Distinguish slow from fast sloppy arguments (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/elements.h ('k') | src/elements-kind.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 7ea6554b32237ae8e6c3a8cb34f9fd7ba375e91b..3c6e2726ce4f8803b2d23a8313aeb3ba57806dfe 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -47,6 +47,8 @@
// - FixedUint8ClampedElementsAccessor
// - DictionaryElementsAccessor
// - SloppyArgumentsElementsAccessor
+// - FastSloppyArgumentsElementsAccessor
+// - SlowSloppyArgumentsElementsAccessor
namespace v8 {
@@ -61,48 +63,45 @@ static const int kPackedSizeNotKnown = -1;
// fast element handler for smi-only arrays. The implementation is currently
// identical. Note that the order must match that of the ElementsKind enum for
// the |accessor_array[]| below to work.
-#define ELEMENTS_LIST(V) \
- V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
- V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \
- FixedArray) \
- V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
- V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
- V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \
- FixedDoubleArray) \
- V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
- FixedDoubleArray) \
- V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \
- SeededNumberDictionary) \
- V(SloppyArgumentsElementsAccessor, SLOPPY_ARGUMENTS_ELEMENTS, \
- FixedArray) \
- V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, \
- ExternalInt8Array) \
- V(ExternalUint8ElementsAccessor, \
- EXTERNAL_UINT8_ELEMENTS, ExternalUint8Array) \
- V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
- ExternalInt16Array) \
- V(ExternalUint16ElementsAccessor, \
- EXTERNAL_UINT16_ELEMENTS, ExternalUint16Array) \
- V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
- ExternalInt32Array) \
- V(ExternalUint32ElementsAccessor, \
- EXTERNAL_UINT32_ELEMENTS, ExternalUint32Array) \
- V(ExternalFloat32ElementsAccessor, \
- EXTERNAL_FLOAT32_ELEMENTS, ExternalFloat32Array) \
- V(ExternalFloat64ElementsAccessor, \
- EXTERNAL_FLOAT64_ELEMENTS, ExternalFloat64Array) \
- V(ExternalUint8ClampedElementsAccessor, \
- EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
- ExternalUint8ClampedArray) \
- V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
- V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
- V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
- V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
- V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
- V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
- V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
- V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
- V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
+#define ELEMENTS_LIST(V) \
+ V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
+ V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \
+ V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
+ V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
+ V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
+ V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
+ FixedDoubleArray) \
+ V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \
+ V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \
+ FixedArray) \
+ V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
+ FixedArray) \
+ V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, ExternalInt8Array) \
+ V(ExternalUint8ElementsAccessor, EXTERNAL_UINT8_ELEMENTS, \
+ ExternalUint8Array) \
+ V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
+ ExternalInt16Array) \
+ V(ExternalUint16ElementsAccessor, EXTERNAL_UINT16_ELEMENTS, \
+ ExternalUint16Array) \
+ V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
+ ExternalInt32Array) \
+ V(ExternalUint32ElementsAccessor, EXTERNAL_UINT32_ELEMENTS, \
+ ExternalUint32Array) \
+ V(ExternalFloat32ElementsAccessor, EXTERNAL_FLOAT32_ELEMENTS, \
+ ExternalFloat32Array) \
+ V(ExternalFloat64ElementsAccessor, EXTERNAL_FLOAT64_ELEMENTS, \
+ ExternalFloat64Array) \
+ V(ExternalUint8ClampedElementsAccessor, EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
+ ExternalUint8ClampedArray) \
+ V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
+ V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
+ V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
+ V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
+ V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
+ V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
+ V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
+ V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
+ V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
FixedUint8ClampedArray)
@@ -550,6 +549,9 @@ template <typename ElementsAccessorSubclass,
typename ElementsTraitsParam>
class ElementsAccessorBase : public ElementsAccessor {
protected:
+ template <typename SloppyArgumentsElementsAccessorSubclass,
+ typename ArgumentsAccessor, typename KindTraits>
+ friend class SloppyArgumentsElementsAccessor;
explicit ElementsAccessorBase(const char* name)
: ElementsAccessor(name) { }
@@ -922,6 +924,12 @@ class ElementsAccessorBase : public ElementsAccessor {
};
+class FastSloppyArgumentsElementsAccessor;
+class FastHoleyObjectElementsAccessor;
+template <typename SloppyArgumentsElementsAccessorSubclass,
+ typename ArgumentsAccessor, typename KindTraits>
+class SloppyArgumentsElementsAccessor;
+
// Super class for all fast element arrays.
template<typename FastElementsAccessorSubclass,
typename KindTraits>
@@ -934,7 +942,9 @@ class FastElementsAccessor
protected:
friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
- friend class SloppyArgumentsElementsAccessor;
+ friend class SloppyArgumentsElementsAccessor<
+ FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
+ ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
typedef typename KindTraits::BackingStore BackingStore;
@@ -1066,33 +1076,6 @@ class FastElementsAccessor
};
-static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
- switch (array->map()->instance_type()) {
- case FIXED_ARRAY_TYPE:
- if (array->IsDictionary()) {
- return DICTIONARY_ELEMENTS;
- } else {
- return FAST_HOLEY_ELEMENTS;
- }
- case FIXED_DOUBLE_ARRAY_TYPE:
- return FAST_HOLEY_DOUBLE_ELEMENTS;
-
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
- case EXTERNAL_##TYPE##_ARRAY_TYPE: \
- return EXTERNAL_##TYPE##_ELEMENTS; \
- case FIXED_##TYPE##_ARRAY_TYPE: \
- return TYPE##_ELEMENTS;
-
- TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
-
- default:
- UNREACHABLE();
- }
- return FAST_HOLEY_ELEMENTS;
-}
-
-
template<typename FastElementsAccessorSubclass,
typename KindTraits>
class FastSmiOrObjectElementsAccessor
@@ -1132,17 +1115,9 @@ class FastSmiOrObjectElementsAccessor
CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
copy_size);
break;
- case SLOPPY_ARGUMENTS_ELEMENTS: {
- // TODO(verwaest): This is a temporary hack to support extending
- // SLOPPY_ARGUMENTS_ELEMENTS in GrowCapacityAndConvert.
- // This case should be UNREACHABLE().
- FixedArray* parameter_map = FixedArray::cast(from);
- FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
- ElementsKind from_kind = ElementsKindForArray(arguments);
- CopyElementsImpl(arguments, from_start, to, from_kind,
- to_start, packed_size, copy_size);
- break;
- }
+ case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
+ case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
+ UNREACHABLE();
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case EXTERNAL_##TYPE##_ELEMENTS: \
case TYPE##_ELEMENTS: \
@@ -1237,7 +1212,8 @@ class FastDoubleElementsAccessor
CopyDictionaryToDoubleElements(from, from_start, to, to_start,
copy_size);
break;
- case SLOPPY_ARGUMENTS_ELEMENTS:
+ case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
+ case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
@@ -1355,6 +1331,8 @@ TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
#undef FIXED_ELEMENTS_ACCESSOR
+class SlowSloppyArgumentsElementsAccessor;
+
class DictionaryElementsAccessor
: public ElementsAccessorBase<DictionaryElementsAccessor,
@@ -1417,13 +1395,28 @@ class DictionaryElementsAccessor
array->set_length(*length_obj);
}
+ static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+ FixedArrayBase* to, ElementsKind from_kind,
+ uint32_t to_start, int packed_size,
+ int copy_size) {
+ UNREACHABLE();
+ }
+
+
+ protected:
+ friend class ElementsAccessorBase<DictionaryElementsAccessor,
+ ElementsKindTraits<DICTIONARY_ELEMENTS> >;
+ friend class SlowSloppyArgumentsElementsAccessor;
+ friend class SloppyArgumentsElementsAccessor<
+ SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
+
static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
LanguageMode language_mode) {
Isolate* isolate = obj->GetIsolate();
Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
isolate);
- bool is_arguments =
- (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
+ bool is_arguments = obj->HasSloppyArgumentsElements();
if (is_arguments) {
backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
}
@@ -1446,18 +1439,6 @@ class DictionaryElementsAccessor
}
}
- static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
- FixedArrayBase* to, ElementsKind from_kind,
- uint32_t to_start, int packed_size,
- int copy_size) {
- UNREACHABLE();
- }
-
-
- protected:
- friend class ElementsAccessorBase<DictionaryElementsAccessor,
- ElementsKindTraits<DICTIONARY_ELEMENTS> >;
-
virtual void Delete(Handle<JSObject> obj, uint32_t key,
LanguageMode language_mode) final {
DeleteCommon(obj, key, language_mode);
@@ -1556,18 +1537,19 @@ class DictionaryElementsAccessor
};
-class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
- SloppyArgumentsElementsAccessor,
- ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > {
+template <typename SloppyArgumentsElementsAccessorSubclass,
+ typename ArgumentsAccessor, typename KindTraits>
+class SloppyArgumentsElementsAccessor
+ : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
+ KindTraits> {
public:
explicit SloppyArgumentsElementsAccessor(const char* name)
- : ElementsAccessorBase<
- SloppyArgumentsElementsAccessor,
- ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
+ : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
+ KindTraits>(name) {}
+
protected:
- friend class ElementsAccessorBase<
- SloppyArgumentsElementsAccessor,
- ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
+ friend class ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
+ KindTraits>;
static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
Handle<FixedArrayBase> parameters) {
@@ -1584,8 +1566,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
// Object is not mapped, defer to the arguments.
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
isolate);
- Handle<Object> result =
- ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments);
+ Handle<Object> result = ArgumentsAccessor::GetImpl(obj, key, arguments);
// Elements of the arguments object in slow mode might be slow aliases.
if (result->IsAliasedArgumentsEntry()) {
DisallowHeapAllocation no_gc;
@@ -1600,20 +1581,22 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
}
+ virtual void Delete(Handle<JSObject> obj, uint32_t key,
+ LanguageMode language_mode) final {
+ FixedArray* parameter_map = FixedArray::cast(obj->elements());
+ if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) {
+ // TODO(kmillikin): We could check if this was the last aliased
+ // parameter, and revert to normal elements in that case. That
+ // would enable GC of the context.
+ parameter_map->set_the_hole(key + 2);
+ } else {
+ ArgumentsAccessor::DeleteCommon(obj, key, language_mode);
+ }
+ }
+
static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
uint32_t capacity) {
- Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
- Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
- ElementsKind from_kind = old_elements->IsDictionary() ? DICTIONARY_ELEMENTS
- : FAST_HOLEY_ELEMENTS;
- // This method should only be called if there's a reason to update the
- // elements.
- DCHECK(IsDictionaryElementsKind(from_kind) ||
- static_cast<uint32_t>(old_elements->length()) < capacity);
- Handle<FixedArrayBase> elements =
- ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
- parameter_map->set(1, *elements);
- JSObject::ValidateElements(object);
+ UNREACHABLE();
}
static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
@@ -1626,62 +1609,10 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
context->set(context_index, value);
} else {
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
- ElementsAccessor::ForArray(arguments)->Set(arguments, key, value);
- }
- }
-
- static void ReconfigureImpl(Handle<JSObject> object,
- Handle<FixedArrayBase> store, uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes) {
- Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
- uint32_t length = parameter_map->length() - 2;
- if (index < length) {
- Object* probe = parameter_map->get(index + 2);
- DCHECK(!probe->IsTheHole());
- Context* context = Context::cast(parameter_map->get(0));
- int context_index = Smi::cast(probe)->value();
- DCHECK(!context->get(context_index)->IsTheHole());
- context->set(context_index, *value);
-
- // Redefining attributes of an aliased element destroys fast aliasing.
- parameter_map->set_the_hole(index + 2);
- // For elements that are still writable we re-establish slow aliasing.
- if ((attributes & READ_ONLY) == 0) {
- Isolate* isolate = store->GetIsolate();
- value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
- }
-
- PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
- Handle<SeededNumberDictionary> arguments =
- parameter_map->get(1)->IsSeededNumberDictionary()
- ? handle(SeededNumberDictionary::cast(parameter_map->get(1)))
- : JSObject::NormalizeElements(object);
- arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
- value, details);
- parameter_map->set(1, *arguments);
- } else {
- Handle<FixedArrayBase> arguments(
- FixedArrayBase::cast(parameter_map->get(1)));
- ElementsAccessor::ForArray(arguments)
- ->Reconfigure(object, arguments, index - length, value, attributes);
+ ArgumentsAccessor::SetImpl(arguments, key, value);
}
}
- static void AddImpl(Handle<JSObject> object, uint32_t key,
- Handle<Object> value, PropertyAttributes attributes,
- uint32_t new_capacity) {
- DCHECK_EQ(NONE, attributes);
- Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
- Handle<FixedArrayBase> old_elements(
- FixedArrayBase::cast(parameter_map->get(1)));
- if (old_elements->IsSeededNumberDictionary() ||
- static_cast<uint32_t>(old_elements->length()) < new_capacity) {
- GrowCapacityAndConvertImpl(object, new_capacity);
- }
- SetImpl(object->elements(), key, *value);
- }
-
static MaybeHandle<AccessorPair> GetAccessorPairImpl(
Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
@@ -1692,8 +1623,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
} else {
// If not aliased, check the arguments.
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
- return ElementsAccessor::ForArray(arguments)
- ->GetAccessorPair(obj, key, arguments);
+ return ArgumentsAccessor::GetAccessorPairImpl(obj, key, arguments);
}
}
@@ -1703,50 +1633,12 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
UNREACHABLE();
}
- virtual void Delete(Handle<JSObject> obj, uint32_t key,
- LanguageMode language_mode) final {
- Isolate* isolate = obj->GetIsolate();
- Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
- Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
- if (!probe->IsTheHole()) {
- // TODO(kmillikin): We could check if this was the last aliased
- // parameter, and revert to normal elements in that case. That
- // would enable GC of the context.
- parameter_map->set_the_hole(key + 2);
- } else {
- Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
- if (arguments->IsDictionary()) {
- DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
- } else {
- // It's difficult to access the version of DeleteCommon that is declared
- // in the templatized super class, call the concrete implementation in
- // the class for the most generalized ElementsKind subclass.
- FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
- }
- }
- }
-
- static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
- FixedArrayBase* to, ElementsKind from_kind,
- uint32_t to_start, int packed_size,
- int copy_size) {
- DCHECK(!to->IsDictionary());
- if (from_kind == DICTIONARY_ELEMENTS) {
- CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
- to_start, copy_size);
- } else {
- DCHECK_EQ(FAST_HOLEY_ELEMENTS, from_kind);
- CopyObjectToObjectElements(from, from_kind, from_start, to,
- FAST_HOLEY_ELEMENTS, to_start, copy_size);
- }
- }
-
static uint32_t GetCapacityImpl(JSObject* holder,
FixedArrayBase* backing_store) {
FixedArray* parameter_map = FixedArray::cast(backing_store);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
return parameter_map->length() - 2 +
- ForArray(arguments)->GetCapacity(holder, arguments);
+ ArgumentsAccessor::GetCapacityImpl(holder, arguments);
}
static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
@@ -1757,7 +1649,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
- return ForArray(arguments)->HasIndex(arguments, index - length);
+ return ArgumentsAccessor::HasIndexImpl(arguments, index - length);
}
static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
@@ -1767,7 +1659,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
if (index < length) return index;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
- return ForArray(arguments)->GetKeyForIndex(arguments, index - length);
+ return ArgumentsAccessor::GetKeyForIndexImpl(arguments, index - length);
}
static uint32_t GetIndexForKeyImpl(JSObject* holder,
@@ -1777,8 +1669,8 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
if (!probe->IsTheHole()) return key;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
- uint32_t index = ElementsAccessor::ForArray(arguments)
- ->GetIndexForKey(holder, arguments, key);
+ uint32_t index =
+ ArgumentsAccessor::GetIndexForKeyImpl(holder, arguments, key);
if (index == kMaxUInt32) return index;
return (parameter_map->length() - 2) + index;
}
@@ -1792,10 +1684,9 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
index -= length;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
- return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index);
+ return ArgumentsAccessor::GetDetailsImpl(arguments, index);
}
- private:
static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
uint32_t length = parameter_map->length() - 2;
return key < length
@@ -1805,14 +1696,160 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
};
-ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
- return elements_accessors_[ElementsKindForArray(array)];
-}
+class FastSloppyArgumentsElementsAccessor
+ : public SloppyArgumentsElementsAccessor<
+ FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
+ ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
+ public:
+ friend class SloppyArgumentsElementsAccessor<
+ FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
+ ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
+ friend class ElementsAccessorBase<
+ FastSloppyArgumentsElementsAccessor,
+ ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
+ explicit FastSloppyArgumentsElementsAccessor(const char* name)
+ : SloppyArgumentsElementsAccessor<
+ FastSloppyArgumentsElementsAccessor,
+ FastHoleyObjectElementsAccessor,
+ ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
+
+ protected:
+ static void AddImpl(Handle<JSObject> object, uint32_t key,
+ Handle<Object> value, PropertyAttributes attributes,
+ uint32_t new_capacity) {
+ DCHECK_EQ(NONE, attributes);
+ Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
+ Handle<FixedArrayBase> old_elements(
+ FixedArrayBase::cast(parameter_map->get(1)));
+ if (old_elements->IsSeededNumberDictionary() ||
+ static_cast<uint32_t>(old_elements->length()) < new_capacity) {
+ GrowCapacityAndConvertImpl(object, new_capacity);
+ }
+ SetImpl(object->elements(), key, *value);
+ }
+ static void ReconfigureImpl(Handle<JSObject> object,
+ Handle<FixedArrayBase> store, uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ Handle<SeededNumberDictionary> dictionary =
+ JSObject::NormalizeElements(object);
+ FixedArray::cast(*store)->set(1, *dictionary);
+ uint32_t length = static_cast<uint32_t>(store->length()) - 2;
+ if (index >= length) {
+ index = dictionary->FindEntry(index - length) + length;
+ }
+ object->GetElementsAccessor()->Reconfigure(object, store, index, value,
+ attributes);
+ }
-ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) {
- return ForArray(*array);
-}
+ static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+ FixedArrayBase* to, ElementsKind from_kind,
+ uint32_t to_start, int packed_size,
+ int copy_size) {
+ DCHECK(!to->IsDictionary());
+ if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
+ CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
+ to_start, copy_size);
+ } else {
+ DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, from_kind);
+ CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to,
+ FAST_HOLEY_ELEMENTS, to_start, copy_size);
+ }
+ }
+
+ static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
+ uint32_t capacity) {
+ Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
+ Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
+ ElementsKind from_kind = object->GetElementsKind();
+ // This method should only be called if there's a reason to update the
+ // elements.
+ DCHECK(from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS ||
+ static_cast<uint32_t>(old_elements->length()) < capacity);
+ Handle<FixedArrayBase> elements =
+ ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
+ Handle<Map> new_map = JSObject::GetElementsTransitionMap(
+ object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
+ JSObject::MigrateToMap(object, new_map);
+ parameter_map->set(1, *elements);
+ JSObject::ValidateElements(object);
+ }
+};
+
+
+class SlowSloppyArgumentsElementsAccessor
+ : public SloppyArgumentsElementsAccessor<
+ SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
+ public:
+ friend class ElementsAccessorBase<
+ SlowSloppyArgumentsElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
+ friend class SloppyArgumentsElementsAccessor<
+ SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
+ explicit SlowSloppyArgumentsElementsAccessor(const char* name)
+ : SloppyArgumentsElementsAccessor<
+ SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
+
+ protected:
+ static void AddImpl(Handle<JSObject> object, uint32_t key,
+ Handle<Object> value, PropertyAttributes attributes,
+ uint32_t new_capacity) {
+ Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
+ Handle<FixedArrayBase> old_elements(
+ FixedArrayBase::cast(parameter_map->get(1)));
+ Handle<SeededNumberDictionary> dictionary =
+ old_elements->IsSeededNumberDictionary()
+ ? Handle<SeededNumberDictionary>::cast(old_elements)
+ : JSObject::NormalizeElements(object);
+ PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
+ Handle<SeededNumberDictionary> new_dictionary =
+ SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details);
+ if (attributes != NONE) new_dictionary->set_requires_slow_elements();
+ if (*dictionary != *new_dictionary) {
+ FixedArray::cast(object->elements())->set(1, *new_dictionary);
+ }
+ }
+
+ static void ReconfigureImpl(Handle<JSObject> object,
+ Handle<FixedArrayBase> store, uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
+ uint32_t length = parameter_map->length() - 2;
+ if (index < length) {
+ Object* probe = parameter_map->get(index + 2);
+ DCHECK(!probe->IsTheHole());
+ Context* context = Context::cast(parameter_map->get(0));
+ int context_index = Smi::cast(probe)->value();
+ DCHECK(!context->get(context_index)->IsTheHole());
+ context->set(context_index, *value);
+
+ // Redefining attributes of an aliased element destroys fast aliasing.
+ parameter_map->set_the_hole(index + 2);
+ // For elements that are still writable we re-establish slow aliasing.
+ if ((attributes & READ_ONLY) == 0) {
+ Isolate* isolate = store->GetIsolate();
+ value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
+ }
+
+ PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
+ Handle<SeededNumberDictionary> arguments(
+ SeededNumberDictionary::cast(parameter_map->get(1)));
+ arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
+ value, details);
+ parameter_map->set(1, *arguments);
+ } else {
+ Handle<FixedArrayBase> arguments(
+ FixedArrayBase::cast(parameter_map->get(1)));
+ DictionaryElementsAccessor::ReconfigureImpl(
+ object, arguments, index - length, value, attributes);
+ }
+ }
+};
void ElementsAccessor::InitializeOncePerProcess() {
« no previous file with comments | « src/elements.h ('k') | src/elements-kind.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698