119 head = (MallocSiteHashtableEntry*)head->next();
120 }
121 }
122 return true;
123 }
124
125 /*
126 * The hashtable does not have deletion policy on individual entry,
127 * and each linked list node is inserted via compare-and-swap,
128 * so each linked list is stable, the contention only happens
129 * at the end of linked list.
130 * This method should not return NULL under normal circumstance.
131 * If NULL is returned, it indicates:
132 * 1. Out of memory, it cannot allocate new hash entry.
133 * 2. Overflow hash bucket.
134 * Under any of above circumstances, caller should handle the situation.
135 */
136 MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx,
137 size_t* pos_idx) {
138 int index = hash_to_index(key.hash());
139 assert(index >= 0, "Negative index");
140 *bucket_idx = (size_t)index;
141 *pos_idx = 0;
142
143 // First entry for this hash bucket
144 if (_table[index] == NULL) {
145 MallocSiteHashtableEntry* entry = new_entry(key);
146 // OOM check
147 if (entry == NULL) return NULL;
148
149 // swap in the head
150 if (Atomic::cmpxchg_ptr((void*)entry, (volatile void *)&_table[index], NULL) == NULL) {
151 return entry->data();
152 }
153
154 delete entry;
155 }
156
157 MallocSiteHashtableEntry* head = _table[index];
158 while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) {
159 MallocSite* site = head->data();
|
119 head = (MallocSiteHashtableEntry*)head->next();
120 }
121 }
122 return true;
123 }
124
125 /*
126 * The hashtable does not have deletion policy on individual entry,
127 * and each linked list node is inserted via compare-and-swap,
128 * so each linked list is stable, the contention only happens
129 * at the end of linked list.
130 * This method should not return NULL under normal circumstance.
131 * If NULL is returned, it indicates:
132 * 1. Out of memory, it cannot allocate new hash entry.
133 * 2. Overflow hash bucket.
134 * Under any of above circumstances, caller should handle the situation.
135 */
136 MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx,
137 size_t* pos_idx) {
138 int index = hash_to_index(key.hash());
139 assert(index >= 0, err_msg("Negative index %d", index));
140 *bucket_idx = (size_t)index;
141 *pos_idx = 0;
142
143 // First entry for this hash bucket
144 if (_table[index] == NULL) {
145 MallocSiteHashtableEntry* entry = new_entry(key);
146 // OOM check
147 if (entry == NULL) return NULL;
148
149 // swap in the head
150 if (Atomic::cmpxchg_ptr((void*)entry, (volatile void *)&_table[index], NULL) == NULL) {
151 return entry->data();
152 }
153
154 delete entry;
155 }
156
157 MallocSiteHashtableEntry* head = _table[index];
158 while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) {
159 MallocSite* site = head->data();
|