js/src/jit/IonLinker.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit/IonLinker.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,108 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef jit_IonLinker_h
    1.11 +#define jit_IonLinker_h
    1.12 +
    1.13 +#include "jscntxt.h"
    1.14 +#include "jscompartment.h"
    1.15 +#include "jsgc.h"
    1.16 +
    1.17 +#include "assembler/jit/ExecutableAllocator.h"
    1.18 +#include "jit/IonCode.h"
    1.19 +#include "jit/IonMacroAssembler.h"
    1.20 +#include "jit/JitCompartment.h"
    1.21 +
    1.22 +namespace js {
    1.23 +namespace jit {
    1.24 +
    1.25 +class Linker
    1.26 +{
    1.27 +    MacroAssembler &masm;
    1.28 +
    1.29 +    JitCode *fail(JSContext *cx) {
    1.30 +        js_ReportOutOfMemory(cx);
    1.31 +        return nullptr;
    1.32 +    }
    1.33 +
    1.34 +    template <AllowGC allowGC>
    1.35 +    JitCode *newCode(JSContext *cx, JSC::ExecutableAllocator *execAlloc, JSC::CodeKind kind) {
    1.36 +        JS_ASSERT(kind == JSC::ION_CODE ||
    1.37 +                  kind == JSC::BASELINE_CODE ||
    1.38 +                  kind == JSC::OTHER_CODE);
    1.39 +        JS_ASSERT(masm.numAsmJSAbsoluteLinks() == 0);
    1.40 +
    1.41 +        gc::AutoSuppressGC suppressGC(cx);
    1.42 +        if (masm.oom())
    1.43 +            return fail(cx);
    1.44 +
    1.45 +        JSC::ExecutablePool *pool;
    1.46 +        size_t bytesNeeded = masm.bytesNeeded() + sizeof(JitCode *) + CodeAlignment;
    1.47 +        if (bytesNeeded >= MAX_BUFFER_SIZE)
    1.48 +            return fail(cx);
    1.49 +
    1.50 +        // ExecutableAllocator requires bytesNeeded to be word-size aligned.
    1.51 +        bytesNeeded = AlignBytes(bytesNeeded, sizeof(void *));
    1.52 +
    1.53 +        uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind);
    1.54 +        if (!result)
    1.55 +            return fail(cx);
    1.56 +
    1.57 +        // The JitCode pointer will be stored right before the code buffer.
    1.58 +        uint8_t *codeStart = result + sizeof(JitCode *);
    1.59 +
    1.60 +        // Bump the code up to a nice alignment.
    1.61 +        codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment);
    1.62 +        uint32_t headerSize = codeStart - result;
    1.63 +        JitCode *code = JitCode::New<allowGC>(cx, codeStart, bytesNeeded - headerSize,
    1.64 +                                              headerSize, pool, kind);
    1.65 +        if (!code)
    1.66 +            return nullptr;
    1.67 +        if (masm.oom())
    1.68 +            return fail(cx);
    1.69 +        code->copyFrom(masm);
    1.70 +        masm.link(code);
    1.71 +#ifdef JSGC_GENERATIONAL
    1.72 +        if (masm.embedsNurseryPointers())
    1.73 +            cx->runtime()->gcStoreBuffer.putWholeCell(code);
    1.74 +#endif
    1.75 +        return code;
    1.76 +    }
    1.77 +
    1.78 +  public:
    1.79 +    Linker(MacroAssembler &masm)
    1.80 +      : masm(masm)
    1.81 +    {
    1.82 +        masm.finish();
    1.83 +    }
    1.84 +
    1.85 +    template <AllowGC allowGC>
    1.86 +    JitCode *newCode(JSContext *cx, JSC::CodeKind kind) {
    1.87 +        return newCode<allowGC>(cx, cx->runtime()->jitRuntime()->execAlloc(), kind);
    1.88 +    }
    1.89 +
    1.90 +    JitCode *newCodeForIonScript(JSContext *cx) {
    1.91 +#ifdef JS_CODEGEN_ARM
    1.92 +        // ARM does not yet use implicit interrupt checks, see bug 864220.
    1.93 +        return newCode<CanGC>(cx, JSC::ION_CODE);
    1.94 +#else
    1.95 +        // The caller must lock the runtime against interrupt requests, as the
    1.96 +        // thread requesting an interrupt may use the executable allocator below.
    1.97 +        JS_ASSERT(cx->runtime()->currentThreadOwnsInterruptLock());
    1.98 +
    1.99 +        JSC::ExecutableAllocator *alloc = cx->runtime()->jitRuntime()->getIonAlloc(cx);
   1.100 +        if (!alloc)
   1.101 +            return nullptr;
   1.102 +
   1.103 +        return newCode<CanGC>(cx, alloc, JSC::ION_CODE);
   1.104 +#endif
   1.105 +    }
   1.106 +};
   1.107 +
   1.108 +} // namespace jit
   1.109 +} // namespace js
   1.110 +
   1.111 +#endif /* jit_IonLinker_h */

mercurial