Beispiel #1
0
static bool
SendBlocksToPerf(JSContext *cx, AsmJSModule &module)
{
    if (!PerfBlockEnabled())
        return true;

    unsigned long funcBaseAddress = (unsigned long) module.functionCode();
    const char *filename = module.sourceDesc().scriptSource()->filename();

    for (unsigned i = 0; i < module.numPerfBlocksFunctions(); i++) {
        const AsmJSModule::ProfiledBlocksFunction &func = module.perfProfiledBlocksFunction(i);

        size_t size = func.endCodeOffset - func.startCodeOffset;

        JSAutoByteString bytes;
        const char *name = AtomToPrintableString(cx, func.name, &bytes);
        if (!name)
            return false;

        writePerfSpewerAsmJSBlocksMap(funcBaseAddress, func.startCodeOffset,
                                      func.endInlineCodeOffset, size, filename, name, func.blocks);
    }

    return true;
}
Beispiel #2
0
static bool
SendFunctionsToPerf(JSContext *cx, AsmJSModule &module)
{
    if (!PerfFuncEnabled())
        return true;

    uintptr_t base = (uintptr_t) module.functionCode();
    const char *filename = module.sourceDesc().scriptSource()->filename();

    for (unsigned i = 0; i < module.numPerfFunctions(); i++) {
        const AsmJSModule::ProfiledFunction &func = module.perfProfiledFunction(i);
        uintptr_t start = base + (unsigned long) func.startCodeOffset;
        uintptr_t end   = base + (unsigned long) func.endCodeOffset;
        JS_ASSERT(end >= start);
        size_t size = end - start;

        JSAutoByteString bytes;
        const char *name = AtomToPrintableString(cx, func.name, &bytes);
        if (!name)
            return false;

        writePerfSpewerAsmJSFunctionMap(start, size, filename, func.lineno, func.columnIndex, name);
    }

    return true;
}
static bool
SendBlocksToPerf(JSContext *cx, AsmJSModule &module)
{
    if (!PerfBlockEnabled())
        return true;

    AsmJSPerfSpewer spewer;
    unsigned long funcBaseAddress = (unsigned long) module.functionCode();

    const AsmJSModule::PostLinkFailureInfo &info = module.postLinkFailureInfo();
    const char *filename = const_cast<char *>(info.scriptSource->filename());

    for (unsigned i = 0; i < module.numPerfBlocksFunctions(); i++) {
        const AsmJSModule::ProfiledBlocksFunction &func = module.perfProfiledBlocksFunction(i);

        unsigned long size = (unsigned long)func.endCodeOffset - (unsigned long)func.startCodeOffset;
        JSAutoByteString bytes;
        const char *method_name = AtomToPrintableString(cx, func.name, &bytes);
        if (!method_name)
            return false;

        spewer.writeBlocksMap(funcBaseAddress, func.startCodeOffset, size, filename, method_name, func.blocks);
    }

    return true;
}
static bool
SendFunctionsToPerf(JSContext *cx, AsmJSModule &module)
{
    if (!PerfFuncEnabled())
        return true;

    AsmJSPerfSpewer perfSpewer;

    unsigned long base = (unsigned long) module.functionCode();

    const AsmJSModule::PostLinkFailureInfo &info = module.postLinkFailureInfo();
    const char *filename = const_cast<char *>(info.scriptSource->filename());

    for (unsigned i = 0; i < module.numPerfFunctions(); i++) {
        const AsmJSModule::ProfiledFunction &func = module.perfProfiledFunction(i);

        unsigned long start = base + (unsigned long) func.startCodeOffset;
        unsigned long end   = base + (unsigned long) func.endCodeOffset;
        JS_ASSERT(end >= start);

        unsigned long size = (end - start);

        JSAutoByteString bytes;
        const char *method_name = AtomToPrintableString(cx, func.name, &bytes);
        if (!method_name)
            return false;

        unsigned lineno = func.lineno;
        unsigned columnIndex = func.columnIndex;

        perfSpewer.writeFunctionMap(start, size, filename, lineno, columnIndex, method_name);
    }

    return true;
}
Beispiel #5
0
static bool
SendFunctionsToVTune(JSContext *cx, AsmJSModule &module)
{
    uint8_t *base = module.functionCode();

    for (unsigned i = 0; i < module.numProfiledFunctions(); i++) {
        const AsmJSModule::ProfiledFunction &func = module.profiledFunction(i);

        uint8_t *start = base + func.startCodeOffset;
        uint8_t *end   = base + func.endCodeOffset;
        JS_ASSERT(end >= start);

        unsigned method_id = iJIT_GetNewMethodID();
        if (method_id == 0)
            return false;

        JSAutoByteString bytes;
        const char *method_name = js_AtomToPrintableString(cx, func.name, &bytes);
        if (!method_name)
            return false;

        iJIT_Method_Load method;
        method.method_id = method_id;
        method.method_name = const_cast<char *>(method_name);
        method.method_load_address = (void *)start;
        method.method_size = unsigned(end - start);
        method.line_number_size = 0;
        method.line_number_table = NULL;
        method.class_id = 0;
        method.class_file_name = NULL;
        method.source_file_name = NULL;

        iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void *)&method);
    }

    return true;
}
Beispiel #6
0
static bool
DynamicallyLinkModule(JSContext *cx, CallArgs args, AsmJSModule &module)
{
    if (module.isLinked())
        return LinkFail(cx, "As a temporary limitation, modules cannot be linked more than "
                            "once. This limitation should be removed in a future release. To "
                            "work around this, compile a second module (e.g., using the "
                            "Function constructor).");

    RootedValue globalVal(cx, UndefinedValue());
    if (args.length() > 0)
        globalVal = args[0];

    RootedValue importVal(cx, UndefinedValue());
    if (args.length() > 1)
        importVal = args[1];

    RootedValue bufferVal(cx, UndefinedValue());
    if (args.length() > 2)
        bufferVal = args[2];

    Rooted<ArrayBufferObject*> heap(cx);
    if (module.hasArrayView()) {
        if (!IsTypedArrayBuffer(bufferVal))
            return LinkFail(cx, "bad ArrayBuffer argument");

        heap = &bufferVal.toObject().as<ArrayBufferObject>();

        if (!IsPowerOfTwo(heap->byteLength()) || heap->byteLength() < AsmJSAllocationGranularity)
            return LinkFail(cx, "ArrayBuffer byteLength must be a power of two greater than or equal to 4096");

        if (!ArrayBufferObject::prepareForAsmJS(cx, heap))
            return LinkFail(cx, "Unable to prepare ArrayBuffer for asm.js use");

#if defined(JS_CPU_X86)
        void *heapOffset = (void*)heap->dataPointer();
        void *heapLength = (void*)heap->byteLength();
        uint8_t *code = module.functionCode();
        for (unsigned i = 0; i < module.numHeapAccesses(); i++) {
            const AsmJSHeapAccess &access = module.heapAccess(i);
            JSC::X86Assembler::setPointer(access.patchLengthAt(code), heapLength);
            JSC::X86Assembler::setPointer(access.patchOffsetAt(code), heapOffset);
        }
#elif defined(JS_CPU_ARM)
        // Now the length of the array is know, patch all of the bounds check sites
        // with the new length.
        jit::IonContext ic(cx, NULL);
        module.patchBoundsChecks(heap->byteLength());

#endif
    }

    AutoObjectVector ffis(cx);
    if (!ffis.resize(module.numFFIs()))
        return false;

    for (unsigned i = 0; i < module.numGlobals(); i++) {
        AsmJSModule::Global &global = module.global(i);
        switch (global.which()) {
          case AsmJSModule::Global::Variable:
            if (!ValidateGlobalVariable(cx, module, global, importVal))
                return false;
            break;
          case AsmJSModule::Global::FFI:
            if (!ValidateFFI(cx, global, importVal, &ffis))
                return false;
            break;
          case AsmJSModule::Global::ArrayView:
            if (!ValidateArrayView(cx, global, globalVal, bufferVal))
                return false;
            break;
          case AsmJSModule::Global::MathBuiltin:
            if (!ValidateMathBuiltin(cx, global, globalVal))
                return false;
            break;
          case AsmJSModule::Global::Constant:
            if (!ValidateGlobalConstant(cx, global, globalVal))
                return false;
            break;
        }
    }

    for (unsigned i = 0; i < module.numExits(); i++)
        module.exitIndexToGlobalDatum(i).fun = &ffis[module.exit(i).ffiIndex()]->as<JSFunction>();

    module.setIsLinked(heap);
    return true;
}