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

Unified Diff: src/elements.cc

Issue 1225493002: Move slow classes above fast to directly call ReconfigureImpl, remove friends, make things public (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Just make everything public within elements.cc 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 | « no previous file | no next file » | 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 3c6e2726ce4f8803b2d23a8313aeb3ba57806dfe..2082543a2473a7ccde8db3f562669cd38e6102f7 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -548,10 +548,7 @@ void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t key,
template <typename ElementsAccessorSubclass,
typename ElementsTraitsParam>
class ElementsAccessorBase : public ElementsAccessor {
- protected:
- template <typename SloppyArgumentsElementsAccessorSubclass,
- typename ArgumentsAccessor, typename KindTraits>
- friend class SloppyArgumentsElementsAccessor;
+ public:
explicit ElementsAccessorBase(const char* name)
: ElementsAccessor(name) { }
@@ -864,7 +861,6 @@ class ElementsAccessorBase : public ElementsAccessor {
return result;
}
- protected:
static uint32_t GetCapacityImpl(JSObject* holder,
FixedArrayBase* backing_store) {
return backing_store->length();
@@ -924,11 +920,200 @@ class ElementsAccessorBase : public ElementsAccessor {
};
-class FastSloppyArgumentsElementsAccessor;
-class FastHoleyObjectElementsAccessor;
-template <typename SloppyArgumentsElementsAccessorSubclass,
- typename ArgumentsAccessor, typename KindTraits>
-class SloppyArgumentsElementsAccessor;
+class DictionaryElementsAccessor
+ : public ElementsAccessorBase<DictionaryElementsAccessor,
+ ElementsKindTraits<DICTIONARY_ELEMENTS> > {
+ public:
+ explicit DictionaryElementsAccessor(const char* name)
+ : ElementsAccessorBase<DictionaryElementsAccessor,
+ ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
+
+ static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
+ Handle<FixedArrayBase> backing_store) {
+ Handle<SeededNumberDictionary> dict =
+ Handle<SeededNumberDictionary>::cast(backing_store);
+ Isolate* isolate = array->GetIsolate();
+ int capacity = dict->Capacity();
+ uint32_t old_length = 0;
+ CHECK(array->length()->ToArrayLength(&old_length));
+ if (length < old_length) {
+ if (dict->requires_slow_elements()) {
+ // Find last non-deletable element in range of elements to be
+ // deleted and adjust range accordingly.
+ for (int i = 0; i < capacity; i++) {
+ DisallowHeapAllocation no_gc;
+ Object* key = dict->KeyAt(i);
+ if (key->IsNumber()) {
+ uint32_t number = static_cast<uint32_t>(key->Number());
+ if (length <= number && number < old_length) {
+ PropertyDetails details = dict->DetailsAt(i);
+ if (!details.IsConfigurable()) length = number + 1;
+ }
+ }
+ }
+ }
+
+ if (length == 0) {
+ // Flush the backing store.
+ JSObject::ResetElements(array);
+ } else {
+ DisallowHeapAllocation no_gc;
+ // Remove elements that should be deleted.
+ int removed_entries = 0;
+ Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
+ for (int i = 0; i < capacity; i++) {
+ Object* key = dict->KeyAt(i);
+ if (key->IsNumber()) {
+ uint32_t number = static_cast<uint32_t>(key->Number());
+ if (length <= number && number < old_length) {
+ dict->SetEntry(i, the_hole_value, the_hole_value);
+ removed_entries++;
+ }
+ }
+ }
+
+ // Update the number of elements.
+ dict->ElementsRemoved(removed_entries);
+ }
+ }
+
+ Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
+ 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();
+ }
+
+
+ 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->HasSloppyArgumentsElements();
+ if (is_arguments) {
+ backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
+ }
+ Handle<SeededNumberDictionary> dictionary =
+ Handle<SeededNumberDictionary>::cast(backing_store);
+ int entry = dictionary->FindEntry(key);
+ if (entry != SeededNumberDictionary::kNotFound) {
+ Handle<Object> result =
+ SeededNumberDictionary::DeleteProperty(dictionary, entry);
+ USE(result);
+ DCHECK(result->IsTrue());
+ Handle<FixedArray> new_elements =
+ SeededNumberDictionary::Shrink(dictionary, key);
+
+ if (is_arguments) {
+ FixedArray::cast(obj->elements())->set(1, *new_elements);
+ } else {
+ obj->set_elements(*new_elements);
+ }
+ }
+ }
+
+ virtual void Delete(Handle<JSObject> obj, uint32_t key,
+ LanguageMode language_mode) final {
+ DeleteCommon(obj, key, language_mode);
+ }
+
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
+ Handle<FixedArrayBase> store) {
+ Handle<SeededNumberDictionary> backing_store =
+ Handle<SeededNumberDictionary>::cast(store);
+ Isolate* isolate = backing_store->GetIsolate();
+ int entry = backing_store->FindEntry(key);
+ if (entry != SeededNumberDictionary::kNotFound) {
+ return handle(backing_store->ValueAt(entry), isolate);
+ }
+ return isolate->factory()->the_hole_value();
+ }
+
+ static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
+ SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
+ int entry = dictionary->FindEntry(key);
+ DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
+ dictionary->ValueAtPut(entry, value);
+ }
+
+ static void ReconfigureImpl(Handle<JSObject> object,
+ Handle<FixedArrayBase> store, uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
+ if (attributes != NONE) dictionary->set_requires_slow_elements();
+ dictionary->ValueAtPut(index, *value);
+ PropertyDetails details = dictionary->DetailsAt(index);
+ details = PropertyDetails(attributes, DATA, details.dictionary_index(),
+ PropertyCellType::kNoCell);
+ dictionary->DetailsAtPut(index, details);
+ }
+
+ static void AddImpl(Handle<JSObject> object, uint32_t index,
+ Handle<Object> value, PropertyAttributes attributes,
+ uint32_t new_capacity) {
+ PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
+ Handle<SeededNumberDictionary> dictionary =
+ object->HasFastElements()
+ ? JSObject::NormalizeElements(object)
+ : handle(SeededNumberDictionary::cast(object->elements()));
+ Handle<SeededNumberDictionary> new_dictionary =
+ SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
+ details);
+ if (attributes != NONE) new_dictionary->set_requires_slow_elements();
+ if (dictionary.is_identical_to(new_dictionary)) return;
+ object->set_elements(*new_dictionary);
+ }
+
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
+ Handle<SeededNumberDictionary> backing_store =
+ Handle<SeededNumberDictionary>::cast(store);
+ int entry = backing_store->FindEntry(key);
+ if (entry != SeededNumberDictionary::kNotFound &&
+ backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT &&
+ backing_store->ValueAt(entry)->IsAccessorPair()) {
+ return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
+ }
+ return MaybeHandle<AccessorPair>();
+ }
+
+ static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) {
+ DisallowHeapAllocation no_gc;
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
+ Object* key = dict->KeyAt(index);
+ return !key->IsTheHole();
+ }
+
+ static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) {
+ DisallowHeapAllocation no_gc;
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
+ uint32_t result = 0;
+ CHECK(dict->KeyAt(index)->ToArrayIndex(&result));
+ return result;
+ }
+
+ static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store,
+ uint32_t key) {
+ DisallowHeapAllocation no_gc;
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
+ int entry = dict->FindEntry(key);
+ return entry == SeededNumberDictionary::kNotFound
+ ? kMaxUInt32
+ : static_cast<uint32_t>(entry);
+ }
+
+ static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
+ uint32_t index) {
+ return SeededNumberDictionary::cast(backing_store)->DetailsAt(index);
+ }
+};
+
// Super class for all fast element arrays.
template<typename FastElementsAccessorSubclass,
@@ -940,12 +1125,6 @@ class FastElementsAccessor
: ElementsAccessorBase<FastElementsAccessorSubclass,
KindTraits>(name) {}
- protected:
- friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
- friend class SloppyArgumentsElementsAccessor<
- FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
- ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
-
typedef typename KindTraits::BackingStore BackingStore;
static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
@@ -1011,8 +1190,8 @@ class FastElementsAccessor
Handle<SeededNumberDictionary> dictionary =
JSObject::NormalizeElements(object);
index = dictionary->FindEntry(index);
- object->GetElementsAccessor()->Reconfigure(object, dictionary, index, value,
- attributes);
+ DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, index,
+ value, attributes);
}
static void AddImpl(Handle<JSObject> object, uint32_t index,
@@ -1186,7 +1365,6 @@ class FastDoubleElementsAccessor
: FastElementsAccessor<FastElementsAccessorSubclass,
KindTraits>(name) {}
- protected:
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
FixedArrayBase* to, ElementsKind from_kind,
uint32_t to_start, int packed_size,
@@ -1232,8 +1410,6 @@ class FastPackedDoubleElementsAccessor
FastPackedDoubleElementsAccessor,
ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > {
public:
- friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor,
- ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
explicit FastPackedDoubleElementsAccessor(const char* name)
: FastDoubleElementsAccessor<
FastPackedDoubleElementsAccessor,
@@ -1246,9 +1422,6 @@ class FastHoleyDoubleElementsAccessor
FastHoleyDoubleElementsAccessor,
ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
public:
- friend class ElementsAccessorBase<
- FastHoleyDoubleElementsAccessor,
- ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >;
explicit FastHoleyDoubleElementsAccessor(const char* name)
: FastDoubleElementsAccessor<
FastHoleyDoubleElementsAccessor,
@@ -1266,13 +1439,9 @@ class TypedElementsAccessor
: ElementsAccessorBase<AccessorClass,
ElementsKindTraits<Kind> >(name) {}
- protected:
typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
typedef TypedElementsAccessor<Kind> AccessorClass;
- friend class ElementsAccessorBase<AccessorClass,
- ElementsKindTraits<Kind> >;
-
static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
Handle<FixedArrayBase> backing_store) {
if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
@@ -1331,268 +1500,58 @@ TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
#undef FIXED_ELEMENTS_ACCESSOR
-class SlowSloppyArgumentsElementsAccessor;
+template <typename SloppyArgumentsElementsAccessorSubclass,
+ typename ArgumentsAccessor, typename KindTraits>
+class SloppyArgumentsElementsAccessor
+ : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
+ KindTraits> {
+ public:
+ explicit SloppyArgumentsElementsAccessor(const char* name)
+ : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
+ KindTraits>(name) {}
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
+ Handle<FixedArrayBase> parameters) {
+ Isolate* isolate = obj->GetIsolate();
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
+ if (!probe->IsTheHole()) {
+ DisallowHeapAllocation no_gc;
+ Context* context = Context::cast(parameter_map->get(0));
+ int context_index = Handle<Smi>::cast(probe)->value();
+ DCHECK(!context->get(context_index)->IsTheHole());
+ return handle(context->get(context_index), isolate);
+ } else {
+ // Object is not mapped, defer to the arguments.
+ Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
+ isolate);
+ 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;
+ AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
+ Context* context = Context::cast(parameter_map->get(0));
+ int context_index = entry->aliased_context_slot();
+ DCHECK(!context->get(context_index)->IsTheHole());
+ return handle(context->get(context_index), isolate);
+ } else {
+ return result;
+ }
+ }
+ }
-class DictionaryElementsAccessor
- : public ElementsAccessorBase<DictionaryElementsAccessor,
- ElementsKindTraits<DICTIONARY_ELEMENTS> > {
- public:
- explicit DictionaryElementsAccessor(const char* name)
- : ElementsAccessorBase<DictionaryElementsAccessor,
- ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
-
- static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
- Handle<FixedArrayBase> backing_store) {
- Handle<SeededNumberDictionary> dict =
- Handle<SeededNumberDictionary>::cast(backing_store);
- Isolate* isolate = array->GetIsolate();
- int capacity = dict->Capacity();
- uint32_t old_length = 0;
- CHECK(array->length()->ToArrayLength(&old_length));
- if (length < old_length) {
- if (dict->requires_slow_elements()) {
- // Find last non-deletable element in range of elements to be
- // deleted and adjust range accordingly.
- for (int i = 0; i < capacity; i++) {
- DisallowHeapAllocation no_gc;
- Object* key = dict->KeyAt(i);
- if (key->IsNumber()) {
- uint32_t number = static_cast<uint32_t>(key->Number());
- if (length <= number && number < old_length) {
- PropertyDetails details = dict->DetailsAt(i);
- if (!details.IsConfigurable()) length = number + 1;
- }
- }
- }
- }
-
- if (length == 0) {
- // Flush the backing store.
- JSObject::ResetElements(array);
- } else {
- DisallowHeapAllocation no_gc;
- // Remove elements that should be deleted.
- int removed_entries = 0;
- Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
- for (int i = 0; i < capacity; i++) {
- Object* key = dict->KeyAt(i);
- if (key->IsNumber()) {
- uint32_t number = static_cast<uint32_t>(key->Number());
- if (length <= number && number < old_length) {
- dict->SetEntry(i, the_hole_value, the_hole_value);
- removed_entries++;
- }
- }
- }
-
- // Update the number of elements.
- dict->ElementsRemoved(removed_entries);
- }
- }
-
- Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
- 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->HasSloppyArgumentsElements();
- if (is_arguments) {
- backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
- }
- Handle<SeededNumberDictionary> dictionary =
- Handle<SeededNumberDictionary>::cast(backing_store);
- int entry = dictionary->FindEntry(key);
- if (entry != SeededNumberDictionary::kNotFound) {
- Handle<Object> result =
- SeededNumberDictionary::DeleteProperty(dictionary, entry);
- USE(result);
- DCHECK(result->IsTrue());
- Handle<FixedArray> new_elements =
- SeededNumberDictionary::Shrink(dictionary, key);
-
- if (is_arguments) {
- FixedArray::cast(obj->elements())->set(1, *new_elements);
- } else {
- obj->set_elements(*new_elements);
- }
- }
- }
-
- virtual void Delete(Handle<JSObject> obj, uint32_t key,
- LanguageMode language_mode) final {
- DeleteCommon(obj, key, language_mode);
- }
-
- static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
- Handle<FixedArrayBase> store) {
- Handle<SeededNumberDictionary> backing_store =
- Handle<SeededNumberDictionary>::cast(store);
- Isolate* isolate = backing_store->GetIsolate();
- int entry = backing_store->FindEntry(key);
- if (entry != SeededNumberDictionary::kNotFound) {
- return handle(backing_store->ValueAt(entry), isolate);
- }
- return isolate->factory()->the_hole_value();
- }
-
- static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
- SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
- int entry = dictionary->FindEntry(key);
- DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
- dictionary->ValueAtPut(entry, value);
- }
-
- static void ReconfigureImpl(Handle<JSObject> object,
- Handle<FixedArrayBase> store, uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes) {
- SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
- if (attributes != NONE) dictionary->set_requires_slow_elements();
- dictionary->ValueAtPut(index, *value);
- PropertyDetails details = dictionary->DetailsAt(index);
- details = PropertyDetails(attributes, DATA, details.dictionary_index(),
- PropertyCellType::kNoCell);
- dictionary->DetailsAtPut(index, details);
- }
-
- static void AddImpl(Handle<JSObject> object, uint32_t index,
- Handle<Object> value, PropertyAttributes attributes,
- uint32_t new_capacity) {
- PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
- Handle<SeededNumberDictionary> dictionary =
- object->HasFastElements()
- ? JSObject::NormalizeElements(object)
- : handle(SeededNumberDictionary::cast(object->elements()));
- Handle<SeededNumberDictionary> new_dictionary =
- SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
- details);
- if (attributes != NONE) new_dictionary->set_requires_slow_elements();
- if (dictionary.is_identical_to(new_dictionary)) return;
- object->set_elements(*new_dictionary);
- }
-
- static MaybeHandle<AccessorPair> GetAccessorPairImpl(
- Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
- Handle<SeededNumberDictionary> backing_store =
- Handle<SeededNumberDictionary>::cast(store);
- int entry = backing_store->FindEntry(key);
- if (entry != SeededNumberDictionary::kNotFound &&
- backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT &&
- backing_store->ValueAt(entry)->IsAccessorPair()) {
- return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
- }
- return MaybeHandle<AccessorPair>();
- }
-
- static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) {
- DisallowHeapAllocation no_gc;
- SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
- Object* key = dict->KeyAt(index);
- return !key->IsTheHole();
- }
-
- static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) {
- DisallowHeapAllocation no_gc;
- SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
- uint32_t result = 0;
- CHECK(dict->KeyAt(index)->ToArrayIndex(&result));
- return result;
- }
-
- static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store,
- uint32_t key) {
- DisallowHeapAllocation no_gc;
- SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
- int entry = dict->FindEntry(key);
- return entry == SeededNumberDictionary::kNotFound
- ? kMaxUInt32
- : static_cast<uint32_t>(entry);
- }
-
- static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
- uint32_t index) {
- return SeededNumberDictionary::cast(backing_store)->DetailsAt(index);
- }
-};
-
-
-template <typename SloppyArgumentsElementsAccessorSubclass,
- typename ArgumentsAccessor, typename KindTraits>
-class SloppyArgumentsElementsAccessor
- : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
- KindTraits> {
- public:
- explicit SloppyArgumentsElementsAccessor(const char* name)
- : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
- KindTraits>(name) {}
-
- protected:
- friend class ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
- KindTraits>;
-
- static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
- Handle<FixedArrayBase> parameters) {
- Isolate* isolate = obj->GetIsolate();
- Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
- Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
- if (!probe->IsTheHole()) {
- DisallowHeapAllocation no_gc;
- Context* context = Context::cast(parameter_map->get(0));
- int context_index = Handle<Smi>::cast(probe)->value();
- DCHECK(!context->get(context_index)->IsTheHole());
- return handle(context->get(context_index), isolate);
- } else {
- // Object is not mapped, defer to the arguments.
- Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
- isolate);
- 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;
- AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
- Context* context = Context::cast(parameter_map->get(0));
- int context_index = entry->aliased_context_slot();
- DCHECK(!context->get(context_index)->IsTheHole());
- return handle(context->get(context_index), isolate);
- } else {
- return result;
- }
- }
- }
-
- 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);
- }
- }
+ 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) {
@@ -1696,24 +1655,84 @@ class SloppyArgumentsElementsAccessor
};
+class SlowSloppyArgumentsElementsAccessor
+ : public SloppyArgumentsElementsAccessor<
+ SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
+ public:
+ explicit SlowSloppyArgumentsElementsAccessor(const char* name)
+ : SloppyArgumentsElementsAccessor<
+ SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
+
+ 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);
+ }
+ }
+};
+
+
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) {
@@ -1739,8 +1758,8 @@ class FastSloppyArgumentsElementsAccessor
if (index >= length) {
index = dictionary->FindEntry(index - length) + length;
}
- object->GetElementsAccessor()->Reconfigure(object, store, index, value,
- attributes);
+ SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, index,
+ value, attributes);
}
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
@@ -1778,80 +1797,6 @@ class FastSloppyArgumentsElementsAccessor
};
-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() {
static ElementsAccessor* accessor_array[] = {
#define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698