2013-01-15 04:26:47 +04:00
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
2012-05-21 15:12:37 +04:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
2012-07-27 18:03:27 +04:00
# include "nsError.h"
1998-07-16 05:16:47 +04:00
# include "nsJSEnvironment.h"
# include "nsIScriptGlobalObject.h"
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
# include "nsIScriptObjectPrincipal.h"
2005-06-08 06:13:10 +04:00
# include "nsIDOMChromeWindow.h"
2005-11-29 02:56:44 +03:00
# include "nsPIDOMWindow.h"
1998-11-21 03:12:33 +03:00
# include "nsIScriptSecurityManager.h"
1998-12-23 01:03:20 +03:00
# include "nsDOMCID.h"
# include "nsIServiceManager.h"
1999-04-24 06:37:41 +04:00
# include "nsIXPConnect.h"
1999-09-05 04:43:39 +04:00
# include "nsIJSRuntimeService.h"
1999-08-30 01:58:42 +04:00
# include "nsCOMPtr.h"
2006-06-13 07:07:47 +04:00
# include "nsISupportsPrimitives.h"
2001-09-29 12:28:41 +04:00
# include "nsReadableUtils.h"
1999-12-18 23:29:29 +03:00
# include "nsJSUtils.h"
2000-04-24 08:41:27 +04:00
# include "nsIDocShell.h"
2000-12-07 05:08:21 +03:00
# include "nsIDocShellTreeItem.h"
2004-08-01 03:15:21 +04:00
# include "nsPresContext.h"
2004-01-04 03:29:27 +03:00
# include "nsIConsoleService.h"
2000-12-07 05:08:21 +03:00
# include "nsIScriptError.h"
2000-06-24 20:18:41 +04:00
# include "nsIInterfaceRequestor.h"
2001-09-06 01:28:38 +04:00
# include "nsIInterfaceRequestorUtils.h"
2000-06-24 20:18:41 +04:00
# include "nsIPrompt.h"
2000-06-20 07:45:21 +04:00
# include "nsIObserverService.h"
2001-11-27 12:46:38 +03:00
# include "nsITimer.h"
2002-07-25 22:31:10 +04:00
# include "nsIAtom.h"
2004-04-30 03:34:19 +04:00
# include "nsContentUtils.h"
2013-05-22 20:05:26 +04:00
# include "nsCxPusher.h"
2014-03-18 08:48:21 +04:00
# include "mozilla/EventDispatcher.h"
2006-08-25 01:49:14 +04:00
# include "nsIContent.h"
2007-01-05 04:44:42 +03:00
# include "nsCycleCollector.h"
2007-07-10 02:07:07 +04:00
# include "nsNetUtil.h"
2009-01-12 19:05:10 +03:00
# include "nsXPCOMCIDInternal.h"
# include "nsIXULRuntime.h"
2013-08-15 22:17:48 +04:00
# include "nsTextFormatter.h"
1998-07-16 05:16:47 +04:00
2011-02-16 23:47:08 +03:00
# include "xpcpublic.h"
2003-06-25 01:09:57 +04:00
2013-08-27 06:05:20 +04:00
# include "js/OldDebugAPI.h"
2011-05-03 02:47:10 +04:00
# include "jswrapper.h"
2006-06-13 07:07:47 +04:00
# include "nsIArray.h"
# include "nsIObjectInputStream.h"
# include "nsIObjectOutputStream.h"
2012-12-05 13:19:33 +04:00
# include "prmem.h"
2010-10-11 02:38:10 +04:00
# include "WrapperFactory.h"
2006-07-12 04:26:56 +04:00
# include "nsGlobalWindow.h"
2011-10-03 23:11:31 +04:00
# include "nsScriptNameSpaceManager.h"
2012-04-24 14:58:07 +04:00
# include "StructuredCloneTags.h"
2014-02-23 09:01:12 +04:00
# include "mozilla/AutoRestore.h"
# include "mozilla/dom/ErrorEvent.h"
2012-04-24 14:58:07 +04:00
# include "mozilla/dom/ImageData.h"
2012-10-22 21:08:52 +04:00
# include "mozilla/dom/ImageDataBinding.h"
2013-09-06 21:50:24 +04:00
# include "nsAXPCNativeCallContext.h"
2013-11-21 02:35:16 +04:00
# include "mozilla/CycleCollectedJSRuntime.h"
2005-06-08 06:13:10 +04:00
2011-12-19 21:48:12 +04:00
# include "nsJSPrincipals.h"
2010-10-22 09:15:21 +04:00
# ifdef XP_MACOSX
// AssertMacros.h defines 'check' and conflicts with AccessCheck.h
# undef check
# endif
# include "AccessCheck.h"
2006-06-23 01:30:49 +04:00
# ifdef MOZ_JSDEBUGGER
# include "jsdIDebuggerService.h"
# endif
2001-05-05 14:18:53 +04:00
# ifdef MOZ_LOGGING
1999-12-03 06:40:30 +03:00
// Force PR_LOGGING so we can get JS strict warnings even in release builds
# define FORCE_PR_LOG 1
2001-05-05 14:18:53 +04:00
# endif
1999-12-03 06:40:30 +03:00
# include "prlog.h"
2000-05-15 08:21:04 +04:00
# include "prthread.h"
1999-12-03 06:40:30 +03:00
2011-05-25 10:31:59 +04:00
# include "mozilla/Preferences.h"
2012-01-21 00:02:18 +04:00
# include "mozilla/Telemetry.h"
2012-05-03 08:35:38 +04:00
# include "mozilla/dom/BindingUtils.h"
2012-06-15 06:31:55 +04:00
# include "mozilla/Attributes.h"
2013-11-19 01:49:53 +04:00
# include "mozilla/dom/asmjscache/AsmJSCache.h"
2012-06-13 19:14:15 +04:00
# include "mozilla/dom/CanvasRenderingContext2DBinding.h"
2013-09-05 01:06:54 +04:00
# include "mozilla/CycleCollectedJSRuntime.h"
2013-09-25 15:21:20 +04:00
# include "mozilla/ContentEvents.h"
2010-05-20 03:22:19 +04:00
2013-09-05 01:06:54 +04:00
# include "nsCycleCollectionNoteRootCallback.h"
2013-03-18 18:25:50 +04:00
# include "GeckoProfiler.h"
2011-12-03 02:05:33 +04:00
2011-04-29 02:48:52 +04:00
using namespace mozilla ;
2012-04-24 14:58:07 +04:00
using namespace mozilla : : dom ;
2011-04-29 02:48:52 +04:00
1998-07-16 05:16:47 +04:00
const size_t gStackSize = 8192 ;
2000-10-29 02:17:53 +04:00
# ifdef PR_LOGGING
2003-06-25 03:06:12 +04:00
static PRLogModuleInfo * gJSDiagnostics ;
2000-10-29 02:17:53 +04:00
# endif
2003-06-25 01:09:57 +04:00
// Thank you Microsoft!
# ifdef CompareString
# undef CompareString
# endif
2001-11-27 12:46:38 +03:00
2011-12-27 15:59:29 +04:00
# define NS_SHRINK_GC_BUFFERS_DELAY 4000 // ms
2007-01-11 03:02:58 +03:00
// The amount of time we wait from the first request to GC to actually
// doing the first GC.
# define NS_FIRST_GC_DELAY 10000 // ms
2001-11-27 12:46:38 +03:00
2012-05-09 22:53:23 +04:00
# define NS_FULL_GC_DELAY 60000 // ms
2012-02-18 02:35:20 +04:00
// Maximum amount of time that should elapse between incremental GC slices
# define NS_INTERSLICE_GC_DELAY 100 // ms
2012-08-01 05:39:39 +04:00
// If we haven't painted in 100ms, we allow for a longer GC budget
# define NS_INTERSLICE_GC_BUDGET 40 // ms
2011-02-17 02:47:12 +03:00
// The amount of time we wait between a request to CC (after GC ran)
// and doing the actual CC.
2012-02-19 22:36:06 +04:00
# define NS_CC_DELAY 6000 // ms
2006-06-13 07:07:47 +04:00
2012-02-19 22:36:06 +04:00
# define NS_CC_SKIPPABLE_DELAY 400 // ms
2012-01-31 00:06:18 +04:00
2013-12-21 18:35:08 +04:00
// Maximum amount of time that should elapse between incremental CC slices
static const int64_t kICCIntersliceDelay = 32 ; // ms
2013-12-22 18:58:19 +04:00
// Time budget for an incremental CC slice
static const int64_t kICCSliceBudget = 10 ; // ms
// Maximum total duration for an ICC
static const uint32_t kMaxICCDuration = 2000 ; // ms
2012-07-15 14:30:39 +04:00
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
// objects in the purple buffer.
2012-03-06 01:48:33 +04:00
# define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
2012-07-15 14:30:39 +04:00
# define NS_CC_FORCED_PURPLE_LIMIT 10
2012-03-06 01:48:33 +04:00
2012-03-09 03:37:13 +04:00
// Don't allow an incremental GC to lock out the CC for too long.
2012-07-16 01:37:09 +04:00
# define NS_MAX_CC_LOCKEDOUT_TIME (15 * PR_USEC_PER_SEC) // 15 seconds
2012-03-09 03:37:13 +04:00
2012-03-06 01:48:33 +04:00
// Trigger a CC if the purple buffer exceeds this size when we check it.
2012-07-15 14:30:39 +04:00
# define NS_CC_PURPLE_LIMIT 200
2012-01-31 00:06:18 +04:00
2011-02-17 02:47:12 +03:00
# define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
2007-10-23 01:42:25 +04:00
2013-01-31 21:23:50 +04:00
// Large value used to specify that a script should run essentially forever
# define NS_UNLIMITED_SCRIPT_RUNTIME (0x40000000LL << 32)
2013-07-27 14:48:45 +04:00
# define NS_MAJOR_FORGET_SKIPPABLE_CALLS 2
2013-08-20 03:24:29 +04:00
// if you add statics here, add them to the list in StartupJSEnvironment
2004-06-09 22:36:25 +04:00
2003-06-25 03:06:12 +04:00
static nsITimer * sGCTimer ;
2011-12-27 15:59:29 +04:00
static nsITimer * sShrinkGCBuffersTimer ;
2011-02-17 02:47:12 +03:00
static nsITimer * sCCTimer ;
2013-12-21 18:35:08 +04:00
static nsITimer * sICCTimer ;
2012-05-09 22:53:23 +04:00
static nsITimer * sFullGCTimer ;
2012-06-11 08:27:59 +04:00
static nsITimer * sInterSliceGCTimer ;
2001-11-27 12:46:38 +03:00
2013-12-31 21:20:21 +04:00
static TimeStamp sLastCCEndTime ;
2012-01-21 00:02:18 +04:00
2012-02-18 02:35:20 +04:00
static bool sCCLockedOut ;
2012-03-09 03:37:13 +04:00
static PRTime sCCLockedOutTime ;
2012-02-18 02:35:20 +04:00
2013-01-28 00:35:12 +04:00
static JS : : GCSliceCallback sPrevGCSliceCallback ;
2011-02-23 11:08:36 +03:00
2013-01-31 02:46:37 +04:00
static bool sHasRunGC ;
2007-01-11 03:02:58 +03:00
// The number of currently pending document loads. This count isn't
// guaranteed to always reflect reality and can't easily as we don't
// have an easy place to know when a load ends or is interrupted in
// all cases. This counter also gets reset if we end up GC'ing while
// we're waiting for a slow page to load. IOW, this count may be 0
// even when there are pending loads.
2012-08-22 19:56:38 +04:00
static uint32_t sPendingLoadCount ;
2011-09-29 10:19:26 +04:00
static bool sLoadingInProgress ;
2007-01-11 03:02:58 +03:00
2012-08-22 19:56:38 +04:00
static uint32_t sCCollectedWaitingForGC ;
2013-03-07 22:53:19 +04:00
static uint32_t sLikelyShortLivingObjectsNeedingGC ;
2011-09-29 10:19:26 +04:00
static bool sPostGCEventsToConsole ;
2012-07-13 23:13:52 +04:00
static bool sPostGCEventsToObserver ;
2014-03-05 04:21:48 +04:00
static int32_t sCCTimerFireCount = 0 ;
2012-09-28 10:57:33 +04:00
static uint32_t sMinForgetSkippableTime = UINT32_MAX ;
2012-08-22 19:56:38 +04:00
static uint32_t sMaxForgetSkippableTime = 0 ;
static uint32_t sTotalForgetSkippableTime = 0 ;
static uint32_t sRemovedPurples = 0 ;
static uint32_t sForgetSkippableBeforeCC = 0 ;
static uint32_t sPreviousSuspectedCount = 0 ;
2012-09-28 10:57:33 +04:00
static uint32_t sCleanupsSinceLastGC = UINT32_MAX ;
2012-02-27 18:49:59 +04:00
static bool sNeedsFullCC = false ;
2013-08-22 01:02:12 +04:00
static bool sNeedsGCAfterCC = false ;
2013-12-21 18:35:08 +04:00
static bool sIncrementalCC = false ;
2007-01-11 03:02:58 +03:00
2012-11-05 02:18:44 +04:00
static nsScriptNameSpaceManager * gNameSpaceManager ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2003-06-25 03:06:12 +04:00
static nsIJSRuntimeService * sRuntimeService ;
2002-05-03 07:02:07 +04:00
static const char kJSRuntimeServiceContractID [ ] =
" @mozilla.org/js/xpc/RuntimeService;1 " ;
2011-11-10 01:32:17 +04:00
static PRTime sFirstCollectionTime ;
2002-05-03 07:02:07 +04:00
2013-08-20 03:24:29 +04:00
static JSRuntime * sRuntime ;
2011-09-29 10:19:26 +04:00
static bool sIsInitialized ;
static bool sDidShutdown ;
2013-01-22 23:17:48 +04:00
static bool sShuttingDown ;
2012-08-22 19:56:38 +04:00
static int32_t sContextCount ;
2002-05-03 07:02:07 +04:00
2003-06-25 03:06:12 +04:00
static nsIScriptSecurityManager * sSecurityManager ;
2002-05-03 07:02:07 +04:00
2013-01-22 23:17:48 +04:00
// nsJSEnvironmentObserver observes the memory-pressure notifications
2011-07-07 22:27:07 +04:00
// and forces a garbage collection and cycle collection when it happens, if
// the appropriate pref is set.
2011-09-29 10:19:26 +04:00
static bool sGCOnMemoryPressure ;
2007-10-23 01:42:25 +04:00
2012-08-22 22:28:34 +04:00
static PRTime
GetCollectionTimeDelta ( )
{
PRTime now = PR_Now ( ) ;
if ( sFirstCollectionTime ) {
return now - sFirstCollectionTime ;
}
sFirstCollectionTime = now ;
return 0 ;
}
2013-01-22 23:17:48 +04:00
static void
KillTimers ( )
{
nsJSContext : : KillGCTimer ( ) ;
nsJSContext : : KillShrinkGCBuffersTimer ( ) ;
nsJSContext : : KillCCTimer ( ) ;
2013-12-21 18:35:08 +04:00
nsJSContext : : KillICCTimer ( ) ;
2013-01-22 23:17:48 +04:00
nsJSContext : : KillFullGCTimer ( ) ;
nsJSContext : : KillInterSliceGCTimer ( ) ;
}
2014-02-03 19:31:11 +04:00
// If we collected a substantial amount of cycles, poke the GC since more objects
// might be unreachable now.
static bool
NeedsGCAfterCC ( )
{
return sCCollectedWaitingForGC > 250 | |
sLikelyShortLivingObjectsNeedingGC > 2500 | |
sNeedsGCAfterCC ;
}
2013-01-22 23:17:48 +04:00
class nsJSEnvironmentObserver MOZ_FINAL : public nsIObserver
2007-10-23 01:42:25 +04:00
{
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
} ;
2013-01-22 23:17:48 +04:00
NS_IMPL_ISUPPORTS1 ( nsJSEnvironmentObserver , nsIObserver )
2007-10-23 01:42:25 +04:00
NS_IMETHODIMP
2013-01-22 23:17:48 +04:00
nsJSEnvironmentObserver : : Observe ( nsISupports * aSubject , const char * aTopic ,
2014-01-04 19:02:17 +04:00
const char16_t * aData )
2007-11-07 00:47:35 +03:00
{
2013-01-22 23:17:48 +04:00
if ( sGCOnMemoryPressure & & ! nsCRT : : strcmp ( aTopic , " memory-pressure " ) ) {
2013-04-26 05:36:53 +04:00
if ( StringBeginsWith ( nsDependentString ( aData ) ,
NS_LITERAL_STRING ( " low-memory-ongoing " ) ) ) {
// Don't GC/CC if we are in an ongoing low-memory state since its very
// slow and it likely won't help us anyway.
return NS_OK ;
}
2013-01-28 00:35:12 +04:00
nsJSContext : : GarbageCollectNow ( JS : : gcreason : : MEM_PRESSURE ,
2012-07-01 01:16:32 +04:00
nsJSContext : : NonIncrementalGC ,
nsJSContext : : NonCompartmentGC ,
nsJSContext : : ShrinkingGC ) ;
2011-07-07 22:27:07 +04:00
nsJSContext : : CycleCollectNow ( ) ;
2014-02-03 19:31:11 +04:00
if ( NeedsGCAfterCC ( ) ) {
nsJSContext : : GarbageCollectNow ( JS : : gcreason : : MEM_PRESSURE ,
nsJSContext : : NonIncrementalGC ,
nsJSContext : : NonCompartmentGC ,
nsJSContext : : ShrinkingGC ) ;
}
2013-01-22 23:17:48 +04:00
} else if ( ! nsCRT : : strcmp ( aTopic , " quit-application " ) ) {
sShuttingDown = true ;
KillTimers ( ) ;
2011-07-07 22:27:07 +04:00
}
2013-01-22 23:17:48 +04:00
2007-11-07 00:47:35 +03:00
return NS_OK ;
}
2006-06-13 07:07:47 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * AutoFree * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class AutoFree {
public :
AutoFree ( void * aPtr ) : mPtr ( aPtr ) {
}
~ AutoFree ( ) {
if ( mPtr )
nsMemory : : Free ( mPtr ) ;
}
void Invalidate ( ) {
mPtr = 0 ;
}
private :
void * mPtr ;
} ;
// A utility function for script languages to call. Although it looks small,
// the use of nsIDocShell and nsPresContext triggers a huge number of
// dependencies that most languages would not otherwise need.
// XXXmarkh - This function is mis-placed!
2011-09-29 10:19:26 +04:00
bool
2006-06-13 07:07:47 +04:00
NS_HandleScriptError ( nsIScriptGlobalObject * aScriptGlobal ,
2014-02-23 09:01:12 +04:00
const ErrorEventInit & aErrorEventInit ,
2006-06-13 07:07:47 +04:00
nsEventStatus * aStatus )
{
2011-09-29 10:19:26 +04:00
bool called = false ;
2006-06-13 07:07:47 +04:00
nsCOMPtr < nsPIDOMWindow > win ( do_QueryInterface ( aScriptGlobal ) ) ;
2012-07-30 18:20:58 +04:00
nsIDocShell * docShell = win ? win - > GetDocShell ( ) : nullptr ;
2006-06-13 07:07:47 +04:00
if ( docShell ) {
2010-03-25 16:17:11 +03:00
nsRefPtr < nsPresContext > presContext ;
2006-06-13 07:07:47 +04:00
docShell - > GetPresContext ( getter_AddRefs ( presContext ) ) ;
2012-08-22 19:56:38 +04:00
static int32_t errorDepth ; // Recursion prevention
2006-06-13 07:07:47 +04:00
+ + errorDepth ;
2008-07-27 03:17:12 +04:00
2014-02-23 09:01:12 +04:00
if ( errorDepth < 2 ) {
2006-06-13 07:07:47 +04:00
// Dispatch() must be synchronous for the recursion block
// (errorDepth) to work.
2014-02-23 09:01:12 +04:00
nsRefPtr < ErrorEvent > event =
ErrorEvent : : Constructor ( static_cast < nsGlobalWindow * > ( win . get ( ) ) ,
NS_LITERAL_STRING ( " error " ) ,
aErrorEventInit ) ;
event - > SetTrusted ( true ) ;
2014-03-18 08:48:21 +04:00
EventDispatcher : : DispatchDOMEvent ( win , nullptr , event , presContext ,
aStatus ) ;
2011-10-17 18:59:28 +04:00
called = true ;
2006-06-13 07:07:47 +04:00
}
- - errorDepth ;
}
return called ;
}
2013-08-29 08:30:06 +04:00
namespace mozilla {
namespace dom {
AsyncErrorReporter : : AsyncErrorReporter ( JSRuntime * aRuntime ,
JSErrorReport * aErrorReport ,
const char * aFallbackMessage ,
2013-10-31 03:17:36 +04:00
bool aIsChromeError ,
2013-08-29 08:30:06 +04:00
nsPIDOMWindow * aWindow )
2014-01-04 19:02:17 +04:00
: mSourceLine ( static_cast < const char16_t * > ( aErrorReport - > uclinebuf ) )
2013-08-29 08:30:06 +04:00
, mLineNumber ( aErrorReport - > lineno )
2014-03-20 19:46:28 +04:00
, mColumn ( aErrorReport - > column )
2013-08-29 08:30:06 +04:00
, mFlags ( aErrorReport - > flags )
{
if ( ! aErrorReport - > filename ) {
mFileName . SetIsVoid ( true ) ;
} else {
mFileName . AssignWithConversion ( aErrorReport - > filename ) ;
}
2014-01-04 19:02:17 +04:00
const char16_t * m = static_cast < const char16_t * > ( aErrorReport - > ucmessage ) ;
2013-08-29 08:30:06 +04:00
if ( m ) {
2014-01-04 19:02:17 +04:00
const char16_t * n = static_cast < const char16_t * >
2013-08-29 08:30:06 +04:00
( js : : GetErrorTypeName ( aRuntime , aErrorReport - > exnType ) ) ;
if ( n ) {
mErrorMsg . Assign ( n ) ;
mErrorMsg . AppendLiteral ( " : " ) ;
}
mErrorMsg . Append ( m ) ;
}
if ( mErrorMsg . IsEmpty ( ) & & aFallbackMessage ) {
mErrorMsg . AssignWithConversion ( aFallbackMessage ) ;
}
2013-10-31 03:17:36 +04:00
mCategory = aIsChromeError ? NS_LITERAL_CSTRING ( " chrome javascript " ) :
NS_LITERAL_CSTRING ( " content javascript " ) ;
2013-08-29 08:30:06 +04:00
mInnerWindowID = 0 ;
if ( aWindow & & aWindow - > IsOuterWindow ( ) ) {
aWindow = aWindow - > GetCurrentInnerWindow ( ) ;
}
if ( aWindow ) {
mInnerWindowID = aWindow - > WindowID ( ) ;
}
}
void
AsyncErrorReporter : : ReportError ( )
{
nsCOMPtr < nsIScriptError > errorObject =
do_CreateInstance ( " @mozilla.org/scripterror;1 " ) ;
if ( ! errorObject ) {
return ;
}
nsresult rv = errorObject - > InitWithWindowID ( mErrorMsg , mFileName ,
mSourceLine , mLineNumber ,
mColumn , mFlags , mCategory ,
mInnerWindowID ) ;
if ( NS_FAILED ( rv ) ) {
return ;
}
nsCOMPtr < nsIConsoleService > consoleService =
do_GetService ( NS_CONSOLESERVICE_CONTRACTID ) ;
if ( ! consoleService ) {
return ;
}
consoleService - > LogMessage ( errorObject ) ;
return ;
}
} // namespace dom
} // namespace mozilla
class ScriptErrorEvent : public AsyncErrorReporter
2009-12-18 22:27:57 +03:00
{
public :
ScriptErrorEvent ( nsIScriptGlobalObject * aScriptGlobal ,
2013-08-29 08:30:06 +04:00
JSRuntime * aRuntime ,
JSErrorReport * aErrorReport ,
const char * aFallbackMessage ,
2011-12-19 21:48:12 +04:00
nsIPrincipal * aScriptOriginPrincipal ,
2013-08-29 08:30:06 +04:00
nsIPrincipal * aGlobalPrincipal ,
nsPIDOMWindow * aWindow ,
2014-01-03 05:04:15 +04:00
JS : : Handle < JS : : Value > aError ,
2013-08-29 08:30:06 +04:00
bool aDispatchEvent )
// Pass an empty category, then compute ours
: AsyncErrorReporter ( aRuntime , aErrorReport , aFallbackMessage ,
2013-10-31 03:17:36 +04:00
nsContentUtils : : IsSystemPrincipal ( aGlobalPrincipal ) ,
aWindow )
2013-08-29 08:30:06 +04:00
, mScriptGlobal ( aScriptGlobal )
, mOriginPrincipal ( aScriptOriginPrincipal )
, mDispatchEvent ( aDispatchEvent )
2014-01-03 05:04:15 +04:00
, mError ( aRuntime , aError )
2013-08-29 08:30:06 +04:00
{
}
2009-12-18 22:27:57 +03:00
NS_IMETHOD Run ( )
{
nsEventStatus status = nsEventStatus_eIgnore ;
// First, notify the DOM that we have a script error.
if ( mDispatchEvent ) {
nsCOMPtr < nsPIDOMWindow > win ( do_QueryInterface ( mScriptGlobal ) ) ;
2012-07-30 18:20:58 +04:00
nsIDocShell * docShell = win ? win - > GetDocShell ( ) : nullptr ;
2009-12-18 22:27:57 +03:00
if ( docShell & &
! JSREPORT_IS_WARNING ( mFlags ) & &
! sHandlingScriptError ) {
2014-02-23 09:01:12 +04:00
AutoRestore < bool > recursionGuard ( sHandlingScriptError ) ;
sHandlingScriptError = true ;
2009-12-18 22:27:57 +03:00
2010-03-25 16:17:11 +03:00
nsRefPtr < nsPresContext > presContext ;
2009-12-18 22:27:57 +03:00
docShell - > GetPresContext ( getter_AddRefs ( presContext ) ) ;
2014-01-03 05:04:15 +04:00
ThreadsafeAutoJSContext cx ;
RootedDictionary < ErrorEventInit > init ( cx ) ;
2014-02-23 09:01:12 +04:00
init . mCancelable = true ;
init . mFilename = mFileName ;
init . mBubbles = true ;
2009-12-18 22:27:57 +03:00
2014-02-23 09:01:12 +04:00
nsCOMPtr < nsIScriptObjectPrincipal > sop ( do_QueryInterface ( win ) ) ;
NS_ENSURE_STATE ( sop ) ;
nsIPrincipal * p = sop - > GetPrincipal ( ) ;
NS_ENSURE_STATE ( p ) ;
2009-12-18 22:27:57 +03:00
2014-02-23 09:01:12 +04:00
bool sameOrigin = ! mOriginPrincipal ;
2009-12-18 22:27:57 +03:00
2014-02-23 09:01:12 +04:00
if ( p & & ! sameOrigin ) {
if ( NS_FAILED ( p - > Subsumes ( mOriginPrincipal , & sameOrigin ) ) ) {
sameOrigin = false ;
2009-12-18 22:27:57 +03:00
}
2014-02-23 09:01:12 +04:00
}
2009-12-18 22:27:57 +03:00
2014-02-23 09:01:12 +04:00
NS_NAMED_LITERAL_STRING ( xoriginMsg , " Script error. " ) ;
if ( sameOrigin ) {
init . mMessage = mErrorMsg ;
init . mLineno = mLineNumber ;
2014-04-23 15:55:58 +04:00
init . mColno = mColumn ;
2014-01-03 05:04:15 +04:00
init . mError = mError ;
2014-02-23 09:01:12 +04:00
} else {
NS_WARNING ( " Not same origin error! " ) ;
init . mMessage = xoriginMsg ;
init . mLineno = 0 ;
2009-12-18 22:27:57 +03:00
}
2014-02-23 09:01:12 +04:00
nsRefPtr < ErrorEvent > event =
ErrorEvent : : Constructor ( static_cast < nsGlobalWindow * > ( win . get ( ) ) ,
NS_LITERAL_STRING ( " error " ) , init ) ;
event - > SetTrusted ( true ) ;
2014-03-18 08:48:21 +04:00
EventDispatcher : : DispatchDOMEvent ( win , nullptr , event , presContext ,
& status ) ;
2009-12-18 22:27:57 +03:00
}
}
if ( status ! = nsEventStatus_eConsumeNoDefault ) {
2013-08-29 08:30:06 +04:00
AsyncErrorReporter : : ReportError ( ) ;
2009-12-18 22:27:57 +03:00
}
2013-08-29 08:30:06 +04:00
2009-12-18 22:27:57 +03:00
return NS_OK ;
}
2013-08-29 08:30:06 +04:00
private :
2009-12-18 22:27:57 +03:00
nsCOMPtr < nsIScriptGlobalObject > mScriptGlobal ;
2011-12-19 21:48:12 +04:00
nsCOMPtr < nsIPrincipal > mOriginPrincipal ;
2011-09-29 10:19:26 +04:00
bool mDispatchEvent ;
2014-01-03 05:04:15 +04:00
JS : : PersistentRootedValue mError ;
2009-12-18 22:27:57 +03:00
2011-09-29 10:19:26 +04:00
static bool sHandlingScriptError ;
2009-12-18 22:27:57 +03:00
} ;
2011-09-29 10:19:26 +04:00
bool ScriptErrorEvent : : sHandlingScriptError = false ;
2009-12-18 22:27:57 +03:00
2006-06-13 07:07:47 +04:00
// NOTE: This function could be refactored to use the above. The only reason
// it has not been done is that the code below only fills the error event
// after it has a good nsPresContext - whereas using the above function
// would involve always filling it. Is that a concern?
2008-09-07 02:21:43 +04:00
void
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
NS_ScriptErrorReporter ( JSContext * cx ,
const char * message ,
1999-09-09 03:14:30 +04:00
JSErrorReport * report )
1998-08-12 08:56:40 +04:00
{
2009-02-26 04:32:48 +03:00
// We don't want to report exceptions too eagerly, but warnings in the
// absence of werror are swallowed whole, so report those now.
if ( ! JSREPORT_IS_WARNING ( report - > flags ) ) {
2013-07-23 19:32:36 +04:00
nsIXPConnect * xpc = nsContentUtils : : XPConnect ( ) ;
2014-02-25 19:43:14 +04:00
if ( JS : : DescribeScriptedCaller ( cx ) ) {
2013-07-23 19:32:36 +04:00
xpc - > MarkErrorUnreported ( cx ) ;
2012-04-16 23:30:00 +04:00
return ;
2008-10-12 22:32:34 +04:00
}
2009-02-26 04:32:48 +03:00
if ( xpc ) {
2012-07-30 18:20:58 +04:00
nsAXPCNativeCallContext * cc = nullptr ;
2009-02-26 04:32:48 +03:00
xpc - > GetCurrentNativeCallContext ( & cc ) ;
if ( cc ) {
nsAXPCNativeCallContext * prev = cc ;
while ( NS_SUCCEEDED ( prev - > GetPreviousCallContext ( & prev ) ) & & prev ) {
2012-08-22 19:56:38 +04:00
uint16_t lang ;
2009-02-26 04:32:48 +03:00
if ( NS_SUCCEEDED ( prev - > GetLanguage ( & lang ) ) & &
lang = = nsAXPCNativeCallContext : : LANG_JS ) {
2013-07-23 19:32:36 +04:00
xpc - > MarkErrorUnreported ( cx ) ;
2009-02-26 04:32:48 +03:00
return ;
}
2008-10-12 22:32:34 +04:00
}
}
}
}
2004-02-10 01:48:53 +03:00
// XXX this means we are not going to get error reports on non DOM contexts
nsIScriptContext * context = nsJSUtils : : GetDynamicScriptContext ( cx ) ;
2014-01-03 05:04:15 +04:00
JS : : Rooted < JS : : Value > exception ( cx ) ;
: : JS_GetPendingException ( cx , & exception ) ;
2006-03-03 02:09:43 +03:00
// Note: we must do this before running any more code on cx (if cx is the
// dynamic script context).
: : JS_ClearPendingException ( cx ) ;
1999-12-18 23:29:29 +03:00
if ( context ) {
2007-03-02 04:05:46 +03:00
nsIScriptGlobalObject * globalObject = context - > GetGlobalObject ( ) ;
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
2007-03-02 04:05:46 +03:00
if ( globalObject ) {
2001-11-02 07:49:07 +03:00
2010-10-21 04:24:15 +04:00
nsCOMPtr < nsPIDOMWindow > win = do_QueryInterface ( globalObject ) ;
2013-08-29 08:30:06 +04:00
nsCOMPtr < nsIScriptObjectPrincipal > scriptPrincipal =
do_QueryInterface ( globalObject ) ;
NS_ASSERTION ( scriptPrincipal , " Global objects must implement "
" nsIScriptObjectPrincipal " ) ;
2009-12-18 22:27:57 +03:00
nsContentUtils : : AddScriptRunner (
2012-03-09 13:48:50 +04:00
new ScriptErrorEvent ( globalObject ,
2013-08-29 08:30:06 +04:00
JS_GetRuntime ( cx ) ,
report ,
message ,
2012-03-09 13:48:50 +04:00
nsJSPrincipals : : get ( report - > originPrincipals ) ,
2013-08-29 08:30:06 +04:00
scriptPrincipal - > GetPrincipal ( ) ,
win ,
2014-01-03 05:04:15 +04:00
exception ,
2013-08-29 08:30:06 +04:00
/* We do not try to report Out Of Memory via a dom
* event because the dom event handler would
* encounter an OOM exception trying to process the
* event , and then we ' d need to generate a new OOM
* event for that new OOM instance - - this isn ' t
* pretty .
*/
report - > errorNumber ! = JSMSG_OUT_OF_MEMORY ) ) ;
1999-09-09 03:14:30 +04:00
}
}
2013-08-01 04:04:49 +04:00
if ( nsContentUtils : : DOMWindowDumpEnabled ( ) ) {
// Print it to stderr as well, for the benefit of those invoking
// mozilla with -console.
nsAutoCString error ;
error . Assign ( " JavaScript " ) ;
if ( JSREPORT_IS_STRICT ( report - > flags ) )
error . Append ( " strict " ) ;
if ( JSREPORT_IS_WARNING ( report - > flags ) )
error . Append ( " warning: " ) ;
else
error . Append ( " error: " ) ;
error . Append ( report - > filename ) ;
error . Append ( " , line " ) ;
error . AppendInt ( report - > lineno , 10 ) ;
error . Append ( " : " ) ;
if ( report - > ucmessage ) {
2014-01-04 19:02:17 +04:00
AppendUTF16toUTF8 ( reinterpret_cast < const char16_t * > ( report - > ucmessage ) ,
2013-08-01 04:04:49 +04:00
error ) ;
} else {
error . Append ( message ) ;
}
2009-12-18 22:27:57 +03:00
2013-08-01 04:04:49 +04:00
fprintf ( stderr , " %s \n " , error . get ( ) ) ;
fflush ( stderr ) ;
}
2000-04-15 05:56:47 +04:00
1999-12-03 06:40:30 +03:00
# ifdef PR_LOGGING
2007-07-12 04:04:11 +04:00
if ( ! gJSDiagnostics )
gJSDiagnostics = PR_NewLogModule ( " JSDiagnostics " ) ;
if ( gJSDiagnostics ) {
PR_LOG ( gJSDiagnostics ,
JSREPORT_IS_WARNING ( report - > flags ) ? PR_LOG_WARNING : PR_LOG_ERROR ,
( " file %s, line %u: %s \n %s%s " ,
report - > filename , report - > lineno , message ,
report - > linebuf ? report - > linebuf : " " ,
( report - > linebuf & &
report - > linebuf [ strlen ( report - > linebuf ) - 1 ] ! = ' \n ' )
? " \n "
: " " ) ) ;
1999-12-03 06:40:30 +03:00
}
# endif
1998-08-12 08:56:40 +04:00
}
2006-07-12 01:03:52 +04:00
# ifdef DEBUG
// A couple of useful functions to call when you're debugging.
nsGlobalWindow *
2014-01-30 18:31:16 +04:00
JSObject2Win ( JSObject * obj )
2006-07-12 01:03:52 +04:00
{
2014-01-30 18:31:16 +04:00
return xpc : : WindowOrNull ( obj ) ;
2006-07-12 01:03:52 +04:00
}
void
PrintWinURI ( nsGlobalWindow * win )
{
if ( ! win ) {
printf ( " No window passed in. \n " ) ;
return ;
}
2013-04-24 08:22:37 +04:00
nsCOMPtr < nsIDocument > doc = win - > GetExtantDoc ( ) ;
2006-07-12 01:03:52 +04:00
if ( ! doc ) {
printf ( " No document in the window. \n " ) ;
return ;
}
nsIURI * uri = doc - > GetDocumentURI ( ) ;
2006-09-20 04:53:43 +04:00
if ( ! uri ) {
2006-07-12 01:03:52 +04:00
printf ( " Document doesn't have a URI. \n " ) ;
return ;
}
2012-09-02 06:35:17 +04:00
nsAutoCString spec ;
2006-07-12 01:03:52 +04:00
uri - > GetSpec ( spec ) ;
printf ( " %s \n " , spec . get ( ) ) ;
}
void
PrintWinCodebase ( nsGlobalWindow * win )
{
if ( ! win ) {
printf ( " No window passed in. \n " ) ;
return ;
}
nsIPrincipal * prin = win - > GetPrincipal ( ) ;
if ( ! prin ) {
printf ( " Window doesn't have principals. \n " ) ;
return ;
}
nsCOMPtr < nsIURI > uri ;
prin - > GetURI ( getter_AddRefs ( uri ) ) ;
if ( ! uri ) {
printf ( " No URI, maybe the system principal. \n " ) ;
return ;
}
2012-09-02 06:35:17 +04:00
nsAutoCString spec ;
2006-07-12 01:03:52 +04:00
uri - > GetSpec ( spec ) ;
printf ( " %s \n " , spec . get ( ) ) ;
}
2010-02-12 04:04:41 +03:00
void
DumpString ( const nsAString & str )
{
printf ( " %s \n " , NS_ConvertUTF16toUTF8 ( str ) . get ( ) ) ;
}
2006-07-12 01:03:52 +04:00
# endif
2000-09-02 05:58:51 +04:00
# define JS_OPTIONS_DOT_STR "javascript.options."
static const char js_options_dot_str [ ] = JS_OPTIONS_DOT_STR ;
static const char js_strict_option_str [ ] = JS_OPTIONS_DOT_STR " strict " ;
2009-12-23 03:52:13 +03:00
# ifdef DEBUG
static const char js_strict_debug_option_str [ ] = JS_OPTIONS_DOT_STR " strict.debug " ;
# endif
2000-09-02 05:58:51 +04:00
static const char js_werror_option_str [ ] = JS_OPTIONS_DOT_STR " werror " ;
2007-11-11 21:59:28 +03:00
# ifdef JS_GC_ZEAL
2011-07-22 01:31:36 +04:00
static const char js_zeal_option_str [ ] = JS_OPTIONS_DOT_STR " gczeal " ;
static const char js_zeal_frequency_str [ ] = JS_OPTIONS_DOT_STR " gczeal.frequency " ;
2007-11-11 21:59:28 +03:00
# endif
2012-07-13 23:13:52 +04:00
static const char js_memlog_option_str [ ] = JS_OPTIONS_DOT_STR " mem.log " ;
static const char js_memnotify_option_str [ ] = JS_OPTIONS_DOT_STR " mem.notify " ;
2000-09-02 05:58:51 +04:00
2013-12-11 03:10:01 +04:00
void
2000-09-02 05:58:51 +04:00
nsJSContext : : JSOptionChangedCallback ( const char * pref , void * data )
{
2007-07-08 11:08:04 +04:00
nsJSContext * context = reinterpret_cast < nsJSContext * > ( data ) ;
2013-10-28 15:51:05 +04:00
JSContext * cx = context - > mContext ;
2000-09-02 05:58:51 +04:00
2011-05-25 10:31:59 +04:00
sPostGCEventsToConsole = Preferences : : GetBool ( js_memlog_option_str ) ;
2012-07-13 23:13:52 +04:00
sPostGCEventsToObserver = Preferences : : GetBool ( js_memnotify_option_str ) ;
2011-02-17 02:47:12 +03:00
2013-10-28 15:51:05 +04:00
JS : : ContextOptionsRef ( cx ) . setExtraWarnings ( Preferences : : GetBool ( js_strict_option_str ) ) ;
2004-04-30 03:34:19 +04:00
2012-04-12 22:21:12 +04:00
// The vanilla GetGlobalObject returns null if a global isn't set up on
// the context yet. We can sometimes be call midway through context init,
// So ask for the member directly instead.
nsIScriptGlobalObject * global = context - > GetGlobalObjectRef ( ) ;
2008-08-20 19:49:00 +04:00
// XXX should we check for sysprin instead of a chrome window, to make
// XXX components be covered by the chrome pref instead of the content one?
2012-03-28 15:09:33 +04:00
nsCOMPtr < nsIDOMWindow > contentWindow ( do_QueryInterface ( global ) ) ;
2008-07-11 07:05:27 +04:00
nsCOMPtr < nsIDOMChromeWindow > chromeWindow ( do_QueryInterface ( global ) ) ;
2009-01-12 19:05:10 +03:00
2007-07-10 12:05:54 +04:00
# ifdef DEBUG
2011-01-27 13:54:58 +03:00
// In debug builds, warnings are enabled in chrome context if
// javascript.options.strict.debug is true
2013-10-28 15:51:05 +04:00
if ( Preferences : : GetBool ( js_strict_debug_option_str ) & &
( chromeWindow | | ! contentWindow ) ) {
JS : : ContextOptionsRef ( cx ) . setExtraWarnings ( true ) ;
2007-07-10 12:05:54 +04:00
}
# endif
2013-10-28 15:51:05 +04:00
JS : : ContextOptionsRef ( cx ) . setWerror ( Preferences : : GetBool ( js_werror_option_str ) ) ;
2000-09-02 05:58:51 +04:00
2007-11-11 21:59:28 +03:00
# ifdef JS_GC_ZEAL
2012-08-22 19:56:38 +04:00
int32_t zeal = Preferences : : GetInt ( js_zeal_option_str , - 1 ) ;
int32_t frequency = Preferences : : GetInt ( js_zeal_frequency_str , JS_DEFAULT_ZEAL_FREQ ) ;
2007-11-11 21:59:28 +03:00
if ( zeal > = 0 )
2012-08-22 19:56:38 +04:00
: : JS_SetGCZeal ( context - > mContext , ( uint8_t ) zeal , frequency ) ;
2007-11-11 21:59:28 +03:00
# endif
2000-09-02 05:58:51 +04:00
}
2013-08-20 03:24:29 +04:00
nsJSContext : : nsJSContext ( bool aGCOnDestruction ,
2012-11-04 12:05:23 +04:00
nsIScriptGlobalObject * aGlobalObject )
2013-09-05 01:06:56 +04:00
: mWindowProxy ( nullptr )
, mGCOnDestruction ( aGCOnDestruction )
2012-11-04 12:04:04 +04:00
, mGlobalObjectRef ( aGlobalObject )
1998-07-16 05:16:47 +04:00
{
2013-08-20 03:24:29 +04:00
EnsureStatics ( ) ;
2002-05-03 07:02:07 +04:00
+ + sContextCount ;
2013-08-20 03:24:29 +04:00
mContext = : : JS_NewContext ( sRuntime , gStackSize ) ;
1999-12-03 06:40:30 +03:00
if ( mContext ) {
2007-07-08 11:08:04 +04:00
: : JS_SetContextPrivate ( mContext , static_cast < nsIScriptContext * > ( this ) ) ;
1999-12-03 06:40:30 +03:00
2001-09-18 07:32:03 +04:00
// Make sure the new context gets the default context options
2013-10-28 15:51:05 +04:00
JS : : ContextOptionsRef ( mContext ) . setPrivateIsNSISupports ( true )
. setNoDefaultCompartmentObject ( true ) ;
2001-09-18 07:32:03 +04:00
2007-03-24 00:27:14 +03:00
// Watch for the JS boolean options
2011-05-29 03:42:57 +04:00
Preferences : : RegisterCallback ( JSOptionChangedCallback ,
js_options_dot_str , this ) ;
1999-12-03 06:40:30 +03:00
}
2011-10-17 18:59:28 +04:00
mIsInitialized = false ;
2013-01-15 15:46:35 +04:00
mProcessingScriptTag = false ;
2013-09-05 01:58:23 +04:00
HoldJSObjects ( this ) ;
1998-07-16 05:16:47 +04:00
}
nsJSContext : : ~ nsJSContext ( )
{
2012-07-30 18:20:58 +04:00
mGlobalObjectRef = nullptr ;
2009-05-07 22:19:36 +04:00
DestroyJSContext ( ) ;
2007-11-02 01:51:57 +03:00
- - sContextCount ;
if ( ! sContextCount & & sDidShutdown ) {
// The last context is being deleted, and we're already in the
// process of shutting down, release the JS runtime service, and
// the security manager.
NS_IF_RELEASE ( sRuntimeService ) ;
NS_IF_RELEASE ( sSecurityManager ) ;
}
}
2013-07-03 21:05:19 +04:00
// This function is called either by the destructor or unlink, which means that
// it can never be called when there is an outstanding ref to the
// nsIScriptContext on the stack. Our stack-scoped cx pushers hold such a ref,
// so we can assume here that mContext is not on the stack (and therefore not
// in use).
2007-11-02 01:51:57 +03:00
void
2009-05-07 22:19:36 +04:00
nsJSContext : : DestroyJSContext ( )
2007-11-02 01:51:57 +03:00
{
2011-12-27 15:59:29 +04:00
if ( ! mContext ) {
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
return ;
2011-12-27 15:59:29 +04:00
}
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
2001-02-02 09:05:17 +03:00
// Clear our entry in the JSContext, bugzilla bug 66413
2012-07-30 18:20:58 +04:00
: : JS_SetContextPrivate ( mContext , nullptr ) ;
2001-02-02 09:05:17 +03:00
2000-09-02 05:58:51 +04:00
// Unregister our "javascript.options.*" pref-changed callback.
2011-05-29 03:42:57 +04:00
Preferences : : UnregisterCallback ( JSOptionChangedCallback ,
js_options_dot_str , this ) ;
2000-09-02 05:58:51 +04:00
2011-12-27 15:59:29 +04:00
if ( mGCOnDestruction ) {
2013-01-28 00:35:12 +04:00
PokeGC ( JS : : gcreason : : NSJSCONTEXT_DESTROY ) ;
2011-12-27 15:59:29 +04:00
}
2013-07-03 21:05:19 +04:00
JS_DestroyContextNoGC ( mContext ) ;
2012-07-30 18:20:58 +04:00
mContext = nullptr ;
2013-09-05 01:58:23 +04:00
DropJSObjects ( this ) ;
2007-05-25 12:42:08 +04:00
}
2001-11-27 12:46:38 +03:00
// QueryInterface implementation for nsJSContext
2013-08-02 05:29:05 +04:00
NS_IMPL_CYCLE_COLLECTION_CLASS ( nsJSContext )
2010-11-08 18:02:49 +03:00
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN ( nsJSContext )
2013-09-05 01:06:56 +04:00
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK ( mWindowProxy )
2010-11-08 18:02:49 +03:00
NS_IMPL_CYCLE_COLLECTION_TRACE_END
2013-08-02 05:29:05 +04:00
2010-11-08 18:02:49 +03:00
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN ( nsJSContext )
2012-09-05 02:22:05 +04:00
NS_ASSERTION ( ! tmp - > mContext | | ! js : : ContextHasOutstandingRequests ( tmp - > mContext ) ,
2009-05-07 22:19:36 +04:00
" Trying to unlink a context with outstanding requests. " ) ;
2011-10-17 18:59:28 +04:00
tmp - > mIsInitialized = false ;
tmp - > mGCOnDestruction = false ;
2013-09-05 01:06:56 +04:00
tmp - > mWindowProxy = nullptr ;
2009-05-07 22:19:36 +04:00
tmp - > DestroyJSContext ( ) ;
2012-11-15 11:32:40 +04:00
NS_IMPL_CYCLE_COLLECTION_UNLINK ( mGlobalObjectRef )
2007-11-02 01:51:57 +03:00
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
2009-02-27 17:48:26 +03:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL ( nsJSContext )
NS_IMPL_CYCLE_COLLECTION_DESCRIBE ( nsJSContext , tmp - > GetCCRefcnt ( ) )
2012-11-15 11:32:40 +04:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE ( mGlobalObjectRef )
2013-09-05 01:06:56 +04:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
2007-03-08 14:17:16 +03:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
2007-04-25 20:35:27 +04:00
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION ( nsJSContext )
2001-11-27 12:46:38 +03:00
NS_INTERFACE_MAP_ENTRY ( nsIScriptContext )
2013-08-15 01:00:03 +04:00
NS_INTERFACE_MAP_ENTRY ( nsISupports )
2001-11-27 12:46:38 +03:00
NS_INTERFACE_MAP_END
2011-03-06 14:11:31 +03:00
NS_IMPL_CYCLE_COLLECTING_ADDREF ( nsJSContext )
NS_IMPL_CYCLE_COLLECTING_RELEASE ( nsJSContext )
2001-11-27 12:46:38 +03:00
2009-05-07 22:19:36 +04:00
nsrefcnt
nsJSContext : : GetCCRefcnt ( )
{
2009-05-22 22:45:26 +04:00
nsrefcnt refcnt = mRefCnt . get ( ) ;
2012-09-05 02:22:05 +04:00
// In the (abnormal) case of synchronous cycle-collection, the context may be
// actively running JS code in which case we must keep it alive by adding an
// extra refcount.
if ( mContext & & js : : ContextHasOutstandingRequests ( mContext ) ) {
refcnt + + ;
}
2009-05-22 22:45:26 +04:00
return refcnt ;
2009-05-07 22:19:36 +04:00
}
2010-03-08 18:45:00 +03:00
# ifdef DEBUG
2011-09-29 10:19:26 +04:00
bool
2010-03-08 18:45:00 +03:00
AtomIsEventHandlerName ( nsIAtom * aName )
1999-12-03 06:40:30 +03:00
{
2014-01-04 19:02:17 +04:00
const char16_t * name = aName - > GetUTF16String ( ) ;
1999-12-03 06:40:30 +03:00
2014-01-04 19:02:17 +04:00
const char16_t * cp ;
char16_t c ;
2003-07-01 09:11:46 +04:00
for ( cp = name ; * cp ! = ' \0 ' ; + + cp )
{
c = * cp ;
2010-03-08 18:45:00 +03:00
if ( ( c < ' A ' | | c > ' Z ' ) & & ( c < ' a ' | | c > ' z ' ) )
2011-10-17 18:59:28 +04:00
return false ;
2003-07-01 09:11:46 +04:00
}
1999-12-03 06:40:30 +03:00
2011-10-17 18:59:28 +04:00
return true ;
1999-12-03 06:40:30 +03:00
}
2010-03-08 18:45:00 +03:00
# endif
1999-12-03 06:40:30 +03:00
2004-02-10 01:48:53 +03:00
nsIScriptGlobalObject *
nsJSContext : : GetGlobalObject ( )
1998-07-16 05:16:47 +04:00
{
2013-05-22 20:05:24 +04:00
AutoJSContext cx ;
2013-09-05 01:06:57 +04:00
JS : : Rooted < JSObject * > global ( mContext , GetWindowProxy ( ) ) ;
2001-05-26 11:44:19 +04:00
if ( ! global ) {
2012-07-30 18:20:58 +04:00
return nullptr ;
2010-09-18 01:54:40 +04:00
}
2011-04-29 00:28:54 +04:00
if ( mGlobalObjectRef )
return mGlobalObjectRef ;
# ifdef DEBUG
{
2013-05-22 20:05:24 +04:00
JSObject * inner = JS_ObjectToInnerObject ( cx , global ) ;
2011-04-29 00:28:54 +04:00
// If this assertion hits then it means that we have a window object as
// our global, but we never called CreateOuterObject.
NS_ASSERTION ( inner = = global , " Shouldn't be able to innerize here " ) ;
2001-05-26 11:44:19 +04:00
}
2011-04-29 00:28:54 +04:00
# endif
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2013-09-11 16:49:05 +04:00
const JSClass * c = JS_GetClass ( global ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2014-01-30 18:31:16 +04:00
nsCOMPtr < nsIScriptGlobalObject > sgo ;
if ( IsDOMClass ( c ) ) {
sgo = do_QueryInterface ( UnwrapDOMObjectToISupports ( global ) ) ;
} else {
if ( ( ~ c - > flags ) & ( JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS ) ) {
return nullptr ;
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2014-01-30 18:31:16 +04:00
nsISupports * priv = static_cast < nsISupports * > ( js : : GetObjectPrivate ( global ) ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2014-01-30 18:31:16 +04:00
nsCOMPtr < nsIXPConnectWrappedNative > wrapped_native =
do_QueryInterface ( priv ) ;
if ( wrapped_native ) {
// The global object is a XPConnect wrapped native, the native in
// the wrapper might be the nsIScriptGlobalObject
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2014-01-30 18:31:16 +04:00
sgo = do_QueryWrappedNative ( wrapped_native ) ;
} else {
sgo = do_QueryInterface ( priv ) ;
}
2004-02-10 01:48:53 +03:00
}
2001-06-20 07:27:48 +04:00
2004-02-10 01:48:53 +03:00
// This'll return a pointer to something we're about to release, but
// that's ok, the JS object will hold it alive long enough.
2011-04-29 00:28:54 +04:00
return sgo ;
1998-07-16 05:16:47 +04:00
}
2011-09-18 13:22:17 +04:00
JSContext *
1998-12-21 19:51:10 +03:00
nsJSContext : : GetNativeContext ( )
1998-07-16 05:16:47 +04:00
{
2013-09-05 01:06:56 +04:00
return mContext ;
1998-07-16 05:16:47 +04:00
}
2004-02-10 01:48:53 +03:00
nsresult
2010-07-16 02:16:29 +04:00
nsJSContext : : InitContext ( )
1998-07-16 05:16:47 +04:00
{
2005-08-10 04:15:51 +04:00
// Make sure callers of this use
// WillInitializeContext/DidInitializeContext around this call.
NS_ENSURE_TRUE ( ! mIsInitialized , NS_ERROR_ALREADY_INITIALIZED ) ;
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
if ( ! mContext )
return NS_ERROR_OUT_OF_MEMORY ;
2001-05-18 11:25:56 +04:00
: : JS_SetErrorReporter ( mContext , NS_ScriptErrorReporter ) ;
2012-03-22 12:36:36 +04:00
JSOptionChangedCallback ( js_options_dot_str , this ) ;
2010-07-16 02:16:29 +04:00
return NS_OK ;
}
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
1998-12-31 00:35:35 +03:00
nsresult
nsJSContext : : InitializeExternalClasses ( )
{
2013-08-20 03:24:29 +04:00
nsScriptNameSpaceManager * nameSpaceManager = GetNameSpaceManager ( ) ;
2007-11-13 13:35:49 +03:00
NS_ENSURE_TRUE ( nameSpaceManager , NS_ERROR_NOT_INITIALIZED ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2007-11-13 13:35:49 +03:00
return nameSpaceManager - > InitForContext ( this ) ;
1998-12-31 00:35:35 +03:00
}
2006-06-13 07:07:47 +04:00
nsresult
2013-05-12 09:17:42 +04:00
nsJSContext : : SetProperty ( JS : : Handle < JSObject * > aTarget , const char * aPropName , nsISupports * aArgs )
2006-06-13 07:07:47 +04:00
{
2013-02-26 23:04:12 +04:00
nsCxPusher pusher ;
pusher . Push ( mContext ) ;
2007-07-26 21:52:26 +04:00
2014-02-11 14:59:15 +04:00
JS : : AutoValueVector args ( mContext ) ;
2010-01-25 19:48:07 +03:00
2013-09-05 01:06:57 +04:00
JS : : Rooted < JSObject * > global ( mContext , GetWindowProxy ( ) ) ;
2012-03-11 12:50:22 +04:00
nsresult rv =
2014-02-11 14:59:15 +04:00
ConvertSupportsTojsvals ( aArgs , global , args ) ;
2006-06-13 07:07:47 +04:00
NS_ENSURE_SUCCESS ( rv , rv ) ;
2007-07-26 21:52:26 +04:00
// got the arguments, now attach them.
2014-02-11 14:59:15 +04:00
for ( uint32_t i = 0 ; i < args . length ( ) ; + + i ) {
if ( ! JS_WrapValue ( mContext , args . handleAt ( i ) ) ) {
2013-05-17 21:43:19 +04:00
return NS_ERROR_FAILURE ;
2010-09-28 07:40:27 +04:00
}
2013-05-17 12:08:44 +04:00
}
2013-05-17 10:33:14 +04:00
2014-01-22 06:11:17 +04:00
JS : : Rooted < JSObject * > array ( mContext , : : JS_NewArrayObject ( mContext , args ) ) ;
2014-02-11 14:59:15 +04:00
if ( ! array ) {
2013-10-26 20:19:05 +04:00
return NS_ERROR_FAILURE ;
}
2013-05-17 21:43:19 +04:00
2014-01-22 06:11:17 +04:00
return JS_DefineProperty ( mContext , aTarget , aPropName , array , 0 ) ? NS_OK : NS_ERROR_FAILURE ;
2006-06-13 07:07:47 +04:00
}
nsresult
2014-02-11 14:59:15 +04:00
nsJSContext : : ConvertSupportsTojsvals ( nsISupports * aArgs ,
2013-05-02 13:12:46 +04:00
JS : : Handle < JSObject * > aScope ,
2014-02-11 14:59:15 +04:00
JS : : AutoValueVector & aArgsOut )
2006-06-13 07:07:47 +04:00
{
nsresult rv = NS_OK ;
2014-02-11 14:59:15 +04:00
// If the array implements nsIJSArgArray, copy the contents and return.
2006-06-13 07:07:47 +04:00
nsCOMPtr < nsIJSArgArray > fastArray = do_QueryInterface ( aArgs ) ;
2014-02-11 14:59:15 +04:00
if ( fastArray ) {
uint32_t argc ;
JS : : Value * argv ;
rv = fastArray - > GetArgs ( & argc , reinterpret_cast < void * * > ( & argv ) ) ;
if ( NS_SUCCEEDED ( rv ) & & ! aArgsOut . append ( argv , argc ) ) {
rv = NS_ERROR_OUT_OF_MEMORY ;
}
return rv ;
}
2010-01-25 19:48:07 +03:00
2006-06-13 07:07:47 +04:00
// Take the slower path converting each item.
// Handle only nsIArray and nsIVariant. nsIArray is only needed for
// SetProperty('arguments', ...);
nsIXPConnect * xpc = nsContentUtils : : XPConnect ( ) ;
NS_ENSURE_TRUE ( xpc , NS_ERROR_UNEXPECTED ) ;
2013-05-22 20:05:24 +04:00
AutoJSContext cx ;
2006-06-13 07:07:47 +04:00
if ( ! aArgs )
return NS_OK ;
2012-08-22 19:56:38 +04:00
uint32_t argCount ;
2006-06-13 07:07:47 +04:00
// This general purpose function may need to convert an arg array
// (window.arguments, event-handler args) and a generic property.
nsCOMPtr < nsIArray > argsArray ( do_QueryInterface ( aArgs ) ) ;
if ( argsArray ) {
rv = argsArray - > GetLength ( & argCount ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
if ( argCount = = 0 )
return NS_OK ;
2006-06-22 02:10:35 +04:00
} else {
2006-06-13 07:07:47 +04:00
argCount = 1 ; // the nsISupports which is not an array
2006-06-22 02:10:35 +04:00
}
2006-06-13 07:07:47 +04:00
2010-02-17 22:32:47 +03:00
// Use the caller's auto guards to release and unroot.
2014-02-11 14:59:15 +04:00
if ( ! aArgsOut . resize ( argCount ) ) {
return NS_ERROR_OUT_OF_MEMORY ;
}
2010-01-25 19:48:07 +03:00
2006-06-13 07:07:47 +04:00
if ( argsArray ) {
2012-08-22 19:56:38 +04:00
for ( uint32_t argCtr = 0 ; argCtr < argCount & & NS_SUCCEEDED ( rv ) ; argCtr + + ) {
2006-06-13 07:07:47 +04:00
nsCOMPtr < nsISupports > arg ;
2014-02-11 14:59:15 +04:00
JS : : MutableHandle < JS : : Value > thisVal = aArgsOut . handleAt ( argCtr ) ;
2006-06-22 02:10:35 +04:00
argsArray - > QueryElementAt ( argCtr , NS_GET_IID ( nsISupports ) ,
getter_AddRefs ( arg ) ) ;
if ( ! arg ) {
2014-02-11 14:59:15 +04:00
thisVal . setNull ( ) ;
2006-06-22 02:10:35 +04:00
continue ;
}
2006-06-13 07:07:47 +04:00
nsCOMPtr < nsIVariant > variant ( do_QueryInterface ( arg ) ) ;
2012-07-30 18:20:58 +04:00
if ( variant ! = nullptr ) {
2014-02-11 14:59:15 +04:00
rv = xpc - > VariantToJS ( cx , aScope , variant , thisVal ) ;
2006-06-13 07:07:47 +04:00
} else {
// And finally, support the nsISupportsPrimitives supplied
// by the AppShell. It generally will pass only strings, but
// as we have code for handling all, we may as well use it.
2014-02-11 14:59:15 +04:00
rv = AddSupportsPrimitiveTojsvals ( arg , thisVal . address ( ) ) ;
2006-06-13 07:07:47 +04:00
if ( rv = = NS_ERROR_NO_INTERFACE ) {
2007-07-26 21:52:26 +04:00
// something else - probably an event object or similar -
2006-06-13 07:07:47 +04:00
// just wrap it.
2012-06-25 23:59:42 +04:00
# ifdef DEBUG
2006-06-13 07:07:47 +04:00
// but first, check its not another nsISupportsPrimitive, as
// these are now deprecated for use with script contexts.
nsCOMPtr < nsISupportsPrimitive > prim ( do_QueryInterface ( arg ) ) ;
2012-07-30 18:20:58 +04:00
NS_ASSERTION ( prim = = nullptr ,
2006-06-13 07:07:47 +04:00
" Don't pass nsISupportsPrimitives - use nsIVariant! " ) ;
# endif
2014-04-10 08:58:41 +04:00
JSAutoCompartment ac ( cx , aScope ) ;
rv = nsContentUtils : : WrapNative ( cx , arg , thisVal ) ;
2006-06-13 07:07:47 +04:00
}
}
}
} else {
2011-10-30 00:06:17 +04:00
nsCOMPtr < nsIVariant > variant = do_QueryInterface ( aArgs ) ;
if ( variant ) {
2014-02-11 14:59:15 +04:00
rv = xpc - > VariantToJS ( cx , aScope , variant , aArgsOut . handleAt ( 0 ) ) ;
2011-10-30 00:06:17 +04:00
} else {
2006-06-13 07:07:47 +04:00
NS_ERROR ( " Not an array, not an interface? " ) ;
rv = NS_ERROR_UNEXPECTED ;
}
}
2014-02-11 14:59:15 +04:00
return rv ;
2006-06-13 07:07:47 +04:00
}
// This really should go into xpconnect somewhere...
nsresult
2013-04-12 02:52:10 +04:00
nsJSContext : : AddSupportsPrimitiveTojsvals ( nsISupports * aArg , JS : : Value * aArgv )
2006-06-13 07:07:47 +04:00
{
NS_PRECONDITION ( aArg , " Empty arg " ) ;
nsCOMPtr < nsISupportsPrimitive > argPrimitive ( do_QueryInterface ( aArg ) ) ;
if ( ! argPrimitive )
return NS_ERROR_NO_INTERFACE ;
2013-05-22 20:05:24 +04:00
AutoJSContext cx ;
2012-08-22 19:56:38 +04:00
uint16_t type ;
2006-06-13 07:07:47 +04:00
argPrimitive - > GetType ( & type ) ;
switch ( type ) {
case nsISupportsPrimitive : : TYPE_CSTRING : {
nsCOMPtr < nsISupportsCString > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2012-09-02 06:35:17 +04:00
nsAutoCString data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( data ) ;
2008-07-27 03:17:12 +04:00
2006-06-13 07:07:47 +04:00
JSString * str = : : JS_NewStringCopyN ( cx , data . get ( ) , data . Length ( ) ) ;
NS_ENSURE_TRUE ( str , NS_ERROR_OUT_OF_MEMORY ) ;
* aArgv = STRING_TO_JSVAL ( str ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_STRING : {
nsCOMPtr < nsISupportsString > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
nsAutoString data ;
p - > GetData ( data ) ;
// cast is probably safe since wchar_t and jschar are expected
// to be equivalent; both unsigned 16-bit entities
JSString * str =
2013-12-04 16:19:38 +04:00
: : JS_NewUCStringCopyN ( cx , data . get ( ) , data . Length ( ) ) ;
2006-06-13 07:07:47 +04:00
NS_ENSURE_TRUE ( str , NS_ERROR_OUT_OF_MEMORY ) ;
* aArgv = STRING_TO_JSVAL ( str ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_PRBOOL : {
nsCOMPtr < nsISupportsPRBool > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2011-09-29 10:19:26 +04:00
bool data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( & data ) ;
* aArgv = BOOLEAN_TO_JSVAL ( data ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_PRUINT8 : {
nsCOMPtr < nsISupportsPRUint8 > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2012-08-22 19:56:38 +04:00
uint8_t data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( & data ) ;
* aArgv = INT_TO_JSVAL ( data ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_PRUINT16 : {
nsCOMPtr < nsISupportsPRUint16 > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2012-08-22 19:56:38 +04:00
uint16_t data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( & data ) ;
* aArgv = INT_TO_JSVAL ( data ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_PRUINT32 : {
nsCOMPtr < nsISupportsPRUint32 > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2012-08-22 19:56:38 +04:00
uint32_t data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( & data ) ;
* aArgv = INT_TO_JSVAL ( data ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_CHAR : {
nsCOMPtr < nsISupportsChar > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
char data ;
p - > GetData ( & data ) ;
JSString * str = : : JS_NewStringCopyN ( cx , & data , 1 ) ;
NS_ENSURE_TRUE ( str , NS_ERROR_OUT_OF_MEMORY ) ;
* aArgv = STRING_TO_JSVAL ( str ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_PRINT16 : {
nsCOMPtr < nsISupportsPRInt16 > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2012-08-22 19:56:38 +04:00
int16_t data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( & data ) ;
* aArgv = INT_TO_JSVAL ( data ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_PRINT32 : {
nsCOMPtr < nsISupportsPRInt32 > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
2012-08-22 19:56:38 +04:00
int32_t data ;
2006-06-13 07:07:47 +04:00
p - > GetData ( & data ) ;
* aArgv = INT_TO_JSVAL ( data ) ;
break ;
}
case nsISupportsPrimitive : : TYPE_FLOAT : {
nsCOMPtr < nsISupportsFloat > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
float data ;
p - > GetData ( & data ) ;
2012-08-02 04:59:47 +04:00
* aArgv = : : JS_NumberValue ( data ) ;
2006-06-13 07:07:47 +04:00
break ;
}
case nsISupportsPrimitive : : TYPE_DOUBLE : {
nsCOMPtr < nsISupportsDouble > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
double data ;
p - > GetData ( & data ) ;
2012-08-02 04:59:47 +04:00
* aArgv = : : JS_NumberValue ( data ) ;
2006-06-13 07:07:47 +04:00
break ;
}
case nsISupportsPrimitive : : TYPE_INTERFACE_POINTER : {
nsCOMPtr < nsISupportsInterfacePointer > p ( do_QueryInterface ( argPrimitive ) ) ;
NS_ENSURE_TRUE ( p , NS_ERROR_UNEXPECTED ) ;
nsCOMPtr < nsISupports > data ;
2012-07-30 18:20:58 +04:00
nsIID * iid = nullptr ;
2006-06-13 07:07:47 +04:00
p - > GetData ( getter_AddRefs ( data ) ) ;
p - > GetDataIID ( & iid ) ;
NS_ENSURE_TRUE ( iid , NS_ERROR_UNEXPECTED ) ;
AutoFree iidGuard ( iid ) ; // Free iid upon destruction.
2014-04-10 08:58:41 +04:00
JS : : Rooted < JSObject * > scope ( cx , GetWindowProxy ( ) ) ;
2013-05-02 13:12:46 +04:00
JS : : Rooted < JS : : Value > v ( cx ) ;
2014-04-10 08:58:41 +04:00
JSAutoCompartment ac ( cx , scope ) ;
nsresult rv = nsContentUtils : : WrapNative ( cx , data , iid , & v ) ;
2006-06-13 07:07:47 +04:00
NS_ENSURE_SUCCESS ( rv , rv ) ;
2009-08-14 23:00:24 +04:00
* aArgv = v ;
2006-06-13 07:07:47 +04:00
break ;
}
case nsISupportsPrimitive : : TYPE_ID :
case nsISupportsPrimitive : : TYPE_PRUINT64 :
case nsISupportsPrimitive : : TYPE_PRINT64 :
case nsISupportsPrimitive : : TYPE_PRTIME :
case nsISupportsPrimitive : : TYPE_VOID : {
NS_WARNING ( " Unsupported primitive type used " ) ;
* aArgv = JSVAL_NULL ;
break ;
}
default : {
NS_WARNING ( " Unknown primitive type used " ) ;
* aArgv = JSVAL_NULL ;
break ;
}
}
return NS_OK ;
}
2000-04-27 08:02:22 +04:00
# ifdef NS_TRACE_MALLOC
# include <errno.h> // XXX assume Linux if NS_TRACE_MALLOC
# include <fcntl.h>
2001-01-26 01:54:05 +03:00
# ifdef XP_UNIX
2000-04-27 08:02:22 +04:00
# include <unistd.h>
2001-01-26 01:54:05 +03:00
# endif
# ifdef XP_WIN32
# include <io.h>
# endif
2000-04-27 08:02:22 +04:00
# include "nsTraceMalloc.h"
2013-08-02 11:41:57 +04:00
static bool
2010-10-18 06:36:25 +04:00
CheckUniversalXPConnectForTraceMalloc ( JSContext * cx )
{
2012-10-22 10:29:55 +04:00
if ( nsContentUtils : : IsCallerChrome ( ) )
2013-08-02 11:41:57 +04:00
return true ;
2010-10-18 06:36:25 +04:00
JS_ReportError ( cx , " trace-malloc functions require UniversalXPConnect " ) ;
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocDisable ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-04-27 08:02:22 +04:00
{
2014-03-19 21:05:04 +04:00
JS : : CallArgs args = JS : : CallArgsFromVp ( argc , vp ) ;
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
2000-04-27 08:02:22 +04:00
NS_TraceMallocDisable ( ) ;
2014-03-19 21:05:04 +04:00
args . rval ( ) . setUndefined ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-04-27 08:02:22 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocEnable ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-04-27 08:02:22 +04:00
{
2014-03-19 21:05:04 +04:00
JS : : CallArgs args = JS : : CallArgsFromVp ( argc , vp ) ;
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
2000-04-27 08:02:22 +04:00
NS_TraceMallocEnable ( ) ;
2014-03-19 21:05:04 +04:00
args . rval ( ) . setUndefined ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-04-27 08:02:22 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocOpenLogFile ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-04-27 08:02:22 +04:00
{
2013-11-16 16:31:36 +04:00
JS : : CallArgs args = JS : : CallArgsFromVp ( argc , vp ) ;
2000-04-27 08:02:22 +04:00
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
2013-11-16 16:31:36 +04:00
int fd ;
2000-05-17 10:58:48 +04:00
if ( argc = = 0 ) {
2000-04-27 08:02:22 +04:00
fd = - 1 ;
} else {
2013-11-16 16:31:36 +04:00
JSString * str = JS : : ToString ( cx , args [ 0 ] ) ;
2000-04-27 08:02:22 +04:00
if ( ! str )
2013-08-02 11:41:57 +04:00
return false ;
2010-11-11 23:40:29 +03:00
JSAutoByteString filename ( cx , str ) ;
if ( ! filename )
2013-08-02 11:41:57 +04:00
return false ;
2010-11-11 23:40:29 +03:00
fd = open ( filename . ptr ( ) , O_CREAT | O_WRONLY | O_TRUNC , 0644 ) ;
2000-04-27 08:02:22 +04:00
if ( fd < 0 ) {
2010-11-11 23:40:29 +03:00
JS_ReportError ( cx , " can't open %s: %s " , filename . ptr ( ) , strerror ( errno ) ) ;
2013-08-02 11:41:57 +04:00
return false ;
2000-04-27 08:02:22 +04:00
}
}
2013-11-16 16:31:36 +04:00
args . rval ( ) . setInt32 ( fd ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-05-17 10:58:48 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocChangeLogFD ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-05-17 10:58:48 +04:00
{
2013-08-16 01:41:51 +04:00
JS : : CallArgs args = CallArgsFromVp ( argc , vp ) ;
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-09 07:54:10 +04:00
int32_t fd , oldfd ;
2013-08-16 01:41:51 +04:00
if ( args . length ( ) = = 0 ) {
2000-05-17 10:58:48 +04:00
oldfd = - 1 ;
} else {
2013-08-16 01:41:51 +04:00
if ( ! JS : : ToInt32 ( cx , args [ 0 ] , & fd ) )
2013-08-02 11:41:57 +04:00
return false ;
2000-05-17 10:58:48 +04:00
oldfd = NS_TraceMallocChangeLogFD ( fd ) ;
if ( oldfd = = - 2 ) {
JS_ReportOutOfMemory ( cx ) ;
2013-08-02 11:41:57 +04:00
return false ;
2000-05-17 10:58:48 +04:00
}
}
2013-08-16 01:41:51 +04:00
args . rval ( ) . setInt32 ( oldfd ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-04-27 08:02:22 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocCloseLogFD ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-05-17 08:44:14 +04:00
{
2013-08-16 01:41:51 +04:00
JS : : CallArgs args = CallArgsFromVp ( argc , vp ) ;
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-09 07:54:10 +04:00
int32_t fd ;
2013-08-16 01:41:51 +04:00
if ( args . length ( ) = = 0 ) {
args . rval ( ) . setUndefined ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2013-08-16 01:41:51 +04:00
}
if ( ! JS : : ToInt32 ( cx , args [ 0 ] , & fd ) )
2013-08-02 11:41:57 +04:00
return false ;
2000-05-17 08:44:14 +04:00
NS_TraceMallocCloseLogFD ( ( int ) fd ) ;
2013-08-16 01:41:51 +04:00
args . rval ( ) . setInt32 ( fd ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-05-17 08:44:14 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocLogTimestamp ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-08-09 06:43:09 +04:00
{
2013-11-16 16:31:36 +04:00
JS : : CallArgs args = JS : : CallArgsFromVp ( argc , vp ) ;
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
2013-11-16 16:31:36 +04:00
JSString * str = JS : : ToString ( cx , args . get ( 0 ) ) ;
2000-08-09 06:43:09 +04:00
if ( ! str )
2013-08-02 11:41:57 +04:00
return false ;
2010-11-11 23:40:29 +03:00
JSAutoByteString caption ( cx , str ) ;
if ( ! caption )
2013-08-02 11:41:57 +04:00
return false ;
2010-11-11 23:40:29 +03:00
NS_TraceMallocLogTimestamp ( caption . ptr ( ) ) ;
2013-11-16 16:31:36 +04:00
args . rval ( ) . setUndefined ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-08-09 06:43:09 +04:00
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
TraceMallocDumpAllocations ( JSContext * cx , unsigned argc , JS : : Value * vp )
2000-08-29 05:52:13 +04:00
{
2013-11-16 16:31:36 +04:00
JS : : CallArgs args = JS : : CallArgsFromVp ( argc , vp ) ;
2010-10-18 06:36:25 +04:00
if ( ! CheckUniversalXPConnectForTraceMalloc ( cx ) )
2013-08-02 11:41:57 +04:00
return false ;
2010-10-18 06:36:25 +04:00
2013-11-16 16:31:36 +04:00
JSString * str = JS : : ToString ( cx , args . get ( 0 ) ) ;
2000-08-29 05:52:13 +04:00
if ( ! str )
2013-08-02 11:41:57 +04:00
return false ;
2010-11-11 23:40:29 +03:00
JSAutoByteString pathname ( cx , str ) ;
if ( ! pathname )
2013-08-02 11:41:57 +04:00
return false ;
2010-11-11 23:40:29 +03:00
if ( NS_TraceMallocDumpAllocations ( pathname . ptr ( ) ) < 0 ) {
JS_ReportError ( cx , " can't dump to %s: %s " , pathname . ptr ( ) , strerror ( errno ) ) ;
2013-08-02 11:41:57 +04:00
return false ;
2000-08-29 05:52:13 +04:00
}
2013-11-16 16:31:36 +04:00
args . rval ( ) . setUndefined ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2000-08-29 05:52:13 +04:00
}
2013-04-23 01:15:49 +04:00
static const JSFunctionSpec TraceMallocFunctions [ ] = {
2012-08-08 09:26:19 +04:00
JS_FS ( " TraceMallocDisable " , TraceMallocDisable , 0 , 0 ) ,
JS_FS ( " TraceMallocEnable " , TraceMallocEnable , 0 , 0 ) ,
JS_FS ( " TraceMallocOpenLogFile " , TraceMallocOpenLogFile , 1 , 0 ) ,
JS_FS ( " TraceMallocChangeLogFD " , TraceMallocChangeLogFD , 1 , 0 ) ,
JS_FS ( " TraceMallocCloseLogFD " , TraceMallocCloseLogFD , 1 , 0 ) ,
JS_FS ( " TraceMallocLogTimestamp " , TraceMallocLogTimestamp , 1 , 0 ) ,
JS_FS ( " TraceMallocDumpAllocations " , TraceMallocDumpAllocations , 1 , 0 ) ,
JS_FS_END
2000-04-27 08:02:22 +04:00
} ;
# endif /* NS_TRACE_MALLOC */
2012-12-11 04:05:07 +04:00
# ifdef MOZ_DMD
# include <errno.h>
namespace mozilla {
namespace dmd {
// See https://wiki.mozilla.org/Performance/MemShrink/DMD for instructions on
// how to use DMD.
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
ReportAndDump ( JSContext * cx , unsigned argc , JS : : Value * vp )
2012-12-11 04:05:07 +04:00
{
2013-11-16 16:31:36 +04:00
JS : : CallArgs args = JS : : CallArgsFromVp ( argc , vp ) ;
JSString * str = JS : : ToString ( cx , args . get ( 0 ) ) ;
2012-12-11 04:05:07 +04:00
if ( ! str )
2013-08-02 11:41:57 +04:00
return false ;
2012-12-11 04:05:07 +04:00
JSAutoByteString pathname ( cx , str ) ;
if ( ! pathname )
2013-08-02 11:41:57 +04:00
return false ;
2012-12-11 04:05:07 +04:00
FILE * fp = fopen ( pathname . ptr ( ) , " w " ) ;
if ( ! fp ) {
JS_ReportError ( cx , " DMD can't open %s: %s " ,
pathname . ptr ( ) , strerror ( errno ) ) ;
2013-08-02 11:41:57 +04:00
return false ;
2012-12-11 04:05:07 +04:00
}
2013-01-07 01:34:39 +04:00
dmd : : ClearReports ( ) ;
fprintf ( stderr , " DMD: running reporters... \n " ) ;
2013-12-02 04:29:37 +04:00
dmd : : RunReportersForThisProcess ( ) ;
2012-12-11 04:05:07 +04:00
dmd : : Writer writer ( FpWrite , fp ) ;
dmd : : Dump ( writer ) ;
fclose ( fp ) ;
2013-11-16 16:31:36 +04:00
args . rval ( ) . setUndefined ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2012-12-11 04:05:07 +04:00
}
} // namespace dmd
} // namespace mozilla
2013-04-23 01:15:49 +04:00
static const JSFunctionSpec DMDFunctions [ ] = {
2012-12-11 04:05:07 +04:00
JS_FS ( " DMDReportAndDump " , dmd : : ReportAndDump , 1 , 0 ) ,
JS_FS_END
} ;
# endif // defined(MOZ_DMD)
2004-05-11 06:37:25 +04:00
# ifdef MOZ_JPROF
# include <signal.h>
2011-09-29 10:19:26 +04:00
inline bool
2004-05-11 06:37:25 +04:00
IsJProfAction ( struct sigaction * action )
{
return ( action - > sa_sigaction & &
2011-11-08 09:34:40 +04:00
( action - > sa_flags & ( SA_RESTART | SA_SIGINFO ) ) = = ( SA_RESTART | SA_SIGINFO ) ) ;
2004-05-11 06:37:25 +04:00
}
2006-12-12 18:47:47 +03:00
void NS_JProfStartProfiling ( ) ;
void NS_JProfStopProfiling ( ) ;
2011-11-08 09:34:40 +04:00
void NS_JProfClearCircular ( ) ;
2006-12-12 18:47:47 +03:00
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
JProfStartProfilingJS ( JSContext * cx , unsigned argc , JS : : Value * vp )
2006-12-12 18:47:47 +03:00
{
NS_JProfStartProfiling ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2006-12-12 18:47:47 +03:00
}
void NS_JProfStartProfiling ( )
2004-05-11 06:37:25 +04:00
{
// Figure out whether we're dealing with SIGPROF, SIGALRM, or
// SIGPOLL profiling (SIGALRM for JP_REALTIME, SIGPOLL for
// JP_RTC_HZ)
struct sigaction action ;
2011-11-08 09:34:40 +04:00
// Must check ALRM before PROF since both are enabled for real-time
2012-07-30 18:20:58 +04:00
sigaction ( SIGALRM , nullptr , & action ) ;
2011-11-08 09:34:40 +04:00
//printf("SIGALRM: %p, flags = %x\n",action.sa_sigaction,action.sa_flags);
2004-05-11 06:37:25 +04:00
if ( IsJProfAction ( & action ) ) {
2011-11-08 09:34:40 +04:00
//printf("Beginning real-time jprof profiling.\n");
2004-05-11 06:37:25 +04:00
raise ( SIGALRM ) ;
2006-12-12 18:47:47 +03:00
return ;
2004-05-11 06:37:25 +04:00
}
2012-07-30 18:20:58 +04:00
sigaction ( SIGPROF , nullptr , & action ) ;
2011-11-08 09:34:40 +04:00
//printf("SIGPROF: %p, flags = %x\n",action.sa_sigaction,action.sa_flags);
2004-05-11 06:37:25 +04:00
if ( IsJProfAction ( & action ) ) {
2011-11-08 09:34:40 +04:00
//printf("Beginning process-time jprof profiling.\n");
2004-05-11 06:37:25 +04:00
raise ( SIGPROF ) ;
2006-12-12 18:47:47 +03:00
return ;
2004-05-11 06:37:25 +04:00
}
2012-07-30 18:20:58 +04:00
sigaction ( SIGPOLL , nullptr , & action ) ;
2011-11-08 09:34:40 +04:00
//printf("SIGPOLL: %p, flags = %x\n",action.sa_sigaction,action.sa_flags);
2004-05-11 06:37:25 +04:00
if ( IsJProfAction ( & action ) ) {
2011-11-08 09:34:40 +04:00
//printf("Beginning rtc-based jprof profiling.\n");
2004-05-11 06:37:25 +04:00
raise ( SIGPOLL ) ;
2006-12-12 18:47:47 +03:00
return ;
2004-05-11 06:37:25 +04:00
}
printf ( " Could not start jprof-profiling since JPROF_FLAGS was not set. \n " ) ;
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
JProfStopProfilingJS ( JSContext * cx , unsigned argc , JS : : Value * vp )
2006-12-12 18:47:47 +03:00
{
NS_JProfStopProfiling ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2006-12-12 18:47:47 +03:00
}
void
NS_JProfStopProfiling ( )
2004-05-11 06:37:25 +04:00
{
raise ( SIGUSR1 ) ;
2011-11-08 09:34:40 +04:00
//printf("Stopped jprof profiling.\n");
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
JProfClearCircularJS ( JSContext * cx , unsigned argc , JS : : Value * vp )
2011-11-08 09:34:40 +04:00
{
NS_JProfClearCircular ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2011-11-08 09:34:40 +04:00
}
void
NS_JProfClearCircular ( )
{
raise ( SIGUSR2 ) ;
//printf("cleared jprof buffer\n");
}
2013-08-02 11:41:57 +04:00
static bool
2013-04-12 02:52:10 +04:00
JProfSaveCircularJS ( JSContext * cx , unsigned argc , JS : : Value * vp )
2011-11-08 09:34:40 +04:00
{
// Not ideal...
NS_JProfStopProfiling ( ) ;
NS_JProfStartProfiling ( ) ;
2013-08-02 11:41:57 +04:00
return true ;
2004-05-11 06:37:25 +04:00
}
2013-04-23 01:15:49 +04:00
static const JSFunctionSpec JProfFunctions [ ] = {
2012-10-05 03:01:32 +04:00
JS_FS ( " JProfStartProfiling " , JProfStartProfilingJS , 0 , 0 ) ,
JS_FS ( " JProfStopProfiling " , JProfStopProfilingJS , 0 , 0 ) ,
JS_FS ( " JProfClearCircular " , JProfClearCircularJS , 0 , 0 ) ,
JS_FS ( " JProfSaveCircular " , JProfSaveCircularJS , 0 , 0 ) ,
JS_FS_END
2004-05-11 06:37:25 +04:00
} ;
# endif /* defined(MOZ_JPROF) */
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
nsresult
2013-05-12 09:17:42 +04:00
nsJSContext : : InitClasses ( JS : : Handle < JSObject * > aGlobalObj )
1998-07-16 05:16:47 +04:00
{
2011-11-26 14:19:45 +04:00
nsresult rv = InitializeExternalClasses ( ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
NS_ENSURE_SUCCESS ( rv , rv ) ;
2000-04-27 08:02:22 +04:00
2012-03-28 15:09:33 +04:00
JSOptionChangedCallback ( js_options_dot_str , this ) ;
2013-05-22 20:05:24 +04:00
AutoPushJSContext cx ( mContext ) ;
2000-09-01 07:10:33 +04:00
2011-01-15 04:58:40 +03:00
// Attempt to initialize profiling functions
2013-05-22 20:05:24 +04:00
: : JS_DefineProfilingFunctions ( cx , aGlobalObj ) ;
2011-01-15 04:58:40 +03:00
2000-04-27 08:02:22 +04:00
# ifdef NS_TRACE_MALLOC
2013-08-29 02:48:43 +04:00
if ( nsContentUtils : : IsCallerChrome ( ) ) {
// Attempt to initialize TraceMalloc functions
: : JS_DefineFunctions ( cx , aGlobalObj , TraceMallocFunctions ) ;
}
2000-04-27 08:02:22 +04:00
# endif
2012-12-11 04:05:07 +04:00
# ifdef MOZ_DMD
// Attempt to initialize DMD functions
2013-05-22 20:05:24 +04:00
: : JS_DefineFunctions ( cx , aGlobalObj , DMDFunctions ) ;
2012-12-11 04:05:07 +04:00
# endif
2004-05-11 06:37:25 +04:00
# ifdef MOZ_JPROF
// Attempt to initialize JProf functions
2013-05-22 20:05:24 +04:00
: : JS_DefineFunctions ( cx , aGlobalObj , JProfFunctions ) ;
2004-05-11 06:37:25 +04:00
# endif
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
return rv ;
1998-07-16 05:16:47 +04:00
}
2005-07-31 00:57:07 +04:00
void
nsJSContext : : WillInitializeContext ( )
{
2011-10-17 18:59:28 +04:00
mIsInitialized = false ;
2005-07-31 00:57:07 +04:00
}
void
nsJSContext : : DidInitializeContext ( )
{
2011-10-17 18:59:28 +04:00
mIsInitialized = true ;
2005-07-31 00:57:07 +04:00
}
2011-09-29 10:19:26 +04:00
bool
1998-12-30 05:46:36 +03:00
nsJSContext : : IsContextInitialized ( )
{
2004-02-10 01:48:53 +03:00
return mIsInitialized ;
1998-12-30 05:46:36 +03:00
}
2013-01-15 15:46:35 +04:00
bool
nsJSContext : : GetProcessingScriptTag ( )
{
return mProcessingScriptTag ;
}
void
nsJSContext : : SetProcessingScriptTag ( bool aFlag )
{
mProcessingScriptTag = aFlag ;
}
2012-05-09 22:53:23 +04:00
void
FullGCTimerFired ( nsITimer * aTimer , void * aClosure )
{
NS_RELEASE ( sFullGCTimer ) ;
uintptr_t reason = reinterpret_cast < uintptr_t > ( aClosure ) ;
2013-01-28 00:35:12 +04:00
nsJSContext : : GarbageCollectNow ( static_cast < JS : : gcreason : : Reason > ( reason ) ,
2012-07-01 01:16:32 +04:00
nsJSContext : : IncrementalGC ) ;
2012-05-09 22:53:23 +04:00
}
2007-10-23 01:42:25 +04:00
//static
void
2013-01-28 00:35:12 +04:00
nsJSContext : : GarbageCollectNow ( JS : : gcreason : : Reason aReason ,
2012-07-01 01:16:32 +04:00
IsIncremental aIncremental ,
IsCompartment aCompartment ,
2012-08-01 05:39:39 +04:00
IsShrinking aShrinking ,
int64_t aSliceMillis )
2007-10-23 01:42:25 +04:00
{
2013-03-16 08:47:02 +04:00
PROFILER_LABEL ( " GC " , " GarbageCollectNow " ) ;
2010-05-20 03:22:19 +04:00
2012-08-01 05:39:39 +04:00
MOZ_ASSERT_IF ( aSliceMillis , aIncremental = = IncrementalGC ) ;
2011-02-17 02:47:12 +03:00
KillGCTimer ( ) ;
2011-12-27 15:59:29 +04:00
KillShrinkGCBuffersTimer ( ) ;
2008-02-25 20:47:25 +03:00
2011-02-17 02:47:12 +03:00
// Reset sPendingLoadCount in case the timer that fired was a
// timer we scheduled due to a normal GC timer firing while
// documents were loading. If this happens we're waiting for a
// document that is taking a long time to load, and we effectively
// ignore the fact that the currently loading documents are still
// loading and move on as if they weren't.
sPendingLoadCount = 0 ;
2011-10-17 18:59:28 +04:00
sLoadingInProgress = false ;
2007-10-23 01:42:25 +04:00
2013-08-20 03:24:29 +04:00
if ( ! nsContentUtils : : XPConnect ( ) | | ! sRuntime ) {
2012-05-09 22:53:23 +04:00
return ;
2011-02-19 02:14:21 +03:00
}
2012-07-01 01:16:32 +04:00
2012-07-01 01:18:10 +04:00
if ( sCCLockedOut & & aIncremental = = IncrementalGC ) {
// We're in the middle of incremental GC. Do another slice.
2013-08-20 03:24:29 +04:00
JS : : PrepareForIncrementalGC ( sRuntime ) ;
JS : : IncrementalGC ( sRuntime , aReason , aSliceMillis ) ;
2012-07-01 01:18:10 +04:00
return ;
}
2013-08-20 03:24:29 +04:00
JS : : PrepareForFullGC ( sRuntime ) ;
2012-07-01 01:16:32 +04:00
if ( aIncremental = = IncrementalGC ) {
2014-01-11 02:44:28 +04:00
MOZ_ASSERT ( aShrinking = = NonShrinkingGC ) ;
2013-08-20 03:24:29 +04:00
JS : : IncrementalGC ( sRuntime , aReason , aSliceMillis ) ;
2014-01-11 02:44:28 +04:00
} else if ( aShrinking = = ShrinkingGC ) {
JS : : ShrinkingGC ( sRuntime , aReason ) ;
2012-07-01 01:16:32 +04:00
} else {
2013-08-20 03:24:29 +04:00
JS : : GCForReason ( sRuntime , aReason ) ;
2012-07-01 01:16:32 +04:00
}
2007-10-23 01:42:25 +04:00
}
2011-12-27 15:59:29 +04:00
//static
void
nsJSContext : : ShrinkGCBuffersNow ( )
{
2013-03-16 08:47:02 +04:00
PROFILER_LABEL ( " GC " , " ShrinkGCBuffersNow " ) ;
2011-12-27 15:59:29 +04:00
KillShrinkGCBuffersTimer ( ) ;
2013-08-20 03:24:29 +04:00
JS : : ShrinkGCBuffers ( sRuntime ) ;
2011-12-27 15:59:29 +04:00
}
2013-01-01 00:54:37 +04:00
static void
FinishAnyIncrementalGC ( )
{
if ( sCCLockedOut ) {
// We're in the middle of an incremental GC, so finish it.
2013-08-20 03:24:29 +04:00
JS : : PrepareForIncrementalGC ( sRuntime ) ;
JS : : FinishIncrementalGC ( sRuntime , JS : : gcreason : : CC_FORCED ) ;
2013-01-01 00:54:37 +04:00
}
}
2012-07-15 14:30:39 +04:00
static void
2012-08-22 19:56:38 +04:00
FireForgetSkippable ( uint32_t aSuspected , bool aRemoveChildless )
2012-07-15 14:30:39 +04:00
{
PRTime startTime = PR_Now ( ) ;
2013-01-01 00:54:37 +04:00
FinishAnyIncrementalGC ( ) ;
2013-07-27 14:48:45 +04:00
bool earlyForgetSkippable =
sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS ;
nsCycleCollector_forgetSkippable ( aRemoveChildless , earlyForgetSkippable ) ;
2012-07-15 14:30:39 +04:00
sPreviousSuspectedCount = nsCycleCollector_suspectedCount ( ) ;
+ + sCleanupsSinceLastGC ;
PRTime delta = PR_Now ( ) - startTime ;
if ( sMinForgetSkippableTime > delta ) {
sMinForgetSkippableTime = delta ;
}
if ( sMaxForgetSkippableTime < delta ) {
sMaxForgetSkippableTime = delta ;
}
sTotalForgetSkippableTime + = delta ;
sRemovedPurples + = ( aSuspected - sPreviousSuspectedCount ) ;
+ + sForgetSkippableBeforeCC ;
}
2013-01-01 00:55:07 +04:00
MOZ_ALWAYS_INLINE
static uint32_t
2013-12-31 21:20:21 +04:00
TimeBetween ( TimeStamp start , TimeStamp end )
2013-01-01 00:55:07 +04:00
{
MOZ_ASSERT ( end > = start ) ;
2013-12-31 21:20:21 +04:00
return ( uint32_t ) ( ( end - start ) . ToMilliseconds ( ) ) ;
}
static uint32_t
TimeUntilNow ( TimeStamp start )
{
if ( start . IsNull ( ) ) {
return 0 ;
}
return TimeBetween ( start , TimeStamp : : Now ( ) ) ;
2013-01-01 00:55:07 +04:00
}
2013-11-21 02:35:16 +04:00
struct CycleCollectorStats
{
void Clear ( )
{
2013-12-31 21:20:21 +04:00
mBeginSliceTime = TimeStamp ( ) ;
2014-03-06 22:54:37 +04:00
mEndSliceTime = TimeStamp ( ) ;
2013-12-31 21:20:21 +04:00
mBeginTime = TimeStamp ( ) ;
2013-11-21 02:35:16 +04:00
mMaxGCDuration = 0 ;
mRanSyncForgetSkippable = false ;
mSuspected = 0 ;
mMaxSkippableDuration = 0 ;
2013-12-31 21:20:21 +04:00
mMaxSliceTime = 0 ;
2014-01-08 05:33:47 +04:00
mTotalSliceTime = 0 ;
2013-11-21 02:35:16 +04:00
mAnyLockedOut = false ;
2014-01-01 23:00:35 +04:00
mExtraForgetSkippableCalls = 0 ;
2013-11-21 02:35:16 +04:00
}
2013-12-31 21:20:21 +04:00
void PrepareForCycleCollectionSlice ( int32_t aExtraForgetSkippableCalls = 0 ) ;
2013-12-31 21:20:21 +04:00
void FinishCycleCollectionSlice ( )
{
2014-03-05 04:21:48 +04:00
if ( mBeginSliceTime . IsNull ( ) ) {
// We already called this method from EndCycleCollectionCallback for this slice.
return ;
}
2014-03-06 22:54:37 +04:00
mEndSliceTime = TimeStamp : : Now ( ) ;
uint32_t sliceTime = TimeBetween ( mBeginSliceTime , mEndSliceTime ) ;
2013-12-31 21:20:21 +04:00
mMaxSliceTime = std : : max ( mMaxSliceTime , sliceTime ) ;
2014-01-08 05:33:47 +04:00
mTotalSliceTime + = sliceTime ;
2014-03-05 04:21:48 +04:00
mBeginSliceTime = TimeStamp ( ) ;
2014-01-01 23:00:35 +04:00
MOZ_ASSERT ( mExtraForgetSkippableCalls = = 0 , " Forget to reset extra forget skippable calls? " ) ;
2013-12-31 21:20:21 +04:00
}
2014-01-01 23:00:35 +04:00
void RunForgetSkippable ( ) ;
2013-11-21 02:35:16 +04:00
// Time the current slice began, including any GC finishing.
2013-12-31 21:20:21 +04:00
TimeStamp mBeginSliceTime ;
2013-11-21 02:35:16 +04:00
2014-03-06 22:54:37 +04:00
// Time the previous slice of the current CC ended.
TimeStamp mEndSliceTime ;
2013-11-21 02:35:16 +04:00
// Time the current cycle collection began.
2013-12-31 21:20:21 +04:00
TimeStamp mBeginTime ;
2013-11-21 02:35:16 +04:00
// The longest GC finishing duration for any slice of the current CC.
uint32_t mMaxGCDuration ;
// True if we ran sync forget skippable in any slice of the current CC.
bool mRanSyncForgetSkippable ;
// Number of suspected objects at the start of the current CC.
uint32_t mSuspected ;
// The longest duration spent on sync forget skippable in any slice of the
2013-12-31 21:20:21 +04:00
// current CC.
2013-11-21 02:35:16 +04:00
uint32_t mMaxSkippableDuration ;
2013-12-31 21:20:21 +04:00
// The longest pause of any slice in the current CC.
uint32_t mMaxSliceTime ;
2014-01-08 05:33:47 +04:00
// The total amount of time spent actually running the current CC.
uint32_t mTotalSliceTime ;
2013-11-21 02:35:16 +04:00
// True if we were locked out by the GC in any slice of the current CC.
bool mAnyLockedOut ;
2014-01-01 23:00:35 +04:00
int32_t mExtraForgetSkippableCalls ;
2013-11-21 02:35:16 +04:00
} ;
CycleCollectorStats gCCStats ;
2013-12-31 21:20:21 +04:00
void
CycleCollectorStats : : PrepareForCycleCollectionSlice ( int32_t aExtraForgetSkippableCalls )
2013-11-21 02:35:17 +04:00
{
2013-12-31 21:20:21 +04:00
mBeginSliceTime = TimeStamp : : Now ( ) ;
2011-02-17 02:47:12 +03:00
2013-01-01 00:55:07 +04:00
// Before we begin the cycle collection, make sure there is no active GC.
2013-11-21 02:35:16 +04:00
if ( sCCLockedOut ) {
2013-12-31 21:20:21 +04:00
mAnyLockedOut = true ;
2013-11-21 02:35:16 +04:00
FinishAnyIncrementalGC ( ) ;
2014-03-05 04:21:48 +04:00
uint32_t gcTime = TimeBetween ( mBeginSliceTime , TimeStamp : : Now ( ) ) ;
2013-12-31 21:20:21 +04:00
mMaxGCDuration = std : : max ( mMaxGCDuration , gcTime ) ;
2013-11-21 02:35:16 +04:00
}
2012-01-31 00:06:18 +04:00
2014-01-01 23:00:35 +04:00
mExtraForgetSkippableCalls = aExtraForgetSkippableCalls ;
}
void
CycleCollectorStats : : RunForgetSkippable ( )
{
2013-01-01 00:55:07 +04:00
// Run forgetSkippable synchronously to reduce the size of the CC graph. This
// is particularly useful if we recently finished a GC.
2014-01-01 23:00:35 +04:00
if ( mExtraForgetSkippableCalls > = 0 ) {
TimeStamp beginForgetSkippable = TimeStamp : : Now ( ) ;
2013-11-21 02:35:16 +04:00
bool ranSyncForgetSkippable = false ;
2013-07-27 14:48:45 +04:00
while ( sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS ) {
2012-07-15 14:30:39 +04:00
FireForgetSkippable ( nsCycleCollector_suspectedCount ( ) , false ) ;
2013-01-01 00:55:07 +04:00
ranSyncForgetSkippable = true ;
2012-05-03 20:17:01 +04:00
}
2012-01-31 00:06:18 +04:00
2014-01-01 23:00:35 +04:00
for ( int32_t i = 0 ; i < mExtraForgetSkippableCalls ; + + i ) {
2013-11-21 02:35:16 +04:00
FireForgetSkippable ( nsCycleCollector_suspectedCount ( ) , false ) ;
ranSyncForgetSkippable = true ;
}
if ( ranSyncForgetSkippable ) {
2013-12-31 21:20:21 +04:00
mMaxSkippableDuration =
2014-01-01 23:00:35 +04:00
std : : max ( mMaxSkippableDuration , TimeUntilNow ( beginForgetSkippable ) ) ;
2013-12-31 21:20:21 +04:00
mRanSyncForgetSkippable = true ;
2013-11-21 02:35:16 +04:00
}
2012-01-31 00:06:18 +04:00
}
2014-01-01 23:00:35 +04:00
mExtraForgetSkippableCalls = 0 ;
2013-11-21 02:35:17 +04:00
}
2012-05-03 20:17:01 +04:00
2013-11-21 02:35:17 +04:00
//static
void
nsJSContext : : CycleCollectNow ( nsICycleCollectorListener * aListener ,
int32_t aExtraForgetSkippableCalls )
{
if ( ! NS_IsMainThread ( ) ) {
return ;
}
PROFILER_LABEL ( " CC " , " CycleCollectNow " ) ;
2013-12-31 21:20:21 +04:00
gCCStats . PrepareForCycleCollectionSlice ( aExtraForgetSkippableCalls ) ;
2013-11-21 02:35:17 +04:00
nsCycleCollector_collect ( aListener ) ;
2013-12-31 21:20:21 +04:00
gCCStats . FinishCycleCollectionSlice ( ) ;
2013-11-21 02:35:17 +04:00
}
//static
void
2014-03-05 04:21:48 +04:00
nsJSContext : : RunCycleCollectorSlice ( )
2013-11-21 02:35:17 +04:00
{
if ( ! NS_IsMainThread ( ) ) {
return ;
}
2013-11-21 02:35:16 +04:00
2014-01-01 23:00:35 +04:00
PROFILER_LABEL ( " CC " , " RunCycleCollectorSlice " ) ;
2013-12-22 18:58:19 +04:00
2013-12-31 21:20:21 +04:00
gCCStats . PrepareForCycleCollectionSlice ( ) ;
2014-03-06 22:54:37 +04:00
// Decide how long we want to budget for this slice. By default,
// use an unlimited budget.
int64_t sliceBudget = - 1 ;
if ( sIncrementalCC ) {
if ( gCCStats . mBeginTime . IsNull ( ) ) {
// If no CC is in progress, use the standard slice time.
sliceBudget = kICCSliceBudget ;
} else {
TimeStamp now = TimeStamp : : Now ( ) ;
// Only run a limited slice if we're within the max running time.
if ( TimeBetween ( gCCStats . mBeginTime , now ) < kMaxICCDuration ) {
float sliceMultiplier = std : : max ( TimeBetween ( gCCStats . mEndSliceTime , now ) / ( float ) kICCIntersliceDelay , 1.0f ) ;
sliceBudget = kICCSliceBudget * sliceMultiplier ;
}
}
}
nsCycleCollector_collectSlice ( sliceBudget ) ;
2013-12-31 21:20:21 +04:00
gCCStats . FinishCycleCollectionSlice ( ) ;
2013-12-19 09:22:55 +04:00
}
2013-12-21 18:35:08 +04:00
static void
ICCTimerFired ( nsITimer * aTimer , void * aClosure )
{
if ( sDidShutdown ) {
return ;
}
// Ignore ICC timer fires during IGC. Running ICC during an IGC will cause us
// to synchronously finish the GC, which is bad.
if ( sCCLockedOut ) {
PRTime now = PR_Now ( ) ;
if ( sCCLockedOutTime = = 0 ) {
sCCLockedOutTime = now ;
return ;
}
if ( now - sCCLockedOutTime < NS_MAX_CC_LOCKEDOUT_TIME ) {
return ;
}
}
2014-03-05 04:21:48 +04:00
nsJSContext : : RunCycleCollectorSlice ( ) ;
2013-12-21 18:35:08 +04:00
}
2013-11-21 02:35:16 +04:00
//static
void
nsJSContext : : BeginCycleCollectionCallback ( )
{
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
2013-12-31 21:20:21 +04:00
gCCStats . mBeginTime = gCCStats . mBeginSliceTime . IsNull ( ) ? TimeStamp : : Now ( ) : gCCStats . mBeginSliceTime ;
2013-11-21 02:35:16 +04:00
gCCStats . mSuspected = nsCycleCollector_suspectedCount ( ) ;
KillCCTimer ( ) ;
2013-12-21 18:35:08 +04:00
2014-01-01 23:00:35 +04:00
gCCStats . RunForgetSkippable ( ) ;
2013-12-21 18:35:08 +04:00
MOZ_ASSERT ( ! sICCTimer , " Tried to create a new ICC timer when one already existed. " ) ;
if ( ! sIncrementalCC ) {
return ;
}
CallCreateInstance ( " @mozilla.org/timer;1 " , & sICCTimer ) ;
if ( sICCTimer ) {
sICCTimer - > InitWithFuncCallback ( ICCTimerFired ,
nullptr ,
kICCIntersliceDelay ,
nsITimer : : TYPE_REPEATING_SLACK ) ;
}
2013-11-21 02:35:16 +04:00
}
//static
void
nsJSContext : : EndCycleCollectionCallback ( CycleCollectorResults & aResults )
{
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
2012-06-27 19:10:09 +04:00
2013-12-21 18:35:08 +04:00
nsJSContext : : KillICCTimer ( ) ;
2014-03-05 04:21:48 +04:00
// Update timing information for the current slice before we log it, if
// we previously called PrepareForCycleCollectionSlice(). During shutdown
// CCs, this won't happen.
2013-12-31 21:20:21 +04:00
gCCStats . FinishCycleCollectionSlice ( ) ;
2013-11-21 02:35:16 +04:00
sCCollectedWaitingForGC + = aResults . mFreedRefCounted + aResults . mFreedGCed ;
2011-02-17 02:47:12 +03:00
2014-02-03 19:31:11 +04:00
if ( NeedsGCAfterCC ( ) ) {
2013-01-28 00:35:12 +04:00
PokeGC ( JS : : gcreason : : CC_WAITING ) ;
2010-11-07 22:07:59 +03:00
}
2014-02-18 18:58:40 +04:00
TimeStamp endCCTimeStamp = TimeStamp : : Now ( ) ;
PRTime endCCTime ;
if ( sPostGCEventsToObserver ) {
endCCTime = PR_Now ( ) ;
}
2013-01-01 00:55:07 +04:00
// Log information about the CC via telemetry, JSON and the console.
2014-02-18 18:58:40 +04:00
uint32_t ccNowDuration = TimeBetween ( gCCStats . mBeginTime , endCCTimeStamp ) ;
2013-11-21 02:35:16 +04:00
Telemetry : : Accumulate ( Telemetry : : CYCLE_COLLECTOR_FINISH_IGC , gCCStats . mAnyLockedOut ) ;
Telemetry : : Accumulate ( Telemetry : : CYCLE_COLLECTOR_SYNC_SKIPPABLE , gCCStats . mRanSyncForgetSkippable ) ;
2013-01-01 00:55:07 +04:00
Telemetry : : Accumulate ( Telemetry : : CYCLE_COLLECTOR_FULL , ccNowDuration ) ;
2013-12-31 21:20:21 +04:00
Telemetry : : Accumulate ( Telemetry : : CYCLE_COLLECTOR_MAX_PAUSE , gCCStats . mMaxSliceTime ) ;
2012-01-21 00:02:18 +04:00
2013-12-31 21:20:21 +04:00
if ( ! sLastCCEndTime . IsNull ( ) ) {
2013-11-21 02:35:16 +04:00
uint32_t timeBetween = TimeBetween ( sLastCCEndTime , gCCStats . mBeginTime ) ;
2012-01-21 00:02:18 +04:00
Telemetry : : Accumulate ( Telemetry : : CYCLE_COLLECTOR_TIME_BETWEEN , timeBetween ) ;
}
2014-02-18 18:58:40 +04:00
sLastCCEndTime = endCCTimeStamp ;
2012-01-21 00:02:18 +04:00
2012-02-11 03:30:20 +04:00
Telemetry : : Accumulate ( Telemetry : : FORGET_SKIPPABLE_MAX ,
sMaxForgetSkippableTime / PR_USEC_PER_MSEC ) ;
2012-08-22 22:28:34 +04:00
PRTime delta = GetCollectionTimeDelta ( ) ;
2011-11-10 01:32:17 +04:00
2012-08-22 19:56:38 +04:00
uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1 ;
2012-09-28 10:57:33 +04:00
uint32_t minForgetSkippableTime = ( sMinForgetSkippableTime = = UINT32_MAX )
2012-07-13 23:13:52 +04:00
? 0 : sMinForgetSkippableTime ;
2011-11-10 01:32:17 +04:00
2012-07-13 23:13:52 +04:00
if ( sPostGCEventsToConsole ) {
2012-06-27 19:10:09 +04:00
nsCString mergeMsg ;
2013-11-21 02:35:16 +04:00
if ( aResults . mMergedZones ) {
2012-06-27 19:10:09 +04:00
mergeMsg . AssignLiteral ( " merged " ) ;
}
2012-05-23 00:10:37 +04:00
nsCString gcMsg ;
2013-11-21 02:35:16 +04:00
if ( aResults . mForcedGC ) {
2012-05-23 00:10:37 +04:00
gcMsg . AssignLiteral ( " , forced a GC " ) ;
2012-02-24 08:16:37 +04:00
}
2012-01-31 00:06:18 +04:00
NS_NAMED_MULTILINE_LITERAL_STRING ( kFmt ,
2013-12-31 21:20:21 +04:00
MOZ_UTF16 ( " CC(T+%.1f) max pause: %lums, total time: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s \n " )
2013-11-21 02:35:16 +04:00
MOZ_UTF16 ( " ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, max sync: %lu ms, removed: %lu " ) ) ;
2011-02-17 02:47:12 +03:00
nsString msg ;
2011-11-10 01:32:17 +04:00
msg . Adopt ( nsTextFormatter : : smprintf ( kFmt . get ( ) , double ( delta ) / PR_USEC_PER_SEC ,
2014-01-08 05:33:47 +04:00
gCCStats . mMaxSliceTime , gCCStats . mTotalSliceTime ,
gCCStats . mSuspected ,
2013-11-21 02:35:16 +04:00
aResults . mVisitedRefCounted , aResults . mVisitedGCed , mergeMsg . get ( ) ,
aResults . mFreedRefCounted , aResults . mFreedGCed ,
2013-03-07 22:53:19 +04:00
sCCollectedWaitingForGC , sLikelyShortLivingObjectsNeedingGC ,
gcMsg . get ( ) ,
2012-01-31 00:06:18 +04:00
sForgetSkippableBeforeCC ,
2012-07-13 23:13:52 +04:00
minForgetSkippableTime / PR_USEC_PER_MSEC ,
2012-01-31 00:06:18 +04:00
sMaxForgetSkippableTime / PR_USEC_PER_MSEC ,
( sTotalForgetSkippableTime / cleanups ) /
PR_USEC_PER_MSEC ,
sTotalForgetSkippableTime / PR_USEC_PER_MSEC ,
2013-11-21 02:35:16 +04:00
gCCStats . mMaxSkippableDuration , sRemovedPurples ) ) ;
2011-02-17 02:47:12 +03:00
nsCOMPtr < nsIConsoleService > cs =
do_GetService ( NS_CONSOLESERVICE_CONTRACTID ) ;
if ( cs ) {
cs - > LogStringMessage ( msg . get ( ) ) ;
}
2012-07-13 23:13:52 +04:00
}
2012-03-06 03:33:24 +04:00
2012-10-02 23:27:31 +04:00
if ( sPostGCEventsToObserver ) {
2012-03-06 03:33:24 +04:00
NS_NAMED_MULTILINE_LITERAL_STRING ( kJSONFmt ,
2013-09-18 07:43:21 +04:00
MOZ_UTF16 ( " { \" timestamp \" : %llu, " )
2014-02-17 16:16:23 +04:00
MOZ_UTF16 ( " \" duration \" : %lu, " )
MOZ_UTF16 ( " \" max_slice_pause \" : %lu, " )
MOZ_UTF16 ( " \" total_slice_pause \" : %lu, " )
MOZ_UTF16 ( " \" max_finish_gc_duration \" : %lu, " )
MOZ_UTF16 ( " \" max_sync_skippable_duration \" : %lu, " )
2013-09-18 07:43:21 +04:00
MOZ_UTF16 ( " \" suspected \" : %lu, " )
MOZ_UTF16 ( " \" visited \" : { " )
MOZ_UTF16 ( " \" RCed \" : %lu, " )
MOZ_UTF16 ( " \" GCed \" : %lu }, " )
MOZ_UTF16 ( " \" collected \" : { " )
MOZ_UTF16 ( " \" RCed \" : %lu, " )
MOZ_UTF16 ( " \" GCed \" : %lu }, " )
MOZ_UTF16 ( " \" waiting_for_gc \" : %lu, " )
MOZ_UTF16 ( " \" short_living_objects_waiting_for_gc \" : %lu, " )
MOZ_UTF16 ( " \" forced_gc \" : %d, " )
MOZ_UTF16 ( " \" forget_skippable \" : { " )
MOZ_UTF16 ( " \" times_before_cc \" : %lu, " )
MOZ_UTF16 ( " \" min \" : %lu, " )
MOZ_UTF16 ( " \" max \" : %lu, " )
MOZ_UTF16 ( " \" avg \" : %lu, " )
MOZ_UTF16 ( " \" total \" : %lu, " )
MOZ_UTF16 ( " \" removed \" : %lu } " )
MOZ_UTF16 ( " } " ) ) ;
2012-03-06 03:33:24 +04:00
nsString json ;
2013-12-31 21:20:21 +04:00
json . Adopt ( nsTextFormatter : : smprintf ( kJSONFmt . get ( ) , endCCTime , ccNowDuration ,
2014-01-08 05:33:47 +04:00
gCCStats . mMaxSliceTime ,
gCCStats . mTotalSliceTime ,
gCCStats . mMaxGCDuration ,
2013-11-21 02:35:16 +04:00
gCCStats . mMaxSkippableDuration ,
gCCStats . mSuspected ,
2013-11-21 02:35:16 +04:00
aResults . mVisitedRefCounted , aResults . mVisitedGCed ,
aResults . mFreedRefCounted , aResults . mFreedGCed ,
2012-03-17 03:36:26 +04:00
sCCollectedWaitingForGC ,
2013-03-07 22:53:19 +04:00
sLikelyShortLivingObjectsNeedingGC ,
2013-11-21 02:35:16 +04:00
aResults . mForcedGC ,
2012-03-17 03:36:26 +04:00
sForgetSkippableBeforeCC ,
2012-07-13 23:13:52 +04:00
minForgetSkippableTime / PR_USEC_PER_MSEC ,
2012-03-17 03:36:26 +04:00
sMaxForgetSkippableTime / PR_USEC_PER_MSEC ,
( sTotalForgetSkippableTime / cleanups ) /
PR_USEC_PER_MSEC ,
sTotalForgetSkippableTime / PR_USEC_PER_MSEC ,
sRemovedPurples ) ) ;
2012-03-06 03:33:24 +04:00
nsCOMPtr < nsIObserverService > observerService = mozilla : : services : : GetObserverService ( ) ;
if ( observerService ) {
2012-07-30 18:20:58 +04:00
observerService - > NotifyObservers ( nullptr , " cycle-collection-statistics " , json . get ( ) ) ;
2012-03-06 03:33:24 +04:00
}
2009-07-08 19:08:22 +04:00
}
2013-01-01 00:55:07 +04:00
// Update global state to indicate we have just run a cycle collection.
2012-09-28 10:57:33 +04:00
sMinForgetSkippableTime = UINT32_MAX ;
2012-01-31 00:06:18 +04:00
sMaxForgetSkippableTime = 0 ;
sTotalForgetSkippableTime = 0 ;
sRemovedPurples = 0 ;
sForgetSkippableBeforeCC = 0 ;
2012-02-27 18:49:59 +04:00
sNeedsFullCC = false ;
2013-08-22 01:02:12 +04:00
sNeedsGCAfterCC = false ;
2013-11-21 02:35:16 +04:00
gCCStats . Clear ( ) ;
2009-07-08 19:08:22 +04:00
}
2012-08-01 05:39:39 +04:00
// static
void
InterSliceGCTimerFired ( nsITimer * aTimer , void * aClosure )
{
NS_RELEASE ( sInterSliceGCTimer ) ;
2013-01-28 00:35:12 +04:00
nsJSContext : : GarbageCollectNow ( JS : : gcreason : : INTER_SLICE_GC ,
2012-08-01 05:39:39 +04:00
nsJSContext : : IncrementalGC ,
nsJSContext : : CompartmentGC ,
nsJSContext : : NonShrinkingGC ,
NS_INTERSLICE_GC_BUDGET ) ;
}
2009-02-12 15:06:59 +03:00
// static
void
GCTimerFired ( nsITimer * aTimer , void * aClosure )
2001-11-27 12:46:38 +03:00
{
2012-08-01 05:39:39 +04:00
NS_RELEASE ( sGCTimer ) ;
2007-01-11 03:02:58 +03:00
2012-01-25 22:59:55 +04:00
uintptr_t reason = reinterpret_cast < uintptr_t > ( aClosure ) ;
2013-01-28 00:35:12 +04:00
nsJSContext : : GarbageCollectNow ( static_cast < JS : : gcreason : : Reason > ( reason ) ,
2012-07-01 01:16:32 +04:00
nsJSContext : : IncrementalGC ,
nsJSContext : : CompartmentGC ) ;
2011-02-17 02:47:12 +03:00
}
2007-01-26 04:19:31 +03:00
2011-12-27 15:59:29 +04:00
void
ShrinkGCBuffersTimerFired ( nsITimer * aTimer , void * aClosure )
{
NS_RELEASE ( sShrinkGCBuffersTimer ) ;
nsJSContext : : ShrinkGCBuffersNow ( ) ;
}
2012-03-06 01:48:33 +04:00
static bool
2012-08-22 19:56:38 +04:00
ShouldTriggerCC ( uint32_t aSuspected )
2011-02-17 02:47:12 +03:00
{
2012-03-06 01:48:33 +04:00
return sNeedsFullCC | |
aSuspected > NS_CC_PURPLE_LIMIT | |
2012-07-15 14:30:39 +04:00
( aSuspected > NS_CC_FORCED_PURPLE_LIMIT & &
2013-12-31 21:20:21 +04:00
TimeUntilNow ( sLastCCEndTime ) > NS_CC_FORCED ) ;
2012-03-06 01:48:33 +04:00
}
2013-12-22 18:58:20 +04:00
static uint32_t
TimeToNextCC ( )
{
if ( sIncrementalCC ) {
return NS_CC_DELAY - kMaxICCDuration ;
}
return NS_CC_DELAY ;
}
static_assert ( NS_CC_DELAY > kMaxICCDuration , " ICC shouldn't reduce CC delay to 0 " ) ;
2012-03-06 01:48:33 +04:00
static void
CCTimerFired ( nsITimer * aTimer , void * aClosure )
{
2012-03-09 03:37:13 +04:00
if ( sDidShutdown ) {
2012-02-18 02:35:20 +04:00
return ;
}
2012-03-09 03:37:13 +04:00
2012-08-22 19:56:38 +04:00
static uint32_t ccDelay = NS_CC_DELAY ;
2012-03-09 03:37:13 +04:00
if ( sCCLockedOut ) {
2013-12-22 18:58:20 +04:00
ccDelay = TimeToNextCC ( ) / 3 ;
2012-07-16 01:37:09 +04:00
2012-03-09 03:37:13 +04:00
PRTime now = PR_Now ( ) ;
if ( sCCLockedOutTime = = 0 ) {
2013-01-08 15:11:01 +04:00
// Reset sCCTimerFireCount so that we run forgetSkippable
// often enough before CC. Because of reduced ccDelay
// forgetSkippable will be called just a few times.
// NS_MAX_CC_LOCKEDOUT_TIME limit guarantees that we end up calling
// forgetSkippable and CycleCollectNow eventually.
sCCTimerFireCount = 0 ;
2012-03-09 03:37:13 +04:00
sCCLockedOutTime = now ;
return ;
}
if ( now - sCCLockedOutTime < NS_MAX_CC_LOCKEDOUT_TIME ) {
return ;
}
}
2012-01-31 00:06:18 +04:00
+ + sCCTimerFireCount ;
2012-03-06 01:48:33 +04:00
// During early timer fires, we only run forgetSkippable. During the first
// late timer fire, we decide if we are going to have a second and final
2014-03-05 04:21:48 +04:00
// late timer fire, where we may begin to run the CC. Should run at least one
// early timer fire to allow cleanup before the CC.
int32_t numEarlyTimerFires = std : : max ( ( int32_t ) ccDelay / NS_CC_SKIPPABLE_DELAY - 2 , 1 ) ;
2012-03-06 01:48:33 +04:00
bool isLateTimerFire = sCCTimerFireCount > numEarlyTimerFires ;
2012-08-22 19:56:38 +04:00
uint32_t suspected = nsCycleCollector_suspectedCount ( ) ;
2012-03-06 01:48:33 +04:00
if ( isLateTimerFire & & ShouldTriggerCC ( suspected ) ) {
if ( sCCTimerFireCount = = numEarlyTimerFires + 1 ) {
2012-07-15 14:30:39 +04:00
FireForgetSkippable ( suspected , true ) ;
2012-03-06 01:48:33 +04:00
if ( ShouldTriggerCC ( nsCycleCollector_suspectedCount ( ) ) ) {
// Our efforts to avoid a CC have failed, so we return to let the
// timer fire once more to trigger a CC.
return ;
}
} else {
// We are in the final timer fire and still meet the conditions for
2014-01-01 23:00:35 +04:00
// triggering a CC. Let RunCycleCollectorSlice finish the current IGC, if
// any because that will allow us to include the GC time in the CC pause.
2014-03-05 04:21:48 +04:00
nsJSContext : : RunCycleCollectorSlice ( ) ;
2012-01-31 00:06:18 +04:00
}
2012-03-06 01:48:33 +04:00
} else if ( ( sPreviousSuspectedCount + 100 ) < = suspected ) {
2013-01-01 00:54:37 +04:00
// Only do a forget skippable if there are more than a few new objects.
FireForgetSkippable ( suspected , false ) ;
2012-03-06 01:48:33 +04:00
}
if ( isLateTimerFire ) {
2013-12-22 18:58:20 +04:00
ccDelay = TimeToNextCC ( ) ;
2012-07-16 01:37:09 +04:00
2012-03-06 01:48:33 +04:00
// We have either just run the CC or decided we don't want to run the CC
// next time, so kill the timer.
sPreviousSuspectedCount = 0 ;
nsJSContext : : KillCCTimer ( ) ;
2012-01-31 00:06:18 +04:00
}
}
2001-11-27 12:46:38 +03:00
2012-01-31 00:06:18 +04:00
// static
2012-08-22 19:56:38 +04:00
uint32_t
2012-05-03 20:17:01 +04:00
nsJSContext : : CleanupsSinceLastGC ( )
2012-01-31 00:06:18 +04:00
{
2012-05-03 20:17:01 +04:00
return sCleanupsSinceLastGC ;
2001-11-27 12:46:38 +03:00
}
1998-07-16 05:16:47 +04:00
2007-01-11 03:02:58 +03:00
// static
2001-11-27 12:46:38 +03:00
void
2007-01-11 03:02:58 +03:00
nsJSContext : : LoadStart ( )
{
2011-10-17 18:59:28 +04:00
sLoadingInProgress = true ;
2007-01-11 03:02:58 +03:00
+ + sPendingLoadCount ;
}
// static
void
2007-10-21 20:46:54 +04:00
nsJSContext : : LoadEnd ( )
2007-01-11 03:02:58 +03:00
{
2011-02-17 02:47:12 +03:00
if ( ! sLoadingInProgress )
return ;
2007-01-11 03:02:58 +03:00
// sPendingLoadCount is not a well managed load counter (and doesn't
// need to be), so make sure we don't make it wrap backwards here.
if ( sPendingLoadCount > 0 ) {
- - sPendingLoadCount ;
2011-02-17 02:47:12 +03:00
return ;
2007-01-11 03:02:58 +03:00
}
2011-02-17 02:47:12 +03:00
// Its probably a good idea to GC soon since we have finished loading.
2011-10-17 18:59:28 +04:00
sLoadingInProgress = false ;
2013-01-28 00:35:12 +04:00
PokeGC ( JS : : gcreason : : LOAD_END ) ;
2007-01-11 03:02:58 +03:00
}
2009-02-12 15:06:59 +03:00
// static
2007-01-11 03:02:58 +03:00
void
2013-01-28 00:35:12 +04:00
nsJSContext : : PokeGC ( JS : : gcreason : : Reason aReason , int aDelay )
1998-07-16 05:16:47 +04:00
{
2013-09-13 03:07:02 +04:00
if ( sGCTimer | | sInterSliceGCTimer | | sShuttingDown ) {
2005-12-06 08:48:46 +03:00
// There's already a timer for GC'ing, just return
2001-11-27 12:46:38 +03:00
return ;
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
}
2001-11-27 12:46:38 +03:00
2013-08-22 01:02:12 +04:00
if ( sCCTimer ) {
// Make sure CC is called...
sNeedsFullCC = true ;
// and GC after it.
sNeedsGCAfterCC = true ;
return ;
}
2014-03-05 04:21:48 +04:00
if ( sICCTimer ) {
// Make sure GC is called after the current CC completes.
// No need to set sNeedsFullCC because we are currently running a CC.
sNeedsGCAfterCC = true ;
return ;
}
2004-11-01 21:50:36 +03:00
CallCreateInstance ( " @mozilla.org/timer;1 " , & sGCTimer ) ;
2001-11-27 12:46:38 +03:00
if ( ! sGCTimer ) {
2011-05-28 03:53:01 +04:00
// Failed to create timer (probably because we're in XPCOM shutdown)
2001-11-27 12:46:38 +03:00
return ;
}
2011-09-29 10:19:26 +04:00
static bool first = true ;
2001-11-27 12:46:38 +03:00
2012-01-25 22:59:55 +04:00
sGCTimer - > InitWithFuncCallback ( GCTimerFired , reinterpret_cast < void * > ( aReason ) ,
2012-02-18 02:35:20 +04:00
aDelay
? aDelay
: ( first
? NS_FIRST_GC_DELAY
: NS_GC_DELAY ) ,
2009-02-12 15:06:59 +03:00
nsITimer : : TYPE_ONE_SHOT ) ;
2001-11-27 12:46:38 +03:00
2011-10-17 18:59:28 +04:00
first = false ;
1998-07-16 05:16:47 +04:00
}
2011-12-27 15:59:29 +04:00
// static
void
nsJSContext : : PokeShrinkGCBuffers ( )
{
2013-01-22 23:17:48 +04:00
if ( sShrinkGCBuffersTimer | | sShuttingDown ) {
2011-12-27 15:59:29 +04:00
return ;
}
CallCreateInstance ( " @mozilla.org/timer;1 " , & sShrinkGCBuffersTimer ) ;
if ( ! sShrinkGCBuffersTimer ) {
// Failed to create timer (probably because we're in XPCOM shutdown)
return ;
}
2012-07-30 18:20:58 +04:00
sShrinkGCBuffersTimer - > InitWithFuncCallback ( ShrinkGCBuffersTimerFired , nullptr ,
2011-12-27 15:59:29 +04:00
NS_SHRINK_GC_BUFFERS_DELAY ,
nsITimer : : TYPE_ONE_SHOT ) ;
}
2011-02-17 02:47:12 +03:00
// static
void
nsJSContext : : MaybePokeCC ( )
{
2013-12-21 18:35:08 +04:00
if ( sCCTimer | | sICCTimer | | sShuttingDown | | ! sHasRunGC ) {
2011-02-17 02:47:12 +03:00
return ;
}
2012-07-15 14:30:39 +04:00
if ( ShouldTriggerCC ( nsCycleCollector_suspectedCount ( ) ) ) {
2012-01-31 00:06:18 +04:00
sCCTimerFireCount = 0 ;
CallCreateInstance ( " @mozilla.org/timer;1 " , & sCCTimer ) ;
if ( ! sCCTimer ) {
return ;
}
2013-07-09 21:30:58 +04:00
// We can kill some objects before running forgetSkippable.
nsCycleCollector_dispatchDeferredDeletion ( ) ;
2012-07-30 18:20:58 +04:00
sCCTimer - > InitWithFuncCallback ( CCTimerFired , nullptr ,
2012-01-31 00:06:18 +04:00
NS_CC_SKIPPABLE_DELAY ,
nsITimer : : TYPE_REPEATING_SLACK ) ;
2011-02-17 02:47:12 +03:00
}
}
//static
void
nsJSContext : : KillGCTimer ( )
{
if ( sGCTimer ) {
sGCTimer - > Cancel ( ) ;
NS_RELEASE ( sGCTimer ) ;
}
}
2012-05-09 22:53:23 +04:00
void
nsJSContext : : KillFullGCTimer ( )
{
if ( sFullGCTimer ) {
sFullGCTimer - > Cancel ( ) ;
NS_RELEASE ( sFullGCTimer ) ;
}
}
2012-06-11 08:27:59 +04:00
void
nsJSContext : : KillInterSliceGCTimer ( )
{
if ( sInterSliceGCTimer ) {
sInterSliceGCTimer - > Cancel ( ) ;
NS_RELEASE ( sInterSliceGCTimer ) ;
}
}
2011-12-27 15:59:29 +04:00
//static
void
nsJSContext : : KillShrinkGCBuffersTimer ( )
{
if ( sShrinkGCBuffersTimer ) {
sShrinkGCBuffersTimer - > Cancel ( ) ;
NS_RELEASE ( sShrinkGCBuffersTimer ) ;
}
}
2011-02-17 02:47:12 +03:00
//static
void
nsJSContext : : KillCCTimer ( )
{
2012-03-09 03:37:13 +04:00
sCCLockedOutTime = 0 ;
2011-02-17 02:47:12 +03:00
if ( sCCTimer ) {
sCCTimer - > Cancel ( ) ;
NS_RELEASE ( sCCTimer ) ;
}
}
2013-12-21 18:35:08 +04:00
//static
void
nsJSContext : : KillICCTimer ( )
{
sCCLockedOutTime = 0 ;
if ( sICCTimer ) {
sICCTimer - > Cancel ( ) ;
NS_RELEASE ( sICCTimer ) ;
}
}
2011-02-17 02:47:12 +03:00
void
2013-01-28 00:35:12 +04:00
nsJSContext : : GC ( JS : : gcreason : : Reason aReason )
2011-02-17 02:47:12 +03:00
{
2012-01-25 22:59:55 +04:00
PokeGC ( aReason ) ;
2011-02-17 02:47:12 +03:00
}
2012-03-06 03:33:24 +04:00
class NotifyGCEndRunnable : public nsRunnable
{
nsString mMessage ;
public :
NotifyGCEndRunnable ( const nsString & aMessage ) : mMessage ( aMessage ) { }
NS_DECL_NSIRUNNABLE
} ;
NS_IMETHODIMP
NotifyGCEndRunnable : : Run ( )
{
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
nsCOMPtr < nsIObserverService > observerService = mozilla : : services : : GetObserverService ( ) ;
if ( ! observerService ) {
return NS_OK ;
}
const jschar oomMsg [ 3 ] = { ' { ' , ' } ' , 0 } ;
const jschar * toSend = mMessage . get ( ) ? mMessage . get ( ) : oomMsg ;
2012-07-30 18:20:58 +04:00
observerService - > NotifyObservers ( nullptr , " garbage-collection-statistics " , toSend ) ;
2012-03-06 03:33:24 +04:00
return NS_OK ;
}
2012-02-03 18:01:35 +04:00
static void
2013-01-28 00:35:12 +04:00
DOMGCSliceCallback ( JSRuntime * aRt , JS : : GCProgress aProgress , const JS : : GCDescription & aDesc )
2011-11-10 01:32:17 +04:00
{
NS_ASSERTION ( NS_IsMainThread ( ) , " GCs must run on the main thread " ) ;
2011-02-17 02:47:12 +03:00
2013-01-28 00:35:12 +04:00
if ( aProgress = = JS : : GC_CYCLE_END ) {
2012-08-22 22:28:34 +04:00
PRTime delta = GetCollectionTimeDelta ( ) ;
2011-02-20 09:59:49 +03:00
2012-07-13 23:13:52 +04:00
if ( sPostGCEventsToConsole ) {
NS_NAMED_LITERAL_STRING ( kFmt , " GC(T+%.1f) " ) ;
nsString prefix , gcstats ;
gcstats . Adopt ( aDesc . formatMessage ( aRt ) ) ;
prefix . Adopt ( nsTextFormatter : : smprintf ( kFmt . get ( ) ,
double ( delta ) / PR_USEC_PER_SEC ) ) ;
nsString msg = prefix + gcstats ;
nsCOMPtr < nsIConsoleService > cs = do_GetService ( NS_CONSOLESERVICE_CONTRACTID ) ;
if ( cs ) {
cs - > LogStringMessage ( msg . get ( ) ) ;
}
2011-02-20 09:59:49 +03:00
}
2012-03-17 03:36:26 +04:00
2012-10-02 23:27:31 +04:00
if ( sPostGCEventsToObserver ) {
2012-07-13 23:13:52 +04:00
nsString json ;
2012-08-22 22:28:34 +04:00
json . Adopt ( aDesc . formatJSON ( aRt , PR_Now ( ) ) ) ;
2012-07-13 23:13:52 +04:00
nsRefPtr < NotifyGCEndRunnable > notify = new NotifyGCEndRunnable ( json ) ;
NS_DispatchToMainThread ( notify ) ;
}
2011-02-17 02:47:12 +03:00
}
2012-03-09 03:37:13 +04:00
// Prevent cycle collections and shrinking during incremental GC.
2013-01-28 00:35:12 +04:00
if ( aProgress = = JS : : GC_CYCLE_BEGIN ) {
2012-02-18 02:35:20 +04:00
sCCLockedOut = true ;
2012-03-09 03:37:13 +04:00
nsJSContext : : KillShrinkGCBuffersTimer ( ) ;
2013-01-28 00:35:12 +04:00
} else if ( aProgress = = JS : : GC_CYCLE_END ) {
2012-02-18 02:35:20 +04:00
sCCLockedOut = false ;
}
2012-01-31 00:06:18 +04:00
2012-02-18 02:35:20 +04:00
// The GC has more work to do, so schedule another GC slice.
2013-01-28 00:35:12 +04:00
if ( aProgress = = JS : : GC_SLICE_END ) {
2012-06-11 08:27:59 +04:00
nsJSContext : : KillInterSliceGCTimer ( ) ;
2013-01-22 23:17:48 +04:00
if ( ! sShuttingDown ) {
CallCreateInstance ( " @mozilla.org/timer;1 " , & sInterSliceGCTimer ) ;
sInterSliceGCTimer - > InitWithFuncCallback ( InterSliceGCTimerFired ,
2013-10-28 18:04:12 +04:00
nullptr ,
2013-01-22 23:17:48 +04:00
NS_INTERSLICE_GC_DELAY ,
nsITimer : : TYPE_ONE_SHOT ) ;
}
2012-02-18 02:35:20 +04:00
}
2013-01-28 00:35:12 +04:00
if ( aProgress = = JS : : GC_CYCLE_END ) {
2012-03-09 03:37:13 +04:00
// May need to kill the inter-slice GC timer
2012-06-11 08:27:59 +04:00
nsJSContext : : KillInterSliceGCTimer ( ) ;
2012-03-09 03:37:13 +04:00
2012-02-18 02:35:20 +04:00
sCCollectedWaitingForGC = 0 ;
2013-03-07 22:53:19 +04:00
sLikelyShortLivingObjectsNeedingGC = 0 ;
2012-05-03 20:17:01 +04:00
sCleanupsSinceLastGC = 0 ;
2012-03-09 03:37:13 +04:00
sNeedsFullCC = true ;
2013-01-31 02:46:37 +04:00
sHasRunGC = true ;
2012-03-09 03:37:13 +04:00
nsJSContext : : MaybePokeCC ( ) ;
2013-02-18 10:56:32 +04:00
if ( aDesc . isCompartment_ ) {
2013-01-22 23:17:48 +04:00
if ( ! sFullGCTimer & & ! sShuttingDown ) {
2012-05-09 22:53:23 +04:00
CallCreateInstance ( " @mozilla.org/timer;1 " , & sFullGCTimer ) ;
2013-01-28 00:35:12 +04:00
JS : : gcreason : : Reason reason = JS : : gcreason : : FULL_GC_TIMER ;
2012-05-09 22:53:23 +04:00
sFullGCTimer - > InitWithFuncCallback ( FullGCTimerFired ,
reinterpret_cast < void * > ( reason ) ,
NS_FULL_GC_DELAY ,
nsITimer : : TYPE_ONE_SHOT ) ;
}
} else {
nsJSContext : : KillFullGCTimer ( ) ;
2012-03-09 03:37:13 +04:00
// Avoid shrinking during heavy activity, which is suggested by
// compartment GC.
2012-02-18 02:35:20 +04:00
nsJSContext : : PokeShrinkGCBuffers ( ) ;
2011-11-10 01:32:17 +04:00
}
}
2005-04-26 05:23:53 +04:00
2013-07-27 14:48:45 +04:00
if ( ( aProgress = = JS : : GC_SLICE_END | | aProgress = = JS : : GC_CYCLE_END ) & &
ShouldTriggerCC ( nsCycleCollector_suspectedCount ( ) ) ) {
nsCycleCollector_dispatchDeferredDeletion ( ) ;
}
2012-02-18 02:35:20 +04:00
if ( sPrevGCSliceCallback )
( * sPrevGCSliceCallback ) ( aRt , aProgress , aDesc ) ;
2000-05-15 08:21:04 +04:00
}
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
2008-03-20 03:42:47 +03:00
void
2009-05-20 06:11:01 +04:00
nsJSContext : : ReportPendingException ( )
2008-03-20 03:42:47 +03:00
{
2012-11-09 19:43:57 +04:00
if ( mIsInitialized ) {
nsJSUtils : : ReportPendingException ( mContext ) ;
2008-12-13 04:46:43 +03:00
}
2008-03-20 03:42:47 +03:00
}
2013-09-05 01:06:55 +04:00
void
nsJSContext : : SetWindowProxy ( JS : : Handle < JSObject * > aWindowProxy )
{
2013-09-05 01:06:56 +04:00
mWindowProxy = aWindowProxy ;
2013-09-05 01:06:55 +04:00
}
JSObject *
nsJSContext : : GetWindowProxy ( )
{
2013-09-09 07:28:48 +04:00
JSObject * windowProxy = GetWindowProxyPreserveColor ( ) ;
if ( windowProxy ) {
JS : : ExposeObjectToActiveJS ( windowProxy ) ;
}
return windowProxy ;
2013-09-05 01:06:55 +04:00
}
JSObject *
nsJSContext : : GetWindowProxyPreserveColor ( )
{
2013-09-05 01:06:56 +04:00
return mWindowProxy ;
2013-09-05 01:06:55 +04:00
}
2013-03-07 22:53:19 +04:00
void
nsJSContext : : LikelyShortLivingObjectCreated ( )
{
+ + sLikelyShortLivingObjectsNeedingGC ;
}
2004-06-09 22:36:25 +04:00
void
2013-08-20 03:24:29 +04:00
mozilla : : dom : : StartupJSEnvironment ( )
2004-06-09 22:36:25 +04:00
{
// initialize all our statics, so that we can restart XPCOM
2013-12-21 18:35:08 +04:00
sGCTimer = sFullGCTimer = sCCTimer = sICCTimer = nullptr ;
2012-02-18 02:35:20 +04:00
sCCLockedOut = false ;
2012-03-09 03:37:13 +04:00
sCCLockedOutTime = 0 ;
2013-12-31 21:20:21 +04:00
sLastCCEndTime = TimeStamp ( ) ;
2013-01-31 02:46:37 +04:00
sHasRunGC = false ;
2007-01-11 03:02:58 +03:00
sPendingLoadCount = 0 ;
2011-10-17 18:59:28 +04:00
sLoadingInProgress = false ;
2011-03-01 01:44:22 +03:00
sCCollectedWaitingForGC = 0 ;
2013-03-07 22:53:19 +04:00
sLikelyShortLivingObjectsNeedingGC = 0 ;
2011-10-17 18:59:28 +04:00
sPostGCEventsToConsole = false ;
2012-02-27 18:49:59 +04:00
sNeedsFullCC = false ;
2013-08-22 01:02:12 +04:00
sNeedsGCAfterCC = false ;
2012-07-30 18:20:58 +04:00
gNameSpaceManager = nullptr ;
sRuntimeService = nullptr ;
sRuntime = nullptr ;
2011-10-17 18:59:28 +04:00
sIsInitialized = false ;
sDidShutdown = false ;
2013-01-22 23:17:48 +04:00
sShuttingDown = false ;
2004-06-09 22:36:25 +04:00
sContextCount = 0 ;
2012-07-30 18:20:58 +04:00
sSecurityManager = nullptr ;
2013-11-21 02:35:16 +04:00
gCCStats . Clear ( ) ;
2004-06-09 22:36:25 +04:00
}
2013-12-11 03:10:01 +04:00
static void
2008-04-10 21:35:56 +04:00
ReportAllJSExceptionsPrefChangedCallback ( const char * aPrefName , void * aClosure )
{
2011-09-29 10:19:26 +04:00
bool reportAll = Preferences : : GetBool ( aPrefName , false ) ;
2008-04-10 21:35:56 +04:00
nsContentUtils : : XPConnect ( ) - > SetReportAllJSExceptions ( reportAll ) ;
}
2013-12-11 03:10:01 +04:00
static void
2009-07-09 16:16:26 +04:00
SetMemoryHighWaterMarkPrefChangedCallback ( const char * aPrefName , void * aClosure )
{
2012-08-22 19:56:38 +04:00
int32_t highwatermark = Preferences : : GetInt ( aPrefName , 128 ) ;
2010-12-03 01:38:00 +03:00
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , JSGC_MAX_MALLOC_BYTES ,
2010-12-03 01:38:00 +03:00
highwatermark * 1024L * 1024L ) ;
}
2013-12-11 03:10:01 +04:00
static void
2010-12-03 01:38:00 +03:00
SetMemoryMaxPrefChangedCallback ( const char * aPrefName , void * aClosure )
{
2012-08-22 19:56:38 +04:00
int32_t pref = Preferences : : GetInt ( aPrefName , - 1 ) ;
2011-01-12 20:35:36 +03:00
// handle overflow and negative pref values
2012-08-22 19:56:38 +04:00
uint32_t max = ( pref < = 0 | | pref > = 0x1000 ) ? - 1 : ( uint32_t ) pref * 1024 * 1024 ;
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , JSGC_MAX_BYTES , max ) ;
2009-07-09 16:16:26 +04:00
}
2013-12-11 03:10:01 +04:00
static void
2011-01-10 09:57:21 +03:00
SetMemoryGCModePrefChangedCallback ( const char * aPrefName , void * aClosure )
{
2012-04-04 13:15:10 +04:00
bool enableCompartmentGC = Preferences : : GetBool ( " javascript.options.mem.gc_per_compartment " ) ;
bool enableIncrementalGC = Preferences : : GetBool ( " javascript.options.mem.gc_incremental " ) ;
2012-02-18 02:35:20 +04:00
JSGCMode mode ;
if ( enableIncrementalGC ) {
mode = JSGC_MODE_INCREMENTAL ;
} else if ( enableCompartmentGC ) {
mode = JSGC_MODE_COMPARTMENT ;
} else {
mode = JSGC_MODE_GLOBAL ;
}
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , JSGC_MODE , mode ) ;
2012-02-18 02:35:20 +04:00
}
2013-12-11 03:10:01 +04:00
static void
2012-02-18 02:35:20 +04:00
SetMemoryGCSliceTimePrefChangedCallback ( const char * aPrefName , void * aClosure )
{
2012-08-22 19:56:38 +04:00
int32_t pref = Preferences : : GetInt ( aPrefName , - 1 ) ;
2012-02-18 02:35:20 +04:00
// handle overflow and negative pref values
if ( pref > 0 & & pref < 100000 )
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , JSGC_SLICE_TIME_BUDGET , pref ) ;
2011-01-10 09:57:21 +03:00
}
2013-12-11 03:10:01 +04:00
static void
2012-07-11 22:09:53 +04:00
SetMemoryGCPrefChangedCallback ( const char * aPrefName , void * aClosure )
{
2012-08-22 19:56:38 +04:00
int32_t pref = Preferences : : GetInt ( aPrefName , - 1 ) ;
2012-07-11 22:09:53 +04:00
// handle overflow and negative pref values
2013-06-27 10:40:17 +04:00
if ( pref > = 0 & & pref < 10000 )
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , ( JSGCParamKey ) ( intptr_t ) aClosure , pref ) ;
2012-07-11 22:09:53 +04:00
}
2013-12-11 03:10:01 +04:00
static void
2012-07-11 22:09:53 +04:00
SetMemoryGCDynamicHeapGrowthPrefChangedCallback ( const char * aPrefName , void * aClosure )
{
bool pref = Preferences : : GetBool ( aPrefName ) ;
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , JSGC_DYNAMIC_HEAP_GROWTH , pref ) ;
2012-07-11 22:09:53 +04:00
}
2013-12-11 03:10:01 +04:00
static void
2012-07-11 22:09:53 +04:00
SetMemoryGCDynamicMarkSlicePrefChangedCallback ( const char * aPrefName , void * aClosure )
{
bool pref = Preferences : : GetBool ( aPrefName ) ;
2013-08-20 03:24:29 +04:00
JS_SetGCParameter ( sRuntime , JSGC_DYNAMIC_MARK_SLICE , pref ) ;
2012-07-11 22:09:53 +04:00
}
2013-12-22 19:14:36 +04:00
static void
SetIncrementalCCPrefChangedCallback ( const char * aPrefName , void * aClosure )
{
bool pref = Preferences : : GetBool ( aPrefName ) ;
sIncrementalCC = pref ;
}
2011-07-17 23:09:13 +04:00
JSObject *
NS_DOMReadStructuredClone ( JSContext * cx ,
JSStructuredCloneReader * reader ,
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-09 07:54:10 +04:00
uint32_t tag ,
uint32_t data ,
2011-07-17 23:09:13 +04:00
void * closure )
2010-10-11 02:39:11 +04:00
{
2012-04-24 14:58:07 +04:00
if ( tag = = SCTAG_DOM_IMAGEDATA ) {
// Read the information out of the stream.
uint32_t width , height ;
2013-05-02 13:12:46 +04:00
JS : : Rooted < JS : : Value > dataArray ( cx ) ;
2012-04-24 14:58:07 +04:00
if ( ! JS_ReadUint32Pair ( reader , & width , & height ) | |
2014-03-20 13:32:37 +04:00
! JS_ReadTypedArray ( reader , & dataArray ) ) {
2012-07-30 18:20:58 +04:00
return nullptr ;
2012-04-24 14:58:07 +04:00
}
MOZ_ASSERT ( dataArray . isObject ( ) ) ;
// Construct the ImageData.
2012-10-22 21:08:52 +04:00
nsRefPtr < ImageData > imageData = new ImageData ( width , height ,
dataArray . toObject ( ) ) ;
2013-04-12 02:52:10 +04:00
// Wrap it in a JS::Value.
2014-04-09 02:27:18 +04:00
return imageData - > WrapObject ( cx ) ;
2012-04-24 14:58:07 +04:00
}
// Don't know what this is. Bail.
2012-06-20 03:01:10 +04:00
xpc : : Throw ( cx , NS_ERROR_DOM_DATA_CLONE_ERR ) ;
2012-07-30 18:20:58 +04:00
return nullptr ;
2010-10-11 02:39:11 +04:00
}
2013-08-09 02:53:04 +04:00
bool
2011-07-17 23:09:13 +04:00
NS_DOMWriteStructuredClone ( JSContext * cx ,
JSStructuredCloneWriter * writer ,
2013-05-09 11:27:40 +04:00
JS : : Handle < JSObject * > obj ,
2011-07-17 23:09:13 +04:00
void * closure )
2010-10-11 02:39:11 +04:00
{
2012-10-22 21:08:52 +04:00
ImageData * imageData ;
2013-11-21 16:51:16 +04:00
nsresult rv = UNWRAP_OBJECT ( ImageData , obj , imageData ) ;
2012-10-22 21:08:52 +04:00
if ( NS_FAILED ( rv ) ) {
// Don't know what this is. Bail.
xpc : : Throw ( cx , NS_ERROR_DOM_DATA_CLONE_ERR ) ;
2013-08-07 10:59:54 +04:00
return false ;
2012-04-24 14:58:07 +04:00
}
2012-10-22 21:08:52 +04:00
// Prepare the ImageData internals.
uint32_t width = imageData - > Width ( ) ;
uint32_t height = imageData - > Height ( ) ;
2013-05-12 09:17:42 +04:00
JS : : Rooted < JSObject * > dataArray ( cx , imageData - > GetDataObject ( ) ) ;
2012-10-22 21:08:52 +04:00
// Write the internals to the stream.
2013-02-23 01:43:28 +04:00
JSAutoCompartment ac ( cx , dataArray ) ;
2014-04-02 18:28:03 +04:00
JS : : Rooted < JS : : Value > arrayValue ( cx , JS : : ObjectValue ( * dataArray ) ) ;
2012-10-22 21:08:52 +04:00
return JS_WriteUint32Pair ( writer , SCTAG_DOM_IMAGEDATA , 0 ) & &
JS_WriteUint32Pair ( writer , width , height ) & &
2014-04-02 18:28:03 +04:00
JS_WriteTypedArray ( writer , arrayValue ) ;
2010-10-11 02:39:11 +04:00
}
2011-07-17 23:09:13 +04:00
void
NS_DOMStructuredCloneError ( JSContext * cx ,
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-09 07:54:10 +04:00
uint32_t errorid )
2010-10-11 02:39:11 +04:00
{
// We don't currently support any extensions to structured cloning.
2012-06-20 03:01:10 +04:00
xpc : : Throw ( cx , NS_ERROR_DOM_DATA_CLONE_ERR ) ;
2010-10-11 02:39:11 +04:00
}
2013-12-03 23:31:30 +04:00
static bool
AsmJSCacheOpenEntryForRead ( JS : : Handle < JSObject * > aGlobal ,
const jschar * aBegin ,
const jschar * aLimit ,
size_t * aSize ,
const uint8_t * * aMemory ,
intptr_t * aHandle )
{
nsIPrincipal * principal = nsContentUtils : : GetObjectPrincipal ( aGlobal ) ;
return asmjscache : : OpenEntryForRead ( principal , aBegin , aLimit , aSize , aMemory ,
aHandle ) ;
}
static bool
AsmJSCacheOpenEntryForWrite ( JS : : Handle < JSObject * > aGlobal ,
2014-03-06 00:47:10 +04:00
bool aInstalled ,
2013-12-03 23:31:30 +04:00
const jschar * aBegin ,
const jschar * aEnd ,
size_t aSize ,
uint8_t * * aMemory ,
intptr_t * aHandle )
{
nsIPrincipal * principal = nsContentUtils : : GetObjectPrincipal ( aGlobal ) ;
2014-03-06 00:47:10 +04:00
return asmjscache : : OpenEntryForWrite ( principal , aInstalled , aBegin , aEnd ,
aSize , aMemory , aHandle ) ;
2013-12-03 23:31:30 +04:00
}
2014-02-13 08:50:15 +04:00
static void
OnLargeAllocationFailure ( )
{
nsCOMPtr < nsIObserverService > os =
mozilla : : services : : GetObserverService ( ) ;
if ( os ) {
os - > NotifyObservers ( nullptr , " memory-pressure " , MOZ_UTF16 ( " heap-minimize " ) ) ;
}
}
2013-08-20 03:24:28 +04:00
static NS_DEFINE_CID ( kDOMScriptObjectFactoryCID , NS_DOM_SCRIPT_OBJECT_FACTORY_CID ) ;
2013-08-20 03:24:29 +04:00
void
nsJSContext : : EnsureStatics ( )
1998-07-16 05:16:47 +04:00
{
2004-06-09 22:36:25 +04:00
if ( sIsInitialized ) {
2013-08-20 03:24:29 +04:00
if ( ! nsContentUtils : : XPConnect ( ) ) {
MOZ_CRASH ( ) ;
}
return ;
2000-06-20 07:45:21 +04:00
}
2008-09-06 03:26:04 +04:00
nsresult rv = CallGetService ( NS_SCRIPTSECURITYMANAGER_CONTRACTID ,
& sSecurityManager ) ;
2013-08-20 03:24:29 +04:00
if ( NS_FAILED ( rv ) ) {
MOZ_CRASH ( ) ;
}
2008-09-06 03:26:04 +04:00
rv = CallGetService ( kJSRuntimeServiceContractID , & sRuntimeService ) ;
2013-08-20 03:24:29 +04:00
if ( NS_FAILED ( rv ) ) {
MOZ_CRASH ( ) ;
}
2001-11-27 12:46:38 +03:00
rv = sRuntimeService - > GetRuntime ( & sRuntime ) ;
2013-08-20 03:24:29 +04:00
if ( NS_FAILED ( rv ) ) {
MOZ_CRASH ( ) ;
}
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
2001-06-05 05:00:48 +04:00
// Let's make sure that our main thread is the same as the xpcom main thread.
2013-08-20 03:24:29 +04:00
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
2001-06-05 05:00:48 +04:00
2013-01-28 00:35:12 +04:00
sPrevGCSliceCallback = JS : : SetGCSliceCallback ( sRuntime , DOMGCSliceCallback ) ;
2000-05-15 08:21:04 +04:00
2010-10-11 02:39:11 +04:00
// Set up the structured clone callbacks.
static JSStructuredCloneCallbacks cloneCallbacks = {
2011-07-17 23:09:13 +04:00
NS_DOMReadStructuredClone ,
NS_DOMWriteStructuredClone ,
2013-11-15 08:42:34 +04:00
NS_DOMStructuredCloneError ,
nullptr ,
nullptr ,
nullptr
2010-10-11 02:39:11 +04:00
} ;
JS_SetStructuredCloneCallbacks ( sRuntime , & cloneCallbacks ) ;
2012-08-08 09:26:18 +04:00
static js : : DOMCallbacks DOMcallbacks = {
InstanceClassHasProtoAtDepth
} ;
SetDOMCallbacks ( sRuntime , & DOMcallbacks ) ;
2013-11-19 01:49:53 +04:00
// Set up the asm.js cache callbacks
static JS : : AsmJSCacheOps asmJSCacheOps = {
2013-12-03 23:31:30 +04:00
AsmJSCacheOpenEntryForRead ,
2013-11-19 01:49:53 +04:00
asmjscache : : CloseEntryForRead ,
2013-12-03 23:31:30 +04:00
AsmJSCacheOpenEntryForWrite ,
2013-11-19 01:49:53 +04:00
asmjscache : : CloseEntryForWrite ,
asmjscache : : GetBuildId
} ;
JS : : SetAsmJSCacheOps ( sRuntime , & asmJSCacheOps ) ;
2014-02-13 08:50:15 +04:00
JS : : SetLargeAllocationFailureCallback ( sRuntime , OnLargeAllocationFailure ) ;
2001-06-05 05:00:48 +04:00
// Set these global xpconnect options...
2013-02-20 23:49:51 +04:00
Preferences : : RegisterCallbackAndCall ( ReportAllJSExceptionsPrefChangedCallback ,
" dom.report_all_js_exceptions " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryHighWaterMarkPrefChangedCallback ,
" javascript.options.mem.high_water_mark " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryMaxPrefChangedCallback ,
" javascript.options.mem.max " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCModePrefChangedCallback ,
" javascript.options.mem.gc_per_compartment " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCModePrefChangedCallback ,
" javascript.options.mem.gc_incremental " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCSliceTimePrefChangedCallback ,
" javascript.options.mem.gc_incremental_slice_ms " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_high_frequency_time_limit_ms " ,
( void * ) JSGC_HIGH_FREQUENCY_TIME_LIMIT ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCDynamicMarkSlicePrefChangedCallback ,
" javascript.options.mem.gc_dynamic_mark_slice " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCDynamicHeapGrowthPrefChangedCallback ,
" javascript.options.mem.gc_dynamic_heap_growth " ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_low_frequency_heap_growth " ,
( void * ) JSGC_LOW_FREQUENCY_HEAP_GROWTH ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_high_frequency_heap_growth_min " ,
( void * ) JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_high_frequency_heap_growth_max " ,
( void * ) JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_high_frequency_low_limit_mb " ,
( void * ) JSGC_HIGH_FREQUENCY_LOW_LIMIT ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_high_frequency_high_limit_mb " ,
( void * ) JSGC_HIGH_FREQUENCY_HIGH_LIMIT ) ;
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_allocation_threshold_mb " ,
( void * ) JSGC_ALLOCATION_THRESHOLD ) ;
2013-06-21 05:06:53 +04:00
Preferences : : RegisterCallbackAndCall ( SetMemoryGCPrefChangedCallback ,
" javascript.options.mem.gc_decommit_threshold_mb " ,
( void * ) JSGC_DECOMMIT_THRESHOLD ) ;
2013-12-22 19:14:36 +04:00
Preferences : : RegisterCallbackAndCall ( SetIncrementalCCPrefChangedCallback ,
" dom.cycle_collector.incremental " ) ;
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 20:59:13 +04:00
nsCOMPtr < nsIObserverService > obs = mozilla : : services : : GetObserverService ( ) ;
2013-08-20 03:24:29 +04:00
if ( ! obs ) {
MOZ_CRASH ( ) ;
}
2007-10-23 01:42:25 +04:00
2011-07-07 22:27:07 +04:00
Preferences : : AddBoolVarCache ( & sGCOnMemoryPressure ,
" javascript.options.gc_on_memory_pressure " ,
2011-10-17 18:59:28 +04:00
true ) ;
2011-07-07 22:27:07 +04:00
2013-01-22 23:17:48 +04:00
nsIObserver * observer = new nsJSEnvironmentObserver ( ) ;
obs - > AddObserver ( observer , " memory-pressure " , false ) ;
obs - > AddObserver ( observer , " quit-application " , false ) ;
2007-11-07 00:47:35 +03:00
2013-08-22 10:56:02 +04:00
// Bug 907848 - We need to explicitly get the nsIDOMScriptObjectFactory
// service in order to force its constructor to run, which registers a
// shutdown observer. It would be nice to make this more explicit and less
// side-effect-y.
2013-08-20 03:24:28 +04:00
nsCOMPtr < nsIDOMScriptObjectFactory > factory = do_GetService ( kDOMScriptObjectFactoryCID ) ;
if ( ! factory ) {
MOZ_CRASH ( ) ;
}
2011-10-17 18:59:28 +04:00
sIsInitialized = true ;
1998-07-16 05:16:47 +04:00
}
2007-11-13 13:35:49 +03:00
nsScriptNameSpaceManager *
2013-08-20 03:24:29 +04:00
mozilla : : dom : : GetNameSpaceManager ( )
2007-11-13 13:35:49 +03:00
{
if ( sDidShutdown )
2012-07-30 18:20:58 +04:00
return nullptr ;
2007-11-13 13:35:49 +03:00
if ( ! gNameSpaceManager ) {
gNameSpaceManager = new nsScriptNameSpaceManager ;
2010-11-17 01:09:50 +03:00
NS_ADDREF ( gNameSpaceManager ) ;
2007-11-13 13:35:49 +03:00
nsresult rv = gNameSpaceManager - > Init ( ) ;
2012-07-30 18:20:58 +04:00
NS_ENSURE_SUCCESS ( rv , nullptr ) ;
2007-11-13 13:35:49 +03:00
}
return gNameSpaceManager ;
}
2008-09-11 17:20:56 +04:00
void
2013-08-20 03:24:29 +04:00
mozilla : : dom : : ShutdownJSEnvironment ( )
1998-07-16 05:16:47 +04:00
{
2013-01-22 23:17:48 +04:00
KillTimers ( ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2010-11-17 01:09:50 +03:00
NS_IF_RELEASE ( gNameSpaceManager ) ;
2001-11-27 12:46:38 +03:00
2002-05-03 07:02:07 +04:00
if ( ! sContextCount ) {
// We're being shutdown, and there are no more contexts
2003-04-18 00:21:00 +04:00
// alive, release the JS runtime service and the security manager.
2002-05-03 07:02:07 +04:00
NS_IF_RELEASE ( sRuntimeService ) ;
2003-04-18 00:21:00 +04:00
NS_IF_RELEASE ( sSecurityManager ) ;
2001-11-27 12:46:38 +03:00
}
2002-05-03 07:02:07 +04:00
2013-01-22 23:17:48 +04:00
sShuttingDown = true ;
2011-10-17 18:59:28 +04:00
sDidShutdown = true ;
1998-07-16 05:16:47 +04:00
}
2006-06-13 07:07:47 +04:00
// A fast-array class for JS. This class supports both nsIJSScriptArray and
// nsIArray. If it is JS itself providing and consuming this class, all work
// can be done via nsIJSScriptArray, and avoid the conversion of elements
// to/from nsISupports.
// When consumed by non-JS (eg, another script language), conversion is done
// on-the-fly.
2012-06-15 06:31:55 +04:00
class nsJSArgArray MOZ_FINAL : public nsIJSArgArray {
2006-06-13 07:07:47 +04:00
public :
2013-04-12 02:52:10 +04:00
nsJSArgArray ( JSContext * aContext , uint32_t argc , JS : : Value * argv ,
nsresult * prv ) ;
2006-06-13 07:07:47 +04:00
~ nsJSArgArray ( ) ;
// nsISupports
2007-03-08 14:17:16 +03:00
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
2007-10-29 16:45:07 +03:00
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS ( nsJSArgArray ,
nsIJSArgArray )
2006-06-13 07:07:47 +04:00
// nsIArray
NS_DECL_NSIARRAY
// nsIJSArgArray
2012-08-22 19:56:38 +04:00
nsresult GetArgs ( uint32_t * argc , void * * argv ) ;
2007-03-08 14:17:16 +03:00
void ReleaseJSObjects ( ) ;
2006-06-13 07:07:47 +04:00
protected :
JSContext * mContext ;
2013-06-18 14:00:37 +04:00
JS : : Heap < JS : : Value > * mArgv ;
2012-12-05 13:19:33 +04:00
uint32_t mArgc ;
2006-06-13 07:07:47 +04:00
} ;
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
2013-04-12 02:52:10 +04:00
nsJSArgArray : : nsJSArgArray ( JSContext * aContext , uint32_t argc , JS : : Value * argv ,
2006-06-13 07:07:47 +04:00
nsresult * prv ) :
2012-12-05 13:19:33 +04:00
mContext ( aContext ) ,
mArgv ( nullptr ) ,
mArgc ( argc )
2006-06-13 07:07:47 +04:00
{
// copy the array - we don't know its lifetime, and ours is tied to xpcom
2013-06-18 14:00:37 +04:00
// refcounting.
2012-12-05 13:19:33 +04:00
if ( argc ) {
2013-06-18 14:00:37 +04:00
static const fallible_t fallible = fallible_t ( ) ;
mArgv = new ( fallible ) JS : : Heap < JS : : Value > [ argc ] ;
2012-12-05 13:19:33 +04:00
if ( ! mArgv ) {
* prv = NS_ERROR_OUT_OF_MEMORY ;
return ;
}
2006-06-13 07:07:47 +04:00
}
2007-09-19 04:26:39 +04:00
2007-10-29 16:45:07 +03:00
// Callers are allowed to pass in a null argv even for argc > 0. They can
// then use GetArgs to initialize the values.
if ( argv ) {
2012-08-22 19:56:38 +04:00
for ( uint32_t i = 0 ; i < argc ; + + i )
2006-06-13 07:07:47 +04:00
mArgv [ i ] = argv [ i ] ;
}
2007-10-31 13:52:22 +03:00
2012-11-13 05:15:00 +04:00
if ( argc > 0 ) {
2013-08-17 00:10:17 +04:00
mozilla : : HoldJSObjects ( this ) ;
2012-11-13 05:15:00 +04:00
}
* prv = NS_OK ;
2006-06-13 07:07:47 +04:00
}
2005-08-10 04:15:51 +04:00
2006-06-13 07:07:47 +04:00
nsJSArgArray : : ~ nsJSArgArray ( )
2007-03-08 14:17:16 +03:00
{
ReleaseJSObjects ( ) ;
}
void
nsJSArgArray : : ReleaseJSObjects ( )
2006-06-13 07:07:47 +04:00
{
2012-12-05 13:19:33 +04:00
if ( mArgv ) {
2013-06-18 14:00:37 +04:00
delete [ ] mArgv ;
2012-12-05 13:19:33 +04:00
}
if ( mArgc > 0 ) {
mArgc = 0 ;
2013-08-17 00:10:17 +04:00
mozilla : : DropJSObjects ( this ) ;
2012-12-05 13:19:33 +04:00
}
2006-06-13 07:07:47 +04:00
}
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
2006-06-13 07:07:47 +04:00
// QueryInterface implementation for nsJSArgArray
2013-08-02 05:29:05 +04:00
NS_IMPL_CYCLE_COLLECTION_CLASS ( nsJSArgArray )
2010-11-08 18:02:49 +03:00
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN ( nsJSArgArray )
2007-03-08 14:17:16 +03:00
tmp - > ReleaseJSObjects ( ) ;
2010-11-08 18:02:49 +03:00
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
2007-03-08 14:17:16 +03:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN ( nsJSArgArray )
2007-10-29 16:45:07 +03:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN ( nsJSArgArray )
2013-05-27 15:50:49 +04:00
if ( tmp - > mArgv ) {
for ( uint32_t i = 0 ; i < tmp - > mArgc ; + + i ) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK ( mArgv [ i ] )
}
2007-03-08 14:17:16 +03:00
}
2007-10-29 16:45:07 +03:00
NS_IMPL_CYCLE_COLLECTION_TRACE_END
2007-03-08 14:17:16 +03:00
2007-04-25 20:35:27 +04:00
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION ( nsJSArgArray )
2006-06-13 07:07:47 +04:00
NS_INTERFACE_MAP_ENTRY ( nsIArray )
NS_INTERFACE_MAP_ENTRY ( nsIJSArgArray )
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS ( nsISupports , nsIJSArgArray )
NS_INTERFACE_MAP_END
2001-11-27 12:46:38 +03:00
2011-03-06 14:11:31 +03:00
NS_IMPL_CYCLE_COLLECTING_ADDREF ( nsJSArgArray )
NS_IMPL_CYCLE_COLLECTING_RELEASE ( nsJSArgArray )
2001-11-27 12:46:38 +03:00
2006-06-13 07:07:47 +04:00
nsresult
2012-08-22 19:56:38 +04:00
nsJSArgArray : : GetArgs ( uint32_t * argc , void * * argv )
2006-06-13 07:07:47 +04:00
{
2012-12-05 13:19:33 +04:00
* argv = ( void * ) mArgv ;
* argc = mArgc ;
2006-06-13 07:07:47 +04:00
return NS_OK ;
}
// nsIArray impl
2012-08-22 19:56:38 +04:00
NS_IMETHODIMP nsJSArgArray : : GetLength ( uint32_t * aLength )
2006-06-13 07:07:47 +04:00
{
2012-12-05 13:19:33 +04:00
* aLength = mArgc ;
2006-06-13 07:07:47 +04:00
return NS_OK ;
}
/* void queryElementAt (in unsigned long index, in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
2012-08-22 19:56:38 +04:00
NS_IMETHODIMP nsJSArgArray : : QueryElementAt ( uint32_t index , const nsIID & uuid , void * * result )
2006-06-13 07:07:47 +04:00
{
2012-07-30 18:20:58 +04:00
* result = nullptr ;
2012-12-05 13:19:33 +04:00
if ( index > = mArgc )
2006-06-13 07:07:47 +04:00
return NS_ERROR_INVALID_ARG ;
if ( uuid . Equals ( NS_GET_IID ( nsIVariant ) ) | | uuid . Equals ( NS_GET_IID ( nsISupports ) ) ) {
2014-01-15 23:39:08 +04:00
// Have to copy a Heap into a Rooted to work with it.
JS : : Rooted < JS : : Value > val ( mContext , mArgv [ index ] ) ;
return nsContentUtils : : XPConnect ( ) - > JSToVariant ( mContext , val ,
2006-06-13 07:07:47 +04:00
( nsIVariant * * ) result ) ;
}
NS_WARNING ( " nsJSArgArray only handles nsIVariant " ) ;
return NS_ERROR_NO_INTERFACE ;
1998-07-16 05:16:47 +04:00
}
2006-06-13 07:07:47 +04:00
/* unsigned long indexOf (in unsigned long startIndex, in nsISupports element); */
2012-08-22 19:56:38 +04:00
NS_IMETHODIMP nsJSArgArray : : IndexOf ( uint32_t startIndex , nsISupports * element , uint32_t * _retval )
2006-06-13 07:07:47 +04:00
{
return NS_ERROR_NOT_IMPLEMENTED ;
}
/* nsISimpleEnumerator enumerate (); */
NS_IMETHODIMP nsJSArgArray : : Enumerate ( nsISimpleEnumerator * * _retval )
{
return NS_ERROR_NOT_IMPLEMENTED ;
}
// The factory function
2012-08-22 19:56:38 +04:00
nsresult NS_CreateJSArgv ( JSContext * aContext , uint32_t argc , void * argv ,
2012-03-11 12:53:05 +04:00
nsIJSArgArray * * aArray )
2006-06-13 07:07:47 +04:00
{
nsresult rv ;
nsJSArgArray * ret = new nsJSArgArray ( aContext , argc ,
2013-04-12 02:52:10 +04:00
static_cast < JS : : Value * > ( argv ) , & rv ) ;
2012-07-30 18:20:58 +04:00
if ( ret = = nullptr )
2006-06-13 07:07:47 +04:00
return NS_ERROR_OUT_OF_MEMORY ;
if ( NS_FAILED ( rv ) ) {
delete ret ;
return rv ;
}
return ret - > QueryInterface ( NS_GET_IID ( nsIArray ) , ( void * * ) aArray ) ;
}