A code review comment from Stefan K about the "ugly macro":
5) This macro and the jesting is pretty bad. I complained about it to Erik, and then he confessed that he wrote it :D
+// Possibly the ugliest for loop the world has seen. C++ does not allow
+// multiple types in the declaration section of the for loop. In this case
+// we are only dealing with pointers and hence can cast them. It looks ugly
+// but macros are ugly and therefore it's fine to make things absurdly ugly.
+#define DO_JAVA_THREADS(LIST, X) \
+ for (JavaThread *MACRO_scan_interval = (JavaThread*)(uintptr_t)PrefetchScanIntervalInBytes, \
+ *MACRO_list = (JavaThread*)(LIST), \
+ **MACRO_end = ((JavaThread**)((ThreadsList*)MACRO_list)->threads()) + ((ThreadsList*)MACRO_list)->length(), \
+ **MACRO_current_p = (JavaThread**)((ThreadsList*)MACRO_list)->threads(), \
+ *X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval); \
+ MACRO_current_p != MACRO_end; \
+ MACRO_current_p++, \
+ X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval))
+
This can be rewritten without all these cast, and minimal usage of the macros expansions:
struct JavaThreadPrefetchedIterator {
ThreadList* _list;
JavaThread** _end;
JavaThread** _current;
JavaThreadIteror(ThreadList* list) :
_list(list), _end(list->threads() + list->length()), _current(list->threads()) {}
JavaThread* current() {
return context._current != context._end
? prefetch_and_load_ptr(context._current, PrefetchScanIntervalInBytes)
: NULL) // ^ prefetch would be rewritten to return JavaThread* and not void*
}
void next() {
_current++;
};
#define DO_JAVA_THREADS(LIST, X) \
for (JavaThreadPrefetchedIterator iter(LIST); JavaThread* X = iter.current(); iter.next())
(I did some changes to the code above and haven't compiled this exact version)
5) This macro and the jesting is pretty bad. I complained about it to Erik, and then he confessed that he wrote it :D
+// Possibly the ugliest for loop the world has seen. C++ does not allow
+// multiple types in the declaration section of the for loop. In this case
+// we are only dealing with pointers and hence can cast them. It looks ugly
+// but macros are ugly and therefore it's fine to make things absurdly ugly.
+#define DO_JAVA_THREADS(LIST, X) \
+ for (JavaThread *MACRO_scan_interval = (JavaThread*)(uintptr_t)PrefetchScanIntervalInBytes, \
+ *MACRO_list = (JavaThread*)(LIST), \
+ **MACRO_end = ((JavaThread**)((ThreadsList*)MACRO_list)->threads()) + ((ThreadsList*)MACRO_list)->length(), \
+ **MACRO_current_p = (JavaThread**)((ThreadsList*)MACRO_list)->threads(), \
+ *X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval); \
+ MACRO_current_p != MACRO_end; \
+ MACRO_current_p++, \
+ X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval))
+
This can be rewritten without all these cast, and minimal usage of the macros expansions:
struct JavaThreadPrefetchedIterator {
ThreadList* _list;
JavaThread** _end;
JavaThread** _current;
JavaThreadIteror(ThreadList* list) :
_list(list), _end(list->threads() + list->length()), _current(list->threads()) {}
JavaThread* current() {
return context._current != context._end
? prefetch_and_load_ptr(context._current, PrefetchScanIntervalInBytes)
: NULL) // ^ prefetch would be rewritten to return JavaThread* and not void*
}
void next() {
_current++;
};
#define DO_JAVA_THREADS(LIST, X) \
for (JavaThreadPrefetchedIterator iter(LIST); JavaThread* X = iter.current(); iter.next())
(I did some changes to the code above and haven't compiled this exact version)
- blocks
-
JDK-8271513 support JavaThreadIteratorWithHandle replacement by new ThreadsList::Iterator
- Resolved
- relates to
-
JDK-8167108 inconsistent handling of SR_lock can lead to crashes
- Resolved