Exemplo n.º 1
0
void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
    Timer _t("for compileModule()");

    ScopingAnalysis* scoping = runScopingAnalysis(m);

    SourceInfo* si = new SourceInfo(bm, scoping);
    si->cfg = computeCFG(AST_TYPE::Module, m->body);
    si->ast = m;
    si->liveness = computeLivenessInfo(si->cfg);
    si->phis = computeRequiredPhis(NULL, si->cfg, si->liveness, si->scoping->getScopeInfoForNode(si->ast));

    CLFunction* cl_f = new CLFunction(si);

    EffortLevel::EffortLevel effort = initialEffort();

    CompiledFunction* cf
        = compileFunction(cl_f, new FunctionSignature(VOID, &si->getArgNames(), 0, false, false), effort, NULL);
    assert(cf->clfunc->versions.size());

    _t.end();

    if (cf->is_interpreted)
        interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL);
    else
        ((void (*)())cf->code)();
}
Exemplo n.º 2
0
/// Reoptimizes the given function version at the new effort level.
/// The cf must be an active version in its parents CLFunction; the given
/// version will be replaced by the new version, which will be returned.
static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel::EffortLevel new_effort) {
    assert(cf->clfunc->versions.size());

    assert(cf);
    assert(cf->entry_descriptor == NULL && "We can't reopt an osr-entry compile!");
    assert(cf->sig);

    CLFunction* clfunc = cf->clfunc;
    assert(clfunc);

    assert(new_effort > cf->effort);

    FunctionList& versions = clfunc->versions;
    for (int i = 0; i < versions.size(); i++) {
        if (versions[i] == cf) {
            versions.erase(versions.begin() + i);

            CompiledFunction* new_cf
                = compileFunction(clfunc, cf->sig, new_effort,
                                  NULL); // this pushes the new CompiledVersion to the back of the version list

            cf->dependent_callsites.invalidateAll();

            return new_cf;
        }
    }
    assert(0 && "Couldn't find a version to reopt! Probably reopt'd already?");
    abort();
}
Exemplo n.º 3
0
void* compilePartialFunc(OSRExit* exit) {
    LOCK_REGION(codegen_rwlock.asWrite());

    assert(exit);
    assert(exit->parent_cf);
    assert(exit->parent_cf->effort < EffortLevel::MAXIMAL);
    stat_osrexits.log();

    // if (VERBOSITY("irgen") >= 1) printf("In compilePartialFunc, handling %p\n", exit);

    assert(exit->parent_cf->clfunc);
    CompiledFunction*& new_cf = exit->parent_cf->clfunc->osr_versions[exit->entry];
    if (new_cf == NULL) {
        EffortLevel::EffortLevel new_effort = EffortLevel::MAXIMAL;
        if (exit->parent_cf->effort == EffortLevel::INTERPRETED)
            new_effort = EffortLevel::MINIMAL;
        // EffortLevel::EffortLevel new_effort = (EffortLevel::EffortLevel)(exit->parent_cf->effort + 1);
        // new_effort = EffortLevel::MAXIMAL;
        CompiledFunction* compiled
            = compileFunction(exit->parent_cf->clfunc, exit->parent_cf->spec, new_effort, exit->entry);
        assert(compiled = new_cf);
    }

    return new_cf->code;
}
Exemplo n.º 4
0
void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
    CompiledFunction* cf;

    { // scope for limiting the locked region:
        LOCK_REGION(codegen_rwlock.asWrite());

        Timer _t("for compileModule()");

        bm->future_flags = getFutureFlags(m, bm->fn.c_str());

        ScopingAnalysis* scoping = runScopingAnalysis(m);

        SourceInfo* si = new SourceInfo(bm, scoping, m, m->body);
        si->cfg = computeCFG(si, m->body);
        si->liveness = computeLivenessInfo(si->cfg);
        si->phis = computeRequiredPhis(si->arg_names, si->cfg, si->liveness, si->getScopeInfo());

        CLFunction* cl_f = new CLFunction(0, 0, false, false, si);

        EffortLevel::EffortLevel effort = initialEffort();

        cf = compileFunction(cl_f, new FunctionSpecialization(VOID), effort, NULL);
        assert(cf->clfunc->versions.size());
    }

    if (cf->is_interpreted)
        interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL, NULL, NULL);
    else
        ((void (*)())cf->code)();
}
Exemplo n.º 5
0
// Compile the whole program
BC* compileProgram(AST* prog) {
	// Create the bytecode structure
	BC* out = malloc(sizeof(BC));

	// Create a bytecode function for
	// each original function
	out->funcc = prog->funcc;
	out->functions = malloc(sizeof(BFunc) * out->funcc);
	for (int i = 0; i < out->funcc; i++)
		out->functions[i] = compileFunction(prog->functions[i]);

	return out;
}
Exemplo n.º 6
0
// Compiles a new version of the function with the given signature and adds it to the list;
// should only be called after checking to see if the other versions would work.
static CompiledFunction* _doCompile(CLFunction *f, FunctionSignature *sig, EffortLevel::EffortLevel effort, const OSREntryDescriptor *entry) {
    Timer _t("for _doCompile()");
    assert(sig);

    ASSERT(f->versions.size() < 20, "%ld", f->versions.size());
    SourceInfo *source = f->source;
    assert(source);

    std::string name = source->getName();
    const std::vector<AST_expr*> &arg_names = source->getArgNames();
    AST_arguments *args = source->getArgsAST();

    if (VERBOSITY("irgen") >= 1) {
        std::string s;
        llvm::raw_string_ostream ss(s);

        ss << "\033[34;1mJIT'ing " << name << " with signature (";
        for (int i = 0; i < sig->arg_types.size(); i++) {
            if (i > 0) ss << ", ";
            ss << sig->arg_types[i]->debugName();
            //sig->arg_types[i]->llvmType()->print(ss);
        }
        ss << ") -> ";
        ss << sig->rtn_type->debugName();
        //sig->rtn_type->llvmType()->print(ss);
        ss << " at effort level " << effort;
        if (entry != NULL) {
            ss << "\nDoing OSR-entry partial compile, starting with backedge to block " << entry->backedge->target->idx << '\n';
        }
        ss << "\033[0m";
        printf("%s\n", ss.str().c_str());
    }

    // Do the analysis now if we had deferred it earlier:
    if (source->cfg == NULL) {
        assert(source->ast);
        source->cfg = computeCFG(source->ast->type, source->getBody());
        source->liveness = computeLivenessInfo(source->cfg);
        source->phis = computeRequiredPhis(args, source->cfg, source->liveness, 
                source->scoping->getScopeInfoForNode(source->ast));
    }

    CompiledFunction *cf = compileFunction(source, entry, effort, sig, arg_names, name);

    compileIR(cf, effort);
    f->addVersion(cf);
    assert(f->versions.size());

    long us = _t.end();
    static StatCounter us_compiling("us_compiling");
    us_compiling.log(us);
    static StatCounter num_compiles("num_compiles");
    num_compiles.log();

    switch(effort) {
        case EffortLevel::INTERPRETED: {
            static StatCounter us_compiling("us_compiling_0_interpreted");
            us_compiling.log(us);
            static StatCounter num_compiles("num_compiles_0_interpreted");
            num_compiles.log();
            break;
        }
        case EffortLevel::MINIMAL: {
            static StatCounter us_compiling("us_compiling_1_minimal");
            us_compiling.log(us);
            static StatCounter num_compiles("num_compiles_1_minimal");
            num_compiles.log();
            break;
        }
        case EffortLevel::MODERATE: {
            static StatCounter us_compiling("us_compiling_2_moderate");
            us_compiling.log(us);
            static StatCounter num_compiles("num_compiles_2_moderate");
            num_compiles.log();
            break;
        }
        case EffortLevel::MAXIMAL: {
            static StatCounter us_compiling("us_compiling_3_maximal");
            us_compiling.log(us);
            static StatCounter num_compiles("num_compiles_3_maximal");
            num_compiles.log();
            break;
        }
    }

    return cf;
}
Exemplo n.º 7
0
    jsval toval( const BSONElement& e ) {

        switch( e.type() ) {
        case EOO:
        case jstNULL:
        case Undefined:
            return JSVAL_NULL;
        case NumberDouble:
        case NumberInt:
            return toval( e.number() );
        case Symbol: // TODO: should we make a special class for this
        case String:
            return toval( e.valuestr() );
        case Bool:
            return e.boolean() ? JSVAL_TRUE : JSVAL_FALSE;
        case Object: {
            BSONObj embed = e.embeddedObject().getOwned();
            return toval( &embed );
        }
        case Array: {

            BSONObj embed = e.embeddedObject().getOwned();

            if ( embed.isEmpty() ) {
                return OBJECT_TO_JSVAL( JS_NewArrayObject( _context , 0 , 0 ) );
            }

            int n = embed.nFields();

            JSObject * array = JS_NewArrayObject( _context , n , 0 );
            assert( array );

            jsval myarray = OBJECT_TO_JSVAL( array );

            for ( int i=0; i<n; i++ ) {
                jsval v = toval( embed[i] );
                assert( JS_SetElement( _context , array , i , &v ) );
            }

            return myarray;
        }
        case jstOID: {
            OID oid = e.__oid();
            JSObject * o = JS_NewObject( _context , &object_id_class , 0 , 0 );
            setProperty( o , "str" , toval( oid.str().c_str() ) );
            return OBJECT_TO_JSVAL( o );
        }
        case RegEx: {
            const char * flags = e.regexFlags();
            uintN flagNumber = 0;
            while ( *flags ) {
                switch ( *flags ) {
                case 'g':
                    flagNumber |= JSREG_GLOB;
                    break;
                case 'i':
                    flagNumber |= JSREG_FOLD;
                    break;
                case 'm':
                    flagNumber |= JSREG_MULTILINE;
                    break;
                //case 'y': flagNumber |= JSREG_STICKY; break;

                default:
                    log() << "warning: unknown regex flag:" << *flags << endl;
                }
                flags++;
            }

            JSObject * r = JS_NewRegExpObject( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber );
            assert( r );
            return OBJECT_TO_JSVAL( r );
        }
        case Code: {
            JSFunction * func = compileFunction( e.valuestr() );
            return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) );
        }
        case CodeWScope: {
            JSFunction * func = compileFunction( e.codeWScopeCode() );

            BSONObj extraScope = e.codeWScopeObject();
            if ( ! extraScope.isEmpty() ) {
                log() << "warning: CodeWScope doesn't transfer to db.eval" << endl;
            }

            return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) );
        }
        case Date:
            return OBJECT_TO_JSVAL( js_NewDateObjectMsec( _context , (jsdouble) e.date().millis ) );

        case MinKey:
            return OBJECT_TO_JSVAL( JS_NewObject( _context , &minkey_class , 0 , 0 ) );

        case MaxKey:
            return OBJECT_TO_JSVAL( JS_NewObject( _context , &maxkey_class , 0 , 0 ) );

        case Timestamp: {
            JSObject * o = JS_NewObject( _context , &timestamp_class , 0 , 0 );
            setProperty( o , "t" , toval( (double)(e.timestampTime()) ) );
            setProperty( o , "i" , toval( (double)(e.timestampInc()) ) );
            return OBJECT_TO_JSVAL( o );
        }
        case NumberLong: {
            boost::uint64_t val = (boost::uint64_t)e.numberLong();
            JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 );
            setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) );
            if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) {
                // using 2 doubles here instead of a single double because certain double
                // bit patterns represent undefined values and sm might trash them
                setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) );
                setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) );
            }
            return OBJECT_TO_JSVAL( o );
        }
        case DBRef: {
            JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 );
            setProperty( o , "ns" , toval( e.dbrefNS() ) );

            JSObject * oid = JS_NewObject( _context , &object_id_class , 0 , 0 );
            setProperty( oid , "str" , toval( e.dbrefOID().str().c_str() ) );

            setProperty( o , "id" , OBJECT_TO_JSVAL( oid ) );
            return OBJECT_TO_JSVAL( o );
        }
        case BinData: {
            JSObject * o = JS_NewObject( _context , &bindata_class , 0 , 0 );
            int len;
            const char * data = e.binData( len );
            assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) );

            setProperty( o , "len" , toval( len ) );
            setProperty( o , "type" , toval( (int)e.binDataType() ) );
            return OBJECT_TO_JSVAL( o );
        }
        }