@Override public Object dispatchWithSelfAndBlock( VirtualFrame frame, final RubyBasicObject block, Object self, RubyBasicObject modifiedBlock, Object... argumentsObjects) { CompilerDirectives.transferToInterpreterAndInvalidate(); assert block == null || RubyGuards.isRubyProc(block); assert modifiedBlock == null || RubyGuards.isRubyProc(modifiedBlock); final YieldDispatchNode dispatch = atomic( new Callable<YieldDispatchNode>() { @Override public YieldDispatchNode call() { // First try to see if we did not a miss a specialization added by another thread. final YieldDispatchHeadNode dispatchHead = getHeadNode(); final YieldDispatchNode first = dispatchHead.getDispatch(); YieldDispatchNode lookupDispatch = first; while (lookupDispatch != null) { if (lookupDispatch.guard(block)) { // This one worked, no need to rewrite anything. return lookupDispatch; } lookupDispatch = lookupDispatch.getNext(); } final YieldDispatchNode newDispatchNode; if (depth < DispatchNode.DISPATCH_POLYMORPHIC_MAX) { depth++; newDispatchNode = new CachedYieldDispatchNode(getContext(), block, first); } else { newDispatchNode = new GeneralYieldDispatchNode(getContext()); } first.replace(newDispatchNode); return first; } }); return dispatch.dispatchWithSelfAndBlock(frame, block, self, modifiedBlock, argumentsObjects); }
@Override public Object dispatchWithSelfAndBlock( VirtualFrame frame, RubyProc block, Object self, RubyProc modifiedBlock, Object... argumentsObjects) { if (guard(block)) { return callNode.call( frame, RubyArguments.pack( block.getMethod(), block.getDeclarationFrame(), self, modifiedBlock, argumentsObjects)); } else { return next.dispatchWithSelfAndBlock(frame, block, self, modifiedBlock, argumentsObjects); } }