Commit f461c7a6 authored by verwaest's avatar verwaest Committed by Commit bot

Move reconfiguration into the elements accessor

BUG=v8:4137
LOG=n

Review URL: https://codereview.chromium.org/1207613005

Cr-Commit-Position: refs/heads/master@{#29289}
parent 35eb3a02
...@@ -623,6 +623,21 @@ class ElementsAccessorBase : public ElementsAccessor { ...@@ -623,6 +623,21 @@ class ElementsAccessorBase : public ElementsAccessor {
BackingStore::cast(backing_store)->SetValue(key, value); BackingStore::cast(backing_store)->SetValue(key, value);
} }
virtual void Reconfigure(Handle<JSObject> object,
Handle<FixedArrayBase> store, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) final {
ElementsAccessorSubclass::ReconfigureImpl(object, store, index, value,
attributes);
}
static void ReconfigureImpl(Handle<JSObject> object,
Handle<FixedArrayBase> store, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
UNREACHABLE();
}
virtual MaybeHandle<AccessorPair> GetAccessorPair( virtual MaybeHandle<AccessorPair> GetAccessorPair(
Handle<JSObject> holder, uint32_t key, Handle<JSObject> holder, uint32_t key,
Handle<FixedArrayBase> backing_store) final { Handle<FixedArrayBase> backing_store) final {
...@@ -903,6 +918,18 @@ class FastElementsAccessor ...@@ -903,6 +918,18 @@ class FastElementsAccessor
explicit FastElementsAccessor(const char* name) explicit FastElementsAccessor(const char* name)
: ElementsAccessorBase<FastElementsAccessorSubclass, : ElementsAccessorBase<FastElementsAccessorSubclass,
KindTraits>(name) {} KindTraits>(name) {}
static void ReconfigureImpl(Handle<JSObject> object,
Handle<FixedArrayBase> store, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
Handle<SeededNumberDictionary> dictionary =
JSObject::NormalizeElements(object);
index = dictionary->FindEntry(index);
object->GetElementsAccessor()->Reconfigure(object, dictionary, index, value,
attributes);
}
protected: protected:
friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
friend class SloppyArgumentsElementsAccessor; friend class SloppyArgumentsElementsAccessor;
...@@ -1409,10 +1436,23 @@ class DictionaryElementsAccessor ...@@ -1409,10 +1436,23 @@ class DictionaryElementsAccessor
} }
static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
int entry = backing_store->FindEntry(key); int entry = dictionary->FindEntry(key);
DCHECK_NE(SeededNumberDictionary::kNotFound, entry); DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
backing_store->ValueAtPut(entry, value); 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 MaybeHandle<AccessorPair> GetAccessorPairImpl( static MaybeHandle<AccessorPair> GetAccessorPairImpl(
...@@ -1533,6 +1573,44 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< ...@@ -1533,6 +1573,44 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
} }
} }
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);
}
}
static MaybeHandle<AccessorPair> GetAccessorPairImpl( static MaybeHandle<AccessorPair> GetAccessorPairImpl(
Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) { Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
......
...@@ -140,6 +140,10 @@ class ElementsAccessor { ...@@ -140,6 +140,10 @@ class ElementsAccessor {
virtual void Set(FixedArrayBase* backing_store, uint32_t key, virtual void Set(FixedArrayBase* backing_store, uint32_t key,
Object* value) = 0; Object* value) = 0;
virtual void Reconfigure(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) = 0;
protected: protected:
friend class SloppyArgumentsElementsAccessor; friend class SloppyArgumentsElementsAccessor;
......
...@@ -156,19 +156,12 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value, ...@@ -156,19 +156,12 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
DCHECK(HolderIsReceiverOrHiddenPrototype()); DCHECK(HolderIsReceiverOrHiddenPrototype());
Handle<JSObject> holder = GetHolder<JSObject>(); Handle<JSObject> holder = GetHolder<JSObject>();
if (IsElement()) { if (IsElement()) {
// TODO(verwaest): Clean up. DCHECK(!holder->HasExternalArrayElements());
DCHECK(holder->HasFastElements() || holder->HasDictionaryElements() || DCHECK(!holder->HasFixedTypedArrayElements());
holder->HasSloppyArgumentsElements());
DCHECK(attributes != NONE || !holder->HasFastElements()); DCHECK(attributes != NONE || !holder->HasFastElements());
Handle<SeededNumberDictionary> d = JSObject::NormalizeElements(holder); Handle<FixedArrayBase> elements(holder->elements());
// TODO(verwaest): Move this into NormalizeElements. holder->GetElementsAccessor()->Reconfigure(holder, elements, number_, value,
d->set_requires_slow_elements(); attributes);
if (holder->HasDictionaryElements()) {
JSObject::SetDictionaryElement(holder, index(), value, attributes);
} else {
JSObject::SetDictionaryArgumentsElement(holder, index(), value,
attributes);
}
} else if (holder_map_->is_dictionary_map()) { } else if (holder_map_->is_dictionary_map()) {
PropertyDetails details(attributes, v8::internal::DATA, 0, PropertyDetails details(attributes, v8::internal::DATA, 0,
PropertyCellType::kMutable); PropertyCellType::kMutable);
......
...@@ -12292,89 +12292,6 @@ static void AddDictionaryElement(Handle<JSObject> object, ...@@ -12292,89 +12292,6 @@ static void AddDictionaryElement(Handle<JSObject> object,
} }
void JSObject::SetDictionaryArgumentsElement(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
// TODO(verwaest): Handle with the elements accessor.
Isolate* isolate = object->GetIsolate();
DCHECK(object->HasDictionaryArgumentsElements());
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
uint32_t length = parameter_map->length();
Handle<Object> probe =
index < length - 2
? handle(parameter_map->get(index + 2), isolate)
: Handle<Object>::cast(isolate->factory()->the_hole_value());
if (!probe->IsTheHole()) {
Handle<Context> context(Context::cast(parameter_map->get(0)));
int context_index = Handle<Smi>::cast(probe)->value();
DCHECK(!context->get(context_index)->IsTheHole());
context->set(context_index, *value);
DCHECK_NE(NONE, attributes);
// 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) {
value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
}
Handle<SeededNumberDictionary> dictionary(
SeededNumberDictionary::cast(parameter_map->get(1)));
AddDictionaryElement(object, dictionary, index, value, attributes);
} else {
SetDictionaryElement(object, index, value, attributes);
}
}
void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
// TODO(verwaest): Handle with the elements accessor.
Isolate* isolate = object->GetIsolate();
// Insert element in the dictionary.
Handle<FixedArray> elements(FixedArray::cast(object->elements()));
bool is_arguments =
(elements->map() == isolate->heap()->sloppy_arguments_elements_map());
DCHECK(object->HasDictionaryElements() ||
object->HasDictionaryArgumentsElements());
Handle<SeededNumberDictionary> dictionary(is_arguments
? SeededNumberDictionary::cast(elements->get(1))
: SeededNumberDictionary::cast(*elements));
int entry = dictionary->FindEntry(index);
DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
PropertyDetails details = dictionary->DetailsAt(entry);
details = PropertyDetails(attributes, DATA, details.dictionary_index(),
PropertyCellType::kNoCell);
dictionary->DetailsAtPut(entry, details);
// Elements of the arguments object in slow mode might be slow aliases.
if (is_arguments) {
Handle<Object> element(dictionary->ValueAt(entry), isolate);
if (element->IsAliasedArgumentsEntry()) {
Handle<AliasedArgumentsEntry> entry =
Handle<AliasedArgumentsEntry>::cast(element);
Handle<Context> context(Context::cast(elements->get(0)));
int context_index = entry->aliased_context_slot();
DCHECK(!context->get(context_index)->IsTheHole());
context->set(context_index, *value);
// For elements that are still writable we keep slow aliasing.
if (!details.IsReadOnly()) value = element;
}
}
dictionary->ValueAtPut(entry, *value);
}
// static // static
MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
uint32_t index, Handle<Object> value, uint32_t index, Handle<Object> 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