зеркало из https://github.com/mozilla/pjs.git
Merge mozilla-central to inbound
This commit is contained in:
Коммит
2d95d4ff31
|
@ -318,3 +318,12 @@ nsBrowserAccess.prototype = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pipe `console` log messages to the nsIConsoleService which writes them
|
||||||
|
// to logcat.
|
||||||
|
Services.obs.addObserver(function onConsoleAPILogEvent(subject, topic, data) {
|
||||||
|
let message = subject.wrappedJSObject;
|
||||||
|
let prefix = "Content JS " + message.level.toUpperCase() +
|
||||||
|
" at " + message.filename + ":" + message.lineNumber +
|
||||||
|
" in " + (message.functionName || "anonymous") + ": ";
|
||||||
|
Services.console.logStringMessage(prefix + Array.join(message.arguments, " "));
|
||||||
|
}, "console-api-log-event", false);
|
||||||
|
|
|
@ -817,7 +817,7 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
|
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS, nsGCNormal, true);
|
||||||
nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
|
nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -135,6 +135,8 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||||
// doing the first GC.
|
// doing the first GC.
|
||||||
#define NS_FIRST_GC_DELAY 10000 // ms
|
#define NS_FIRST_GC_DELAY 10000 // ms
|
||||||
|
|
||||||
|
#define NS_FULL_GC_DELAY 60000 // ms
|
||||||
|
|
||||||
// The amount of time we wait between a request to CC (after GC ran)
|
// The amount of time we wait between a request to CC (after GC ran)
|
||||||
// and doing the actual CC.
|
// and doing the actual CC.
|
||||||
#define NS_CC_DELAY 5000 // ms
|
#define NS_CC_DELAY 5000 // ms
|
||||||
|
@ -148,6 +150,7 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||||
// if you add statics here, add them to the list in nsJSRuntime::Startup
|
// if you add statics here, add them to the list in nsJSRuntime::Startup
|
||||||
|
|
||||||
static nsITimer *sGCTimer;
|
static nsITimer *sGCTimer;
|
||||||
|
static nsITimer *sFullGCTimer;
|
||||||
static nsITimer *sShrinkGCBuffersTimer;
|
static nsITimer *sShrinkGCBuffersTimer;
|
||||||
static nsITimer *sCCTimer;
|
static nsITimer *sCCTimer;
|
||||||
|
|
||||||
|
@ -166,6 +169,7 @@ static bool sLoadingInProgress;
|
||||||
|
|
||||||
static PRUint32 sCCollectedWaitingForGC;
|
static PRUint32 sCCollectedWaitingForGC;
|
||||||
static bool sPostGCEventsToConsole;
|
static bool sPostGCEventsToConsole;
|
||||||
|
static bool sDisableExplicitCompartmentGC;
|
||||||
static PRUint32 sCCTimerFireCount = 0;
|
static PRUint32 sCCTimerFireCount = 0;
|
||||||
static PRUint32 sMinForgetSkippableTime = PR_UINT32_MAX;
|
static PRUint32 sMinForgetSkippableTime = PR_UINT32_MAX;
|
||||||
static PRUint32 sMaxForgetSkippableTime = 0;
|
static PRUint32 sMaxForgetSkippableTime = 0;
|
||||||
|
@ -173,9 +177,15 @@ static PRUint32 sTotalForgetSkippableTime = 0;
|
||||||
static PRUint32 sRemovedPurples = 0;
|
static PRUint32 sRemovedPurples = 0;
|
||||||
static PRUint32 sForgetSkippableBeforeCC = 0;
|
static PRUint32 sForgetSkippableBeforeCC = 0;
|
||||||
static PRUint32 sPreviousSuspectedCount = 0;
|
static PRUint32 sPreviousSuspectedCount = 0;
|
||||||
|
static PRUint32 sCompartmentGCCount = 0;
|
||||||
|
static nsJSContext* sTopEvaluator = nsnull;
|
||||||
|
static bool sContextDeleted = false;
|
||||||
|
static bool sPreviousWasChromeCompGC = false;
|
||||||
|
|
||||||
static bool sCleanupSinceLastGC = true;
|
static bool sCleanupSinceLastGC = true;
|
||||||
|
|
||||||
|
PRUint32 nsJSContext::sGlobalGCEpoch = 0;
|
||||||
|
|
||||||
nsScriptNameSpaceManager *gNameSpaceManager;
|
nsScriptNameSpaceManager *gNameSpaceManager;
|
||||||
|
|
||||||
static nsIJSRuntimeService *sRuntimeService;
|
static nsIJSRuntimeService *sRuntimeService;
|
||||||
|
@ -216,7 +226,8 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||||
const PRUnichar* aData)
|
const PRUnichar* aData)
|
||||||
{
|
{
|
||||||
if (sGCOnMemoryPressure) {
|
if (sGCOnMemoryPressure) {
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking);
|
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking,
|
||||||
|
true);
|
||||||
nsJSContext::CycleCollectNow();
|
nsJSContext::CycleCollectNow();
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -938,6 +949,8 @@ static const char js_pccounts_content_str[] = JS_OPTIONS_DOT_STR "pccounts.con
|
||||||
static const char js_pccounts_chrome_str[] = JS_OPTIONS_DOT_STR "pccounts.chrome";
|
static const char js_pccounts_chrome_str[] = JS_OPTIONS_DOT_STR "pccounts.chrome";
|
||||||
static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening";
|
static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening";
|
||||||
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
|
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
|
||||||
|
static const char js_disable_explicit_compartment_gc[] =
|
||||||
|
JS_OPTIONS_DOT_STR "disable_explicit_compartment_gc";
|
||||||
|
|
||||||
int
|
int
|
||||||
nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||||
|
@ -947,6 +960,8 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||||
PRUint32 newDefaultJSOptions = oldDefaultJSOptions;
|
PRUint32 newDefaultJSOptions = oldDefaultJSOptions;
|
||||||
|
|
||||||
sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
|
sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
|
||||||
|
sDisableExplicitCompartmentGC =
|
||||||
|
Preferences::GetBool(js_disable_explicit_compartment_gc);
|
||||||
|
|
||||||
bool strict = Preferences::GetBool(js_strict_option_str);
|
bool strict = Preferences::GetBool(js_strict_option_str);
|
||||||
if (strict)
|
if (strict)
|
||||||
|
@ -1048,6 +1063,9 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||||
|
|
||||||
nsJSContext::nsJSContext(JSRuntime *aRuntime)
|
nsJSContext::nsJSContext(JSRuntime *aRuntime)
|
||||||
: mGCOnDestruction(true),
|
: mGCOnDestruction(true),
|
||||||
|
mChromeComp(false),
|
||||||
|
mGlobalGCEpoch(0),
|
||||||
|
mEvaluationCount(0),
|
||||||
mExecuteDepth(0)
|
mExecuteDepth(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1098,6 +1116,9 @@ nsJSContext::~nsJSContext()
|
||||||
DestroyJSContext();
|
DestroyJSContext();
|
||||||
|
|
||||||
--sContextCount;
|
--sContextCount;
|
||||||
|
if (sTopEvaluator == this) {
|
||||||
|
sTopEvaluator = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sContextCount && sDidShutdown) {
|
if (!sContextCount && sDidShutdown) {
|
||||||
// The last context is being deleted, and we're already in the
|
// The last context is being deleted, and we're already in the
|
||||||
|
@ -1124,6 +1145,7 @@ nsJSContext::DestroyJSContext()
|
||||||
js_options_dot_str, this);
|
js_options_dot_str, this);
|
||||||
|
|
||||||
if (mGCOnDestruction) {
|
if (mGCOnDestruction) {
|
||||||
|
sContextDeleted = true;
|
||||||
PokeGC(js::gcreason::NSJSCONTEXT_DESTROY);
|
PokeGC(js::gcreason::NSJSCONTEXT_DESTROY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2237,6 +2259,7 @@ nsJSContext::CreateNativeGlobalForInner(
|
||||||
{
|
{
|
||||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||||
PRUint32 flags = aIsChrome? nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT : 0;
|
PRUint32 flags = aIsChrome? nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT : 0;
|
||||||
|
mChromeComp = aIsChrome;
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> systemPrincipal;
|
nsCOMPtr<nsIPrincipal> systemPrincipal;
|
||||||
if (aIsChrome) {
|
if (aIsChrome) {
|
||||||
|
@ -3159,6 +3182,12 @@ nsJSContext::ScriptEvaluated(bool aTerminated)
|
||||||
if (aTerminated && mExecuteDepth == 0 && !JS_IsRunning(mContext)) {
|
if (aTerminated && mExecuteDepth == 0 && !JS_IsRunning(mContext)) {
|
||||||
mOperationCallbackTime = 0;
|
mOperationCallbackTime = 0;
|
||||||
mModalStateTime = 0;
|
mModalStateTime = 0;
|
||||||
|
|
||||||
|
IncreaseEvaluationCount(this);
|
||||||
|
if (EvaluationCount(sTopEvaluator) < EvaluationCount(this) &&
|
||||||
|
(!mChromeComp || !sPreviousWasChromeCompGC)) {
|
||||||
|
sTopEvaluator = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3231,9 +3260,20 @@ nsJSContext::ScriptExecuted()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FullGCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
NS_RELEASE(sFullGCTimer);
|
||||||
|
|
||||||
|
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||||
|
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||||
|
nsGCNormal, true);
|
||||||
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void
|
void
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
|
||||||
|
bool aGlobal)
|
||||||
{
|
{
|
||||||
NS_TIME_FUNCTION_MIN(1.0);
|
NS_TIME_FUNCTION_MIN(1.0);
|
||||||
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
||||||
|
@ -3250,9 +3290,44 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
||||||
sPendingLoadCount = 0;
|
sPendingLoadCount = 0;
|
||||||
sLoadingInProgress = false;
|
sLoadingInProgress = false;
|
||||||
|
|
||||||
if (nsContentUtils::XPConnect()) {
|
if (!nsContentUtils::XPConnect()) {
|
||||||
nsContentUtils::XPConnect()->GarbageCollect(reason, gckind);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use compartment GC when we're not asked to do a shrinking GC nor
|
||||||
|
// global GC and compartment GC has been called less than 10 times after
|
||||||
|
// the previous global GC. If a top level browsing context has been
|
||||||
|
// deleted, we do a global GC.
|
||||||
|
if (!sDisableExplicitCompartmentGC &&
|
||||||
|
aGckind != nsGCShrinking && !aGlobal &&
|
||||||
|
EvaluationCount(sTopEvaluator) > 0 &&
|
||||||
|
!sContextDeleted && sCompartmentGCCount < 10) {
|
||||||
|
nsJSContext* top = sTopEvaluator;
|
||||||
|
sTopEvaluator = nsnull;
|
||||||
|
ResetEvaluationCount(top);
|
||||||
|
JSContext* cx = top->GetNativeContext();
|
||||||
|
if (cx) {
|
||||||
|
JSObject* global = top->GetNativeGlobal();
|
||||||
|
if (global) {
|
||||||
|
if (!sFullGCTimer) {
|
||||||
|
CallCreateInstance("@mozilla.org/timer;1", &sFullGCTimer);
|
||||||
|
}
|
||||||
|
if (sFullGCTimer) {
|
||||||
|
sFullGCTimer->Cancel();
|
||||||
|
js::gcreason::Reason reason = js::gcreason::FULL_GC_TIMER;
|
||||||
|
sFullGCTimer->InitWithFuncCallback(FullGCTimerFired,
|
||||||
|
reinterpret_cast<void *>(reason),
|
||||||
|
NS_FULL_GC_DELAY,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
}
|
||||||
|
JSCompartment* comp = js::GetObjectCompartment(global);
|
||||||
|
js::CompartmentGCForReason(cx, comp, aReason);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsContentUtils::XPConnect()->GarbageCollect(aReason, aGckind);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
|
@ -3356,7 +3431,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||||
NS_RELEASE(sGCTimer);
|
NS_RELEASE(sGCTimer);
|
||||||
|
|
||||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason), nsGCNormal);
|
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||||
|
nsGCNormal, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3524,6 +3600,16 @@ nsJSContext::KillGCTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsJSContext::KillFullGCTimer()
|
||||||
|
{
|
||||||
|
if (sFullGCTimer) {
|
||||||
|
sFullGCTimer->Cancel();
|
||||||
|
|
||||||
|
NS_RELEASE(sFullGCTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void
|
void
|
||||||
nsJSContext::KillShrinkGCBuffersTimer()
|
nsJSContext::KillShrinkGCBuffersTimer()
|
||||||
|
@ -3552,8 +3638,8 @@ nsJSContext::GC(js::gcreason::Reason aReason)
|
||||||
PokeGC(aReason);
|
PokeGC(aReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
nsJSContext::DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
|
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
|
||||||
|
|
||||||
|
@ -3579,6 +3665,19 @@ DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
||||||
sCCollectedWaitingForGC = 0;
|
sCCollectedWaitingForGC = 0;
|
||||||
sCleanupSinceLastGC = false;
|
sCleanupSinceLastGC = false;
|
||||||
|
|
||||||
|
if (!comp) {
|
||||||
|
sPreviousWasChromeCompGC = false;
|
||||||
|
sContextDeleted = false;
|
||||||
|
sCompartmentGCCount = 0;
|
||||||
|
++sGlobalGCEpoch;
|
||||||
|
KillFullGCTimer();
|
||||||
|
} else {
|
||||||
|
// Only every other compartment GC is allowed to collect a chrome
|
||||||
|
// compartment. Otherwise we'd collect chrome compartment all the time.
|
||||||
|
sPreviousWasChromeCompGC = xpc::AccessCheck::isChrome(comp);
|
||||||
|
++sCompartmentGCCount;
|
||||||
|
}
|
||||||
|
|
||||||
if (sGCTimer) {
|
if (sGCTimer) {
|
||||||
// If we were waiting for a GC to happen, kill the timer.
|
// If we were waiting for a GC to happen, kill the timer.
|
||||||
nsJSContext::KillGCTimer();
|
nsJSContext::KillGCTimer();
|
||||||
|
@ -3699,13 +3798,14 @@ void
|
||||||
nsJSRuntime::Startup()
|
nsJSRuntime::Startup()
|
||||||
{
|
{
|
||||||
// initialize all our statics, so that we can restart XPCOM
|
// initialize all our statics, so that we can restart XPCOM
|
||||||
sGCTimer = sCCTimer = nsnull;
|
sGCTimer = sFullGCTimer = sCCTimer = nsnull;
|
||||||
sGCHasRun = false;
|
sGCHasRun = false;
|
||||||
sLastCCEndTime = 0;
|
sLastCCEndTime = 0;
|
||||||
sPendingLoadCount = 0;
|
sPendingLoadCount = 0;
|
||||||
sLoadingInProgress = false;
|
sLoadingInProgress = false;
|
||||||
sCCollectedWaitingForGC = 0;
|
sCCollectedWaitingForGC = 0;
|
||||||
sPostGCEventsToConsole = false;
|
sPostGCEventsToConsole = false;
|
||||||
|
sDisableExplicitCompartmentGC = false;
|
||||||
gNameSpaceManager = nsnull;
|
gNameSpaceManager = nsnull;
|
||||||
sRuntimeService = nsnull;
|
sRuntimeService = nsnull;
|
||||||
sRuntime = nsnull;
|
sRuntime = nsnull;
|
||||||
|
@ -3862,7 +3962,7 @@ nsJSRuntime::Init()
|
||||||
// Let's make sure that our main thread is the same as the xpcom main thread.
|
// Let's make sure that our main thread is the same as the xpcom main thread.
|
||||||
NS_ASSERTION(NS_IsMainThread(), "bad");
|
NS_ASSERTION(NS_IsMainThread(), "bad");
|
||||||
|
|
||||||
::JS_SetGCFinishedCallback(sRuntime, DOMGCFinishedCallback);
|
::JS_SetGCFinishedCallback(sRuntime, nsJSContext::DOMGCFinishedCallback);
|
||||||
|
|
||||||
JSSecurityCallbacks *callbacks = JS_GetRuntimeSecurityCallbacks(sRuntime);
|
JSSecurityCallbacks *callbacks = JS_GetRuntimeSecurityCallbacks(sRuntime);
|
||||||
NS_ASSERTION(callbacks, "SecMan should have set security callbacks!");
|
NS_ASSERTION(callbacks, "SecMan should have set security callbacks!");
|
||||||
|
@ -3947,6 +4047,7 @@ void
|
||||||
nsJSRuntime::Shutdown()
|
nsJSRuntime::Shutdown()
|
||||||
{
|
{
|
||||||
nsJSContext::KillGCTimer();
|
nsJSContext::KillGCTimer();
|
||||||
|
nsJSContext::KillFullGCTimer();
|
||||||
nsJSContext::KillShrinkGCBuffersTimer();
|
nsJSContext::KillShrinkGCBuffersTimer();
|
||||||
nsJSContext::KillCCTimer();
|
nsJSContext::KillCCTimer();
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,9 @@ public:
|
||||||
static void LoadStart();
|
static void LoadStart();
|
||||||
static void LoadEnd();
|
static void LoadEnd();
|
||||||
|
|
||||||
static void GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind = nsGCNormal);
|
static void GarbageCollectNow(js::gcreason::Reason aReason,
|
||||||
|
PRUint32 aGckind,
|
||||||
|
bool aGlobal);
|
||||||
static void ShrinkGCBuffersNow();
|
static void ShrinkGCBuffersNow();
|
||||||
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
|
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
|
||||||
// called even if the previous collection was GC.
|
// called even if the previous collection was GC.
|
||||||
|
@ -190,6 +192,7 @@ public:
|
||||||
|
|
||||||
static void PokeGC(js::gcreason::Reason aReason);
|
static void PokeGC(js::gcreason::Reason aReason);
|
||||||
static void KillGCTimer();
|
static void KillGCTimer();
|
||||||
|
static void KillFullGCTimer();
|
||||||
|
|
||||||
static void PokeShrinkGCBuffers();
|
static void PokeShrinkGCBuffers();
|
||||||
static void KillShrinkGCBuffersTimer();
|
static void KillShrinkGCBuffersTimer();
|
||||||
|
@ -208,6 +211,29 @@ public:
|
||||||
JSObject* global = JS_GetGlobalObject(mContext);
|
JSObject* global = JS_GetGlobalObject(mContext);
|
||||||
return global ? mGlobalObjectRef.get() : nsnull;
|
return global ? mGlobalObjectRef.get() : nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRUint32 EvaluationCount(nsJSContext* aCx)
|
||||||
|
{
|
||||||
|
return aCx && aCx->mGlobalGCEpoch == sGlobalGCEpoch ?
|
||||||
|
aCx->mEvaluationCount : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IncreaseEvaluationCount(nsJSContext* aCx)
|
||||||
|
{
|
||||||
|
if (aCx->mGlobalGCEpoch != sGlobalGCEpoch) {
|
||||||
|
aCx->mEvaluationCount = 0;
|
||||||
|
aCx->mGlobalGCEpoch = sGlobalGCEpoch;
|
||||||
|
}
|
||||||
|
++(aCx->mEvaluationCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetEvaluationCount(nsJSContext* aCx)
|
||||||
|
{
|
||||||
|
aCx->mEvaluationCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DOMGCFinishedCallback(JSRuntime* aRt, JSCompartment* aComp,
|
||||||
|
const char* aStatus);
|
||||||
protected:
|
protected:
|
||||||
nsresult InitializeExternalClasses();
|
nsresult InitializeExternalClasses();
|
||||||
|
|
||||||
|
@ -296,7 +322,9 @@ private:
|
||||||
bool mScriptsEnabled;
|
bool mScriptsEnabled;
|
||||||
bool mGCOnDestruction;
|
bool mGCOnDestruction;
|
||||||
bool mProcessingScriptTag;
|
bool mProcessingScriptTag;
|
||||||
|
bool mChromeComp;
|
||||||
|
PRUint32 mGlobalGCEpoch;
|
||||||
|
PRUint32 mEvaluationCount;
|
||||||
PRUint32 mExecuteDepth;
|
PRUint32 mExecuteDepth;
|
||||||
PRUint32 mDefaultJSOptions;
|
PRUint32 mDefaultJSOptions;
|
||||||
PRTime mOperationCallbackTime;
|
PRTime mOperationCallbackTime;
|
||||||
|
@ -308,6 +336,8 @@ private:
|
||||||
// context does. It is eventually collected by the cycle collector.
|
// context does. It is eventually collected by the cycle collector.
|
||||||
nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;
|
nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;
|
||||||
|
|
||||||
|
static PRUint32 sGlobalGCEpoch;
|
||||||
|
|
||||||
static int JSOptionChangedCallback(const char *pref, void *data);
|
static int JSOptionChangedCallback(const char *pref, void *data);
|
||||||
|
|
||||||
static JSBool DOMOperationCallback(JSContext *cx);
|
static JSBool DOMOperationCallback(JSContext *cx);
|
||||||
|
|
|
@ -800,14 +800,14 @@ ContentChild::GetIndexedDBPath()
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvGarbageCollect()
|
ContentChild::RecvGarbageCollect()
|
||||||
{
|
{
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvCycleCollect()
|
ContentChild::RecvCycleCollect()
|
||||||
{
|
{
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
|
||||||
nsJSContext::CycleCollectNow();
|
nsJSContext::CycleCollectNow();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ EXTRA_COMPONENTS = \
|
||||||
EXTRA_JS_MODULES = \
|
EXTRA_JS_MODULES = \
|
||||||
ril_consts.js \
|
ril_consts.js \
|
||||||
ril_worker.js \
|
ril_worker.js \
|
||||||
|
systemlibs.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -47,7 +47,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||||
var RIL = {};
|
var RIL = {};
|
||||||
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
||||||
|
|
||||||
const DEBUG = true; // set to false to suppress debug messages
|
const DEBUG = false; // set to true to see debug messages
|
||||||
|
|
||||||
const RADIOINTERFACELAYER_CID =
|
const RADIOINTERFACELAYER_CID =
|
||||||
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
|
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
|
||||||
|
@ -241,7 +241,9 @@ RadioInterfaceLayer.prototype = {
|
||||||
handleCallStateChange: function handleCallStateChange(call) {
|
handleCallStateChange: function handleCallStateChange(call) {
|
||||||
debug("handleCallStateChange: " + JSON.stringify(call));
|
debug("handleCallStateChange: " + JSON.stringify(call));
|
||||||
call.state = convertRILCallState(call.state);
|
call.state = convertRILCallState(call.state);
|
||||||
if (call.state == nsIRadioInterfaceLayer.CALL_STATE_CONNECTED) {
|
if (call.state == nsIRadioInterfaceLayer.CALL_STATE_DIALING ||
|
||||||
|
call.state == nsIRadioInterfaceLayer.CALL_STATE_RINGING ||
|
||||||
|
call.state == nsIRadioInterfaceLayer.CALL_STATE_CONNECTED) {
|
||||||
// This is now the active call.
|
// This is now the active call.
|
||||||
this._activeCall = call;
|
this._activeCall = call;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
importScripts("ril_consts.js");
|
importScripts("ril_consts.js", "systemlibs.js");
|
||||||
|
|
||||||
let DEBUG = false;
|
let DEBUG = false;
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ const UINT16_SIZE = 2;
|
||||||
const UINT32_SIZE = 4;
|
const UINT32_SIZE = 4;
|
||||||
const PARCEL_SIZE_SIZE = UINT32_SIZE;
|
const PARCEL_SIZE_SIZE = UINT32_SIZE;
|
||||||
|
|
||||||
|
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This object contains helpers buffering incoming data & deconstructing it
|
* This object contains helpers buffering incoming data & deconstructing it
|
||||||
* into parcels as well as buffering outgoing data & constructing parcels.
|
* into parcels as well as buffering outgoing data & constructing parcels.
|
||||||
|
@ -432,7 +434,6 @@ let Buf = {
|
||||||
/**
|
/**
|
||||||
* Process one parcel.
|
* Process one parcel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
processParcel: function processParcel() {
|
processParcel: function processParcel() {
|
||||||
let response_type = this.readUint32();
|
let response_type = this.readUint32();
|
||||||
let length = this.readIncoming - UINT32_SIZE;
|
let length = this.readIncoming - UINT32_SIZE;
|
||||||
|
@ -445,20 +446,24 @@ let Buf = {
|
||||||
request_type = this.tokenRequestMap[token];
|
request_type = this.tokenRequestMap[token];
|
||||||
if (error) {
|
if (error) {
|
||||||
//TODO
|
//TODO
|
||||||
debug("Received error " + error + " for solicited parcel type " +
|
if (DEBUG) {
|
||||||
request_type);
|
debug("Received error " + error + " for solicited parcel type " +
|
||||||
|
request_type);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug("Solicited response for request type " + request_type +
|
if (DEBUG) {
|
||||||
", token " + token);
|
debug("Solicited response for request type " + request_type +
|
||||||
|
", token " + token);
|
||||||
|
}
|
||||||
delete this.tokenRequestMap[token];
|
delete this.tokenRequestMap[token];
|
||||||
this.lastSolicitedToken = token;
|
this.lastSolicitedToken = token;
|
||||||
} else if (response_type == RESPONSE_TYPE_UNSOLICITED) {
|
} else if (response_type == RESPONSE_TYPE_UNSOLICITED) {
|
||||||
request_type = this.readUint32();
|
request_type = this.readUint32();
|
||||||
length -= UINT32_SIZE;
|
length -= UINT32_SIZE;
|
||||||
debug("Unsolicited response for request type " + request_type);
|
if (DEBUG) debug("Unsolicited response for request type " + request_type);
|
||||||
} else {
|
} else {
|
||||||
debug("Unknown response type: " + response_type);
|
if (DEBUG) debug("Unknown response type: " + response_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,9 +488,8 @@ let Buf = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Communication with the RIL IPC thread.
|
* Communicate with the RIL IPC thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sendParcel: function sendParcel() {
|
sendParcel: function sendParcel() {
|
||||||
// Compute the size of the parcel and write it to the front of the parcel
|
// Compute the size of the parcel and write it to the front of the parcel
|
||||||
// where we left room for it. Note that he parcel size does not include
|
// where we left room for it. Note that he parcel size does not include
|
||||||
|
@ -496,7 +500,7 @@ let Buf = {
|
||||||
// This assumes that postRILMessage will make a copy of the ArrayBufferView
|
// This assumes that postRILMessage will make a copy of the ArrayBufferView
|
||||||
// right away!
|
// right away!
|
||||||
let parcel = this.outgoingBytes.subarray(0, this.outgoingIndex);
|
let parcel = this.outgoingBytes.subarray(0, this.outgoingIndex);
|
||||||
debug("Outgoing parcel: " + Array.slice(parcel));
|
if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel));
|
||||||
postRILMessage(parcel);
|
postRILMessage(parcel);
|
||||||
this.outgoingIndex = PARCEL_SIZE_SIZE;
|
this.outgoingIndex = PARCEL_SIZE_SIZE;
|
||||||
},
|
},
|
||||||
|
@ -516,6 +520,25 @@ let Buf = {
|
||||||
*/
|
*/
|
||||||
let RIL = {
|
let RIL = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set quirk flags based on the RIL model detected. Note that this
|
||||||
|
* requires the RIL being "warmed up" first, which happens when on
|
||||||
|
* an incoming or outgoing call.
|
||||||
|
*/
|
||||||
|
rilQuirksInitialized: false,
|
||||||
|
initRILQuirks: function initRILQuirks() {
|
||||||
|
// The Samsung Galaxy S2 I-9100 radio sends an extra Uint32 in the
|
||||||
|
// call state.
|
||||||
|
let model_id = libcutils.property_get("ril.model_id");
|
||||||
|
if (DEBUG) debug("Detected RIL model " + model_id);
|
||||||
|
if (model_id == "I9100") {
|
||||||
|
if (DEBUG) debug("Enabling RILQUIRKS_CALLSTATE_EXTRA_UINT32 for I9100.");
|
||||||
|
RILQUIRKS_CALLSTATE_EXTRA_UINT32 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rilQuirksInitialized = true;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the ICC's status.
|
* Retrieve the ICC's status.
|
||||||
*
|
*
|
||||||
|
@ -865,7 +888,7 @@ let RIL = {
|
||||||
handleParcel: function handleParcel(request_type, length) {
|
handleParcel: function handleParcel(request_type, length) {
|
||||||
let method = this[request_type];
|
let method = this[request_type];
|
||||||
if (typeof method == "function") {
|
if (typeof method == "function") {
|
||||||
debug("Handling parcel as " + method.name);
|
if (DEBUG) debug("Handling parcel as " + method.name);
|
||||||
method.call(this, length);
|
method.call(this, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -915,6 +938,10 @@ RIL[REQUEST_CHANGE_SIM_PIN] = function REQUEST_CHANGE_SIM_PIN() {
|
||||||
RIL[REQUEST_CHANGE_SIM_PIN2] = null;
|
RIL[REQUEST_CHANGE_SIM_PIN2] = null;
|
||||||
RIL[REQUEST_ENTER_NETWORK_DEPERSONALIZATION] = null;
|
RIL[REQUEST_ENTER_NETWORK_DEPERSONALIZATION] = null;
|
||||||
RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
||||||
|
if (!this.rilQuirksInitialized) {
|
||||||
|
this.initRILQuirks();
|
||||||
|
}
|
||||||
|
|
||||||
let calls_length = 0;
|
let calls_length = 0;
|
||||||
// The RIL won't even send us the length integer if there are no active calls.
|
// The RIL won't even send us the length integer if there are no active calls.
|
||||||
// So only read this integer if the parcel actually has it.
|
// So only read this integer if the parcel actually has it.
|
||||||
|
@ -928,22 +955,24 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
||||||
|
|
||||||
let calls = {};
|
let calls = {};
|
||||||
for (let i = 0; i < calls_length; i++) {
|
for (let i = 0; i < calls_length; i++) {
|
||||||
let call = {
|
let call = {};
|
||||||
state: Buf.readUint32(), // CALL_STATE_*
|
call.state = Buf.readUint32(); // CALL_STATE_*
|
||||||
callIndex: Buf.readUint32(), // GSM index (1-based)
|
call.callIndex = Buf.readUint32(); // GSM index (1-based)
|
||||||
toa: Buf.readUint32(),
|
call.toa = Buf.readUint32();
|
||||||
isMpty: Boolean(Buf.readUint32()),
|
call.isMpty = Boolean(Buf.readUint32());
|
||||||
isMT: Boolean(Buf.readUint32()),
|
call.isMT = Boolean(Buf.readUint32());
|
||||||
als: Buf.readUint32(),
|
call.als = Buf.readUint32();
|
||||||
isVoice: Boolean(Buf.readUint32()),
|
call.isVoice = Boolean(Buf.readUint32());
|
||||||
isVoicePrivacy: Boolean(Buf.readUint32()),
|
call.isVoicePrivacy = Boolean(Buf.readUint32());
|
||||||
somethingOrOther: Buf.readUint32(), //XXX TODO whatziz? not in ril.h, but it's in the output...
|
if (RILQUIRKS_CALLSTATE_EXTRA_UINT32) {
|
||||||
number: Buf.readString(), //TODO munge with TOA
|
Buf.readUint32();
|
||||||
numberPresentation: Buf.readUint32(), // CALL_PRESENTATION_*
|
}
|
||||||
name: Buf.readString(),
|
call.number = Buf.readString(); //TODO munge with TOA
|
||||||
namePresentation: Buf.readUint32(),
|
call.numberPresentation = Buf.readUint32(); // CALL_PRESENTATION_*
|
||||||
uusInfo: null
|
call.name = Buf.readString();
|
||||||
};
|
call.namePresentation = Buf.readUint32();
|
||||||
|
|
||||||
|
call.uusInfo = null;
|
||||||
let uusInfoPresent = Buf.readUint32();
|
let uusInfoPresent = Buf.readUint32();
|
||||||
if (uusInfoPresent == 1) {
|
if (uusInfoPresent == 1) {
|
||||||
call.uusInfo = {
|
call.uusInfo = {
|
||||||
|
@ -952,6 +981,7 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
||||||
userData: null //XXX TODO byte array?!?
|
userData: null //XXX TODO byte array?!?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
calls[call.callIndex] = call;
|
calls[call.callIndex] = call;
|
||||||
}
|
}
|
||||||
Phone.onCurrentCalls(calls);
|
Phone.onCurrentCalls(calls);
|
||||||
|
@ -1218,9 +1248,6 @@ RIL[UNSOLICITED_RESEND_INCALL_MUTE] = null;
|
||||||
*/
|
*/
|
||||||
let Phone = {
|
let Phone = {
|
||||||
|
|
||||||
//XXX TODO beware, this is just demo code. It's still missing
|
|
||||||
// communication with the UI thread.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One of the RADIO_STATE_* constants.
|
* One of the RADIO_STATE_* constants.
|
||||||
*/
|
*/
|
||||||
|
@ -1313,7 +1340,9 @@ let Phone = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
onRadioStateChanged: function onRadioStateChanged(newState) {
|
onRadioStateChanged: function onRadioStateChanged(newState) {
|
||||||
debug("Radio state changed from " + this.radioState + " to " + newState);
|
if (DEBUG) {
|
||||||
|
debug("Radio state changed from " + this.radioState + " to " + newState);
|
||||||
|
}
|
||||||
if (this.radioState == newState) {
|
if (this.radioState == newState) {
|
||||||
// No change in state, return.
|
// No change in state, return.
|
||||||
return;
|
return;
|
||||||
|
@ -1455,13 +1484,13 @@ let Phone = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onNetworkStateChanged: function onNetworkStateChanged() {
|
onNetworkStateChanged: function onNetworkStateChanged() {
|
||||||
debug("Network state changed, re-requesting phone state.");
|
if (DEBUG) debug("Network state changed, re-requesting phone state.");
|
||||||
this.requestNetworkInfo();
|
this.requestNetworkInfo();
|
||||||
},
|
},
|
||||||
|
|
||||||
onICCStatus: function onICCStatus(iccStatus) {
|
onICCStatus: function onICCStatus(iccStatus) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
debug("iccStatus: " + JSON.stringify(iccStatus));
|
debug("iccStatus: " + JSON.stringify(iccStatus));
|
||||||
}
|
}
|
||||||
this.iccStatus = iccStatus;
|
this.iccStatus = iccStatus;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
const SYSTEM_PROPERTY_KEY_MAX = 32;
|
||||||
|
const SYSTEM_PROPERTY_VALUE_MAX = 92;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose some system-level functions.
|
||||||
|
*/
|
||||||
|
let libcutils = (function() {
|
||||||
|
let lib;
|
||||||
|
try {
|
||||||
|
lib = ctypes.open("libcutils.so");
|
||||||
|
} catch(ex) {
|
||||||
|
// Return a fallback option in case libcutils.so isn't present (e.g.
|
||||||
|
// when building Firefox with MOZ_B2G_RIL.
|
||||||
|
dump("Could not load libcutils.so. Using fake propdb.");
|
||||||
|
let fake_propdb = Object.create(null);
|
||||||
|
return {
|
||||||
|
property_get: function fake_property_get(key, defaultValue) {
|
||||||
|
if (key in fake_propdb) {
|
||||||
|
return fake_propdb[key];
|
||||||
|
}
|
||||||
|
return defaultValue === undefined ? null : defaultValue;
|
||||||
|
},
|
||||||
|
property_set: function fake_property_set(key, value) {
|
||||||
|
fake_propdb[key] = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let c_property_get = lib.declare("property_get", ctypes.default_abi,
|
||||||
|
ctypes.int, // return value: length
|
||||||
|
ctypes.char.ptr, // key
|
||||||
|
ctypes.char.ptr, // value
|
||||||
|
ctypes.char.ptr); // default
|
||||||
|
let c_property_set = lib.declare("property_set", ctypes.default_abi,
|
||||||
|
ctypes.int, // return value: success
|
||||||
|
ctypes.char.ptr, // key
|
||||||
|
ctypes.char.ptr); // value
|
||||||
|
let c_value_buf = ctypes.char.array(SYSTEM_PROPERTY_VALUE_MAX)();
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a system property.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* Name of the property
|
||||||
|
* @param defaultValue [optional]
|
||||||
|
* Default value to return if the property isn't set (default: null)
|
||||||
|
*/
|
||||||
|
property_get: function property_get(key, defaultValue) {
|
||||||
|
if (defaultValue === undefined) {
|
||||||
|
defaultValue = null;
|
||||||
|
}
|
||||||
|
c_property_get(key, c_value_buf, defaultValue);
|
||||||
|
return c_value_buf.readString();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a system property
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* Name of the property
|
||||||
|
* @param value
|
||||||
|
* Value to set the property to.
|
||||||
|
*/
|
||||||
|
property_set: function property_set(key, value) {
|
||||||
|
let rv = c_property_set(key, value);
|
||||||
|
if (rv) {
|
||||||
|
throw Error('libcutils.property_set("' + key + '", "' + value +
|
||||||
|
'") failed with error ' + rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
})();
|
|
@ -657,7 +657,8 @@ SizeOfJSContext();
|
||||||
D(DOM_IPC) \
|
D(DOM_IPC) \
|
||||||
D(DOM_WORKER) \
|
D(DOM_WORKER) \
|
||||||
D(INTER_SLICE_GC) \
|
D(INTER_SLICE_GC) \
|
||||||
D(REFRESH_FRAME)
|
D(REFRESH_FRAME) \
|
||||||
|
D(FULL_GC_TIMER)
|
||||||
|
|
||||||
namespace gcreason {
|
namespace gcreason {
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
{
|
{
|
||||||
"talos_zip": "http://build.mozilla.org/talos/zips/talos.bug721857.05f01e049452.zip"
|
"talos.zip": {
|
||||||
|
"url": "http://build.mozilla.org/talos/zips/talos.bug721857.05f01e049452.zip",
|
||||||
|
"path": ""
|
||||||
|
},
|
||||||
|
"pageloader.xpi": {
|
||||||
|
"url": "http://build.mozilla.org/talos/xpis/pageloader.xpi",
|
||||||
|
"path": "talos/page_load_test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
|
#
|
||||||
|
# Script name: talos_from_code.py
|
||||||
|
# Purpose: Read from a talos.json file the different files to download for a talos job
|
||||||
|
# Author(s): Zambrano Gasparnian, Armen <armenzg@mozilla.com>
|
||||||
|
# Target: Python 2.5
|
||||||
|
#
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
|
@ -8,41 +14,49 @@ import re
|
||||||
import urllib2
|
import urllib2
|
||||||
import urlparse
|
import urlparse
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
'''
|
||||||
|
This script downloads a talos.json file which indicates which files to download
|
||||||
|
for a talos job.
|
||||||
|
See a talos.json file for a better understand:
|
||||||
|
http://hg.mozilla.org/mozilla-central/raw-file/default/testing/talos/talos.json
|
||||||
|
'''
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.add_option("--talos-json-url", dest="talos_json_url", type="string",
|
parser.add_option("--talos-json-url", dest="talos_json_url", type="string",
|
||||||
help="It indicates from where to download the talos.json file.")
|
help="It indicates from where to download the talos.json file.")
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
# 1) check that the url was passed
|
||||||
if options.talos_json_url == None:
|
if options.talos_json_url == None:
|
||||||
print "You need to specify --talos-json-url."
|
print "You need to specify --talos-json-url."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# json file with info on which talos.zip to use
|
# 2) try to download the talos.json file
|
||||||
# the json file URL should look like this:
|
|
||||||
# %(repo_path)s/raw-file/%(revision)s/testing/talos/talos.json
|
|
||||||
try:
|
try:
|
||||||
jsonFilename = download_file(options.talos_json_url)
|
jsonFilename = download_file(options.talos_json_url)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print "ERROR: We have been unable to download the talos.zip indicated " + \
|
print "ERROR: We tried to download the talos.json file but something failed."
|
||||||
"in the talos.json file."
|
|
||||||
print "ERROR: %s" % str(e)
|
print "ERROR: %s" % str(e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print "INFO: talos.json URL: %s" % options.talos_json_url
|
# 3) download the necessary files
|
||||||
talos_zip_url = get_value(jsonFilename, "talos_zip")
|
print "INFO: talos.json URL: %s" % options.talos_json_url
|
||||||
print "INFO: talos.zip URL: '%s'" % talos_zip_url
|
|
||||||
try:
|
try:
|
||||||
if passesRestrictions(options.talos_json_url, talos_zip_url) == False:
|
for key in ('talos.zip', 'pageloader.xpi',):
|
||||||
print "ERROR: You have tried to download a talos.zip from a location " + \
|
entity = get_value(jsonFilename, key)
|
||||||
"different than http://build.mozilla.org/talos/zips"
|
if passesRestrictions(options.talos_json_url, entity["url"]):
|
||||||
print "ERROR: This is only allowed for the 'try' branch."
|
# the key is at the same time the filename e.g. talos.zip
|
||||||
sys.exit(1)
|
download_file(entity["url"], entity["path"], key)
|
||||||
download_file(talos_zip_url, "talos.zip")
|
print "INFO: %s -> %s" % (entity["url"], os.path.join(entity["path"], key))
|
||||||
|
else:
|
||||||
|
print "ERROR: You have tried to download a file " + \
|
||||||
|
"from: %s " % fileUrl + \
|
||||||
|
"which is a location different than http://build.mozilla.org/talos/"
|
||||||
|
print "ERROR: This is only allowed for the certain branches."
|
||||||
|
sys.exit(1)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print "ERROR: We have been unable to download the talos.zip indicated " + \
|
|
||||||
"in the talos.json file."
|
|
||||||
print "ERROR: %s" % str(e)
|
print "ERROR: %s" % str(e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@ -73,15 +87,21 @@ def get_filename_from_url(url):
|
||||||
"but the URL seems to be incorrect."
|
"but the URL seems to be incorrect."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def download_file(url, saveAs=None):
|
def download_file(url, path="", saveAs=None):
|
||||||
'''
|
'''
|
||||||
It downloads a file from the URL indicated and can be saved locally with
|
It downloads a file from URL to the indicated path
|
||||||
a different name if needed.
|
|
||||||
'''
|
'''
|
||||||
req = urllib2.Request(url)
|
req = urllib2.Request(url)
|
||||||
filename = get_filename_from_url(url)
|
|
||||||
f = urllib2.urlopen(req)
|
f = urllib2.urlopen(req)
|
||||||
local_file = open(saveAs if saveAs else filename, 'wb')
|
if path != "" and not os.path.isdir(path):
|
||||||
|
try:
|
||||||
|
os.makedirs(path)
|
||||||
|
print "INFO: directory %s created" % path
|
||||||
|
except Exception, e:
|
||||||
|
print "ERROR: %s" % str(e)
|
||||||
|
sys.exit(1)
|
||||||
|
filename = saveAs if saveAs else get_filename_from_url(url)
|
||||||
|
local_file = open(os.path.join(path, filename), 'wb')
|
||||||
local_file.write(f.read())
|
local_file.write(f.read())
|
||||||
local_file.close()
|
local_file.close()
|
||||||
return filename
|
return filename
|
||||||
|
|
|
@ -12,7 +12,7 @@ Form History test: form field autocomplete
|
||||||
<p id="display"></p>
|
<p id="display"></p>
|
||||||
|
|
||||||
<!-- we presumably can't hide the content for this test. -->
|
<!-- we presumably can't hide the content for this test. -->
|
||||||
<div id="content">
|
<div id="content" style="direction: rtl;">
|
||||||
<!-- unused -->
|
<!-- unused -->
|
||||||
<form id="unused" onsubmit="return false;">
|
<form id="unused" onsubmit="return false;">
|
||||||
<input type="text" name="field1" value="unused">
|
<input type="text" name="field1" value="unused">
|
||||||
|
@ -32,6 +32,7 @@ Form History test: form field autocomplete
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||||
|
|
||||||
var autocompletePopup = getAutocompletePopup();
|
var autocompletePopup = getAutocompletePopup();
|
||||||
|
autocompletePopup.style.direction = "ltr";
|
||||||
|
|
||||||
var input = $_(1, "field1");
|
var input = $_(1, "field1");
|
||||||
|
|
||||||
|
@ -366,6 +367,7 @@ function runTest(testNum) {
|
||||||
case 211:
|
case 211:
|
||||||
checkPopupOpen(false);
|
checkPopupOpen(false);
|
||||||
checkForm("");
|
checkForm("");
|
||||||
|
is(autocompletePopup.style.direction, "rtl", "direction should have been changed from ltr to rtl");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -72,7 +72,6 @@ _TEST_FILES = findbar_window.xul \
|
||||||
test_bug570192.xul \
|
test_bug570192.xul \
|
||||||
test_bug624329.xul \
|
test_bug624329.xul \
|
||||||
bug624329_window.xul \
|
bug624329_window.xul \
|
||||||
test_bug649840.xul \
|
|
||||||
test_popup_preventdefault_chrome.xul \
|
test_popup_preventdefault_chrome.xul \
|
||||||
window_popup_preventdefault_chrome.xul \
|
window_popup_preventdefault_chrome.xul \
|
||||||
test_largemenu.xul \
|
test_largemenu.xul \
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
|
||||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=649840
|
|
||||||
-->
|
|
||||||
<window title="Mozilla Bug 649840"
|
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
||||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
|
||||||
|
|
||||||
<textbox id="textLTR" type="autocomplete" autocompletesearch="simple"/>
|
|
||||||
<textbox id="textRTL" type="autocomplete" autocompletesearch="simple"/>
|
|
||||||
|
|
||||||
<!-- test results are displayed in the html:body -->
|
|
||||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=649840"
|
|
||||||
target="_blank">Mozilla Bug 649840</a>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<!-- test code goes here -->
|
|
||||||
<script type="application/javascript">
|
|
||||||
<![CDATA[
|
|
||||||
/** Test for Bug 649840 **/
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
addLoadEvent(runTest);
|
|
||||||
|
|
||||||
function runTest()
|
|
||||||
{
|
|
||||||
var textLTR = $("textLTR");
|
|
||||||
var textRTL = $("textRTL");
|
|
||||||
|
|
||||||
textLTR.style.direction = "ltr";
|
|
||||||
textRTL.style.direction = "rtl";
|
|
||||||
|
|
||||||
textLTR.value="abcd";
|
|
||||||
textRTL.value="ابجد";
|
|
||||||
|
|
||||||
// open and close the popups to update the popupdir attribute value
|
|
||||||
textLTR.openPopup();
|
|
||||||
textLTR.closePopup();
|
|
||||||
textRTL.openPopup();
|
|
||||||
textRTL.closePopup();
|
|
||||||
|
|
||||||
is(textLTR.popup.style.direction, textLTR.style.direction, "LTR textbox test fails");
|
|
||||||
is(textRTL.popup.style.direction, textRTL.style.direction, "RTL textbox test fails");
|
|
||||||
|
|
||||||
// switch directions of the two textboxes
|
|
||||||
textLTR.style.direction = "rtl";
|
|
||||||
textRTL.style.direction = "ltr";
|
|
||||||
|
|
||||||
// open and close the popups to update the popupdir attribute value
|
|
||||||
textLTR.openPopup();
|
|
||||||
textLTR.closePopup();
|
|
||||||
textRTL.openPopup();
|
|
||||||
textRTL.closePopup();
|
|
||||||
|
|
||||||
is(textLTR.popup.style.direction, textLTR.style.direction, "RTL-switched textbox test fails");
|
|
||||||
is(textRTL.popup.style.direction, textRTL.style.direction, "LTR-switched textbox test fails");
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
]]>
|
|
||||||
</script>
|
|
||||||
</window>
|
|
Загрузка…
Ссылка в новой задаче