Skip to content

Commit

Permalink
[Truffle] Use switch instead of a big if.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Jan 8, 2015
1 parent f52241e commit ef46083
Showing 1 changed file with 63 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ public Object dispatch(
Object methodName,
Object blockObject,
Object argumentsObjects) {
final DispatchAction dispatchAction = getDispatchAction();

if (receiverObject) {
trueProfile.enter();

Expand All @@ -128,33 +126,38 @@ public Object dispatch(
"class modified");
}

if (dispatchAction == DispatchAction.CALL_METHOD) {
if (isIndirect()) {
return indirectCallNode.call(
frame,
trueMethod.getCallTarget(),
RubyArguments.pack(
trueMethod,
trueMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
} else {
return trueCallDirect.call(
frame,
RubyArguments.pack(
trueMethod,
trueMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
switch (getDispatchAction()) {
case CALL_METHOD: {
if (isIndirect()) {
return indirectCallNode.call(
frame,
trueMethod.getCallTarget(),
RubyArguments.pack(
trueMethod,
trueMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
} else {
return trueCallDirect.call(
frame,
RubyArguments.pack(
trueMethod,
trueMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
}
}
} else if (dispatchAction == DispatchAction.RESPOND_TO_METHOD) {
return true;
} else if (dispatchAction == DispatchAction.READ_CONSTANT) {
return trueValue;
} else {
throw new UnsupportedOperationException();

case RESPOND_TO_METHOD:
return true;

case READ_CONSTANT:
return trueValue;

default:
throw new UnsupportedOperationException();
}
} else {
falseProfile.enter();
Expand All @@ -171,33 +174,39 @@ public Object dispatch(
"class modified");
}

if (dispatchAction == DispatchAction.CALL_METHOD) {
if (isIndirect()) {
return indirectCallNode.call(
frame,
falseMethod.getCallTarget(),
RubyArguments.pack(
falseMethod,
falseMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
} else {
return falseCallDirect.call(
frame,
RubyArguments.pack(
falseMethod,
falseMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
switch (getDispatchAction()) {
case CALL_METHOD: {
if (isIndirect()) {
return indirectCallNode.call(
frame,
falseMethod.getCallTarget(),
RubyArguments.pack(
falseMethod,
falseMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
} else {
return falseCallDirect.call(
frame,
RubyArguments.pack(
falseMethod,
falseMethod.getDeclarationFrame(),
receiverObject,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
}

This comment has been minimized.

Copy link
@thomaswue

thomaswue Jan 8, 2015

Contributor

These unsafe casts should not be necessary. Can you remove them and check whether there is any measurable performance impact? CompilerDirectives.unsafeCast will become unsupported in the future and should be avoided.

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton Jan 9, 2015

Author Contributor

The one on argumentsObjects is redundant now, but the one on RubyProc is there because it's null if there isn't one, so we can't type the argument in the specialisation because then it wouldn't let null through. We'll find another way around using a sentinel RubyProc probably.

This comment has been minimized.

Copy link
@thomaswue

thomaswue Jan 9, 2015

Contributor

What I mean is just replacing the unsafeCast with normal casts. Should not make a difference in both cases.

}
} else if (dispatchAction == DispatchAction.RESPOND_TO_METHOD) {
return true;
} else if (dispatchAction == DispatchAction.READ_CONSTANT) {
return falseValue;
} else {
throw new UnsupportedOperationException();

case RESPOND_TO_METHOD:
return true;

case READ_CONSTANT:
return falseValue;

default:
throw new UnsupportedOperationException();

}
}
}
Expand Down

0 comments on commit ef46083

Please sign in to comment.