Putting many objects into the db from a jsm file causes a warning in
nsresult IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
The calling code is a jsm which means that we fall into the else-block for if(mScriptContext)
The following
obj = GetWrapper();
NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
code then bails due to obj being null.

So the fact that this is inside a jsm is likely what is causing problems. The code in the else-block is looking iffy.
First of all it gets the JS-wrapper for the request and uses that when entering the compartment. However the code for normal windows uses the window global to enter the compartment. Is it really ok to use the wrapper for the request?
Second, calling GetWrapper can return null if we've GC'ed the js-wrapper, no? That seems like a legitimate case and not something that should cause us to error out. Especially if we don't root the wrapper anywhere.
Bent, do you know what the right thing to do here is?

(In reply to Jonas Sicking (:sicking) from comment #1)
> Second, calling GetWrapper can return null if we've GC'ed the js-wrapper,
> no? That seems like a legitimate case and not something that should cause us
> to error out. Especially if we don't root the wrapper anywhere.
The request roots its own wrapper though, doesn't it?
(In reply to Gregor Wagner [:gwagner] from comment #2)
> It seems that storing the request object is a temporary fix:
>
> obj = store.put(record);
Presumably this manual wrapper preservation causes it to work. The question is why the wrapper isn't preserved to begin with ...

(In reply to Jonas Sicking (:sicking) from comment #4)
> (In reply to Kyle Huey [:khuey] (khuey@mozilla.com) from comment #3)
> > The request roots its own wrapper though, doesn't it?
>
> Do we do that even if no event handlers are registered?
Aha, good question.

How are you rooting the object? Just creating a local variable pointing to the return value will just keep it rooted until the function exits. If you keep an array on the transaction, and add all requests to that array, you should be rooting properly.

Created attachment 589930[details][diff][review]
Testcase
Just run the test in dom/contacts/tests/
You might have to run it a few times but I increased the number of contacts I create to 800 and after some time you should see:
147 INFO TEST-PASS | /tests/dom/contacts/tests/test_contacts_basics.html | The contact now has an ID.
WARNING: NS_ENSURE_TRUE(obj) failed: file /Volumes/mac/moz/ws1/dom/indexedDB/IDBRequest.cpp, line 155
WARNING: NS_ENSURE_TRUE(obj) failed: file /Volumes/mac/moz/ws1/dom/indexedDB/IDBRequest.cpp, line 155

(In reply to Kyle Huey [:khuey] (khuey@mozilla.com) from comment #16)
> This is a behavior change, do we want this?
Yep, the old code assumed only one script child per preserved wrapper, which is not always true.

Created attachment 591037[details][diff][review]
Crash fix, interdif
This fixes the crash, which was a simple refcounting bug due to NS_DROP_JS_OBJECTS in IDBFactory.
I also removed some of the preserved wrapper stuff because I think we don't really need it after all.

(In reply to Gregor Wagner [:gwagner] from comment #22)
> I tried my patch on top of both patches and got the same error again right
> away:
> WARNING: NS_ENSURE_TRUE(obj) failed: file
> /Users/idefix/moz/ws5/dom/indexedDB/IDBRequest.cpp, line 155
Ok this was my mistake. Works fine!