- Remove bogus JS_ASSERT(!outermost) from the code that deals with a "#n="
type string being returned from js_EnterSharpObject, where the hash entry
is not yet sharp (because we haven't seen the object twice during depth
first search). This case trivially arises for the outermost object in,
e.g., 'o={}; o.foo=o; uneval(o)'.
- Avoid parenthesizing #n={...} object initializers for uneval, as they are
not ambiguous (whereas {foo:1}, e.g., is ambiguous because it could be a
block statement containing a labeled expression statement, or it could be
an object initializer).
- Death to tabs!
Backing out Brendan's previous checkin for bug #65553 (jsapi.c, jsdbgapi.c, jsemit.c, jsinterp.c, jsinterp.h, jsobj.c, and jsscript.c), so we can get smoke tests going.
r=attinasi@netscape.com (sheriff)
especially to jband for his great stress-test setup and particularly helpful
(in terms of reproducing bugs in draft patches) MP and laptop machines.
- Radical(*) object (scope) locking optimization: don't lock if a scope is
accessed on the context that exclusively owns it (initially, the context
on which the scope was created). Once a scope becomes shared among more
than one owner-context, give it the usual thin or fat lock, per existing
jslock.c code.
I did this at the memory cost of another word per JSScope, ownercx, which
raised scope size from 12 to 13 words if !DEBUG. I also added a linked
list head pointer, rt->scopeSharingTodo, and a scopeSharingDone condition
variable to JSRuntime, and a scopeToShare pointer to JSContext that's
necessary for deadlock avoidance.
The rt->scopeSharingTodo list links JSScopes through the scope->u.link
union arm, which overlays the pre-existing scope->count (now u.count)
member. This list holds scopes still exclusively owned by a context, but
wanted by js_LockScope calls active on other threads. Those calls wait
on the rt->scopeSharingDone condition, which is notified every time an
owner-context ends the request running on it, in which code active on
that context may be using scope freely until end of request.
The code that waits on rt->scopeSharingDone must first suspend any and
all requests active on the calling context, and resume those contexts
after the wait is notified. This means a GC could happen while the
thread locking a scope owned by another thread's context blocks; all
calls to JS_LOCK_OBJ must therefore first home fp->sp above any live
operands, e.g. The interpreter takes care to do that already.
To avoid AB-BA deadlocks, if a js_LockScope attempt on one context finds
that the owner-context of the scope is already waiting on a scope owned
by the current context (or indirectly depending on such a scope lock),
the attempt converts the scope from lock-free exclusive ownership to
shared ownership (thin or fat lock).
- Fix js_SetupLocks and the js_LockGlobal/js_UnlockGlobal code to avoid
divmod instruction costs, strength-reducing to bit-mask instructions.
- The radical lock-free scope change required care in handling the 0=>1
and 1=>0 transitions of cx->requestDepth, which was till now thread-local
because part of the JSContext not manipulated by other threads. It's
still updated only by cx's thread, but it is read by other threads in
the course of attempting to claim exclusive ownership of a scope for more
lock-free JS object operations.
- The JS_SuspendRequest and JS_ResumeRequest APIs have changed incompatibly
to require their caller to save and restore the requestCount found when
JS_SuspendRequest is called. This is necessary to avoid deadlock; sorry
for the incompatible change.
- Fixed various nits in jslock.[ch], including using Init/Finish rather
than New/Destroy for the methods that take a JSThinLock and initialize
and finish/free its members. Another example: JS_ATOMIC_ADDREF is now
JS_ATOMIC_INCREMENT and JS_ATOMIC_DECREMENT, so the two cases can be
mapped to PR_AtomicIncrement and PR_AtomicDecrement. This entailed
changing jsrefcount from jsword to int32 (PRInt32).
- No need to use JS_ATOMIC_INCREMENT on JSScopeProperty.nrefs, as it is
always and everywhere protected by the property's JSScope.lock.
- Cleaned up gratuitous casts in jscntxt.c by using &cx->links, etc.
- The lock used for mutual exclusion around both request begin and end vs.
GC synchronization is rt->gcLock, and this lock now also protects all
scope->ownercx pointer changes from non-null (exclusive) to null (shared),
the rt->scopeSharingTodo/scope->u.link list operations, and of course the
rt->scopeSharingDone condition.
But this means that js_GC cannot hold rt->gcLock across the bulk of its
body, in particular the mark phase, during which JS_GetPrivate calls,
e.g., may need to "promote" scope locks from lock-free to thin or fat,
because doing so would double-trip. There never was any good reason to
hold rt->gcLock so long, of course -- locks are for mutual exclusion, not
for waiting or notifying a thread -- those operations require a condition,
rt->gcDone, which we already use along with rt->gcLevel to keep racing GC
attempts at bay.
So now that rt->gcLock does not protect the mark phase, the enumeration
of rt->gcRootsHash can race badly with JS_RemoveRootRT, an API that may
legitimately be called outside of a request, without even a context. It
turns out that people may be cheating on the request model even with
JS_AddRoot, JS_AddNamedRoot, and JS_RemoveRoot calls, so we must make
all of those interlock with the GC using gcLevel and gcDone, unless they
are called on the gcThread.
Also, since bug 49816 was fixed, there has been no need for a separate
finalize phase, or for rt->gcFinalVec. Finalizers can no longer allocate
newborn GC-things that might be swept (because unmarked), or double-trip
on rt->gcLock (which is no longer held). So js_GC finalizes as it sweeps,
just as it did in days of old.
- I added comments to jslock.h making it plain that callers of JS_LOCK_OBJ
and JS_UNLOCK_OBJ must either be implementations of js_ObjectOps hooks,
or code reachable only from those hooks; or else must be predicated on
OBJ_IS_NATIVE tests. It turns out jsinterp.c's CACHED_GET and CACHED_SET
macros neglected to do such tests, limiting the ability of JS embeddings
to implement JSObjectOps with their own non-JSScope JSObjectMap subclass.
Fixed, small performance hit that the lock-free optimization should more
than make up for.
- jslock.c now gives a #error if you try to compile it on a platform that
lacks a compare-and-swap instruction. The #error says to use NSPR locks.
Before this change, some platforms would emulate compare-and-swap using
a global PRLock, which is always worse in runtime than using per-scope
PRLocks.
- All jsvals for which JSVAL_IS_GCTHING evaluates to true must contain tagged
pointers into the GC heap -- therefore jsapi.c's JS_DefineConstDoubles cannot
"cheat" by tagging addresses of static jsdoubles to avoid js_NewNumberValue.
- Finalization is now interleaved with the Sweep phase, to avoid allocating
memory for finalization records while sweeping. Instead, the JSRuntime holds a
preallocated JSGCThing vector (gcFinalVec) that the Sweep phase fills and
flushes via gc_finalize_phase, repeatedly.
This means that finalizers cannot allocate a new GC thing, an incompatible but
plausible change. js_AllocGCThing asserts and then checks whether it is called
while rt->gcLevel is non-zero, and fails the allocation attempt if so. But this
fixes bug 38942, where the old sweep-then-finalize with a sweep => malloc
dependency could lead to memory exhaustion.
- Instead of scanning whole stackPool arenas, which led to UMRs (bug 27924) and
sometimes to gross over-scanning that depended on the GC bounds-checking all
thing pointers against its heap, we scan exactly those stack slots in use:
- arguments reachable from fp->argv;
- variables reachable from fp->vars;
- operands now reachable from fp->spbase, bounded above by the lesser of
fp->sp or fp->spbase + fp->script->depth for an interpreted frame; if the
latter, fp->sp has advanced logically above the operand budget, in order to
call a native method, and all unused slots from fp->sp up to depth slots
above fp->spbase must be set to JSVAL_VOID;
- stack segments pushed when calling native methods, prefixed by JSStackHeader
structs and linked from cx->stackSegments through each header.
The stack segment headers help the GC avoid scanning unused portions of the
stack: the generating pc slots running depth slots below fp->spbase, and slots
at the end of an arena that aren't sufficient to satisfy a contiguous allocation
for more args, vars, or operands.
- Exact GC means the stack pointer must remain above live operands until the
interpreter is done with them, so jsinterp.c got heavily whacked. Instead of
POPs of various kinds followed by a PUSH for binary operators (e.g.), we use
FETCH and STORE macros that index by -1 and -2 from sp, and minimize adjustments
to sp. When sp is homed to fp->sp, this allows js_DecompileValueGenerator to
find the value reliably, and if possible its generating pc.
- Finally, the O(n**2) growth rate of gc_find_flags has been fixed, using the
scheme sketched in bug 49816 and documented in a new major comment in jsgc.c.
Briefly, by allocating flags and things from one arena, we can align things on
1024-byte "thing page" boundaries, and use JSGCPageInfo headers in each page to
find a given thing's flags in O(1) time.
/be
Bug #34187, adding 'eval' as property of global object.
Bug #31864, decompiler failure when attempting to invoke a non-function
where that object is accessed via an incoming argument of the current
function.
caps/idl/nsICertificatePrincipal.idl
caps/idl/nsIPrincipal.idl
caps/src/nsBasePrincipal.cpp
Implement the ability to manipulate multiple capabilties simultaneously.
r=mstoltz@netscape.com
Files:
caps/src/nsCodebasePrincipal.cpp
Codebase equality should be based upon origin, not full path.
r=mstoltz@netscape.com
Files:
caps/src/nsScriptSecurityManager.cpp
Change URI checking to deny based upon scheme rather than allow based upon
scheme for greater flexibility.
r=mstoltz@netscape.com
Files:
dom/public/nsDOMPropEnums.h
dom/public/nsDOMPropNames.h
dom/src/base/nsGlobalWindow.cpp
modules/libpref/src/init/all.js
Fix bug 20469 Seeing JS functions and global variables from arbitrary host
r=vidur@netscape.com
Files:
dom/src/base/nsJSUtils.cpp
dom/src/base/nsJSUtils.h
dom/src/base/nsJSEnvironment.cpp
dom/tools/JSStubGen.cpp
layout/base/src/nsDocument.cpp
layout/html/content/src/nsGenericHTMLElement.cpp
Improve performance by removing NS_WITH_SERVICE call for every DOM access.
Propagate XPCOM failure codes out properly.
r=vidur@netscape.com
Files:
layout/html/document/src/nsFrameFrame.cpp
Fix 27387 Circumventing Same Origin security policy using setAttribute
r=vidur@netscape.com
Added ECMA3 compliant getter/setter syntax.
Fixed bugs
- #28686, mishandling of \$ in replace()
- #27902, eval not detected as heavyweight indicator for non ECMA
context version.
was causing defered calls to js_FreeSlot to do wild pointer writes into slots that
were no longer owned by the object. Also this improves the fix to 14462 (see note
in 28982 from brendan). r=brendan@mozilla.orga=jar@netscape.com
Bug #14462, lot's of discussin there about these changes, but here's
Brendan's description :
In order, changes in the patch are:
- Rename JSSLOT_ITR_STATE to be JSSLOT_ITER_STATE (avoid cybercrud abbreviation
as cbrcrd, no more six-char id limits!).
- Property cache tests must occur with the object's scope-lock held, to close a
race with delete (js_DestroyProperty, always called with the property's scope
locked). Once the cache has been hit, and before the lock is released, the
property's refcount must be bumped. This requires re-acquisition of the lock
and js_DropScopeProperty afterward.
- Reworked js_FindProperty to use a do-while loop, as cx->fp->scopeChain must be
non-null. This avoids a gratuitous lastobj init done to "Suppress gcc warning"
in the old revision.
- Akin to the property cache hit cases in jsinterp.c and jsobj.c's
js_FindProperty, code to hold and drop the scope-property by its refcount that
was #ifdef JS_THREADSAFE must be unconditional, now that user-defined getters
and setters may delete the property id they're getting or setting.
- Fixed overlong continuation line in jsobj.h.
/be
Courtesy Bill Gibbons <bill@gibbons.org>
His comments:
Here are the changes to JSRef to make it compile either as C or C++. Mostly the changes are to add missing casts (since C++ doesn't have implict conversion from void* to other pointer types nor implicit casts from ints to enumerations) plus a few random things like the use of "private" as a variable name.
There are a few other minor bug fixes; in particular:
* A long statement with and'ed conditions is reformatted to make it easier to remove other builtin objects (e.g. Date).
* A #if was added to jsscript.c for the JS_HAS_SCRIPT_OBJECT off case.
* In jsmath a #ifdef was changed to #if.
My notes also mention...
* jsobj.c should include jsopcode.h
* jsfun.c - doesn't link if JS_HAS_ARGS_OBJECT is off
* jsarray.c - a reference to js_ValueToSource should be conditional on JS_HAS_TOSOURCE
r=mccabe