? JSObject::NormalizeElements(object)
: handle(SeededNumberDictionary::cast(object->elements()));
Handle<SeededNumberDictionary> new_dictionary =
- SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
- details);
+ SeededNumberDictionary::AddNumberEntry(
+ dictionary, index, value, details,
+ object->map()->is_prototype_map());
if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
if (dictionary.is_identical_to(new_dictionary)) return;
object->set_elements(*new_dictionary);
: JSObject::NormalizeElements(object);
PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
Handle<SeededNumberDictionary> new_dictionary =
- SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
- details);
+ SeededNumberDictionary::AddNumberEntry(
+ dictionary, index, value, details,
+ object->map()->is_prototype_map());
if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
if (*dictionary != *new_dictionary) {
FixedArray::cast(object->elements())->set(1, *new_dictionary);
PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
Handle<SeededNumberDictionary> arguments(
SeededNumberDictionary::cast(parameter_map->get(1)));
- arguments = SeededNumberDictionary::AddNumberEntry(arguments, entry,
- value, details);
+ arguments = SeededNumberDictionary::AddNumberEntry(
+ arguments, entry, value, details, object->map()->is_prototype_map());
// If the attributes were NONE, we would have called set rather than
// reconfigure.
DCHECK_NE(NONE, attributes);
static Handle<SeededNumberDictionary> CopyFastElementsToDictionary(
- Handle<FixedArrayBase> array,
- int length,
- Handle<SeededNumberDictionary> dictionary) {
+ Handle<FixedArrayBase> array, int length,
+ Handle<SeededNumberDictionary> dictionary, bool used_as_prototype) {
Isolate* isolate = array->GetIsolate();
Factory* factory = isolate->factory();
bool has_double_elements = array->IsFixedDoubleArray();
}
if (!value->IsTheHole()) {
PropertyDetails details = PropertyDetails::Empty();
- dictionary =
- SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details);
+ dictionary = SeededNumberDictionary::AddNumberEntry(
+ dictionary, i, value, details, used_as_prototype);
}
}
return dictionary;
int used = object->GetFastElementsUsage();
Handle<SeededNumberDictionary> dictionary =
SeededNumberDictionary::New(isolate, used);
- return CopyFastElementsToDictionary(elements, length, dictionary);
+ return CopyFastElementsToDictionary(elements, length, dictionary,
+ object->map()->is_prototype_map());
}
return bailout;
} else {
Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
- new_dict, pos, value, details);
+ new_dict, pos, value, details, object->map()->is_prototype_map());
DCHECK(result.is_identical_to(new_dict));
USE(result);
pos++;
return bailout;
} else {
Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
- new_dict, key, value, details);
+ new_dict, key, value, details, object->map()->is_prototype_map());
DCHECK(result.is_identical_to(new_dict));
USE(result);
}
}
HandleScope scope(isolate);
Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
- new_dict, pos, isolate->factory()->undefined_value(), no_details);
+ new_dict, pos, isolate->factory()->undefined_value(), no_details,
+ object->map()->is_prototype_map());
DCHECK(result.is_identical_to(new_dict));
USE(result);
pos++;
}
-void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
+void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key,
+ bool used_as_prototype) {
DisallowHeapAllocation no_allocation;
// If the dictionary requires slow elements an element has already
// been added at a high index.
// Check if this index is high enough that we should require slow
// elements.
if (key > kRequiresSlowElementsLimit) {
- // TODO(verwaest): Remove this hack.
- GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
+ if (used_as_prototype) {
+ // TODO(verwaest): Remove this hack.
+ GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC);
+ }
set_requires_slow_elements();
return;
}
Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value,
- PropertyDetails details) {
- dictionary->UpdateMaxNumberKey(key);
+ Handle<SeededNumberDictionary> dictionary, uint32_t key,
+ Handle<Object> value, PropertyDetails details, bool used_as_prototype) {
+ dictionary->UpdateMaxNumberKey(key, used_as_prototype);
SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
return Add(dictionary, key, value, details);
}
Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value) {
- dictionary->UpdateMaxNumberKey(key);
+ Handle<SeededNumberDictionary> dictionary, uint32_t key,
+ Handle<Object> value, bool used_as_prototype) {
+ dictionary->UpdateMaxNumberKey(key, used_as_prototype);
return AtPut(dictionary, key, value);
}
Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value,
- PropertyDetails details) {
+ Handle<SeededNumberDictionary> dictionary, uint32_t key,
+ Handle<Object> value, PropertyDetails details, bool used_as_prototype) {
int entry = dictionary->FindEntry(key);
if (entry == kNotFound) {
- return AddNumberEntry(dictionary, key, value, details);
+ return AddNumberEntry(dictionary, key, value, details, used_as_prototype);
}
// Preserve enumeration index.
details = details.set_index(dictionary->DetailsAt(entry).dictionary_index());
// Type specific at put (default NONE attributes is used when adding).
MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value);
+ Handle<SeededNumberDictionary> dictionary, uint32_t key,
+ Handle<Object> value, bool used_as_prototype);
MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value,
- PropertyDetails details);
+ Handle<SeededNumberDictionary> dictionary, uint32_t key,
+ Handle<Object> value, PropertyDetails details, bool used_as_prototype);
// Set an existing entry or add a new one if needed.
// Return the updated dictionary.
MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value,
- PropertyDetails details);
+ Handle<SeededNumberDictionary> dictionary, uint32_t key,
+ Handle<Object> value, PropertyDetails details, bool used_as_prototype);
- void UpdateMaxNumberKey(uint32_t key);
+ void UpdateMaxNumberKey(uint32_t key, bool used_as_prototype);
// If slow elements are required we will never go back to fast-case
// for the elements kept in this dictionary. We require slow
DCHECK(!fast_elements());
Handle<SeededNumberDictionary> dict(
SeededNumberDictionary::cast(*storage_));
+ // The object holding this backing store has just been allocated, so
+ // it cannot yet be used as a prototype.
Handle<SeededNumberDictionary> result =
- SeededNumberDictionary::AtNumberPut(dict, index, elm);
+ SeededNumberDictionary::AtNumberPut(dict, index, elm, false);
if (!result.is_identical_to(dict)) {
// Dictionary needed to grow.
clear_storage();
HandleScope loop_scope(isolate_);
Handle<Object> element(current_storage->get(i), isolate_);
if (!element->IsTheHole()) {
+ // The object holding this backing store has just been allocated, so
+ // it cannot yet be used as a prototype.
Handle<SeededNumberDictionary> new_storage =
- SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
+ SeededNumberDictionary::AtNumberPut(slow_storage, i, element,
+ false);
if (!new_storage.is_identical_to(slow_storage)) {
slow_storage = loop_scope.CloseAndEscape(new_storage);
}