Bug 839376 (part 3) - Some low-hanging exact rooting fruit. sfink.
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 11 Feb 2013 14:04:25 -0800
changeset 121543 c4562906fc61a36c0a6f4c3e48ab86acb6f038ce
parent 121542 1b3c6d4ee0aef388ec130294a1588f77ce64d69f
child 121544 35eda1ce617e0a3dc2d7006330dd80b086f388aa
push id22783
push usernnethercote@mozilla.com
push dateMon, 11 Feb 2013 22:42:55 +0000
treeherdermozilla-inbound@c4562906fc61 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs839376
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 839376 (part 3) - Some low-hanging exact rooting fruit. sfink.
js/src/builtin/Eval.cpp
js/src/builtin/ParallelArray.cpp
js/src/jsatom.cpp
js/src/jsfun.cpp
js/src/jsopcode.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -158,17 +158,18 @@ enum EvalType { DIRECT_EVAL = EXECUTE_DI
 static bool
 EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, AbstractFramePtr caller,
            HandleObject scopeobj)
 {
     JS_ASSERT((evalType == INDIRECT_EVAL) == !caller);
     JS_ASSERT_IF(evalType == INDIRECT_EVAL, scopeobj->isGlobal());
     AssertInnerizedScopeChain(cx, *scopeobj);
 
-    if (!scopeobj->global().isRuntimeCodeGenEnabled(cx)) {
+    Rooted<GlobalObject*> scopeObjGlobal(cx, &scopeobj->global());
+    if (!GlobalObject::isRuntimeCodeGenEnabled(cx, scopeObjGlobal)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CSP_BLOCKED_EVAL);
         return false;
     }
 
     // ES5 15.1.2.1 step 1.
     if (args.length() < 1) {
         args.rval().setUndefined();
         return true;
--- a/js/src/builtin/ParallelArray.cpp
+++ b/js/src/builtin/ParallelArray.cpp
@@ -1413,17 +1413,17 @@ ParallelArrayObject::scatter(JSContext *
     uint32_t outer = obj->outermostDimension();
 
     // Get the scatter vector.
     RootedObject targets(cx, NonNullObject(cx, args[0]));
     if (!targets)
         return false;
 
     // The default value is optional and defaults to undefined.
-    Value defaultValue;
+    RootedValue defaultValue(cx);
     if (args.length() >= 2)
         defaultValue = args[1];
     else
         defaultValue.setUndefined();
 
     // The conflict function is optional.
     RootedObject conflictFun(cx);
     if (args.length() >= 3 && !args[2].isUndefined()) {
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -372,38 +372,35 @@ UnrootedAtom
 js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib)
 {
     AssertCanGC();
     CHECK_REQUEST(cx);
 
     if (!JSString::validateLength(cx, length))
         return NULL;
 
-    UnrootedAtom atom;
     static const unsigned ATOMIZE_BUF_MAX = 32;
     if (length < ATOMIZE_BUF_MAX) {
         /*
          * Avoiding the malloc in InflateString on shorter strings saves us
          * over 20,000 malloc calls on mozilla browser startup. This compares to
          * only 131 calls where the string is longer than a 31 char (net) buffer.
          * The vast majority of atomized strings are already in the hashtable. So
          * js::AtomizeString rarely has to copy the temp string we make.
          */
         jschar inflated[ATOMIZE_BUF_MAX];
         size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
         InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength);
-        atom = AtomizeAndCopyStableChars<CanGC>(cx, inflated, inflatedLength, ib);
-    } else {
-        jschar *tbcharsZ = InflateString(cx, bytes, &length);
-        if (!tbcharsZ)
-            return UnrootedAtom();
-        atom = AtomizeAndTakeOwnership(cx, StableCharPtr(tbcharsZ, length), length, ib);
+        return AtomizeAndCopyStableChars<CanGC>(cx, inflated, inflatedLength, ib);
     }
 
-    return atom;
+    jschar *tbcharsZ = InflateString(cx, bytes, &length);
+    if (!tbcharsZ)
+        return UnrootedAtom();
+    return AtomizeAndTakeOwnership(cx, StableCharPtr(tbcharsZ, length), length, ib);
 }
 
 template <AllowGC allowGC>
 UnrootedAtom
 js::AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavior ib)
 {
     CHECK_REQUEST(cx);
 
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1225,17 +1225,17 @@ JSFunctionSpec js::function_methods[] = 
 JSBool
 js::Function(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedString arg(cx);   // used multiple times below
 
     /* Block this call if security callbacks forbid it. */
     Rooted<GlobalObject*> global(cx, &args.callee().global());
-    if (!global->isRuntimeCodeGenEnabled(cx)) {
+    if (!GlobalObject::isRuntimeCodeGenEnabled(cx, global)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CSP_BLOCKED_FUNCTION);
         return false;
     }
 
     AutoKeepAtoms keepAtoms(cx->runtime);
     AutoNameVector formals(cx);
 
     bool hasRest = false;
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1529,17 +1529,17 @@ FindStartPC(JSContext *cx, ScriptFrameIt
             *valuepc = current;
     } else {
         *valuepc = pcstack[spindex];
     }
     return true;
 }
 
 static bool
-DecompileExpressionFromStack(JSContext *cx, int spindex, int skipStackHits, Value v, char **res)
+DecompileExpressionFromStack(JSContext *cx, int spindex, int skipStackHits, HandleValue v, char **res)
 {
     AssertCanGC();
     JS_ASSERT(spindex < 0 ||
               spindex == JSDVG_IGNORE_STACK ||
               spindex == JSDVG_SEARCH_STACK);
 
     *res = NULL;
 
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -476,27 +476,27 @@ GlobalObject::initStandardClasses(JSCont
            js_InitSetClass(cx, global) &&
            GlobalObject::initSetIteratorProto(cx, global) &&
 #if ENABLE_INTL_API
            js_InitIntlClass(cx, global) &&
 #endif
            true;
 }
 
-bool
-GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx)
+/* static */ bool
+GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx, Handle<GlobalObject*> global)
 {
-    HeapSlot &v = getSlotRef(RUNTIME_CODEGEN_ENABLED);
+    HeapSlot &v = global->getSlotRef(RUNTIME_CODEGEN_ENABLED);
     if (v.isUndefined()) {
         /*
          * If there are callbacks, make sure that the CSP callback is installed
          * and that it permits runtime code generation, then cache the result.
          */
         JSCSPEvalChecker allows = cx->runtime->securityCallbacks->contentSecurityPolicyAllows;
-        v.set(this, HeapSlot::Slot, RUNTIME_CODEGEN_ENABLED, BooleanValue(!allows || allows(cx)));
+        v.set(global, HeapSlot::Slot, RUNTIME_CODEGEN_ENABLED, BooleanValue(!allows || allows(cx)));
     }
     return !v.isFalse();
 }
 
 JSFunction *
 GlobalObject::createConstructor(JSContext *cx, Native ctor, JSAtom *nameArg, unsigned length,
                                 gc::AllocKind kind)
 {
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -415,17 +415,17 @@ class GlobalObject : public JSObject
     template<typename T>
     inline Value createArrayFromBuffer() const;
 
     Value protoGetter() const {
         JS_ASSERT(functionObjectClassesInitialized());
         return getSlot(PROTO_GETTER);
     }
 
-    bool isRuntimeCodeGenEnabled(JSContext *cx);
+    static bool isRuntimeCodeGenEnabled(JSContext *cx, Handle<GlobalObject*> global);
 
     const Value &getOriginalEval() const {
         JS_ASSERT(getSlot(EVAL).isObject());
         return getSlot(EVAL);
     }
 
     // Implemented in jsiter.cpp.
     static bool initIteratorClasses(JSContext *cx, Handle<GlobalObject*> global);
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -694,17 +694,17 @@ RegExpCompartment::get(JSContext *cx, JS
     }
 
     /* Since error deletes |shared|, only guard |shared| on success. */
     g->init(*shared.forget());
     return true;
 }
 
 bool
-RegExpCompartment::get(JSContext *cx, JSAtom *atom, JSString *opt, RegExpGuard *g)
+RegExpCompartment::get(JSContext *cx, HandleAtom atom, JSString *opt, RegExpGuard *g)
 {
     RegExpFlag flags = RegExpFlag(0);
     if (opt && !ParseRegExpFlags(cx, opt, &flags))
         return false;
 
     return get(cx, atom, flags, g);
 }
 
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -273,17 +273,17 @@ class RegExpCompartment
     ~RegExpCompartment();
 
     bool init(JSContext *cx);
     void sweep(JSRuntime *rt);
 
     bool get(JSContext *cx, JSAtom *source, RegExpFlag flags, RegExpGuard *g);
 
     /* Like 'get', but compile 'maybeOpt' (if non-null). */
-    bool get(JSContext *cx, JSAtom *source, JSString *maybeOpt, RegExpGuard *g);
+    bool get(JSContext *cx, HandleAtom source, JSString *maybeOpt, RegExpGuard *g);
 
     size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf);
 };
 
 class RegExpObject : public JSObject
 {
     static const unsigned LAST_INDEX_SLOT          = 0;
     static const unsigned SOURCE_SLOT              = 1;