Examples of Instr


Examples of org.jruby.ir.instructions.Instr

                // Pop on all scope-exit paths
                BasicBlock exitBB = cfg.getExitBB();
                for (BasicBlock bb: cfg.getBasicBlocks()) {
                    ListIterator<Instr> instrs = bb.getInstrs().listIterator();
                    while (instrs.hasNext()) {
                        Instr i = instrs.next();
                        if ((bb != exitBB) && (i instanceof ReturnBase) || (i instanceof BreakInstr)) {
                            // Add before the break/return
                            instrs.previous();
                            instrs.add(new PopBindingInstr());
                            instrs.add(new PopFrameInstr());
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        //    ensure blocks for the two are identical.
        // 2. One of 'a' or 'b' is empty.  We dont need to check for rescue block match because
        //    an empty basic block cannot raise an exception, can it.
        if ((aR == bR) || a.isEmpty() || b.isEmpty()) {
            // First, remove straight-line jump, if present
            Instr lastInstr = a.getLastInstr();
            if (lastInstr instanceof JumpInstr) a.removeInstr(lastInstr);

            // Swallow b's instrs.
            a.swallowBB(b);
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        // clone bbs
        for (BasicBlock b : getBasicBlocks()) {
            BasicBlock bCloned = new BasicBlock(clone, b.getLabel().clone());
            for (Instr i: b.getInstrs()) {
                Instr clonedInstr = i.cloneForBlockCloning(ii);
                if (clonedInstr != null) bCloned.addInstr(clonedInstr);
            }
            clone.addBasicBlock(bCloned);
            cloneBBMap.put(b, bCloned);
        }
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

    public BasicBlock cloneForInlinedMethod(InlinerInfo ii) {
        IRScope hostScope = ii.getInlineHostScope();
        BasicBlock clonedBB = ii.getOrCreateRenamedBB(this);
        for (Instr i: getInstrs()) {
            Instr clonedInstr = i.cloneForInlinedScope(ii);
            if (clonedInstr != null) {
                clonedBB.addInstr(clonedInstr);
                if (clonedInstr instanceof YieldInstr) ii.recordYieldSite(clonedBB, (YieldInstr)clonedInstr);
                if (clonedInstr instanceof CallBase) {
                    CallBase call = (CallBase)clonedInstr;
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        IRScope hostScope = ii.getInlineHostScope();
        BasicBlock clonedBB = ii.getOrCreateRenamedBB(this);

        // Process instructions
        for (Instr i: getInstrs()) {
            Instr clonedInstr = i.cloneForInlinedClosure(ii);
            if (clonedInstr != null) {
                clonedBB.addInstr(clonedInstr);
                if (clonedInstr instanceof CallBase) {
                    CallBase call = (CallBase)clonedInstr;
                    Operand block = call.getClosureArg(null);
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        // Traverse the instructions in this basic block in reverse order!
        List<Instr> instrs = basicBlock.getInstrs();
        ListIterator<Instr> it = instrs.listIterator(instrs.size());
        while (it.hasPrevious()) {
            Instr i = it.previous();
            // System.out.println("TF: Processing: " + i);

            // v is defined => It is no longer live before 'i'
            if (i instanceof ResultInstr) {
                Variable v = ((ResultInstr) i).getResult();
                living.clear(lvp.getDFVar(v).getId());
            }

            // Check if 'i' is a call and uses a closure!
            // If so, we need to process the closure for live variable info.
            if (i instanceof CallBase) {
                CallBase c = (CallBase) i;
                Operand  o = c.getClosureArg(null);
                // System.out.println("Processing closure: " + o + "-------");
                if (o != null && o instanceof WrappedIRClosure) {
                    IRClosure cl = ((WrappedIRClosure)o).getClosure();
                    LiveVariablesProblem cl_lvp = (LiveVariablesProblem)cl.getDataFlowSolution(DataFlowConstants.LVP_NAME);
                    if (cl_lvp == null) {
                        cl_lvp = new LiveVariablesProblem(cl, lvp.getNonSelfLocalVars());
                        cl.setDataFlowSolution(cl_lvp.getName(), cl_lvp);
                    }

                    // Collect live local variables at this point.
                    Set<LocalVariable> liveVars = new HashSet<LocalVariable>();
                    for (int j = 0; j < living.size(); j++) {
                        if (living.get(j)) {
                            Variable v = lvp.getVariable(j);
                            if (v instanceof LocalVariable) liveVars.add((LocalVariable)v);
                        }
                    }

                    // Collect variables live on entry of the closure -- they could all be live on exit as well (conservative, but safe).
                    //
                    //   def foo
                    //     i = 0;
                    //     loop { i += 1; break if i > n }
                    //   end
                    //
                    // Here, i is not live outside the closure, but it is clearly live on exit of the closure because
                    // it is reused on the next iteration.  In the absence of information about the call accepting the closure,
                    // we have to assume that all vars live on exit from the closure will be live on entry into the closure as well
                    // because of looping.
                    List<Variable> liveOnEntryBefore = cl_lvp.getVarsLiveOnScopeEntry();
                    for (Variable y: liveOnEntryBefore) {
                        if (y instanceof LocalVariable) liveVars.add((LocalVariable)y);
                    }

                    // Collect variables live out of the exception target node.  Since this call can directly jump to
                    // the rescue block (or scope exit) without executing the rest of the instructions in this bb, we
                    // have a control-flow edge from this call to that block.  Since we dont want to add a
                    // control-flow edge from pretty much every call to the rescuer/exit BB, we are handling it
                    // implicitly here.
                    if (c.canRaiseException()) {
                        BitSet etOut = ((LiveVariableNode)getExceptionTargetNode()).out;
                        for (int k = 0; k < etOut.size(); k++) {
                            if (etOut.get(k)) {
                                Variable v = lvp.getVariable(k);
                                if (v instanceof LocalVariable) liveVars.add((LocalVariable)v);
                            }
                        }
                    }

                    // Run LVA on the closure to propagate current LVA state through the closure
                    // SSS FIXME: Think through this .. Is there any way out of having
                    // to recompute the entire lva for the closure each time through?
                    cl_lvp.setVarsLiveOnScopeExit(liveVars);
                    cl_lvp.compute_MOP_Solution();

                    // Check if liveOnScopeEntry added new vars -- if so, rerun.
                    // NOTE: This is conservative since we are not checking if some vars got deleted.
                    // But, this conservativeness guarantees forward progress of the analysis.
                    boolean changed;
                    List<Variable> liveOnEntryAfter;
                    do {
                        changed = false;
                        liveOnEntryAfter = cl_lvp.getVarsLiveOnScopeEntry();
                        for (Variable y: liveOnEntryAfter) {
                            if (y instanceof LocalVariable) {
                                LocalVariable ly = (LocalVariable)y;
                                if (!liveVars.contains(ly)) {
                                    changed = true;
                                    liveVars.add(ly);
                                }
                            }
                        }

                        if (changed) {
                            cl_lvp.setVarsLiveOnScopeExit(liveVars);
                            cl_lvp.compute_MOP_Solution();
                        }
                    } while (changed);

                    // Merge live on closure entry info into the current problem.
                    markAllVariablesLive(lvp, living, liveOnEntryAfter);
                }

                // If this is a dataflow barrier -- mark all local vars but %self and %block live
                if (scopeBindingHasEscaped || c.targetRequiresCallersBinding()) {
                    // System.out.println(".. call is a data flow barrier ..");
                    // Mark all non-self, non-block local variables live if 'c' is a dataflow barrier!
                    for (Variable x: lvp.getNonSelfLocalVars()) {
                        if (!x.isImplicitBlockArg()) living.set(lvp.getDFVar(x).getId());
                    }
                } else if (c.canRaiseException()) {
                    makeOutExceptionVariablesLiving(living);
                }
            } else if (i.canRaiseException()) {
                makeOutExceptionVariablesLiving(living);
            }

            // Now, for all variables used by 'i', mark them live before 'i'
            markAllVariablesLive(lvp, living, i.getUsedVariables());
        }

        // System.out.println("After TF, df state is:\n" + toString());

        if (living.equals(out)) { // OUT is the same!
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        // Traverse the instructions in this basic block in reverse order!
        // Mark as dead all instructions whose results are not used!
        List<Instr> instrs = basicBlock.getInstrs();
        ListIterator<Instr> it = instrs.listIterator(instrs.size());
        while (it.hasPrevious()) {
            Instr i = it.previous();
            // System.out.println("DEAD?? " + i);
            if (i instanceof ResultInstr) {
                Variable v = ((ResultInstr) i).getResult();
                DataFlowVar dv = lvp.getDFVar(v);

                // If 'v' is not live at the instruction site, and it has no side effects, mark it dead!
                // System.out.println("df var for " + v + " is " + dv.getId());
                if (living.get(dv.getId())) {
                    living.clear(dv.getId());
                    // System.out.println("NO! LIVE result:" + v);
                } else if (i.canBeDeleted(scope)) {
                    // System.out.println("YES!");
                    i.markDead();
                    it.remove();
                    if (v.isImplicitBlockArg()) lvp.getScope().markUnusedImplicitBlockArg();
                } else {
                    // System.out.println("NO! has side effects! Op is: " + i.getOperation());
                }
            } else if (i.canBeDeleted(scope)) {
                 i.markDead();
                 it.remove();
            } else {
                // System.out.println("IGNORING! No result!");
            }

            if (i instanceof CallBase) {
                CallBase c = (CallBase) i;
                Operand  o = c.getClosureArg(null);
                if (o != null && o instanceof WrappedIRClosure) {
                    IRClosure cl = ((WrappedIRClosure)o).getClosure();
                    LiveVariablesProblem cl_lvp = (LiveVariablesProblem)cl.getDataFlowSolution(lvp.getName());
                    // Collect variables live on entry and merge that info into the current problem.
                    markAllVariablesLive(lvp, living, cl_lvp.getVarsLiveOnScopeEntry());
                } else if (scopeBindingHasEscaped || c.targetRequiresCallersBinding()) {
                    // Mark all non-self, non-block local variables live if 'c' is a dataflow barrier!
                    for (Variable x: lvp.getNonSelfLocalVars()) {
                        if (!x.isImplicitBlockArg()) living.set(lvp.getDFVar(x).getId());
                    }
                } else if (c.canRaiseException()) {
                    makeOutExceptionVariablesLiving(living);
                }
            } else if (i.canRaiseException()) {
                makeOutExceptionVariablesLiving(living);
            }

            // Do not mark this instruction's operands live if the instruction itself is dead!
            if (!i.isDead()) markAllVariablesLive(lvp, living, i.getUsedVariables());
        }
    }
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        for (BasicBlock b: linearizedBBList) {
            labelIPCMap.put(b.getLabel(), ipc);
            List<Instr> bbInstrs = b.getInstrs();
            int bbInstrsLength = bbInstrs.size();
            for (int i = 0; i < bbInstrsLength; i++) {
                Instr instr = bbInstrs.get(i);
               
                if (instr instanceof Specializeable) {
                    instr = ((Specializeable) instr).specializeForInterpretation();
                    bbInstrs.set(i, instr);
                }
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        Map<Variable, Integer> ends = new HashMap<Variable, Integer>();
        Map<Variable, Integer> starts = new HashMap<Variable, Integer>();
        SortedSet<Variable> variables = new TreeSet<Variable>();
       
        for (int i = instrList.size() - 1; i >= 0; i--) {
            Instr instr = instrList.get(i);

            if (instr instanceof ResultInstr) {
                Variable var = ((ResultInstr) instr).getResult();
                variables.add(var);
                starts.put(var, i);
            }

            for (Operand operand : instr.getOperands()) {
                if (operand != null && operand instanceof Variable && ends.get((Variable)operand) == null) {
                    ends.put((Variable)operand, i);
                    variables.add((Variable)operand);
                }
            }
View Full Code Here

Examples of org.jruby.ir.instructions.Instr

        int temporaryVariablesSize = scope.getTemporaryVariableSize();
        Object[] temp = temporaryVariablesSize > 0 ? new Object[temporaryVariablesSize] : null;
        int n   = instrs.length;
        int ipc = 0;
        Instr instr = null;
        Object exception = null;
        Ruby runtime = context.runtime;
        DynamicScope currDynScope = context.getCurrentScope();

        // Set up thread-poll counter for this scope
        Counter tpCount = null;
        if (profile) {
            tpCount = scopeThreadPollCounts.get(scope);
            if (tpCount == null) {
                tpCount = new Counter();
                scopeThreadPollCounts.put(scope, tpCount);
            }
        }

        // Enter the looooop!
        while (ipc < n) {
            instr = instrs[ipc];
            Operation operation = instr.getOperation();

            if (debug) {
                LOG.info("I: {}", instr);
               interpInstrsCount++;
            } else if (profile) {
                if (operation.modifiesCode()) codeModificationsCount++;
               interpInstrsCount++;
            }

            try {
                Variable resultVar = null;
                Object result = null;
                switch(operation) {

                // ----------- Control-transfer instructions -------------
                case JUMP: {
                    ipc = ((JumpInstr)instr).getJumpTarget().getTargetPC();
                    break;
                }
                case MODULE_GUARD:
                case JUMP_INDIRECT:
                case B_TRUE:
                case B_FALSE:
                case B_NIL:
                case B_UNDEF:
                case BEQ:
                case BNE: {
                    ipc = instr.interpretAndGetNewIPC(context, currDynScope, self, temp, ipc);
                    break;
                }

                // ------------- Arg-receive instructions ------------
                case RECV_PRE_REQD_ARG: {
                    ReceivePreReqdArgInstr ra = (ReceivePreReqdArgInstr)instr;
                    int argIndex = ra.getArgIndex();
                    result = (argIndex < args.length) ? args[argIndex] : context.nil; // SSS FIXME: This check is only required for closures, not methods
                    resultVar = ra.getResult();
                    ipc++;
                    break;
                }
                case RECV_POST_REQD_ARG: {
                    ReceivePostReqdArgInstr ra = (ReceivePostReqdArgInstr)instr;
                    result = ra.receivePostReqdArg(args);
                    if (result == null) result = context.nil; // For blocks
                    resultVar = ra.getResult();
                    ipc++;
                    break;
                }
                case RECV_OPT_ARG: {
                    ReceiveOptArgBase ra = (ReceiveOptArgBase)instr;
                    result = ra.receiveOptArg(args);
                    resultVar = ra.getResult();
                    ipc++;
                    break;
                }
                case RECV_REST_ARG: {
                    ReceiveRestArgBase ra = (ReceiveRestArgBase)instr;
                    result = ra.receiveRestArg(runtime, args);
                    resultVar = ra.getResult();
                    ipc++;
                    break;
                }
                case RECV_CLOSURE: {
                    result = block == Block.NULL_BLOCK ? context.nil : runtime.newProc(Block.Type.PROC, block);
                    resultVar = ((ResultInstr)instr).getResult();
                    ipc++;
                    break;
                }
                case RECV_EXCEPTION: {
                    ReceiveExceptionInstr rei = (ReceiveExceptionInstr)instr;
                    result = (exception instanceof RaiseException && rei.checkType) ? ((RaiseException)exception).getException() : exception;
                    resultVar = rei.getResult();
                    ipc++;
                    break;
                }

                // --------- Return flavored instructions --------
                case BREAK: {
                    BreakInstr bi = (BreakInstr)instr;
                    IRubyObject rv = (IRubyObject)bi.getReturnValue().retrieve(context, self, currDynScope, temp);
                    // This also handles breaks in lambdas -- by converting them to a return
                    return IRRuntimeHelpers.initiateBreak(context, scope, bi.getScopeToReturnTo(), rv, blockType);
                }
                case RETURN: {
                    return (IRubyObject)((ReturnBase)instr).getReturnValue().retrieve(context, self, currDynScope, temp);
                }
                case NONLOCAL_RETURN: {
                    NonlocalReturnInstr ri = (NonlocalReturnInstr)instr;
                    IRubyObject rv = (IRubyObject)ri.getReturnValue().retrieve(context, self, currDynScope, temp);
                    ipc = n;
                    // If not in a lambda, check if this was a non-local return
                    if (!IRRuntimeHelpers.inLambda(blockType)) {
                        IRRuntimeHelpers.initiateNonLocalReturn(context, scope, ri.methodToReturnFrom, rv);
                    }
                    return rv;
                }

                // --------- Bookkeeping instructions --------
                case CHECK_ARITY: {
                    ((CheckArityInstr)instr).checkArity(runtime, args.length);
                    ipc++;
                    break;
                }
                case PUSH_FRAME: {
                    context.preMethodFrameAndClass(implClass, scope.getName(), self, block, scope.getStaticScope());
                    context.setCurrentVisibility(visibility);
                    ipc++;
                    break;
                }
                case PUSH_BINDING: {
                    // SSS NOTE: Method scopes only!
                    //
                    // Blocks are a headache -- so, these instrs. are only added to IRMethods.
                    // Blocks have more complicated logic for pushing a dynamic scope (see InterpretedIRBlockBody)
                    currDynScope = DynamicScope.newDynamicScope(scope.getStaticScope());
                    context.pushScope(currDynScope);
                    ipc++;
                    break;
                }
                case POP_FRAME: {
                    context.popFrame();
                    context.popRubyClass();
                    ipc++;
                    break;
                }
                case POP_BINDING: {
                    context.popScope();
                    ipc++;
                    break;
                }
                case THREAD_POLL: {
                    if (profile) {
                        tpCount.count++;
                        globalThreadPollCount++;
                        // SSS: Uncomment this to analyze profile
                        // Every 10K profile counts, spit out profile stats
                        // if (globalThreadPollCount % 10000 == 0) analyzeProfile(); //outputProfileStats();
                    }
                    context.callThreadPoll();
                    ipc++;
                    break;
                }
                case LINE_NUM: {
                    context.setLine(((LineNumberInstr)instr).lineNumber);
                    ipc++;
                    break;
                }
                case RUNTIME_HELPER: {
                    ipc++;
                    resultVar = ((ResultInstr)instr).getResult();
                    result = ((RuntimeHelperCall)instr).callHelper(context, currDynScope, self, temp, scope, blockType);
                    break;
                }

                // ---------- Common instruction ---------
                case COPY: {
                    CopyInstr c = (CopyInstr)instr;
                    result = c.getSource().retrieve(context, self, currDynScope, temp);
                    resultVar = ((ResultInstr)instr).getResult();
                    ipc++;
                    break;
                }

                // ---------- All the rest ---------
                default:
                    ipc++;
                    if (instr instanceof ResultInstr) resultVar = ((ResultInstr)instr).getResult();
                    result = instr.interpret(context, currDynScope, self, temp, block);
                    break;
                }

                if (resultVar != null) {
                    if (resultVar instanceof TemporaryVariable) {
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.