Replace Set*Callback with TransitionToAccessorPair

BUG=v8:4137
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#29649}
This commit is contained in:
verwaest 2015-07-14 04:58:32 -07:00 committed by Commit bot
parent 5f24690384
commit 103675d68b
4 changed files with 24 additions and 85 deletions

View File

@ -277,9 +277,9 @@ void LookupIterator::TransitionToAccessorProperty(
// handled via a trap. Adding properties to primitive values is not
// observable.
Handle<JSObject> receiver = GetStoreTarget();
holder_ = receiver;
if (!IsElement() && !receiver->map()->is_dictionary_map()) {
holder_ = receiver;
holder_map_ = Map::TransitionToAccessorProperty(
handle(receiver->map(), isolate_), name_, component, accessor,
attributes);
@ -290,8 +290,6 @@ void LookupIterator::TransitionToAccessorProperty(
if (!holder_map_->is_dictionary_map()) return;
}
PropertyDetails details(attributes, ACCESSOR_CONSTANT, 0,
PropertyCellType::kMutable);
Handle<AccessorPair> pair;
if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) {
pair = Handle<AccessorPair>::cast(GetAccessors());
@ -307,6 +305,18 @@ void LookupIterator::TransitionToAccessorProperty(
pair->set(component, *accessor);
}
TransitionToAccessorPair(pair, attributes);
}
void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
PropertyAttributes attributes) {
Handle<JSObject> receiver = GetStoreTarget();
holder_ = receiver;
PropertyDetails details(attributes, ACCESSOR_CONSTANT, 0,
PropertyCellType::kMutable);
if (IsElement()) {
// TODO(verwaest): Remove this hack once we have a quick way to check the
// prototype chain in element setters.
@ -331,6 +341,13 @@ void LookupIterator::TransitionToAccessorProperty(
if (!was_dictionary) heap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
}
} else {
PropertyNormalizationMode mode = receiver->map()->is_prototype_map()
? KEEP_INOBJECT_PROPERTIES
: CLEAR_INOBJECT_PROPERTIES;
// Normalize object to make this operation simple.
JSObject::NormalizeProperties(receiver, mode, 0,
"TransitionToAccessorPair");
JSObject::SetNormalizedProperty(receiver, name_, pair, details);
JSObject::ReoptimizeIfPrototype(receiver);
}

View File

@ -222,6 +222,8 @@ class LookupIterator final BASE_EMBEDDED {
void TransitionToAccessorProperty(AccessorComponent component,
Handle<Object> accessor,
PropertyAttributes attributes);
void TransitionToAccessorPair(Handle<Object> pair,
PropertyAttributes attributes);
PropertyDetails property_details() const {
DCHECK(has_property_);
return property_details_;

View File

@ -4215,13 +4215,7 @@ MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
ExecutableAccessorInfo::ClearSetter(new_data);
}
if (it->IsElement()) {
SetElementCallback(it->GetHolder<JSObject>(), it->index(), new_data,
attributes);
} else {
SetPropertyCallback(it->GetHolder<JSObject>(), it->name(), new_data,
attributes);
}
it->TransitionToAccessorPair(new_data, attributes);
} else {
it->ReconfigureDataProperty(value, attributes);
it->WriteDataValue(value);
@ -6251,66 +6245,6 @@ bool Map::DictionaryElementsInPrototypeChainOnly() {
}
void JSObject::SetElementCallback(Handle<JSObject> object,
uint32_t index,
Handle<Object> structure,
PropertyAttributes attributes) {
Heap* heap = object->GetHeap();
PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
PropertyCellType::kNoCell);
// Normalize elements to make this operation simple.
bool had_dictionary_elements = object->HasDictionaryElements();
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
// Update the dictionary with the new ACCESSOR_CONSTANT property.
dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
details);
dictionary->set_requires_slow_elements();
// Update the dictionary backing store on the object.
if (object->elements()->map() == heap->sloppy_arguments_elements_map()) {
// Also delete any parameter alias.
//
// TODO(kmillikin): when deleting the last parameter alias we could
// switch to a direct backing store without the parameter map. This
// would allow GC of the context.
FixedArray* parameter_map = FixedArray::cast(object->elements());
if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
parameter_map->set(index + 2, heap->the_hole_value());
}
parameter_map->set(1, *dictionary);
} else {
object->set_elements(*dictionary);
if (!had_dictionary_elements) {
// KeyedStoreICs (at least the non-generic ones) need a reset.
heap->ClearAllICsByKind(Code::KEYED_STORE_IC);
}
}
}
void JSObject::SetPropertyCallback(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> structure,
PropertyAttributes attributes) {
PropertyNormalizationMode mode = object->map()->is_prototype_map()
? KEEP_INOBJECT_PROPERTIES
: CLEAR_INOBJECT_PROPERTIES;
// Normalize object to make this operation simple.
NormalizeProperties(object, mode, 0, "SetPropertyCallback");
// Update the dictionary with the new ACCESSOR_CONSTANT property.
PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
PropertyCellType::kMutable);
SetNormalizedProperty(object, name, structure, details);
ReoptimizeIfPrototype(object);
}
MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> getter,
@ -6420,11 +6354,7 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
return it.factory()->undefined_value();
}
if (it.IsElement()) {
SetElementCallback(object, it.index(), info, info->property_attributes());
} else {
SetPropertyCallback(object, name, info, info->property_attributes());
}
it.TransitionToAccessorPair(info, info->property_attributes());
return object;
}

View File

@ -2310,16 +2310,6 @@ class JSObject: public JSReceiver {
ElementsKind kind,
Object* object);
static bool CanSetCallback(Handle<JSObject> object, Handle<Name> name);
static void SetElementCallback(Handle<JSObject> object,
uint32_t index,
Handle<Object> structure,
PropertyAttributes attributes);
static void SetPropertyCallback(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> structure,
PropertyAttributes attributes);
// Return the hash table backing store or the inline stored identity hash,
// whatever is found.
MUST_USE_RESULT Object* GetHiddenPropertiesHashTable();