author | Kyle Huey <khuey@kylehuey.com> |
Wed, 29 Jun 2011 16:37:41 -0700 | |
changeset 72514 | d452aaf438f1ca254bd1cf2a81b8d0375ce1c2da |
parent 72510 | 323029d49c8dbc7d95e8750cf3e8213f088d5eed (current diff) |
parent 72513 | b2a1b2fd6d234a7fadc7ccf2603975d6a61f918a (diff) |
child 72515 | 98285b0ee9a171051c4a7763bcb6c7ca83243318 |
push id | 159 |
push user | eakhgari@mozilla.com |
push date | Tue, 16 Aug 2011 17:53:11 +0000 |
treeherder | mozilla-beta@8786e3e49240 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 7.0a1 |
first release with | nightly linux32
d452aaf438f1
/
7.0a1
/
20110630030749
/
files
nightly linux64
d452aaf438f1
/
7.0a1
/
20110630030749
/
files
nightly mac
d452aaf438f1
/
7.0a1
/
20110630030749
/
files
nightly win32
d452aaf438f1
/
7.0a1
/
20110630030749
/
files
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
7.0a1
/
20110630030749
/
pushlog to previous
nightly linux64
7.0a1
/
20110630030749
/
pushlog to previous
nightly mac
7.0a1
/
20110630030749
/
pushlog to previous
nightly win32
7.0a1
/
20110630030749
/
pushlog to previous
|
--- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -38,16 +38,17 @@ * ***** END LICENSE BLOCK ***** */ #include "IDBObjectStore.h" #include "nsIJSContextStack.h" #include "nsIVariant.h" #include "jscntxt.h" +#include "jsclone.h" #include "mozilla/storage.h" #include "nsContentUtils.h" #include "nsDOMClassInfo.h" #include "nsEventDispatcher.h" #include "nsJSUtils.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" @@ -70,19 +71,20 @@ class AddHelper : public AsyncConnection { public: AddHelper(IDBTransaction* aTransaction, IDBRequest* aRequest, IDBObjectStore* aObjectStore, JSAutoStructuredCloneBuffer& aCloneBuffer, const Key& aKey, bool aOverwrite, - nsTArray<IndexUpdateInfo>& aIndexUpdateInfo) + nsTArray<IndexUpdateInfo>& aIndexUpdateInfo, + PRUint64 aOffsetToKeyProp) : AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore), - mKey(aKey), mOverwrite(aOverwrite) + mKey(aKey), mOverwrite(aOverwrite), mOffsetToKeyProp(aOffsetToKeyProp) { mCloneBuffer.swap(aCloneBuffer); mIndexUpdateInfo.SwapElements(aIndexUpdateInfo); } ~AddHelper() { IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffer); @@ -106,16 +108,17 @@ private: // In-params. nsRefPtr<IDBObjectStore> mObjectStore; // These may change in the autoincrement case. JSAutoStructuredCloneBuffer mCloneBuffer; Key mKey; const bool mOverwrite; nsTArray<IndexUpdateInfo> mIndexUpdateInfo; + PRUint64 mOffsetToKeyProp; }; class GetHelper : public AsyncConnectionHelper { public: GetHelper(IDBTransaction* aTransaction, IDBRequest* aRequest, IDBObjectStore* aObjectStore, @@ -418,16 +421,51 @@ already_AddRefed<IDBRequest> GenerateRequest(IDBObjectStore* aObjectStore) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); IDBDatabase* database = aObjectStore->Transaction()->Database(); return IDBRequest::Create(aObjectStore, database->ScriptContext(), database->Owner(), aObjectStore->Transaction()); } +JSClass gDummyPropClass = { + "dummy", 0, + JS_PropertyStub, JS_PropertyStub, + JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, + JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +JSBool +StructuredCloneWriteDummyProp(JSContext* aCx, + JSStructuredCloneWriter* aWriter, + JSObject* aObj, + void* aClosure) +{ + if (JS_GET_CLASS(aCx, aObj) == &gDummyPropClass) { + PRUint64* closure = reinterpret_cast<PRUint64*>(aClosure); + + NS_ASSERTION(*closure == 0, "We should not have been here before!"); + *closure = js_GetSCOffset(aWriter); + + PRUint64 value = 0; + return JS_WriteBytes(aWriter, &value, sizeof(value)); + } + + // try using the runtime callbacks + const JSStructuredCloneCallbacks* runtimeCallbacks = + aCx->runtime->structuredCloneCallbacks; + if (runtimeCallbacks) { + return runtimeCallbacks->write(aCx, aWriter, aObj, nsnull); + } + + return JS_FALSE; +} + } // anonymous namespace // static already_AddRefed<IDBObjectStore> IDBObjectStore::Create(IDBTransaction* aTransaction, const ObjectStoreInfo* aStoreInfo) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); @@ -835,45 +873,49 @@ IDBObjectStore::ClearStructuredCloneBuff } } } // static bool IDBObjectStore::DeserializeValue(JSContext* aCx, JSAutoStructuredCloneBuffer& aBuffer, - jsval* aValue) + jsval* aValue, + JSStructuredCloneCallbacks* aCallbacks, + void* aClosure) { NS_ASSERTION(NS_IsMainThread(), "Should only be deserializing on the main thread!"); NS_ASSERTION(aCx, "A JSContext is required!"); if (!aBuffer.data()) { *aValue = JSVAL_VOID; return true; } JSAutoRequest ar(aCx); - return aBuffer.read(aValue, aCx, nsnull); + return aBuffer.read(aValue, aCx, aCallbacks, aClosure); } // static bool IDBObjectStore::SerializeValue(JSContext* aCx, JSAutoStructuredCloneBuffer& aBuffer, - jsval aValue) + jsval aValue, + JSStructuredCloneCallbacks* aCallbacks, + void* aClosure) { NS_ASSERTION(NS_IsMainThread(), "Should only be serializing on the main thread!"); NS_ASSERTION(aCx, "A JSContext is required!"); JSAutoRequest ar(aCx); - return aBuffer.write(aCx, aValue, nsnull); + return aBuffer.write(aCx, aValue, aCallbacks, aClosure); } static inline jsdouble SwapBytes(PRUint64 u) { #ifdef IS_BIG_ENDIAN return ((u & 0x00000000000000ffLLU) << 56) | ((u & 0x000000000000ff00LLU) << 40) | @@ -885,69 +927,55 @@ SwapBytes(PRUint64 u) ((u & 0xff00000000000000LLU) >> 56); #else return u; #endif } nsresult IDBObjectStore::ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer, - Key& aKey) + Key& aKey, + PRUint64 aOffsetToKeyProp) { NS_ASSERTION(IsAutoIncrement() && KeyPath().IsEmpty() && aKey.IsInt(), "Don't call me!"); NS_ASSERTION(!NS_IsMainThread(), "Wrong thread"); - NS_ASSERTION(mKeyPathSerializationOffset, "How did this happen?"); - - // The minus 8 dangling off the end here is to account for the null entry - // that terminates the buffer - const PRUint32 keyPropLen = mKeyPathSerialization.nbytes() - - mKeyPathSerializationOffset - sizeof(PRUint64); - - const char* location = nsCRT::memmem((char*)aBuffer.data(), - aBuffer.nbytes(), - (char*)mKeyPathSerialization.data() + - mKeyPathSerializationOffset, - keyPropLen); - NS_ASSERTION(location, "How did this happen?"); // This is a duplicate of the js engine's byte munging here union { jsdouble d; PRUint64 u; } pun; pun.d = SwapBytes(aKey.IntValue()); - memcpy(const_cast<char*>(location) + keyPropLen - - sizeof(pun.u), // We're overwriting the last 8 bytes - &pun.u, sizeof(PRUint64)); + memcpy((char*)aBuffer.data() + aOffsetToKeyProp, &pun.u, sizeof(PRUint64)); return NS_OK; } IDBObjectStore::IDBObjectStore() : mId(LL_MININT), - mAutoIncrement(PR_FALSE), - mKeyPathSerializationOffset(0) + mAutoIncrement(PR_FALSE) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); } IDBObjectStore::~IDBObjectStore() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); } nsresult IDBObjectStore::GetAddInfo(JSContext* aCx, jsval aValue, jsval aKeyVal, JSAutoStructuredCloneBuffer& aCloneBuffer, Key& aKey, - nsTArray<IndexUpdateInfo>& aUpdateInfoArray) + nsTArray<IndexUpdateInfo>& aUpdateInfoArray, + PRUint64* aOffsetToKeyProp) { nsresult rv; // Return DATA_ERR if a key was passed in and this objectStore uses inline // keys. if (!JSVAL_IS_VOID(aKeyVal) && !mKeyPath.IsEmpty()) { return NS_ERROR_DOM_INDEXEDDB_DATA_ERR; } @@ -988,33 +1016,41 @@ IDBObjectStore::GetAddInfo(JSContext* aC const jschar* keyPathChars = reinterpret_cast<const jschar*>(mKeyPath.get()); const size_t keyPathLen = mKeyPath.Length(); JSBool ok = JS_FALSE; if (!mKeyPath.IsEmpty() && aKey.IsUnset()) { NS_ASSERTION(mAutoIncrement, "Should have bailed earlier!"); - jsval key; - ok = JS_NewNumberValue(aCx, kTotallyRandomNumber, &key); - NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + JSObject* obj = JS_NewObject(aCx, &gDummyPropClass, nsnull, nsnull); + NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + jsval key = OBJECT_TO_JSVAL(obj); ok = JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(aValue), keyPathChars, keyPathLen, key, nsnull, nsnull, JSPROP_ENUMERATE); NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); // From this point on we have to try to remove the property. - rv = EnsureKeyPathSerializationData(aCx); } + JSStructuredCloneCallbacks callbacks = { + nsnull, + StructuredCloneWriteDummyProp, + nsnull + }; + *aOffsetToKeyProp = 0; + // We guard on rv being a success because we need to run the property // deletion code below even if we should not be serializing the value if (NS_SUCCEEDED(rv) && - !IDBObjectStore::SerializeValue(aCx, aCloneBuffer, aValue)) { + !IDBObjectStore::SerializeValue(aCx, aCloneBuffer, aValue, &callbacks, + aOffsetToKeyProp)) { rv = NS_ERROR_DOM_DATA_CLONE_ERR; } if (ok) { // If this fails, we lose, and the web page sees a magical property // appear on the object :-( jsval succeeded; ok = JS_DeleteUCProperty2(aCx, JSVAL_TO_OBJECT(aValue), keyPathChars, @@ -1046,81 +1082,43 @@ IDBObjectStore::AddOrPut(const jsval& aV return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR; } jsval keyval = (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID; JSAutoStructuredCloneBuffer cloneBuffer; Key key; nsTArray<IndexUpdateInfo> updateInfo; - - nsresult rv = GetAddInfo(aCx, aValue, keyval, cloneBuffer, key, updateInfo); + PRUint64 offset; + + nsresult rv = + GetAddInfo(aCx, aValue, keyval, cloneBuffer, key, updateInfo, &offset); if (NS_FAILED(rv)) { return rv; } // Put requires a key. if (aOverwrite && key.IsUnset()) { return NS_ERROR_DOM_INDEXEDDB_DATA_ERR; } nsRefPtr<IDBRequest> request = GenerateRequest(this); NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); nsRefPtr<AddHelper> helper = new AddHelper(mTransaction, request, this, cloneBuffer, key, aOverwrite, - updateInfo); + updateInfo, offset); rv = helper->DispatchToTransactionPool(); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); request.forget(_retval); return NS_OK; } -nsresult -IDBObjectStore::EnsureKeyPathSerializationData(JSContext* aCx) -{ - NS_ASSERTION(NS_IsMainThread(), "Wrong thread"); - - if (!mKeyPathSerializationOffset) { - JSBool ok; - - JSAutoStructuredCloneBuffer emptyObjectBuffer; - JSAutoStructuredCloneBuffer fakeObjectBuffer; - - const jschar* keyPathChars = - reinterpret_cast<const jschar*>(mKeyPath.get()); - const size_t keyPathLen = mKeyPath.Length(); - - JSObject* object = JS_NewObject(aCx, nsnull, nsnull, nsnull); - NS_ENSURE_TRUE(object, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - ok = emptyObjectBuffer.write(aCx, OBJECT_TO_JSVAL(object)); - NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - jsval key; - // This is just to give us some random marker in the byte stream - ok = JS_NewNumberValue(aCx, kTotallyRandomNumber, &key); - NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - ok = JS_DefineUCProperty(aCx, object, keyPathChars, keyPathLen, - key, nsnull, nsnull, JSPROP_ENUMERATE); - NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - ok = fakeObjectBuffer.write(aCx, OBJECT_TO_JSVAL(object)); - NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - - mKeyPathSerialization.swap(fakeObjectBuffer); - mKeyPathSerializationOffset = emptyObjectBuffer.nbytes(); - } - - return NS_OK; -} - NS_IMPL_CYCLE_COLLECTION_CLASS(IDBObjectStore) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction, nsIDOMEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext) @@ -1845,17 +1843,18 @@ AddHelper::DoDatabaseWork(mozIStorageCon NS_ASSERTION(mKey.IntValue() == oldKey, "Something went haywire!"); } #endif if (!keyPath.IsEmpty() && unsetKey) { // Special case where someone put an object into an autoIncrement'ing // objectStore with no key in its keyPath set. We needed to figure out // which row id we would get above before we could set that properly. - rv = mObjectStore->ModifyValueForNewKey(mCloneBuffer, mKey); + rv = mObjectStore->ModifyValueForNewKey(mCloneBuffer, mKey, + mOffsetToKeyProp); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); scoper.Abandon(); rv = stmt->Reset(); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); stmt = mTransaction->AddStatement(false, true, true); NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
--- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -114,22 +114,26 @@ public: JSAutoStructuredCloneBuffer& aBuffer); static void ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer); static bool DeserializeValue(JSContext* aCx, JSAutoStructuredCloneBuffer& aBuffer, - jsval* aValue); + jsval* aValue, + JSStructuredCloneCallbacks* aCallbacks = nsnull, + void* aClosure = nsnull); static bool SerializeValue(JSContext* aCx, JSAutoStructuredCloneBuffer& aBuffer, - jsval aValue); + jsval aValue, + JSStructuredCloneCallbacks* aCallbacks = nsnull, + void* aClosure = nsnull); const nsString& Name() const { return mName; } bool IsAutoIncrement() const { @@ -153,55 +157,49 @@ public: } IDBTransaction* Transaction() { return mTransaction; } nsresult ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer, - Key& aKey); + Key& aKey, + PRUint64 aOffsetToKeyProp); protected: IDBObjectStore(); ~IDBObjectStore(); nsresult GetAddInfo(JSContext* aCx, jsval aValue, jsval aKeyVal, JSAutoStructuredCloneBuffer& aCloneBuffer, Key& aKey, - nsTArray<IndexUpdateInfo>& aUpdateInfoArray); + nsTArray<IndexUpdateInfo>& aUpdateInfoArray, + PRUint64* aOffsetToKeyProp); nsresult AddOrPut(const jsval& aValue, const jsval& aKey, JSContext* aCx, PRUint8 aOptionalArgCount, nsIIDBRequest** _retval, bool aOverwrite); - nsresult EnsureKeyPathSerializationData(JSContext* aCx); - private: nsRefPtr<IDBTransaction> mTransaction; nsCOMPtr<nsIScriptContext> mScriptContext; nsCOMPtr<nsPIDOMWindow> mOwner; PRInt64 mId; nsString mName; nsString mKeyPath; PRBool mAutoIncrement; PRUint32 mDatabaseId; PRUint32 mStructuredCloneVersion; - // Used to store a serialized representation of the fake property - // entry used to handle autoincrement with keypaths. - JSAutoStructuredCloneBuffer mKeyPathSerialization; - PRUint32 mKeyPathSerializationOffset; - nsTArray<nsRefPtr<IDBIndex> > mCreatedIndexes; - }; END_INDEXEDDB_NAMESPACE #endif // mozilla_dom_indexeddb_idbobjectstore_h__
--- a/js/src/jsclone.cpp +++ b/js/src/jsclone.cpp @@ -41,16 +41,23 @@ #include "jsregexp.h" #include "jstypedarray.h" #include "jsregexpinlines.h" #include "jstypedarrayinlines.h" using namespace js; +JS_FRIEND_API(uint64_t) +js_GetSCOffset(JSStructuredCloneWriter* writer) +{ + JS_ASSERT(writer); + return writer->output().count() * sizeof(uint64_t); +} + namespace js { bool WriteStructuredClone(JSContext *cx, const Value &v, uint64 **bufp, size_t *nbytesp, const JSStructuredCloneCallbacks *cb, void *cbClosure) { SCOutput out(cx);
--- a/js/src/jsclone.h +++ b/js/src/jsclone.h @@ -41,16 +41,19 @@ #include "jsapi.h" #include "jscntxt.h" #include "jshashtable.h" #include "jsstdint.h" #include "jsvector.h" #include "jsvalue.h" +JS_FRIEND_API(uint64_t) +js_GetSCOffset(JSStructuredCloneWriter* writer); + namespace js { bool WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp, const JSStructuredCloneCallbacks *cb, void *cbClosure); bool ReadStructuredClone(JSContext *cx, const uint64_t *data, size_t nbytes, Value *vp, @@ -68,16 +71,18 @@ struct SCOutput { bool writeBytes(const void *p, size_t nbytes); bool writeChars(const jschar *p, size_t nchars); template <class T> bool writeArray(const T *p, size_t nbytes); bool extractBuffer(uint64_t **datap, size_t *sizep); + uint64_t count() { return buf.length(); } + private: JSContext *cx; js::Vector<uint64_t> buf; }; struct SCInput { public: SCInput(JSContext *cx, const uint64_t *data, size_t nbytes);
--- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -802,17 +802,17 @@ UPLOAD_FILES= \ $(call QUOTED_WILDCARD,$(DIST)/$(PKG_PATH)$(TEST_PACKAGE)) \ $(call QUOTED_WILDCARD,$(DIST)/$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip) \ $(call QUOTED_WILDCARD,$(DIST)/$(SDK)) \ $(call QUOTED_WILDCARD,$(MOZ_SOURCESTAMP_FILE)) \ $(call QUOTED_WILDCARD,$(PKG_JSSHELL)) \ $(if $(UPLOAD_EXTRA_FILES), $(foreach f, $(UPLOAD_EXTRA_FILES), $(wildcard $(DIST)/$(f)))) checksum: - mkdir -p `dirname $CHECKSUM_FILE` + mkdir -p `dirname $(CHECKSUM_FILE)` @$(PYTHON) $(MOZILLA_DIR)/build/checksums.py \ -o $(CHECKSUM_FILE) \ -d $(CHECKSUM_ALGORITHM) \ -s $(call QUOTED_WILDCARD,$(DIST)) \ $(UPLOAD_FILES) @echo "CHECKSUM FILE START" @cat $(CHECKSUM_FILE) @echo "CHECKSUM FILE END"