G1's slow allocation path uses an unusual asymmetric locking scheme according to which some of the methods assume that they have the heap lock when called and they either release the heap lock when returning a non-NULL result or retain it when returning a NULL result.
The last major changes to this code were done as part of CR 6974966 (G1: unnecessary direct-to-old allocations) but the above asymmetric locking scheme was retained.
I've had a lot of encouragement to replace it with a symmetric locking scheme to make long-term maintenance of this code simpler.