Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Unified Diff: src/objects.cc

Issue 151019: Changed the global object representation (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | test/cctest/test-api.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | test/cctest/test-api.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698