Search in sources :

Example 1 with LLVMScopeChain

use of com.oracle.truffle.llvm.runtime.LLVMScopeChain in project graal by oracle.

the class LoadModulesNode method execute.

@Override
public Object execute(VirtualFrame frame) {
    LLVMContext context = getContext();
    synchronized (context) {
        if (!hasInitialised) {
            CompilerDirectives.transferToInterpreterAndInvalidate();
            LLVMFunction mainFunction = findMainFunction();
            if (mainFunction != null) {
                main = new CachedMainFunction(mainFunction);
            } else {
                main = null;
            }
            initContext = this.insert(language.createInitializeContextNode());
            hasInitialised = true;
        }
        LLVMScopeChain firstScopeChain = loadModule(frame, context);
        context.addSourceForCache(bitcodeID, source);
        context.addCalltargetForCache(libraryName, this.getCallTarget());
        // Only the root library (not a dependency) will have a non-null scope.
        if (firstScopeChain != null) {
            SulongLibrary library = new SulongLibrary(this.libraryName, firstScopeChain, main, context, parserRuntime.getLocator(), parserRuntime.getBitcodeID());
            if (main != null) {
                context.setMainLibrary(library);
            }
            return library;
        }
    }
    return null;
}
Also used : LLVMContext(com.oracle.truffle.llvm.runtime.LLVMContext) LLVMFunction(com.oracle.truffle.llvm.runtime.LLVMFunction) LLVMScopeChain(com.oracle.truffle.llvm.runtime.LLVMScopeChain) SulongLibrary(com.oracle.truffle.llvm.runtime.SulongLibrary) CachedMainFunction(com.oracle.truffle.llvm.runtime.SulongLibrary.CachedMainFunction)

Example 2 with LLVMScopeChain

use of com.oracle.truffle.llvm.runtime.LLVMScopeChain in project graal by oracle.

the class LoadModulesNode method loadModule.

@SuppressWarnings("unchecked")
private LLVMScopeChain loadModule(VirtualFrame frame, LLVMContext context) {
    stackAccess.executeEnter(frame, getContext().getThreadingStack().getStack());
    try {
        LLVMLoadingPhase phase;
        // instead of creating a llvm local scope, just create a llvm scope here, and then put
        // it inside the chains
        LLVMScopeChain headLocalScopeChain = null;
        LLVMScopeChain tailLocalScopeChain = null;
        BitSet visited = null;
        ArrayDeque<CallTarget> que = null;
        ArrayList<CallTarget> dependencies = null;
        LLVMScopeChain headResultScopeChain = null;
        LLVMScopeChain tailResultScopeChain = null;
        RTLDFlags localOrGlobal = RTLDFlags.RTLD_OPEN_DEFAULT;
        // check for arguments for dlOpen
        if (frame.getArguments().length > 0 && (frame.getArguments()[0] instanceof RTLDFlags)) {
            localOrGlobal = (RTLDFlags) frame.getArguments()[0];
        }
        /*
             * The arguments in the frames for every loading phase include: 1) The current loading
             * phase. 2) The visited set. The scope building, the external symbol, and overwriting
             * symbol phases all require an additional argument: 3) The RTLD flag, if the library is
             * loaded with RTLD_LOCAL or RTLD_GLOBAL. The scope building phase also have: 4) The
             * tail of the linked structure for local scope. 5) The que of library dependencies. 6)
             * The tail of the linked structure for returning result scope. The external symbol and
             * overwriting symbol phases require instead: 4) The head of the linked structure for
             * local scope.
             */
        if (frame.getArguments().length > 0 && (frame.getArguments()[0] instanceof LLVMLoadingPhase)) {
            phase = (LLVMLoadingPhase) frame.getArguments()[0];
            if (phase == LLVMLoadingPhase.BUILD_SCOPES || phase == LLVMLoadingPhase.BUILD_DEPENDENCY) {
                visited = (BitSet) frame.getArguments()[1];
            }
            if (phase == LLVMLoadingPhase.INIT_EXTERNALS || phase == LLVMLoadingPhase.INIT_OVERWRITE) {
                localOrGlobal = (RTLDFlags) frame.getArguments()[1];
                headLocalScopeChain = (LLVMScopeChain) frame.getArguments()[2];
            }
            if (phase == LLVMLoadingPhase.BUILD_SCOPES) {
                localOrGlobal = (RTLDFlags) frame.getArguments()[2];
            }
            if (phase == LLVMLoadingPhase.BUILD_DEPENDENCY) {
                dependencies = (ArrayList<CallTarget>) frame.getArguments()[2];
            }
            // Additional arguments are required for building the scopes.
            if (phase == LLVMLoadingPhase.BUILD_SCOPES) {
                tailLocalScopeChain = (LLVMScopeChain) frame.getArguments()[3];
                que = (ArrayDeque<CallTarget>) frame.getArguments()[4];
                tailResultScopeChain = (LLVMScopeChain) frame.getArguments()[5];
            }
        // For the root library, it is defined when either the frame has no argument, or
        // when the first argument is not one of the loading phases.
        } else if (frame.getArguments().length == 0 || !(frame.getArguments()[0] instanceof LLVMLoadingPhase)) {
            // create first and last of the scope chain.
            phase = LLVMLoadingPhase.ALL;
            headResultScopeChain = new LLVMScopeChain(bitcodeID, parserRuntime.getFileScope());
            tailResultScopeChain = headResultScopeChain;
            headLocalScopeChain = new LLVMScopeChain(bitcodeID, parserRuntime.getPublicFileScope());
            tailLocalScopeChain = headLocalScopeChain;
            visited = createBitset(libraryDependencies.length);
            que = new ArrayDeque<>();
            dependencies = new ArrayList<>();
        } else {
            throw new LLVMParserException("LoadModulesNode is called with unexpected arguments");
        }
        /*
             * The scope is built in parsing order, which requires breadth-first with a que.
             */
        if (LLVMLoadingPhase.BUILD_SCOPES.isActive(phase)) {
            int id = bitcodeID.getId();
            if (!visited.get(id)) {
                visited.set(id);
                if (LLVMLoadingPhase.ALL.isActive(phase)) {
                    context.addGlobalScope(new LLVMScopeChain(bitcodeID, parserRuntime.getPublicFileScope()));
                } else {
                    LLVMScopeChain currentLocalScopeChain = new LLVMScopeChain(bitcodeID, parserRuntime.getPublicFileScope());
                    LLVMScopeChain currentResultScopeChain = new LLVMScopeChain(bitcodeID, parserRuntime.getFileScope());
                    if (RTLDFlags.RTLD_OPEN_DEFAULT.isActive(localOrGlobal)) {
                        context.addGlobalScope(new LLVMScopeChain(bitcodeID, parserRuntime.getPublicFileScope()));
                        tailLocalScopeChain.concatNextChain(currentLocalScopeChain);
                        tailResultScopeChain.concatNextChain(currentResultScopeChain);
                    } else if (RTLDFlags.RTLD_LOCAL.isActive(localOrGlobal)) {
                        tailLocalScopeChain.concatNextChain(currentLocalScopeChain);
                    } else if (RTLDFlags.RTLD_GLOBAL.isActive(localOrGlobal)) {
                        tailLocalScopeChain.concatNextChain(currentLocalScopeChain);
                        context.addGlobalScope(new LLVMScopeChain(bitcodeID, parserRuntime.getPublicFileScope()));
                    } else {
                        throw new LLVMParserException(this, "Toplevel executable %s does not contain bitcode");
                    }
                }
                for (int i = 0; i < libraryDependencies.length; i++) {
                    CallTarget callTarget = libraryDependencies[i].execute();
                    if (callTarget != null) {
                        queAdd(que, callTarget);
                    }
                }
                if (LLVMLoadingPhase.ALL.isActive(phase)) {
                    while (!que.isEmpty()) {
                        // Foward the tail scope chain to the latest scope chain.
                        while (tailLocalScopeChain != null && tailLocalScopeChain.getNext() != null) {
                            tailLocalScopeChain = tailLocalScopeChain.getNext();
                        }
                        while (tailResultScopeChain != null && tailResultScopeChain.getNext() != null) {
                            tailResultScopeChain = tailResultScopeChain.getNext();
                        }
                        indirectCall.call(quePoll(que), LLVMLoadingPhase.BUILD_SCOPES, visited, localOrGlobal, tailLocalScopeChain, que, tailResultScopeChain);
                    }
                }
            }
        }
        if (context.isLibraryAlreadyLoaded(bitcodeID)) {
            if (RTLDFlags.RTLD_OPEN_DEFAULT.isActive(localOrGlobal)) {
                return headResultScopeChain;
            } else {
                return headLocalScopeChain;
            }
        }
        if (LLVMLoadingPhase.BUILD_DEPENDENCY.isActive(phase)) {
            if (LLVMLoadingPhase.ALL == phase) {
                visited.clear();
            }
            int id = bitcodeID.getId();
            if (!visited.get(id)) {
                visited.set(id);
                for (LoadDependencyNode libraryDependency : libraryDependencies) {
                    CallTarget lib = libraryDependency.execute();
                    if (lib != null) {
                        callDependencies.call(lib, LLVMLoadingPhase.BUILD_DEPENDENCY, visited, dependencies);
                    }
                }
                dependencies.add(this.getCallTarget());
            }
        }
        /*
             * The order of the initialization nodes is very important. The defined symbols and the
             * external symbols must be initialized before the global symbols can be initialized.
             * The overwriting of symbols can only be done once all the globals are initialized and
             * the symbol table has been allocated.
             */
        switch(phase) {
            case BUILD_SCOPES:
            case BUILD_DEPENDENCY:
                break;
            case ALL:
                assert dependencies != null;
                executeInitialiseAllPhase(dependencies, localOrGlobal, headLocalScopeChain);
                break;
            case INIT_SYMBOLS:
                executeInitialiseSymbolPhase(context);
                break;
            case INIT_EXTERNALS:
                initExternals.execute(context, headLocalScopeChain, localOrGlobal);
                break;
            case INIT_GLOBALS:
                initGlobals.execute(frame, context.getReadOnlyGlobals(bitcodeID));
                break;
            case INIT_OVERWRITE:
                initOverwrite.execute(context, headLocalScopeChain, localOrGlobal);
                break;
            case INIT_CONTEXT:
                initContext.execute(frame);
                break;
            case INIT_MODULE:
                initModules.execute(frame, context);
                break;
            case INIT_DONE:
                context.markLibraryLoaded(bitcodeID);
                break;
            default:
                throw CompilerDirectives.shouldNotReachHere("Unknown loading phase");
        }
        if (LLVMLoadingPhase.ALL == phase) {
            if (RTLDFlags.RTLD_OPEN_DEFAULT.isActive(localOrGlobal)) {
                return headResultScopeChain;
            } else {
                return headLocalScopeChain;
            }
        }
        return null;
    } finally {
        stackAccess.executeExit(frame);
    }
}
Also used : RTLDFlags(com.oracle.truffle.llvm.runtime.nodes.intrinsics.c.LLVMDLOpen.RTLDFlags) LLVMScopeChain(com.oracle.truffle.llvm.runtime.LLVMScopeChain) RootCallTarget(com.oracle.truffle.api.RootCallTarget) CallTarget(com.oracle.truffle.api.CallTarget) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList) ArrayDeque(java.util.ArrayDeque) LLVMParserException(com.oracle.truffle.llvm.runtime.except.LLVMParserException)

Example 3 with LLVMScopeChain

use of com.oracle.truffle.llvm.runtime.LLVMScopeChain in project graal by oracle.

the class InitializeExternalNode method execute.

/*
     * (PLi): Need to be careful of native functions/globals that are not in the nfi context (i.e.
     * __xstat). Ideally they will be added to the symbol table as unresolved/undefined
     * functions/globals.
     */
public void execute(LLVMContext context, LLVMScopeChain localScope, LLVMDLOpen.RTLDFlags rtldFlags) {
    LLVMScopeChain globalScope = context.getGlobalScopeChain();
    LLVMIntrinsicProvider intrinsicProvider = getLanguage().getCapability(LLVMIntrinsicProvider.class);
    NativeContextExtension nativeContextExtension = getNativeContextExtension(context);
    for (int i = 0; i < globals.length; i++) {
        LLVMGlobal global = globals[i];
        LLVMPointer pointer = allocExternalSymbol.execute(localScope, globalScope, intrinsicProvider, nativeContextExtension, context, rtldFlags, global);
        if (pointer == null) {
            continue;
        }
        context.initializeSymbol(globals[i], pointer);
    }
    for (int i = 0; i < functions.length; i++) {
        LLVMFunction function = functions[i];
        LLVMPointer pointer = allocExternalSymbol.execute(localScope, globalScope, intrinsicProvider, nativeContextExtension, context, rtldFlags, function);
        if (pointer == null) {
            continue;
        }
        context.initializeSymbol(functions[i], pointer);
    }
}
Also used : LLVMFunction(com.oracle.truffle.llvm.runtime.LLVMFunction) LLVMPointer(com.oracle.truffle.llvm.runtime.pointer.LLVMPointer) LLVMScopeChain(com.oracle.truffle.llvm.runtime.LLVMScopeChain) LLVMGlobal(com.oracle.truffle.llvm.runtime.global.LLVMGlobal) LLVMIntrinsicProvider(com.oracle.truffle.llvm.runtime.LLVMIntrinsicProvider) NativeContextExtension(com.oracle.truffle.llvm.runtime.NativeContextExtension)

Example 4 with LLVMScopeChain

use of com.oracle.truffle.llvm.runtime.LLVMScopeChain in project graal by oracle.

the class InitializeOverwriteNode method execute.

public void execute(LLVMContext context, LLVMScopeChain localScope, RTLDFlags rtldFlags) {
    LLVMScopeChain globalScope = context.getGlobalScopeChain();
    for (LLVMFunction function : functions) {
        LLVMPointer pointer = allocExternalSymbol.execute(localScope, globalScope, null, null, context, rtldFlags, function);
        // skip allocating fallbacks
        if (pointer == null) {
            continue;
        }
        context.initializeSymbol(function, pointer);
    }
    for (LLVMGlobal global : globals) {
        LLVMPointer pointer = allocExternalSymbol.execute(localScope, globalScope, null, null, context, rtldFlags, global);
        // skip allocating fallbacks
        if (pointer == null) {
            continue;
        }
        context.initializeSymbol(global, pointer);
    }
}
Also used : LLVMFunction(com.oracle.truffle.llvm.runtime.LLVMFunction) LLVMPointer(com.oracle.truffle.llvm.runtime.pointer.LLVMPointer) LLVMScopeChain(com.oracle.truffle.llvm.runtime.LLVMScopeChain) LLVMGlobal(com.oracle.truffle.llvm.runtime.global.LLVMGlobal)

Example 5 with LLVMScopeChain

use of com.oracle.truffle.llvm.runtime.LLVMScopeChain in project graal by oracle.

the class LLVMDebuggerScopeFactory method toDebuggerScope.

@TruffleBoundary
private static LLVMDebuggerScopeEntries toDebuggerScope(LLVMScopeChain scope, DataLayout dataLayout, LLVMContext context) {
    final LLVMDebuggerScopeEntries entries = new LLVMDebuggerScopeEntries();
    LLVMScopeChain next = scope;
    while (next != null) {
        for (LLVMSymbol symbol : next.getScope().values()) {
            if (symbol.isGlobalVariable()) {
                LLVMGlobal global = symbol.asGlobalVariable();
                Object value = CommonNodeFactory.toGenericDebuggerValue(global.getPointeeType(), context.getSymbolUncached(global), dataLayout);
                entries.add(LLVMIdentifier.toGlobalIdentifier(global.getName()), value);
            }
        }
        next = next.getNext();
    }
    return entries;
}
Also used : LLVMScopeChain(com.oracle.truffle.llvm.runtime.LLVMScopeChain) LLVMGlobal(com.oracle.truffle.llvm.runtime.global.LLVMGlobal) LLVMSymbol(com.oracle.truffle.llvm.runtime.LLVMSymbol) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)

Aggregations

LLVMScopeChain (com.oracle.truffle.llvm.runtime.LLVMScopeChain)5 LLVMFunction (com.oracle.truffle.llvm.runtime.LLVMFunction)3 LLVMGlobal (com.oracle.truffle.llvm.runtime.global.LLVMGlobal)3 LLVMPointer (com.oracle.truffle.llvm.runtime.pointer.LLVMPointer)2 CallTarget (com.oracle.truffle.api.CallTarget)1 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)1 RootCallTarget (com.oracle.truffle.api.RootCallTarget)1 LLVMContext (com.oracle.truffle.llvm.runtime.LLVMContext)1 LLVMIntrinsicProvider (com.oracle.truffle.llvm.runtime.LLVMIntrinsicProvider)1 LLVMSymbol (com.oracle.truffle.llvm.runtime.LLVMSymbol)1 NativeContextExtension (com.oracle.truffle.llvm.runtime.NativeContextExtension)1 SulongLibrary (com.oracle.truffle.llvm.runtime.SulongLibrary)1 CachedMainFunction (com.oracle.truffle.llvm.runtime.SulongLibrary.CachedMainFunction)1 LLVMParserException (com.oracle.truffle.llvm.runtime.except.LLVMParserException)1 RTLDFlags (com.oracle.truffle.llvm.runtime.nodes.intrinsics.c.LLVMDLOpen.RTLDFlags)1 ArrayDeque (java.util.ArrayDeque)1 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1