"log" will never be eliminated, here is why:
To eliminate "log" it must be inlined.
It can't currently be inlined unless it can be devirtualized.
It can't be devirtualized unless it can be disambiguated.
It can't be disambiguated if a definition exists on a super class (https://code.google.com/p/closure-compiler/issues/detail?id=1184)
Object is a superclass.
Math is a namespace, defined as an Object.
Math has the property log.
You also need to do the following:
1) Remove the IFFE, method devirtualization only works on global type definitions
2) Move the ENABLE_LOGGING check to be inside the method. Devirtualization only works on function definitions and occurs before dead code elimination.
All of these restrictions can be avoided by using a local function definition instead of object method.
This has the effect you want:
/** @define {boolean} */
var ENABLE_LOGGING = false;
(function() {
function obj(name) {
this.name = name;
}
var log =
ENABLE_LOGGING ?
function(obj, msg) { console.log(obj.name + ': ' + msg); } :
function(obj, msg) {};
var A = new obj('bob');
var B = new obj('tom');
log(A, 'I am an object!');
log(B, 'I am another object!');
})();