js/src/jit/IonLinker.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:13f3fd0ccf8a
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef jit_IonLinker_h
8 #define jit_IonLinker_h
9
10 #include "jscntxt.h"
11 #include "jscompartment.h"
12 #include "jsgc.h"
13
14 #include "assembler/jit/ExecutableAllocator.h"
15 #include "jit/IonCode.h"
16 #include "jit/IonMacroAssembler.h"
17 #include "jit/JitCompartment.h"
18
19 namespace js {
20 namespace jit {
21
22 class Linker
23 {
24 MacroAssembler &masm;
25
26 JitCode *fail(JSContext *cx) {
27 js_ReportOutOfMemory(cx);
28 return nullptr;
29 }
30
31 template <AllowGC allowGC>
32 JitCode *newCode(JSContext *cx, JSC::ExecutableAllocator *execAlloc, JSC::CodeKind kind) {
33 JS_ASSERT(kind == JSC::ION_CODE ||
34 kind == JSC::BASELINE_CODE ||
35 kind == JSC::OTHER_CODE);
36 JS_ASSERT(masm.numAsmJSAbsoluteLinks() == 0);
37
38 gc::AutoSuppressGC suppressGC(cx);
39 if (masm.oom())
40 return fail(cx);
41
42 JSC::ExecutablePool *pool;
43 size_t bytesNeeded = masm.bytesNeeded() + sizeof(JitCode *) + CodeAlignment;
44 if (bytesNeeded >= MAX_BUFFER_SIZE)
45 return fail(cx);
46
47 // ExecutableAllocator requires bytesNeeded to be word-size aligned.
48 bytesNeeded = AlignBytes(bytesNeeded, sizeof(void *));
49
50 uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind);
51 if (!result)
52 return fail(cx);
53
54 // The JitCode pointer will be stored right before the code buffer.
55 uint8_t *codeStart = result + sizeof(JitCode *);
56
57 // Bump the code up to a nice alignment.
58 codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment);
59 uint32_t headerSize = codeStart - result;
60 JitCode *code = JitCode::New<allowGC>(cx, codeStart, bytesNeeded - headerSize,
61 headerSize, pool, kind);
62 if (!code)
63 return nullptr;
64 if (masm.oom())
65 return fail(cx);
66 code->copyFrom(masm);
67 masm.link(code);
68 #ifdef JSGC_GENERATIONAL
69 if (masm.embedsNurseryPointers())
70 cx->runtime()->gcStoreBuffer.putWholeCell(code);
71 #endif
72 return code;
73 }
74
75 public:
76 Linker(MacroAssembler &masm)
77 : masm(masm)
78 {
79 masm.finish();
80 }
81
82 template <AllowGC allowGC>
83 JitCode *newCode(JSContext *cx, JSC::CodeKind kind) {
84 return newCode<allowGC>(cx, cx->runtime()->jitRuntime()->execAlloc(), kind);
85 }
86
87 JitCode *newCodeForIonScript(JSContext *cx) {
88 #ifdef JS_CODEGEN_ARM
89 // ARM does not yet use implicit interrupt checks, see bug 864220.
90 return newCode<CanGC>(cx, JSC::ION_CODE);
91 #else
92 // The caller must lock the runtime against interrupt requests, as the
93 // thread requesting an interrupt may use the executable allocator below.
94 JS_ASSERT(cx->runtime()->currentThreadOwnsInterruptLock());
95
96 JSC::ExecutableAllocator *alloc = cx->runtime()->jitRuntime()->getIonAlloc(cx);
97 if (!alloc)
98 return nullptr;
99
100 return newCode<CanGC>(cx, alloc, JSC::ION_CODE);
101 #endif
102 }
103 };
104
105 } // namespace jit
106 } // namespace js
107
108 #endif /* jit_IonLinker_h */

mercurial