My understanding is that GCC has a more diverse arsenal of optimizations that it can apply to code while hotspot has the advantage that it can profile at runtime and apply speculative optimizations based on those profiles and bail out later if things change. In principle it can even optimize code that never reaches steady state as long as the transient states last long enough.
What costs java performance these days is not the quality of the JIT compilers or even the garbage collectors. It's the object layout that is not very cache-friendly. There is lots of pointer-chasing going on since there are no arrays-of-structs.
Valhalla[0] promises to improve the data layout issue at some point in the future while graal may allow compiler writers to cram some more optimizations into the jits.
[0] http://openjdk.java.net/projects/valhalla/