Add sublinear indexing of objects, outline of support for fixing the object
identity problem.


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6099 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/npapi/LocalObjectTable.cpp b/plugins/npapi/LocalObjectTable.cpp
index a450381..cc2a4ad 100644
--- a/plugins/npapi/LocalObjectTable.cpp
+++ b/plugins/npapi/LocalObjectTable.cpp
@@ -6,3 +6,16 @@
     freeAll();
   }
 }
+
+void* LocalObjectTable::getIdentityFrom(NPObject* obj) {
+  void** rawPtr = reinterpret_cast<void**>(reinterpret_cast<char*>(obj) + sizeof(NPClass*)
+      + sizeof(uint32_t));
+  Debug::log(Debug::Info) << "getIdentity(obj=" << (void*)obj << "): class=" << (void*)obj->_class
+      << ", bytes:";
+  for (int i = 0; i< 4; ++i) {
+    Debug::log(Debug::Info) << " " << rawPtr[i];
+  }
+  Debug::log(Debug::Info) << Debug::flush;
+  return obj;
+}
+
diff --git a/plugins/npapi/LocalObjectTable.h b/plugins/npapi/LocalObjectTable.h
index cc8beb7..857d2e6 100644
--- a/plugins/npapi/LocalObjectTable.h
+++ b/plugins/npapi/LocalObjectTable.h
@@ -18,6 +18,7 @@
 
 #include <vector>
 #include <algorithm>
+#include <map>
 
 #include "Debug.h"
 
@@ -29,6 +30,7 @@
 
   int nextFree;
   std::vector<NPObject*> objects;
+  std::map<void*, int> objectIndex;
   bool dontFree;
 
   bool isFree(int id) {
@@ -41,6 +43,16 @@
     objects[id] = reinterpret_cast<NPObject*>((nextFree << 1) | 1LL);
     nextFree = id;
   }
+
+  int findIndex(void* ptr) {
+    std::map<void*, int>::iterator it = objectIndex.find(ptr);
+    if (it == objectIndex.end()) {
+      return -1;
+    }
+    return it->second;
+  }
+
+  static void* getIdentityFrom(NPObject* obj);
 public:
   LocalObjectTable() {
     nextFree = -1;
@@ -51,7 +63,8 @@
   virtual ~LocalObjectTable();
 
   int add(NPObject* obj) {
-    int id = find(obj);
+    void* objId = getIdentityFrom(obj);
+    int id = findIndex(objId);
     if (id >= 0) {
       Debug::log(Debug::Spam) << "LocalObjectTable::add(obj=" << obj
           << "): returning old id=" << id << Debug::flush;
@@ -65,6 +78,7 @@
       id = static_cast<int>(objects.size());
       objects.push_back(obj);
     }
+    objectIndex[objId] = id;
     Debug::log(Debug::Spam) << "LocalObjectTable::add(obj=" << obj << "): id=" << id
         << Debug::flush;
     // keep track that we hold a reference in the table
@@ -72,13 +86,9 @@
     return id;
   }
 
-  // TODO(jat): sublinear search
   int find(NPObject* obj) {
-    std::vector<NPObject*>::iterator it = std::find(objects.begin(), objects.end(), obj);
-    if (it == objects.end()) {
-      return -1;
-    }
-    return static_cast<int>(it - objects.begin());
+    void* objId = getIdentityFrom(obj);
+    return findIndex(objId);
   }
 
   void free(int id) {