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.


Reply via email to