I am in the early stages of a project that aims to estimate the power consumption of Javascript apps. Similar work has been done with Android apps through Java bytecode profiling, and I am hoping to apply a similar methodology using the bytecode generated by Ignition in the V8 engine. However, understandably, there seem to be more tools and resources available for granular analysis of Java bytecode.
My question is whether or not it is possible in V8 to have the engine run hand-coded bytecode scripts for testing purposes, rather than those generated through the compilation process from actual JS source.
The reason for doing this would the development of energy cost functions at the bytecode instruction level. To accomplish this, I'm hoping to run the same instruction (or set of instructions) repeatedly in a loop on a machine connected to speciliazed hardware to measure power draw. These measurements would then be used to inform an estimate of the total power consumption of a program by analysing the composition of the bytecode generated by V8.
(V8 developer here.)
No, this is not possible.
Bytecode is an internal implementation detail. It intentionally doesn't have an external interface (you can't get it out of V8, and can't feed it back in), and is not standardized or documented -- in fact, it could change any day.
Also, bytecode typically isn't executed very much, because "hot" functions get tiered up (by an evolving set of compilers). So while you could create an artificial lab setting where you stress-test bytecode execution, that would be so far removed from reality that I doubt the results would be very useful. In particular, they would definitely not allow you to make any meaningful statements about actual power consumption of a JavaScript program.
The only way to measure power consumption of a JavaScript program is to run the program in question and measure power consumption while doing so. Due to JavaScript's dynamic/flexible nature, there are no static rules as simple as "every +
operation takes X microjoules, every obj.prop
load takes Y microjoules". The reality will be "it depends". To give two obvious examples, adding two strings has a different cost from adding two integers (in terms of both time and power). A monomorphic load is much cheaper than a megamorphic load, loading a simple property has a different cost from having to walk the prototype chain and call a getter; optimization may be able to avoid the load entirely or it might not, depending on various kinds of surrounding circumstances.