Merge TM -> JM

This commit is contained in:
Brian Hackett 2011-06-01 11:22:03 -07:00
commit ca3b30dcbc
21 changed files with 124 additions and 142 deletions

View File

@ -914,7 +914,6 @@ nsDOMWorkerScope::Trace(nsIXPConnectWrappedNative* /* aWrapper */,
JSTracer* aTracer,
JSObject* /*aObj */)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsDOMWorkerMessageHandler::Trace(aTracer);
return NS_OK;
}
@ -1509,8 +1508,6 @@ nsDOMWorker::Trace(nsIXPConnectWrappedNative* /* aWrapper */,
JSTracer* aTracer,
JSObject* /*aObj */)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
PRBool canceled = PR_FALSE;
{
MutexAutoLock lock(mLock);

View File

@ -430,8 +430,6 @@ nsDOMWorkerXHR::Trace(nsIXPConnectWrappedNative* /* aWrapper */,
JSTracer* aTracer,
JSObject* /*aObj */)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mCanceled) {
nsDOMWorkerMessageHandler::Trace(aTracer);
if (mUpload) {

View File

@ -1008,11 +1008,6 @@
#define ENABLE_JIT 0
#endif
/* JIT is not implemented for 64 bit on MSVC */
#if !defined(ENABLE_JIT) && WTF_COMPILER_MSVC && WTF_CPU_X86_64
#define ENABLE_JIT 0
#endif
/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */
#if !defined(ENABLE_JIT) \
&& (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_MIPS) \

View File

@ -327,7 +327,7 @@ def run_tests(tests, test_dir, lib_dir, shell_args):
def show_test(test):
if OPTIONS.show_failed:
print(' ' + subprocess.list2cmdline(get_test_cmd(test.path, test.jitflags, lib_dir)))
print(' ' + subprocess.list2cmdline(get_test_cmd(test.path, test.jitflags, lib_dir, shell_args)))
else:
print(' ' + ' '.join(test.jitflags + [ test.path ]))
@ -494,6 +494,8 @@ def main(argv):
job_list.append(new_test)
shell_args = shlex.split(OPTIONS.shell_args)
if OPTIONS.debug:
if len(job_list) > 1:
print('Multiple tests match command line arguments, debugger can only run one')
@ -502,12 +504,10 @@ def main(argv):
sys.exit(1)
tc = job_list[0]
cmd = [ 'gdb', '--args' ] + get_test_cmd(tc.path, tc.jitflags, lib_dir)
cmd = [ 'gdb', '--args' ] + get_test_cmd(tc.path, tc.jitflags, lib_dir, shell_args)
call(cmd)
sys.exit()
shell_args = shlex.split(OPTIONS.shell_args)
try:
ok = run_tests(job_list, test_dir, lib_dir, shell_args)
if not ok:

View File

@ -1,8 +1,8 @@
/* Bug 614653 - This test .2 seconds with the fix, 20 minutes without. */
for (var i = 0; i < 100; ++i) {
for (var i = 0; i < 10; ++i) {
var arr = [];
var s = "abcdefghijklmnop";
for (var i = 0; i < 50000; ++i) {
for (var j = 0; j < 50000; ++j) {
s = "<" + s + ">";
arr.push(s);
}

View File

@ -0,0 +1,13 @@
for (var i = 0; i < 10; ++i) {
var arr = [];
var s = "abcdefghijklmnop";
for (var j = 0; j < 5000; ++j) {
s = "<" + s + ">";
arr.push(s);
}
gc();
for (var j = 0; j < 5000; ++j) {
arr[j].search("a");
}
gc();
}

View File

@ -427,6 +427,7 @@ struct JSRuntime {
/* Pre-allocated space for the GC mark stacks. Pointer type ensures alignment. */
void *gcMarkStackObjs[js::OBJECT_MARK_STACK_SIZE / sizeof(void *)];
void *gcMarkStackRopes[js::ROPES_MARK_STACK_SIZE / sizeof(void *)];
void *gcMarkStackXMLs[js::XML_MARK_STACK_SIZE / sizeof(void *)];
void *gcMarkStackLarges[js::LARGE_MARK_STACK_SIZE / sizeof(void *)];

View File

@ -1514,6 +1514,7 @@ GCMarker::GCMarker(JSContext *cx)
: color(0),
unmarkedArenaStackTop(MarkingDelay::stackBottom()),
objStack(cx->runtime->gcMarkStackObjs, sizeof(cx->runtime->gcMarkStackObjs)),
ropeStack(cx->runtime->gcMarkStackRopes, sizeof(cx->runtime->gcMarkStackRopes)),
xmlStack(cx->runtime->gcMarkStackXMLs, sizeof(cx->runtime->gcMarkStackXMLs)),
largeStack(cx->runtime->gcMarkStackLarges, sizeof(cx->runtime->gcMarkStackLarges))
{

View File

@ -1185,6 +1185,7 @@ struct LargeMarkItem
};
static const size_t OBJECT_MARK_STACK_SIZE = 32768 * sizeof(JSObject *);
static const size_t ROPES_MARK_STACK_SIZE = 1024 * sizeof(JSString *);
static const size_t XML_MARK_STACK_SIZE = 1024 * sizeof(JSXML *);
static const size_t LARGE_MARK_STACK_SIZE = 64 * sizeof(LargeMarkItem);
@ -1212,6 +1213,7 @@ struct GCMarker : public JSTracer {
#endif
MarkStack<JSObject *> objStack;
MarkStack<JSRope *> ropeStack;
MarkStack<JSXML *> xmlStack;
MarkStack<LargeMarkItem> largeStack;
@ -1234,7 +1236,10 @@ struct GCMarker : public JSTracer {
void markDelayedChildren();
bool isMarkStackEmpty() {
return objStack.isEmpty() && xmlStack.isEmpty() && largeStack.isEmpty();
return objStack.isEmpty() &&
ropeStack.isEmpty() &&
xmlStack.isEmpty() &&
largeStack.isEmpty();
}
JS_FRIEND_API(void) drainMarkStack();
@ -1244,6 +1249,11 @@ struct GCMarker : public JSTracer {
delayMarkingChildren(obj);
}
void pushRope(JSRope *rope) {
if (!ropeStack.push(rope))
delayMarkingChildren(rope);
}
void pushXML(JSXML *xml) {
if (!xmlStack.push(xml))
delayMarkingChildren(xml);

View File

@ -527,6 +527,34 @@ restart:
goto restart;
}
static inline void
ScanRope(GCMarker *gcmarker, JSRope *rope)
{
JS_ASSERT_IF(gcmarker->context->runtime->gcCurrentCompartment,
rope->compartment() == gcmarker->context->runtime->gcCurrentCompartment
|| rope->compartment() == gcmarker->context->runtime->atomsCompartment);
JS_ASSERT(rope->isMarked());
JSString *leftChild = NULL;
do {
JSString *rightChild = rope->rightChild();
if (rightChild->isRope()) {
if (rightChild->markIfUnmarked())
gcmarker->pushRope(&rightChild->asRope());
} else {
rightChild->asLinear().mark(gcmarker);
}
leftChild = rope->leftChild();
if (leftChild->isLinear()) {
leftChild->asLinear().mark(gcmarker);
return;
}
rope = &leftChild->asRope();
} while (leftChild->markIfUnmarked());
}
static inline void
PushMarkStack(GCMarker *gcmarker, JSString *str)
{
@ -534,7 +562,13 @@ PushMarkStack(GCMarker *gcmarker, JSString *str)
str->compartment() == gcmarker->context->runtime->gcCurrentCompartment
|| str->compartment() == gcmarker->context->runtime->atomsCompartment);
str->mark(gcmarker);
if (str->isLinear()) {
str->asLinear().mark(gcmarker);
} else {
JS_ASSERT(str->isRope());
if (str->markIfUnmarked())
ScanRope(gcmarker, &str->asRope());
}
}
static const uintN LARGE_OBJECT_CHUNK_SIZE = 2048;
@ -708,6 +742,9 @@ void
GCMarker::drainMarkStack()
{
while (!isMarkStackEmpty()) {
while (!ropeStack.isEmpty())
ScanRope(this, ropeStack.pop());
while (!objStack.isEmpty())
ScanObject(this, objStack.pop());

View File

@ -113,26 +113,6 @@ JSString::isExternal() const
return is_external;
}
static JS_ALWAYS_INLINE JSString *
Tag(JSRope *str)
{
JS_ASSERT(!(size_t(str) & 1));
return (JSString *)(size_t(str) | 1);
}
static JS_ALWAYS_INLINE bool
Tagged(JSString *str)
{
return (size_t(str) & 1) != 0;
}
static JS_ALWAYS_INLINE JSRope *
Untag(JSString *str)
{
JS_ASSERT((size_t(str) & 1) == 1);
return (JSRope *)(size_t(str) & ~size_t(1));
}
void
JSLinearString::mark(JSTracer *)
{
@ -141,64 +121,6 @@ JSLinearString::mark(JSTracer *)
str = str->asDependent().base();
}
void
JSString::mark(JSTracer *trc)
{
if (isLinear()) {
asLinear().mark(trc);
return;
}
/*
* This function must not fail, so a simple stack-based traversal must not
* be used (since it may oom if the stack grows large). Instead, strings
* are temporarily mutated to embed parent pointers as they are traversed.
* This algorithm is homomorphic to JSString::flatten.
*/
JSRope *str = &asRope();
JSRope *parent = NULL;
first_visit_node: {
if (!str->markIfUnmarked())
goto finish_node;
JS_ASSERT(!Tagged(str->d.u1.left) && !Tagged(str->d.s.u2.right));
JSString *left = str->d.u1.left;
if (left->isRope()) {
str->d.u1.left = Tag(parent);
parent = str;
str = &left->asRope();
goto first_visit_node;
}
left->asLinear().mark(trc);
}
visit_right_child: {
JSString *right = str->d.s.u2.right;
if (right->isRope()) {
str->d.s.u2.right = Tag(parent);
parent = str;
str = &right->asRope();
goto first_visit_node;
}
right->asLinear().mark(trc);
}
finish_node: {
if (!parent)
return;
if (Tagged(parent->d.u1.left)) {
JS_ASSERT(!Tagged(parent->d.s.u2.right));
JSRope *nextParent = Untag(parent->d.u1.left);
parent->d.u1.left = str;
str = parent;
parent = nextParent;
goto visit_right_child;
}
JSRope *nextParent = Untag(parent->d.s.u2.right);
parent->d.s.u2.right = str;
str = parent;
parent = nextParent;
goto finish_node;
}
}
static JS_ALWAYS_INLINE size_t
RopeCapacityFor(size_t length)
{

View File

@ -371,10 +371,6 @@ class JSString : public js::gc::Cell
inline void finalize(JSContext *cx);
/* Called during GC for any string. */
void mark(JSTracer *trc);
/* Offsets for direct field from jit code. */
static size_t offsetOfLengthAndFlags() {
@ -413,9 +409,10 @@ JS_STATIC_ASSERT(sizeof(JSRope) == sizeof(JSString));
class JSLinearString : public JSString
{
friend class JSString;
void mark(JSTracer *trc);
public:
void mark(JSTracer *trc);
JS_ALWAYS_INLINE
const jschar *chars() const {
JS_ASSERT(isLinear());

View File

@ -1969,7 +1969,7 @@ stubs::DecGlobalName(VMFrame &f, JSAtom *atom)
template void JS_FASTCALL stubs::DecGlobalName<true>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::DecGlobalName<false>(VMFrame &f, JSAtom *atom);
static bool JS_FASTCALL
static bool JS_ALWAYS_INLINE
InlineGetProp(VMFrame &f)
{
JSContext *cx = f.cx;

View File

@ -135,7 +135,7 @@ Unwrap(JSContext *cx, JSObject *wrapper)
}
JSObject *
UnsafeUnwrapSecurityWrapper(JSContext *cx, JSObject *obj)
UnsafeUnwrapSecurityWrapper(JSObject *obj)
{
if (obj->isProxy()) {
return obj->unwrap();

View File

@ -96,7 +96,7 @@ JSObject *
Unwrap(JSContext *cx, JSObject *wrapper);
JSObject *
UnsafeUnwrapSecurityWrapper(JSContext *cx, JSObject *obj);
UnsafeUnwrapSecurityWrapper(JSObject *obj);
} // namespace XPCWrapper

View File

@ -3017,7 +3017,7 @@ SandboxImport(JSContext *cx, uintN argc, jsval *vp)
// NB: funobj must only be used to get the JSFunction out.
JSObject *funobj = JSVAL_TO_OBJECT(argv[0]);
if (funobj->isProxy()) {
funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(cx, funobj);
funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj);
}
JSAutoEnterCompartment ac;
@ -3560,7 +3560,7 @@ xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
}
#endif
sandbox = XPCWrapper::UnsafeUnwrapSecurityWrapper(cx, sandbox);
sandbox = XPCWrapper::UnsafeUnwrapSecurityWrapper(sandbox);
if (!sandbox || sandbox->getJSClass() != &SandboxClass) {
return NS_ERROR_INVALID_ARG;
}

View File

@ -1442,10 +1442,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj);
(clazz) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass || \
(clazz) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass)
// Comes from xpcwrappednativeops.cpp
extern void
xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper);
/***************************************************************************/
namespace XPCWrapper {
@ -2579,6 +2575,8 @@ public:
// If pobj2 is not null and *pobj2 is not null after the call then *pobj2
// points to an object for which IS_SLIM_WRAPPER_OBJECT is true.
// cx is null when invoked from the marking phase of the GC. In this case
// fubobj must be null as well.
static XPCWrappedNative*
GetWrappedNativeOfJSObject(JSContext* cx, JSObject* obj,
JSObject* funobj = nsnull,

View File

@ -1751,6 +1751,12 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
{
NS_PRECONDITION(obj, "bad param");
// fubobj must be null if called without cx.
NS_PRECONDITION(cx || !funobj, "bad param");
// *pTeaorOff must be null if pTearOff is given
NS_PRECONDITION(!pTearOff || !*pTearOff, "bad param");
JSObject* cur;
XPCWrappedNativeProto* proto = nsnull;
@ -1770,7 +1776,7 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
if(IS_PROTO_CLASS(funObjParentClass))
{
NS_ASSERTION(funObjParent->getParent(), "funobj's parent (proto) is global");
proto = (XPCWrappedNativeProto*) xpc_GetJSPrivate(funObjParent);
proto = (XPCWrappedNativeProto*) funObjParent->getPrivate();
if(proto)
protoClassInfo = proto->GetClassInfo();
}
@ -1792,6 +1798,7 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
}
}
restart:
for(cur = obj; cur; cur = cur->getProto())
{
// this is on two lines to make the compiler happy given the goto.
@ -1803,7 +1810,7 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
return_wrapper:
JSBool isWN = IS_WN_WRAPPER_OBJECT(cur);
XPCWrappedNative* wrapper =
isWN ? (XPCWrappedNative*) xpc_GetJSPrivate(cur) : nsnull;
isWN ? (XPCWrappedNative*) cur->getPrivate() : nsnull;
if(proto)
{
XPCWrappedNativeProto* wrapper_proto =
@ -1822,7 +1829,7 @@ return_wrapper:
{
return_tearoff:
XPCWrappedNative* wrapper =
(XPCWrappedNative*) xpc_GetJSPrivate(cur->getParent());
(XPCWrappedNative*) cur->getParent()->getPrivate();
if(proto && proto != wrapper->GetProto() &&
(proto->GetScope() != wrapper->GetScope() ||
!protoClassInfo || !wrapper->GetProto() ||
@ -1830,8 +1837,7 @@ return_tearoff:
continue;
if(pobj2)
*pobj2 = nsnull;
XPCWrappedNativeTearOff* to =
(XPCWrappedNativeTearOff*) xpc_GetJSPrivate(cur);
XPCWrappedNativeTearOff* to = (XPCWrappedNativeTearOff*) cur->getPrivate();
if(!to)
return nsnull;
if(pTearOff)
@ -1840,10 +1846,14 @@ return_tearoff:
}
// Unwrap any wrapper wrappers.
JSObject *unsafeObj;
if((unsafeObj = XPCWrapper::Unwrap(cx, cur)))
return GetWrappedNativeOfJSObject(cx, unsafeObj, funobj, pobj2,
pTearOff);
JSObject *unsafeObj = cx
? XPCWrapper::Unwrap(cx, cur)
: XPCWrapper::UnsafeUnwrapSecurityWrapper(cur);
if(unsafeObj)
{
obj = unsafeObj;
goto restart;
}
}
if(pobj2)

View File

@ -713,8 +713,8 @@ TraceScopeJSObjects(JSTracer *trc, XPCWrappedNativeScope* scope)
}
}
void
xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper)
static void
TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper)
{
// NOTE: It might be nice to also do the wrapper->Mark() call here too
// when we are called during the marking phase of JS GC to mark the
@ -743,17 +743,23 @@ xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper)
}
static void
XPC_WN_Shared_Trace(JSTracer *trc, JSObject *obj)
MarkWrappedNative(JSTracer *trc, JSObject *obj, bool helper)
{
JSObject *obj2;
// Pass null for the first JSContext* parameter to skip any security
// checks and to avoid potential state change there.
XPCWrappedNative* wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj, nsnull,
&obj2);
XPCWrappedNative::GetWrappedNativeOfJSObject(nsnull, obj, nsnull, &obj2);
if(wrapper)
{
if(wrapper->IsValid())
xpc_TraceForValidWrapper(trc, wrapper);
{
if(helper)
wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
TraceForValidWrapper(trc, wrapper);
}
}
else if(obj2)
{
@ -761,6 +767,12 @@ XPC_WN_Shared_Trace(JSTracer *trc, JSObject *obj)
}
}
static void
XPC_WN_Shared_Trace(JSTracer *trc, JSObject *obj)
{
MarkWrappedNative(trc, obj, false);
}
static JSBool
XPC_WN_NoHelper_Resolve(JSContext *cx, JSObject *obj, jsid id)
{
@ -1098,22 +1110,7 @@ XPC_WN_Helper_Finalize(JSContext *cx, JSObject *obj)
static void
XPC_WN_Helper_Trace(JSTracer *trc, JSObject *obj)
{
JSObject *obj2;
XPCWrappedNative* wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj, nsnull,
&obj2);
if(wrapper)
{
if(wrapper->IsValid())
{
wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
xpc_TraceForValidWrapper(trc, wrapper);
}
}
else if(obj2)
{
GetSlimWrapperProto(obj2)->TraceJS(trc);
}
MarkWrappedNative(trc, obj, true);
}
static JSBool

View File

@ -82,10 +82,17 @@ class YarrGenerator : private MacroAssembler {
static const RegisterID returnRegister = X86Registers::eax;
#elif WTF_CPU_X86_64
#if WTF_PLATFORM_WIN
static const RegisterID input = X86Registers::ecx;
static const RegisterID index = X86Registers::edx;
static const RegisterID length = X86Registers::r8;
static const RegisterID output = X86Registers::r9;
#else
static const RegisterID input = X86Registers::edi;
static const RegisterID index = X86Registers::esi;
static const RegisterID length = X86Registers::edx;
static const RegisterID output = X86Registers::ecx;
#endif
static const RegisterID regT0 = X86Registers::eax;
static const RegisterID regT1 = X86Registers::ebx;

View File

@ -68,7 +68,6 @@ installer:
@$(MAKE) -C mobile/installer installer
package:
rm -rf dist/fennec*
@$(MAKE) -C mobile/installer
install::