js/src/jit/AsmJS.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef jit_AsmJS_h
michael@0 8 #define jit_AsmJS_h
michael@0 9
michael@0 10 #include <stddef.h>
michael@0 11
michael@0 12 #include "js/TypeDecls.h"
michael@0 13 #include "vm/ObjectImpl.h"
michael@0 14
michael@0 15 namespace js {
michael@0 16
michael@0 17 class ExclusiveContext;
michael@0 18 namespace frontend {
michael@0 19 template <typename ParseHandler> struct Parser;
michael@0 20 template <typename ParseHandler> struct ParseContext;
michael@0 21 class FullParseHandler;
michael@0 22 struct ParseNode;
michael@0 23 }
michael@0 24
michael@0 25 typedef frontend::Parser<frontend::FullParseHandler> AsmJSParser;
michael@0 26 typedef frontend::ParseContext<frontend::FullParseHandler> AsmJSParseContext;
michael@0 27
michael@0 28 // Takes over parsing of a function starting with "use asm". The return value
michael@0 29 // indicates whether an error was reported which the caller should propagate.
michael@0 30 // If no error was reported, the function may still fail to validate as asm.js.
michael@0 31 // In this case, the parser.tokenStream has been advanced an indeterminate
michael@0 32 // amount and the entire function should be reparsed from the beginning.
michael@0 33 extern bool
michael@0 34 CompileAsmJS(ExclusiveContext *cx, AsmJSParser &parser, frontend::ParseNode *stmtList,
michael@0 35 bool *validated);
michael@0 36
michael@0 37 // The assumed page size; dynamically checked in CompileAsmJS.
michael@0 38 const size_t AsmJSPageSize = 4096;
michael@0 39
michael@0 40 // The asm.js spec requires that the ArrayBuffer's byteLength be a multiple of 4096.
michael@0 41 static const size_t AsmJSAllocationGranularity = 4096;
michael@0 42
michael@0 43 #ifdef JS_CODEGEN_X64
michael@0 44 // On x64, the internal ArrayBuffer data array is inflated to 4GiB (only the
michael@0 45 // byteLength portion of which is accessible) so that out-of-bounds accesses
michael@0 46 // (made using a uint32 index) are guaranteed to raise a SIGSEGV.
michael@0 47 static const size_t AsmJSBufferProtectedSize = 4 * 1024ULL * 1024ULL * 1024ULL;
michael@0 48
michael@0 49 // To avoid dynamically checking bounds on each load/store, asm.js code relies
michael@0 50 // on the SIGSEGV handler in AsmJSSignalHandlers.cpp. However, this only works
michael@0 51 // if we can guarantee that *any* out-of-bounds access generates a fault. This
michael@0 52 // isn't generally true since an out-of-bounds access could land on other
michael@0 53 // Mozilla data. To overcome this on x64, we reserve an entire 4GB space,
michael@0 54 // making only the range [0, byteLength) accessible, and use a 32-bit unsigned
michael@0 55 // index into this space. (x86 and ARM require different tricks.)
michael@0 56 //
michael@0 57 // One complication is that we need to put an ObjectElements struct immediately
michael@0 58 // before the data array (as required by the general JSObject data structure).
michael@0 59 // Thus, we must stick a page before the elements to hold ObjectElements.
michael@0 60 //
michael@0 61 // |<------------------------------ 4GB + 1 pages --------------------->|
michael@0 62 // |<--- sizeof --->|<------------------- 4GB ----------------->|
michael@0 63 //
michael@0 64 // | waste | ObjectElements | data array | inaccessible reserved memory |
michael@0 65 // ^ ^ ^
michael@0 66 // | \ /
michael@0 67 // obj->elements required to be page boundaries
michael@0 68 //
michael@0 69 static const size_t AsmJSMappedSize = AsmJSPageSize + AsmJSBufferProtectedSize;
michael@0 70 #endif // JS_CODEGEN_X64
michael@0 71
michael@0 72 #ifdef JS_ION
michael@0 73
michael@0 74 // Return whether asm.js optimization is inhibitted by the platform or
michael@0 75 // dynamically disabled:
michael@0 76 extern bool
michael@0 77 IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, JS::Value *vp);
michael@0 78
michael@0 79 #else // JS_ION
michael@0 80
michael@0 81 inline bool
michael@0 82 IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
michael@0 83 {
michael@0 84 CallArgs args = CallArgsFromVp(argc, vp);
michael@0 85 args.rval().set(BooleanValue(false));
michael@0 86 return true;
michael@0 87 }
michael@0 88
michael@0 89 #endif // JS_ION
michael@0 90
michael@0 91 // The Asm.js heap length is constrained by the x64 backend heap access scheme
michael@0 92 // to be a multiple of the page size which is 4096 bytes, and also constrained
michael@0 93 // by the limits of ARM backends 'cmp immediate' instruction which supports a
michael@0 94 // complex range for the immediate argument.
michael@0 95 //
michael@0 96 // ARMv7 mode supports the following immediate constants, and the Thumb T2
michael@0 97 // instruction encoding also supports the subset of immediate constants used.
michael@0 98 // abcdefgh 00000000 00000000 00000000
michael@0 99 // 00abcdef gh000000 00000000 00000000
michael@0 100 // 0000abcd efgh0000 00000000 00000000
michael@0 101 // 000000ab cdefgh00 00000000 00000000
michael@0 102 // 00000000 abcdefgh 00000000 00000000
michael@0 103 // 00000000 00abcdef gh000000 00000000
michael@0 104 // 00000000 0000abcd efgh0000 00000000
michael@0 105 // ...
michael@0 106 //
michael@0 107 // The 4096 page size constraint restricts the length to:
michael@0 108 // xxxxxxxx xxxxxxxx xxxx0000 00000000
michael@0 109 //
michael@0 110 // Intersecting all the above constraints gives:
michael@0 111 // Heap length 0x40000000 to 0xff000000 quanta 0x01000000
michael@0 112 // Heap length 0x10000000 to 0x3fc00000 quanta 0x00400000
michael@0 113 // Heap length 0x04000000 to 0x0ff00000 quanta 0x00100000
michael@0 114 // Heap length 0x01000000 to 0x03fc0000 quanta 0x00040000
michael@0 115 // Heap length 0x00400000 to 0x00ff0000 quanta 0x00010000
michael@0 116 // Heap length 0x00100000 to 0x003fc000 quanta 0x00004000
michael@0 117 // Heap length 0x00001000 to 0x000ff000 quanta 0x00001000
michael@0 118 //
michael@0 119 inline uint32_t
michael@0 120 RoundUpToNextValidAsmJSHeapLength(uint32_t length)
michael@0 121 {
michael@0 122 if (length < 0x00001000u) // Minimum length is the pages size of 4096.
michael@0 123 return 0x1000u;
michael@0 124 if (length < 0x00100000u) // < 1M quanta 4K
michael@0 125 return (length + 0x00000fff) & ~0x00000fff;
michael@0 126 if (length < 0x00400000u) // < 4M quanta 16K
michael@0 127 return (length + 0x00003fff) & ~0x00003fff;
michael@0 128 if (length < 0x01000000u) // < 16M quanta 64K
michael@0 129 return (length + 0x0000ffff) & ~0x0000ffff;
michael@0 130 if (length < 0x04000000u) // < 64M quanta 256K
michael@0 131 return (length + 0x0003ffff) & ~0x0003ffff;
michael@0 132 if (length < 0x10000000u) // < 256M quanta 1M
michael@0 133 return (length + 0x000fffff) & ~0x000fffff;
michael@0 134 if (length < 0x40000000u) // < 1024M quanta 4M
michael@0 135 return (length + 0x003fffff) & ~0x003fffff;
michael@0 136 // < 4096M quanta 16M. Note zero is returned if over 0xff000000 but such
michael@0 137 // lengths are not currently valid.
michael@0 138 JS_ASSERT(length <= 0xff000000);
michael@0 139 return (length + 0x00ffffff) & ~0x00ffffff;
michael@0 140 }
michael@0 141
michael@0 142 inline bool
michael@0 143 IsValidAsmJSHeapLength(uint32_t length)
michael@0 144 {
michael@0 145 if (length < AsmJSAllocationGranularity)
michael@0 146 return false;
michael@0 147 if (length <= 0x00100000u)
michael@0 148 return (length & 0x00000fff) == 0;
michael@0 149 if (length <= 0x00400000u)
michael@0 150 return (length & 0x00003fff) == 0;
michael@0 151 if (length <= 0x01000000u)
michael@0 152 return (length & 0x0000ffff) == 0;
michael@0 153 if (length <= 0x04000000u)
michael@0 154 return (length & 0x0003ffff) == 0;
michael@0 155 if (length <= 0x10000000u)
michael@0 156 return (length & 0x000fffff) == 0;
michael@0 157 if (length <= 0x40000000u)
michael@0 158 return (length & 0x003fffff) == 0;
michael@0 159 if (length <= 0xff000000u)
michael@0 160 return (length & 0x00ffffff) == 0;
michael@0 161 return false;
michael@0 162 }
michael@0 163
michael@0 164 } // namespace js
michael@0 165
michael@0 166 #endif // jit_AsmJS_h

mercurial