mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1239403 - Add JSFUN_HAS_REST flag to JSFunctionSpec entries for self-hosted builtins with ...rest parameters. r=jandem (72ed527b81) - Bug 1238548 - Make GCRuntime::setParameter() fallible r=terrence (52a5bd8044) - Bug 1247679, part 2 - Null check inside TraceCallbackFunc::Trace. r=smaug (ebad38ad73) - bug 1241453 - switch MaiAtkObject to use AccessibleOrProxy r=davidb (42d09b21da) - bug 1241453 - switch MaiHyperLink to use AccessibleOrProxy r=davidb (61a1799bc3) - bug 1241453 - add an AccessibleOrProxy class r=davidb (7882027a59) - bug 1243077 - add AccessibleOrProxy::IsNull() r=davidb (91bf2962a5) - bug 1203861 - use strncmp() instead of nsCString.equals() to compare names r=davidb (1a4f043375) - bug 1243077 - simplify GetRoleCB some r=davidb (37e4ac2e23)
This commit is contained in:
@@ -145,7 +145,7 @@ MaiAtkObject::GetAtkHyperlink()
|
||||
void
|
||||
MaiAtkObject::Shutdown()
|
||||
{
|
||||
accWrap = 0;
|
||||
accWrap.SetBits(0);
|
||||
MaiHyperlink* maiHyperlink =
|
||||
(MaiHyperlink*)g_object_get_qdata(G_OBJECT(this), quark_mai_hyperlink);
|
||||
if (maiHyperlink) {
|
||||
@@ -559,7 +559,7 @@ initializeCB(AtkObject *aAtkObj, gpointer aData)
|
||||
ATK_OBJECT_CLASS(parent_class)->initialize(aAtkObj, aData);
|
||||
|
||||
/* initialize object */
|
||||
MAI_ATK_OBJECT(aAtkObj)->accWrap = reinterpret_cast<uintptr_t>(aData);
|
||||
MAI_ATK_OBJECT(aAtkObj)->accWrap.SetBits(reinterpret_cast<uintptr_t>(aData));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -567,7 +567,7 @@ finalizeCB(GObject *aObj)
|
||||
{
|
||||
if (!IS_MAI_OBJECT(aObj))
|
||||
return;
|
||||
NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap == 0, "AccWrap NOT null");
|
||||
NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap.IsNull(), "AccWrap NOT null");
|
||||
|
||||
// call parent finalize function
|
||||
// finalize of GObjectClass will unref the accessible parent if has
|
||||
@@ -597,7 +597,8 @@ static void
|
||||
MaybeFireNameChange(AtkObject* aAtkObj, const nsString& aNewName)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 newNameUTF8(aNewName);
|
||||
if (aAtkObj->name && newNameUTF8.Equals(aAtkObj->name))
|
||||
if (aAtkObj->name &&
|
||||
!strncmp(aAtkObj->name, newNameUTF8.get(), newNameUTF8.Length()))
|
||||
return;
|
||||
|
||||
// Below we duplicate the functionality of atk_object_set_name(),
|
||||
@@ -649,22 +650,17 @@ getRoleCB(AtkObject *aAtkObj)
|
||||
if (aAtkObj->role != ATK_ROLE_INVALID)
|
||||
return aAtkObj->role;
|
||||
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||
a11y::role role;
|
||||
if (!accWrap) {
|
||||
ProxyAccessible* proxy = GetProxy(aAtkObj);
|
||||
if (!proxy)
|
||||
return ATK_ROLE_INVALID;
|
||||
AccessibleOrProxy acc = GetInternalObj(aAtkObj);
|
||||
if (acc.IsNull()) {
|
||||
return ATK_ROLE_INVALID;
|
||||
}
|
||||
|
||||
role = proxy->Role();
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
if (AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj)) {
|
||||
NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
|
||||
"Does not support Text interface when it should");
|
||||
#endif
|
||||
|
||||
role = accWrap->Role();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ROLE(geckoRole, stringRole, atkRole, macRole, \
|
||||
msaaRole, ia2Role, nameRule) \
|
||||
@@ -672,7 +668,7 @@ getRoleCB(AtkObject *aAtkObj)
|
||||
aAtkObj->role = atkRole; \
|
||||
break;
|
||||
|
||||
switch (role) {
|
||||
switch (acc.Role()) {
|
||||
#include "RoleMap.h"
|
||||
default:
|
||||
MOZ_CRASH("Unknown role.");
|
||||
@@ -1064,7 +1060,7 @@ GetAccessibleWrap(AtkObject* aAtkObj)
|
||||
nullptr);
|
||||
|
||||
uintptr_t accWrapPtr = isMAIObject ?
|
||||
MAI_ATK_OBJECT(aAtkObj)->accWrap :
|
||||
MAI_ATK_OBJECT(aAtkObj)->accWrap.Bits() :
|
||||
reinterpret_cast<uintptr_t>(MAI_ATK_SOCKET(aAtkObj)->accWrap);
|
||||
if (accWrapPtr & IS_PROXY)
|
||||
return nullptr;
|
||||
@@ -1088,11 +1084,10 @@ ProxyAccessible*
|
||||
GetProxy(AtkObject* aObj)
|
||||
{
|
||||
if (!aObj || !IS_MAI_OBJECT(aObj) ||
|
||||
!(MAI_ATK_OBJECT(aObj)->accWrap & IS_PROXY))
|
||||
!MAI_ATK_OBJECT(aObj)->accWrap.IsProxy())
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<ProxyAccessible*>(MAI_ATK_OBJECT(aObj)->accWrap
|
||||
& ~IS_PROXY);
|
||||
return MAI_ATK_OBJECT(aObj)->accWrap.AsProxy();
|
||||
}
|
||||
|
||||
AtkObject*
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "AccessibleOrProxy.h"
|
||||
#include "AccessibleWrap.h"
|
||||
|
||||
namespace mozilla {
|
||||
@@ -95,7 +96,7 @@ struct MaiAtkObject
|
||||
* The AccessibleWrap whose properties and features are exported
|
||||
* via this object instance.
|
||||
*/
|
||||
uintptr_t accWrap;
|
||||
mozilla::a11y::AccessibleOrProxy accWrap;
|
||||
|
||||
/*
|
||||
* Get the AtkHyperlink for this atk object.
|
||||
|
||||
@@ -100,7 +100,7 @@ mai_atk_hyperlink_get_type(void)
|
||||
return type;
|
||||
}
|
||||
|
||||
MaiHyperlink::MaiHyperlink(uintptr_t aHyperLink) :
|
||||
MaiHyperlink::MaiHyperlink(AccessibleOrProxy aHyperLink) :
|
||||
mHyperlink(aHyperLink),
|
||||
mMaiAtkHyperlink(nullptr)
|
||||
{
|
||||
|
||||
@@ -23,31 +23,29 @@ namespace a11y {
|
||||
class MaiHyperlink
|
||||
{
|
||||
public:
|
||||
explicit MaiHyperlink(uintptr_t aHyperLink);
|
||||
explicit MaiHyperlink(AccessibleOrProxy aHyperLink);
|
||||
~MaiHyperlink();
|
||||
|
||||
public:
|
||||
AtkHyperlink* GetAtkHyperlink() const { return mMaiAtkHyperlink; }
|
||||
Accessible* GetAccHyperlink()
|
||||
{
|
||||
if (!mHyperlink || mHyperlink & IS_PROXY)
|
||||
if (!mHyperlink.IsAccessible())
|
||||
return nullptr;
|
||||
|
||||
Accessible* link = reinterpret_cast<Accessible*>(mHyperlink);
|
||||
Accessible* link = mHyperlink.AsAccessible();
|
||||
if (!link) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ASSERTION(link->IsLink(), "Why isn't it a link!");
|
||||
return link;
|
||||
}
|
||||
|
||||
ProxyAccessible* Proxy() const
|
||||
{
|
||||
if (!(mHyperlink & IS_PROXY))
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<ProxyAccessible*>(mHyperlink & ~IS_PROXY);
|
||||
}
|
||||
ProxyAccessible* Proxy() const { return mHyperlink.AsProxy(); }
|
||||
|
||||
protected:
|
||||
uintptr_t mHyperlink;
|
||||
AccessibleOrProxy mHyperlink;
|
||||
AtkHyperlink* mMaiAtkHyperlink;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_a11y_AccessibleOrProxy_h
|
||||
#define mozilla_a11y_AccessibleOrProxy_h
|
||||
|
||||
#include "mozilla/a11y/Accessible.h"
|
||||
#include "mozilla/a11y/ProxyAccessible.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* This class stores an Accessible* or a ProxyAccessible* in a safe manner
|
||||
* with size sizeof(void*).
|
||||
*/
|
||||
class AccessibleOrProxy
|
||||
{
|
||||
public:
|
||||
MOZ_IMPLICIT AccessibleOrProxy(Accessible* aAcc) :
|
||||
mBits(reinterpret_cast<uintptr_t>(aAcc)) {}
|
||||
MOZ_IMPLICIT AccessibleOrProxy(ProxyAccessible* aProxy) :
|
||||
mBits(reinterpret_cast<uintptr_t>(aProxy) | IS_PROXY) {}
|
||||
MOZ_IMPLICIT AccessibleOrProxy(decltype(nullptr)) : mBits(0) {}
|
||||
|
||||
bool IsProxy() const { return mBits & IS_PROXY; }
|
||||
ProxyAccessible* AsProxy() const
|
||||
{
|
||||
if (IsProxy()) {
|
||||
return reinterpret_cast<ProxyAccessible*>(mBits & ~IS_PROXY);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IsAccessible() const { return !IsProxy(); }
|
||||
Accessible* AsAccessible() const
|
||||
{
|
||||
if (IsAccessible()) {
|
||||
return reinterpret_cast<Accessible*>(mBits);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IsNull() const { return mBits == 0; }
|
||||
|
||||
// XXX these are implementation details that ideally would not be exposed.
|
||||
uintptr_t Bits() const { return mBits; }
|
||||
void SetBits(uintptr_t aBits) { mBits = aBits; }
|
||||
|
||||
private:
|
||||
uintptr_t mBits;
|
||||
static const uintptr_t IS_PROXY = 0x1;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -321,43 +321,42 @@ MinorGC(JSContext* cx, unsigned argc, Value* vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define FOR_EACH_GC_PARAM(_) \
|
||||
_("maxBytes", JSGC_MAX_BYTES, true, false) \
|
||||
_("maxMallocBytes", JSGC_MAX_MALLOC_BYTES, true, false) \
|
||||
_("gcBytes", JSGC_BYTES, false, false) \
|
||||
_("gcNumber", JSGC_NUMBER, false, false) \
|
||||
_("mode", JSGC_MODE, true, true) \
|
||||
_("unusedChunks", JSGC_UNUSED_CHUNKS, false, false) \
|
||||
_("totalChunks", JSGC_TOTAL_CHUNKS, false, false) \
|
||||
_("sliceTimeBudget", JSGC_SLICE_TIME_BUDGET, true, false) \
|
||||
_("markStackLimit", JSGC_MARK_STACK_LIMIT, true, false) \
|
||||
_("highFrequencyTimeLimit", JSGC_HIGH_FREQUENCY_TIME_LIMIT, true, false) \
|
||||
_("highFrequencyLowLimit", JSGC_HIGH_FREQUENCY_LOW_LIMIT, true, false) \
|
||||
_("highFrequencyHighLimit", JSGC_HIGH_FREQUENCY_HIGH_LIMIT, true, false) \
|
||||
_("highFrequencyHeapGrowthMax", JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, true, false) \
|
||||
_("highFrequencyHeapGrowthMin", JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, true, false) \
|
||||
_("lowFrequencyHeapGrowth", JSGC_LOW_FREQUENCY_HEAP_GROWTH, true, false) \
|
||||
_("dynamicHeapGrowth", JSGC_DYNAMIC_HEAP_GROWTH, true, true) \
|
||||
_("dynamicMarkSlice", JSGC_DYNAMIC_MARK_SLICE, true, true) \
|
||||
_("allocationThreshold", JSGC_ALLOCATION_THRESHOLD, true, false) \
|
||||
_("decommitThreshold", JSGC_DECOMMIT_THRESHOLD, true, false) \
|
||||
_("minEmptyChunkCount", JSGC_MIN_EMPTY_CHUNK_COUNT, true, true) \
|
||||
_("maxEmptyChunkCount", JSGC_MAX_EMPTY_CHUNK_COUNT, true, true) \
|
||||
_("compactingEnabled", JSGC_COMPACTING_ENABLED, true, true)
|
||||
#define FOR_EACH_GC_PARAM(_) \
|
||||
_("maxBytes", JSGC_MAX_BYTES, true) \
|
||||
_("maxMallocBytes", JSGC_MAX_MALLOC_BYTES, true) \
|
||||
_("gcBytes", JSGC_BYTES, false) \
|
||||
_("gcNumber", JSGC_NUMBER, false) \
|
||||
_("mode", JSGC_MODE, true) \
|
||||
_("unusedChunks", JSGC_UNUSED_CHUNKS, false) \
|
||||
_("totalChunks", JSGC_TOTAL_CHUNKS, false) \
|
||||
_("sliceTimeBudget", JSGC_SLICE_TIME_BUDGET, true) \
|
||||
_("markStackLimit", JSGC_MARK_STACK_LIMIT, true) \
|
||||
_("highFrequencyTimeLimit", JSGC_HIGH_FREQUENCY_TIME_LIMIT, true) \
|
||||
_("highFrequencyLowLimit", JSGC_HIGH_FREQUENCY_LOW_LIMIT, true) \
|
||||
_("highFrequencyHighLimit", JSGC_HIGH_FREQUENCY_HIGH_LIMIT, true) \
|
||||
_("highFrequencyHeapGrowthMax", JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, true) \
|
||||
_("highFrequencyHeapGrowthMin", JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, true) \
|
||||
_("lowFrequencyHeapGrowth", JSGC_LOW_FREQUENCY_HEAP_GROWTH, true) \
|
||||
_("dynamicHeapGrowth", JSGC_DYNAMIC_HEAP_GROWTH, true) \
|
||||
_("dynamicMarkSlice", JSGC_DYNAMIC_MARK_SLICE, true) \
|
||||
_("allocationThreshold", JSGC_ALLOCATION_THRESHOLD, true) \
|
||||
_("decommitThreshold", JSGC_DECOMMIT_THRESHOLD, true) \
|
||||
_("minEmptyChunkCount", JSGC_MIN_EMPTY_CHUNK_COUNT, true) \
|
||||
_("maxEmptyChunkCount", JSGC_MAX_EMPTY_CHUNK_COUNT, true) \
|
||||
_("compactingEnabled", JSGC_COMPACTING_ENABLED, true)
|
||||
|
||||
static const struct ParamInfo {
|
||||
const char* name;
|
||||
JSGCParamKey param;
|
||||
bool writable;
|
||||
bool allowZero;
|
||||
} paramMap[] = {
|
||||
#define DEFINE_PARAM_INFO(name, key, writable, allowZero) \
|
||||
{name, key, writable, allowZero},
|
||||
#define DEFINE_PARAM_INFO(name, key, writable) \
|
||||
{name, key, writable},
|
||||
FOR_EACH_GC_PARAM(DEFINE_PARAM_INFO)
|
||||
#undef DEFINE_PARAM_INFO
|
||||
};
|
||||
|
||||
#define PARAM_NAME_LIST_ENTRY(name, key, writable, allowZero) \
|
||||
#define PARAM_NAME_LIST_ENTRY(name, key, writable) \
|
||||
" " name
|
||||
#define GC_PARAMETER_ARGS_LIST FOR_EACH_GC_PARAM(PARAM_NAME_LIST_ENTRY)
|
||||
|
||||
@@ -414,12 +413,6 @@ GCParameter(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
uint32_t value = floor(d);
|
||||
if (!info.allowZero && value == 0) {
|
||||
JS_ReportError(cx, "the second argument must be convertable to uint32_t "
|
||||
"with non-zero value");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param == JSGC_MARK_STACK_LIMIT && JS::IsIncrementalGCInProgress(cx->runtime())) {
|
||||
JS_ReportError(cx, "attempt to set markStackLimit while a GC is in progress");
|
||||
return false;
|
||||
@@ -436,7 +429,18 @@ GCParameter(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
}
|
||||
|
||||
JS_SetGCParameter(cx->runtime(), param, value);
|
||||
bool ok;
|
||||
{
|
||||
JSRuntime* rt = cx->runtime();
|
||||
AutoLockGC lock(rt);
|
||||
ok = rt->gc.setParameter(param, value, lock);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
JS_ReportError(cx, "Parameter value out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,8 +231,8 @@ const Class js::ScalarTypeDescr::class_ = {
|
||||
|
||||
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
|
||||
JS_SELF_HOSTED_FN("toSource", "DescrToSource", 0, 0),
|
||||
{"array", {nullptr, nullptr}, 0, 0, "ArrayShorthand"},
|
||||
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
|
||||
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, JSFUN_HAS_REST),
|
||||
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
||||
@@ -154,8 +154,8 @@ class GCSchedulingTunables
|
||||
/*
|
||||
* Controls the number of empty chunks reserved for future allocation.
|
||||
*/
|
||||
unsigned minEmptyChunkCount_;
|
||||
unsigned maxEmptyChunkCount_;
|
||||
uint32_t minEmptyChunkCount_;
|
||||
uint32_t maxEmptyChunkCount_;
|
||||
|
||||
public:
|
||||
GCSchedulingTunables()
|
||||
@@ -190,7 +190,7 @@ class GCSchedulingTunables
|
||||
unsigned minEmptyChunkCount(const AutoLockGC&) const { return minEmptyChunkCount_; }
|
||||
unsigned maxEmptyChunkCount() const { return maxEmptyChunkCount_; }
|
||||
|
||||
void setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock);
|
||||
bool setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -593,7 +593,7 @@ class GCRuntime
|
||||
void removeRoot(Value* vp);
|
||||
void setMarkStackLimit(size_t limit, AutoLockGC& lock);
|
||||
|
||||
void setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock);
|
||||
bool setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock);
|
||||
uint32_t getParameter(JSGCParamKey key, const AutoLockGC& lock);
|
||||
|
||||
bool triggerGC(JS::gcreason::Reason reason);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// |jit-test| error: Error
|
||||
gcparam("highFrequencyHeapGrowthMax", 1);
|
||||
+5
-2
@@ -1460,7 +1460,7 @@ JS_PUBLIC_API(void)
|
||||
JS_SetGCParameter(JSRuntime* rt, JSGCParamKey key, uint32_t value)
|
||||
{
|
||||
AutoLockGC lock(rt);
|
||||
rt->gc.setParameter(key, value, lock);
|
||||
MOZ_ALWAYS_TRUE(rt->gc.setParameter(key, value, lock));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
@@ -3401,7 +3401,10 @@ JS::NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return &funVal.toObject().as<JSFunction>();
|
||||
JSFunction* fun = &funVal.toObject().as<JSFunction>();
|
||||
if (fs->flags & JSFUN_HAS_REST)
|
||||
fun->setHasRest();
|
||||
return fun;
|
||||
}
|
||||
|
||||
RootedAtom atom(cx, IdToFunctionName(cx, id));
|
||||
|
||||
+3
-1
@@ -840,7 +840,9 @@ class MOZ_STACK_CLASS SourceBufferHolder final
|
||||
*/
|
||||
#define JSFUN_GENERIC_NATIVE 0x800
|
||||
|
||||
#define JSFUN_FLAGS_MASK 0xe00 /* | of all the JSFUN_* flags */
|
||||
#define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */
|
||||
|
||||
#define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */
|
||||
|
||||
/*
|
||||
* If set, will allow redefining a non-configurable property, but only on a
|
||||
|
||||
+1
-1
@@ -1671,7 +1671,7 @@ const JSFunctionSpec js::function_methods[] = {
|
||||
JS_FN(js_apply_str, fun_apply, 2,0),
|
||||
JS_FN(js_call_str, fun_call, 1,0),
|
||||
JS_FN("isGenerator", fun_isGenerator,0,0),
|
||||
JS_SELF_HOSTED_FN("bind", "FunctionBind", 1,JSPROP_DEFINE_LATE),
|
||||
JS_SELF_HOSTED_FN("bind", "FunctionBind", 2,JSPROP_DEFINE_LATE|JSFUN_HAS_REST),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
||||
+45
-18
@@ -1293,7 +1293,7 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
|
||||
* for default backward API compatibility.
|
||||
*/
|
||||
AutoLockGC lock(rt);
|
||||
tunables.setParameter(JSGC_MAX_BYTES, maxbytes, lock);
|
||||
MOZ_ALWAYS_TRUE(tunables.setParameter(JSGC_MAX_BYTES, maxbytes, lock));
|
||||
setMaxMallocBytes(maxbytes);
|
||||
|
||||
const char* size = getenv("JSGC_MARK_STACK_LIMIT");
|
||||
@@ -1401,7 +1401,7 @@ GCRuntime::finishRoots()
|
||||
FinishPersistentRootedChains(rt->mainThread.roots);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
GCRuntime::setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock)
|
||||
{
|
||||
switch (key) {
|
||||
@@ -1420,24 +1420,30 @@ GCRuntime::setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock)
|
||||
decommitThreshold = (uint64_t)value * 1024 * 1024;
|
||||
break;
|
||||
case JSGC_MODE:
|
||||
if (mode != JSGC_MODE_GLOBAL &&
|
||||
mode != JSGC_MODE_COMPARTMENT &&
|
||||
mode != JSGC_MODE_INCREMENTAL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mode = JSGCMode(value);
|
||||
MOZ_ASSERT(mode == JSGC_MODE_GLOBAL ||
|
||||
mode == JSGC_MODE_COMPARTMENT ||
|
||||
mode == JSGC_MODE_INCREMENTAL);
|
||||
break;
|
||||
case JSGC_COMPACTING_ENABLED:
|
||||
compactingEnabled = value != 0;
|
||||
break;
|
||||
default:
|
||||
tunables.setParameter(key, value, lock);
|
||||
if (!tunables.setParameter(key, value, lock))
|
||||
return false;
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
zone->threshold.updateAfterGC(zone->usage.gcBytes(), GC_NORMAL, tunables,
|
||||
schedulingState, lock);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock)
|
||||
{
|
||||
switch(key) {
|
||||
@@ -1447,31 +1453,50 @@ GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoL
|
||||
case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
|
||||
highFrequencyThresholdUsec_ = value * PRMJ_USEC_PER_MSEC;
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_LOW_LIMIT:
|
||||
highFrequencyLowLimitBytes_ = (uint64_t)value * 1024 * 1024;
|
||||
case JSGC_HIGH_FREQUENCY_LOW_LIMIT: {
|
||||
uint64_t newLimit = (uint64_t)value * 1024 * 1024;
|
||||
if (newLimit == UINT64_MAX)
|
||||
return false;
|
||||
highFrequencyLowLimitBytes_ = newLimit;
|
||||
if (highFrequencyLowLimitBytes_ >= highFrequencyHighLimitBytes_)
|
||||
highFrequencyHighLimitBytes_ = highFrequencyLowLimitBytes_ + 1;
|
||||
MOZ_ASSERT(highFrequencyHighLimitBytes_ > highFrequencyLowLimitBytes_);
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_HIGH_LIMIT:
|
||||
MOZ_ASSERT(value > 0);
|
||||
highFrequencyHighLimitBytes_ = (uint64_t)value * 1024 * 1024;
|
||||
}
|
||||
case JSGC_HIGH_FREQUENCY_HIGH_LIMIT: {
|
||||
uint64_t newLimit = (uint64_t)value * 1024 * 1024;
|
||||
if (newLimit == 0)
|
||||
return false;
|
||||
highFrequencyHighLimitBytes_ = newLimit;
|
||||
if (highFrequencyHighLimitBytes_ <= highFrequencyLowLimitBytes_)
|
||||
highFrequencyLowLimitBytes_ = highFrequencyHighLimitBytes_ - 1;
|
||||
MOZ_ASSERT(highFrequencyHighLimitBytes_ > highFrequencyLowLimitBytes_);
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX:
|
||||
highFrequencyHeapGrowthMax_ = value / 100.0;
|
||||
}
|
||||
case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX: {
|
||||
double newGrowth = value / 100.0;
|
||||
if (newGrowth <= 0.85)
|
||||
return false;
|
||||
highFrequencyHeapGrowthMax_ = newGrowth;
|
||||
MOZ_ASSERT(highFrequencyHeapGrowthMax_ / 0.85 > 1.0);
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN:
|
||||
highFrequencyHeapGrowthMin_ = value / 100.0;
|
||||
}
|
||||
case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN: {
|
||||
double newGrowth = value / 100.0;
|
||||
if (newGrowth <= 0.85)
|
||||
return false;
|
||||
highFrequencyHeapGrowthMin_ = newGrowth;
|
||||
MOZ_ASSERT(highFrequencyHeapGrowthMin_ / 0.85 > 1.0);
|
||||
break;
|
||||
case JSGC_LOW_FREQUENCY_HEAP_GROWTH:
|
||||
lowFrequencyHeapGrowth_ = value / 100.0;
|
||||
}
|
||||
case JSGC_LOW_FREQUENCY_HEAP_GROWTH: {
|
||||
double newGrowth = value / 100.0;
|
||||
if (newGrowth <= 0.9)
|
||||
return false;
|
||||
lowFrequencyHeapGrowth_ = newGrowth;
|
||||
MOZ_ASSERT(lowFrequencyHeapGrowth_ / 0.9 > 1.0);
|
||||
break;
|
||||
}
|
||||
case JSGC_DYNAMIC_HEAP_GROWTH:
|
||||
dynamicHeapGrowthEnabled_ = value != 0;
|
||||
break;
|
||||
@@ -1496,6 +1521,8 @@ GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoL
|
||||
default:
|
||||
MOZ_CRASH("Unknown GC parameter.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
+1
-1
@@ -4243,7 +4243,7 @@ static const JSFunctionSpec string_static_methods[] = {
|
||||
JS_INLINABLE_FN("fromCharCode", js::str_fromCharCode, 1, 0, StringFromCharCode),
|
||||
|
||||
JS_SELF_HOSTED_FN("fromCodePoint", "String_static_fromCodePoint", 1,0),
|
||||
JS_SELF_HOSTED_FN("raw", "String_static_raw", 1,0),
|
||||
JS_SELF_HOSTED_FN("raw", "String_static_raw", 2,JSFUN_HAS_REST),
|
||||
JS_SELF_HOSTED_FN("substring", "String_static_substring", 3,0),
|
||||
JS_SELF_HOSTED_FN("substr", "String_static_substr", 3,0),
|
||||
JS_SELF_HOSTED_FN("slice", "String_static_slice", 3,0),
|
||||
|
||||
@@ -301,7 +301,7 @@ MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
|
||||
|
||||
RootedFunction ctor(cx);
|
||||
if (!cx->runtime()->createLazySelfHostedFunctionClone(cx, selfHostedName, name,
|
||||
/* nargs = */ 0,
|
||||
/* nargs = */ !!derived,
|
||||
proto, TenuredObject, &ctor))
|
||||
{
|
||||
return nullptr;
|
||||
@@ -309,6 +309,8 @@ MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
|
||||
|
||||
ctor->setIsConstructor();
|
||||
ctor->setIsClassConstructor();
|
||||
if (derived)
|
||||
ctor->setHasRest();
|
||||
|
||||
MOZ_ASSERT(ctor->infallibleIsDefaultClassConstructor(cx));
|
||||
|
||||
|
||||
@@ -2276,19 +2276,8 @@ JSRuntime::cloneSelfHostedFunctionScript(JSContext* cx, HandlePropertyName name,
|
||||
return false;
|
||||
MOZ_ASSERT(!targetFun->isInterpretedLazy());
|
||||
|
||||
// ...rest args don't count as formal args, but are included in nargs. We don't,
|
||||
// however, want to introduce a flag "has rest args" in the declaration of
|
||||
// self-hosted functions, so we fix up the flag and the nargs value here.
|
||||
// Since the target function might have been cloned and relazified before,
|
||||
// this only happens if the target function isn't marked as having rest
|
||||
// args.
|
||||
MOZ_ASSERT(sourceFun->nargs() - sourceFun->hasRest() ==
|
||||
targetFun->nargs() - targetFun->hasRest());
|
||||
MOZ_ASSERT_IF(targetFun->hasRest(), sourceFun->hasRest());
|
||||
if (sourceFun->hasRest() && !targetFun->hasRest()) {
|
||||
targetFun->setHasRest();
|
||||
targetFun->setArgCount(sourceFun->nargs());
|
||||
}
|
||||
MOZ_ASSERT(sourceFun->nargs() == targetFun->nargs());
|
||||
MOZ_ASSERT(sourceFun->hasRest() == targetFun->hasRest());
|
||||
|
||||
// The target function might have been relazified after its flags changed.
|
||||
targetFun->setFlags(targetFun->flags() | sourceFun->flags());
|
||||
|
||||
@@ -58,40 +58,52 @@ void
|
||||
TraceCallbackFunc::Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
if (aPtr->get()) {
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JSObject** aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
|
||||
if (*aPtr) {
|
||||
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(aPtr->getPtr()), aName, aClosure);
|
||||
if (aPtr->getPtr()) {
|
||||
mCallback(JS::GCCellPtr(aPtr->getPtr()), aName, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JS::Heap<JSFunction*>* aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
if (aPtr->get()) {
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JS::Heap<JSString*>* aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
if (aPtr->get()) {
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JS::Heap<JSScript*>* aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
if (aPtr->get()) {
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,11 +468,10 @@ DowncastCCParticipant(void* aPtr)
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Trace(s, aCallbacks, aClosure);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(_field) \
|
||||
if (tmp->_field) \
|
||||
aCallbacks.Trace(&tmp->_field, #_field, aClosure);
|
||||
aCallbacks.Trace(&tmp->_field, #_field, aClosure);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(_field) \
|
||||
aCallbacks.Trace(&tmp->_field, #_field, aClosure);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(_field)
|
||||
|
||||
// NB: The (void)tmp; hack in the TRACE_END macro exists to support
|
||||
// implementations that don't need to do anything in their Trace method.
|
||||
|
||||
Reference in New Issue
Block a user