88 JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); }
89
90 public:
91
92 // accessor methods
93 inline oop* object_addr() { return &_object; }
94 inline oop object() { return NativeAccess<ON_PHANTOM_OOP_REF>::oop_load(object_addr()); }
95 // Peek at the object without keeping it alive. The returned object must be
96 // kept alive using a normal access if it leaks out of a thread transition from VM.
97 inline oop object_peek() {
98 return NativeAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(object_addr());
99 }
100 inline jlong tag() const { return _tag; }
101
102 inline void set_tag(jlong tag) {
103 assert(tag != 0, "can't be zero");
104 _tag = tag;
105 }
106
107 inline bool equals(oop object) {
108 return object == object_peek();
109 }
110
111 inline JvmtiTagHashmapEntry* next() const { return _next; }
112 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; }
113 };
114
115
116 // JvmtiTagHashmap
117 //
118 // A hashmap is essentially a table of pointers to entries. Entries
119 // are hashed to a location, or position in the table, and then
120 // chained from that location. The "key" for hashing is address of
121 // the object, or oop. The "value" is the tag value.
122 //
123 // A hashmap maintains a count of the number entries in the hashmap
124 // and resizes if the number of entries exceeds a given threshold.
125 // The threshold is specified as a percentage of the size - for
126 // example a threshold of 0.75 will trigger the hashmap to resize
127 // if the number of entries is >75% of table size.
128 //
169 _load_factor = load_factor;
170 _resize_threshold = (int)(_load_factor * _size);
171 _resizing_enabled = true;
172 size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*);
173 _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
174 if (_table == NULL) {
175 vm_exit_out_of_memory(s, OOM_MALLOC_ERROR,
176 "unable to allocate initial hashtable for jvmti object tags");
177 }
178 for (int i=0; i<initial_size; i++) {
179 _table[i] = NULL;
180 }
181 }
182
183 // hash a given key (oop) with the specified size
184 static unsigned int hash(oop key, int size) {
185 ZGC_ONLY(assert(ZAddressMetadataShift >= sizeof(unsigned int) * BitsPerByte, "cast removes the metadata bits");)
186
187 // shift right to get better distribution (as these bits will be zero
188 // with aligned addresses)
189 unsigned int addr = (unsigned int)(cast_from_oop<intptr_t>(key));
190 #ifdef _LP64
191 return (addr >> 3) % size;
192 #else
193 return (addr >> 2) % size;
194 #endif
195 }
196
197 // hash a given key (oop)
198 unsigned int hash(oop key) {
199 return hash(key, _size);
200 }
201
202 // resize the hashmap - allocates a large table and re-hashes
203 // all entries into the new table.
204 void resize() {
205 int new_size_index = _size_index+1;
206 int new_size = _sizes[new_size_index];
207 if (new_size < 0) {
208 // hashmap already at maximum capacity
|
88 JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); }
89
90 public:
91
92 // accessor methods
93 inline oop* object_addr() { return &_object; }
94 inline oop object() { return NativeAccess<ON_PHANTOM_OOP_REF>::oop_load(object_addr()); }
95 // Peek at the object without keeping it alive. The returned object must be
96 // kept alive using a normal access if it leaks out of a thread transition from VM.
97 inline oop object_peek() {
98 return NativeAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(object_addr());
99 }
100 inline jlong tag() const { return _tag; }
101
102 inline void set_tag(jlong tag) {
103 assert(tag != 0, "can't be zero");
104 _tag = tag;
105 }
106
107 inline bool equals(oop object) {
108 return oopDesc::equals(object, object_peek());
109 }
110
111 inline JvmtiTagHashmapEntry* next() const { return _next; }
112 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; }
113 };
114
115
116 // JvmtiTagHashmap
117 //
118 // A hashmap is essentially a table of pointers to entries. Entries
119 // are hashed to a location, or position in the table, and then
120 // chained from that location. The "key" for hashing is address of
121 // the object, or oop. The "value" is the tag value.
122 //
123 // A hashmap maintains a count of the number entries in the hashmap
124 // and resizes if the number of entries exceeds a given threshold.
125 // The threshold is specified as a percentage of the size - for
126 // example a threshold of 0.75 will trigger the hashmap to resize
127 // if the number of entries is >75% of table size.
128 //
169 _load_factor = load_factor;
170 _resize_threshold = (int)(_load_factor * _size);
171 _resizing_enabled = true;
172 size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*);
173 _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
174 if (_table == NULL) {
175 vm_exit_out_of_memory(s, OOM_MALLOC_ERROR,
176 "unable to allocate initial hashtable for jvmti object tags");
177 }
178 for (int i=0; i<initial_size; i++) {
179 _table[i] = NULL;
180 }
181 }
182
183 // hash a given key (oop) with the specified size
184 static unsigned int hash(oop key, int size) {
185 ZGC_ONLY(assert(ZAddressMetadataShift >= sizeof(unsigned int) * BitsPerByte, "cast removes the metadata bits");)
186
187 // shift right to get better distribution (as these bits will be zero
188 // with aligned addresses)
189 key = Access<>::resolve(key);
190 unsigned int addr = (unsigned int)(cast_from_oop<intptr_t>(key));
191 #ifdef _LP64
192 return (addr >> 3) % size;
193 #else
194 return (addr >> 2) % size;
195 #endif
196 }
197
198 // hash a given key (oop)
199 unsigned int hash(oop key) {
200 return hash(key, _size);
201 }
202
203 // resize the hashmap - allocates a large table and re-hashes
204 // all entries into the new table.
205 void resize() {
206 int new_size_index = _size_index+1;
207 int new_size = _sizes[new_size_index];
208 if (new_size < 0) {
209 // hashmap already at maximum capacity
|