Skip to content

Commit

Permalink
Revert "Move alternateImpl detection into MethodInfo constructor."
Browse files Browse the repository at this point in the history
  • Loading branch information
mykmelez committed Oct 8, 2014
1 parent dd4f995 commit 2be0a5b
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 25 deletions.
24 changes: 4 additions & 20 deletions classinfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ FieldInfo.prototype.toString = function() {
return "[field " + this.name + "]";
}

function missingNativeImpl(key, ctx, stack) {
console.error("Attempted to invoke missing native:", key);
}

function MethodInfo(m, classInfo, constantPool) {
this.classInfo = classInfo;
this.name = constantPool[m.name_index].bytes;
Expand All @@ -54,22 +50,10 @@ function MethodInfo(m, classInfo, constantPool) {
this.isPublic = ACCESS_FLAGS.isPublic(m.access_flags);
this.isStatic = ACCESS_FLAGS.isStatic(m.access_flags);
this.isSynchronized = ACCESS_FLAGS.isSynchronized(m.access_flags);
this.key = (this.isStatic ? "S." : "I.") + this.name + "." + this.signature;
this.implKey = this.classInfo.className + "." + this.name + "." + this.signature;

if (this.isNative) {
if (this.implKey in Native) {
this.alternateImpl = Native[this.implKey];
} else {
// Some Native MethodInfos are constructed but never called;
// that's fine, unless we actually try to call them.
this.alternateImpl = missingNativeImpl.bind(null, this.implKey);
}
} else if (this.implKey in Override) {
this.alternateImpl = Override[this.implKey];
} else {
this.alternateImpl = null;
}

this.alternateImpl = (this.isNative ? Native :
Override.hasMethod(this) ? Override :
null);
}

var ClassInfo = function(classBytes) {
Expand Down
15 changes: 10 additions & 5 deletions instrument.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ var Instrument = {
profiling: false,
profile: null,

getKey: function(methodInfo) {
return methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
},

callEnterHooks: function(methodInfo, caller, callee) {
var key = methodInfo.implKey;
var key = this.getKey(methodInfo);
if (Instrument.enter[key]) {
Instrument.enter[key](caller, callee);
}
Expand All @@ -32,7 +36,7 @@ var Instrument = {
},

callExitHooks: function(methodInfo, caller, callee) {
var key = methodInfo.implKey;
var key = this.getKey(methodInfo);

if (this.profiling) {
var now = performance.now();
Expand Down Expand Up @@ -97,15 +101,16 @@ var Instrument = {
this.profiling = false;
},

measure: function(alternateImpl, ctx, methodInfo) {
measure: function(Alt, ctx, methodInfo) {
if (this.profiling) {
var then = performance.now();
alternateImpl.call(null, ctx, ctx.current().stack);
Alt.invoke(ctx, methodInfo);
var key = this.getKey(methodInfo);
var methodProfileData = this.profile[key] || (this.profile[key] = { count: 0, cost: 0 });
methodProfileData.count++;
methodProfileData.cost += performance.now() - then;
} else {
alternateImpl.call(null, ctx, ctx.current().stack);
Alt.invoke(ctx, methodInfo);
}
},
};
Expand Down
12 changes: 12 additions & 0 deletions native.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@

var Native = {};

Native.invoke = function(ctx, methodInfo) {
if (!methodInfo.native) {
var key = methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
methodInfo.native = Native[key];
if (!methodInfo.native) {
console.error("Missing native: " + key);
ctx.raiseExceptionAndYield("java/lang/RuntimeException", key + " not found");
}
}
methodInfo.native.call(null, ctx, ctx.current().stack);
}

Native["java/lang/System.arraycopy.(Ljava/lang/Object;ILjava/lang/Object;II)V"] = function(ctx, stack) {
var length = stack.pop(), dstOffset = stack.pop(), dst = stack.pop(), srcOffset = stack.pop(), src = stack.pop();
if (!src || !dst)
Expand Down
20 changes: 20 additions & 0 deletions override.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@

var Override = {};

Override.getKey = function(methodInfo) {
return methodInfo.classInfo.className + "." + methodInfo.name + "." + methodInfo.signature;
}

Override.hasMethod = function(methodInfo) {
return ("override" in methodInfo || Override.getKey(methodInfo) in Override);
}

Override.invoke = function(ctx, methodInfo) {
if (!methodInfo.override) {
var key = Override.getKey(methodInfo);
methodInfo.override = Override[key];
if (!methodInfo.override) {
console.error("Missing override: " + key);
ctx.raiseExceptionAndYield("java/lang/RuntimeException", key + " not found");
}
}
methodInfo.override.call(null, ctx, ctx.current().stack);
}

Override["com/ibm/oti/connection/file/Connection.decode.(Ljava/lang/String;)Ljava/lang/String;"] = function(ctx, stack) {
var string = util.fromJavaString(stack.pop());
stack.push(ctx.newString(decodeURIComponent(string)));
Expand Down
4 changes: 4 additions & 0 deletions vm.js
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,10 @@ VM.execute = function(ctx) {
case OPCODES.invokevirtual:
case OPCODES.invokeinterface:
if (methodInfo.classInfo != obj.class) {
if (!methodInfo.key) {
methodInfo.key = "I." + methodInfo.name + "." + methodInfo.signature;
}

// Check if the method is already in the virtual method cache
if (obj.class.vmc[methodInfo.key]) {
methodInfo = obj.class.vmc[methodInfo.key];
Expand Down

0 comments on commit 2be0a5b

Please sign in to comment.