Reviewers: Michael Starzinger,
Description:
For HashTable-backed JS objects, use the proper type in the table() accessor
Currently nearly all code using JSSet/JSMap/JSWeakMap does a cast
whenever calling table(). This patch simply puts that cast inside
the accessor. The only possible way for table() to not be valid
is during heap verification (which has been fixed up to not call
the accessor) or if GC occurs during construction of the hash table
itself (where a call to HeapObject::RawField has been moved up to
do the read instead of going through the accessor).
This is a precursor to making a similar change to JSArray::length(),
but is hopefully less dramatic, since there are many fewer uses of
sets and maps than arrays.
Please review this at https://codereview.chromium.org/12217025/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/mark-compact.cc
M src/objects-debug.cc
M src/objects-inl.h
M src/objects.h
M src/objects.cc
M src/runtime.cc
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index
869b318f547572257b66beb0df92c9e32b2ed814..e093b1850d713346af0028b560e2278d748ca0eb
100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1324,11 +1324,10 @@ class MarkCompactMarkingVisitor
object_size);
// Mark the backing hash table without pushing it on the marking stack.
- Object* table_object = weak_map->table();
- if (!table_object->IsHashTable()) return;
- ObjectHashTable* table = ObjectHashTable::cast(table_object);
Object** table_slot =
HeapObject::RawField(weak_map, JSWeakMap::kTableOffset);
+ if (!(*table_slot)->IsHashTable()) return;
+ ObjectHashTable* table = ObjectHashTable::cast(*table_slot);
MarkBit table_mark = Marking::MarkBitFrom(table);
collector->RecordSlot(table_slot, table_slot, table);
if (!table_mark.Get()) collector->SetMark(table, table_mark);
@@ -2411,7 +2410,7 @@ void MarkCompactCollector::ProcessWeakMaps() {
while (weak_map_obj != Smi::FromInt(0)) {
ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
- ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
+ ObjectHashTable* table = weak_map->table();
Object** anchor = reinterpret_cast<Object**>(table->address());
for (int i = 0; i < table->Capacity(); i++) {
if
(MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
@@ -2436,7 +2435,7 @@ void MarkCompactCollector::ClearWeakMaps() {
while (weak_map_obj != Smi::FromInt(0)) {
ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
- ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
+ ObjectHashTable* table = weak_map->table();
for (int i = 0; i < table->Capacity(); i++) {
if
(!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
table->RemoveEntry(i);
Index: src/objects-debug.cc
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index
60463684999001b779eef13970299db1d6a3ed08..0fd9f7dfbab97fe369b3447bec35a5b0ac73d415
100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -623,24 +623,32 @@ void JSArray::JSArrayVerify() {
void JSSet::JSSetVerify() {
CHECK(IsJSSet());
JSObjectVerify();
- VerifyHeapPointer(table());
- CHECK(table()->IsHashTable() || table()->IsUndefined());
+ VerifyObjectField(kTableOffset);
+ Object* table = *RawField(this, kTableOffset);
+ CHECK(table->IsHashTable() || table->IsUndefined());
}
void JSMap::JSMapVerify() {
CHECK(IsJSMap());
JSObjectVerify();
- VerifyHeapPointer(table());
- CHECK(table()->IsHashTable() || table()->IsUndefined());
+ VerifyObjectField(kTableOffset);
+ Object* table = *RawField(this, kTableOffset);
+ CHECK(table->IsHashTable() || table->IsUndefined());
}
void JSWeakMap::JSWeakMapVerify() {
CHECK(IsJSWeakMap());
JSObjectVerify();
- VerifyHeapPointer(table());
- CHECK(table()->IsHashTable() || table()->IsUndefined());
+ VerifyObjectField(kTableOffset);
+ VerifyObjectField(kNextOffset);
+ Object* table = *RawField(this, kTableOffset);
+ CHECK(table->IsHashTable() || table->IsUndefined());
+ if (next()->IsSmi())
+ CHECK_EQ(0, Smi::cast(next())->value());
+ else
+ CHECK(next()->IsJSWeakMap() || next()->IsUndefined());
}
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
18894c1d56123f99fe02df5967ea06ffdac8a857..11a3754e5b1872b7f6847ddc1e1d337a1cc30642
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4830,9 +4830,9 @@ void JSProxy::InitializeBody(int object_size, Object*
value) {
}
-ACCESSORS(JSSet, table, Object, kTableOffset)
-ACCESSORS(JSMap, table, Object, kTableOffset)
-ACCESSORS(JSWeakMap, table, Object, kTableOffset)
+ACCESSORS(JSSet, table, ObjectHashSet, kTableOffset)
+ACCESSORS(JSMap, table, ObjectHashTable, kTableOffset)
+ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
ACCESSORS(JSWeakMap, next, Object, kNextOffset)
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
46539311de9625d9c7ffccc54bd476ab5510a47b..7420d886547c921d7d7d7823574c170ed9718d64
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -13492,11 +13492,10 @@ MaybeObject* ObjectHashTable::Put(Object* key,
Object* value) {
}
// Check whether the hash table should be extended.
- Object* obj;
+ ObjectHashTable* table;
{ MaybeObject* maybe_obj = EnsureCapacity(1, key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ if (!maybe_obj->To(&table)) return maybe_obj;
}
- ObjectHashTable* table = ObjectHashTable::cast(obj);
table->AddEntry(table->FindInsertionEntry(hash), key, value);
return table;
}
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
12413123c09c2a922da3f76a7fbe3679a3dd0609..8e729dfac32fcb8bfc4610284c1e79581262572e
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -8150,7 +8150,7 @@ class JSFunctionProxy: public JSProxy {
class JSSet: public JSObject {
public:
// [set]: the backing hash set containing keys.
- DECL_ACCESSORS(table, Object)
+ DECL_ACCESSORS(table, ObjectHashSet)
// Casting.
static inline JSSet* cast(Object* obj);
@@ -8171,7 +8171,7 @@ class JSSet: public JSObject {
class JSMap: public JSObject {
public:
// [table]: the backing hash table mapping keys to values.
- DECL_ACCESSORS(table, Object)
+ DECL_ACCESSORS(table, ObjectHashTable)
// Casting.
static inline JSMap* cast(Object* obj);
@@ -8192,7 +8192,7 @@ class JSMap: public JSObject {
class JSWeakMap: public JSObject {
public:
// [table]: the backing hash table mapping keys to values.
- DECL_ACCESSORS(table, Object)
+ DECL_ACCESSORS(table, ObjectHashTable)
// [next]: linked list of encountered weak maps during GC.
DECL_ACCESSORS(next, Object)
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
d8623f8ce9b5376ba082bd0da79ff3ddcd3a3403..c27b98179bba5ce02bd94ef6343e01da1d280e6e
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -760,7 +760,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1]);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
+ Handle<ObjectHashSet> table(holder->table());
table = ObjectHashSetAdd(table, key);
holder->set_table(*table);
return isolate->heap()->undefined_value();
@@ -772,7 +772,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1]);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
+ Handle<ObjectHashSet> table(holder->table());
return isolate->heap()->ToBoolean(table->Contains(*key));
}
@@ -782,7 +782,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1]);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
+ Handle<ObjectHashSet> table(holder->table());
table = ObjectHashSetRemove(table, key);
holder->set_table(*table);
return isolate->heap()->undefined_value();
@@ -793,7 +793,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
+ Handle<ObjectHashSet> table(holder->table());
return Smi::FromInt(table->NumberOfElements());
}
@@ -813,7 +813,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<ObjectHashTable> table(holder->table());
Handle<Object> lookup(table->Lookup(*key));
return lookup->IsTheHole() ? isolate->heap()->undefined_value() :
*lookup;
}
@@ -824,7 +824,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<ObjectHashTable> table(holder->table());
Handle<Object> lookup(table->Lookup(*key));
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
@@ -835,7 +835,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<ObjectHashTable> table(holder->table());
Handle<Object> lookup(table->Lookup(*key));
Handle<ObjectHashTable> new_table =
PutIntoObjectHashTable(table, key,
isolate->factory()->the_hole_value());
@@ -850,7 +850,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<ObjectHashTable> table(holder->table());
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key,
value);
holder->set_table(*new_table);
return isolate->heap()->undefined_value();
@@ -861,7 +861,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<ObjectHashTable> table(holder->table());
return Smi::FromInt(table->NumberOfElements());
}
@@ -889,7 +889,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<ObjectHashTable> table(weakmap->table());
Handle<Object> lookup(table->Lookup(*key));
return lookup->IsTheHole() ? isolate->heap()->undefined_value() :
*lookup;
}
@@ -900,7 +900,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapHas) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<ObjectHashTable> table(weakmap->table());
Handle<Object> lookup(table->Lookup(*key));
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
@@ -911,7 +911,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapDelete) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<ObjectHashTable> table(weakmap->table());
Handle<Object> lookup(table->Lookup(*key));
Handle<ObjectHashTable> new_table =
PutIntoObjectHashTable(table, key,
isolate->factory()->the_hole_value());
@@ -926,7 +926,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, key, 1);
Handle<Object> value(args[2]);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
+ Handle<ObjectHashTable> table(weakmap->table());
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key,
value);
weakmap->set_table(*new_table);
return isolate->heap()->undefined_value();
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.