js/src/devtools/rootAnalysis/annotations.js

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: Javascript; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2
michael@0 3 "use strict";
michael@0 4
michael@0 5 // Ignore calls made through these function pointers
michael@0 6 var ignoreIndirectCalls = {
michael@0 7 "mallocSizeOf" : true,
michael@0 8 "aMallocSizeOf" : true,
michael@0 9 "_malloc_message" : true,
michael@0 10 "__conv" : true,
michael@0 11 "__convf" : true,
michael@0 12 "prerrortable.c:callback_newtable" : true,
michael@0 13 "mozalloc_oom.cpp:void (* gAbortHandler)(size_t)" : true,
michael@0 14
michael@0 15 // I don't know why these are getting truncated
michael@0 16 "nsTraceRefcnt.cpp:void (* leakyLogAddRef)(void*": true,
michael@0 17 "nsTraceRefcnt.cpp:void (* leakyLogAddRef)(void*, int, int)": true,
michael@0 18 "nsTraceRefcnt.cpp:void (* leakyLogRelease)(void*": true,
michael@0 19 "nsTraceRefcnt.cpp:void (* leakyLogRelease)(void*, int, int)": true,
michael@0 20 };
michael@0 21
michael@0 22 function indirectCallCannotGC(fullCaller, fullVariable)
michael@0 23 {
michael@0 24 var caller = readable(fullCaller);
michael@0 25
michael@0 26 // This is usually a simple variable name, but sometimes a full name gets
michael@0 27 // passed through. And sometimes that name is truncated. Examples:
michael@0 28 // _ZL13gAbortHandler|mozalloc_oom.cpp:void (* gAbortHandler)(size_t)
michael@0 29 // _ZL14pMutexUnlockFn|umutex.cpp:void (* pMutexUnlockFn)(const void*
michael@0 30 var name = readable(fullVariable);
michael@0 31
michael@0 32 if (name in ignoreIndirectCalls)
michael@0 33 return true;
michael@0 34
michael@0 35 if (name == "mapper" && caller == "ptio.c:pt_MapError")
michael@0 36 return true;
michael@0 37
michael@0 38 if (name == "params" && caller == "PR_ExplodeTime")
michael@0 39 return true;
michael@0 40
michael@0 41 if (name == "op" && /GetWeakmapKeyDelegate/.test(caller))
michael@0 42 return true;
michael@0 43
michael@0 44 var CheckCallArgs = "AsmJS.cpp:uint8 CheckCallArgs(FunctionCompiler*, js::frontend::ParseNode*, (uint8)(FunctionCompiler*,js::frontend::ParseNode*,Type)*, FunctionCompiler::Call*)";
michael@0 45 if (name == "checkArg" && caller == CheckCallArgs)
michael@0 46 return true;
michael@0 47
michael@0 48 // hook called during script finalization which cannot GC.
michael@0 49 if (/CallDestroyScriptHook/.test(caller))
michael@0 50 return true;
michael@0 51
michael@0 52 // template method called during marking and hence cannot GC
michael@0 53 if (name == "op" && caller.indexOf("bool js::WeakMap<Key, Value, HashPolicy>::keyNeedsMark(JSObject*)") != -1)
michael@0 54 {
michael@0 55 return true;
michael@0 56 }
michael@0 57
michael@0 58 return false;
michael@0 59 }
michael@0 60
michael@0 61 // Ignore calls through functions pointers with these types
michael@0 62 var ignoreClasses = {
michael@0 63 "JSTracer" : true,
michael@0 64 "JSStringFinalizer" : true,
michael@0 65 "SprintfState" : true,
michael@0 66 "SprintfStateStr" : true,
michael@0 67 "JSLocaleCallbacks" : true,
michael@0 68 "JSC::ExecutableAllocator" : true,
michael@0 69 "PRIOMethods": true,
michael@0 70 "XPCOMFunctions" : true, // I'm a little unsure of this one
michael@0 71 "_MD_IOVector" : true,
michael@0 72 };
michael@0 73
michael@0 74 // Ignore calls through TYPE.FIELD, where TYPE is the class or struct name containing
michael@0 75 // a function pointer field named FIELD.
michael@0 76 var ignoreCallees = {
michael@0 77 "js::Class.trace" : true,
michael@0 78 "js::Class.finalize" : true,
michael@0 79 "JSRuntime.destroyPrincipals" : true,
michael@0 80 "icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC
michael@0 81 "mozilla::CycleCollectedJSRuntime.DescribeCustomObjects" : true, // During tracing, cannot GC.
michael@0 82 "mozilla::CycleCollectedJSRuntime.NoteCustomGCThingXPCOMChildren" : true, // During tracing, cannot GC.
michael@0 83 "PLDHashTableOps.hashKey" : true,
michael@0 84 "z_stream_s.zfree" : true,
michael@0 85 };
michael@0 86
michael@0 87 function fieldCallCannotGC(csu, fullfield)
michael@0 88 {
michael@0 89 if (csu in ignoreClasses)
michael@0 90 return true;
michael@0 91 if (fullfield in ignoreCallees)
michael@0 92 return true;
michael@0 93 return false;
michael@0 94 }
michael@0 95
michael@0 96 function ignoreEdgeUse(edge, variable)
michael@0 97 {
michael@0 98 // Functions which should not be treated as using variable.
michael@0 99 if (edge.Kind == "Call") {
michael@0 100 var callee = edge.Exp[0];
michael@0 101 if (callee.Kind == "Var") {
michael@0 102 var name = callee.Variable.Name[0];
michael@0 103 if (/~Anchor/.test(name))
michael@0 104 return true;
michael@0 105 if (/~DebugOnly/.test(name))
michael@0 106 return true;
michael@0 107 if (/~ScopedThreadSafeStringInspector/.test(name))
michael@0 108 return true;
michael@0 109 }
michael@0 110 }
michael@0 111
michael@0 112 return false;
michael@0 113 }
michael@0 114
michael@0 115 function ignoreEdgeAddressTaken(edge)
michael@0 116 {
michael@0 117 // Functions which may take indirect pointers to unrooted GC things,
michael@0 118 // but will copy them into rooted locations before calling anything
michael@0 119 // that can GC. These parameters should usually be replaced with
michael@0 120 // handles or mutable handles.
michael@0 121 if (edge.Kind == "Call") {
michael@0 122 var callee = edge.Exp[0];
michael@0 123 if (callee.Kind == "Var") {
michael@0 124 var name = callee.Variable.Name[0];
michael@0 125 if (/js::Invoke\(/.test(name))
michael@0 126 return true;
michael@0 127 }
michael@0 128 }
michael@0 129
michael@0 130 return false;
michael@0 131 }
michael@0 132
michael@0 133 // Ignore calls of these functions (so ignore any stack containing these)
michael@0 134 var ignoreFunctions = {
michael@0 135 "ptio.c:pt_MapError" : true,
michael@0 136 "PR_ExplodeTime" : true,
michael@0 137 "PR_ErrorInstallTable" : true,
michael@0 138 "PR_SetThreadPrivate" : true,
michael@0 139 "JSObject* js::GetWeakmapKeyDelegate(JSObject*)" : true, // FIXME: mark with AutoAssertNoGC instead
michael@0 140 "uint8 NS_IsMainThread()" : true,
michael@0 141
michael@0 142 // FIXME!
michael@0 143 "NS_LogInit": true,
michael@0 144 "NS_LogTerm": true,
michael@0 145 "NS_LogAddRef": true,
michael@0 146 "NS_LogRelease": true,
michael@0 147 "NS_LogCtor": true,
michael@0 148 "NS_LogDtor": true,
michael@0 149 "NS_LogCOMPtrAddRef": true,
michael@0 150 "NS_LogCOMPtrRelease": true,
michael@0 151
michael@0 152 // FIXME!
michael@0 153 "NS_DebugBreak": true,
michael@0 154
michael@0 155 // These are a little overzealous -- these destructors *can* GC if they end
michael@0 156 // up wrapping a pending exception. See bug 898815 for the heavyweight fix.
michael@0 157 "void js::AutoCompartment::~AutoCompartment(int32)" : true,
michael@0 158 "void JSAutoCompartment::~JSAutoCompartment(int32)" : true,
michael@0 159
michael@0 160 // Bug 948646 - the only thing AutoJSContext's constructor calls
michael@0 161 // is an Init() routine whose entire body is covered with an
michael@0 162 // AutoAssertNoGC. AutoSafeJSContext is the same thing, just with
michael@0 163 // a different value for the 'aSafe' parameter.
michael@0 164 "void mozilla::AutoJSContext::AutoJSContext(mozilla::detail::GuardObjectNotifier*)" : true,
michael@0 165 "void mozilla::AutoSafeJSContext::~AutoSafeJSContext(int32)" : true,
michael@0 166
michael@0 167 // And these are workarounds to avoid even more analysis work,
michael@0 168 // which would sadly still be needed even with bug 898815.
michael@0 169 "void js::AutoCompartment::AutoCompartment(js::ExclusiveContext*, JSCompartment*)": true,
michael@0 170 };
michael@0 171
michael@0 172 function ignoreGCFunction(mangled)
michael@0 173 {
michael@0 174 assert(mangled in readableNames);
michael@0 175 var fun = readableNames[mangled][0];
michael@0 176
michael@0 177 if (fun in ignoreFunctions)
michael@0 178 return true;
michael@0 179
michael@0 180 // Templatized function
michael@0 181 if (fun.indexOf("void nsCOMPtr<T>::Assert_NoQueryNeeded()") >= 0)
michael@0 182 return true;
michael@0 183
michael@0 184 // XXX modify refillFreeList<NoGC> to not need data flow analysis to understand it cannot GC.
michael@0 185 if (/refillFreeList/.test(fun) && /\(js::AllowGC\)0u/.test(fun))
michael@0 186 return true;
michael@0 187 return false;
michael@0 188 }
michael@0 189
michael@0 190 function isRootedTypeName(name)
michael@0 191 {
michael@0 192 if (name == "mozilla::ErrorResult" ||
michael@0 193 name == "JSErrorResult" ||
michael@0 194 name == "WrappableJSErrorResult" ||
michael@0 195 name == "js::frontend::TokenStream" ||
michael@0 196 name == "js::frontend::TokenStream::Position" ||
michael@0 197 name == "ModuleCompiler")
michael@0 198 {
michael@0 199 return true;
michael@0 200 }
michael@0 201 return false;
michael@0 202 }
michael@0 203
michael@0 204 function isRootedPointerTypeName(name)
michael@0 205 {
michael@0 206 if (name.startsWith('struct '))
michael@0 207 name = name.substr(7);
michael@0 208 if (name.startsWith('class '))
michael@0 209 name = name.substr(6);
michael@0 210 if (name.startsWith('const '))
michael@0 211 name = name.substr(6);
michael@0 212 if (name.startsWith('js::ctypes::'))
michael@0 213 name = name.substr(12);
michael@0 214 if (name.startsWith('js::'))
michael@0 215 name = name.substr(4);
michael@0 216 if (name.startsWith('JS::'))
michael@0 217 name = name.substr(4);
michael@0 218 if (name.startsWith('mozilla::dom::'))
michael@0 219 name = name.substr(14);
michael@0 220
michael@0 221 if (name.startsWith('MaybeRooted<'))
michael@0 222 return /\(js::AllowGC\)1u>::RootType/.test(name);
michael@0 223
michael@0 224 return name.startsWith('Rooted') || name.startsWith('PersistentRooted');
michael@0 225 }
michael@0 226
michael@0 227 function isSuppressConstructor(name)
michael@0 228 {
michael@0 229 return name.indexOf("::AutoSuppressGC") != -1
michael@0 230 || name.indexOf("::AutoEnterAnalysis") != -1
michael@0 231 || name.indexOf("::AutoAssertNoGC") != -1
michael@0 232 || name.indexOf("::AutoIgnoreRootingHazards") != -1;
michael@0 233 }
michael@0 234
michael@0 235 // nsISupports subclasses' methods may be scriptable (or overridden
michael@0 236 // via binary XPCOM), and so may GC. But some fields just aren't going
michael@0 237 // to get overridden with something that can GC.
michael@0 238 function isOverridableField(initialCSU, csu, field)
michael@0 239 {
michael@0 240 if (csu != 'nsISupports')
michael@0 241 return false;
michael@0 242 if (field == 'GetCurrentJSContext')
michael@0 243 return false;
michael@0 244 if (field == 'IsOnCurrentThread')
michael@0 245 return false;
michael@0 246 if (field == 'GetNativeContext')
michael@0 247 return false;
michael@0 248 if (field == "GetGlobalJSObject")
michael@0 249 return false;
michael@0 250 if (field == "GetIsMainThread")
michael@0 251 return false;
michael@0 252 if (initialCSU == 'nsIXPConnectJSObjectHolder' && field == 'GetJSObject')
michael@0 253 return false;
michael@0 254
michael@0 255 return true;
michael@0 256 }

mercurial