129 } 130 IndexCache(); 131 }; 132 133 void maybe_initialize(); 134 int add_handle(T h, bool make_findable); 135 136 enum { null_index = 0, first_index = 1, index_cache_threshold = 20 }; 137 138 GrowableArray<T>* _handles; // ordered list (first is always NULL) 139 GrowableArray<int>* _no_finds; // all unfindable indexes; usually empty 140 IndexCache<T>* _indexes; // map: handle -> its probable index 141 Arena* _arena; 142 bool _complete; 143 144 #ifdef ASSERT 145 static int _find_index_calls, _hit_indexes, _missed_indexes; 146 #endif 147 }; 148 149 class OopRecorder : public ResourceObj { 150 private: 151 ValueRecorder<jobject> _oops; 152 ValueRecorder<Metadata*> _metadata; 153 public: 154 OopRecorder(Arena* arena = NULL): _oops(arena), _metadata(arena) {} 155 156 int allocate_oop_index(jobject h) { 157 return _oops.allocate_index(h); 158 } 159 int find_index(jobject h) { 160 return _oops.find_index(h); 161 } 162 jobject oop_at(int index) { 163 return _oops.at(index); 164 } 165 int oop_size() { 166 return _oops.size(); 167 } 168 int oop_count() { 169 return _oops.count(); 170 } 171 bool is_real(jobject h) { 172 return _oops.is_real(h); 173 } 174 175 int allocate_metadata_index(Metadata* oop) { 176 return _metadata.allocate_index(oop); 177 } 178 int find_index(Metadata* h) { 179 return _metadata.find_index(h); 180 } 181 Metadata* metadata_at(int index) { 182 return _metadata.at(index); 183 } 184 int metadata_size() { 185 return _metadata.size(); 186 } 187 int metadata_count() { 188 return _metadata.count(); 189 } 190 bool is_real(Metadata* h) { 191 return _metadata.is_real(h); 192 } 193 194 bool is_unused() { 195 return _oops.is_unused() && _metadata.is_unused(); 196 } 197 198 void freeze() { | 129 } 130 IndexCache(); 131 }; 132 133 void maybe_initialize(); 134 int add_handle(T h, bool make_findable); 135 136 enum { null_index = 0, first_index = 1, index_cache_threshold = 20 }; 137 138 GrowableArray<T>* _handles; // ordered list (first is always NULL) 139 GrowableArray<int>* _no_finds; // all unfindable indexes; usually empty 140 IndexCache<T>* _indexes; // map: handle -> its probable index 141 Arena* _arena; 142 bool _complete; 143 144 #ifdef ASSERT 145 static int _find_index_calls, _hit_indexes, _missed_indexes; 146 #endif 147 }; 148 149 class OopRecorder; 150 151 class ObjectLookup : public ResourceObj { 152 private: 153 class ObjectEntry { 154 private: 155 jobject _value; 156 int _index; 157 158 public: 159 ObjectEntry(jobject value, int index): _value(value), _index(index) {} 160 ObjectEntry() {} 161 oop oop_value(); // { return JNIHandles::resolve(_value); } 162 int index() { return _index; } 163 }; 164 165 GrowableArray<ObjectEntry> _values; 166 unsigned int _gc_count; 167 168 // Utility sort functions 169 static int sort_by_address(oop a, oop b); 170 static int sort_by_address(ObjectEntry* a, ObjectEntry* b); 171 static int sort_oop_by_address(oop& a, ObjectEntry& b); 172 173 public: 174 ObjectLookup(); 175 176 // Resort list if a GC has occurred since the last sort 177 void maybe_resort(); 178 int find_index(jobject object, OopRecorder* oop_recorder); 179 }; 180 181 class OopRecorder : public ResourceObj { 182 private: 183 ValueRecorder<jobject> _oops; 184 ValueRecorder<Metadata*> _metadata; 185 ObjectLookup* _object_lookup; 186 public: 187 OopRecorder(Arena* arena = NULL, bool deduplicate = false): _oops(arena), _metadata(arena) { 188 if (deduplicate) { 189 _object_lookup = new ObjectLookup(); 190 } else { 191 _object_lookup = NULL; 192 } 193 } 194 195 int allocate_oop_index(jobject h) { 196 return _oops.allocate_index(h); 197 } 198 virtual int find_index(jobject h) { 199 return _object_lookup != NULL ? _object_lookup->find_index(h, this) : _oops.find_index(h); 200 } 201 jobject oop_at(int index) { 202 return _oops.at(index); 203 } 204 int oop_size() { 205 return _oops.size(); 206 } 207 int oop_count() { 208 return _oops.count(); 209 } 210 bool is_real(jobject h) { 211 return _oops.is_real(h); 212 } 213 214 int allocate_metadata_index(Metadata* oop) { 215 return _metadata.allocate_index(oop); 216 } 217 virtual int find_index(Metadata* h) { 218 return _metadata.find_index(h); 219 } 220 Metadata* metadata_at(int index) { 221 return _metadata.at(index); 222 } 223 int metadata_size() { 224 return _metadata.size(); 225 } 226 int metadata_count() { 227 return _metadata.count(); 228 } 229 bool is_real(Metadata* h) { 230 return _metadata.is_real(h); 231 } 232 233 bool is_unused() { 234 return _oops.is_unused() && _metadata.is_unused(); 235 } 236 237 void freeze() { |