| Index: src/objects.cc
|
| ===================================================================
|
| --- src/objects.cc (revision 2285)
|
| +++ src/objects.cc (working copy)
|
| @@ -138,7 +138,7 @@
|
| } else if (IsBoolean()) {
|
| holder = global_context->boolean_function()->instance_prototype();
|
| }
|
| - ASSERT(holder != NULL); // cannot handle null or undefined.
|
| + ASSERT(holder != NULL); // Cannot handle null or undefined.
|
| JSObject::cast(holder)->Lookup(name, result);
|
| }
|
|
|
| @@ -399,6 +399,88 @@
|
| }
|
|
|
|
|
| +Object* JSObject::GetNormalizedProperty(LookupResult* result) {
|
| + ASSERT(!HasFastProperties());
|
| + Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
|
| + if (IsJSGlobalObject()) {
|
| + value = JSGlobalPropertyCell::cast(value)->value();
|
| + }
|
| + ASSERT(!value->IsJSGlobalPropertyCell());
|
| + return value;
|
| +}
|
| +
|
| +
|
| +Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
|
| + ASSERT(!HasFastProperties());
|
| + if (IsJSGlobalObject()) {
|
| + JSGlobalPropertyCell* cell =
|
| + JSGlobalPropertyCell::cast(
|
| + property_dictionary()->ValueAt(result->GetDictionaryEntry()));
|
| + cell->set_value(value);
|
| + } else {
|
| + property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
|
| + }
|
| + return value;
|
| +}
|
| +
|
| +
|
| +Object* JSObject::SetNormalizedProperty(String* name,
|
| + Object* value,
|
| + PropertyDetails details) {
|
| + ASSERT(!HasFastProperties());
|
| + int entry = property_dictionary()->FindStringEntry(name);
|
| + if (entry == Dictionary::kNotFound) {
|
| + Object* store_value = value;
|
| + if (IsJSGlobalObject()) {
|
| + store_value = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (store_value->IsFailure()) return store_value;
|
| + }
|
| + Object* dict =
|
| + property_dictionary()->AddStringEntry(name, store_value, details);
|
| + if (dict->IsFailure()) return dict;
|
| + set_properties(Dictionary::cast(dict));
|
| + return value;
|
| + }
|
| + // Preserve enumeration index.
|
| + details = PropertyDetails(details.attributes(),
|
| + details.type(),
|
| + property_dictionary()->DetailsAt(entry).index());
|
| + if (IsJSGlobalObject()) {
|
| + JSGlobalPropertyCell* cell =
|
| + JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
|
| + cell->set_value(value);
|
| + // Please note we have to update the property details.
|
| + property_dictionary()->DetailsAtPut(entry, details);
|
| + } else {
|
| + property_dictionary()->SetStringEntry(entry, name, value, details);
|
| + }
|
| + return value;
|
| +}
|
| +
|
| +
|
| +Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
|
| + ASSERT(!HasFastProperties());
|
| + Dictionary* dictionary = property_dictionary();
|
| + int entry = dictionary->FindStringEntry(name);
|
| + if (entry != Dictionary::kNotFound) {
|
| + // If we have a global object set the cell to the hole.
|
| + if (IsJSGlobalObject()) {
|
| + PropertyDetails details = dictionary->DetailsAt(entry);
|
| + if (details.IsDontDelete() && mode != FORCE_DELETION) {
|
| + return Heap::false_value();
|
| + }
|
| + JSGlobalPropertyCell* cell =
|
| + JSGlobalPropertyCell::cast(dictionary->ValueAt(entry));
|
| + cell->set_value(Heap::the_hole_value());
|
| + dictionary->DetailsAtPut(entry, details.AsDeleted());
|
| + } else {
|
| + return dictionary->DeleteProperty(entry, mode);
|
| + }
|
| + }
|
| + return Heap::true_value();
|
| +}
|
| +
|
| +
|
| Object* Object::GetProperty(Object* receiver,
|
| LookupResult* result,
|
| String* name,
|
| @@ -449,8 +531,7 @@
|
| JSObject* holder = result->holder();
|
| switch (result->type()) {
|
| case NORMAL:
|
| - value =
|
| - holder->property_dictionary()->ValueAt(result->GetDictionaryEntry());
|
| + value = holder->GetNormalizedProperty(result);
|
| ASSERT(!value->IsTheHole() || result->IsReadOnly());
|
| return value->IsTheHole() ? Heap::undefined_value() : value;
|
| case FIELD:
|
| @@ -949,6 +1030,10 @@
|
| case PROXY_TYPE:
|
| accumulator->Add("<Proxy>");
|
| break;
|
| + case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
| + accumulator->Add("Cell for ");
|
| + JSGlobalPropertyCell::cast(this)->value()->ShortPrint(accumulator);
|
| + break;
|
| default:
|
| accumulator->Add("<Other heap object (%d)>", map()->instance_type());
|
| break;
|
| @@ -1042,6 +1127,10 @@
|
| case CODE_TYPE:
|
| reinterpret_cast<Code*>(this)->CodeIterateBody(v);
|
| break;
|
| + case JS_GLOBAL_PROPERTY_CELL_TYPE:
|
| + reinterpret_cast<JSGlobalPropertyCell*>(this)
|
| + ->JSGlobalPropertyCellIterateBody(v);
|
| + break;
|
| case HEAP_NUMBER_TYPE:
|
| case FILLER_TYPE:
|
| case BYTE_ARRAY_TYPE:
|
| @@ -1250,12 +1339,27 @@
|
| Object* JSObject::AddSlowProperty(String* name,
|
| Object* value,
|
| PropertyAttributes attributes) {
|
| + ASSERT(!HasFastProperties());
|
| + Dictionary* dict = property_dictionary();
|
| + Object* store_value = value;
|
| + if (IsJSGlobalObject()) {
|
| + // In case name is an orphaned property reuse the cell.
|
| + int entry = dict->FindStringEntry(name);
|
| + if (entry != Dictionary::kNotFound) {
|
| + store_value = dict->ValueAt(entry);
|
| + JSGlobalPropertyCell::cast(store_value)->set_value(value);
|
| + PropertyDetails details = PropertyDetails(attributes, NORMAL);
|
| + dict->SetStringEntry(entry, name, store_value, details);
|
| + return value;
|
| + }
|
| + store_value = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (store_value->IsFailure()) return store_value;
|
| + JSGlobalPropertyCell::cast(store_value)->set_value(value);
|
| + }
|
| PropertyDetails details = PropertyDetails(attributes, NORMAL);
|
| - Object* result = property_dictionary()->AddStringEntry(name, value, details);
|
| + Object* result = dict->AddStringEntry(name, store_value, details);
|
| if (result->IsFailure()) return result;
|
| - if (property_dictionary() != result) {
|
| - set_properties(Dictionary::cast(result));
|
| - }
|
| + if (dict != result) set_properties(Dictionary::cast(result));
|
| return value;
|
| }
|
|
|
| @@ -1311,13 +1415,7 @@
|
| }
|
|
|
| PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
|
| - Object* result =
|
| - dictionary->SetOrAddStringEntry(name, value, new_details);
|
| - if (result->IsFailure()) return result;
|
| - if (dictionary != result) {
|
| - set_properties(Dictionary::cast(result));
|
| - }
|
| - return value;
|
| + return SetNormalizedProperty(name, value, new_details);
|
| }
|
|
|
| Object* JSObject::ConvertDescriptorToFieldAndMapTransition(
|
| @@ -1550,7 +1648,7 @@
|
| if (JSObject::cast(pt)->HasFastElements()) continue;
|
| Dictionary* dictionary = JSObject::cast(pt)->element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) {
|
| + if (entry != Dictionary::kNotFound) {
|
| Object* element = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.type() == CALLBACKS) {
|
| @@ -1601,10 +1699,20 @@
|
| }
|
| } else {
|
| int entry = property_dictionary()->FindStringEntry(name);
|
| - if (entry != DescriptorArray::kNotFound) {
|
| + if (entry != Dictionary::kNotFound) {
|
| // Make sure to disallow caching for uninitialized constants
|
| // found in the dictionary-mode objects.
|
| - if (property_dictionary()->ValueAt(entry)->IsTheHole()) {
|
| + Object* value = property_dictionary()->ValueAt(entry);
|
| + if (IsJSGlobalObject()) {
|
| + PropertyDetails d = property_dictionary()->DetailsAt(entry);
|
| + if (d.IsDeleted()) {
|
| + result->NotFound();
|
| + return;
|
| + }
|
| + value = JSGlobalPropertyCell::cast(value)->value();
|
| + ASSERT(result->IsLoaded());
|
| + }
|
| + if (value->IsTheHole()) {
|
| result->DisallowCaching();
|
| }
|
| result->DictionaryResult(this, entry);
|
| @@ -1736,8 +1844,7 @@
|
| // transition or null descriptor and there are no setters in the prototypes.
|
| switch (result->type()) {
|
| case NORMAL:
|
| - property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
|
| - return value;
|
| + return SetNormalizedProperty(result, value);
|
| case FIELD:
|
| return FastPropertyAtPut(result->GetFieldIndex(), value);
|
| case MAP_TRANSITION:
|
| @@ -1819,8 +1926,7 @@
|
| // Check of IsReadOnly removed from here in clone.
|
| switch (result->type()) {
|
| case NORMAL:
|
| - property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
|
| - return value;
|
| + return SetNormalizedProperty(result, value);
|
| case FIELD:
|
| return FastPropertyAtPut(result->GetFieldIndex(), value);
|
| case MAP_TRANSITION:
|
| @@ -2008,6 +2114,10 @@
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, details.index());
|
| Object* value = r.GetConstantFunction();
|
| + if (IsJSGlobalObject()) {
|
| + value = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (value->IsFailure()) return value;
|
| + }
|
| Object* result = dictionary->AddStringEntry(r.GetKey(), value, d);
|
| if (result->IsFailure()) return result;
|
| dictionary = Dictionary::cast(result);
|
| @@ -2017,6 +2127,10 @@
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, details.index());
|
| Object* value = FastPropertyAt(r.GetFieldIndex());
|
| + if (IsJSGlobalObject()) {
|
| + value = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (value->IsFailure()) return value;
|
| + }
|
| Object* result = dictionary->AddStringEntry(r.GetKey(), value, d);
|
| if (result->IsFailure()) return result;
|
| dictionary = Dictionary::cast(result);
|
| @@ -2026,6 +2140,10 @@
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), CALLBACKS, details.index());
|
| Object* value = r.GetCallbacksObject();
|
| + if (IsJSGlobalObject()) {
|
| + value = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (value->IsFailure()) return value;
|
| + }
|
| Object* result = dictionary->AddStringEntry(r.GetKey(), value, d);
|
| if (result->IsFailure()) return result;
|
| dictionary = Dictionary::cast(result);
|
| @@ -2085,6 +2203,7 @@
|
|
|
| Object* JSObject::TransformToFastProperties(int unused_property_fields) {
|
| if (HasFastProperties()) return this;
|
| + ASSERT(!IsJSGlobalObject());
|
| return property_dictionary()->
|
| TransformPropertiesToFastFor(this, unused_property_fields);
|
| }
|
| @@ -2139,12 +2258,7 @@
|
| Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
|
| if (obj->IsFailure()) return obj;
|
|
|
| - ASSERT(!HasFastProperties());
|
| - // Attempt to remove the property from the property dictionary.
|
| - Dictionary* dictionary = property_dictionary();
|
| - int entry = dictionary->FindStringEntry(name);
|
| - if (entry != -1) return dictionary->DeleteProperty(entry, mode);
|
| - return Heap::true_value();
|
| + return DeleteNormalizedProperty(name, mode);
|
| }
|
|
|
|
|
| @@ -2194,7 +2308,9 @@
|
| ASSERT(!HasFastElements());
|
| Dictionary* dictionary = element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) return dictionary->DeleteProperty(entry, mode);
|
| + if (entry != Dictionary::kNotFound) {
|
| + return dictionary->DeleteProperty(entry, mode);
|
| + }
|
| return Heap::true_value();
|
| }
|
|
|
| @@ -2266,7 +2382,9 @@
|
| } else {
|
| Dictionary* dictionary = element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) return dictionary->DeleteProperty(entry, mode);
|
| + if (entry != Dictionary::kNotFound) {
|
| + return dictionary->DeleteProperty(entry, mode);
|
| + }
|
| }
|
| return Heap::true_value();
|
| }
|
| @@ -2318,10 +2436,7 @@
|
| Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
|
| if (obj->IsFailure()) return obj;
|
| // Make sure the properties are normalized before removing the entry.
|
| - Dictionary* dictionary = property_dictionary();
|
| - int entry = dictionary->FindStringEntry(name);
|
| - if (entry != -1) return dictionary->DeleteProperty(entry, mode);
|
| - return Heap::true_value();
|
| + return DeleteNormalizedProperty(name, mode);
|
| }
|
| }
|
|
|
| @@ -2574,7 +2689,7 @@
|
| if (!HasFastElements()) {
|
| Dictionary* dictionary = element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) {
|
| + if (entry != Dictionary::kNotFound) {
|
| Object* result = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.IsReadOnly()) return Heap::undefined_value();
|
| @@ -2624,12 +2739,7 @@
|
| if (ok->IsFailure()) return ok;
|
|
|
| // Update the dictionary with the new CALLBACKS property.
|
| - Object* dict =
|
| - property_dictionary()->SetOrAddStringEntry(name, structure, details);
|
| - if (dict->IsFailure()) return dict;
|
| -
|
| - // Set the potential new dictionary on the object.
|
| - set_properties(Dictionary::cast(dict));
|
| + return SetNormalizedProperty(name, structure, details);
|
| }
|
|
|
| return structure;
|
| @@ -2683,7 +2793,7 @@
|
| if (!jsObject->HasFastElements()) {
|
| Dictionary* dictionary = jsObject->element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) {
|
| + if (entry != Dictionary::kNotFound) {
|
| Object* element = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.type() == CALLBACKS) {
|
| @@ -3974,6 +4084,11 @@
|
| }
|
|
|
|
|
| +void JSGlobalPropertyCell::JSGlobalPropertyCellIterateBody(ObjectVisitor* v) {
|
| + IteratePointers(v, kValueOffset, kValueOffset + kPointerSize);
|
| +}
|
| +
|
| +
|
| uint16_t ConsString::ConsStringGet(int index) {
|
| ASSERT(index >= 0 && index < this->length());
|
|
|
| @@ -4897,8 +5012,30 @@
|
| }
|
|
|
|
|
| +const char* Code::PropertyType2String(PropertyType type) {
|
| + switch (type) {
|
| + case NORMAL: return "NORMAL";
|
| + case FIELD: return "FIELD";
|
| + case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION";
|
| + case CALLBACKS: return "CALLBACKS";
|
| + case INTERCEPTOR: return "INTERCEPTOR";
|
| + case MAP_TRANSITION: return "MAP_TRANSITION";
|
| + case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
|
| + case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
|
| + }
|
| + UNREACHABLE();
|
| + return NULL;
|
| +}
|
| +
|
| void Code::Disassemble(const char* name) {
|
| PrintF("kind = %s\n", Kind2String(kind()));
|
| + if (is_inline_cache_stub()) {
|
| + PrintF("ic_state = %s\n", ICState2String(ic_state()));
|
| + PrintF("ic_in_loop = %d\n", ic_in_loop() == IN_LOOP);
|
| + if (ic_state() == MONOMORPHIC) {
|
| + PrintF("type = %s\n", PropertyType2String(type()));
|
| + }
|
| + }
|
| if ((name != NULL) && (name[0] != '\0')) {
|
| PrintF("name = %s\n", name);
|
| }
|
| @@ -5095,7 +5232,9 @@
|
| return true;
|
| }
|
| } else {
|
| - if (element_dictionary()->FindNumberEntry(index) != -1) return true;
|
| + if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) {
|
| + return true;
|
| + }
|
| }
|
|
|
| // Handle [] on String objects.
|
| @@ -5170,7 +5309,8 @@
|
| return (index < length) &&
|
| !FixedArray::cast(elements())->get(index)->IsTheHole();
|
| } else {
|
| - return element_dictionary()->FindNumberEntry(index) != -1;
|
| + return element_dictionary()->FindNumberEntry(index)
|
| + != Dictionary::kNotFound;
|
| }
|
| }
|
|
|
| @@ -5196,7 +5336,9 @@
|
| if ((index < length) &&
|
| !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
|
| } else {
|
| - if (element_dictionary()->FindNumberEntry(index) != -1) return true;
|
| + if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) {
|
| + return true;
|
| + }
|
| }
|
|
|
| // Handle [] on String objects.
|
| @@ -5332,7 +5474,7 @@
|
| Dictionary* dictionary = Dictionary::cast(elms);
|
|
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) {
|
| + if (entry != Dictionary::kNotFound) {
|
| Object* element = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.type() == CALLBACKS) {
|
| @@ -5426,7 +5568,7 @@
|
| } else {
|
| Dictionary* dictionary = element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) {
|
| + if (entry != Dictionary::kNotFound) {
|
| Object* element = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.type() == CALLBACKS) {
|
| @@ -5510,7 +5652,7 @@
|
| } else {
|
| Dictionary* dictionary = element_dictionary();
|
| int entry = dictionary->FindNumberEntry(index);
|
| - if (entry != -1) {
|
| + if (entry != Dictionary::kNotFound) {
|
| Object* element = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.type() == CALLBACKS) {
|
| @@ -5803,7 +5945,8 @@
|
| return (index < length) &&
|
| !FixedArray::cast(elements())->get(index)->IsTheHole();
|
| }
|
| - return element_dictionary()->FindNumberEntry(index) != -1;
|
| + return element_dictionary()->FindNumberEntry(index)
|
| + != Dictionary::kNotFound;
|
| }
|
|
|
|
|
| @@ -6328,7 +6471,7 @@
|
| template <int prefix_size, int element_size>
|
| int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) {
|
| uint32_t nof = NumberOfElements();
|
| - if (nof == 0) return -1; // Bail out if empty.
|
| + if (nof == 0) return kNotFound; // Bail out if empty.
|
|
|
| uint32_t capacity = Capacity();
|
| uint32_t hash = key->Hash();
|
| @@ -6338,17 +6481,17 @@
|
| uint32_t passed_elements = 0;
|
| if (!element->IsNull()) {
|
| if (!element->IsUndefined() && key->IsMatch(element)) return entry;
|
| - if (++passed_elements == nof) return -1;
|
| + if (++passed_elements == nof) return kNotFound;
|
| }
|
| for (uint32_t i = 1; !element->IsUndefined(); i++) {
|
| entry = GetProbe(hash, i, capacity);
|
| element = KeyAt(entry);
|
| if (!element->IsNull()) {
|
| if (!element->IsUndefined() && key->IsMatch(element)) return entry;
|
| - if (++passed_elements == nof) return -1;
|
| + if (++passed_elements == nof) return kNotFound;
|
| }
|
| }
|
| - return -1;
|
| + return kNotFound;
|
| }
|
|
|
|
|
| @@ -6588,6 +6731,14 @@
|
| }
|
|
|
|
|
| +Object* JSGlobalObject::GetPropertyCell(LookupResult* result) {
|
| + ASSERT(!HasFastProperties());
|
| + Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
|
| + ASSERT(value->IsJSGlobalPropertyCell());
|
| + return value;
|
| +}
|
| +
|
| +
|
| Object* SymbolTable::LookupString(String* string, Object** s) {
|
| SymbolKey key(string);
|
| return LookupKey(&key, s);
|
| @@ -6597,7 +6748,7 @@
|
| bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) {
|
| SymbolKey key(string);
|
| int entry = FindEntry(&key);
|
| - if (entry == -1) {
|
| + if (entry == kNotFound) {
|
| return false;
|
| } else {
|
| String* result = String::cast(KeyAt(entry));
|
| @@ -6618,7 +6769,7 @@
|
| int entry = FindEntry(key);
|
|
|
| // Symbol already in table.
|
| - if (entry != -1) {
|
| + if (entry != kNotFound) {
|
| *s = KeyAt(entry);
|
| return this;
|
| }
|
| @@ -6648,7 +6799,7 @@
|
| Object* CompilationCacheTable::Lookup(String* src) {
|
| StringKey key(src);
|
| int entry = FindEntry(&key);
|
| - if (entry == -1) return Heap::undefined_value();
|
| + if (entry == kNotFound) return Heap::undefined_value();
|
| return get(EntryToIndex(entry) + 1);
|
| }
|
|
|
| @@ -6656,7 +6807,7 @@
|
| Object* CompilationCacheTable::LookupEval(String* src, Context* context) {
|
| StringSharedKey key(src, context->closure()->shared());
|
| int entry = FindEntry(&key);
|
| - if (entry == -1) return Heap::undefined_value();
|
| + if (entry == kNotFound) return Heap::undefined_value();
|
| return get(EntryToIndex(entry) + 1);
|
| }
|
|
|
| @@ -6665,7 +6816,7 @@
|
| JSRegExp::Flags flags) {
|
| RegExpKey key(src, flags);
|
| int entry = FindEntry(&key);
|
| - if (entry == -1) return Heap::undefined_value();
|
| + if (entry == kNotFound) return Heap::undefined_value();
|
| return get(EntryToIndex(entry) + 1);
|
| }
|
|
|
| @@ -6764,7 +6915,7 @@
|
| Object* MapCache::Lookup(FixedArray* array) {
|
| SymbolsKey key(array);
|
| int entry = FindEntry(&key);
|
| - if (entry == -1) return Heap::undefined_value();
|
| + if (entry == kNotFound) return Heap::undefined_value();
|
| return get(EntryToIndex(entry) + 1);
|
| }
|
|
|
| @@ -6915,7 +7066,7 @@
|
| int entry = FindEntry(key);
|
|
|
| // If the entry is present set the value;
|
| - if (entry != -1) {
|
| + if (entry != kNotFound) {
|
| ValueAtPut(entry, value);
|
| return this;
|
| }
|
| @@ -6988,7 +7139,7 @@
|
| Object* value,
|
| PropertyDetails details) {
|
| StringKey k(key);
|
| - SLOW_ASSERT(FindEntry(&k) == -1);
|
| + SLOW_ASSERT(FindEntry(&k) == kNotFound);
|
| return Add(&k, value, details);
|
| }
|
|
|
| @@ -6998,17 +7149,11 @@
|
| PropertyDetails details) {
|
| NumberKey k(key);
|
| UpdateMaxNumberKey(key);
|
| - SLOW_ASSERT(FindEntry(&k) == -1);
|
| + SLOW_ASSERT(FindEntry(&k) == kNotFound);
|
| return Add(&k, value, details);
|
| }
|
|
|
|
|
| -Object* Dictionary::AtStringPut(String* key, Object* value) {
|
| - StringKey k(key);
|
| - return AtPut(&k, value);
|
| -}
|
| -
|
| -
|
| Object* Dictionary::AtNumberPut(uint32_t key, Object* value) {
|
| NumberKey k(key);
|
| UpdateMaxNumberKey(key);
|
| @@ -7016,12 +7161,10 @@
|
| }
|
|
|
|
|
| -Object* Dictionary::SetOrAddStringEntry(String* key,
|
| - Object* value,
|
| - PropertyDetails details) {
|
| - StringKey k(key);
|
| - int entry = FindEntry(&k);
|
| - if (entry == -1) return AddStringEntry(key, value, details);
|
| +Object* Dictionary::SetStringEntry(int entry,
|
| + String* key,
|
| + Object* value,
|
| + PropertyDetails details) {
|
| // Preserve enumeration index.
|
| details = PropertyDetails(details.attributes(),
|
| details.type(),
|
| @@ -7124,8 +7267,12 @@
|
| int capacity = Capacity();
|
| for (int i = 0; i < capacity; i++) {
|
| Object* k = KeyAt(i);
|
| - if (IsKey(k) && ValueAt(i) == value) {
|
| - return k;
|
| + if (IsKey(k)) {
|
| + Object* e = ValueAt(i);
|
| + if (e->IsJSGlobalPropertyCell()) {
|
| + e = JSGlobalPropertyCell::cast(e)->value();
|
| + }
|
| + if (e == value) return k;
|
| }
|
| }
|
| return Heap::undefined_value();
|
|
|