How can I detect which javascript engine (v8 or JSC) is used at runtime in Android?

digitalbath picture digitalbath · Jul 20, 2011 · Viewed 14.5k times · Source

Newer versions of Android ( > 2.2) include the v8 javascript engine, while older versions only had JSC. However, according to http://blogs.nitobi.com/joe/2011/01/14/android-your-js-engine-is-not-always-v8/, which javascript engine is used at runtime seems to depend on an environment variable present at build-time (JS_ENGINE), as well as the hardware specs of the device:

# The default / alternative engine depends on the device class.
# On devices with a lot of memory (e.g. Passion/Sholes), the
# default is V8. On everything else, the only choice is JSC.

My question is this: is there any way that I can determine which javascript engine is in use from within a webpage, an embedded WebView, or an application?

If the answer is no, does anybody know which JS engine is used by the Android emulator?


The reason I'm asking this is because of this issue: http://code.google.com/p/android/issues/detail?id=12987

Basically, it may be that the javascript-to-java bridge in JSC is broken on Android 2.3.X, and this impacts the application I'm trying to write. I'm seeing a segfault from somewhere deep in the JNI on my emulator, but not on the handful of physical devices I've tested. I'm trying to determine if this is an emulator-only thing, a JSC-only thing, or something different altogether.

Answer

T.J. Crowder picture T.J. Crowder · Jul 20, 2011

I think the better question is: Why do you care? You're basically falling into the "browser detection" trap that a lot of people fell into in the late 90's / early 00's. Since then, though, we've learned that it's feature detection that's the more useful approach, not least because the features supported in a given browser were (mostly) a moving target. There's code now, running on IE9 with its dramatically-improved DOM and JavaScript support, that's not using those features because it's doing browser detection and falling back on IE6 techniques.

So rather than worrying about V8 vs. JSC, just worry about the features you want. I don't know anything about JSC, but for instance let's assume it doesn't have the forEach method on arrays that V8 has (part of the ECMAScript 5th edition standard). Rather than throwing a big "V8 vs. JSC" lever, you'd do:

if (typeof Array.prototype.forEach === "function") {
    // Code that expects `forEach`
}
else {
    // Code that falls back
}

(Your "code that falls back" might add forEach to the prototype, or maybe this test is in your own iterator function and you want to know whether to defer to a native implementation or supply your own.)

And similarly for other features you want to use that may or may not be present.


But if you really need to detect V8 vs. JSC (and from your comment it seems you may), this page seems to demonstrate a means of doing so, though it seems awfully fragile. Here's my slightly-edited version (not least to replace window.devicePixelRatio with the test for WebkitAppearance — the former gives false positives on at least some other browsers [Firefox, for instance, which uses Gecko, not WebKit]):

var v8string = 'function%20javaEnabled%28%29%20%7B%20%5Bnative%20code%5D%20%7D';

if ('WebkitAppearance' in document.documentElement.style) { //If (probably) WebKit browser
    if (escape(navigator.javaEnabled.toString()) === v8string) {
        console.log('V8 detected');
    } else {
        console.log('JSC detected');
    }
} else {
    console.log("Not a WebKit browser");
}

Works for me detecting the difference between Chrome (which also uses V8) and Safari (which also uses JSC).