So I was supposed to be working on making the JIT engine conform to W^X a few
months ago. It took a bit longer than expected, but I had a mostly working
patch. Then I disappeared from OpenBSD for a bit and took my patch with me.
Last week I was just starting to feed that patch upstream to firefox, when I
found out about another developer who had already done similar work. Sigh.

The official firefox patch seems likely to ship in some future version, which
is good news for everyone. It's quite similar to the patch I had (though more
polished). To make it available sooner for OpenBSD, here's a backport to the
Firefox in ports.

I haven't been able to test this very much, as I'm still at BSDCan, but when I
get back next week I hope to be able to devote more time to finalizing this
patch. Posting now to let people know it's coming and to give a preview if
you're interested.


--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_irregexp_NativeRegExpMacroAssembler_cpp        Sat Jun 
13 14:16:15 2015
@@ -0,0 +1,12 @@
+$OpenBSD$
+--- js/src/irregexp/NativeRegExpMacroAssembler.cpp.orig        Sat Jun 13 
13:54:41 2015
++++ js/src/irregexp/NativeRegExpMacroAssembler.cpp     Sat Jun 13 13:55:10 2015
+@@ -450,6 +450,8 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx
+     writePerfSpewerJitCodeProfile(code, "RegExp");
+ #endif
+ 
++    AutoWritableJitCode awjc(code);
++
+     for (size_t i = 0; i < labelPatches.length(); i++) {
+         LabelPatch& v = labelPatches[i];
+         MOZ_ASSERT(!v.label);
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_BaselineCompiler_cpp       Sat Jun 13 14:16:15 2015
@@ -0,0 +1,39 @@
+$OpenBSD$
+--- js/src/jit/BaselineCompiler.cpp.orig       Sat Jun 13 13:55:40 2015
++++ js/src/jit/BaselineCompiler.cpp    Sat Jun 13 13:57:13 2015
+@@ -226,7 +226,13 @@ BaselineCompiler::compile()
+     // Adopt fallback stubs from the compiler into the baseline script.
+     baselineScript->adoptFallbackStubs(&stubSpace_);
+ 
+-    // Patch IC loads using IC entries
++    // All barriers are emitted off-by-default, toggle them on if needed.
++    if (cx->zone()->needsIncrementalBarrier())
++        baselineScript->toggleBarriers(true);
++    if 
(cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(cx->runtime()))
++          baselineScript->toggleProfilerInstrumentation(true);
++    AutoWritableJitCode awjc(code);
++
+     for (size_t i = 0; i < icLoadLabels_.length(); i++) {
+         CodeOffsetLabel label = icLoadLabels_[i].label;
+         label.fixup(&masm);
+@@ -240,9 +246,6 @@ BaselineCompiler::compile()
+     if (modifiesArguments_)
+         baselineScript->setModifiesArguments();
+ 
+-    // All barriers are emitted off-by-default, toggle them on if needed.
+-    if (cx->zone()->needsIncrementalBarrier())
+-        baselineScript->toggleBarriers(true);
+ 
+ #ifdef JS_TRACE_LOGGING
+     // Initialize the tracelogger instrumentation.
+@@ -260,10 +263,6 @@ BaselineCompiler::compile()
+ 
+     if (compileDebugInstrumentation_)
+         baselineScript->setHasDebugInstrumentation();
+-
+-    // If profiler instrumentation is enabled, toggle instrumentation on.
+-    if 
(cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(cx->runtime()))
+-        baselineScript->toggleProfilerInstrumentation(true);
+ 
+     // Always register a native => bytecode mapping entry, since profiler can 
be
+     // turned on with baseline jitcode on stack, and baseline jitcode cannot 
be invalidated.
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_BaselineJIT_cpp    Sat Jun 13 14:16:15 2015
@@ -0,0 +1,38 @@
+$OpenBSD$
+--- js/src/jit/BaselineJIT.cpp.orig    Sat Jun 13 13:57:28 2015
++++ js/src/jit/BaselineJIT.cpp Sat Jun 13 13:59:10 2015
+@@ -841,6 +841,8 @@ BaselineScript::toggleDebugTraps(JSScript* script, jsb
+ 
+     SrcNoteLineScanner scanner(script->notes(), script->lineno());
+ 
++    AutoWritableJitCode awjc(method());
++
+     for (uint32_t i = 0; i < numPCMappingIndexEntries(); i++) {
+         PCMappingIndexEntry& entry = pcMappingIndexEntry(i);
+ 
+@@ -887,6 +889,7 @@ BaselineScript::initTraceLogger(JSRuntime* runtime, JS
+         traceLoggerScriptEvent_ = TraceLoggerEvent(logger, 
TraceLogger_Scripts);
+ 
+     if (TraceLogTextIdEnabled(TraceLogger_Engine) || 
TraceLogTextIdEnabled(TraceLogger_Scripts)) {
++          AutoWritableJitCode awjc(method_);
+         CodeLocationLabel enter(method_, 
CodeOffsetLabel(traceLoggerEnterToggleOffset_));
+         CodeLocationLabel exit(method_, 
CodeOffsetLabel(traceLoggerExitToggleOffset_));
+         Assembler::ToggleToCmp(enter);
+@@ -910,6 +913,8 @@ BaselineScript::toggleTraceLoggerScripts(JSRuntime* ru
+     else
+         traceLoggerScriptEvent_ = TraceLoggerEvent(logger, 
TraceLogger_Scripts);
+ 
++    AutoWritableJitCode awjc(method());
++
+     // Enable/Disable the traceLogger prologue and epilogue.
+     CodeLocationLabel enter(method_, 
CodeOffsetLabel(traceLoggerEnterToggleOffset_));
+     CodeLocationLabel exit(method_, 
CodeOffsetLabel(traceLoggerExitToggleOffset_));
+@@ -963,6 +968,8 @@ BaselineScript::toggleProfilerInstrumentation(bool ena
+ 
+     JitSpew(JitSpew_BaselineIC, "  toggling profiling %s for BaselineScript 
%p",
+             enable ? "on" : "off", this);
++
++    AutoWritableJitCode awjc(method());
+ 
+     // Toggle the jump
+     CodeLocationLabel enterToggleLocation(method_, 
CodeOffsetLabel(profilerEnterToggleOffset_));
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_CodeGenerator_cpp  Sat Jun 13 14:16:15 2015
@@ -0,0 +1,96 @@
+$OpenBSD$
+--- js/src/jit/CodeGenerator.cpp.orig  Sat Jun 13 13:59:27 2015
++++ js/src/jit/CodeGenerator.cpp       Sat Jun 13 14:02:49 2015
+@@ -7525,11 +7525,45 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintL
+ 
+     script->setIonScript(cx, ionScript);
+ 
+-    invalidateEpilogueData_.fixup(&masm);
+-    Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
invalidateEpilogueData_),
+-                                       ImmPtr(ionScript),
+-                                       ImmPtr((void*)-1));
++    {
++        AutoWritableJitCode awjc(code);
++        invalidateEpilogueData_.fixup(&masm);
++        Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
invalidateEpilogueData_),
++                                           ImmPtr(ionScript),
++                                           ImmPtr((void*)-1));
+ 
++        for (size_t i = 0; i < ionScriptLabels_.length(); i++) {
++            ionScriptLabels_[i].fixup(&masm);
++            Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
ionScriptLabels_[i]),
++                                               ImmPtr(ionScript),
++                                               ImmPtr((void*)-1));
++        }
++
++#ifdef JS_TRACE_LOGGING
++    TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime());
++    for (uint32_t i = 0; i < patchableTraceLoggers_.length(); i++) {
++        patchableTraceLoggers_[i].fixup(&masm);
++        Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
patchableTraceLoggers_[i]),
++                                           ImmPtr(logger),
++                                           ImmPtr(nullptr));
++    }
++
++    if (patchableTLScripts_.length() > 0) {
++        MOZ_ASSERT(TraceLogTextIdEnabled(TraceLogger_Scripts));
++        TraceLoggerEvent event(logger, TraceLogger_Scripts, script);
++        ionScript->setTraceLoggerEvent(event);
++        uint32_t textId = event.payload()->textId();
++        for (uint32_t i = 0; i < patchableTLScripts_.length(); i++) {
++            patchableTLScripts_[i].fixup(&masm);
++            Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
patchableTLScripts_[i]),
++                                               ImmPtr((void *) 
uintptr_t(textId)),
++                                               ImmPtr((void *)0));
++      }
++    }
++#endif
++    }
++
++
+     JitSpew(JitSpew_Codegen, "Created IonScript %p (raw %p)",
+             (void*) ionScript, (void*) code->raw());
+ 
+@@ -7546,13 +7580,6 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintL
+         perfSpewer_.writeProfile(script, code, masm);
+ #endif
+ 
+-    for (size_t i = 0; i < ionScriptLabels_.length(); i++) {
+-        ionScriptLabels_[i].fixup(&masm);
+-        Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
ionScriptLabels_[i]),
+-                                           ImmPtr(ionScript),
+-                                           ImmPtr((void*)-1));
+-    }
+-
+     // for generating inline caches during the execution.
+     if (runtimeData_.length())
+         ionScript->copyRuntimeData(&runtimeData_[0]);
+@@ -7580,28 +7607,6 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintL
+     if (patchableBackedges_.length() > 0)
+         ionScript->copyPatchableBackedges(cx, code, 
patchableBackedges_.begin(), masm);
+ 
+-#ifdef JS_TRACE_LOGGING
+-    TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
+-    for (uint32_t i = 0; i < patchableTraceLoggers_.length(); i++) {
+-        patchableTraceLoggers_[i].fixup(&masm);
+-        Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
patchableTraceLoggers_[i]),
+-                                           ImmPtr(logger),
+-                                           ImmPtr(nullptr));
+-    }
+-
+-    if (patchableTLScripts_.length() > 0) {
+-        MOZ_ASSERT(TraceLogTextIdEnabled(TraceLogger_Scripts));
+-        TraceLoggerEvent event(logger, TraceLogger_Scripts, script);
+-        ionScript->setTraceLoggerEvent(event);
+-        uint32_t textId = event.payload()->textId();
+-        for (uint32_t i = 0; i < patchableTLScripts_.length(); i++) {
+-            patchableTLScripts_[i].fixup(&masm);
+-            Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
patchableTLScripts_[i]),
+-                                               ImmPtr((void*) 
uintptr_t(textId)),
+-                                               ImmPtr((void*)0));
+-        }
+-    }
+-#endif
+ 
+     // Replace dummy JSObject pointers embedded by LNurseryObject.
+     code->fixupNurseryObjects(cx, gen->nurseryObjects());
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_ExecutableAllocatorPosix_cpp       Sat Jun 13 
14:16:15 2015
@@ -0,0 +1,22 @@
+$OpenBSD$
+--- js/src/jit/ExecutableAllocatorPosix.cpp.orig       Sat Jun 13 14:04:07 2015
++++ js/src/jit/ExecutableAllocatorPosix.cpp    Sat Jun 13 14:04:47 2015
+@@ -70,11 +70,9 @@ void ExecutableAllocator::systemRelease(const Executab
+     DeallocateExecutableMemory(alloc.pages, alloc.size, pageSize);
+ }
+ 
+-#if WTF_ENABLE_ASSEMBLER_WX_EXCLUSIVE
+ void ExecutableAllocator::reprotectRegion(void* start, size_t size, 
ProtectionSetting setting)
+ {
+-    if (!pageSize)
+-        intializePageSize();
++      MOZ_ASSERT(pageSize);
+ 
+     // Calculate the start of the page containing this region,
+     // and account for this extra memory within size.
+@@ -89,5 +87,4 @@ void ExecutableAllocator::reprotectRegion(void* start,
+ 
+     mprotect(pageStart, size, (setting == Writable) ? PROTECTION_FLAGS_RW : 
PROTECTION_FLAGS_RX);
+ }
+-#endif
+ 
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_ExecutableAllocator_h      Sat Jun 13 14:16:15 2015
@@ -0,0 +1,46 @@
+$OpenBSD$
+--- js/src/jit/ExecutableAllocator.h.orig      Sat Jun 13 14:03:05 2015
++++ js/src/jit/ExecutableAllocator.h   Sat Jun 13 14:03:51 2015
+@@ -57,13 +57,9 @@ extern  "C" void sync_instruction_memory(caddr_t v, u_
+ #include <sys/cachectl.h>
+ #endif
+ 
+-#if ENABLE_ASSEMBLER_WX_EXCLUSIVE
+ #define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE)
+ #define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC)
+ #define INITIAL_PROTECTION_FLAGS PROTECTION_FLAGS_RX
+-#else
+-#define INITIAL_PROTECTION_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC)
+-#endif
+ 
+ namespace JS {
+     struct CodeSizes;
+@@ -379,7 +375,6 @@ class ExecutableAllocator {
+         return pool;
+     }
+ 
+-#if ENABLE_ASSEMBLER_WX_EXCLUSIVE
+     static void makeWritable(void* start, size_t size)
+     {
+         reprotectRegion(start, size, Writable);
+@@ -389,10 +384,6 @@ class ExecutableAllocator {
+     {
+         reprotectRegion(start, size, Executable);
+     }
+-#else
+-    static void makeWritable(void*, size_t) {}
+-    static void makeExecutable(void*, size_t) {}
+-#endif
+ 
+ 
+ #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
+@@ -446,9 +437,7 @@ class ExecutableAllocator {
+     ExecutableAllocator(const ExecutableAllocator&) = delete;
+     void operator=(const ExecutableAllocator&) = delete;
+ 
+-#if ENABLE_ASSEMBLER_WX_EXCLUSIVE
+     static void reprotectRegion(void*, size_t, ProtectionSetting);
+-#endif
+ 
+     // These are strong references;  they keep pools alive.
+     static const size_t maxSmallPools = 4;
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_IonCaches_cpp      Sat Jun 13 14:16:15 2015
@@ -0,0 +1,20 @@
+$OpenBSD$
+--- js/src/jit/IonCaches.cpp.orig      Sat Jun 13 14:07:41 2015
++++ js/src/jit/IonCaches.cpp   Sat Jun 13 14:08:21 2015
+@@ -246,6 +246,7 @@ class IonCache::StubAttacher
+ 
+     void patchStubCodePointer(MacroAssembler& masm, JitCode* code) {
+         if (hasStubCodePatchOffset_) {
++              AutoWritableJitCode awjc(code);
+             stubCodePatchOffset_.fixup(&masm);
+             Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, 
stubCodePatchOffset_),
+                                                ImmPtr(code), STUB_ADDR);
+@@ -312,6 +313,8 @@ RepatchIonCache::bindInitialJump(MacroAssembler& masm,
+ void
+ RepatchIonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
+ {
++      AutoWritableJitCode awjc(code);
++
+     IonCache::updateBaseAddress(code, masm);
+     initialJump_.repoint(code, &masm);
+     lastJump_.repoint(code, &masm);
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_IonCode_h  Sat Jun 13 14:16:15 2015
@@ -0,0 +1,14 @@
+$OpenBSD$
+--- js/src/jit/IonCode.h.orig  Sat Jun 13 14:10:25 2015
++++ js/src/jit/IonCode.h       Sat Jun 13 14:10:46 2015
+@@ -107,6 +107,10 @@ class JitCode : public gc::TenuredCell
+     size_t instructionsSize() const {
+         return insnSize_;
+     }
++    size_t bufferSize() const {
++          return bufferSize_;
++
++    }
+     void trace(JSTracer* trc);
+     void finalize(FreeOp* fop);
+     void fixupAfterMovingGC() {}
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_Ion_cpp    Sat Jun 13 14:16:15 2015
@@ -0,0 +1,49 @@
+$OpenBSD$
+--- js/src/jit/Ion.cpp.orig    Sat Jun 13 14:05:05 2015
++++ js/src/jit/Ion.cpp Sat Jun 13 14:07:32 2015
+@@ -626,6 +626,8 @@ JitCode::trace(JSTracer* trc)
+     if (invalidated())
+         return;
+ 
++    AutoWritableJitCode awjc(this);
++
+     if (jumpRelocTableBytes_) {
+         uint8_t* start = code_ + jumpRelocTableOffset();
+         CompactBufferReader reader(start, start + jumpRelocTableBytes_);
+@@ -644,6 +646,8 @@ JitCode::fixupNurseryObjects(JSContext* cx, const Obje
+     if (nurseryObjects.empty() || !dataRelocTableBytes_)
+         return;
+ 
++    AutoWritableJitCode awjc(this);
++
+     uint8_t* start = code_ + dataRelocTableOffset();
+     CompactBufferReader reader(start, start + dataRelocTableBytes_);
+     MacroAssembler::FixupNurseryObjects(cx, this, reader, nurseryObjects);
+@@ -663,7 +667,10 @@ JitCode::finalize(FreeOp* fop)
+     // Buffer can be freed at any time hereafter. Catch use-after-free bugs.
+     // Don't do this if the Ion code is protected, as the signal handler will
+     // deadlock trying to reacquire the interrupt lock.
+-    memset(code_, JS_SWEPT_CODE_PATTERN, bufferSize_);
++    {
++      AutoWritableJitCode awjc(this);
++      memset(code_, JS_SWEPT_CODE_PATTERN, bufferSize_);
++    }
+     code_ = nullptr;
+ 
+     // Code buffers are stored inside JSC pools.
+@@ -680,6 +687,7 @@ JitCode::finalize(FreeOp* fop)
+ void
+ JitCode::togglePreBarriers(bool enabled)
+ {
++      AutoWritableJitCode awjc(this);
+     uint8_t* start = code_ + preBarrierTableOffset();
+     CompactBufferReader reader(start, start + preBarrierTableBytes_);
+ 
+@@ -2590,6 +2598,7 @@ InvalidateActivation(FreeOp* fop, const JitActivationI
+         // the call sequence causing the safepoint being >= the size of
+         // a uint32, which is checked during safepoint index
+         // construction.
++      AutoWritableJitCode awjc(ionCode);
+         const SafepointIndex* si = 
ionScript->getSafepointIndex(it.returnAddressToFp());
+         CodeLocationLabel dataLabelToMunge(it.returnAddressToFp());
+         ptrdiff_t delta = ionScript->invalidateEpilogueDataOffset() -
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_Linker_h   Sat Jun 13 14:16:15 2015
@@ -0,0 +1,11 @@
+$OpenBSD$
+--- js/src/jit/Linker.h.orig   Sat Jun 13 14:10:54 2015
++++ js/src/jit/Linker.h        Sat Jun 13 14:11:25 2015
+@@ -68,6 +68,7 @@ class Linker
+             return nullptr;
+         if (masm.oom())
+             return fail(cx);
++      AutoWritableJitCode awjc(result, bytesNeeded);
+         code->copyFrom(masm);
+         masm.link(code);
+         if (masm.embedsNurseryPointers())
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_jit_x86_Assembler-x86_h        Sat Jun 13 14:16:15 2015
@@ -0,0 +1,11 @@
+$OpenBSD$
+--- js/src/jit/x86/Assembler-x86.h.orig        Sat Jun 13 14:11:43 2015
++++ js/src/jit/x86/Assembler-x86.h     Sat Jun 13 14:11:59 2015
+@@ -164,6 +164,7 @@ PatchJump(CodeLocationJump jump, CodeLocationLabel lab
+     MOZ_ASSERT(((*x >= 0x80 && *x <= 0x8F) && *(x - 1) == 0x0F) ||
+                (*x == 0xE9));
+ #endif
++    AutoWritableJitCode awjc(jump.raw() - 8, 8);
+     X86Encoding::SetRel32(jump.raw(), label.raw());
+ }
+ static inline void
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_vm_Runtime_cpp Sat Jun 13 14:16:15 2015
@@ -0,0 +1,11 @@
+$OpenBSD$
+--- js/src/vm/Runtime.cpp.orig Sat Jun 13 14:12:26 2015
++++ js/src/vm/Runtime.cpp      Sat Jun 13 14:12:47 2015
+@@ -206,6 +206,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
+     ctypesActivityCallback(nullptr),
+     offthreadIonCompilationEnabled_(true),
+     parallelParsingEnabled_(true),
++    autoWritableJitCodeActive_(false),
+ #ifdef DEBUG
+     enteredPolicy(nullptr),
+ #endif
--- /dev/null   Sat Jun 13 16:06:25 2015
+++ patches/patch-js_src_vm_Runtime_h   Sat Jun 13 14:16:15 2015
@@ -0,0 +1,57 @@
+$OpenBSD$
+--- js/src/vm/Runtime.h.orig   Sat Jun 13 14:12:57 2015
++++ js/src/vm/Runtime.h        Sat Jun 13 14:15:02 2015
+@@ -1305,6 +1305,8 @@ struct JSRuntime : public JS::shadow::Runtime,
+     bool offthreadIonCompilationEnabled_;
+     bool parallelParsingEnabled_;
+ 
++    bool autoWritableJitCodeActive_;
++
+   public:
+ 
+     // Note: these values may be toggled dynamically (in response to 
about:config
+@@ -1322,6 +1324,11 @@ struct JSRuntime : public JS::shadow::Runtime,
+         return parallelParsingEnabled_;
+     }
+ 
++    void toggleAutoWritableJitCodeActive(bool b) {
++          MOZ_ASSERT(autoWritableJitCodeActive_ != b);
++          autoWritableJitCodeActive_ = b;
++    }
++
+     const JS::RuntimeOptions& options() const {
+         return options_;
+     }
+@@ -1714,6 +1721,32 @@ class AutoEnterIonCompilation
+ 
+     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+ };
++
++class MOZ_STACK_CLASS AutoWritableJitCode
++{
++    JSRuntime *rt_;
++    void *addr_;
++    size_t size_;
++
++  public:
++    AutoWritableJitCode(JSRuntime *rt, void *addr, size_t size)
++      : rt_(rt), addr_(addr), size_(size)
++    {
++        rt_->toggleAutoWritableJitCodeActive(true);
++        jit::ExecutableAllocator::makeWritable(addr_, size_);
++    }
++    AutoWritableJitCode(void *addr, size_t size)
++      : AutoWritableJitCode(TlsPerThreadData.get()->runtimeFromMainThread(), 
addr, size)
++    {}
++    explicit AutoWritableJitCode(jit::JitCode *code)
++      : AutoWritableJitCode(code->runtimeFromMainThread(), code->raw(), 
code->bufferSize())
++    {}
++    ~AutoWritableJitCode() {
++        jit::ExecutableAllocator::makeExecutable(addr_, size_);
++        rt_->toggleAutoWritableJitCodeActive(false);
++    }
++};
++
+ 
+ } /* namespace js */
+ 

Reply via email to