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:
parent
5f24690384
commit
103675d68b
@ -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);
|
||||
}
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user