#ifdef DEBUG
for (int i = 0; i < new_space_strings_.length(); ++i) {
ASSERT(heap_->InNewSpace(new_space_strings_[i]));
- ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_null_value());
+ ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_the_hole_value());
}
for (int i = 0; i < old_space_strings_.length(); ++i) {
ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
- ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_null_value());
+ ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_the_hole_value());
}
#endif
}
for (Object** p = start; p < end; p++) {
if ((*p)->IsHeapObject()) {
// Check that the symbol is actually a symbol.
- ASSERT((*p)->IsNull() || (*p)->IsUndefined() || (*p)->IsSymbol());
+ ASSERT((*p)->IsTheHole() || (*p)->IsUndefined() || (*p)->IsSymbol());
}
}
}
void ExternalStringTable::CleanUp() {
int last = 0;
for (int i = 0; i < new_space_strings_.length(); ++i) {
- if (new_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
+ if (new_space_strings_[i] == heap_->raw_unchecked_the_hole_value()) {
+ continue;
+ }
if (heap_->InNewSpace(new_space_strings_[i])) {
new_space_strings_[last++] = new_space_strings_[i];
} else {
new_space_strings_.Rewind(last);
last = 0;
for (int i = 0; i < old_space_strings_.length(); ++i) {
- if (old_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
+ if (old_space_strings_[i] == heap_->raw_unchecked_the_hole_value()) {
+ continue;
+ }
ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
old_space_strings_[last++] = old_space_strings_[i];
}
if (o->IsExternalString()) {
heap_->FinalizeExternalString(String::cast(*p));
}
- // Set the entry to null_value (as deleted).
- *p = heap_->null_value();
+ // Set the entry to the_hole_value (as deleted).
+ *p = heap_->the_hole_value();
pointers_removed_++;
}
}
i += MapCache::kEntrySize) {
Object* raw_key = map_cache->get(i);
if (raw_key == heap()->undefined_value() ||
- raw_key == heap()->null_value()) continue;
+ raw_key == heap()->the_hole_value()) continue;
STATIC_ASSERT(MapCache::kEntrySize == 2);
Object* raw_map = map_cache->get(i + 1);
if (raw_map->IsHeapObject() && IsMarked(raw_map)) {
} else {
// Delete useless entries with unmarked maps.
ASSERT(raw_map->IsMap());
- map_cache->set_null_unchecked(heap(), i);
- map_cache->set_null_unchecked(heap(), i + 1);
+ map_cache->set_the_hole(i);
+ map_cache->set_the_hole(i + 1);
}
}
if (used_elements == 0) {
ObjectHashTable* table = weak_map->unchecked_table();
for (int i = 0; i < table->Capacity(); i++) {
if (!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
- table->RemoveEntry(i, heap());
+ table->RemoveEntry(i);
}
}
weak_map_obj = weak_map->next();
while (true) {
Object* element = KeyAt(entry);
if (element == isolate->heap()->undefined_value()) break; // Empty entry.
- if (element != isolate->heap()->null_value() &&
+ if (element != isolate->heap()->the_hole_value() &&
Shape::IsMatch(key, element)) return entry;
entry = NextProbe(entry, count++, capacity);
}
template <int entrysize>
uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
- ASSERT(!key->IsUndefined() && !key->IsNull());
MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
return Smi::cast(maybe_hash->ToObjectChecked())->value();
}
template <int entrysize>
uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
Object* other) {
- ASSERT(!other->IsUndefined() && !other->IsNull());
MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
return Smi::cast(maybe_hash->ToObjectChecked())->value();
}
}
-void ObjectHashTable::RemoveEntry(int entry) {
- RemoveEntry(entry, GetHeap());
-}
-
-
void Map::ClearCodeCache(Heap* heap) {
// No write barrier is needed since empty_fixed_array is not in new space.
// Please note this function is used during marking:
void CodeCacheHashTable::RemoveByIndex(int index) {
ASSERT(index >= 0);
Heap* heap = GetHeap();
- set(EntryToIndex(index), heap->null_value());
- set(EntryToIndex(index) + 1, heap->null_value());
+ set(EntryToIndex(index), heap->the_hole_value());
+ set(EntryToIndex(index) + 1, heap->the_hole_value());
ElementRemoved();
}
if (element->IsUndefined()) break; // Empty entry.
if (key == element) return entry;
if (!element->IsSymbol() &&
- !element->IsNull() &&
+ !element->IsTheHole() &&
String::cast(element)->Equals(key)) {
// Replace a non-symbol key by the equivalent symbol for faster further
// lookups.
set(index, key);
return entry;
}
- ASSERT(element->IsNull() || !String::cast(element)->Equals(key));
+ ASSERT(element->IsTheHole() || !String::cast(element)->Equals(key));
entry = NextProbe(entry, count++, capacity);
}
return kNotFound;
// EnsureCapacity will guarantee the hash table is never full.
while (true) {
Object* element = KeyAt(entry);
- if (element->IsUndefined() || element->IsNull()) break;
+ if (element->IsUndefined() || element->IsTheHole()) break;
entry = NextProbe(entry, count++, capacity);
}
return entry;
void CompilationCacheTable::Remove(Object* value) {
- Object* null_value = GetHeap()->null_value();
+ Object* the_hole_value = GetHeap()->the_hole_value();
for (int entry = 0, size = Capacity(); entry < size; entry++) {
int entry_index = EntryToIndex(entry);
int value_index = entry_index + 1;
if (get(value_index) == value) {
- NoWriteBarrierSet(this, entry_index, null_value);
- NoWriteBarrierSet(this, value_index, null_value);
+ NoWriteBarrierSet(this, entry_index, the_hole_value);
+ NoWriteBarrierSet(this, value_index, the_hole_value);
ElementRemoved();
}
}
Heap* heap = GetHeap();
int removed_entries = 0;
- Object* sentinel = heap->null_value();
+ Object* the_hole_value = heap->the_hole_value();
int capacity = Capacity();
for (int i = 0; i < capacity; i++) {
Object* key = KeyAt(i);
if (key->IsNumber()) {
uint32_t number = static_cast<uint32_t>(key->Number());
if (from <= number && number < to) {
- SetEntry(i, sentinel, sentinel);
+ SetEntry(i, the_hole_value, the_hole_value);
removed_entries++;
}
}
if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) {
return heap->false_value();
}
- SetEntry(entry, heap->null_value(), heap->null_value());
+ SetEntry(entry, heap->the_hole_value(), heap->the_hole_value());
HashTable<Shape, Key>::ElementRemoved();
return heap->true_value();
}
bool ObjectHashSet::Contains(Object* key) {
+ ASSERT(IsKey(key));
+
// If the object does not have an identity hash, it was never used as a key.
{ MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false;
MaybeObject* ObjectHashSet::Add(Object* key) {
+ ASSERT(IsKey(key));
+
// Make sure the key object has an identity hash code.
int hash;
{ MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
MaybeObject* ObjectHashSet::Remove(Object* key) {
+ ASSERT(IsKey(key));
+
// If the object does not have an identity hash, it was never used as a key.
{ MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this;
if (entry == kNotFound) return this;
// Remove entry and try to shrink this hash set.
- set_null(EntryToIndex(entry));
+ set_the_hole(EntryToIndex(entry));
ElementRemoved();
return Shrink(key);
}
Object* ObjectHashTable::Lookup(Object* key) {
+ ASSERT(IsKey(key));
+
// If the object does not have an identity hash, it was never used as a key.
{ MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
if (maybe_hash->ToObjectUnchecked()->IsUndefined()) {
MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
+ ASSERT(IsKey(key));
+
// Make sure the key object has an identity hash code.
int hash;
{ MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
}
-void ObjectHashTable::RemoveEntry(int entry, Heap* heap) {
- set_null(heap, EntryToIndex(entry));
- set_null(heap, EntryToIndex(entry) + 1);
+void ObjectHashTable::RemoveEntry(int entry) {
+ set_the_hole(EntryToIndex(entry));
+ set_the_hole(EntryToIndex(entry) + 1);
ElementRemoved();
}
// encountered and stops when unused elements are encountered.
//
// - Elements with key == undefined have not been used yet.
-// - Elements with key == null have been deleted.
+// - Elements with key == the_hole have been deleted.
//
// The hash table class is parameterized with a Shape and a Key.
// Shape must be a class with the following interface:
// Returns the key at entry.
Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
- // Tells whether k is a real key. Null and undefined are not allowed
+ // Tells whether k is a real key. The hole and undefined are not allowed
// as keys and can be used to indicate missing or deleted elements.
bool IsKey(Object* k) {
- return !k->IsNull() && !k->IsUndefined();
+ return !k->IsTheHole() && !k->IsUndefined();
}
// Garbage collection support.
friend class MarkCompactCollector;
void AddEntry(int entry, Object* key, Object* value);
- void RemoveEntry(int entry, Heap* heap);
- inline void RemoveEntry(int entry);
+ void RemoveEntry(int entry);
// Returns the index to the value of an entry.
static inline int EntryToValueIndex(int entry) {
};
-// The JSSet describes EcmaScript Harmony maps
+// The JSSet describes EcmaScript Harmony sets
class JSSet: public JSObject {
public:
// [set]: the backing hash set containing keys.
function TestInvalidCalls(m) {
assertThrows(function () { m.get(undefined) }, TypeError);
assertThrows(function () { m.set(undefined, 0) }, TypeError);
+ assertThrows(function () { m.get(null) }, TypeError);
+ assertThrows(function () { m.set(null, 0) }, TypeError);
assertThrows(function () { m.get(0) }, TypeError);
assertThrows(function () { m.set(0, 0) }, TypeError);
assertThrows(function () { m.get('a-key') }, TypeError);
assertFalse(set.has(key));
}
function TestSetBehavior(set) {
- for (i = 0; i < 20; i++) {
+ for (var i = 0; i < 20; i++) {
TestSet(set, new Object);
}
}
TestMapping(m, i / 10, new Object);
TestMapping(m, 'key-' + i, new Object);
}
- var keys = [ +0, -0, +Infinity, -Infinity, true, false ];
+ var keys = [ +0, -0, +Infinity, -Infinity, true, false, null ];
for (var i = 0; i < keys.length; i++) {
TestMapping(m, keys[i], new Object);
}
map[property] = value;
assertEquals(value, map[property]);
}
- for (i = 0; i < 20; i++) {
+ for (var i = 0; i < 20; i++) {
TestProperty(m, i, 'val' + i);
TestProperty(m, 'foo' + i, 'bar' + i);
}