Exploiting hardware heterogeneity and parallelism for performance and energy efficiency of managed languages