merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 09 Dec 2014 12:51:54 +0100
changeset 218820 acf5660d2048565ea7095f55697dbb1817dd617a
parent 218744 9045013a21cd5ec910d243c4f9a3d8579f7367b5 (current diff)
parent 218819 d4dfb076f5f13ff200b7ecff51ba376d64dcf86d (diff)
child 218833 47f0671e2c65bc2db2bf121f02ad1ed393da2b95
push id27944
push usercbook@mozilla.com
push dateTue, 09 Dec 2014 11:54:28 +0000
treeherdermozilla-central@acf5660d2048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central a=merge
browser/base/content/test/general/browser_updatecommands.js
dom/interfaces/base/nsIRemoteBrowser.idl
media/webrtc/signaling/include/CC_Call.h
media/webrtc/signaling/include/CC_CallInfo.h
media/webrtc/signaling/include/CC_CallServerInfo.h
media/webrtc/signaling/include/CC_CallTypes.h
media/webrtc/signaling/include/CC_Common.h
media/webrtc/signaling/include/CC_Device.h
media/webrtc/signaling/include/CC_DeviceInfo.h
media/webrtc/signaling/include/CC_FeatureInfo.h
media/webrtc/signaling/include/CC_Line.h
media/webrtc/signaling/include/CC_LineInfo.h
media/webrtc/signaling/include/CC_Observer.h
media/webrtc/signaling/include/CC_Service.h
media/webrtc/signaling/include/CSFAudioControl.h
media/webrtc/signaling/include/CSFVideoControl.h
media/webrtc/signaling/include/CallControlManager.h
media/webrtc/signaling/include/ECC_Observer.h
media/webrtc/signaling/include/ECC_Types.h
media/webrtc/signaling/include/PhoneDetails.h
media/webrtc/signaling/include/SharedPtr.h
media/webrtc/signaling/include/debug-psipcc-types.h
media/webrtc/signaling/src/callcontrol/CC_CallTypes.cpp
media/webrtc/signaling/src/callcontrol/CallControlManager.cpp
media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.cpp
media/webrtc/signaling/src/callcontrol/CallControlManagerImpl.h
media/webrtc/signaling/src/callcontrol/ECC_Types.cpp
media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.cpp
media/webrtc/signaling/src/callcontrol/PhoneDetailsImpl.h
media/webrtc/signaling/src/callcontrol/debug-psipcc-types.cpp
media/webrtc/signaling/src/media/CSFVideoControlWrapper.cpp
media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
media/webrtc/signaling/src/media/VcmSIPCCBinding.h
media/webrtc/signaling/src/media/cip_Sipcc_CodecMask.h
media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h
media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.c
media/webrtc/signaling/src/sipcc/core/ccapp/call_logger.h
media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.c
media/webrtc/signaling/src/sipcc/core/ccapp/capability_set.h
media/webrtc/signaling/src/sipcc/core/ccapp/cc_blf.c
media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c
media/webrtc/signaling/src/sipcc/core/ccapp/cc_config.c
media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_feature.c
media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.c
media/webrtc/signaling/src/sipcc/core/ccapp/cc_device_manager.h
media/webrtc/signaling/src/sipcc/core/ccapp/cc_info.c
media/webrtc/signaling/src/sipcc/core/ccapp/cc_service.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call_info.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_config.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_device_info.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_feature_info.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_line_info.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_service.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h
media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapp_task.h
media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.c
media/webrtc/signaling/src/sipcc/core/ccapp/conf_roster.h
media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.c
media/webrtc/signaling/src/sipcc/core/ccapp/sessionHash.h
media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.c
media/webrtc/signaling/src/sipcc/core/common/cfgfile_utils.h
media/webrtc/signaling/src/sipcc/core/common/config_api.c
media/webrtc/signaling/src/sipcc/core/common/config_parser.c
media/webrtc/signaling/src/sipcc/core/common/config_parser.h
media/webrtc/signaling/src/sipcc/core/common/init.c
media/webrtc/signaling/src/sipcc/core/common/logger.c
media/webrtc/signaling/src/sipcc/core/common/logger.h
media/webrtc/signaling/src/sipcc/core/common/logmsg.h
media/webrtc/signaling/src/sipcc/core/common/misc.c
media/webrtc/signaling/src/sipcc/core/common/plat.c
media/webrtc/signaling/src/sipcc/core/common/platform_api.c
media/webrtc/signaling/src/sipcc/core/common/prot_cfgmgr_private.h
media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.c
media/webrtc/signaling/src/sipcc/core/common/prot_configmgr.h
media/webrtc/signaling/src/sipcc/core/common/resource_manager.c
media/webrtc/signaling/src/sipcc/core/common/resource_manager.h
media/webrtc/signaling/src/sipcc/core/common/sip_socket_api.c
media/webrtc/signaling/src/sipcc/core/common/subscription_handler.c
media/webrtc/signaling/src/sipcc/core/common/subscription_handler.h
media/webrtc/signaling/src/sipcc/core/common/text_strings.c
media/webrtc/signaling/src/sipcc/core/common/text_strings.h
media/webrtc/signaling/src/sipcc/core/common/ui.c
media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c
media/webrtc/signaling/src/sipcc/core/gsm/ccapi_strings.c
media/webrtc/signaling/src/sipcc/core/gsm/dcsm.c
media/webrtc/signaling/src/sipcc/core/gsm/fim.c
media/webrtc/signaling/src/sipcc/core/gsm/fsm.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmb2bcnf.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmcac.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmcnf.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmxfr.c
media/webrtc/signaling/src/sipcc/core/gsm/gsm.c
media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c
media/webrtc/signaling/src/sipcc/core/gsm/h/fim.h
media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h
media/webrtc/signaling/src/sipcc/core/gsm/h/gsm.h
media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h
media/webrtc/signaling/src/sipcc/core/gsm/h/lsm.h
media/webrtc/signaling/src/sipcc/core/gsm/h/lsm_private.h
media/webrtc/signaling/src/sipcc/core/gsm/h/sm.h
media/webrtc/signaling/src/sipcc/core/gsm/lsm.c
media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c
media/webrtc/signaling/src/sipcc/core/gsm/sm.c
media/webrtc/signaling/src/sipcc/core/gsm/subapi.c
media/webrtc/signaling/src/sipcc/core/includes/ccSession.h
media/webrtc/signaling/src/sipcc/core/includes/ccapi.h
media/webrtc/signaling/src/sipcc/core/includes/check_sync.h
media/webrtc/signaling/src/sipcc/core/includes/ci.h
media/webrtc/signaling/src/sipcc/core/includes/config.h
media/webrtc/signaling/src/sipcc/core/includes/configapp.h
media/webrtc/signaling/src/sipcc/core/includes/configmgr.h
media/webrtc/signaling/src/sipcc/core/includes/debug.h
media/webrtc/signaling/src/sipcc/core/includes/dialplan.h
media/webrtc/signaling/src/sipcc/core/includes/dialplanint.h
media/webrtc/signaling/src/sipcc/core/includes/digcalc.h
media/webrtc/signaling/src/sipcc/core/includes/dns_utils.h
media/webrtc/signaling/src/sipcc/core/includes/dtmf.h
media/webrtc/signaling/src/sipcc/core/includes/embedded.h
media/webrtc/signaling/src/sipcc/core/includes/intelpentiumtypes.h
media/webrtc/signaling/src/sipcc/core/includes/kpml_common_util.h
media/webrtc/signaling/src/sipcc/core/includes/kpmlmap.h
media/webrtc/signaling/src/sipcc/core/includes/md5.h
media/webrtc/signaling/src/sipcc/core/includes/memory.h
media/webrtc/signaling/src/sipcc/core/includes/misc_apps_task.h
media/webrtc/signaling/src/sipcc/core/includes/misc_util.h
media/webrtc/signaling/src/sipcc/core/includes/phntask.h
media/webrtc/signaling/src/sipcc/core/includes/phone.h
media/webrtc/signaling/src/sipcc/core/includes/phone_debug.h
media/webrtc/signaling/src/sipcc/core/includes/phone_platform_constants.h
media/webrtc/signaling/src/sipcc/core/includes/phone_types.h
media/webrtc/signaling/src/sipcc/core/includes/platform_api.h
media/webrtc/signaling/src/sipcc/core/includes/pres_sub_not_handler.h
media/webrtc/signaling/src/sipcc/core/includes/publish_int.h
media/webrtc/signaling/src/sipcc/core/includes/rcc_int_types.h
media/webrtc/signaling/src/sipcc/core/includes/regexp.h
media/webrtc/signaling/src/sipcc/core/includes/ringlist.h
media/webrtc/signaling/src/sipcc/core/includes/rtp_defs.h
media/webrtc/signaling/src/sipcc/core/includes/scSession.h
media/webrtc/signaling/src/sipcc/core/includes/session.h
media/webrtc/signaling/src/sipcc/core/includes/sessionConstants.h
media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h
media/webrtc/signaling/src/sipcc/core/includes/sessuri.h
media/webrtc/signaling/src/sipcc/core/includes/singly_link_list.h
media/webrtc/signaling/src/sipcc/core/includes/sip_socket_api.h
media/webrtc/signaling/src/sipcc/core/includes/sntp.h
media/webrtc/signaling/src/sipcc/core/includes/string_lib.h
media/webrtc/signaling/src/sipcc/core/includes/subapi.h
media/webrtc/signaling/src/sipcc/core/includes/task.h
media/webrtc/signaling/src/sipcc/core/includes/time2.h
media/webrtc/signaling/src/sipcc/core/includes/timer.h
media/webrtc/signaling/src/sipcc/core/includes/tnpphone.h
media/webrtc/signaling/src/sipcc/core/includes/uart.h
media/webrtc/signaling/src/sipcc/core/includes/uiapi.h
media/webrtc/signaling/src/sipcc/core/includes/upgrade.h
media/webrtc/signaling/src/sipcc/core/includes/util_ios_queue.h
media/webrtc/signaling/src/sipcc/core/includes/util_parse.h
media/webrtc/signaling/src/sipcc/core/includes/util_string.h
media/webrtc/signaling/src/sipcc/core/includes/www.h
media/webrtc/signaling/src/sipcc/core/includes/xml_defs.h
media/webrtc/signaling/src/sipcc/core/sdp/ccsdp.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp.h
media/webrtc/signaling/src/sipcc/core/sdp/sdp_access.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_base64.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_base64.h
media/webrtc/signaling/src/sipcc/core/sdp/sdp_config.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_os_defs.h
media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h
media/webrtc/signaling/src/sipcc/core/sdp/sdp_services_unix.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_services_win32.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c
media/webrtc/signaling/src/sipcc/core/sdp/sdp_utils.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_callinfo.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_cc.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_common_util.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_core.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_debug.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_info.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_messaging.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tcp.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_timers.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_tls.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_platform_udp.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_pmh.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_publish.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_register.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_reldev.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_spi_utils.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_subsmanager.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_task.c
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_callinfo.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_cc.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_common_cb.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_core.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_credentials.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_macros.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_messaging.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tcp.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_timers.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_tls.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_platform_udp.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_pmh.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_protocol.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_publish.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_register.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_reldev.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sdp.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_sim.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_spi_utils.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_subsmanager.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/ccsip_task.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/httpish_protocol.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhdefs.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/pmhutils.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/regmgrapi.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_ccm_transport.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_regmgr.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_common_transport.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_csps_transport.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_interface_regmgr.h
media/webrtc/signaling/src/sipcc/core/sipstack/h/sip_platform_task.h
media/webrtc/signaling/src/sipcc/core/sipstack/httpish.c
media/webrtc/signaling/src/sipcc/core/sipstack/pmhutils.c
media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_regmgr.c
media/webrtc/signaling/src/sipcc/core/sipstack/sip_common_transport.c
media/webrtc/signaling/src/sipcc/core/sipstack/sip_csps_transport.c
media/webrtc/signaling/src/sipcc/core/sipstack/sip_interface_regmgr.c
media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c
media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_win32_task.c
media/webrtc/signaling/src/sipcc/core/src-common/configapp.c
media/webrtc/signaling/src/sipcc/core/src-common/dialplan.c
media/webrtc/signaling/src/sipcc/core/src-common/dialplanint.c
media/webrtc/signaling/src/sipcc/core/src-common/digcalc.c
media/webrtc/signaling/src/sipcc/core/src-common/kpml_common_util.c
media/webrtc/signaling/src/sipcc/core/src-common/kpmlmap.c
media/webrtc/signaling/src/sipcc/core/src-common/md5.c
media/webrtc/signaling/src/sipcc/core/src-common/misc_apps_task.c
media/webrtc/signaling/src/sipcc/core/src-common/pres_sub_not_handler.c
media/webrtc/signaling/src/sipcc/core/src-common/publish_int.c
media/webrtc/signaling/src/sipcc/core/src-common/singly_link_list.c
media/webrtc/signaling/src/sipcc/core/src-common/sll_lite.c
media/webrtc/signaling/src/sipcc/core/src-common/string_lib.c
media/webrtc/signaling/src/sipcc/core/src-common/util_ios_queue.c
media/webrtc/signaling/src/sipcc/core/src-common/util_parse.c
media/webrtc/signaling/src/sipcc/core/src-common/util_string.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_align.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_assert.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_errno.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_errno.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_in.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_init.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_private.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_rand.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_socket.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_socket.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_stdio.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_stdio.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_string.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_string.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_strings.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_time.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_timers.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_timers_using_select.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_tst.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_tst.h
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_types.h
media/webrtc/signaling/src/sipcc/cpr/common/cpr_ipc.c
media/webrtc/signaling/src/sipcc/cpr/common/cpr_string.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_align.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_assert.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_errno.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_errno.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_in.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_init.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_private.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_rand.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_socket.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_socket.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_stdio.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_stdio.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_string.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_string.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_strings.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_threads.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_time.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_timers.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_timers_using_select.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_tst.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_types.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_assert.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_debug.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_errno.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_in.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_ipc.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_locks.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_memory.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_rand.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_socket.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_stddef.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_stdio.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_stdlib.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_string.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_strings.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_threads.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_time.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_timers.h
media/webrtc/signaling/src/sipcc/cpr/include/cpr_types.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_align.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_assert.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_errno.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_errno.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_in.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_init.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_private.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_rand.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_socket.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_socket.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_stdio.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_stdio.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_string.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_string.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_strings.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_threads.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_time.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_timers.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_timers_using_select.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_tst.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_tst.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_types.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_assert.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_debug.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_debug.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_defines.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_errno.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_errno.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_in.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_init.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_locks.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_locks.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_rand.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_rand.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_socket.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_socket.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_stdio.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_stdio.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_string.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_string.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_strings.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.cpp
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_time.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_timers.c
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_timers.h
media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_types.h
media/webrtc/signaling/src/sipcc/include/cc_blf.h
media/webrtc/signaling/src/sipcc/include/cc_blf_listener.h
media/webrtc/signaling/src/sipcc/include/cc_call_feature.h
media/webrtc/signaling/src/sipcc/include/cc_call_listener.h
media/webrtc/signaling/src/sipcc/include/cc_config.h
media/webrtc/signaling/src/sipcc/include/cc_constants.h
media/webrtc/signaling/src/sipcc/include/cc_debug.h
media/webrtc/signaling/src/sipcc/include/cc_device_feature.h
media/webrtc/signaling/src/sipcc/include/cc_device_listener.h
media/webrtc/signaling/src/sipcc/include/cc_info.h
media/webrtc/signaling/src/sipcc/include/cc_info_listener.h
media/webrtc/signaling/src/sipcc/include/cc_service.h
media/webrtc/signaling/src/sipcc/include/cc_service_listener.h
media/webrtc/signaling/src/sipcc/include/cc_types.h
media/webrtc/signaling/src/sipcc/include/ccapi_call.h
media/webrtc/signaling/src/sipcc/include/ccapi_call_info.h
media/webrtc/signaling/src/sipcc/include/ccapi_call_listener.h
media/webrtc/signaling/src/sipcc/include/ccapi_calllog.h
media/webrtc/signaling/src/sipcc/include/ccapi_conf_roster.h
media/webrtc/signaling/src/sipcc/include/ccapi_device.h
media/webrtc/signaling/src/sipcc/include/ccapi_device_info.h
media/webrtc/signaling/src/sipcc/include/ccapi_device_listener.h
media/webrtc/signaling/src/sipcc/include/ccapi_feature_info.h
media/webrtc/signaling/src/sipcc/include/ccapi_line.h
media/webrtc/signaling/src/sipcc/include/ccapi_line_info.h
media/webrtc/signaling/src/sipcc/include/ccapi_line_listener.h
media/webrtc/signaling/src/sipcc/include/ccapi_service.h
media/webrtc/signaling/src/sipcc/include/ccapi_types.h
media/webrtc/signaling/src/sipcc/include/ccsdp.h
media/webrtc/signaling/src/sipcc/include/ccsdp_rtcp_fb.h
media/webrtc/signaling/src/sipcc/include/config_api.h
media/webrtc/signaling/src/sipcc/include/dns_util.h
media/webrtc/signaling/src/sipcc/include/fsmdef_states.h
media/webrtc/signaling/src/sipcc/include/peer_connection_types.h
media/webrtc/signaling/src/sipcc/include/plat_api.h
media/webrtc/signaling/src/sipcc/include/reset_api.h
media/webrtc/signaling/src/sipcc/include/sll_lite.h
media/webrtc/signaling/src/sipcc/include/vcm.h
media/webrtc/signaling/src/sipcc/include/xml_parser_defines.h
media/webrtc/signaling/src/sipcc/plat/common/dns_utils.c
media/webrtc/signaling/src/sipcc/plat/common/plat_debug.h
media/webrtc/signaling/src/sipcc/plat/common/tnp_blf.h
media/webrtc/signaling/src/sipcc/plat/csf2g/model.c
media/webrtc/signaling/src/sipcc/plat/csf2g/reset_api.c
media/webrtc/signaling/src/sipcc/plat/darwin/netif.c
media/webrtc/signaling/src/sipcc/plat/darwin/plat_api_stub.c
media/webrtc/signaling/src/sipcc/plat/unix-common/random.c
media/webrtc/signaling/src/sipcc/plat/win32/dns_utils.c
media/webrtc/signaling/src/sipcc/plat/win32/mystub.c
media/webrtc/signaling/src/sipcc/plat/win32/plat_api_stub.c
media/webrtc/signaling/src/sipcc/plat/win32/plat_api_win.c
media/webrtc/signaling/src/sipcc/stub/cc_blf_stub.c
media/webrtc/signaling/src/sipcc/stub/vcm_stub.c
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallInfo.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallInfo.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallServerInfo.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCallServerInfo.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDevice.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDevice.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDeviceInfo.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCDeviceInfo.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCFeatureInfo.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCFeatureInfo.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLine.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLine.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLineInfo.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCLineInfo.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCService.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCService.h
media/webrtc/signaling/src/softphonewrapper/ccapi_plat_api_impl.cpp
--- a/accessible/base/moz.build
+++ b/accessible/base/moz.build
@@ -92,8 +92,10 @@ else:
     ]
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_ENABLE_GTK']:
     CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
 
 include('/ipc/chromium/chromium-config.mozbuild')
+
+FAIL_ON_WARNINGS = True
--- a/accessible/generic/moz.build
+++ b/accessible/generic/moz.build
@@ -52,8 +52,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'co
 else:
     LOCAL_INCLUDES += [
         '/accessible/other',
     ]
 
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
+
+FAIL_ON_WARNINGS = True
--- a/accessible/html/moz.build
+++ b/accessible/html/moz.build
@@ -38,8 +38,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'co
         '/accessible/mac',
     ]
 else:
     LOCAL_INCLUDES += [
         '/accessible/other',
     ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/accessible/mac/moz.build
+++ b/accessible/mac/moz.build
@@ -33,8 +33,10 @@ LOCAL_INCLUDES += [
     '/accessible/xul',
     '/layout/generic',
     '/layout/xul',
     '/widget',
     '/widget/cocoa',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/accessible/xul/moz.build
+++ b/accessible/xul/moz.build
@@ -43,8 +43,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'co
         '/accessible/mac',
     ]
 else:
     LOCAL_INCLUDES += [
         '/accessible/other',
     ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -720,16 +720,18 @@ var CustomEventManager = {
         break;
       case 'system-message-listener-ready':
         Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
         break;
       case 'captive-portal-login-cancel':
         CaptivePortalLoginHelper.handleEvent(detail);
         break;
       case 'inputmethod-update-layouts':
+      case 'inputregistry-add':
+      case 'inputregistry-remove':
         KeyboardHelper.handleEvent(detail);
         break;
       case 'do-command':
         DoCommandHelper.handleEvent(detail.cmd);
         break;
     }
   }
 }
@@ -863,17 +865,27 @@ let IndexedDBPromptHelper = {
       observer.observe(null, responseTopic,
                        Ci.nsIPermissionManager.DENY_ACTION);
     }, 0);
   }
 }
 
 let KeyboardHelper = {
   handleEvent: function keyboard_handleEvent(detail) {
-    Keyboard.setLayouts(detail.layouts);
+    switch (detail.type) {
+      case 'inputmethod-update-layouts':
+        Keyboard.setLayouts(detail.layouts);
+
+        break;
+      case 'inputregistry-add':
+      case 'inputregistry-remove':
+        Keyboard.inputRegistryGlue.returnMessage(detail);
+
+        break;
+    }
   }
 };
 
 // This is the backend for Gaia's screenshot feature.  Gaia requests a
 // screenshot by sending a mozContentEvent with detail.type set to
 // 'take-screenshot'.  Then we take a screenshot and send a
 // mozChromeEvent with detail.type set to 'take-screenshot-success'
 // and detail.file set to the an image/png blob
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -485,10 +485,9 @@ skip-if = e10s
 [browser_addCertException.js]
 skip-if = e10s # Bug 1100687 - test directly manipulates content (content.document.getElementById)
 [browser_bug1045809.js]
 [browser_e10s_switchbrowser.js]
 [browser_blockHPKP.js]
 skip-if = e10s # bug 1100687 - test directly manipulates content (content.document.getElementById)
 [browser_mcb_redirect.js]
 skip-if = e10s # bug 1084504 - [e10s] Mixed content detection does not take redirection into account
-[browser_updatecommands.js]
 [browser_windowactivation.js]
deleted file mode 100644
--- a/browser/base/content/test/general/browser_updatecommands.js
+++ /dev/null
@@ -1,93 +0,0 @@
-let testPage = "data:text/html,<body><input id='input1' value='value'><select size=2><option val=1>One</select></body>";
-
-let browser;
-
-function test() {
-  waitForExplicitFinish();
-
-  gURLBar.focus();
-
-  var tab = gBrowser.addTab();
-  browser = gBrowser.getBrowserForTab(tab);
-  gBrowser.selectedTab = tab;
-
-  addEventListener("commandupdate", checkTest, false);
-
-  function runFirstTest(event) {
-    browser.removeEventListener("load", runFirstTest, true);
-    doTest();
-  }
-
-  browser.addEventListener("load", runFirstTest, true);
-  browser.contentWindow.location = testPage;
-}
-
-let currentTest;
-
-let tests = [
-  // Switch focus to 'input1'. Paste and select all should be enabled.
-  { name: "focus input", test: function() { EventUtils.synthesizeKey("VK_TAB", {}) },
-    commands: { "cmd_copy" : true, "cmd_paste": true, "cmd_selectAll" : true, "cmd_undo" : false, "cmd_redo": false } },
-
-  // Move cursor to end which will deselect the text. Copy should be disabled but paste and select all should still be enabled.
-  { name: "cursor right", test: function() { EventUtils.synthesizeKey("VK_RIGHT", {}) },
-    commands: { "cmd_copy" : false, "cmd_paste": true, "cmd_selectAll" : true, "cmd_undo" : false, "cmd_redo": false } },
-
-  // Select all of the text. Copy should become enabled.
-  { name: "select all", test: function() { EventUtils.synthesizeKey("a", { accelKey: true }) },
-    commands: { "cmd_copy" : true, "cmd_paste": true, "cmd_selectAll" : true, "cmd_undo" : false, "cmd_redo": false } },
-
-  // Replace the text with 'c'. Copy should now be disabled and undo enabled.
-  { name: "change value", test: function() { EventUtils.synthesizeKey("c", {}) },
-    commands: { "cmd_copy" : false, "cmd_paste": true, "cmd_selectAll" : true, "cmd_undo" : true, "cmd_redo": false } },
-
-  // Undo. Undo should be disabled and redo enabled. The text is reselected so copy is enabled.
-  { name: "undo", test: function() { EventUtils.synthesizeKey("z", {accelKey: true }) },
-    commands: { "cmd_copy" : true, "cmd_paste": true, "cmd_selectAll" : true, "cmd_undo" : false, "cmd_redo": true  } },
-
-  // Switch focus to the select. Only select all should now be enabled.
-  { name: "focus select", test: function() { EventUtils.synthesizeKey("VK_TAB", {}) },
-    commands: { "cmd_copy" : false, "cmd_paste": false, "cmd_selectAll" : true, "cmd_undo" : false, "cmd_redo": false } },
-];
-
-function doTest()
-{
-  if (!tests.length) {
-    removeEventListener("commandupdate", checkTest, false);
-    gBrowser.removeCurrentTab();
-    finish();
-    return;
-  }
-
-  currentTest = tests.shift();
-  currentTest.test();
-}
-
-function checkTest(event)
-{
-  // Ignore commandupdates before the test starts
-  if (document.activeElement != browser || !currentTest) {
-    return;
-  }
-
-  // Skip events fired on command updaters other than the main edit menu one.
-  if (event.target != document.getElementById("editMenuCommandSetAll")) {
-    return;
-  }
-
-  for (let command in currentTest.commands) {
-    // Command updates can come several at a time, and, especially with multiple
-    // processes, the updates can come asynchronously. Handle this by just waiting
-    // until the command have the correct state. The test will timeout if the
-    // correct command update never occurs.
-    if ((document.getElementById(command).getAttribute("disabled") != "true") != currentTest.commands[command]) {
-      return;
-    }
-
-    is(document.getElementById(command).getAttribute("disabled") != "true", currentTest.commands[command],
-       currentTest["name"] + " " + command);
-  }
-
-  currentTest = null; // prevent the check from running again
-  SimpleTest.executeSoon(doTest);
-}
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -502,17 +502,17 @@ class Automation(object):
     # override the user's choice here.  See bug 1049688.
     env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
 
     env['GNOME_DISABLE_CRASH_DIALOG'] = '1'
     env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1'
     env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
 
     # Set WebRTC logging in case it is not set yet
-    env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
+    env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
     env.setdefault('R_LOG_LEVEL', '6')
     env.setdefault('R_LOG_DESTINATION', 'stderr')
     env.setdefault('R_LOG_VERBOSE', '1')
 
     # ASan specific environment stuff
     if self.IS_ASAN and (self.IS_LINUX or self.IS_MAC):
       # Symbolizer support
       llvmsym = os.path.join(xrePath, "llvm-symbolizer")
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -405,17 +405,17 @@ def environment(xrePath, env=None, crash
 
   # Crash on non-local network connections by default.
   # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
   # enable non-local connections for the purposes of local testing.  Don't
   # override the user's choice here.  See bug 1049688.
   env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
 
   # Set WebRTC logging in case it is not set yet
-  env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
+  env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
   env.setdefault('R_LOG_LEVEL', '6')
   env.setdefault('R_LOG_DESTINATION', 'stderr')
   env.setdefault('R_LOG_VERBOSE', '1')
 
   # ASan specific environment stuff
   asan = bool(mozinfo.info.get("asan"))
   if asan and (mozinfo.isLinux or mozinfo.isMac):
     try:
--- a/caps/moz.build
+++ b/caps/moz.build
@@ -33,8 +33,9 @@ MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/js/xpconnect/src',
 ]
 
 FINAL_LIBRARY = 'xul'
 
+FAIL_ON_WARNINGS = True
--- a/chrome/moz.build
+++ b/chrome/moz.build
@@ -37,8 +37,10 @@ GENERATED_INCLUDES += [
 LOCAL_INCLUDES += [
     '/netwerk/base/src',
     '/netwerk/protocol/res',
     '/xpcom/components'
 ]
 
 if CONFIG['MOZ_ENABLE_GTK']:
     CXXFLAGS += CONFIG['TK_CFLAGS']
+
+FAIL_ON_WARNINGS = True
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -21,17 +21,16 @@
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsLayoutUtils.h"
 #include "nsIPresShell.h"
 #include "nsFrameTraversal.h"
 #include "nsIWebNavigation.h"
 #include "nsCaret.h"
 #include "nsIBaseWindow.h"
-#include "nsIXULWindow.h"
 #include "nsViewManager.h"
 #include "nsFrameSelection.h"
 #include "mozilla/dom/Selection.h"
 #include "nsXULPopupManager.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "nsIObserverService.h"
 #include "nsIObjectFrame.h"
@@ -730,20 +729,17 @@ nsFocusManager::WindowRaised(nsIDOMWindo
   nsCOMPtr<nsIPresShell> presShell = currentDocShell->GetPresShell();
   if (presShell) {
     // disable selection mousedown state on activation
     // XXXndeakin P3 not sure if this is necessary, but it doesn't hurt
     nsRefPtr<nsFrameSelection> frameSelection = presShell->FrameSelection();
     frameSelection->SetDragState(false);
   }
 
-  // If there is no nsIXULWindow, then this is an embedded or child process window.
-  // Pass false for aWindowRaised so that commands get updated.
-  nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(baseWindow));
-  Focus(currentWindow, currentFocus, 0, true, false, xulWin != nullptr, true);
+  Focus(currentWindow, currentFocus, 0, true, false, true, true);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFocusManager::WindowLowered(nsIDOMWindow* aWindow)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9265,46 +9265,16 @@ nsGlobalWindow::ShowModalDialog(const ns
 
   ErrorResult rv;
   nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aURI, aArgs, aOptions, rv);
   retVal.forget(aRetVal);
 
   return rv.ErrorCode();
 }
 
-class ChildCommandDispatcher : public nsRunnable
-{
-public:
-  ChildCommandDispatcher(nsGlobalWindow* aWindow,
-                         nsITabChild* aTabChild,
-                         const nsAString& aAction)
-  : mWindow(aWindow), mTabChild(aTabChild), mAction(aAction) {}
-
-  NS_IMETHOD Run()
-  {
-    nsCOMPtr<nsPIWindowRoot> root = mWindow->GetTopWindowRoot();
-    if (!root) {
-      return NS_OK;
-    }
-
-    nsTArray<nsCString> enabledCommands, disabledCommands;
-    root->GetEnabledDisabledCommands(enabledCommands, disabledCommands);
-    if (enabledCommands.Length() || disabledCommands.Length()) {
-      mTabChild->EnableDisableCommands(mAction, enabledCommands, disabledCommands);
-    }
-
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<nsGlobalWindow>             mWindow;
-  nsCOMPtr<nsITabChild>                mTabChild;
-  nsString                             mAction;
-};
-
 class CommandDispatcher : public nsRunnable
 {
 public:
   CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher,
                     const nsAString& aAction)
   : mDispatcher(aDispatcher), mAction(aAction) {}
 
   NS_IMETHOD Run()
@@ -9314,22 +9284,16 @@ public:
 
   nsCOMPtr<nsIDOMXULCommandDispatcher> mDispatcher;
   nsString                             mAction;
 };
 
 NS_IMETHODIMP
 nsGlobalWindow::UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason)
 {
-  // If this is a child process, redirect to the parent process.
-  if (nsCOMPtr<nsITabChild> child = do_GetInterface(GetDocShell())) {
-    nsContentUtils::AddScriptRunner(new ChildCommandDispatcher(this, child, anAction));
-    return NS_OK;
-  }
-
   nsPIDOMWindow *rootWindow = nsGlobalWindow::GetPrivateRoot();
   if (!rootWindow)
     return NS_OK;
 
   nsCOMPtr<nsIDOMXULDocument> xulDoc =
     do_QueryInterface(rootWindow->GetExtantDoc());
   // See if we contain a XUL document.
   // selectionchange action is only used for mozbrowser, not for XUL. So we bypass
--- a/dom/base/nsPIWindowRoot.h
+++ b/dom/base/nsPIWindowRoot.h
@@ -10,37 +10,34 @@
 #include "nsISupports.h"
 #include "mozilla/dom/EventTarget.h"
 
 class nsPIDOMWindow;
 class nsIControllers;
 class nsIController;
 
 #define NS_IWINDOWROOT_IID \
-{ 0x728a2682, 0x55c0, 0x4860, \
- { 0x82, 0x6b, 0x0c, 0x30, 0x0a, 0xac, 0xaa, 0x60 } }
+{ 0x3f71f50c, 0xa7e0, 0x43bc, \
+ { 0xac, 0x25, 0x4d, 0xbb, 0x88, 0x7b, 0x21, 0x09 } }
 
 class nsPIWindowRoot : public mozilla::dom::EventTarget
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWINDOWROOT_IID)
 
   virtual nsPIDOMWindow* GetWindow()=0;
 
   // get and set the node that is the context of a popup menu
   virtual nsIDOMNode* GetPopupNode() = 0;
   virtual void SetPopupNode(nsIDOMNode* aNode) = 0;
 
   virtual nsresult GetControllerForCommand(const char *aCommand,
                                            nsIController** aResult) = 0;
   virtual nsresult GetControllers(nsIControllers** aResult) = 0;
 
-  virtual void GetEnabledDisabledCommands(nsTArray<nsCString>& aEnabledCommands,
-                                          nsTArray<nsCString>& aDisabledCommands) = 0;
-
   virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) = 0;
   virtual mozilla::dom::EventTarget* GetParentTarget() = 0;
   virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIWindowRoot, NS_IWINDOWROOT_IID)
 
 #endif // nsPIWindowRoot_h__
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -276,85 +276,16 @@ nsWindowRoot::GetControllerForCommand(co
     // XXXndeakin P3 is this casting safe?
     nsGlobalWindow *win = static_cast<nsGlobalWindow*>(focusedWindow.get());
     focusedWindow = win->GetPrivateParent();
   }
   
   return NS_OK;
 }
 
-void
-nsWindowRoot::GetEnabledDisabledCommandsForControllers(nsIControllers* aControllers,
-                                                       nsTHashtable<nsCharPtrHashKey>& aCommandsHandled,
-                                                       nsTArray<nsCString>& aEnabledCommands,
-                                                       nsTArray<nsCString>& aDisabledCommands)
-{
-  uint32_t controllerCount;
-  aControllers->GetControllerCount(&controllerCount);
-  for (uint32_t c = 0; c < controllerCount; c++) {
-    nsCOMPtr<nsIController> controller;
-    aControllers->GetControllerAt(c, getter_AddRefs(controller));
-
-    nsCOMPtr<nsICommandController> commandController(do_QueryInterface(controller));
-    if (commandController) {
-      uint32_t commandsCount;
-      char** commands;
-      if (NS_SUCCEEDED(commandController->GetSupportedCommands(&commandsCount, &commands))) {
-        for (uint32_t e = 0; e < commandsCount; e++) {
-          // Use a hash to determine which commands have already been handled by
-          // earlier controllers, as the earlier controller's result should get
-          // priority.
-          if (!aCommandsHandled.Contains(commands[e])) {
-            aCommandsHandled.PutEntry(commands[e]);
-
-            bool enabled = false;
-            controller->IsCommandEnabled(commands[e], &enabled);
-
-            const nsDependentCSubstring commandStr(commands[e], strlen(commands[e]));
-            if (enabled) {
-              aEnabledCommands.AppendElement(commandStr);
-            } else {
-              aDisabledCommands.AppendElement(commandStr);
-            }
-          }
-        }
-
-        NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(commandsCount, commands);
-      }
-    }
-  }
-}
-
-void
-nsWindowRoot::GetEnabledDisabledCommands(nsTArray<nsCString>& aEnabledCommands,
-                                         nsTArray<nsCString>& aDisabledCommands)
-{
-  nsTHashtable<nsCharPtrHashKey> commandsHandled;
-
-  nsCOMPtr<nsIControllers> controllers;
-  GetControllers(getter_AddRefs(controllers));
-  if (controllers) {
-    GetEnabledDisabledCommandsForControllers(controllers, commandsHandled,
-                                             aEnabledCommands, aDisabledCommands);
-  }
-
-  nsCOMPtr<nsPIDOMWindow> focusedWindow;
-  nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow));
-  while (focusedWindow) {
-    focusedWindow->GetControllers(getter_AddRefs(controllers));
-    if (controllers) {
-      GetEnabledDisabledCommandsForControllers(controllers, commandsHandled,
-                                               aEnabledCommands, aDisabledCommands);
-    }
-
-    nsGlobalWindow* win = static_cast<nsGlobalWindow*>(focusedWindow.get());
-    focusedWindow = win->GetPrivateParent();
-  }
-}
-
 nsIDOMNode*
 nsWindowRoot::GetPopupNode()
 {
   return mPopupNode;
 }
 
 void
 nsWindowRoot::SetPopupNode(nsIDOMNode* aNode)
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -18,18 +18,16 @@ class EventChainPreVisitor;
 } // namespace mozilla
 
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
 #include "nsIDOMEventTarget.h"
 #include "nsPIWindowRoot.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
-#include "nsTHashtable.h"
-#include "nsHashKeys.h"
 
 class nsWindowRoot : public nsPIWindowRoot
 {
 public:
   explicit nsWindowRoot(nsPIDOMWindow* aWindow);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIDOMEVENTTARGET
@@ -49,19 +47,16 @@ public:
   // nsPIWindowRoot
 
   virtual nsPIDOMWindow* GetWindow() MOZ_OVERRIDE;
 
   virtual nsresult GetControllers(nsIControllers** aResult) MOZ_OVERRIDE;
   virtual nsresult GetControllerForCommand(const char * aCommand,
                                            nsIController** _retval) MOZ_OVERRIDE;
 
-  virtual void GetEnabledDisabledCommands(nsTArray<nsCString>& aEnabledCommands,
-                                          nsTArray<nsCString>& aDisabledCommands) MOZ_OVERRIDE;
-
   virtual nsIDOMNode* GetPopupNode() MOZ_OVERRIDE;
   virtual void SetPopupNode(nsIDOMNode* aNode) MOZ_OVERRIDE;
 
   virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) MOZ_OVERRIDE
   {
     mParent = aTarget;
   }
   virtual mozilla::dom::EventTarget* GetParentTarget() MOZ_OVERRIDE { return mParent; }
@@ -72,21 +67,16 @@ public:
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
                                                          nsIDOMEventTarget)
 
 protected:
   virtual ~nsWindowRoot();
 
-  void GetEnabledDisabledCommandsForControllers(nsIControllers* aControllers,
-                                                nsTHashtable<nsCharPtrHashKey>& aCommandsHandled,
-                                                nsTArray<nsCString>& aEnabledCommands,
-                                                nsTArray<nsCString>& aDisabledCommands);
-
   // Members
   nsCOMPtr<nsPIDOMWindow> mWindow;
   // We own the manager, which owns event listeners attached to us.
   nsRefPtr<mozilla::EventListenerManager> mListenerManager; // [Strong]
   nsCOMPtr<nsIDOMNode> mPopupNode; // [OWNER]
 
   nsCOMPtr<mozilla::dom::EventTarget> mParent;
 };
--- a/dom/base/test/TestCSPParser.cpp
+++ b/dom/base/test/TestCSPParser.cpp
@@ -273,19 +273,19 @@ nsresult TestIgnoreUpperLowerCasePolicie
     { "script-src 'SHA256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='",
       "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" }
   };
 
   uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
   return runTestSuite(policies, policyCount, 1);
 }
 
-// ============================= TestIgnorePaths ========================
+// ============================= TestPaths ========================
 
-nsresult TestIgnorePaths() {
+nsresult TestPaths() {
 
   static const PolicyTest policies[] =
   {
     { "script-src http://www.example.com",
       "script-src http://www.example.com" },
     { "script-src http://www.example.com/",
       "script-src http://www.example.com/" },
     { "script-src http://www.example.com/path-1",
@@ -355,16 +355,22 @@ nsresult TestIgnorePaths() {
     { "report-uri http://www.example.com:8888/asdf",
       "report-uri http://www.example.com:8888/asdf" },
     { "report-uri http://www.example.com:8888/path_1/path_2",
       "report-uri http://www.example.com:8888/path_1/path_2" },
     { "report-uri http://www.example.com:8888/path_1/path_2/report.sjs&301",
       "report-uri http://www.example.com:8888/path_1/path_2/report.sjs&301" },
     { "report-uri /examplepath",
       "report-uri http://www.selfuri.com/examplepath" },
+    { "connect-src http://www.example.com/foo%3Bsessionid=12%2C34",
+      "connect-src http://www.example.com/foo;sessionid=12,34" },
+    { "connect-src http://www.example.com/foo%3bsessionid=12%2c34",
+      "connect-src http://www.example.com/foo;sessionid=12,34" },
+    { "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@",
+      "connect-src http://test.com/pathincludingaz19-._~!$&'()*+=:@" },
   };
 
   uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
   return runTestSuite(policies, policyCount, 1);
 }
 
 // ============================= TestSimplePolicies ========================
 
@@ -487,16 +493,20 @@ nsresult TestPoliciesWithInvalidSrc() {
     { "script-src http://www.example.com:88/.js",
       "script-src 'none'" },
     { "script-src http://www.example.com:88.js",
       "script-src 'none'" },
     { "script-src http://www.example.com:*.js",
       "script-src 'none'" },
     { "script-src http://www.example.com:*.",
       "script-src 'none'" },
+    { "connect-src http://www.example.com/foo%zz;",
+      "connect-src 'none'" },
+    { "script-src https://foo.com/%$",
+      "script-src 'none'" },
   };
 
   uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
   return runTestSuite(policies, policyCount, 1);
 }
 
 // ============================= TestBadPolicies ========================
 
@@ -1078,17 +1088,17 @@ int main(int argc, char** argv) {
   ScopedXPCOM xpcom("ContentSecurityPolicyParser");
   if (xpcom.failed()) {
     return 1;
   }
 
   if (NS_FAILED(TestDirectives()))                           { return 1; }
   if (NS_FAILED(TestKeywords()))                             { return 1; }
   if (NS_FAILED(TestIgnoreUpperLowerCasePolicies()))         { return 1; }
-  if (NS_FAILED(TestIgnorePaths()))                          { return 1; }
+  if (NS_FAILED(TestPaths()))                                { return 1; }
   if (NS_FAILED(TestSimplePolicies()))                       { return 1; }
   if (NS_FAILED(TestPoliciesWithInvalidSrc()))               { return 1; }
   if (NS_FAILED(TestBadPolicies()))                          { return 1; }
   if (NS_FAILED(TestGoodGeneratedPolicies()))                { return 1; }
   if (NS_FAILED(TestBadGeneratedPolicies()))                 { return 1; }
   if (NS_FAILED(TestGoodGeneratedPoliciesForPathHandling())) { return 1; }
   if (NS_FAILED(TestBadGeneratedPoliciesForPathHandling()))  { return 1; }
   if (NS_FAILED(TestShorteningPolicies()))                   { return 1; }
--- a/dom/base/test/csp/file_csp_redirects_main.html
+++ b/dom/base/test/csp/file_csp_redirects_main.html
@@ -15,16 +15,18 @@ var tests = { "font-src": thisSite+page+
               "frame-src": thisSite+page+"?testid=frame-src&csp=1",
               "img-src":  thisSite+page+"?testid=img-src&csp=1",
               "media-src":  thisSite+page+"?testid=media-src&csp=1",
               "object-src":  thisSite+page+"?testid=object-src&csp=1",
               "script-src":  thisSite+page+"?testid=script-src&csp=1",
               "style-src":  thisSite+page+"?testid=style-src&csp=1",
               "worker":  thisSite+page+"?testid=worker&csp=1",
               "xhr-src":  thisSite+page+"?testid=xhr-src&csp=1",
+              "script-src-from-worker": thisSite+page+"?testid=script-src-from-worker&csp=1",
+              "img-src-from-css":  thisSite+page+"?testid=img-src-from-css&csp=1",
             };
 
 var container = document.getElementById("container");
 
 // load each test in its own iframe
 for (tid in tests) {
   var i = document.createElement("iframe");
   i.id = tid;
--- a/dom/base/test/csp/file_csp_redirects_page.sjs
+++ b/dom/base/test/csp/file_csp_redirects_page.sjs
@@ -71,9 +71,26 @@ function handleRequest(request, response
     return;
   }
 
   // script that XHR's to a resource that redirects to another site
   if (query["testid"] == "xhr-src") {
     response.write('<script src="'+resource+'?res=xhr"></script>');
     return;
   }
+
+  // for bug949706
+  if (query["testid"] == "img-src-from-css") {
+    // loads a stylesheet, which in turn loads an image that redirects.
+    response.write('<link rel="stylesheet" type="text/css" href="'+resource+'?res=cssLoader&id=img-src-redir-from-css">');
+    return;
+  }
+
+  if (query["testid"] == "script-src-from-worker") {
+    // loads a script; launches a worker; that worker uses importscript; which then gets redirected
+    // So it's:
+    // <script "res=loadWorkerThatImports">
+    //   .. loads Worker("res=importScriptWorker")
+    //         .. calls importScript("res=script")
+    response.write('<script src="'+resource+'?res=loadWorkerThatImports&id=script-src-redir-from-worker"></script>');
+    return;
+  }
 }
--- a/dom/base/test/csp/file_csp_redirects_resource.sjs
+++ b/dom/base/test/csp/file_csp_redirects_resource.sjs
@@ -87,16 +87,44 @@ function handleRequest(request, response
 
   // web worker resource
   if (query["res"] == "worker") {
     response.setHeader("Content-Type", "application/javascript", false);
     response.write("worker script data...");
     return;
   }
 
+  // internal stylesheet that loads an image from an external site
+  if (query["res"] == "cssLoader") {
+    let bgURL = thisSite + resource + '?redir=other&res=image&id=' + query["id"];
+    response.setHeader("Content-Type", "text/css", false);
+    response.write("body { background:url('" + bgURL + "'); }");
+    return;
+  }
+
+  // script that loads an internal worker that uses importScripts on a redirect
+  // to an external script.
+  if (query["res"] == "loadWorkerThatImports") {
+    // this creates a worker (same origin) that imports a redirecting script.
+    let workerURL = thisSite + resource + '?res=importScriptWorker&id=' + query["id"];
+    response.setHeader("Content-Type", "application/javascript", false);
+    response.write("var w=new Worker('" + workerURL + "'); w.onmessage=function(event){ alert(event.data); }");
+    return;
+  }
+
+  // source for a worker that simply calls importScripts on a script that
+  // redirects.
+  if (query["res"] == "importScriptWorker") {
+    // this is code for a worker that imports a redirected script.
+    let scriptURL = thisSite + resource + "?redir=other&res=script&id=" + query["id"];
+    response.setHeader("Content-Type", "application/javascript", false);
+    response.write("importScripts('" + scriptURL + "');");
+    return;
+  }
+
   // script that invokes XHR
   if (query["res"] == "xhr") {
     response.setHeader("Content-Type", "text/html", false);
     var resp = 'var x = new XMLHttpRequest(); x.open("GET", "' + otherSite +
                resource+'?res=xhr-resp&testid=xhr-src-redir", false); ' +
                'x.send(null);';
     response.write(resp);
     return;
new file mode 100644
--- /dev/null
+++ b/dom/base/test/csp/file_worker_redirect.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <title>Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected</title>
+  </head>
+  <body>
+  <script src="file_worker_redirect.sjs?stage_0_script_loads_worker"></script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/csp/file_worker_redirect.sjs
@@ -0,0 +1,37 @@
+// testserver customized for the needs of:
+// Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected
+
+function handleRequest(request, response)
+{
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "text/html", false);
+
+  var query = request.queryString;
+
+  if (query === "stage_0_script_loads_worker") {
+    var newWorker =
+      "var myWorker = new Worker(\"file_worker_redirect.sjs?stage_1_worker_import_scripts\");" +
+      "myWorker.onmessage = function (event) { parent.checkResult(\"allowed\"); };" +
+      "myWorker.onerror = function (event) { parent.checkResult(\"blocked\"); };";
+    response.write(newWorker);
+    return;
+  }
+
+  if (query === "stage_1_worker_import_scripts") {
+    response.write("importScripts(\"file_worker_redirect.sjs?stage_2_redirect_imported_script\");");
+    return;
+  }
+
+  if (query === "stage_2_redirect_imported_script") {
+    var newLocation =
+      "http://test1.example.com/tests/dom/base/test/csp/file_worker_redirect.sjs?stage_3_target_script";
+    response.setStatusLine("1.1", 302, "Found");
+    response.setHeader("Location", newLocation, false);
+    return;
+  }
+
+  if (query === "stage_3_target_script") {
+    response.write("postMessage(\"imported script loaded\");");
+    return;
+  }
+}
--- a/dom/base/test/csp/mochitest.ini
+++ b/dom/base/test/csp/mochitest.ini
@@ -96,16 +96,18 @@ support-files =
   file_subframe_run_js_if_allowed.html
   file_subframe_run_js_if_allowed.html^headers^
   file_leading_wildcard.html
   file_multi_policy_injection_bypass.html
   file_multi_policy_injection_bypass.html^headers^
   file_multi_policy_injection_bypass_2.html
   file_multi_policy_injection_bypass_2.html^headers^
   file_form-action.html
+  file_worker_redirect.html
+  file_worker_redirect.sjs
 
 [test_base-uri.html]
 [test_connect-src.html]
 [test_CSP.html]
 [test_csp_allow_https_schemes.html]
 skip-if = buildapp == 'b2g' #no ssl support
 [test_CSP_bug663567.html]
 [test_CSP_bug802872.html]
@@ -142,8 +144,9 @@ skip-if = buildapp == 'b2g' # intermitte
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_303_redirect.html]
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_307_redirect.html]
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_subframe_run_js_if_allowed.html]
 [test_leading_wildcard.html]
 [test_multi_policy_injection_bypass.html]
+[test_worker_redirect.html]
--- a/dom/base/test/csp/test_csp_redirects.html
+++ b/dom/base/test/csp/test_csp_redirects.html
@@ -81,16 +81,20 @@ var testExpectedResults = { "font-src": 
                             "script-src": true,
                             "script-src-redir": false,
                             "style-src": true,
                             "style-src-redir": false,
                             "worker": true,
                             "worker-redir": false,
                             "xhr-src": true,
                             "xhr-src-redir": false,
+                            "script-src-from-worker": true, /* test runs */
+                            "script-src-redir-from-worker": false, /* redir is blocked */
+                            "img-src-from-css": true, /* test runs */
+                            "img-src-redir-from-css": false, /* redir is blocked */
                           };
 
 // takes the name of the test, the URL that was tested, and whether the
 // load occurred
 var testResult = function(testName, url, result) {
   log("  testName: "+testName+", result: "+result+", expected: "+testExpectedResults[testName]+"\n");
   is(result, testExpectedResults[testName], testName+" test: "+url);
 
new file mode 100644
--- /dev/null
+++ b/dom/base/test/csp/test_worker_redirect.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected</title>
+  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <div id="content" style="visibility: hidden">
+    <iframe style="width:100%;" id="testframe"></iframe>
+  </div>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load a page that loads a script which then instantiates a web worker,
+ * where that web worker then imports a script which gets redirected.
+ * We verify that the CSP applies correctly after the imported script of
+ * the worker gets redirected. More specifically, the test works as follows:
+ *
+ * test_worker_redirect.html
+ * -> loads file_worker_redirect.html file into iframe
+ * -> loads worker file_worker_redirect.sjs?stage_0_script_loads_worker
+ * -> creates script file_worker_redirect.sjs?stage_1_worker_import_scripts
+ * -> redirects script file_worker_redirect.sjs?stage_2_redirect_imported_script
+ * -> loads target script file_worker_redirect.sjs?stage_3_target_script
+ *
+ * Please note that we have to use 'unsafe-eval' in the policy
+ * so that workers are actually permitted by the CSP.
+ *
+ * The main test is loaded using:
+ *   http://mochi.test:8888
+ * where the imported script gets redirected to:
+ *   http://test1.example.com
+ */
+
+var tests = [
+  {
+    policy: "default-src 'self'; script-src 'self' 'unsafe-eval' http://test1.example.com;",
+    expected: "allowed"
+  },
+  {
+    policy: "default-src 'self'; script-src 'self' 'unsafe-eval';",
+    expected: "blocked",
+  },
+];
+
+var counter = 0;
+var curTest;
+
+function checkResult(aResult) {
+  is(aResult, curTest.expected, "Should be (" + curTest.expected + ") in Test " + counter + "!");
+  loadNextTest();
+}
+
+function loadNextTest() {
+  if (counter == tests.length) {
+    SimpleTest.finish();
+    return;
+  }
+  curTest = tests[counter++];
+  var src = "file_csp_testserver.sjs";
+  // append the file that should be served
+  src += "?file=" + escape("tests/dom/base/test/csp/file_worker_redirect.html");
+  // append the CSP that should be used to serve the file
+  src += "&csp=" + escape(curTest.policy);
+  document.getElementById("testframe").src = src;
+}
+
+SimpleTest.waitForExplicitFinish();
+loadNextTest();
+
+</script>
+</body>
+</html>
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -857,17 +857,17 @@ DOMInterfaces = {
 },
 
 'Path2D': {
     'nativeType': 'mozilla::dom::CanvasPath',
     'headerFile': 'CanvasRenderingContext2D.h'
 },
 
 'PeerConnectionImpl': {
-    'nativeType': 'sipcc::PeerConnectionImpl',
+    'nativeType': 'mozilla::PeerConnectionImpl',
     'headerFile': 'PeerConnectionImpl.h',
     'wrapperCache': False
 },
 
 'Performance': [{
     'nativeType': 'nsPerformance',
 },
 {
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -59,16 +59,17 @@ LOCAL_INCLUDES += [
     '/dom/xslt/xpath',
     '/dom/xul',
     '/js/ipc',
     '/js/xpconnect/src',
     '/js/xpconnect/wrappers',
     '/layout/style',
     '/layout/xul/tree',
     '/media/mtransport',
+    '/media/webrtc/',
     '/media/webrtc/signaling/src/common/time_profiling',
     '/media/webrtc/signaling/src/peerconnection',
 ]
 
 UNIFIED_SOURCES += [
     'BindingUtils.cpp',
     'CallbackInterface.cpp',
     'CallbackObject.cpp',
--- a/dom/inputmethod/Keyboard.jsm
+++ b/dom/inputmethod/Keyboard.jsm
@@ -14,16 +14,46 @@ Cu.import('resource://gre/modules/Servic
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
   "@mozilla.org/parentprocessmessagemanager;1", "nsIMessageBroadcaster");
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
 
+XPCOMUtils.defineLazyGetter(this, "appsService", function() {
+  return Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
+});
+
+let Utils = {
+  getMMFromMessage: function u_getMMFromMessage(msg) {
+    let mm;
+    try {
+      mm = msg.target.QueryInterface(Ci.nsIFrameLoaderOwner)
+                     .frameLoader.messageManager;
+    } catch(e) {
+      mm = msg.target;
+    }
+
+    return mm;
+  },
+  checkPermissionForMM: function u_checkPermissionForMM(mm, permName) {
+    let testing = false;
+    try {
+      testing = Services.prefs.getBoolPref("dom.mozInputMethod.testing");
+    } catch (e) { }
+
+    if (testing) {
+      return true;
+    }
+
+    return mm.assertPermission(permName);
+  }
+};
+
 this.Keyboard = {
   _formMM: null,      // The current web page message manager.
   _keyboardMM: null,  // The keyboard app message manager.
   _keyboardID: -1,    // The keyboard app's ID number. -1 = invalid
   _nextKeyboardID: 0, // The ID number counter.
   _systemMessageName: [
     'SetValue', 'RemoveFocus', 'SetSelectedOption', 'SetSelectedOptions'
   ],
@@ -67,16 +97,18 @@ this.Keyboard = {
 
     for (let name of this._messageNames) {
       ppmm.addMessageListener('Keyboard:' + name, this);
     }
 
     for (let name of this._systemMessageName) {
       ppmm.addMessageListener('System:' + name, this);
     }
+
+    this.inputRegistryGlue = new InputRegistryGlue();
   },
 
   observe: function keyboardObserve(subject, topic, data) {
     let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
     let mm = frameLoader.messageManager;
 
     if (topic == 'oop-frameloader-crashed') {
       if (this.formMM == mm) {
@@ -117,39 +149,28 @@ this.Keyboard = {
     let isKeyboardRegistration = msg.name == "Keyboard:Register" ||
                                  msg.name == "Keyboard:Unregister";
     if (msg.name.indexOf("Keyboard:") === 0 ||
         msg.name.indexOf("System:") === 0) {
       if (!this.formMM && !isKeyboardRegistration) {
         return;
       }
 
-      try {
-        mm = msg.target.QueryInterface(Ci.nsIFrameLoaderOwner)
-                       .frameLoader.messageManager;
-      } catch(e) {
-        mm = msg.target;
-      }
+      mm = Utils.getMMFromMessage(msg);
 
       // That should never happen.
       if (!mm) {
         dump("!! No message manager found for " + msg.name);
         return;
       }
 
-      let testing = false;
-      try {
-        testing = Services.prefs.getBoolPref("dom.mozInputMethod.testing");
-      } catch (e) {
-      }
-
       let perm = (msg.name.indexOf("Keyboard:") === 0) ? "input"
                                                        : "input-manage";
-      if (!isKeyboardRegistration && !testing &&
-          !mm.assertPermission(perm)) {
+
+      if (!isKeyboardRegistration && !Utils.checkPermissionForMM(mm, perm)) {
         dump("Keyboard message " + msg.name +
         " from a content process with no '" + perm + "' privileges.");
         return;
       }
     }
 
     // we don't process kb messages (other than register)
     // if they come from a kb that we're currently not regsitered for.
@@ -359,9 +380,98 @@ this.Keyboard = {
     // cache the layouts so on init we can respond immediately instead
     // of going back and forth between keyboard_manager
     this._layouts = layouts;
 
     this.sendToKeyboard('Keyboard:LayoutsChange', layouts);
   }
 };
 
+function InputRegistryGlue() {
+  this._messageId = 0;
+  this._msgMap = new Map();
+
+  ppmm.addMessageListener('InputRegistry:Add', this);
+  ppmm.addMessageListener('InputRegistry:Remove', this);
+};
+
+InputRegistryGlue.prototype.receiveMessage = function(msg) {
+  let mm = Utils.getMMFromMessage(msg);
+
+  if (!Utils.checkPermissionForMM(mm, 'input')) {
+    dump("InputRegistryGlue message " + msg.name +
+      " from a content process with no 'input' privileges.");
+    return;
+  }
+
+  switch (msg.name) {
+    case 'InputRegistry:Add':
+      this.addInput(msg, mm);
+
+      break;
+
+    case 'InputRegistry:Remove':
+      this.removeInput(msg, mm);
+
+      break;
+  }
+};
+
+InputRegistryGlue.prototype.addInput = function(msg, mm) {
+  let msgId = this._messageId++;
+  this._msgMap.set(msgId, {
+    mm: mm,
+    requestId: msg.data.requestId
+  });
+
+  let manifestURL = appsService.getManifestURLByLocalId(msg.data.appId);
+
+  SystemAppProxy.dispatchEvent({
+    type: 'inputregistry-add',
+    id: msgId,
+    manifestURL: manifestURL,
+    inputId: msg.data.inputId,
+    inputManifest: msg.data.inputManifest
+  });
+};
+
+InputRegistryGlue.prototype.removeInput = function(msg, mm) {
+  let msgId = this._messageId++;
+  this._msgMap.set(msgId, {
+    mm: mm,
+    requestId: msg.data.requestId
+  });
+
+  let manifestURL = appsService.getManifestURLByLocalId(msg.data.appId);
+
+  SystemAppProxy.dispatchEvent({
+    type: 'inputregistry-remove',
+    id: msgId,
+    manifestURL: manifestURL,
+    inputId: msg.data.inputId
+  });
+};
+
+InputRegistryGlue.prototype.returnMessage = function(detail) {
+  if (!this._msgMap.has(detail.id)) {
+    return;
+  }
+
+  let { mm, requestId } = this._msgMap.get(detail.id);
+  this._msgMap.delete(detail.id);
+
+  if (Cu.isDeadWrapper(mm)) {
+    return;
+  }
+
+  if (!('error' in detail)) {
+    mm.sendAsyncMessage('InputRegistry:Result:OK', {
+      requestId: requestId
+    });
+  } else {
+    mm.sendAsyncMessage('InputRegistry:Result:Error', {
+      error: detail.error,
+      requestId: requestId
+    });
+  }
+};
+
 this.Keyboard.init();
--- a/dom/inputmethod/MozKeyboard.js
+++ b/dom/inputmethod/MozKeyboard.js
@@ -144,16 +144,18 @@ MozInputMethodManager.prototype = {
 /**
  * ==============================================
  * InputMethod
  * ==============================================
  */
 function MozInputMethod() { }
 
 MozInputMethod.prototype = {
+  __proto__: DOMRequestIpcHelper.prototype,
+
   _inputcontext: null,
   _wrappedInputContext: null,
   _layouts: {},
   _window: null,
   _isSystem: false,
   _isKeyboard: true,
 
   classID: Components.ID("{4607330d-e7d2-40a4-9eb8-43967eae0142}"),
@@ -191,60 +193,77 @@ MozInputMethod.prototype = {
       this._isKeyboard = false;
       return;
     }
 
     cpmm.addWeakMessageListener('Keyboard:FocusChange', this);
     cpmm.addWeakMessageListener('Keyboard:SelectionChange', this);
     cpmm.addWeakMessageListener('Keyboard:GetContext:Result:OK', this);
     cpmm.addWeakMessageListener('Keyboard:LayoutsChange', this);
+    cpmm.addWeakMessageListener('InputRegistry:Result:OK', this);
+    cpmm.addWeakMessageListener('InputRegistry:Result:Error', this);
   },
 
   uninit: function mozInputMethodUninit() {
     this._window = null;
     this._mgmt = null;
     Services.obs.removeObserver(this, "inner-window-destroyed");
     if (!this._isKeyboard) {
       return;
     }
 
     cpmm.removeWeakMessageListener('Keyboard:FocusChange', this);
     cpmm.removeWeakMessageListener('Keyboard:SelectionChange', this);
     cpmm.removeWeakMessageListener('Keyboard:GetContext:Result:OK', this);
     cpmm.removeWeakMessageListener('Keyboard:LayoutsChange', this);
+    cpmm.removeWeakMessageListener('InputRegistry:Result:OK', this);
+    cpmm.removeWeakMessageListener('InputRegistry:Result:Error', this);
     this.setActive(false);
   },
 
   receiveMessage: function mozInputMethodReceiveMsg(msg) {
-    if (!WindowMap.isActive(this._window)) {
+    if (!msg.name.startsWith('InputRegistry') &&
+        !WindowMap.isActive(this._window)) {
       return;
     }
 
-    let json = msg.json;
+    let data = msg.data;
+    let resolver = ('requestId' in data) ?
+      this.takePromiseResolver(data.requestId) : null;
 
     switch(msg.name) {
       case 'Keyboard:FocusChange':
-        if (json.type !== 'blur') {
+        if (data.type !== 'blur') {
           // XXX Bug 904339 could receive 'text' event twice
-          this.setInputContext(json);
+          this.setInputContext(data);
         }
         else {
           this.setInputContext(null);
         }
         break;
       case 'Keyboard:SelectionChange':
         if (this.inputcontext) {
-          this._inputcontext.updateSelectionContext(json, false);
+          this._inputcontext.updateSelectionContext(data, false);
         }
         break;
       case 'Keyboard:GetContext:Result:OK':
-        this.setInputContext(json);
+        this.setInputContext(data);
         break;
       case 'Keyboard:LayoutsChange':
-        this._layouts = json;
+        this._layouts = data;
+        break;
+
+      case 'InputRegistry:Result:OK':
+        resolver.resolve();
+
+        break;
+
+      case 'InputRegistry:Result:Error':
+        resolver.reject(data.error);
+
         break;
     }
   },
 
   observe: function mozInputMethodObserve(subject, topic, data) {
     let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
     if (wId == this.innerWindowID)
       this.uninit();
@@ -325,16 +344,41 @@ MozInputMethod.prototype = {
       // Deactive current input method.
       cpmmSendAsyncMessageWithKbID(this, 'Keyboard:Unregister', {});
       if (this._inputcontext) {
         this.setInputContext(null);
       }
     }
   },
 
+  addInput: function(inputId, inputManifest) {
+    return this._sendPromise(function(resolverId) {
+      let appId = this._window.document.nodePrincipal.appId;
+
+      cpmm.sendAsyncMessage('InputRegistry:Add', {
+        requestId: resolverId,
+        inputId: inputId,
+        inputManifest: inputManifest,
+        appId: appId
+      });
+    }.bind(this));
+  },
+
+  removeInput: function(inputId) {
+    return this._sendPromise(function(resolverId) {
+      let appId = this._window.document.nodePrincipal.appId;
+
+      cpmm.sendAsyncMessage('InputRegistry:Remove', {
+        requestId: resolverId,
+        inputId: inputId,
+        appId: appId
+      });
+    }.bind(this));
+  },
+
   setValue: function(value) {
     this._ensureIsSystem();
     cpmm.sendAsyncMessage('System:SetValue', {
       'value': value
     });
   },
 
   setSelectedOption: function(index) {
@@ -356,16 +400,24 @@ MozInputMethod.prototype = {
     cpmm.sendAsyncMessage('System:RemoveFocus', {});
   },
 
   _ensureIsSystem: function() {
     if (!this._isSystem) {
       throw new this._window.DOMError("Security",
                                       "Should have 'input-manage' permssion.");
     }
+  },
+
+  _sendPromise: function(callback) {
+    let self = this;
+    return this.createPromise(function(resolve, reject) {
+      let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
+      callback(resolverId);
+    });
   }
 };
 
  /**
  * ==============================================
  * InputContext
  * ==============================================
  */
--- a/dom/interfaces/base/moz.build
+++ b/dom/interfaces/base/moz.build
@@ -26,17 +26,16 @@ XPIDL_SOURCES += [
     'nsIDOMScreen.idl',
     'nsIDOMWindow.idl',
     'nsIDOMWindowCollection.idl',
     'nsIDOMWindowUtils.idl',
     'nsIFocusManager.idl',
     'nsIFrameRequestCallback.idl',
     'nsIIdleObserver.idl',
     'nsIQueryContentEventResult.idl',
-    'nsIRemoteBrowser.idl',
     'nsIServiceWorkerManager.idl',
     'nsIStructuredCloneContainer.idl',
     'nsITabChild.idl',
     'nsITabParent.idl',
 ]
 
 XPIDL_MODULE = 'dom_base'
 
deleted file mode 100644
--- a/dom/interfaces/base/nsIRemoteBrowser.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(C8379366-F79F-4D25-89A6-22BEC0A93D16)]
-interface nsIRemoteBrowser : nsISupports
-{
-  /*
-   * Called by the child to inform the parent that a command update has occurred
-   * and the supplied set of commands are now enabled and disabled.
-   *
-   * @param action command updater action
-   * @param enabledLength length of enabledCommands array
-   * @param enabledCommands commands to enable
-   * @param disabledLength length of disabledCommands array
-   * @param disabledCommand commands to disable
-   */
-  void enableDisableCommands(in AString action,
-                             in unsigned long enabledLength,
-                             [array, size_is(enabledLength)] in string enabledCommands,
-                             in unsigned long disabledLength,
-                             [array, size_is(disabledLength)] in string disabledCommands);
-};
-
--- a/dom/interfaces/base/nsITabChild.idl
+++ b/dom/interfaces/base/nsITabChild.idl
@@ -2,25 +2,18 @@
  * 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/. */
 
 
 #include "domstubs.idl"
 interface nsIContentFrameMessageManager;
 interface nsIWebBrowserChrome3;
 
-native CommandsArray(nsTArray<nsCString>);
-[ref] native CommandsArrayRef(nsTArray<nsCString>);
-
-[scriptable, uuid(7227bac4-b6fe-4090-aeb4-bc288b790925)]
+[scriptable, uuid(2eb3bc54-78bf-40f2-b301-a5b5b70f7da0)]
 interface nsITabChild : nsISupports
 {
   readonly attribute nsIContentFrameMessageManager messageManager;
 
   attribute nsIWebBrowserChrome3 webBrowserChrome;
 
   [notxpcom] void sendRequestFocus(in boolean canFocus);
-
-  [noscript, notxpcom] void enableDisableCommands(in AString action,
-                                                  in CommandsArrayRef enabledCommands,
-                                                  in CommandsArrayRef disabledCommands);
 };
 
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -239,24 +239,16 @@ parent:
     prio(urgent) sync EndIMEComposition(bool cancel) returns (nsString composition);
 
     /**
      * Request that the parent process move focus to the browser's frame. If
      * canRaise is true, the window can be raised if it is inactive.
      */
     RequestFocus(bool canRaise);
 
-    /**
-     * Indicate, based on the current state, that some commands are enabled and
-     * some are disabled.
-     */
-    EnableDisableCommands(nsString action,
-                          nsCString[] enabledCommands,
-                          nsCString[] disabledCommands);
-
     prio(urgent) sync GetInputContext() returns (int32_t IMEEnabled,
                                                  int32_t IMEOpen,
                                                  intptr_t NativeIMEContext);
 
     prio(urgent) async SetInputContext(int32_t IMEEnabled,
                                        int32_t IMEOpen,
                                        nsString type,
                                        nsString inputmode,
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3221,25 +3221,16 @@ TabChild::SetWebBrowserChrome(nsIWebBrow
 }
 
 void
 TabChild::SendRequestFocus(bool aCanFocus)
 {
   PBrowserChild::SendRequestFocus(aCanFocus);
 }
 
-void
-TabChild::EnableDisableCommands(const nsAString& aAction,
-                                nsTArray<nsCString>& aEnabledCommands,
-                                nsTArray<nsCString>& aDisabledCommands)
-{
-  PBrowserChild::SendEnableDisableCommands(PromiseFlatString(aAction),
-                                           aEnabledCommands, aDisabledCommands);
-}
-
 bool
 TabChild::DoSendBlockingMessage(JSContext* aCx,
                                 const nsAString& aMessage,
                                 const StructuredCloneData& aData,
                                 JS::Handle<JSObject *> aCpows,
                                 nsIPrincipal* aPrincipal,
                                 InfallibleTArray<nsString>* aJSONRetVal,
                                 bool aIsSync)
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -42,17 +42,16 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadInfo.h"
 #include "nsIPromptFactory.h"
 #include "nsIURI.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIWindowCreator2.h"
 #include "nsIXULBrowserWindow.h"
 #include "nsIXULWindow.h"
-#include "nsIRemoteBrowser.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
 #include "nsOpenURIInFrameParams.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowWatcher.h"
 #include "nsPresShell.h"
 #include "nsPrintfCString.h"
@@ -1463,47 +1462,16 @@ TabParent::RecvRequestFocus(const bool& 
   if (aCanRaise)
     flags |= nsIFocusManager::FLAG_RAISE;
 
   nsCOMPtr<nsIDOMElement> node = do_QueryInterface(mFrameElement);
   fm->SetFocus(node, flags);
   return true;
 }
 
-bool
-TabParent::RecvEnableDisableCommands(const nsString& aAction,
-                                     const nsTArray<nsCString>& aEnabledCommands,
-                                     const nsTArray<nsCString>& aDisabledCommands)
-{
-  nsCOMPtr<nsIRemoteBrowser> remoteBrowser = do_QueryInterface(mFrameElement);
-  if (remoteBrowser) {
-    nsAutoArrayPtr<const char*> enabledCommands, disabledCommands;
-
-    if (aEnabledCommands.Length()) {
-      enabledCommands = new const char* [aEnabledCommands.Length()];
-      for (uint32_t c = 0; c < aEnabledCommands.Length(); c++) {
-        enabledCommands[c] = aEnabledCommands[c].get();
-      }
-    }
-
-    if (aDisabledCommands.Length()) {
-      disabledCommands = new const char* [aDisabledCommands.Length()];
-      for (uint32_t c = 0; c < aDisabledCommands.Length(); c++) {
-        disabledCommands[c] = aDisabledCommands[c].get();
-      }
-    }
-
-    remoteBrowser->EnableDisableCommands(aAction,
-                                         aEnabledCommands.Length(), enabledCommands,
-                                         aDisabledCommands.Length(), disabledCommands);
-  }
-
-  return true;
-}
-
 nsIntPoint
 TabParent::GetChildProcessOffset()
 {
   // The "toplevel widget" in child processes is always at position
   // 0,0.  Map the event coordinates to match that.
 
   nsIntPoint offset(0, 0);
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -186,19 +186,16 @@ public:
     virtual bool RecvSetInputContext(const int32_t& aIMEEnabled,
                                      const int32_t& aIMEOpen,
                                      const nsString& aType,
                                      const nsString& aInputmode,
                                      const nsString& aActionHint,
                                      const int32_t& aCause,
                                      const int32_t& aFocusChange) MOZ_OVERRIDE;
     virtual bool RecvRequestFocus(const bool& aCanRaise) MOZ_OVERRIDE;
-    virtual bool RecvEnableDisableCommands(const nsString& aAction,
-                                           const nsTArray<nsCString>& aEnabledCommands,
-                                           const nsTArray<nsCString>& aDisabledCommands) MOZ_OVERRIDE;
     virtual bool RecvSetCursor(const uint32_t& aValue, const bool& aForce) MOZ_OVERRIDE;
     virtual bool RecvSetBackgroundColor(const nscolor& aValue) MOZ_OVERRIDE;
     virtual bool RecvSetStatus(const uint32_t& aType, const nsString& aStatus) MOZ_OVERRIDE;
     virtual bool RecvIsParentWindowMainWidgetVisible(bool* aIsVisible);
     virtual bool RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip);
     virtual bool RecvHideTooltip();
     virtual bool RecvGetDPI(float* aValue) MOZ_OVERRIDE;
     virtual bool RecvGetDefaultScale(double* aValue) MOZ_OVERRIDE;
--- a/dom/media/MediaDataDecodedListener.h
+++ b/dom/media/MediaDataDecodedListener.h
@@ -15,18 +15,16 @@ namespace mozilla {
 class MediaDecoderStateMachine;
 class MediaData;
 
 // A RequestSampleCallback implementation that forwards samples onto the
 // MediaDecoderStateMachine via tasks that run on the supplied task queue.
 template<class Target>
 class MediaDataDecodedListener : public RequestSampleCallback {
 public:
-  using RequestSampleCallback::NotDecodedReason;
-
   MediaDataDecodedListener(Target* aTarget,
                            MediaTaskQueue* aTaskQueue)
     : mMonitor("MediaDataDecodedListener")
     , mTaskQueue(aTaskQueue)
     , mTarget(aTarget)
   {
     MOZ_ASSERT(aTarget);
     MOZ_ASSERT(aTaskQueue);
@@ -47,17 +45,18 @@ public:
     if (!mTarget || !mTaskQueue) {
       // We've been shutdown, abort.
       return;
     }
     RefPtr<nsIRunnable> task(new DeliverVideoTask(aSample, mTarget));
     mTaskQueue->Dispatch(task);
   }
 
-  virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) MOZ_OVERRIDE {
+  virtual void OnNotDecoded(MediaData::Type aType,
+                            MediaDecoderReader::NotDecodedReason aReason) MOZ_OVERRIDE {
     MonitorAutoLock lock(mMonitor);
     if (!mTarget || !mTaskQueue) {
       // We've been shutdown, abort.
       return;
     }
     RefPtr<nsIRunnable> task(new DeliverNotDecodedTask(aType, aReason, mTarget));
     mTaskQueue->Dispatch(task);
   }
@@ -128,17 +127,17 @@ private:
   private:
     nsRefPtr<VideoData> mSample;
     RefPtr<Target> mTarget;
   };
 
   class DeliverNotDecodedTask : public nsRunnable {
   public:
     DeliverNotDecodedTask(MediaData::Type aType,
-                          RequestSampleCallback::NotDecodedReason aReason,
+                          MediaDecoderReader::NotDecodedReason aReason,
                           Target* aTarget)
       : mType(aType)
       , mReason(aReason)
       , mTarget(aTarget)
     {
       MOZ_COUNT_CTOR(DeliverNotDecodedTask);
     }
   protected:
@@ -148,17 +147,17 @@ private:
     }
   public:
     NS_METHOD Run() {
       mTarget->OnNotDecoded(mType, mReason);
       return NS_OK;
     }
   private:
     MediaData::Type mType;
-    RequestSampleCallback::NotDecodedReason mReason;
+    MediaDecoderReader::NotDecodedReason mReason;
     RefPtr<Target> mTarget;
   };
 
   Monitor mMonitor;
   RefPtr<MediaTaskQueue> mTaskQueue;
   RefPtr<Target> mTarget;
 };
 
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -456,17 +456,16 @@ MediaDecoder::MediaDecoder() :
   MOZ_COUNT_CTOR(MediaDecoder);
   MOZ_ASSERT(NS_IsMainThread());
   MediaMemoryTracker::AddMediaDecoder(this);
 #ifdef PR_LOGGING
   if (!gMediaDecoderLog) {
     gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
   }
 #endif
-
   mAudioChannel = AudioChannelService::GetDefaultAudioChannel();
 }
 
 bool MediaDecoder::Init(MediaDecoderOwner* aOwner)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mOwner = aOwner;
   mVideoFrameContainer = aOwner->GetVideoFrameContainer();
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -22,16 +22,26 @@ namespace mozilla {
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gMediaDecoderLog;
 #define DECODER_LOG(x, ...) \
   PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("Decoder=%p " x, mDecoder, ##__VA_ARGS__))
 #else
 #define DECODER_LOG(x, ...)
 #endif
 
+PRLogModuleInfo* gMediaPromiseLog;
+
+void
+EnsureMediaPromiseLog()
+{
+  if (!gMediaPromiseLog) {
+    gMediaPromiseLog = PR_NewLogModule("MediaPromise");
+  }
+}
+
 class VideoQueueMemoryFunctor : public nsDequeFunctor {
 public:
   VideoQueueMemoryFunctor() : mSize(0) {}
 
   MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
 
   virtual void* operator()(void* aObject) {
     const VideoData* v = static_cast<const VideoData*>(aObject);
@@ -64,16 +74,17 @@ MediaDecoderReader::MediaDecoderReader(A
   , mIgnoreAudioOutputFormat(false)
   , mStartTime(-1)
   , mTaskQueueIsBorrowed(false)
   , mAudioDiscontinuity(false)
   , mVideoDiscontinuity(false)
   , mShutdown(false)
 {
   MOZ_COUNT_CTOR(MediaDecoderReader);
+  EnsureMediaPromiseLog();
 }
 
 MediaDecoderReader::~MediaDecoderReader()
 {
   MOZ_ASSERT(mShutdown);
   ResetDecode();
   MOZ_COUNT_DTOR(MediaDecoderReader);
 }
@@ -199,17 +210,17 @@ MediaDecoderReader::RequestVideoData(boo
   if (VideoQueue().GetSize() > 0) {
     nsRefPtr<VideoData> v = VideoQueue().PopFront();
     if (v && mVideoDiscontinuity) {
       v->mDiscontinuity = true;
       mVideoDiscontinuity = false;
     }
     GetCallback()->OnVideoDecoded(v);
   } else if (VideoQueue().IsFinished()) {
-    GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::END_OF_STREAM);
+    GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, END_OF_STREAM);
   }
 }
 
 void
 MediaDecoderReader::RequestAudioData()
 {
   while (AudioQueue().GetSize() == 0 &&
          !AudioQueue().IsFinished()) {
@@ -232,17 +243,17 @@ MediaDecoderReader::RequestAudioData()
     nsRefPtr<AudioData> a = AudioQueue().PopFront();
     if (mAudioDiscontinuity) {
       a->mDiscontinuity = true;
       mAudioDiscontinuity = false;
     }
     GetCallback()->OnAudioDecoded(a);
     return;
   } else if (AudioQueue().IsFinished()) {
-    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::END_OF_STREAM);
+    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, END_OF_STREAM);
     return;
   }
 }
 
 void
 MediaDecoderReader::SetCallback(RequestSampleCallback* aCallback)
 {
   mSampleDecodedCallback = aCallback;
@@ -302,22 +313,23 @@ AudioDecodeRendezvous::OnAudioDecoded(Au
   MonitorAutoLock mon(mMonitor);
   mSample = aSample;
   mStatus = NS_OK;
   mHaveResult = true;
   mon.NotifyAll();
 }
 
 void
-AudioDecodeRendezvous::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason)
+AudioDecodeRendezvous::OnNotDecoded(MediaData::Type aType,
+                                    MediaDecoderReader::NotDecodedReason aReason)
 {
   MOZ_ASSERT(aType == MediaData::AUDIO_DATA);
   MonitorAutoLock mon(mMonitor);
   mSample = nullptr;
-  mStatus = aReason == DECODE_ERROR ? NS_ERROR_FAILURE : NS_OK;
+  mStatus = aReason == MediaDecoderReader::DECODE_ERROR ? NS_ERROR_FAILURE : NS_OK;
   mHaveResult = true;
   mon.NotifyAll();
 }
 
 void
 AudioDecodeRendezvous::Reset()
 {
   MonitorAutoLock mon(mMonitor);
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -25,16 +25,23 @@ class SharedDecoderManager;
 // Encapsulates the decoding and reading of media data. Reading can either
 // synchronous and done on the calling "decode" thread, or asynchronous and
 // performed on a background thread, with the result being returned by
 // callback. Never hold the decoder monitor when calling into this class.
 // Unless otherwise specified, methods and fields of this class can only
 // be accessed on the decode task queue.
 class MediaDecoderReader {
 public:
+  enum NotDecodedReason {
+    END_OF_STREAM,
+    DECODE_ERROR,
+    WAITING_FOR_DATA,
+    CANCELED
+  };
+
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
 
   explicit MediaDecoderReader(AbstractMediaDecoder* aDecoder);
 
   // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
   // on failure.
   virtual nsresult Init(MediaDecoderReader* aCloneDonor) = 0;
 
@@ -285,58 +292,51 @@ private:
 // Interface that callers to MediaDecoderReader::Request{Audio,Video}Data()
 // must implement to receive the requested samples asynchronously.
 // This object is refcounted, and cycles must be broken by calling
 // BreakCycles() during shutdown.
 class RequestSampleCallback {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RequestSampleCallback)
 
-  enum NotDecodedReason {
-    END_OF_STREAM,
-    DECODE_ERROR,
-    WAITING_FOR_DATA,
-    CANCELED
-  };
-
   // Receives the result of a RequestAudioData() call.
   virtual void OnAudioDecoded(AudioData* aSample) = 0;
 
   // Receives the result of a RequestVideoData() call.
   virtual void OnVideoDecoded(VideoData* aSample) = 0;
 
   // Called when a RequestAudioData() or RequestVideoData() call can't be
   // fulfiled. The reason is passed as aReason.
-  virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) = 0;
+  virtual void OnNotDecoded(MediaData::Type aType,
+                            MediaDecoderReader::NotDecodedReason aReason) = 0;
 
   virtual void OnSeekCompleted(nsresult aResult) = 0;
 
   // Called during shutdown to break any reference cycles.
   virtual void BreakCycles() = 0;
 
 protected:
   virtual ~RequestSampleCallback() {}
 };
 
 // A RequestSampleCallback implementation that can be passed to the
 // MediaDecoderReader to block the thread requesting an audio sample until
 // the audio decode is complete. This is used to adapt the asynchronous
 // model of the MediaDecoderReader to a synchronous model.
 class AudioDecodeRendezvous : public RequestSampleCallback {
 public:
-  using RequestSampleCallback::NotDecodedReason;
-
   AudioDecodeRendezvous();
   ~AudioDecodeRendezvous();
 
   // RequestSampleCallback implementation. Called when decode is complete.
   // Note: aSample is null at end of stream.
   virtual void OnAudioDecoded(AudioData* aSample) MOZ_OVERRIDE;
   virtual void OnVideoDecoded(VideoData* aSample) MOZ_OVERRIDE {}
-  virtual void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) MOZ_OVERRIDE;
+  virtual void OnNotDecoded(MediaData::Type aType,
+                            MediaDecoderReader::NotDecodedReason aReason) MOZ_OVERRIDE;
   virtual void OnSeekCompleted(nsresult aResult) MOZ_OVERRIDE {};
   virtual void BreakCycles() MOZ_OVERRIDE {};
   void Reset();
 
   // Returns failure on error, or NS_OK.
   // If *aSample is null, EOS has been reached.
   nsresult Await(nsRefPtr<AudioData>& aSample);
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -800,56 +800,56 @@ MediaDecoderStateMachine::Push(VideoData
     UpdateReadyState();
     DispatchDecodeTasksIfNeeded();
     mDecoder->GetReentrantMonitor().NotifyAll();
   }
 }
 
 void
 MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
-                                       RequestSampleCallback::NotDecodedReason aReason)
+                                       MediaDecoderReader::NotDecodedReason aReason)
 {
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   SAMPLE_LOG("OnNotDecoded (aType=%u, aReason=%u)", aType, aReason);
   bool isAudio = aType == MediaData::AUDIO_DATA;
   MOZ_ASSERT_IF(!isAudio, aType == MediaData::VIDEO_DATA);
 
   // This callback means that the pending request is dead.
   if (isAudio) {
     mAudioRequestPending = false;
   } else {
     mVideoRequestPending = false;
   }
 
   // If this is a decode error, delegate to the generic error path.
-  if (aReason == RequestSampleCallback::DECODE_ERROR) {
+  if (aReason == MediaDecoderReader::DECODE_ERROR) {
     DecodeError();
     return;
   }
 
   // If the decoder is waiting for data, we need to make sure that the requests
   // are cleared, which happened above. Additionally, if we're out of decoded
   // samples, we need to switch to buffering mode.
-  if (aReason == RequestSampleCallback::WAITING_FOR_DATA) {
+  if (aReason == MediaDecoderReader::WAITING_FOR_DATA) {
     bool outOfSamples = isAudio ? !AudioQueue().GetSize() : !VideoQueue().GetSize();
     if (outOfSamples) {
       StartBuffering();
     }
 
     return;
   }
 
-  if (aReason == RequestSampleCallback::CANCELED) {
+  if (aReason == MediaDecoderReader::CANCELED) {
     DispatchDecodeTasksIfNeeded();
     return;
   }
 
   // This is an EOS. Finish off the queue, and then handle things based on our
   // state.
-  MOZ_ASSERT(aReason == RequestSampleCallback::END_OF_STREAM);
+  MOZ_ASSERT(aReason == MediaDecoderReader::END_OF_STREAM);
   if (!isAudio && mState == DECODER_STATE_SEEKING &&
       mCurrentSeekTarget.IsValid() && mFirstVideoFrameAfterSeek) {
     // Null sample. Hit end of stream. If we have decoded a frame,
     // insert it into the queue so that we have something to display.
     // We make sure to do this before invoking VideoQueue().Finish()
     // below.
     VideoQueue().Push(mFirstVideoFrameAfterSeek);
     mFirstVideoFrameAfterSeek = nullptr;
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -368,17 +368,17 @@ public:
   // decoded we preroll, until playback starts. The first time playback starts
   // the state machine is free to return to prerolling normally. Note
   // "prerolling" in this context refers to when we decode and buffer decoded
   // samples in advance of when they're needed for playback.
   void SetMinimizePrerollUntilPlaybackStarts();
 
   void OnAudioDecoded(AudioData* aSample);
   void OnVideoDecoded(VideoData* aSample);
-  void OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason);
+  void OnNotDecoded(MediaData::Type aType, MediaDecoderReader::NotDecodedReason aReason);
   void OnSeekCompleted(nsresult aResult);
 
 private:
   void AcquireMonitorAndInvokeDecodeError();
 
 protected:
   virtual ~MediaDecoderStateMachine();
 
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaPromise.cpp
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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/. */
+
+#include "MediaPromise.h"
+#include "MediaTaskQueue.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla {
+namespace detail {
+
+nsresult
+DispatchMediaPromiseRunnable(MediaTaskQueue* aTaskQueue, nsIRunnable* aRunnable)
+{
+  return aTaskQueue->ForceDispatch(aRunnable);
+}
+
+nsresult
+DispatchMediaPromiseRunnable(nsIEventTarget* aEventTarget, nsIRunnable* aRunnable)
+{
+  return aEventTarget->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
+}
+
+}
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaPromise.h
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#if !defined(MediaPromise_h_)
+#define MediaPromise_h_
+
+#include "prlog.h"
+
+#include "nsTArray.h"
+#include "nsThreadUtils.h"
+
+#include "mozilla/DebugOnly.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/Monitor.h"
+
+/* Polyfill __func__ on MSVC for consumers to pass to the MediaPromise API. */
+#ifdef _MSC_VER
+#define __func__ __FUNCTION__
+#endif
+
+class nsIEventTarget;
+namespace mozilla {
+
+extern PRLogModuleInfo* gMediaPromiseLog;
+void EnsureMediaPromiseLog();
+
+#define PROMISE_LOG(x, ...) \
+  MOZ_ASSERT(gMediaPromiseLog); \
+  PR_LOG(gMediaPromiseLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
+
+class MediaTaskQueue;
+namespace detail {
+
+nsresult DispatchMediaPromiseRunnable(MediaTaskQueue* aQueue, nsIRunnable* aRunnable);
+nsresult DispatchMediaPromiseRunnable(nsIEventTarget* aTarget, nsIRunnable* aRunnable);
+
+} // namespace detail
+
+/*
+ * A promise manages an asynchronous request that may or may not be able to be
+ * fulfilled immediately. When an API returns a promise, the consumer may attach
+ * callbacks to be invoked (asynchronously, on a specified thread) when the
+ * request is either completed (resolved) or cannot be completed (rejected).
+ *
+ * By default, resolve and reject callbacks are always invoked on the same thread
+ * where Then() was invoked.
+ */
+template<typename T> class MediaPromiseHolder;
+template<typename ResolveValueT, typename RejectValueT>
+class MediaPromise
+{
+public:
+  typedef ResolveValueT ResolveValueType;
+  typedef RejectValueT RejectValueType;
+
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaPromise)
+  MediaPromise(const char* aCreationSite)
+    : mCreationSite(aCreationSite)
+    , mMutex("MediaPromise Mutex")
+  {
+    MOZ_COUNT_CTOR(MediaPromise);
+    PROMISE_LOG("%s creating MediaPromise (%p)", mCreationSite, this);
+  }
+
+protected:
+
+  /*
+   * A ThenValue tracks a single consumer waiting on the promise. When a consumer
+   * invokes promise->Then(...), a ThenValue is created. Once the Promise is
+   * resolved or rejected, a {Resolve,Reject}Runnable is dispatched, which
+   * invokes the resolve/reject method and then deletes the ThenValue.
+   */
+  class ThenValueBase
+  {
+  public:
+    class ResolveRunnable : public nsRunnable
+    {
+    public:
+      ResolveRunnable(ThenValueBase* aThenValue, ResolveValueType aResolveValue)
+        : mThenValue(aThenValue)
+        , mResolveValue(aResolveValue)
+      {
+        MOZ_COUNT_CTOR(ResolveRunnable);
+      }
+
+      ~ResolveRunnable()
+      {
+        MOZ_COUNT_DTOR(ResolveRunnable);
+        MOZ_ASSERT(!mThenValue);
+      }
+
+      NS_IMETHODIMP Run()
+      {
+        PROMISE_LOG("ResolveRunnable::Run() [this=%p]", this);
+        mThenValue->DoResolve(mResolveValue);
+
+        delete mThenValue;
+        mThenValue = nullptr;
+        return NS_OK;
+      }
+
+    private:
+      ThenValueBase* mThenValue;
+      ResolveValueType mResolveValue;
+    };
+
+    class RejectRunnable : public nsRunnable
+    {
+    public:
+      RejectRunnable(ThenValueBase* aThenValue, RejectValueType aRejectValue)
+        : mThenValue(aThenValue)
+        , mRejectValue(aRejectValue)
+      {
+        MOZ_COUNT_CTOR(RejectRunnable);
+      }
+
+      ~RejectRunnable()
+      {
+        MOZ_COUNT_DTOR(RejectRunnable);
+        MOZ_ASSERT(!mThenValue);
+      }
+
+      NS_IMETHODIMP Run()
+      {
+        PROMISE_LOG("RejectRunnable::Run() [this=%p]", this);
+        mThenValue->DoReject(mRejectValue);
+
+        delete mThenValue;
+        mThenValue = nullptr;
+        return NS_OK;
+      }
+
+    private:
+      ThenValueBase* mThenValue;
+      RejectValueType mRejectValue;
+    };
+
+    ThenValueBase(const char* aCallSite) : mCallSite(aCallSite)
+    {
+      MOZ_COUNT_CTOR(ThenValueBase);
+    }
+
+    virtual void Dispatch(MediaPromise *aPromise) = 0;
+
+  protected:
+    // This may only be deleted by {Resolve,Reject}Runnable::Run.
+    virtual ~ThenValueBase() { MOZ_COUNT_DTOR(ThenValueBase); }
+
+    virtual void DoResolve(ResolveValueType aResolveValue) = 0;
+    virtual void DoReject(RejectValueType aRejectValue) = 0;
+
+    const char* mCallSite;
+  };
+
+  template<typename TargetType, typename ThisType,
+           typename ResolveMethodType, typename RejectMethodType>
+  class ThenValue : public ThenValueBase
+  {
+  public:
+    ThenValue(TargetType* aResponseTarget, ThisType* aThisVal,
+              ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod,
+              const char* aCallSite)
+      : ThenValueBase(aCallSite)
+      , mResponseTarget(aResponseTarget)
+      , mThisVal(aThisVal)
+      , mResolveMethod(aResolveMethod)
+      , mRejectMethod(aRejectMethod) {}
+
+    void Dispatch(MediaPromise *aPromise) MOZ_OVERRIDE
+    {
+      aPromise->mMutex.AssertCurrentThreadOwns();
+      MOZ_ASSERT(!aPromise->IsPending());
+      bool resolved = aPromise->mResolveValue.isSome();
+      nsRefPtr<nsRunnable> runnable =
+        resolved ? static_cast<nsRunnable*>(new (typename ThenValueBase::ResolveRunnable)(this, aPromise->mResolveValue.ref()))
+                 : static_cast<nsRunnable*>(new (typename ThenValueBase::RejectRunnable)(this, aPromise->mRejectValue.ref()));
+      PROMISE_LOG("%s Then() call made from %s [Runnable=%p, Promise=%p, ThenValue=%p]",
+                  resolved ? "Resolving" : "Rejecting", ThenValueBase::mCallSite,
+                  runnable.get(), aPromise, this);
+      DebugOnly<nsresult> rv = detail::DispatchMediaPromiseRunnable(mResponseTarget, runnable);
+      MOZ_ASSERT(NS_SUCCEEDED(rv));
+    }
+
+  protected:
+    virtual void DoResolve(ResolveValueType aResolveValue)
+    {
+      ((*mThisVal).*mResolveMethod)(aResolveValue);
+    }
+
+    virtual void DoReject(RejectValueType aRejectValue)
+    {
+      ((*mThisVal).*mRejectMethod)(aRejectValue);
+    }
+
+    virtual ~ThenValue() {}
+
+  private:
+    nsRefPtr<TargetType> mResponseTarget;
+    nsRefPtr<ThisType> mThisVal;
+    ResolveMethodType mResolveMethod;
+    RejectMethodType mRejectMethod;
+  };
+public:
+
+  template<typename TargetType, typename ThisType,
+           typename ResolveMethodType, typename RejectMethodType>
+  void Then(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal,
+            ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
+  {
+    MutexAutoLock lock(mMutex);
+    ThenValueBase* thenValue = new ThenValue<TargetType, ThisType, ResolveMethodType,
+                                             RejectMethodType>(aResponseTarget, aThisVal,
+                                                               aResolveMethod, aRejectMethod,
+                                                               aCallSite);
+    PROMISE_LOG("%s invoking Then() [this=%p, thenValue=%p, aThisVal=%p, isPending=%d]",
+                aCallSite, this, thenValue, aThisVal, (int) IsPending());
+    if (!IsPending()) {
+      thenValue->Dispatch(this);
+    } else {
+      mThenValues.AppendElement(thenValue);
+    }
+  }
+
+  void ChainTo(already_AddRefed<MediaPromise> aChainedPromise, const char* aCallSite)
+  {
+    MutexAutoLock lock(mMutex);
+    nsRefPtr<MediaPromise> chainedPromise = aChainedPromise;
+    PROMISE_LOG("%s invoking Chain() [this=%p, chainedPromise=%p, isPending=%d]",
+                aCallSite, this, chainedPromise.get(), (int) IsPending());
+    if (!IsPending()) {
+      ForwardTo(chainedPromise);
+    } else {
+      mChainedPromises.AppendElement(chainedPromise);
+    }
+  }
+
+  void Resolve(ResolveValueType aResolveValue, const char* aResolveSite)
+  {
+    MutexAutoLock lock(mMutex);
+    MOZ_ASSERT(IsPending());
+    PROMISE_LOG("%s resolving MediaPromise (%p created at %s)", aResolveSite, this, mCreationSite);
+    mResolveValue.emplace(aResolveValue);
+    DispatchAll();
+  }
+
+  void Reject(RejectValueType aRejectValue, const char* aRejectSite)
+  {
+    MutexAutoLock lock(mMutex);
+    MOZ_ASSERT(IsPending());
+    PROMISE_LOG("%s rejecting MediaPromise (%p created at %s)", aRejectSite, this, mCreationSite);
+    mRejectValue.emplace(aRejectValue);
+    DispatchAll();
+  }
+
+protected:
+  bool IsPending() { return mResolveValue.isNothing() && mRejectValue.isNothing(); }
+  void DispatchAll()
+  {
+    mMutex.AssertCurrentThreadOwns();
+    for (size_t i = 0; i < mThenValues.Length(); ++i)
+      mThenValues[i]->Dispatch(this);
+    mThenValues.Clear();
+
+    for (size_t i = 0; i < mChainedPromises.Length(); ++i) {
+      ForwardTo(mChainedPromises[i]);
+    }
+    mChainedPromises.Clear();
+  }
+
+  void ForwardTo(MediaPromise* aOther)
+  {
+    MOZ_ASSERT(!IsPending());
+    if (mResolveValue.isSome()) {
+      aOther->Resolve(mResolveValue.ref(), "<chained promise>");
+    } else {
+      aOther->Reject(mRejectValue.ref(), "<chained promise>");
+    }
+  }
+
+  ~MediaPromise()
+  {
+    MOZ_COUNT_DTOR(MediaPromise);
+    PROMISE_LOG("MediaPromise::~MediaPromise [this=%p]", this);
+    MOZ_ASSERT(!IsPending());
+    MOZ_ASSERT(mThenValues.IsEmpty());
+    MOZ_ASSERT(mChainedPromises.IsEmpty());
+  };
+
+  const char* mCreationSite; // For logging
+  Mutex mMutex;
+  Maybe<ResolveValueType> mResolveValue;
+  Maybe<RejectValueType> mRejectValue;
+  nsTArray<ThenValueBase*> mThenValues;
+  nsTArray<nsRefPtr<MediaPromise>> mChainedPromises;
+};
+
+/*
+ * Class to encapsulate a promise for a particular role. Use this as the member
+ * variable for a class whose method returns a promise.
+ */
+template<typename PromiseType>
+class MediaPromiseHolder
+{
+public:
+  MediaPromiseHolder()
+    : mMonitor(nullptr) {}
+
+  ~MediaPromiseHolder() { MOZ_ASSERT(!mPromise); }
+
+  already_AddRefed<PromiseType> Ensure(const char* aMethodName) {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+    if (!mPromise) {
+      mPromise = new PromiseType(aMethodName);
+    }
+    nsRefPtr<PromiseType> p = mPromise;
+    return p.forget();
+  }
+
+  // Provide a Monitor that should always be held when accessing this instance.
+  void SetMonitor(Monitor* aMonitor) { mMonitor = aMonitor; }
+
+  bool IsEmpty()
+  {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+    return !mPromise;
+  }
+
+  already_AddRefed<PromiseType> Steal()
+  {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+
+    nsRefPtr<PromiseType> p = mPromise;
+    mPromise = nullptr;
+    return p.forget();
+  }
+
+  void Resolve(typename PromiseType::ResolveValueType aResolveValue,
+               const char* aMethodName)
+  {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+    MOZ_ASSERT(mPromise);
+    mPromise->Resolve(aResolveValue, aMethodName);
+    mPromise = nullptr;
+  }
+
+  void ResolveIfExists(typename PromiseType::ResolveValueType aResolveValue,
+                       const char* aMethodName)
+  {
+    if (!IsEmpty()) {
+      Resolve(aResolveValue, aMethodName);
+    }
+  }
+
+  void Reject(typename PromiseType::RejectValueType aRejectValue,
+              const char* aMethodName)
+  {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+    MOZ_ASSERT(mPromise);
+    mPromise->Reject(aRejectValue, aMethodName);
+    mPromise = nullptr;
+  }
+
+  void RejectIfExists(typename PromiseType::RejectValueType aRejectValue,
+                      const char* aMethodName)
+  {
+    if (!IsEmpty()) {
+      Reject(aRejectValue, aMethodName);
+    }
+  }
+
+private:
+  Monitor* mMonitor;
+  nsRefPtr<PromiseType> mPromise;
+};
+
+#undef PROMISE_LOG
+
+} // namespace mozilla
+
+#endif
--- a/dom/media/MediaTaskQueue.cpp
+++ b/dom/media/MediaTaskQueue.cpp
@@ -30,27 +30,34 @@ MediaTaskQueue::~MediaTaskQueue()
 nsresult
 MediaTaskQueue::Dispatch(TemporaryRef<nsIRunnable> aRunnable)
 {
   MonitorAutoLock mon(mQueueMonitor);
   return DispatchLocked(aRunnable, AbortIfFlushing);
 }
 
 nsresult
+MediaTaskQueue::ForceDispatch(TemporaryRef<nsIRunnable> aRunnable)
+{
+  MonitorAutoLock mon(mQueueMonitor);
+  return DispatchLocked(aRunnable, Forced);
+}
+
+nsresult
 MediaTaskQueue::DispatchLocked(TemporaryRef<nsIRunnable> aRunnable,
                                DispatchMode aMode)
 {
   mQueueMonitor.AssertCurrentThreadOwns();
   if (mIsFlushing && aMode == AbortIfFlushing) {
     return NS_ERROR_ABORT;
   }
   if (mIsShutdown) {
     return NS_ERROR_FAILURE;
   }
-  mTasks.push(aRunnable);
+  mTasks.push(TaskQueueEntry(aRunnable, aMode == Forced));
   if (mIsRunning) {
     return NS_OK;
   }
   RefPtr<nsIRunnable> runner(new Runner(this));
   nsresult rv = mPool->Dispatch(runner, NS_DISPATCH_NORMAL);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch runnable to run MediaTaskQueue");
     return rv;
@@ -135,34 +142,47 @@ MediaTaskQueue::BeginShutdown()
   mon.NotifyAll();
 }
 
 nsresult
 MediaTaskQueue::FlushAndDispatch(TemporaryRef<nsIRunnable> aRunnable)
 {
   MonitorAutoLock mon(mQueueMonitor);
   AutoSetFlushing autoFlush(this);
-  while (!mTasks.empty()) {
-    mTasks.pop();
-  }
+  FlushLocked();
   nsresult rv = DispatchLocked(aRunnable, IgnoreFlushing);
   NS_ENSURE_SUCCESS(rv, rv);
   AwaitIdleLocked();
   return NS_OK;
 }
 
 void
 MediaTaskQueue::Flush()
 {
   MonitorAutoLock mon(mQueueMonitor);
   AutoSetFlushing autoFlush(this);
-  while (!mTasks.empty()) {
+  FlushLocked();
+  AwaitIdleLocked();
+}
+
+void
+MediaTaskQueue::FlushLocked()
+{
+  mQueueMonitor.AssertCurrentThreadOwns();
+  MOZ_ASSERT(mIsFlushing);
+
+  // Clear the tasks, but preserve those with mForceDispatch by re-appending
+  // them to the queue.
+  size_t numTasks = mTasks.size();
+  for (size_t i = 0; i < numTasks; ++i) {
+    if (mTasks.front().mForceDispatch) {
+      mTasks.push(mTasks.front());
+    }
     mTasks.pop();
   }
-  AwaitIdleLocked();
 }
 
 bool
 MediaTaskQueue::IsEmpty()
 {
   MonitorAutoLock mon(mQueueMonitor);
   return mTasks.empty();
 }
@@ -186,17 +206,17 @@ MediaTaskQueue::Runner::Run()
     MonitorAutoLock mon(mQueue->mQueueMonitor);
     MOZ_ASSERT(mQueue->mIsRunning);
     mQueue->mRunningThread = NS_GetCurrentThread();
     if (mQueue->mTasks.size() == 0) {
       mQueue->mIsRunning = false;
       mon.NotifyAll();
       return NS_OK;
     }
-    event = mQueue->mTasks.front();
+    event = mQueue->mTasks.front().mRunnable;
     mQueue->mTasks.pop();
   }
   MOZ_ASSERT(event);
 
   // Note that dropping the queue monitor before running the task, and
   // taking the monitor again after the task has run ensures we have memory
   // fences enforced. This means that if the object we're calling wasn't
   // designed to be threadsafe, it will be, provided we're only calling it
--- a/dom/media/MediaTaskQueue.h
+++ b/dom/media/MediaTaskQueue.h
@@ -29,16 +29,20 @@ class MediaTaskQueue MOZ_FINAL {
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTaskQueue)
 
   explicit MediaTaskQueue(TemporaryRef<SharedThreadPool> aPool);
 
   nsresult Dispatch(TemporaryRef<nsIRunnable> aRunnable);
 
+  // This should only be used for things that absolutely can't afford to be
+  // flushed. Normal operations should use Dispatch.
+  nsresult ForceDispatch(TemporaryRef<nsIRunnable> aRunnable);
+
   nsresult SyncDispatch(TemporaryRef<nsIRunnable> aRunnable);
 
   nsresult FlushAndDispatch(TemporaryRef<nsIRunnable> aRunnable);
 
   // Removes all pending tasks from the task queue, and blocks until
   // the currently running task (if any) finishes.
   void Flush();
 
@@ -63,28 +67,37 @@ public:
 
 private:
 
   // Blocks until all task finish executing. Called internally by methods
   // that need to wait until the task queue is idle.
   // mQueueMonitor must be held.
   void AwaitIdleLocked();
 
-  enum DispatchMode { AbortIfFlushing, IgnoreFlushing };
+  enum DispatchMode { AbortIfFlushing, IgnoreFlushing, Forced };
 
   nsresult DispatchLocked(TemporaryRef<nsIRunnable> aRunnable,
                           DispatchMode aMode);
+  void FlushLocked();
 
   RefPtr<SharedThreadPool> mPool;
 
   // Monitor that protects the queue and mIsRunning;
   Monitor mQueueMonitor;
 
+  struct TaskQueueEntry {
+    RefPtr<nsIRunnable> mRunnable;
+    bool mForceDispatch;
+
+    TaskQueueEntry(TemporaryRef<nsIRunnable> aRunnable, bool aForceDispatch = false)
+      : mRunnable(aRunnable), mForceDispatch(aForceDispatch) {}
+  };
+
   // Queue of tasks to run.
-  std::queue<RefPtr<nsIRunnable>> mTasks;
+  std::queue<TaskQueueEntry> mTasks;
 
   // The thread currently running the task queue. We store a reference
   // to this so that IsCurrentThreadIn() can tell if the current thread
   // is the thread currently running in the task queue.
   RefPtr<nsIThread> mRunningThread;
 
   // True if we've dispatched an event to the pool to execute events from
   // the queue.
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -20,17 +20,17 @@ const PC_ICE_CONTRACT = "@mozilla.org/do
 const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
 const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
 const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
 const PC_IDENTITY_CONTRACT = "@mozilla.org/dom/rtcidentityassertion;1";
 const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
 const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
 const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
 
-const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
+const PC_CID = Components.ID("{bdc2e533-b308-4708-ac8e-a8bfade6d851}");
 const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
 const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
 const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
 const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
 const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
 const PC_IDENTITY_CID = Components.ID("{1abc7499-3c54-43e0-bd60-686e2703f072}");
 const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
 const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
@@ -844,17 +844,17 @@ RTCPeerConnection.prototype = {
   },
 
   _addIceCandidate: function(cand, onSuccess, onError) {
     this._onAddIceCandidateSuccess = onSuccess || null;
     this._onAddIceCandidateError = onError || null;
 
     this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
                                (cand.sdpMLineIndex === null) ? 0 :
-                                 cand.sdpMLineIndex + 1);
+                                 cand.sdpMLineIndex);
   },
 
   addStream: function(stream) {
     stream.getTracks().forEach(track => this.addTrack(track, stream));
   },
 
   removeStream: function(stream) {
      // Bug 844295: Not implementing this functionality.
@@ -1117,17 +1117,17 @@ PeerConnectionObserver.prototype = {
     this._dompc = dompc._innerObject;
   },
 
   newError: function(code, message) {
     // These strings must match those defined in the WebRTC spec.
     const reasonName = [
       "",
       "InternalError",
-      "InternalError",
+      "InvalidCandidateError",
       "InvalidParameter",
       "InvalidStateError",
       "InvalidSessionDescriptionError",
       "IncompatibleSessionDescriptionError",
       "InternalError",
       "IncompatibleMediaStreamTrackError",
       "InternalError"
     ];
@@ -1216,17 +1216,17 @@ PeerConnectionObserver.prototype = {
   onIceCandidate: function(level, mid, candidate) {
     if (candidate == "") {
       this.foundIceCandidate(null);
     } else {
       this.foundIceCandidate(new this._dompc._win.mozRTCIceCandidate(
           {
               candidate: candidate,
               sdpMid: mid,
-              sdpMLineIndex: level - 1
+              sdpMLineIndex: level
           }
       ));
     }
   },
 
 
   // This method is primarily responsible for updating iceConnectionState.
   // This state is defined in the WebRTC specification as follows:
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -1,20 +1,20 @@
-component {00e0e20d-1494-4776-8e0e-0f0acbea3c79} PeerConnection.js
+component {bdc2e533-b308-4708-ac8e-a8bfade6d851} PeerConnection.js
 component {d1748d4c-7f6a-4dc5-add6-d55b7678537e} PeerConnection.js
 component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
 component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
 component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
 component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
 component {1abc7499-3c54-43e0-bd60-686e2703f072} PeerConnection.js
 component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
 component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
 component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
 
-contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
+contract @mozilla.org/dom/peerconnection;1 {bdc2e533-b308-4708-ac8e-a8bfade6d851}
 contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
 contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
 contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
 contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
 contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
 contract @mozilla.org/dom/rtcidentityassertion;1 {1abc7499-3c54-43e0-bd60-686e2703f072}
 contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}
 contract @mozilla.org/dom/rtpsender;1 {4fff5d46-d827-4cd4-a970-8fd53977440e}
--- a/dom/media/android/moz.build
+++ b/dom/media/android/moz.build
@@ -20,8 +20,10 @@ UNIFIED_SOURCES += [
 ]
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/html',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/dom/media/bridge/IPeerConnection.idl
+++ b/dom/media/bridge/IPeerConnection.idl
@@ -54,16 +54,17 @@ interface IPeerConnection : nsISupports
 
   /* for 'type' in DataChannelInit dictionary */
   const unsigned short kDataChannelReliable = 0;
   const unsigned short kDataChannelPartialReliableRexmit = 1;
   const unsigned short kDataChannelPartialReliableTimed = 2;
 
   /* Constants for 'name' in error callbacks */
   const unsigned long kNoError                          = 0; // Test driver only
+  const unsigned long kInvalidCandidate                 = 2;
   const unsigned long kInvalidMediastreamTrack          = 3;
   const unsigned long kInvalidState                     = 4;
   const unsigned long kInvalidSessionDescription        = 5;
   const unsigned long kIncompatibleSessionDescription   = 6;
   const unsigned long kIncompatibleMediaStreamTrack     = 8;
   const unsigned long kInternalError                    = 9;
   const unsigned long kMaxErrorType                     = 9; // Same as final error
 };
--- a/dom/media/bridge/MediaModule.cpp
+++ b/dom/media/bridge/MediaModule.cpp
@@ -16,27 +16,27 @@
 
 #include "stun_udp_socket_filter.h"
 
 NS_DEFINE_NAMED_CID(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CID)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStunUDPSocketFilterHandler)
 
 
-namespace sipcc
+namespace mozilla
 {
-// Factory defined in sipcc::, defines sipcc::PeerConnectionImplConstructor
+// Factory defined in mozilla::, defines mozilla::PeerConnectionImplConstructor
 NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
 }
 
 // Defines kPEERCONNECTION_CID
 NS_DEFINE_NAMED_CID(PEERCONNECTION_CID);
 
 static const mozilla::Module::CIDEntry kCIDs[] = {
-  { &kPEERCONNECTION_CID, false, nullptr, sipcc::PeerConnectionImplConstructor },
+  { &kPEERCONNECTION_CID, false, nullptr, mozilla::PeerConnectionImplConstructor },
   { &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID, false, nullptr, nsStunUDPSocketFilterHandlerConstructor },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kContracts[] = {
   { PEERCONNECTION_CONTRACTID, &kPEERCONNECTION_CID },
   { NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID, &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID },
   { nullptr }
--- a/dom/media/bridge/moz.build
+++ b/dom/media/bridge/moz.build
@@ -12,17 +12,17 @@ XPIDL_MODULE = 'peerconnection'
 
 SOURCES += [
     'MediaModule.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/ipc/chromium/src',
     '/media/mtransport',
-    '/media/webrtc/signaling/include',
+    '/media/mtransport',
+    '/media/webrtc/',
     '/media/webrtc/signaling/src/common/time_profiling',
     '/media/webrtc/signaling/src/media-conduit',
     '/media/webrtc/signaling/src/mediapipeline',
     '/media/webrtc/signaling/src/peerconnection',
-    '/media/webrtc/signaling/src/sipcc/include',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/dom/media/fmp4/MP4Reader.cpp
+++ b/dom/media/fmp4/MP4Reader.cpp
@@ -661,18 +661,17 @@ MP4Reader::ReturnOutput(MediaData* aData
   } else if (aTrack == kVideo) {
     GetCallback()->OnVideoDecoded(static_cast<VideoData*>(aData));
   }
 }
 
 void
 MP4Reader::ReturnEOS(TrackType aTrack)
 {
-  GetCallback()->OnNotDecoded(aTrack == kAudio ? MediaData::AUDIO_DATA : MediaData::VIDEO_DATA,
-                              RequestSampleCallback::END_OF_STREAM);
+  GetCallback()->OnNotDecoded(aTrack == kAudio ? MediaData::AUDIO_DATA : MediaData::VIDEO_DATA, END_OF_STREAM);
 }
 
 MP4Sample*
 MP4Reader::PopSample(TrackType aTrack)
 {
   switch (aTrack) {
     case kAudio:
       return mDemuxer->DemuxAudioSample();
@@ -748,18 +747,17 @@ MP4Reader::InputExhausted(TrackType aTra
 void
 MP4Reader::Error(TrackType aTrack)
 {
   DecoderData& data = GetDecoderData(aTrack);
   {
     MonitorAutoLock mon(data.mMonitor);
     data.mError = true;
   }
-  GetCallback()->OnNotDecoded(aTrack == kVideo ? MediaData::VIDEO_DATA : MediaData::AUDIO_DATA,
-                              RequestSampleCallback::DECODE_ERROR);
+  GetCallback()->OnNotDecoded(aTrack == kVideo ? MediaData::VIDEO_DATA : MediaData::AUDIO_DATA, DECODE_ERROR);
 }
 
 void
 MP4Reader::Flush(TrackType aTrack)
 {
   MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
   VLOG("Flush(%s) BEGIN", TrackTypeToStr(aTrack));
   DecoderData& data = GetDecoderData(aTrack);
@@ -779,18 +777,17 @@ MP4Reader::Flush(TrackType aTrack)
   {
     MonitorAutoLock mon(data.mMonitor);
     data.mIsFlushing = false;
     data.mOutput.Clear();
     data.mNumSamplesInput = 0;
     data.mNumSamplesOutput = 0;
     data.mInputExhausted = false;
     if (data.mOutputRequested) {
-      GetCallback()->OnNotDecoded(aTrack == kVideo ? MediaData::VIDEO_DATA : MediaData::AUDIO_DATA,
-                                  RequestSampleCallback::CANCELED);
+      GetCallback()->OnNotDecoded(aTrack == kVideo ? MediaData::VIDEO_DATA : MediaData::AUDIO_DATA, CANCELED);
     }
     data.mOutputRequested = false;
     data.mDiscontinuity = true;
   }
   if (aTrack == kVideo) {
     mQueuedVideoSample = nullptr;
   }
   VLOG("Flush(%s) END", TrackTypeToStr(aTrack));
@@ -805,18 +802,17 @@ MP4Reader::SkipVideoDemuxToNextKeyFrame(
 
   Flush(kVideo);
 
   // Loop until we reach the next keyframe after the threshold.
   while (true) {
     nsAutoPtr<MP4Sample> compressed(PopSample(kVideo));
     if (!compressed) {
       // EOS, or error. Let the state machine know.
-      GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA,
-                                  RequestSampleCallback::END_OF_STREAM);
+      GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, END_OF_STREAM);
       {
         MonitorAutoLock mon(mVideo.mMonitor);
         mVideo.mDemuxEOS = true;
       }
       return false;
     }
     parsed++;
     if (!compressed->is_sync_point ||
--- a/dom/media/gmp/rlz/moz.build
+++ b/dom/media/gmp/rlz/moz.build
@@ -13,9 +13,12 @@ USE_STATIC_LIBS = True
 
 UNIFIED_SOURCES += [
     'lib/string_utils.cc',
     'win/lib/machine_id_win.cc',
 ]
 
 LOCAL_INCLUDES += [
     '..',
-]
\ No newline at end of file
+]
+
+if CONFIG['GNU_CXX']:
+    FAIL_ON_WARNINGS = True
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -95,17 +95,17 @@ MediaSourceReader::IsWaitingMediaResourc
 }
 
 void
 MediaSourceReader::RequestAudioData()
 {
   MSE_DEBUGV("MediaSourceReader(%p)::RequestAudioData", this);
   if (!mAudioReader) {
     MSE_DEBUG("MediaSourceReader(%p)::RequestAudioData called with no audio reader", this);
-    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
+    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
     return;
   }
   mAudioIsSeeking = false;
   SwitchAudioReader(mLastAudioTime);
   mAudioReader->RequestAudioData();
 }
 
 void
@@ -134,17 +134,17 @@ MediaSourceReader::OnAudioDecoded(AudioD
 
 void
 MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold)
 {
   MSE_DEBUGV("MediaSourceReader(%p)::RequestVideoData(%d, %lld)",
              this, aSkipToNextKeyframe, aTimeThreshold);
   if (!mVideoReader) {
     MSE_DEBUG("MediaSourceReader(%p)::RequestVideoData called with no video reader", this);
-    GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::DECODE_ERROR);
+    GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, DECODE_ERROR);
     return;
   }
   if (aSkipToNextKeyframe) {
     mTimeThreshold = aTimeThreshold;
     mDropAudioBeforeThreshold = true;
     mDropVideoBeforeThreshold = true;
   }
   mVideoIsSeeking = false;
@@ -172,27 +172,26 @@ MediaSourceReader::OnVideoDecoded(VideoD
   // switching away from.
   if (!mVideoIsSeeking) {
     mLastVideoTime = aSample->mTime + aSample->mDuration;
   }
   GetCallback()->OnVideoDecoded(aSample);
 }
 
 void
-MediaSourceReader::OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason)
+MediaSourceReader::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason)
 {
   MSE_DEBUG("MediaSourceReader(%p)::OnNotDecoded aType=%u aReason=%u IsEnded: %d", this, aType, aReason, IsEnded());
-  if (aReason == RequestSampleCallback::DECODE_ERROR ||
-      aReason == RequestSampleCallback::CANCELED) {
+  if (aReason == DECODE_ERROR || aReason == CANCELED) {
     GetCallback()->OnNotDecoded(aType, aReason);
     return;
   }
   // End of stream. Force switching past this stream to another reader by
   // switching to the end of the buffered range.
-  MOZ_ASSERT(aReason == RequestSampleCallback::END_OF_STREAM);
+  MOZ_ASSERT(aReason == END_OF_STREAM);
   nsRefPtr<MediaDecoderReader> reader = aType == MediaData::AUDIO_DATA ?
                                           mAudioReader : mVideoReader;
 
   // Find the closest approximation to the end time for this stream.
   // mLast{Audio,Video}Time differs from the actual end time because of
   // Bug 1065207 - the duration of a WebM fragment is an estimate not the
   // actual duration. In the case of audio time an example of where they
   // differ would be the actual sample duration being small but the
@@ -223,23 +222,23 @@ MediaSourceReader::OnNotDecoded(MediaDat
   }
   if (aType == MediaData::VIDEO_DATA && SwitchVideoReader(*time + EOS_FUZZ_US)) {
     RequestVideoData(false, 0);
     return;
   }
 
   // If the entire MediaSource is done, generate an EndOfStream.
   if (IsEnded()) {
-    GetCallback()->OnNotDecoded(aType, RequestSampleCallback::END_OF_STREAM);
+    GetCallback()->OnNotDecoded(aType, END_OF_STREAM);
     return;
   }
 
   // We don't have the data the caller wants. Tell that we're waiting for JS to
   // give us more data.
-  GetCallback()->OnNotDecoded(aType, RequestSampleCallback::WAITING_FOR_DATA);
+  GetCallback()->OnNotDecoded(aType, WAITING_FOR_DATA);
 }
 
 void
 MediaSourceReader::Shutdown()
 {
   MediaDecoderReader::Shutdown();
   for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) {
     mTrackBuffers[i]->Shutdown();
--- a/dom/media/mediasource/MediaSourceReader.h
+++ b/dom/media/mediasource/MediaSourceReader.h
@@ -49,17 +49,17 @@ public:
   void RequestAudioData() MOZ_OVERRIDE;
 
   void OnAudioDecoded(AudioData* aSample);
 
   void RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) MOZ_OVERRIDE;
 
   void OnVideoDecoded(VideoData* aSample);
 
-  void OnNotDecoded(MediaData::Type aType, RequestSampleCallback::NotDecodedReason aReason);
+  void OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason);
 
   void OnSeekCompleted(nsresult aResult);
 
   bool HasVideo() MOZ_OVERRIDE
   {
     return mInfo.HasVideo();
   }
 
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -62,17 +62,17 @@ public:
     mDecoder = nullptr;
     return NS_OK;
   }
 
 private:
   nsRefPtr<SourceBufferDecoder> mDecoder;
 };
 
-MOZ_STACK_CLASS class DecodersToInitialize MOZ_FINAL {
+class MOZ_STACK_CLASS DecodersToInitialize MOZ_FINAL {
 public:
   explicit DecodersToInitialize(TrackBuffer* aOwner)
     : mOwner(aOwner)
   {
   }
 
   ~DecodersToInitialize()
   {
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -100,16 +100,17 @@ EXPORTS += [
     'MediaData.h',
     'MediaDataDecodedListener.h',
     'MediaDecoder.h',
     'MediaDecoderOwner.h',
     'MediaDecoderReader.h',
     'MediaDecoderStateMachine.h',
     'MediaInfo.h',
     'MediaMetadataManager.h',
+    'MediaPromise.h',
     'MediaQueue.h',
     'MediaRecorder.h',
     'MediaResource.h',
     'MediaSegment.h',
     'MediaStreamGraph.h',
     'MediaTaskQueue.h',
     'MediaTrack.h',
     'MediaTrackList.h',
@@ -176,16 +177,17 @@ UNIFIED_SOURCES += [
     'MediaCache.cpp',
     'MediaData.cpp',
     'MediaDecoder.cpp',
     'MediaDecoderReader.cpp',
     'MediaDecoderStateMachine.cpp',
     'MediaDecoderStateMachineScheduler.cpp',
     'MediaDevices.cpp',
     'MediaManager.cpp',
+    'MediaPromise.cpp',
     'MediaRecorder.cpp',
     'MediaResource.cpp',
     'MediaShutdownManager.cpp',
     'MediaStreamError.cpp',
     'MediaStreamGraph.cpp',
     'MediaStreamTrack.cpp',
     'MediaTaskQueue.cpp',
     'MediaTrack.cpp',
--- a/dom/media/omx/MediaCodecReader.cpp
+++ b/dom/media/omx/MediaCodecReader.cpp
@@ -483,17 +483,17 @@ MediaCodecReader::DecodeAudioDataTask()
       if (mAudioTrack.mDiscontinuity) {
         a->mDiscontinuity = true;
         mAudioTrack.mDiscontinuity = false;
       }
       GetCallback()->OnAudioDecoded(a);
     }
   }
   if (AudioQueue().AtEndOfStream()) {
-    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::END_OF_STREAM);
+    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, END_OF_STREAM);
   }
   return result;
 }
 
 bool
 MediaCodecReader::DecodeVideoFrameTask(int64_t aTimeThreshold)
 {
   bool result = DecodeVideoFrameSync(aTimeThreshold);
@@ -503,17 +503,17 @@ MediaCodecReader::DecodeVideoFrameTask(i
       if (mVideoTrack.mDiscontinuity) {
         v->mDiscontinuity = true;
         mVideoTrack.mDiscontinuity = false;
       }
       GetCallback()->OnVideoDecoded(v);
     }
   }
   if (VideoQueue().AtEndOfStream()) {
-    GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, RequestSampleCallback::END_OF_STREAM);
+    GetCallback()->OnNotDecoded(MediaData::VIDEO_DATA, END_OF_STREAM);
   }
   return result;
 }
 
 bool
 MediaCodecReader::HasAudio()
 {
   return mInfo.mAudio.mHasAudio;
--- a/dom/media/systemservices/moz.build
+++ b/dom/media/systemservices/moz.build
@@ -35,8 +35,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
             'frameworks/wilhelm/include',
             'system/media/wilhelm/include',
         ]
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/dom/media/tests/mochitest/identity/test_fingerprints.html
+++ b/dom/media/tests/mochitest/identity/test_fingerprints.html
@@ -48,17 +48,17 @@ function makeFingerprints(algo, digest) 
   }
   return fingerprints;
 }
 
 var fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m;
 var identityRegex = /^a=identity:(\S+)/m;
 
 function fingerprintSdp(fingerprints) {
-  return fingerprints.map(fp => "a=fInGeRpRiNt=" + fp.algorithm +
+  return fingerprints.map(fp => "a=fInGeRpRiNt:" + fp.algorithm +
                                 " " + fp.digest + "\n").join("");
 }
 
 // Firefox only uses a single fingerprint
 // that doesn't mean we can't have SDP that describes two
 function testMultipleFingerprints() {
   // this one fails setRemoteDescription if the identity is not good
   var pcStrict = new mozRTCPeerConnection({ peerIdentity: 'someone@example.com'});
@@ -73,30 +73,30 @@ function testMultipleFingerprints() {
   }
 
   navigator.mozGetUserMedia({ audio: true, fake: true }, function(stream) {
     ok(stream, "Got fake stream");
     pcDouble.addStream(stream);
 
     pcDouble.createOffer(function(offer) {
       ok(offer, "Got offer");
-      var m = offer.sdp.match(fingerprintRegex);
-      if (!m) {
+      var fp = offer.sdp.match(fingerprintRegex);
+      if (!fp) {
         finished(false, "No fingerprint in offer SDP");
         return;
       }
 
-      var fingerprints = makeFingerprints(m[1], m[2]);
+      var fingerprints = makeFingerprints(fp[1], fp[2]);
       getIdentityAssertion(fingerprints, function(assertion) {
         ok(assertion, "Should have assertion");
 
-        var sdp = offer.sdp.slice(0, m.index) +
+        var sdp = offer.sdp.slice(0, fp.index) +
           "a=identity:" + assertion + "\n" +
           fingerprintSdp(fingerprints.slice(1)) +
-          offer.sdp.slice(m.index);
+          offer.sdp.slice(fp.index);
 
         var desc = new mozRTCSessionDescription({ type: "offer", sdp: sdp });
         pcStrict.setRemoteDescription(desc, function() {
           finished(true, "session description was OK");
         }, function(err) {
           finished(false, "error setting the session description: " + err);
         });
       });
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -123,10 +123,17 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 [test_peerConnection_setRemoteOfferInHaveLocalOffer.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 [test_peerConnection_throwInCallbacks.html]
 skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
 [test_peerConnection_toJSON.html]
 skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
 
+# multistream is not ready quite yet (bug 1056650)
+# [test_peerConnection_twoAudioStreams.html]
+# [test_peerConnection_twoAudioVideoStreams.html]
+# [test_peerConnection_twoAudioVideoStreamsCombined.html]
+# [test_peerConnection_twoVideoStreams.html]
+# [test_peerConnection_addSecondAudioStream.html]
+
 # Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
 [test_zmedia_cleanup.html]
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1750,51 +1750,53 @@ PeerConnectionWrapper.prototype = {
     element.play();
   },
 
   /**
    * Requests all the media streams as specified in the constrains property.
    *
    * @param {function} onSuccess
    *        Callback to execute if all media has been requested successfully
+   * @param {array} constraintsList
+   *        Array of constraints for GUM calls
    */
-  getAllUserMedia : function PCW_GetAllUserMedia(onSuccess) {
+  getAllUserMedia : function PCW_GetAllUserMedia(constraintsList, onSuccess) {
     var self = this;
 
-    function _getAllUserMedia(constraintsList, index) {
+    function _getAllUserMedia(index) {
       if (index < constraintsList.length) {
         var constraints = constraintsList[index];
 
         getUserMedia(constraints, function (stream) {
           var type = '';
 
           if (constraints.audio) {
             type = 'audio';
           }
 
           if (constraints.video) {
             type += 'video';
           }
 
           self.attachMedia(stream, type, 'local');
 
-          _getAllUserMedia(constraintsList, index + 1);
+          _getAllUserMedia(index + 1);
         }, generateErrorCallback());
       } else {
         onSuccess();
       }
     }
 
-    if (this.constraints.length === 0) {
+    if (constraintsList.length === 0) {
       info("Skipping GUM: no UserMedia requested");
       onSuccess();
     }
     else {
-      info("Get " + this.constraints.length + " local streams");
-      _getAllUserMedia(this.constraints, 0);
+      info("Get " + constraintsList.length + " local streams");
+      _getAllUserMedia(0);
     }
   },
 
   /**
    * Create a new data channel instance
    *
    * @param {Object} options
    *        Options which get forwarded to nsIPeerConnection.createDataChannel
@@ -2169,23 +2171,23 @@ PeerConnectionWrapper.prototype = {
    * @param constraints
    *        The contraint to be examined.
    */
   countAudioTracksInMediaConstraint : function
     PCW_countAudioTracksInMediaConstraint(constraints) {
     if ((!constraints) || (constraints.length === 0)) {
       return 0;
     }
-    var audioTracks = 0;
+    var numAudioTracks = 0;
     for (var i = 0; i < constraints.length; i++) {
       if (constraints[i].audio) {
-        audioTracks++;
+        numAudioTracks++;
       }
     }
-    return audioTracks;
+    return numAudioTracks;
   },
 
   /**
    * Checks for audio in given offer options.
    *
    * @param options
    *        The options to be examined.
    */
@@ -2218,23 +2220,23 @@ PeerConnectionWrapper.prototype = {
    * @param constraint
    *        The contraint to be examined.
    */
   countVideoTracksInMediaConstraint : function
     PCW_countVideoTracksInMediaConstraint(constraints) {
     if ((!constraints) || (constraints.length === 0)) {
       return 0;
     }
-    var videoTracks = 0;
+    var numVideoTracks = 0;
     for (var i = 0; i < constraints.length; i++) {
       if (constraints[i].video) {
-        videoTracks++;
+        numVideoTracks++;
       }
     }
-    return videoTracks;
+    return numVideoTracks;
   },
 
   /**
    * Checks for video in given offer options.
    *
    * @param options
    *        The options to be examined.
    */
@@ -2267,39 +2269,39 @@ PeerConnectionWrapper.prototype = {
    * @param streams
    *        An array of streams (as returned by getLocalStreams()) to be
    *        examined.
    */
   countAudioTracksInStreams : function PCW_countAudioTracksInStreams(streams) {
     if (!streams || (streams.length === 0)) {
       return 0;
     }
-    var audioTracks = 0;
+    var numAudioTracks = 0;
     streams.forEach(function(st) {
-      audioTracks += st.getAudioTracks().length;
+      numAudioTracks += st.getAudioTracks().length;
     });
-    return audioTracks;
+    return numAudioTracks;
   },
 
   /*
    * Counts the amount of video tracks in a given set of streams.
    *
    * @param streams
    *        An array of streams (as returned by getLocalStreams()) to be
    *        examined.
    */
   countVideoTracksInStreams: function PCW_countVideoTracksInStreams(streams) {
     if (!streams || (streams.length === 0)) {
       return 0;
     }
-    var videoTracks = 0;
+    var numVideoTracks = 0;
     streams.forEach(function(st) {
-      videoTracks += st.getVideoTracks().length;
+      numVideoTracks += st.getVideoTracks().length;
     });
-    return videoTracks;
+    return numVideoTracks;
   },
 
   /**
    * Checks that we are getting the media tracks we expect.
    *
    * @param {object} constraintsRemote
    *        The media constraints of the local and remote peer connection object
    */
@@ -2362,20 +2364,19 @@ PeerConnectionWrapper.prototype = {
         if (!self.onAddStreamFired) {
           onSuccess();
         }
       }, 60000);
     }
   },
 
   verifySdp : function PCW_verifySdp(desc, expectedType, offerConstraintsList,
-      answerConstraintsList, offerOptions, trickleIceCallback) {
+      offerOptions, trickleIceCallback) {
     info("Examining this SessionDescription: " + JSON.stringify(desc));
     info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
-    info("answerConstraintsList: " + JSON.stringify(answerConstraintsList));
     info("offerOptions: " + JSON.stringify(offerOptions));
     ok(desc, "SessionDescription is not null");
     is(desc.type, expectedType, "SessionDescription type is " + expectedType);
     ok(desc.sdp.length > 10, "SessionDescription body length is plausible");
     ok(desc.sdp.contains("a=ice-ufrag"), "ICE username is present in SDP");
     ok(desc.sdp.contains("a=ice-pwd"), "ICE password is present in SDP");
     ok(desc.sdp.contains("a=fingerprint"), "ICE fingerprint is present in SDP");
     //TODO: update this for loopback support bug 1027350
@@ -2385,35 +2386,33 @@ PeerConnectionWrapper.prototype = {
       trickleIceCallback(false);
     } else {
       info("No ICE candidate in SDP -> requiring trickle ICE");
       trickleIceCallback(true);
     }
     //TODO: how can we check for absence/presence of m=application?
 
     var audioTracks =
-      Math.max(this.countAudioTracksInMediaConstraint(offerConstraintsList),
-               this.countAudioTracksInMediaConstraint(answerConstraintsList)) ||
+      this.countAudioTracksInMediaConstraint(offerConstraintsList) ||
       this.audioInOfferOptions(offerOptions);
 
     info("expected audio tracks: " + audioTracks);
     if (audioTracks == 0) {
       ok(!desc.sdp.contains("m=audio"), "audio m-line is absent from SDP");
     } else {
       ok(desc.sdp.contains("m=audio"), "audio m-line is present in SDP");
       ok(desc.sdp.contains("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
       //TODO: ideally the rtcp-mux should be for the m=audio, and not just
       //      anywhere in the SDP (JS SDP parser bug 1045429)
       ok(desc.sdp.contains("a=rtcp-mux"), "RTCP Mux is offered in SDP");
 
     }
 
     var videoTracks =
-      Math.max(this.countVideoTracksInMediaConstraint(offerConstraintsList),
-               this.countVideoTracksInMediaConstraint(answerConstraintsList)) ||
+      this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
       this.videoInOfferOptions(offerOptions);
 
     info("expected video tracks: " + videoTracks);
     if (videoTracks == 0) {
       ok(!desc.sdp.contains("m=video"), "video m-line is absent from SDP");
     } else {
       ok(desc.sdp.contains("m=video"), "video m-line is present in SDP");
       if (this.h264) {
@@ -2632,16 +2631,56 @@ PeerConnectionWrapper.prototype = {
          (lIp === serverIp || rIp === serverIp), "One peer uses a relay");
     } else {
       info("P2P configured");
       ok(((lType !== "relayed") && (rType !== "relayed")), "Pure peer to peer call without a relay");
     }
   },
 
   /**
+   * Compares amount of established ICE connection according to ICE candidate
+   * pairs in the stats reporting with the expected amount of connection based
+   * on the constraints.
+   *
+   * @param {object} stats
+   *        The stats to check for ICE candidate pairs
+   * @param {object} counters
+   *        The counters for media and data tracks based on constraints
+   * @param {object} answer
+   *        The SDP answer to check for SDP bundle support
+   */
+  checkStatsIceConnections : function PCW_checkStatsIceConnections(stats,
+      offerConstraintsList, offerOptions, numDataTracks, answer) {
+    var numIceConnections = 0;
+    Object.keys(stats).forEach(function(key) {
+      if ((stats[key].type === "candidatepair") && stats[key].selected) {
+        numIceConnections += 1;
+      }
+    });
+    info("ICE connections according to stats: " + numIceConnections);
+    if (answer.sdp.contains('a=group:BUNDLE')) {
+      is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
+    } else {
+      // This code assumes that no media sections have been rejected due to
+      // codec mismatch or other unrecoverable negotiation failures.
+      var numAudioTracks =
+        this.countAudioTracksInMediaConstraint(offerConstraintsList) ||
+        this.audioInOfferOptions(offerOptions);
+
+      var numVideoTracks =
+        this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
+        this.videoInOfferOptions(offerOptions);
+
+      var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
+      info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
+      is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
+    }
+  },
+
+  /**
    * Property-matching function for finding a certain stat in passed-in stats
    *
    * @param {object} stats
    *        The stats to check from this PeerConnectionWrapper
    * @param {object} props
    *        The properties to look for
    * @returns {boolean} Whether an entry containing all match-props was found.
    */
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -106,25 +106,25 @@ var commandsPeerConnection = [
     function (test) {
       test.pcRemote.logSignalingState();
       test.next();
     }
   ],
   [
     'PC_LOCAL_GUM',
     function (test) {
-      test.pcLocal.getAllUserMedia(function () {
+      test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () {
         test.next();
       });
     }
   ],
   [
     'PC_REMOTE_GUM',
     function (test) {
-      test.pcRemote.getAllUserMedia(function () {
+      test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () {
         test.next();
       });
     }
   ],
   [
     'PC_LOCAL_CHECK_INITIAL_SIGNALINGSTATE',
     function (test) {
       is(test.pcLocal.signalingState, STABLE,
@@ -227,28 +227,28 @@ var commandsPeerConnection = [
         test.next();
       });
     }
   ],
   [
     'PC_LOCAL_SANE_LOCAL_SDP',
     function (test) {
       test.pcLocal.verifySdp(test._local_offer, "offer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function(trickle) {
           test.pcLocal.localRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_REMOTE_SANE_REMOTE_SDP',
     function (test) {
       test.pcRemote.verifySdp(test._local_offer, "offer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function (trickle) {
           test.pcRemote.remoteRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_REMOTE_CREATE_ANSWER',
@@ -351,28 +351,28 @@ var commandsPeerConnection = [
         }
       );
     }
   ],
   [
     'PC_REMOTE_SANE_LOCAL_SDP',
     function (test) {
       test.pcRemote.verifySdp(test._remote_answer, "answer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function (trickle) {
           test.pcRemote.localRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_LOCAL_SANE_REMOTE_SDP',
     function (test) {
       test.pcLocal.verifySdp(test._remote_answer, "answer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function (trickle) {
           test.pcLocal.remoteRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_LOCAL_WAIT_FOR_ICE_CONNECTED',
@@ -518,16 +518,42 @@ var commandsPeerConnection = [
     function (test) {
       test.pcRemote.getStats(null, function(stats) {
         test.pcRemote.checkStatsIceConnectionType(stats);
         test.next();
       });
     }
   ],
   [
+    'PC_LOCAL_CHECK_ICE_CONNECTIONS',
+    function (test) {
+      test.pcLocal.getStats(null, function(stats) {
+        test.pcLocal.checkStatsIceConnections(stats,
+                                              test._offer_constraints,
+                                              test._offer_options,
+                                              0,
+                                              test.originalAnswer);
+        test.next();
+      });
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_ICE_CONNECTIONS',
+    function (test) {
+      test.pcRemote.getStats(null, function(stats) {
+        test.pcRemote.checkStatsIceConnections(stats,
+                                               test._offer_constraints,
+                                               test._offer_options,
+                                               0,
+                                               test.originalAnswer);
+        test.next();
+      });
+    }
+  ],
+  [
     'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND',
     function (test) {
       var pc = test.pcLocal;
       var stream = pc._pc.getLocalStreams()[0];
       var track = stream && stream.getAudioTracks()[0];
       if (track) {
         var msg = "pcLocal.HasStat outbound audio rtp ";
         pc.getStats(track, function(stats) {
@@ -723,17 +749,17 @@ var commandsDataChannel = [
     function (test) {
       test.pcRemote.logSignalingState();
       test.next();
     }
   ],
   [
     'PC_LOCAL_GUM',
     function (test) {
-      test.pcLocal.getAllUserMedia(function () {
+      test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () {
         test.next();
       });
     }
   ],
   [
     'PC_LOCAL_INITIAL_SIGNALINGSTATE',
     function (test) {
       is(test.pcLocal.signalingState, STABLE,
@@ -747,17 +773,17 @@ var commandsDataChannel = [
       is(test.pcLocal.iceConnectionState, ICE_NEW,
         "Initial local ICE connection state is 'new'");
       test.next();
     }
   ],
   [
     'PC_REMOTE_GUM',
     function (test) {
-      test.pcRemote.getAllUserMedia(function () {
+      test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () {
       test.next();
       });
     }
   ],
   [
     'PC_REMOTE_INITIAL_SIGNALINGSTATE',
     function (test) {
       is(test.pcRemote.signalingState, STABLE,
@@ -862,28 +888,28 @@ var commandsDataChannel = [
         test.next();
       });
     }
   ],
   [
     'PC_LOCAL_SANE_LOCAL_SDP',
     function (test) {
       test.pcLocal.verifySdp(test._local_offer, "offer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function(trickle) {
           test.pcLocal.localRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_REMOTE_SANE_REMOTE_SDP',
     function (test) {
       test.pcRemote.verifySdp(test._local_offer, "offer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function (trickle) {
           test.pcRemote.remoteRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_REMOTE_CREATE_ANSWER',
@@ -966,28 +992,28 @@ var commandsDataChannel = [
         }
       );
     }
   ],
   [
     'PC_REMOTE_SANE_LOCAL_SDP',
     function (test) {
       test.pcRemote.verifySdp(test._remote_answer, "answer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function (trickle) {
           test.pcRemote.localRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_LOCAL_SANE_REMOTE_SDP',
     function (test) {
       test.pcLocal.verifySdp(test._remote_answer, "answer",
-        test._offer_constraints, test._answer_constraints, test._offer_options,
+        test._offer_constraints, test._offer_options,
         function (trickle) {
           test.pcLocal.remoteRequiresTrickleIce = trickle;
         });
       test.next();
     }
   ],
   [
     'PC_LOCAL_WAIT_FOR_ICE_CONNECTED',
@@ -1125,16 +1151,42 @@ var commandsDataChannel = [
     'PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT',
     function (test) {
       test.pcRemote.checkMediaFlowPresent(function () {
         test.next();
       });
     }
   ],
   [
+    'PC_LOCAL_CHECK_ICE_CONNECTIONS',
+    function (test) {
+      test.pcLocal.getStats(null, function(stats) {
+        test.pcLocal.checkStatsIceConnections(stats,
+                                              test._offer_constraints,
+                                              test._offer_options,
+                                              1,
+                                              test.originalAnswer);
+        test.next();
+      });
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_ICE_CONNECTIONS',
+    function (test) {
+      test.pcRemote.getStats(null, function(stats) {
+        test.pcRemote.checkStatsIceConnections(stats,
+                                               test._offer_constraints,
+                                               test._offer_options,
+                                               1,
+                                               test.originalAnswer);
+        test.next();
+      });
+    }
+  ],
+  [
     'SEND_MESSAGE',
     function (test) {
       var message = "Lorem ipsum dolor sit amet";
 
       test.send(message, function (channel, data) {
         is(data, message, "Message correctly transmitted from pcLocal to pcRemote.");
 
         test.next();
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="head.js"></script>
+  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+  <script type="application/javascript" src="templates.js"></script>
+  <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1091242",
+    title: "Renegotiation: add second audio stream"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    test.chain.append([
+    [
+      'PC_LOCAL_SETUP_NEGOTIATION_CALLBACK',
+      function (test) {
+        test.pcLocal.onNegotiationneededFired = false;
+        test.pcLocal._pc.onnegotiationneeded = function (anEvent) {
+          info("pcLocal.onnegotiationneeded fired");
+          test.pcLocal.onNegotiationneededFired = true;
+        };
+        test.next();
+      }
+    ],
+    [
+      'PC_LOCAL_ADD_SECOND_STREAM',
+      function (test) {
+        test.pcLocal.getAllUserMedia([{audio: true}], function () {
+          test.next();
+        });
+      }
+    ],
+    [
+      'PC_LOCAL_CREATE_NEW_OFFER',
+      function (test) {
+        ok(test.pcLocal.onNegotiationneededFired, "onnegotiationneeded");
+        test.createOffer(test.pcLocal, function (offer) {
+          test._new_offer = offer;
+          test.next();
+        });
+      }
+    ],
+    [
+      'PC_LOCAL_SET_NEW_LOCAL_DESCRIPTION',
+      function (test) {
+        test.setLocalDescription(test.pcLocal, test._new_offer, HAVE_LOCAL_OFFER, function () {
+          test.next();
+        });
+      }
+    ],
+    [
+      'PC_REMOTE_SET_NEW_REMOTE_DESCRIPTION',
+      function (test) {
+        test.setRemoteDescription(test.pcRemote, test._new_offer, HAVE_REMOTE_OFFER, function () {
+          test.next();
+        });
+      }
+    ],
+    [
+      'PC_REMOTE_CREATE_NEW_ANSWER',
+      function (test) {
+        test.createAnswer(test.pcRemote, function (answer) {
+          test._new_answer = answer;
+          test.next();
+        });
+      }
+    ],
+    [
+      'PC_REMOTE_SET_NEW_LOCAL_DESCRIPTION',
+      function (test) {
+        test.setLocalDescription(test.pcRemote, test._new_answer, STABLE, function () {
+          test.next();
+        });
+      }
+    ],
+    [
+      'PC_LOCAL_SET_NEW_REMOTE_DESCRIPTION',
+      function (test) {
+        test.setRemoteDescription(test.pcLocal, test._new_answer, STABLE, function () {
+          test.next();
+        });
+      }
+    ]
+    // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+    ]);
+    test.setMediaConstraints([{audio: true}], [{audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
@@ -13,17 +13,17 @@
 <script type="application/javascript">
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with audio"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
-
+    test.setMediaConstraints([], [{audio: true}]);
     // TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223).
     // Watch out for case-difference when fixing: { offerToReceiveAudio: true }
     test.setOfferOptions({ mandatory: { OfferToReceiveAudio: true } });
     test.run();
   });
 </script>
 </pre>
 </body>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
@@ -13,16 +13,17 @@
 <script type="application/javascript">
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with video"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
+    test.setMediaConstraints([], [{video: true}]);
     // TODO: Stop using old constraint-like RTCOptions soon (Bug 1064223).
     // Watch out for case-difference when fixing: { offerToReceiveVideo: true }
     test.setOfferOptions({ optional: [{ OfferToReceiveVideo: true }] });
     test.run();
   });
 </script>
 </pre>
 </body>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
@@ -13,18 +13,16 @@
 <script type="application/javascript">
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with video/audio"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
-    test.setOfferOptions({
-      offerToReceiveVideo: true,
-      offerToReceiveAudio: true
-    });
+    test.setMediaConstraints([], [{audio: true, video: true}]);
+    test.setOfferOptions({ offerToReceiveVideo: true, offerToReceiveAudio: true });
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="head.js"></script>
+  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+  <script type="application/javascript" src="templates.js"></script>
+  <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1091242",
+    title: "Multistream: Two audio streams"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    test.setMediaConstraints([{audio: true}, {audio: true}],
+                             [{audio: true}, {audio: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="head.js"></script>
+  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+  <script type="application/javascript" src="templates.js"></script>
+  <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+
+  createHTML({
+    bug: "1091242",
+    title: "Multistream: Two audio streams, two video streams"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    test.setMediaConstraints([{audio: true}, {video: true}, {audio: true},
+                                {video: true}],
+                             [{audio: true}, {video: true}, {audio: true},
+                                {video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="head.js"></script>
+  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+  <script type="application/javascript" src="templates.js"></script>
+  <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+
+  createHTML({
+    bug: "1091242",
+    title: "Multistream: Two audio/video streams"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    test.setMediaConstraints([{audio: true, video: true},
+                                {audio: true, video: true}],
+                             [{audio: true, video: true},
+                                {audio: true, video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="head.js"></script>
+  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+  <script type="application/javascript" src="templates.js"></script>
+  <script type="application/javascript" src="turnConfig.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1091242",
+    title: "Multistream: Two video streams"
+  });
+
+  var test;
+  runNetworkTest(function (options) {
+    test = new PeerConnectionTest(options);
+    test.setMediaConstraints([{video: true}, {video: true}],
+                             [{video: true}, {video: true}]);
+    test.run();
+  });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/webaudio/blink/moz.build
+++ b/dom/media/webaudio/blink/moz.build
@@ -26,8 +26,10 @@ UNIFIED_SOURCES += [
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '/dom/media/webaudio',
 ]
 
+if CONFIG['GNU_CXX']:
+    FAIL_ON_WARNINGS = True
--- a/dom/media/webm/WebMReader.cpp
+++ b/dom/media/webm/WebMReader.cpp
@@ -738,17 +738,17 @@ bool WebMReader::DecodeOpus(const unsign
   if (channels > 8) {
     return false;
   }
 
   if (mPaddingDiscarded) {
     // Discard padding should be used only on the final packet, so
     // decoding after a padding discard is invalid.
     LOG(PR_LOG_DEBUG, ("Opus error, discard padding on interstitial packet"));
-    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
+    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
     return false;
   }
 
   // Maximum value is 63*2880, so there's no chance of overflow.
   int32_t frames_number = opus_packet_get_nb_frames(aData, aLength);
   if (frames_number <= 0) {
     return false; // Invalid packet header.
   }
@@ -792,30 +792,30 @@ bool WebMReader::DecodeOpus(const unsign
     mSkip -= skipFrames;
   }
 
   int64_t discardPadding = 0;
   (void) nestegg_packet_discard_padding(aPacket, &discardPadding);
   if (discardPadding < 0) {
     // Negative discard padding is invalid.
     LOG(PR_LOG_DEBUG, ("Opus error, negative discard padding"));
-    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
+    GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
     return false;
   }
   if (discardPadding > 0) {
     CheckedInt64 discardFrames = UsecsToFrames(discardPadding / NS_PER_USEC,
                                                mInfo.mAudio.mRate);
     if (!discardFrames.isValid()) {
       NS_WARNING("Int overflow in DiscardPadding");
       return false;
     }
     if (discardFrames.value() > frames) {
       // Discarding more than the entire packet is invalid.
       LOG(PR_LOG_DEBUG, ("Opus error, discard padding larger than packet"));
-      GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, RequestSampleCallback::DECODE_ERROR);
+      GetCallback()->OnNotDecoded(MediaData::AUDIO_DATA, DECODE_ERROR);
       return false;
     }
     LOG(PR_LOG_DEBUG, ("Opus decoder discarding %d of %d frames",
                        int32_t(discardFrames.value()), frames));
     // Padding discard is only supposed to happen on the final packet.
     // Record the discard so we can return an error if another packet is
     // decoded.
     mPaddingDiscarded = true;
--- a/dom/media/webspeech/recognition/moz.build
+++ b/dom/media/webspeech/recognition/moz.build
@@ -38,8 +38,10 @@ UNIFIED_SOURCES += [
 
 LOCAL_INCLUDES += [
     '/dom/base',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/dom/plugins/ipc/interpose/moz.build
+++ b/dom/plugins/ipc/interpose/moz.build
@@ -8,8 +8,10 @@ SharedLibrary('plugin_child_interpose')
 
 UNIFIED_SOURCES += [ "%s.mm" % (LIBRARY_NAME) ]
 
 UNIFIED_SOURCES += [
     'plugin_child_quirks.mm',
 ]
 
 OS_LIBS += ['-framework Carbon']
+
+FAIL_ON_WARNINGS = True
--- a/dom/security/nsCSPParser.cpp
+++ b/dom/security/nsCSPParser.cpp
@@ -40,16 +40,25 @@ static const char16_t UNDERLINE    = '_'
 static const char16_t TILDE        = '~';
 static const char16_t WILDCARD     = '*';
 static const char16_t WHITESPACE   = ' ';
 static const char16_t SINGLEQUOTE  = '\'';
 static const char16_t OPEN_CURL    = '{';
 static const char16_t CLOSE_CURL   = '}';
 static const char16_t NUMBER_SIGN  = '#';
 static const char16_t QUESTIONMARK = '?';
+static const char16_t PERCENT_SIGN = '%';
+static const char16_t EXCLAMATION  = '!';
+static const char16_t DOLLAR       = '$';
+static const char16_t AMPERSAND    = '&';
+static const char16_t OPENBRACE    = '(';
+static const char16_t CLOSINGBRACE = ')';
+static const char16_t COMMA        = ',';
+static const char16_t EQUALS       = '=';
+static const char16_t ATSYMBOL     = '@';
 
 static uint32_t kSubHostPathCharacterCutoff = 512;
 
 static const char* kHashSourceValidFns [] = { "sha256", "sha384", "sha512" };
 static const uint32_t kHashSourceValidFnsLen = 3;
 
 /* ===== nsCSPTokenizer ==================== */
 
@@ -135,16 +144,24 @@ isCharacterToken(char16_t aSymbol)
 }
 
 bool
 isNumberToken(char16_t aSymbol)
 {
   return (aSymbol >= '0' && aSymbol <= '9');
 }
 
+bool
+isValidHexDig(char16_t aHexDig)
+{
+  return (isNumberToken(aHexDig) ||
+          (aHexDig >= 'A' && aHexDig <= 'F') ||
+          (aHexDig >= 'a' && aHexDig <= 'f'));
+}
+
 void
 nsCSPParser::resetCurChar(const nsAString& aToken)
 {
   mCurChar = aToken.BeginReading();
   mEndChar = aToken.EndReading();
   resetCurValue();
 }
 
@@ -152,24 +169,128 @@ nsCSPParser::resetCurChar(const nsAStrin
 // number sign ("#") character, or by the end of the URI.
 // http://tools.ietf.org/html/rfc3986#section-3.3
 bool
 nsCSPParser::atEndOfPath()
 {
   return (atEnd() || peek(QUESTIONMARK) || peek(NUMBER_SIGN));
 }
 
+void
+nsCSPParser::percentDecodeStr(const nsAString& aEncStr, nsAString& outDecStr)
+{
+  outDecStr.Truncate();
+
+  // helper function that should not be visible outside this methods scope
+  struct local {
+    static inline char16_t convertHexDig(char16_t aHexDig) {
+      if (isNumberToken(aHexDig)) {
+        return aHexDig - '0';
+      }
+      if (aHexDig >= 'A' && aHexDig <= 'F') {
+        return aHexDig - 'A' + 10;
+      }
+      // must be a lower case character
+      // (aHexDig >= 'a' && aHexDig <= 'f')
+      return aHexDig - 'a' + 10;
+    }
+  };
+
+  const char16_t *cur, *end, *hexDig1, *hexDig2;
+  cur = aEncStr.BeginReading();
+  end = aEncStr.EndReading();
+
+  while (cur != end) {
+    // if it's not a percent sign then there is
+    // nothing to do for that character
+    if (*cur != PERCENT_SIGN) {
+      outDecStr.Append(*cur);
+      cur++;
+      continue;
+    }
+
+    // get the two hexDigs following the '%'-sign
+    hexDig1 = cur + 1;
+    hexDig2 = cur + 2;
+
+    // if there are no hexdigs after the '%' then
+    // there is nothing to do for us.
+    if (hexDig1 == end || hexDig2 == end ||
+        !isValidHexDig(*hexDig1) ||
+        !isValidHexDig(*hexDig2)) {
+      outDecStr.Append(PERCENT_SIGN);
+      cur++;
+      continue;
+    }
+
+    // decode "% hexDig1 hexDig2" into a character.
+    char16_t decChar = (local::convertHexDig(*hexDig1) << 4) +
+                       local::convertHexDig(*hexDig2);
+    outDecStr.Append(decChar);
+
+    // increment 'cur' to after the second hexDig
+    cur = ++hexDig2;
+  }
+}
+
+// unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
 bool
-nsCSPParser::atValidPathChar()
+nsCSPParser::atValidUnreservedChar()
 {
   return (peek(isCharacterToken) || peek(isNumberToken) ||
           peek(DASH) || peek(DOT) ||
           peek(UNDERLINE) || peek(TILDE));
 }
 
+// sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
+//                 / "*" / "+" / "," / ";" / "="
+// Please note that even though ',' and ';' appear to be
+// valid sub-delims according to the RFC production of paths,
+// both can not appear here by itself, they would need to be
+// pct-encoded in order to be part of the path.
+bool
+nsCSPParser::atValidSubDelimChar()
+{
+  return (peek(EXCLAMATION) || peek(DOLLAR) || peek(AMPERSAND) ||
+          peek(SINGLEQUOTE) || peek(OPENBRACE) || peek(CLOSINGBRACE) ||
+          peek(WILDCARD) || peek(PLUS) || peek(EQUALS));
+}
+
+// pct-encoded   = "%" HEXDIG HEXDIG
+bool
+nsCSPParser::atValidPctEncodedChar()
+{
+  const char16_t* pctCurChar = mCurChar;
+
+  if ((pctCurChar + 2) >= mEndChar) {
+    // string too short, can't be a valid pct-encoded char.
+    return false;
+  }
+
+  // Any valid pct-encoding must follow the following format:
+  // "% HEXDIG HEXDIG"
+  if (PERCENT_SIGN != *pctCurChar ||
+     !isValidHexDig(*(pctCurChar+1)) ||
+     !isValidHexDig(*(pctCurChar+2))) {
+    return false;
+  }
+  return true;
+}
+
+// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+// http://tools.ietf.org/html/rfc3986#section-3.3
+bool
+nsCSPParser::atValidPathChar()
+{
+  return (atValidUnreservedChar() ||
+          atValidSubDelimChar() ||
+          atValidPctEncodedChar() ||
+          peek(COLON) || peek(ATSYMBOL));
+}
+
 void
 nsCSPParser::logWarningErrorToConsole(uint32_t aSeverityFlag,
                                       const char* aProperty,
                                       const char16_t* aParams[],
                                       uint32_t aParamsLength)
 {
   CSPPARSERLOG(("nsCSPParser::logWarningErrorToConsole: %s", aProperty));
 
@@ -248,38 +369,54 @@ nsCSPParser::subPath(nsCSPHostSrc* aCspH
   CSPPARSERLOG(("nsCSPParser::subPath, mCurToken: %s, mCurValue: %s",
                NS_ConvertUTF16toUTF8(mCurToken).get(),
                NS_ConvertUTF16toUTF8(mCurValue).get()));
 
   // Emergency exit to avoid endless loops in case a path in a CSP policy
   // is longer than 512 characters, or also to avoid endless loops
   // in case we are parsing unrecognized characters in the following loop.
   uint32_t charCounter = 0;
+  nsString pctDecodedSubPath;
 
   while (!atEndOfPath()) {
     if (peek(SLASH)) {
-      aCspHost->appendPath(mCurValue);
+      // before appendig any additional portion of a subpath we have to pct-decode
+      // that portion of the subpath. atValidPathChar() already verified a correct
+      // pct-encoding, now we can safely decode and append the decoded-sub path.
+      percentDecodeStr(mCurValue, pctDecodedSubPath);
+      aCspHost->appendPath(pctDecodedSubPath);
       // Resetting current value since we are appending parts of the path
       // to aCspHost, e.g; "http://www.example.com/path1/path2" then the
       // first part is "/path1", second part "/path2"
       resetCurValue();
     }
     else if (!atValidPathChar()) {
       const char16_t* params[] = { mCurToken.get() };
       logWarningErrorToConsole(nsIScriptError::warningFlag,
                                "couldntParseInvalidSource",
                                params, ArrayLength(params));
       return false;
     }
+    // potentially we have encountred a valid pct-encoded character in atValidPathChar();
+    // if so, we have to account for "% HEXDIG HEXDIG" and advance the pointer past
+    // the pct-encoded char.
+    if (peek(PERCENT_SIGN)) {
+      advance();
+      advance();
+    }
     advance();
     if (++charCounter > kSubHostPathCharacterCutoff) {
       return false;
     }
   }
-  aCspHost->appendPath(mCurValue);
+  // before appendig any additional portion of a subpath we have to pct-decode
+  // that portion of the subpath. atValidPathChar() already verified a correct
+  // pct-encoding, now we can safely decode and append the decoded-sub path.
+  percentDecodeStr(mCurValue, pctDecodedSubPath);
+  aCspHost->appendPath(pctDecodedSubPath);
   resetCurValue();
   return true;
 }
 
 bool
 nsCSPParser::path(nsCSPHostSrc* aCspHost)
 {
   CSPPARSERLOG(("nsCSPParser::path, mCurToken: %s, mCurValue: %s",
@@ -296,17 +433,19 @@ nsCSPParser::path(nsCSPHostSrc* aCspHost
     const char16_t* params[] = { mCurToken.get() };
     logWarningErrorToConsole(nsIScriptError::warningFlag, "couldntParseInvalidSource",
                              params, ArrayLength(params));
     return false;
   }
   if (atEndOfPath()) {
     // one slash right after host [port] is also considered a path, e.g.
     // www.example.com/ should result in www.example.com/
-    aCspHost->appendPath(mCurValue);
+    // please note that we do not have to perform any pct-decoding here
+    // because we are just appending a '/' and not any actual chars.
+    aCspHost->appendPath(NS_LITERAL_STRING("/"));
     return true;
   }
   // path can begin with "/" but not "//"
   // see http://tools.ietf.org/html/rfc3986#section-3.3
   if (!hostChar()) {
     const char16_t* params[] = { mCurToken.get() };
     logWarningErrorToConsole(nsIScriptError::warningFlag, "couldntParseInvalidSource",
                              params, ArrayLength(params));
--- a/dom/security/nsCSPParser.h
+++ b/dom/security/nsCSPParser.h
@@ -123,18 +123,23 @@ class nsCSPParser {
     nsCSPHostSrc*   appHost(); // helper function to support app specific hosts
     nsCSPHostSrc*   host();
     bool            hostChar();
     bool            schemeChar();
     bool            port();
     bool            path(nsCSPHostSrc* aCspHost);
 
     bool subHost();                                       // helper function to parse subDomains
+    bool atValidUnreservedChar();                         // helper function to parse unreserved
+    bool atValidSubDelimChar();                           // helper function to parse sub-delims
+    bool atValidPctEncodedChar();                         // helper function to parse pct-encoded
     bool subPath(nsCSPHostSrc* aCspHost);                 // helper function to parse paths
     void reportURIList(nsTArray<nsCSPBaseSrc*>& outSrcs); // helper function to parse report-uris
+    void percentDecodeStr(const nsAString& aEncStr,       // helper function to percent-decode
+                          nsAString& outDecStr);
 
     inline bool atEnd()
     {
       return mCurChar >= mEndChar;
     }
 
     inline bool accept(char16_t aSymbol)
     {
--- a/dom/webidl/InputMethod.webidl
+++ b/dom/webidl/InputMethod.webidl
@@ -24,16 +24,30 @@ interface MozInputMethod : EventTarget {
   // allow to mutate.  this attribute should be null when there is no
   // text field currently focused.
   readonly attribute MozInputContext? inputcontext;
 
   [ChromeOnly]
   // Activate or decactive current input method window.
   void setActive(boolean isActive);
 
+  // Add a dynamically declared input.
+  //
+  // The id must not be the same with any statically declared input in the app
+  // manifest. If an input of the same id is already declared, the info of that
+  // input will be updated.
+  Promise<void> addInput(DOMString inputId, object inputManifest);
+
+  // Remove a dynamically declared input.
+  //
+  // The id must not be the same with any statically declared input in the app
+  // manifest. Silently resolves if the input is not previously declared;
+  // rejects if attempt to remove a statically declared input.
+  Promise<void> removeInput(DOMString id);
+
   // The following are internal methods for Firefox OS system app only.
 
   // Set the value on the currently focused element. This has to be used
   // for special situations where the value had to be chosen amongst a
   // list (type=month) or a widget (type=date, time, etc.).
   // If the value passed in parameter isn't valid (in the term of HTML5
   // Forms Validation), the value will simply be ignored by the element.
   [Throws]
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -62,24 +62,24 @@ interface PeerConnectionImpl  {
 
   /* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
   void close();
 
   /* Notify DOM window if this plugin crash is ours. */
   boolean pluginCrash(unsigned long long pluginId, DOMString name, DOMString pluginDumpID);
 
   /* Attributes */
+  [Constant]
   readonly attribute DOMString fingerprint;
   readonly attribute DOMString localDescription;
   readonly attribute DOMString remoteDescription;
 
   readonly attribute PCImplIceConnectionState iceConnectionState;
   readonly attribute PCImplIceGatheringState iceGatheringState;
   readonly attribute PCImplSignalingState signalingState;
-  readonly attribute PCImplSipccState sipccState;
   attribute DOMString id;
 
   attribute DOMString peerIdentity;
   readonly attribute boolean privacyRequested;
 
   /* Data channels */
   [Throws]
   DataChannel createDataChannel(DOMString label, DOMString protocol,
--- a/dom/wifi/moz.build
+++ b/dom/wifi/moz.build
@@ -33,8 +33,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
     UNIFIED_SOURCES = [
         'WifiCertService.cpp',
         'WifiHotspotUtils.cpp',
         'WifiProxyService.cpp',
         'WifiUtils.cpp',
     ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/dom/xul/nsIController.idl
+++ b/dom/xul/nsIController.idl
@@ -2,44 +2,42 @@
 /* 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/. */
 
 #include "nsISupports.idl"
 
 [scriptable, uuid(D5B61B82-1DA4-11d3-BF87-00105A1B0627)]
 interface nsIController : nsISupports {
-  boolean isCommandEnabled(in string command);
-  boolean supportsCommand(in string command);
+	boolean isCommandEnabled(in string command);
+	boolean supportsCommand(in string command);
 
-  void doCommand(in string command);
+	void doCommand(in string command);
 
-  void onEvent(in string eventName);
+	void onEvent(in string eventName);
 };
 
 
 /*
 
   Enhanced controller interface that allows for passing of parameters
   to commands.
   
 */
 
 interface nsICommandParams;
 
-[scriptable, uuid(EEC0B435-7F53-44FE-B00A-CF3EED65C01A)]
+[scriptable, uuid(EBE55080-C8A9-11D5-A73C-DD620D6E04BC)]
 interface nsICommandController : nsISupports
 {
   
   void        getCommandStateWithParams( in string command, in nsICommandParams aCommandParams);
     
   void        doCommandWithParams(in string command, in nsICommandParams aCommandParams);
 
-  void getSupportedCommands(out unsigned long count,
-                            [array, size_is(count), retval] out string commands);
 };
 
 
 /*
   An API for registering commands in groups, to allow for 
   updating via nsIDOMWindow::UpdateCommands.
 */
 interface nsISimpleEnumerator;
--- a/dom/xul/templates/moz.build
+++ b/dom/xul/templates/moz.build
@@ -50,8 +50,10 @@ MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/xul',
     '/layout/xul/tree/',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/editor/reftests/reftest.list
+++ b/editor/reftests/reftest.list
@@ -93,22 +93,22 @@ skip-if(Android||B2G) needs-focus == 462
 == readonly-editable.html readonly-editable-ref.html
 == dynamic-overflow-change.html dynamic-overflow-change-ref.html
 == 694880-1.html 694880-ref.html
 == 694880-2.html 694880-ref.html
 == 694880-3.html 694880-ref.html
 == 388980-1.html 388980-1-ref.html
 needs-focus == spellcheck-superscript-1.html spellcheck-superscript-1-ref.html
 skip-if(B2G) fails-if(Android) needs-focus != spellcheck-superscript-2.html spellcheck-superscript-2-ref.html # bug 783658
-needs-focus == 824080-1.html 824080-1-ref.html
+needs-focus pref(selectioncaret.enabled,false) == 824080-1.html 824080-1-ref.html
 needs-focus == 824080-2.html 824080-2-ref.html
-needs-focus test-pref(selectioncaret.enabled,false) == 824080-3.html 824080-3-ref.html
+needs-focus pref(selectioncaret.enabled,false) == 824080-3.html 824080-3-ref.html
 needs-focus != 824080-2.html 824080-3.html
-needs-focus == 824080-4.html 824080-4-ref.html
-needs-focus test-pref(selectioncaret.enabled,false) == 824080-5.html 824080-5-ref.html
+needs-focus pref(selectioncaret.enabled,false) == 824080-4.html 824080-4-ref.html
+needs-focus pref(selectioncaret.enabled,false) == 824080-5.html 824080-5-ref.html
 needs-focus != 824080-4.html 824080-5.html
 needs-focus == 824080-6.html 824080-6-ref.html
 needs-focus pref(selectioncaret.enabled,false) == 824080-7.html 824080-7-ref.html
 needs-focus != 824080-6.html 824080-7.html
 # Bug 674927: copy spellcheck-textarea tests to contenteditable
 == spellcheck-contenteditable-attr.html spellcheck-contenteditable-nofocus-ref.html
 fails-if(Android||B2G) needs-focus != spellcheck-contenteditable-attr.html spellcheck-contenteditable-ref.html # B2G no spellcheck underline
 needs-focus == spellcheck-contenteditable-focused.html spellcheck-contenteditable-ref.html
--- a/embedding/components/commandhandler/nsBaseCommandController.cpp
+++ b/embedding/components/commandhandler/nsBaseCommandController.cpp
@@ -169,15 +169,8 @@ nsBaseCommandController::GetCommandState
 }
 
 NS_IMETHODIMP
 nsBaseCommandController::OnEvent(const char * aEventName)
 {
   NS_ENSURE_ARG_POINTER(aEventName);
   return NS_OK;
 }
-
-NS_IMETHODIMP
-nsBaseCommandController::GetSupportedCommands(uint32_t* aCount, char*** aCommands)
-{
-  NS_ENSURE_STATE(mCommandTable);
-  return mCommandTable->GetSupportedCommands(aCount, aCommands);
-}
--- a/embedding/components/commandhandler/nsControllerCommandTable.cpp
+++ b/embedding/components/commandhandler/nsControllerCommandTable.cpp
@@ -183,40 +183,16 @@ nsControllerCommandTable::GetCommandStat
 #if DEBUG
     NS_WARNING("Controller command table asked to do a command that it does not handle -- ");
 #endif
     return NS_OK;    // we don't handle this command
   }
   return commandHandler->GetCommandStateParams(aCommandName, aParams, aCommandRefCon);
 }
 
-static PLDHashOperator
-AddCommand(const nsACString& aKey, nsIControllerCommand* aData, void* aArg)
-{
-  // aArg is a pointer to a array of strings. It gets incremented after
-  // allocating each one so that it points to the next location for AddCommand
-  // to assign a string to.
-  char*** commands = static_cast<char***>(aArg);
-  (**commands) = ToNewCString(aKey);
-  (*commands)++;
-  return PL_DHASH_NEXT;
-}
-
-NS_IMETHODIMP
-nsControllerCommandTable::GetSupportedCommands(uint32_t* aCount,
-                                               char*** aCommands)
-{
-  char** commands =
-    static_cast<char **>(NS_Alloc(sizeof(char *) * mCommandsTable.Count()));
-  *aCount = mCommandsTable.Count();
-  *aCommands = commands;
-
-  mCommandsTable.EnumerateRead(AddCommand, &commands);
-  return NS_OK;
-}
 
 nsresult
 NS_NewControllerCommandTable(nsIControllerCommandTable** aResult)
 {
   NS_PRECONDITION(aResult != nullptr, "null ptr");
   if (! aResult)
     return NS_ERROR_NULL_POINTER;
 
--- a/embedding/components/commandhandler/nsIControllerCommandTable.idl
+++ b/embedding/components/commandhandler/nsIControllerCommandTable.idl
@@ -13,17 +13,17 @@
  * and efficiently dispatch commands to their respective handlers.
  *
  * Controllers that use an nsIControllerCommandTable should support
  * nsIInterfaceRequestor, and be able to return an interface to their
  * controller command table via getInterface().
  * 
  */
 
-[scriptable, uuid(c847f90e-b8f3-49db-a4df-8867831f2800)]
+[scriptable, uuid(d1a47834-6ad4-11d7-bfad-000393636592)]
 interface nsIControllerCommandTable : nsISupports
 {
   /**
    * Make this command table immutable, so that commands cannot
    * be registered or unregistered. Some command tables are made
    * mutable after command registration so that they can be 
    * used as singletons.
    */
@@ -77,19 +77,16 @@ interface nsIControllerCommandTable : ns
    * @param aCommandName    the name of the command to execute
    * @param aCommandRefCon  the command context data
    */
 	void    doCommand(in string aCommandName, in nsISupports aCommandRefCon);
 
 	void    doCommandParams(in string aCommandName, in nsICommandParams aParam, in nsISupports aCommandRefCon);
 
 	void    getCommandState(in string aCommandName, in nsICommandParams aParam, in nsISupports aCommandRefCon);
-
-  void getSupportedCommands(out unsigned long count,
-                            [array, size_is(count), retval] out string commands);
 };
 
 
 
 %{C++
 // {670ee5da-6ad5-11d7-9950-000393636592}
 #define NS_CONTROLLERCOMMANDTABLE_CID \
   {0x670ee5da, 0x6ad5, 0x11d7, \
--- a/extensions/auth/moz.build
+++ b/extensions/auth/moz.build
@@ -20,8 +20,10 @@ if CONFIG['OS_ARCH'] == 'WINNT':
     ]
     DEFINES['USE_SSPI'] = True
 else:
     UNIFIED_SOURCES += [
         'nsAuthSambaNTLM.cpp',
     ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/extensions/cookie/moz.build
+++ b/extensions/cookie/moz.build
@@ -22,8 +22,10 @@ UNIFIED_SOURCES += [
     'nsPopupWindowManager.cpp',
 ]
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/extensions/permissions/moz.build
+++ b/extensions/permissions/moz.build
@@ -5,8 +5,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 UNIFIED_SOURCES += [
     'nsContentBlocker.cpp',
     'nsModuleFactory.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/extensions/pref/autoconfig/src/moz.build
+++ b/extensions/pref/autoconfig/src/moz.build
@@ -7,8 +7,10 @@
 UNIFIED_SOURCES += [
     'nsAutoConfig.cpp',
     'nsConfigFactory.cpp',
     'nsJSConfigTriggers.cpp',
     'nsReadConfig.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/gfx/tests/gtest/moz.build
+++ b/gfx/tests/gtest/moz.build
@@ -18,17 +18,17 @@ UNIFIED_SOURCES += [
     # Hangs on linux in ApplyGdkScreenFontOptions
     #'gfxFontSelectionTest.cpp',
     'TestTextures.cpp',
     # Test works but it doesn't assert anything
     #'gfxTextRunPerfTest.cpp',
     'TestTiledLayerBuffer.cpp',
 ]
 
-# Because of gkmedia on windows we wont find these
+# Because of gkmedia on windows we won't find these
 # symbols in xul.dll.
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows':
     UNIFIED_SOURCES += [ '%s/gfx/2d/unittest/%s' % (TOPSRCDIR, p) for p in [
         'TestBase.cpp',
         'TestBugs.cpp',
         'TestPoint.cpp',
         'TestScaling.cpp',
     ]]
@@ -43,8 +43,10 @@ LOCAL_INCLUDES += [
     '/gfx/2d',
     '/gfx/2d/unittest',
     '/gfx/layers',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+
+FAIL_ON_WARNINGS = True
--- a/gfx/ycbcr/moz.build
+++ b/gfx/ycbcr/moz.build
@@ -65,8 +65,10 @@ if CONFIG['CPU_ARCH'] == 'arm' and CONFI
     SOURCES += [
         'yuv_row_arm.s',
     ]
     SOURCES += [
         'yuv_convert_arm.cpp',
     ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/image/src/DynamicImage.cpp
+++ b/image/src/DynamicImage.cpp
@@ -211,17 +211,18 @@ NS_IMETHODIMP_(bool)
 DynamicImage::IsOpaque()
 {
   // XXX(seth): For performance reasons it'd be better to return true here, but
   // I'm not sure how we can guarantee it for an arbitrary gfxDrawable.
   return false;
 }
 
 NS_IMETHODIMP
-DynamicImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
+DynamicImage::GetImageContainer(LayerManager* aManager,
+                                ImageContainer** _retval)
 {
   *_retval = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DynamicImage::Draw(gfxContext* aContext,
                    const nsIntSize& aSize,
@@ -326,17 +327,19 @@ DynamicImage::GetFirstFrameDelay()
   return 0;
 }
 
 NS_IMETHODIMP_(void)
 DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime)
 { }
 
 nsIntSize
-DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags)
+DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest,
+                                      uint32_t aWhichFrame,
+                                      GraphicsFilter aFilter, uint32_t aFlags)
 {
   gfxIntSize size(mDrawable->Size());
   return nsIntSize(size.width, size.height);
 }
 
 NS_IMETHODIMP_(nsIntRect)
 DynamicImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
 {
--- a/image/src/DynamicImage.h
+++ b/image/src/DynamicImage.h
@@ -9,17 +9,16 @@
 #include "mozilla/MemoryReporting.h"
 #include "gfxDrawable.h"
 #include "Image.h"
 
 namespace mozilla {
 namespace image {
 
 /**
- 
  * An Image that is dynamically created. The content of the image is provided by
  * a gfxDrawable. It's anticipated that most uses of DynamicImage will be
  * ephemeral.
  */
 class DynamicImage : public Image
 {
 public:
   NS_DECL_ISUPPORTS
@@ -31,18 +30,18 @@ public:
     MOZ_ASSERT(aDrawable, "Must have a gfxDrawable to wrap");
   }
 
   // Inherited methods from Image.
   virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
 
   virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
-
-  virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
+  virtual size_t SizeOfSourceWithComputedFallback(
+                                 MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
                                MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
 
   virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
   virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
 #ifdef DEBUG
   virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE;
 #endif
--- a/image/src/FrameBlender.cpp
+++ b/image/src/FrameBlender.cpp
@@ -61,19 +61,19 @@ FrameBlender::GetNumFrames() const
 
 int32_t
 FrameBlender::GetTimeoutForFrame(uint32_t aFrameNum)
 {
   nsRefPtr<imgFrame> frame = RawGetFrame(aFrameNum);
   const int32_t timeout = frame->GetRawTimeout();
 
   // Ensure a minimal time between updates so we don't throttle the UI thread.
-  // consider 0 == unspecified and make it fast but not too fast.  Unless we have
-  // a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug 207059.
-  // The behavior of recent IE and Opera versions seems to be:
+  // consider 0 == unspecified and make it fast but not too fast.  Unless we
+  // have a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug
+  // 207059. The behavior of recent IE and Opera versions seems to be:
   // IE 6/Win:
   //   10 - 50ms go 100ms
   //   >50ms go correct speed
   // Opera 7 final/Win:
   //   10ms goes 100ms
   //   >10ms go correct speed
   // It seems that there are broken tools out there that set a 0ms or 10ms
   // timeout when they really want a "default" one.  So munge values in that
@@ -253,18 +253,20 @@ FrameBlender::DoBlend(nsIntRect* aDirtyR
       // Optimization: No need to dispose prev.frame when
       // next frame is full frame and not transparent.
       doDisposal = false;
       // No need to blank the composite frame
       needToBlankComposite = false;
     } else {
       if ((prevFrameRect.x >= nextFrameRect.x) &&
           (prevFrameRect.y >= nextFrameRect.y) &&
-          (prevFrameRect.x + prevFrameRect.width <= nextFrameRect.x + nextFrameRect.width) &&
-          (prevFrameRect.y + prevFrameRect.height <= nextFrameRect.y + nextFrameRect.height)) {
+          (prevFrameRect.x + prevFrameRect.width <=
+              nextFrameRect.x + nextFrameRect.width) &&
+          (prevFrameRect.y + prevFrameRect.height <=
+              nextFrameRect.y + nextFrameRect.height)) {
         // Optimization: No need to dispose prev.frame when
         // next frame fully overlaps previous frame.
         doDisposal = false;
       }
     }
   }
 
   if (doDisposal) {
@@ -294,31 +296,34 @@ FrameBlender::DoBlend(nsIntRect* aDirtyR
         // compositingFrame.
         if (mAnim->compositingPrevFrame) {
           CopyFrameImage(mAnim->compositingPrevFrame->GetRawData(),
                          mAnim->compositingPrevFrame->GetRect(),
                          mAnim->compositingFrame->GetRawData(),
                          mAnim->compositingFrame->GetRect());
 
           // destroy only if we don't need it for this frame's disposal
-          if (nextFrameDisposalMethod != FrameBlender::kDisposeRestorePrevious)
+          if (nextFrameDisposalMethod !=
+              FrameBlender::kDisposeRestorePrevious) {
             mAnim->compositingPrevFrame.reset();
+          }
         } else {
           ClearFrame(mAnim->compositingFrame->GetRawData(),
                      mAnim->compositingFrame->GetRect());
         }
         break;
 
       default:
-        // Copy previous frame into compositingFrame before we put the new frame on top
+        // Copy previous frame into compositingFrame before we put the new
+        // frame on top
         // Assumes that the previous frame represents a full frame (it could be
-        // smaller in size than the container, as long as the frame before it erased
-        // itself)
-        // Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1) will
-        // always be a valid frame number.
+        // smaller in size than the container, as long as the frame before it
+        // erased itself)
+        // Note: Frame 1 never gets into DoBlend(), so (aNextFrameIndex - 1)
+        // will always be a valid frame number.
         if (mAnim->lastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) {
           if (isFullPrevFrame && !prevFrame->GetIsPaletted()) {
             // Just copy the bits
             CopyFrameImage(prevFrame->GetRawData(),
                            prevFrame->GetRect(),
                            mAnim->compositingFrame->GetRawData(),
                            mAnim->compositingFrame->GetRect());
           } else {
@@ -334,23 +339,23 @@ FrameBlender::DoBlend(nsIntRect* aDirtyR
                         prevFrame->GetHasAlpha(),
                         mAnim->compositingFrame->GetRawData(),
                         mAnim->compositingFrame->GetRect(),
                         FrameBlendMethod(prevFrame->GetBlendMethod()));
           }
         }
     }
   } else if (needToBlankComposite) {
-    // If we just created the composite, it could have anything in it's
+    // If we just created the composite, it could have anything in its
     // buffers. Clear them
     ClearFrame(mAnim->compositingFrame->GetRawData(),
                mAnim->compositingFrame->GetRect());
   }
 
-  // Check if the frame we are composing wants the previous image restored afer
+  // Check if the frame we are composing wants the previous image restored after
   // it is done. Don't store it (again) if last frame wanted its image restored
   // too
   if ((nextFrameDisposalMethod == FrameBlender::kDisposeRestorePrevious) &&
       (prevFrameDisposalMethod != FrameBlender::kDisposeRestorePrevious)) {
     // We are storing the whole image.
     // It would be better if we just stored the area that nextFrame is going to
     // overwrite.
     if (!mAnim->compositingPrevFrame) {
@@ -395,65 +400,68 @@ FrameBlender::DoBlend(nsIntRect* aDirtyR
   return true;
 }
 
 //******************************************************************************
 // Fill aFrame with black. Does also clears the mask.
 void
 FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect)
 {
-  if (!aFrameData)
+  if (!aFrameData) {
     return;
+  }
 
   memset(aFrameData, 0, aFrameRect.width * aFrameRect.height * 4);
 }
 
 //******************************************************************************
 void
-FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect& aRectToClear)
+FrameBlender::ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect,
+                         const nsIntRect& aRectToClear)
 {
   if (!aFrameData || aFrameRect.width <= 0 || aFrameRect.height <= 0 ||
       aRectToClear.width <= 0 || aRectToClear.height <= 0) {
     return;
   }
 
   nsIntRect toClear = aFrameRect.Intersect(aRectToClear);
   if (toClear.IsEmpty()) {
     return;
   }
 
   uint32_t bytesPerRow = aFrameRect.width * 4;
   for (int row = toClear.y; row < toClear.y + toClear.height; ++row) {
-    memset(aFrameData + toClear.x * 4 + row * bytesPerRow, 0, toClear.width * 4);
+    memset(aFrameData + toClear.x * 4 + row * bytesPerRow, 0,
+           toClear.width * 4);
   }
 }
 
 //******************************************************************************
 // Whether we succeed or fail will not cause a crash, and there's not much
 // we can do about a failure, so there we don't return a nsresult
 bool
-FrameBlender::CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc,
-                             uint8_t *aDataDest, const nsIntRect& aRectDest)
+FrameBlender::CopyFrameImage(const uint8_t* aDataSrc, const nsIntRect& aRectSrc,
+                             uint8_t* aDataDest, const nsIntRect& aRectDest)
 {
   uint32_t dataLengthSrc = aRectSrc.width * aRectSrc.height * 4;
   uint32_t dataLengthDest = aRectDest.width * aRectDest.height * 4;
 
   if (!aDataDest || !aDataSrc || dataLengthSrc != dataLengthDest) {
     return false;
   }
 
   memcpy(aDataDest, aDataSrc, dataLengthDest);
 
   return true;
 }
 
 nsresult
-FrameBlender::DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect,
+FrameBlender::DrawFrameTo(const uint8_t* aSrcData, const nsIntRect& aSrcRect,
                           uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
-                          uint8_t *aDstPixels, const nsIntRect& aDstRect,
+                          uint8_t* aDstPixels, const nsIntRect& aDstRect,
                           FrameBlender::FrameBlendMethod aBlendMethod)
 {
   NS_ENSURE_ARG_POINTER(aSrcData);
   NS_ENSURE_ARG_POINTER(aDstPixels);
 
   // According to both AGIF and APNG specs, offsets are unsigned
   if (aSrcRect.x < 0 || aSrcRect.y < 0) {
     NS_WARNING("FrameBlender::DrawFrameTo: negative offsets not allowed");
@@ -475,56 +483,61 @@ FrameBlender::DrawFrameTo(const uint8_t 
                  (aSrcRect.y + height <= aDstRect.height),
                 "FrameBlender::DrawFrameTo: Invalid aSrcRect");
 
     // clipped image size may be smaller than source, but not larger
     NS_ASSERTION((width <= aSrcRect.width) && (height <= aSrcRect.height),
                  "FrameBlender::DrawFrameTo: source must be smaller than dest");
 
     // Get pointers to image data
-    const uint8_t *srcPixels = aSrcData + aSrcPaletteLength;
-    uint32_t *dstPixels = reinterpret_cast<uint32_t*>(aDstPixels);
-    const uint32_t *colormap = reinterpret_cast<const uint32_t*>(aSrcData);
+    const uint8_t* srcPixels = aSrcData + aSrcPaletteLength;
+    uint32_t* dstPixels = reinterpret_cast<uint32_t*>(aDstPixels);
+    const uint32_t* colormap = reinterpret_cast<const uint32_t*>(aSrcData);
 
     // Skip to the right offset
     dstPixels += aSrcRect.x + (aSrcRect.y * aDstRect.width);
     if (!aSrcHasAlpha) {
       for (int32_t r = height; r > 0; --r) {
         for (int32_t c = 0; c < width; c++) {
           dstPixels[c] = colormap[srcPixels[c]];
         }
         // Go to the next row in the source resp. destination image
         srcPixels += aSrcRect.width;
         dstPixels += aDstRect.width;
       }
     } else {
       for (int32_t r = height; r > 0; --r) {
         for (int32_t c = 0; c < width; c++) {
           const uint32_t color = colormap[srcPixels[c]];
-          if (color)
+          if (color) {
             dstPixels[c] = color;
+          }
         }
         // Go to the next row in the source resp. destination image
         srcPixels += aSrcRect.width;
         dstPixels += aDstRect.width;
       }
     }
   } else {
-    pixman_image_t* src = pixman_image_create_bits(aSrcHasAlpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
-                                                   aSrcRect.width,
-                                                   aSrcRect.height,
-                                                   reinterpret_cast<uint32_t*>(const_cast<uint8_t*>(aSrcData)),
-                                                   aSrcRect.width * 4);
-    pixman_image_t* dst = pixman_image_create_bits(PIXMAN_a8r8g8b8,
-                                                   aDstRect.width,
-                                                   aDstRect.height,
-                                                   reinterpret_cast<uint32_t*>(aDstPixels),
-                                                   aDstRect.width * 4);
+    pixman_image_t* src =
+      pixman_image_create_bits(
+          aSrcHasAlpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
+          aSrcRect.width, aSrcRect.height,
+          reinterpret_cast<uint32_t*>(const_cast<uint8_t*>(aSrcData)),
+          aSrcRect.width * 4);
+    pixman_image_t* dst =
+      pixman_image_create_bits(PIXMAN_a8r8g8b8,
+                               aDstRect.width,
+                               aDstRect.height,
+                               reinterpret_cast<uint32_t*>(aDstPixels),
+                               aDstRect.width * 4);
 
-    pixman_image_composite32(aBlendMethod == FrameBlender::kBlendSource ? PIXMAN_OP_SRC : PIXMAN_OP_OVER,
+    auto op = aBlendMethod == FrameBlender::kBlendSource ? PIXMAN_OP_SRC
+                                                         : PIXMAN_OP_OVER;
+    pixman_image_composite32(op,
                              src,
                              nullptr,
                              dst,
                              0, 0,
                              0, 0,
                              aSrcRect.x, aSrcRect.y,
                              aSrcRect.width, aSrcRect.height);
 
--- a/image/src/FrameBlender.h
+++ b/image/src/FrameBlender.h
@@ -50,19 +50,20 @@ public:
   void InsertFrame(uint32_t aFrameNum, RawAccessFrameRef&& aRef);
   void RemoveFrame(uint32_t aFrameNum);
   void ClearFrames();
 
   /* The total number of frames in this image. */
   uint32_t GetNumFrames() const;
 
   /*
-   * Returns the frame's adjusted timeout. If the animation loops and the timeout
-   * falls in between a certain range then the timeout is adjusted so that
-   * it's never 0. If the animation does not loop then no adjustments are made.
+   * Returns the frame's adjusted timeout. If the animation loops and the
+   * timeout falls in between a certain range then the timeout is adjusted so
+   * that it's never 0. If the animation does not loop then no adjustments are
+   * made.
    */
   int32_t GetTimeoutForFrame(uint32_t aFrameNum);
 
   /*
    * Set number of times to loop the image.
    * @note -1 means loop forever.
    */
   void SetLoopCount(int32_t aLoopCount);
@@ -125,55 +126,56 @@ private:
     /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
      *
      * The Previous Frame (all frames composited up to the current) needs to be
      * stored in cases where the image specifies it wants the last frame back
      * when it's done with the current frame.
      */
     RawAccessFrameRef compositingPrevFrame;
 
-    Anim() :
-      lastCompositedFrameIndex(-1)
-    {}
+    Anim() : lastCompositedFrameIndex(-1) { }
   };
 
   /** Clears an area of <aFrame> with transparent black.
    *
    * @param aFrameData Target Frame data
    * @param aFrameRect The rectangle of the data pointed ot by aFrameData
    *
-   * @note Does also clears the transparancy mask
+   * @note Does also clears the transparency mask
    */
   static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect);
 
   //! @overload
-  static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect &aRectToClear);
+  static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect,
+                         const nsIntRect& aRectToClear);
 
-  //! Copy one frames's image and mask into another
-  static bool CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc,
-                             uint8_t *aDataDest, const nsIntRect& aRectDest);
+  //! Copy one frame's image and mask into another
+  static bool CopyFrameImage(const uint8_t* aDataSrc, const nsIntRect& aRectSrc,
+                             uint8_t* aDataDest, const nsIntRect& aRectDest);
 
   /**
-   * Draws one frames's image to into another, at the position specified by
+   * Draws one frame's image to into another, at the position specified by
    * aSrcRect.
    *
    * @aSrcData the raw data of the current frame being drawn
    * @aSrcRect the size of the source frame, and the position of that frame in
    *           the composition frame
    * @aSrcPaletteLength the length (in bytes) of the palette at the beginning
    *                    of the source data (0 if image is not paletted)
    * @aSrcHasAlpha whether the source data represents an image with alpha
    * @aDstPixels the raw data of the composition frame where the current frame
    *             is drawn into (32-bit ARGB)
    * @aDstRect the size of the composition frame
-   * @aBlendMethod the blend method for how to blend src on the composition frame.
+   * @aBlendMethod the blend method for how to blend src on the composition
+   * frame.
    */
-  static nsresult DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect,
+  static nsresult DrawFrameTo(const uint8_t* aSrcData,
+                              const nsIntRect& aSrcRect,
                               uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
-                              uint8_t *aDstPixels, const nsIntRect& aDstRect,
+                              uint8_t* aDstPixels, const nsIntRect& aDstRect,
                               FrameBlendMethod aBlendMethod);
 
 private: // data
   //! All the frames of the image
   nsTArray<RawAccessFrameRef> mFrames;
   nsIntSize mSize;
   Anim* mAnim;
   int32_t mLoopCount;
--- a/image/src/ImageFactory.cpp
+++ b/image/src/ImageFactory.cpp
@@ -24,55 +24,60 @@
 #include "ImageFactory.h"
 #include "gfxPrefs.h"
 
 namespace mozilla {
 namespace image {
 
 /*static*/ void
 ImageFactory::Initialize()
-{
-}
+{ }
 
 static uint32_t
 ComputeImageFlags(ImageURL* uri, bool isMultiPart)
 {
   nsresult rv;
 
   // We default to the static globals.
   bool isDiscardable = gfxPrefs::ImageMemDiscardable();
   bool doDecodeOnDraw = gfxPrefs::ImageMemDecodeOnDraw();
 
-  // We want UI to be as snappy as possible and not to flicker. Disable discarding
-  // and decode-on-draw for chrome URLS.
+  // We want UI to be as snappy as possible and not to flicker. Disable
+  // discarding and decode-on-draw for chrome URLS.
   bool isChrome = false;
   rv = uri->SchemeIs("chrome", &isChrome);
-  if (NS_SUCCEEDED(rv) && isChrome)
+  if (NS_SUCCEEDED(rv) && isChrome) {
     isDiscardable = doDecodeOnDraw = false;
+  }
 
   // We don't want resources like the "loading" icon to be discardable or
   // decode-on-draw either.
   bool isResource = false;
   rv = uri->SchemeIs("resource", &isResource);
-  if (NS_SUCCEEDED(rv) && isResource)
+  if (NS_SUCCEEDED(rv) && isResource) {
     isDiscardable = doDecodeOnDraw = false;
+  }
 
   // For multipart/x-mixed-replace, we basically want a direct channel to the
   // decoder. Disable both for this case as well.
-  if (isMultiPart)
+  if (isMultiPart) {
     isDiscardable = doDecodeOnDraw = false;
+  }
 
   // We have all the information we need.
   uint32_t imageFlags = Image::INIT_FLAG_NONE;
-  if (isDiscardable)
+  if (isDiscardable) {
     imageFlags |= Image::INIT_FLAG_DISCARDABLE;
-  if (doDecodeOnDraw)
+  }
+  if (doDecodeOnDraw) {
     imageFlags |= Image::INIT_FLAG_DECODE_ON_DRAW;
-  if (isMultiPart)
+  }
+  if (isMultiPart) {
     imageFlags |= Image::INIT_FLAG_MULTIPART;
+  }
 
   return imageFlags;
 }
 
 /* static */ bool
 ImageFactory::CanRetargetOnDataAvailable(ImageURL* aURI, bool aIsMultiPart)
 {
   // We can't retarget OnDataAvailable safely in cases where we aren't storing
@@ -140,20 +145,22 @@ ImageFactory::CreateAnonymousImage(const
   NS_ENSURE_SUCCESS(rv, BadImage(newImage));
 
   return newImage.forget();
 }
 
 int32_t
 SaturateToInt32(int64_t val)
 {
-  if (val > INT_MAX)
+  if (val > INT_MAX) {
     return INT_MAX;
-  if (val < INT_MIN)
+  }
+  if (val < INT_MIN) {
     return INT_MIN;
+  }
 
   return static_cast<int32_t>(val);
 }
 
 uint32_t
 GetContentSize(nsIRequest* aRequest)
 {
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
@@ -200,17 +207,18 @@ ImageFactory::CreateRasterImage(nsIReque
 
   newImage->SetInnerWindowID(aInnerWindowId);
 
   uint32_t len = GetContentSize(aRequest);
 
   // Pass anything usable on so that the RasterImage can preallocate
   // its source buffer.
   if (len > 0) {
-    uint32_t sizeHint = std::min<uint32_t>(len, 20000000); // Bound by something reasonable
+    // Bound by something reasonable
+    uint32_t sizeHint = std::min<uint32_t>(len, 20000000);
     rv = newImage->SetSourceSizeHint(sizeHint);
     if (NS_FAILED(rv)) {
       // Flush memory, try to get some back, and try again.
       rv = nsMemory::HeapMinimize(true);
       nsresult rv2 = newImage->SetSourceSizeHint(sizeHint);
       // If we've still failed at this point, things are going downhill.
       if (NS_FAILED(rv) || NS_FAILED(rv2)) {
         NS_WARNING("About to hit OOM in imagelib!");
@@ -225,18 +233,18 @@ ImageFactory::CreateRasterImage(nsIReque
     newImage->SetRequestedResolution(parser.GetResolution());
   }
 
   if (parser.HasSampleSize()) {
       /* Get our principal */
       nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
       nsCOMPtr<nsIPrincipal> principal;
       if (chan) {
-        nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(chan,
-                                                                        getter_AddRefs(principal));
+        nsContentUtils::GetSecurityManager()
+          ->GetChannelResultPrincipal(chan, getter_AddRefs(principal));
       }
 
       if ((principal &&
            principal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED) ||
           gfxPrefs::ImageMozSampleSizeEnabled()) {
         newImage->SetRequestedSampleSize(parser.GetSampleSize());
       }
   }
--- a/image/src/ImageFactory.h
+++ b/image/src/ImageFactory.h
@@ -54,33 +54,36 @@ public:
                                              bool aIsMultiPart,
                                              uint32_t aInnerWindowId);
   /**
    * Creates a new image which isn't associated with a URI or loaded through
    * the usual image loading mechanism.
    *
    * @param aMimeType      The mimetype of the image.
    */
-  static already_AddRefed<Image> CreateAnonymousImage(const nsCString& aMimeType);
+  static already_AddRefed<Image>
+  CreateAnonymousImage(const nsCString& aMimeType);
 
 private:
   // Factory functions that create specific types of image containers.
-  static already_AddRefed<Image> CreateRasterImage(nsIRequest* aRequest,
-                                                   ProgressTracker* aProgressTracker,
-                                                   const nsCString& aMimeType,
-                                                   ImageURL* aURI,
-                                                   uint32_t aImageFlags,
-                                                   uint32_t aInnerWindowId);
+  static already_AddRefed<Image>
+  CreateRasterImage(nsIRequest* aRequest,
+                    ProgressTracker* aProgressTracker,
+                    const nsCString& aMimeType,
+                    ImageURL* aURI,
+                    uint32_t aImageFlags,
+                    uint32_t aInnerWindowId);
 
-  static already_AddRefed<Image> CreateVectorImage(nsIRequest* aRequest,
-                                                   ProgressTracker* aProgressTracker,
-                                                   const nsCString& aMimeType,
-                                                   ImageURL* aURI,
-                                                   uint32_t aImageFlags,
-                                                   uint32_t aInnerWindowId);
+  static already_AddRefed<Image>
+  CreateVectorImage(nsIRequest* aRequest,
+                    ProgressTracker* aProgressTracker,
+                    const nsCString& aMimeType,
+                    ImageURL* aURI,
+                    uint32_t aImageFlags,
+                    uint32_t aInnerWindowId);
 
   // This is a static factory class, so disallow instantiation.
   virtual ~ImageFactory() = 0;
 };
 
 } // namespace image
 } // namespace mozilla
 
--- a/image/src/Orientation.h
+++ b/image/src/Orientation.h
@@ -26,17 +26,18 @@ MOZ_END_ENUM_CLASS(Flip)
 
 /**
  * A struct that describes an image's orientation as a rotation optionally
  * followed by a reflection. This may be used to be indicate an image's inherent
  * orientation or a desired orientation for the image.
  */
 struct Orientation
 {
-  explicit Orientation(Angle aRotation = Angle::D0, Flip mFlip = Flip::Unflipped)
+  explicit Orientation(Angle aRotation = Angle::D0,
+                       Flip mFlip = Flip::Unflipped)
     : rotation(aRotation)
     , flip(mFlip)
   { }
 
   bool IsIdentity() const {
     return (rotation == Angle::D0) && (flip == Flip::Unflipped);
   }
 
--- a/image/src/OrientedImage.cpp
+++ b/image/src/OrientedImage.cpp
@@ -136,22 +136,23 @@ OrientedImage::GetFrame(uint32_t aWhichF
     new gfxSurfaceDrawable(innerSurface, size);
 
   // Draw.
   nsRefPtr<gfxContext> ctx = new gfxContext(target);
   ctx->Multiply(OrientationMatrix(size));
   gfxUtils::DrawPixelSnapped(ctx, drawable, size,
                              ImageRegion::Create(size),
                              surfaceFormat, GraphicsFilter::FILTER_FAST);
-  
+
   return target->Snapshot();
 }
 
 NS_IMETHODIMP
-OrientedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
+OrientedImage::GetImageContainer(LayerManager* aManager,
+                                 ImageContainer** _retval)
 {
   // XXX(seth): We currently don't have a way of orienting the result of
   // GetImageContainer. We work around this by always returning null, but if it
   // ever turns out that OrientedImage is widely used on codepaths that can
   // actually benefit from GetImageContainer, it would be a good idea to fix
   // that method for performance reasons.
 
   if (mOrientation.IsIdentity()) {
@@ -163,33 +164,36 @@ OrientedImage::GetImageContainer(LayerMa
 }
 
 struct MatrixBuilder
 {
   explicit MatrixBuilder(bool aInvert) : mInvert(aInvert) { }
 
   gfxMatrix Build() { return mMatrix; }
 
-  void Scale(gfxFloat aX, gfxFloat aY) {
+  void Scale(gfxFloat aX, gfxFloat aY)
+  {
     if (mInvert) {
       mMatrix *= gfxMatrix::Scaling(1.0 / aX, 1.0 / aY);
     } else {
       mMatrix.Scale(aX, aY);
     }
   }
 
-  void Rotate(gfxFloat aPhi) {
+  void Rotate(gfxFloat aPhi)
+  {
     if (mInvert) {
       mMatrix *= gfxMatrix::Rotation(-aPhi);
     } else {
       mMatrix.Rotate(aPhi);
     }
   }
 
-  void Translate(gfxPoint aDelta) {
+  void Translate(gfxPoint aDelta)
+  {
     if (mInvert) {
       mMatrix *= gfxMatrix::Translation(-aDelta);
     } else {
       mMatrix.Translate(aDelta);
     }
   }
 
 private:
@@ -305,21 +309,23 @@ OrientedImage::Draw(gfxContext* aContext
   region.TransformBoundsBy(inverseMatrix);
 
   return InnerImage()->Draw(aContext, size, region, aWhichFrame, aFilter,
                             aSVGContext.map(OrientViewport, mOrientation),
                             aFlags);
 }
 
 nsIntSize
-OrientedImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
+OrientedImage::OptimalImageSizeForDest(const gfxSize& aDest,
+                                       uint32_t aWhichFrame,
                                        GraphicsFilter aFilter, uint32_t aFlags)
 {
   if (!mOrientation.SwapsWidthAndHeight()) {
-    return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags);
+    return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter,
+                                                 aFlags);
   }
 
   // Swap the size for the calculation, then swap it back for the caller.
   gfxSize destSize(aDest.height, aDest.width);
   nsIntSize innerImageSize(InnerImage()->OptimalImageSizeForDest(destSize,
                                                                  aWhichFrame,
                                                                  aFilter,
                                                                  aFlags));
--- a/image/src/OrientedImage.h
+++ b/image/src/OrientedImage.h
@@ -40,22 +40,23 @@ public:
                                layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   const nsIntSize& aSize,
                   const ImageRegion& aRegion,
                   uint32_t aWhichFrame,
                   GraphicsFilter aFilter,
                   const Maybe<SVGImageContext>& aSVGContext,
                   uint32_t aFlags) MOZ_OVERRIDE;
-  NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect(const nsIntRect& aRect) MOZ_OVERRIDE;
+  NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect(
+                                           const nsIntRect& aRect) MOZ_OVERRIDE;
   nsIntSize OptimalImageSizeForDest(const gfxSize& aDest,
                                     uint32_t aWhichFrame,
                                     GraphicsFilter aFilter,
                                     uint32_t aFlags) MOZ_OVERRIDE;
- 
+
 protected:
   OrientedImage(Image* aImage, Orientation aOrientation)
     : ImageWrapper(aImage)
     , mOrientation(aOrientation)
   { }
 
   virtual ~OrientedImage() { }
 
--- a/image/src/ProgressTracker.cpp
+++ b/image/src/ProgressTracker.cpp
@@ -102,17 +102,18 @@ ProgressTracker::SetImage(Image* aImage)
 
 void
 ProgressTracker::ResetImage()
 {
   NS_ABORT_IF_FALSE(mImage, "Resetting image when it's already null!");
   mImage = nullptr;
 }
 
-void ProgressTracker::SetIsMultipart()
+void
+ProgressTracker::SetIsMultipart()
 {
   if (mProgress & FLAG_IS_MULTIPART) {
     return;
   }
 
   MOZ_ASSERT(!(mProgress & FLAG_ONLOAD_BLOCKED),
              "Blocked onload before we knew we were multipart?");
 
@@ -213,19 +214,21 @@ void
 ProgressTracker::Notify(imgRequestProxy* proxy)
 {
   MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
 #ifdef PR_LOGGING
   if (mImage && mImage->GetURI()) {
     nsRefPtr<ImageURL> uri(mImage->GetURI());
     nsAutoCString spec;
     uri->GetSpec(spec);
-    LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::Notify async", "uri", spec.get());
+    LOG_FUNC_WITH_PARAM(GetImgLog(),
+                        "ProgressTracker::Notify async", "uri", spec.get());
   } else {
-    LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::Notify async", "uri", "<unknown>");
+    LOG_FUNC_WITH_PARAM(GetImgLog(),
+                        "ProgressTracker::Notify async", "uri", "<unknown>");
   }
 #endif
 
   proxy->SetNotificationsDeferred(true);
 
   // If we have an existing runnable that we can use, we just append this proxy
   // to its list of proxies to be notified. This ensures we don't unnecessarily
   // delay onload.
@@ -278,17 +281,18 @@ void
 ProgressTracker::NotifyCurrentState(imgRequestProxy* proxy)
 {
   MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
 #ifdef PR_LOGGING
   nsRefPtr<ImageURL> uri;
   proxy->GetURI(getter_AddRefs(uri));
   nsAutoCString spec;
   uri->GetSpec(spec);
-  LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::NotifyCurrentState", "uri", spec.get());
+  LOG_FUNC_WITH_PARAM(GetImgLog(),
+                      "ProgressTracker::NotifyCurrentState", "uri", spec.get());
 #endif
 
   proxy->SetNotificationsDeferred(true);
 
   nsCOMPtr<nsIRunnable> ev = new AsyncNotifyCurrentStateRunnable(this, proxy);
   NS_DispatchToCurrentThread(ev);
 }
 
@@ -306,41 +310,48 @@ ProgressTracker::NotifyCurrentState(imgR
 /* static */ void
 ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies,
                                     bool aHasImage,
                                     Progress aProgress,
                                     const nsIntRect& aDirtyRect)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (aProgress & FLAG_SIZE_AVAILABLE)
+  if (aProgress & FLAG_SIZE_AVAILABLE) {
     NOTIFY_IMAGE_OBSERVERS(aProxies, OnSizeAvailable());
+  }
 
-  if (aProgress & FLAG_DECODE_STARTED)
+  if (aProgress & FLAG_DECODE_STARTED) {
     NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartDecode());
+  }
 
-  if (aProgress & FLAG_ONLOAD_BLOCKED)
+  if (aProgress & FLAG_ONLOAD_BLOCKED) {
     NOTIFY_IMAGE_OBSERVERS(aProxies, BlockOnload());
+  }
 
   if (aHasImage) {
     // OnFrameUpdate
     // If there's any content in this frame at all (always true for
     // vector images, true for raster images that have decoded at
     // least one frame) then send OnFrameUpdate.
-    if (!aDirtyRect.IsEmpty())
+    if (!aDirtyRect.IsEmpty()) {
       NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameUpdate(&aDirtyRect));
+    }
 
-    if (aProgress & FLAG_FRAME_COMPLETE)
+    if (aProgress & FLAG_FRAME_COMPLETE) {
       NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameComplete());
+    }
 
-    if (aProgress & FLAG_HAS_TRANSPARENCY)
+    if (aProgress & FLAG_HAS_TRANSPARENCY) {
       NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageHasTransparency());
+    }
 
-    if (aProgress & FLAG_IS_ANIMATED)
+    if (aProgress & FLAG_IS_ANIMATED) {
       NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageIsAnimated());
+    }
   }
 
   // Send UnblockOnload before OnStopDecode and OnStopRequest. This allows
   // observers that can fire events when they receive those notifications to do
   // so then, instead of being forced to wait for UnblockOnload.
   if (aProgress & FLAG_ONLOAD_UNBLOCKED) {
     NOTIFY_IMAGE_OBSERVERS(aProxies, UnblockOnload());
   }
@@ -353,17 +364,18 @@ ProgressTracker::SyncNotifyInternal(Prox
   if (aProgress & FLAG_LOAD_COMPLETE) {
     NOTIFY_IMAGE_OBSERVERS(aProxies,
                            OnLoadComplete(aProgress & FLAG_LAST_PART_COMPLETE));
   }
 }
 
 void
 ProgressTracker::SyncNotifyProgress(Progress aProgress,
-                                    const nsIntRect& aInvalidRect /* = nsIntRect() */)
+                                    const nsIntRect& aInvalidRect
+                                                  /* = nsIntRect() */)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
 
   // Don't unblock onload if we're not blocked.
   Progress progress = Difference(aProgress);
   if (!((mProgress | progress) & FLAG_ONLOAD_BLOCKED)) {
     progress &= ~FLAG_ONLOAD_UNBLOCKED;
   }
@@ -385,17 +397,18 @@ void
 ProgressTracker::SyncNotify(imgRequestProxy* proxy)
 {
   MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
 #ifdef PR_LOGGING
   nsRefPtr<ImageURL> uri;
   proxy->GetURI(getter_AddRefs(uri));
   nsAutoCString spec;
   uri->GetSpec(spec);
-  LOG_SCOPE_WITH_PARAM(GetImgLog(), "ProgressTracker::SyncNotify", "uri", spec.get());
+  LOG_SCOPE_WITH_PARAM(GetImgLog(),
+                       "ProgressTracker::SyncNotify", "uri", spec.get());
 #endif
 
   nsIntRect r;
   if (mImage) {
     // XXX - Should only send partial rects here, but that needs to
     // wait until we fix up the observer interface
     r = mImage->FrameRect(imgIContainer::FRAME_CURRENT);
   }
--- a/image/src/ProgressTracker.h
+++ b/image/src/ProgressTracker.h
@@ -98,17 +98,17 @@ public:
   // not received OnStopRequest from Necko.
   bool IsLoading() const;
 
   // Get the current image status (as in imgIRequest).
   uint32_t GetImageStatus() const;
 
   // Get the current Progress.
   Progress GetProgress() const { return mProgress; }
- 
+
   // Schedule an asynchronous "replaying" of all the notifications that would
   // have to happen to put us in the current state.
   // We will also take note of any notifications that happen between the time
   // Notify() is called and when we call SyncNotify on |proxy|, and replay them
   // as well.
   // Should be called on the main thread only, since imgRequestProxy and GetURI
   // are not threadsafe.
   void Notify(imgRequestProxy* proxy);
@@ -159,19 +159,19 @@ public:
   // with its loading progress. Weak pointers.
   void AddConsumer(imgRequestProxy* aConsumer);
   bool RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus);
   size_t ConsumerCount() const {
     MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
     return mConsumers.Length();
   }
 
-  // This is intentionally non-general because its sole purpose is to support an
-  // some obscure network priority logic in imgRequest. That stuff could probably
-  // be improved, but it's too scary to mess with at the moment.
+  // This is intentionally non-general because its sole purpose is to support
+  // some obscure network priority logic in imgRequest. That stuff could
+  // probably be improved, but it's too scary to mess with at the moment.
   bool FirstConsumerIs(imgRequestProxy* aConsumer);
 
   void AdoptConsumers(ProgressTracker* aTracker) {
     MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
     MOZ_ASSERT(aTracker);
     mConsumers = aTracker->mConsumers;
   }
 
--- a/intl/chardet/moz.build
+++ b/intl/chardet/moz.build
@@ -12,8 +12,10 @@ EXPORTS += [
 ]
 
 UNIFIED_SOURCES += [
     'nsChardetModule.cpp',
     'nsCyrillicDetector.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/intl/hyphenation/moz.build
+++ b/intl/hyphenation/moz.build
@@ -25,8 +25,11 @@ MSVC_ENABLE_PGO = True
 FINAL_LIBRARY = 'xul'
 
 # Suppress warnings in third-party code.
 if CONFIG['GNU_CC']:
     CFLAGS += [
         '-Wno-sign-compare',
         '-Wno-type-limits',
     ]
+
+if CONFIG['GNU_CXX']:
+    FAIL_ON_WARNINGS = True
--- a/intl/locale/mac/moz.build
+++ b/intl/locale/mac/moz.build
@@ -12,8 +12,9 @@ UNIFIED_SOURCES += [
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '..',
     '../../icu/source/common',
     '../../icu/source/i18n',
 ]
 
+FAIL_ON_WARNINGS = True
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -58,8 +58,10 @@ LOCAL_INCLUDES += [
 
 RESOURCE_FILES += [
     'langGroups.properties',
     'language.properties',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
     CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
+
+FAIL_ON_WARNINGS = True
--- a/intl/lwbrk/moz.build
+++ b/intl/lwbrk/moz.build
@@ -45,8 +45,10 @@ else:
     ]
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_WIDGET_GTK']:
     CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS']
+
+FAIL_ON_WARNINGS = True
--- a/intl/strres/moz.build
+++ b/intl/strres/moz.build
@@ -16,8 +16,10 @@ XPIDL_MODULE = 'intl'
 UNIFIED_SOURCES += [
     'nsStringBundle.cpp',
     'nsStringBundleTextOverride.cpp',
 ]
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/intl/unicharutil/moz.build
+++ b/intl/unicharutil/moz.build
@@ -26,8 +26,10 @@ UNIFIED_SOURCES += [
     'nsCaseConversionImp2.cpp',
     'nsCategoryImp.cpp',
     'nsEntityConverter.cpp',
     'nsSaveAsCharset.cpp',
     'nsUnicodeNormalizer.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
+
+FAIL_ON_WARNINGS = True
--- a/intl/unicharutil/util/internal/moz.build
+++ b/intl/unicharutil/util/internal/moz.build
@@ -8,8 +8,10 @@ include('../objs.mozbuild')
 
 UNIFIED_SOURCES += intl_unicharutil_util_cppsrcs
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '..',
 ]
+
+FAIL_ON_WARNINGS = True
--- a/intl/unicharutil/util/moz.build
+++ b/intl/unicharutil/util/moz.build
@@ -32,8 +32,11 @@ USE_STATIC_LIBS = True
 if CONFIG['_MSC_VER']:
     DEFINES['_USE_ANSI_CPP'] = True
     # Don't include directives about which CRT to use
     CFLAGS += ['-Zl']
     CXXFLAGS += ['-Zl']
 
 if CONFIG['ENABLE_INTL_API']:
     CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+
+if CONFIG['GNU_CXX']:
+    FAIL_ON_WARNINGS = True
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug-1103813.js
@@ -0,0 +1,6 @@
+// Random chosen test: js/src/jit-test/tests/debug/Source-invisible.js
+newGlobal({
+    invisibleToDebugger: true
+})
+// Random chosen test: js/src/jit-test/tests/debug/Debugger-findObjects-05.js
+x = (new Debugger).findObjects()
--- a/js/src/jit/shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/shared/Assembler-x86-shared.cpp
@@ -133,16 +133,18 @@ AssemblerX86Shared::InvertCondition(Cond
         return Above;
       default:
         MOZ_CRASH("unexpected condition");
     }
 }
 
 CPUInfo::SSEVersion CPUInfo::maxSSEVersion = UnknownSSE;
 CPUInfo::SSEVersion CPUInfo::maxEnabledSSEVersion = UnknownSSE;
+bool CPUInfo::avxPresent = false;
+bool CPUInfo::avxEnabled = true;
 
 void
 CPUInfo::SetSSEVersion()
 {
     int flagsEDX = 0;
     int flagsECX = 0;
 
 #ifdef _MSC_VER
@@ -191,9 +193,12 @@ CPUInfo::SetSSEVersion()
     else if (flagsECX & SSSE3Bit) maxSSEVersion = SSSE3;
     else if (flagsECX & SSE3Bit)  maxSSEVersion = SSE3;
     else if (flagsEDX & SSE2Bit)  maxSSEVersion = SSE2;
     else if (flagsEDX & SSEBit)   maxSSEVersion = SSE;
     else                          maxSSEVersion = NoSSE;
 
     if (maxEnabledSSEVersion != UnknownSSE)
         maxSSEVersion = Min(maxSSEVersion, maxEnabledSSEVersion);
+
+    static const int AVXBit = 1 << 28;
+    avxPresent = (flagsECX & AVXBit) && avxEnabled;
 }
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -144,19 +144,29 @@ class CPUInfo
         if (maxSSEVersion == UnknownSSE)
             SetSSEVersion();
 
         MOZ_ASSERT(maxSSEVersion != UnknownSSE);
         MOZ_ASSERT_IF(maxEnabledSSEVersion != UnknownSSE, maxSSEVersion <= maxEnabledSSEVersion);
         return maxSSEVersion;
     }
 
+    static bool IsAVXPresent() {
+        if (MOZ_UNLIKELY(maxSSEVersion == UnknownSSE))
+            SetSSEVersion();
+
+        MOZ_ASSERT_IF(!avxEnabled, !avxPresent);
+        return avxPresent;
+    }
+
   private:
     static SSEVersion maxSSEVersion;
     static SSEVersion maxEnabledSSEVersion;
+    static bool avxPresent;
+    static bool avxEnabled;
 
     static void SetSSEVersion();
 
   public:
     static bool IsSSE2Present() {
 #ifdef JS_CODEGEN_X64
         return true;
 #else
@@ -164,20 +174,21 @@ class CPUInfo
 #endif
     }
     static bool IsSSE3Present()  { return GetSSEVersion() >= SSE3; }
     static bool IsSSSE3Present() { return GetSSEVersion() >= SSSE3; }
     static bool IsSSE41Present() { return GetSSEVersion() >= SSE4_1; }
     static bool IsSSE42Present() { return GetSSEVersion() >= SSE4_2; }
 
 #ifdef JS_CODEGEN_X86
-    static void SetFloatingPointDisabled() { maxEnabledSSEVersion = NoSSE; }
+    static void SetFloatingPointDisabled() { maxEnabledSSEVersion = NoSSE; avxEnabled = false; }
 #endif
-    static void SetSSE3Disabled() { maxEnabledSSEVersion = SSE2; }
-    static void SetSSE4Disabled() { maxEnabledSSEVersion = SSSE3; }
+    static void SetSSE3Disabled() { maxEnabledSSEVersion = SSE2; avxEnabled = false; }
+    static void SetSSE4Disabled() { maxEnabledSSEVersion = SSSE3; avxEnabled = false; }
+    static void SetAVXDisabled() { avxEnabled = false; }
 };
 
 class AssemblerX86Shared : public AssemblerShared
 {
   protected:
     struct RelativePatch {
         int32_t offset;
         void *target;
@@ -206,16 +217,22 @@ class AssemblerX86Shared : public Assemb
 
   protected:
     X86Assembler masm;
 
     typedef X86Assembler::JmpSrc JmpSrc;
     typedef X86Assembler::JmpDst JmpDst;
 
   public:
+    AssemblerX86Shared()
+    {
+        if (!HasAVX())
+            masm.disableVEX();
+    }
+
     enum Condition {
         Equal = X86Assembler::ConditionE,
         NotEqual = X86Assembler::ConditionNE,
         Above = X86Assembler::ConditionA,
         AboveOrEqual = X86Assembler::ConditionAE,
         Below = X86Assembler::ConditionB,
         BelowOrEqual = X86Assembler::ConditionBE,
         GreaterThan = X86Assembler::ConditionG,
@@ -953,16 +970,17 @@ class AssemblerX86Shared : public Assemb
         masm.int3();
     }
 
     static bool HasSSE2() { return CPUInfo::IsSSE2Present(); }
     static bool HasSSE3() { return CPUInfo::IsSSE3Present(); }
     static bool HasSSE41() { return CPUInfo::IsSSE41Present(); }
     static bool SupportsFloatingPoint() { return CPUInfo::IsSSE2Present(); }
     static bool SupportsSimd() { return CPUInfo::IsSSE2Present(); }
+    static bool HasAVX() { return CPUInfo::IsAVXPresent(); }
 
     // The below cmpl methods switch the lhs and rhs when it invokes the
     // macroassembler to conform with intel standard.  When calling this
     // function put the left operand on the left as you would expect.
     void cmpl(Register lhs, Register rhs) {
         masm.cmpl_rr(rhs.code(), lhs.code());
     }
     void cmpl(Register lhs, const Operand &rhs) {
@@ -1670,46 +1688,46 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_ADDRESS32:
             masm.pcmpgtd_mr(src.address(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void cmpps(uint8_t order, const Operand &src, FloatRegister dest) {
+    void vcmpps(uint8_t order, const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.cmpps_rr(order, src.fpu(), dest.code());
+            masm.vcmpps_rr(order, src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.cmpps_mr(order, src.disp(), src.base(), dest.code());
+            masm.vcmpps_mr(order, src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.cmpps_mr(order, src.address(), dest.code());
+            masm.vcmpps_mr(order, src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void cmpeqps(const Operand &src, FloatRegister dest) {
-        cmpps(X86Assembler::ConditionCmp_EQ, src, dest);
+    void vcmpeqps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
+        vcmpps(X86Assembler::ConditionCmp_EQ, src1, src0, dest);
     }
-    void cmpltps(const Operand &src, FloatRegister dest) {
-        cmpps(X86Assembler::ConditionCmp_LT, src, dest);
+    void vcmpltps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
+        vcmpps(X86Assembler::ConditionCmp_LT, src1, src0, dest);
     }
-    void cmpleps(const Operand &src, FloatRegister dest) {
-        cmpps(X86Assembler::ConditionCmp_LE, src, dest);
+    void vcmpleps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
+        vcmpps(X86Assembler::ConditionCmp_LE, src1, src0, dest);
     }
-    void cmpunordps(const Operand &src, FloatRegister dest) {
-        cmpps(X86Assembler::ConditionCmp_UNORD, src, dest);
+    void vcmpunordps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
+        vcmpps(X86Assembler::ConditionCmp_UNORD, src1, src0, dest);
     }
-    void cmpneqps(const Operand &src, FloatRegister dest) {
-        cmpps(X86Assembler::ConditionCmp_NEQ, src, dest);
+    void vcmpneqps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
+        vcmpps(X86Assembler::ConditionCmp_NEQ, src1, src0, dest);
     }
     void rcpps(const Operand &src, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.rcpps_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
@@ -1789,107 +1807,107 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_ADDRESS32:
             masm.psubd_mr(src.address(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void addps(const Operand &src, FloatRegister dest) {
+    void vaddps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.addps_rr(src.fpu(), dest.code());
+            masm.vaddps_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.addps_mr(src.disp(), src.base(), dest.code());
+            masm.vaddps_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.addps_mr(src.address(), dest.code());
+            masm.vaddps_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void subps(const Operand &src, FloatRegister dest) {
+    void vsubps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.subps_rr(src.fpu(), dest.code());
+            masm.vsubps_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.subps_mr(src.disp(), src.base(), dest.code());
+            masm.vsubps_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.subps_mr(src.address(), dest.code());
+            masm.vsubps_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void mulps(const Operand &src, FloatRegister dest) {
+    void vmulps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.mulps_rr(src.fpu(), dest.code());
+            masm.vmulps_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.mulps_mr(src.disp(), src.base(), dest.code());
+            masm.vmulps_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.mulps_mr(src.address(), dest.code());
+            masm.vmulps_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void divps(const Operand &src, FloatRegister dest) {
+    void vdivps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.divps_rr(src.fpu(), dest.code());
+            masm.vdivps_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.divps_mr(src.disp(), src.base(), dest.code());
+            masm.vdivps_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.divps_mr(src.address(), dest.code());
+            masm.vdivps_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void maxps(const Operand &src, FloatRegister dest) {
+    void vmaxps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.maxps_rr(src.fpu(), dest.code());
+            masm.vmaxps_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.maxps_mr(src.disp(), src.base(), dest.code());
+            masm.vmaxps_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.maxps_mr(src.address(), dest.code());
+            masm.vmaxps_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void minps(const Operand &src, FloatRegister dest) {
+    void vminps(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.minps_rr(src.fpu(), dest.code());
+            masm.vminps_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.minps_mr(src.disp(), src.base(), dest.code());
+            masm.vminps_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.minps_mr(src.address(), dest.code());
+            masm.vminps_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
     void andps(const Operand &src, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
         switch (src.kind()) {
@@ -1994,153 +2012,153 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_ADDRESS32:
             masm.shufps_imr(mask, src.address(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void addsd(FloatRegister src, FloatRegister dest) {
+    void vaddsd(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.addsd_rr(src.code(), dest.code());
+        masm.vaddsd_rr(src1.code(), src0.code(), dest.code());
     }
-    void addss(FloatRegister src, FloatRegister dest) {
+    void vaddss(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.addss_rr(src.code(), dest.code());
+        masm.vaddss_rr(src1.code(), src0.code(), dest.code());
     }
-    void addsd(const Operand &src, FloatRegister dest) {
+    void vaddsd(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.addsd_rr(src.fpu(), dest.code());
+            masm.vaddsd_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.addsd_mr(src.disp(), src.base(), dest.code());
+            masm.vaddsd_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.addsd_mr(src.address(), dest.code());
+            masm.vaddsd_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void addss(const Operand &src, FloatRegister dest) {
+    void vaddss(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.addss_rr(src.fpu(), dest.code());
+            masm.vaddss_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.addss_mr(src.disp(), src.base(), dest.code());
+            masm.vaddss_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
-            masm.addss_mr(src.address(), dest.code());
+            masm.vaddss_mr(src1.address(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void subsd(FloatRegister src, FloatRegister dest) {
+    void vsubsd(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.subsd_rr(src.code(), dest.code());
+        masm.vsubsd_rr(src1.code(), src0.code(), dest.code());
     }
-    void subss(FloatRegister src, FloatRegister dest) {
+    void vsubss(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.subss_rr(src.code(), dest.code());
+        masm.vsubss_rr(src1.code(), src0.code(), dest.code());
     }
-    void subsd(const Operand &src, FloatRegister dest) {
+    void vsubsd(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.subsd_rr(src.fpu(), dest.code());
+            masm.vsubsd_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.subsd_mr(src.disp(), src.base(), dest.code());
+            masm.vsubsd_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void subss(const Operand &src, FloatRegister dest) {
+    void vsubss(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.subss_rr(src.fpu(), dest.code());
+            masm.vsubss_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.subss_mr(src.disp(), src.base(), dest.code());
+            masm.vsubss_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void mulsd(FloatRegister src, FloatRegister dest) {
+    void vmulsd(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.mulsd_rr(src.code(), dest.code());
+        masm.vmulsd_rr(src1.code(), src0.code(), dest.code());
     }
-    void mulsd(const Operand &src, FloatRegister dest) {
+    void vmulsd(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.mulsd_rr(src.fpu(), dest.code());
+            masm.vmulsd_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.mulsd_mr(src.disp(), src.base(), dest.code());
+            masm.vmulsd_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void mulss(const Operand &src, FloatRegister dest) {
+    void vmulss(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.mulss_rr(src.fpu(), dest.code());
+            masm.vmulss_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.mulss_mr(src.disp(), src.base(), dest.code());
+            masm.vmulss_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void mulss(FloatRegister src, FloatRegister dest) {
+    void vmulss(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.mulss_rr(src.code(), dest.code());
+        masm.vmulss_rr(src1.code(), src0.code(), dest.code());
     }
-    void divsd(FloatRegister src, FloatRegister dest) {
+    void vdivsd(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.divsd_rr(src.code(), dest.code());
+        masm.vdivsd_rr(src1.code(), src0.code(), dest.code());
     }
-    void divss(FloatRegister src, FloatRegister dest) {
+    void vdivss(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        masm.divss_rr(src.code(), dest.code());
+        masm.vdivss_rr(src1.code(), src0.code(), dest.code());
     }
-    void divsd(const Operand &src, FloatRegister dest) {
+    void vdivsd(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.divsd_rr(src.fpu(), dest.code());
+            masm.vdivsd_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.divsd_mr(src.disp(), src.base(), dest.code());
+            masm.vdivsd_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
-    void divss(const Operand &src, FloatRegister dest) {
+    void vdivss(const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.divss_rr(src.fpu(), dest.code());
+            masm.vdivss_rr(src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.divss_mr(src.disp(), src.base(), dest.code());
+            masm.vdivss_mr(src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
     void xorpd(FloatRegister src, FloatRegister dest) {
         MOZ_ASSERT(HasSSE2());
         masm.xorpd_rr(src.code(), dest.code());
@@ -2194,28 +2212,45 @@ class AssemblerX86Shared : public Assemb
     }
     void insertps(FloatRegister src, FloatRegister dest, unsigned mask) {
         MOZ_ASSERT(HasSSE41());
         masm.insertps_irr(mask, src.code(), dest.code());
     }
     unsigned blendpsMask(bool x, bool y, bool z, bool w) {
         return x | (y << 1) | (z << 2) | (w << 3);
     }
-    void blendps(FloatRegister src, FloatRegister dest, unsigned mask) {
+    void vblendps(unsigned mask, FloatRegister src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE41());
-        masm.blendps_irr(mask, src.code(), dest.code());
+        masm.vblendps_irr(mask, src1.code(), src0.code(), dest.code());
     }
-    void blendps(const Operand &src, FloatRegister dest, unsigned mask) {
+    void vblendps(unsigned mask, const Operand &src1, FloatRegister src0, FloatRegister dest) {
         MOZ_ASSERT(HasSSE41());
-        switch (src.kind()) {
+        switch (src1.kind()) {
           case Operand::FPREG:
-            masm.blendps_irr(mask, src.fpu(), dest.code());
+            masm.vblendps_irr(mask, src1.fpu(), src0.code(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
-            masm.blendps_imr(mask, src.disp(), src.base(), dest.code());
+            masm.vblendps_imr(mask, src1.disp(), src1.base(), src0.code(), dest.code());
+            break;
+          default:
+            MOZ_CRASH("unexpected operand kind");
+        }
+    }
+    void vblendvps(FloatRegister mask, FloatRegister src1, FloatRegister src0, FloatRegister dest) {
+        MOZ_ASSERT(HasSSE41());
+        masm.vblendvps_rr(mask.code(), src1.code(), src0.code(), dest.code());
+    }
+    void vblendvps(FloatRegister mask, const Operand &src1, FloatRegister src0, FloatRegister dest) {
+        MOZ_ASSERT(HasSSE41());
+        switch (src1.kind()) {
+          case Operand::FPREG:
+            masm.vblendvps_rr(mask.code(), src1.fpu(), src0.code(), dest.code());
+            break;
+          case Operand::MEM_REG_DISP:
+            masm.vblendvps_mr(mask.code(), src1.disp(), src1.base(), src0.code(), dest.code());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
     void movsldup(FloatRegister src, FloatRegister dest) {
         MOZ_ASSERT(HasSSE3());
         masm.movsldup_rr(src.code(), dest.code());
--- a/js/src/jit/shared/BaseAssembler-x86-shared.h
+++ b/js/src/jit/shared/BaseAssembler-x86-shared.h
@@ -389,32 +389,43 @@ private:
         OP2_PSLLD_VdqWdq    = 0xF2,
         OP2_PSUBD_VdqWdq    = 0xFA,
         OP2_PADDD_VdqWdq    = 0xFE
     } TwoByteOpcodeID;
 
     typedef enum {
         OP3_ROUNDSS_VsdWsd  = 0x0A,
         OP3_ROUNDSD_VsdWsd  = 0x0B,
+        OP3_BLENDVPS_VdqWdq = 0x14,
         OP3_PEXTRD_EdVdqIb  = 0x16,
         OP3_BLENDPS_VpsWpsIb = 0x0C,
         OP3_PTEST_VdVd      = 0x17,
         OP3_INSERTPS_VpsUps = 0x21,
-        OP3_PINSRD_VdqEdIb  = 0x22
+        OP3_PINSRD_VdqEdIb  = 0x22,
+        OP3_VBLENDVPS_VdqWdq = 0x4A
     } ThreeByteOpcodeID;
 
     typedef enum {
+        ESCAPE_BLENDVPS     = 0x38,
         ESCAPE_PTEST        = 0x38,
         ESCAPE_PINSRD       = 0x3A,
         ESCAPE_PEXTRD       = 0x3A,
         ESCAPE_ROUNDSD      = 0x3A,
         ESCAPE_INSERTPS     = 0x3A,
-        ESCAPE_BLENDPS      = 0x3A
+        ESCAPE_BLENDPS      = 0x3A,
+        ESCAPE_VBLENDVPS    = 0x3A
     } ThreeByteEscape;
 
+    typedef enum {
+        VEX_PS = 0,
+        VEX_PD = 1,
+        VEX_SS = 2,
+        VEX_SD = 3
+    } VexOperandType;
+
     TwoByteOpcodeID jccRel32(Condition cond)
     {
         return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
     }
 
     TwoByteOpcodeID setccOpcode(Condition cond)
     {
         return (TwoByteOpcodeID)(OP_SETCC + cond);
@@ -452,16 +463,21 @@ private:
         FPU6_OP_FISTTP  = 1,
         FPU6_OP_FSTP    = 3,
 
         GROUP11_MOV = 0
     } GroupOpcodeID;
 
     class X86InstructionFormatter;
 public:
+    X86Assembler()
+      : useVEX_(true)
+    { }
+
+    void disableVEX() { useVEX_ = false; }
 
     class JmpSrc {
         friend class X86Assembler;
         friend class X86InstructionFormatter;
     public:
         JmpSrc()
             : m_offset(-1)
         {
@@ -781,116 +797,92 @@ public:
     }
     void psubd_mr(const void* address, XMMRegisterID dst)
     {
         spew("psubd      %p, %s", address, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_PSUBD_VdqWdq, address, (RegisterID)dst);
     }
 
-    void addps_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("addps      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_ADDPS_VpsWps, (RegisterID)src, (RegisterID)dst);
-    }
-    void addps_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("addps      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_ADDPS_VpsWps, offset, base, (RegisterID)dst);
-    }
-    void addps_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("addps      %p, %s", address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_ADDPS_VpsWps, address, (RegisterID)dst);
-    }
-
-    void subps_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("subps      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_SUBPS_VpsWps, (RegisterID)src, (RegisterID)dst);
-    }
-    void subps_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("subps      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_SUBPS_VpsWps, offset, base, (RegisterID)dst);
-    }
-    void subps_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("subps      %p, %s", address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_SUBPS_VpsWps, address, (RegisterID)dst);
-    }
-
-    void mulps_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("mulps      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MULPS_VpsWps, (RegisterID)src, (RegisterID)dst);
-    }
-    void mulps_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("mulps      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MULPS_VpsWps, offset, base, (RegisterID)dst);
-    }
-    void mulps_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("mulps      %p, %s", address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MULPS_VpsWps, address, (RegisterID)dst);
-    }
-
-    void divps_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("divps      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_DIVPS_VpsWps, (RegisterID)src, (RegisterID)dst);
-    }
-    void divps_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("divps      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_DIVPS_VpsWps, offset, base, (RegisterID)dst);
-    }
-    void divps_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("divps      %p, %s", address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_DIVPS_VpsWps, address, (RegisterID)dst);
-    }
-
-    void maxps_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("maxps      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MAXPS_VpsWps, (RegisterID)src, (RegisterID)dst);
-    }
-    void maxps_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("maxps      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MAXPS_VpsWps, offset, base, (RegisterID)dst);
-    }
-    void maxps_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("maxps      %p, %s", address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MAXPS_VpsWps, address, (RegisterID)dst);
-    }
-
-    void minps_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("minps      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MINPS_VpsWps, (RegisterID)src, (RegisterID)dst);
-    }
-    void minps_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("minps      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MINPS_VpsWps, offset, base, (RegisterID)dst);
-    }
-    void minps_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("minps      %p, %s", address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_MINPS_VpsWps, address, (RegisterID)dst);
+    void vaddps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, src1, src0, dst);
+    }
+    void vaddps_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, offset, base, src0, dst);
+    }
+    void vaddps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddps", VEX_PS, OP2_ADDPS_VpsWps, address, src0, dst);
+    }
+
+    void vsubps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, src1, src0, dst);
+    }
+    void vsubps_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, offset, base, src0, dst);
+    }
+    void vsubps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubps", VEX_PS, OP2_SUBPS_VpsWps, address, src0, dst);
+    }
+
+    void vmulps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, src1, src0, dst);
+    }
+    void vmulps_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, offset, base, src0, dst);
+    }
+    void vmulps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulps", VEX_PS, OP2_MULPS_VpsWps, address, src0, dst);
+    }
+
+    void vdivps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, src1, src0, dst);
+    }
+    void vdivps_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, offset, base, src0, dst);
+    }
+    void vdivps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivps", VEX_PS, OP2_DIVPS_VpsWps, address, src0, dst);
+    }
+
+    void vmaxps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, src1, src0, dst);
+    }
+    void vmaxps_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, offset, base, src0, dst);
+    }
+    void vmaxps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmaxps", VEX_PS, OP2_MAXPS_VpsWps, address, src0, dst);
+    }
+
+    void vminps_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, src1, src0, dst);
+    }
+    void vminps_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, offset, base, src0, dst);
+    }
+    void vminps_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vminps", VEX_PS, OP2_MINPS_VpsWps, address, src0, dst);
     }
 
     void andl_rr(RegisterID src, RegisterID dst)
     {
         spew("andl       %s, %s", nameIReg(4,src), nameIReg(4,dst));
         m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
     }
 
@@ -2686,35 +2678,29 @@ public:
 
     void pcmpgtd_mr(const void* address, XMMRegisterID dst)
     {
         spew("pcmpgtd    %p, %s",  address, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_PCMPGTD_VdqWdq, address, (RegisterID)dst);
     }
 
-    void cmpps_rr(uint8_t order, XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("cmpps      $%u, %s, %s", order, nameFPReg(src), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_CMPPS_VpsWps, (RegisterID)src, (RegisterID)dst);
+    void vcmpps_rr(uint8_t order, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vcmpps", VEX_PS, OP2_CMPPS_VpsWps, src1, src0, dst);
         m_formatter.immediate8(order);
     }
-
-    void cmpps_mr(uint8_t order, int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("cmpps      $%u, %s0x%x(%s), %s",
-             order, PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_CMPPS_VpsWps, offset, base, (RegisterID)dst);
+    void vcmpps_mr(uint8_t order, int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vcmpps", VEX_PS, OP2_CMPPS_VpsWps, offset, base, src0, dst);
         m_formatter.immediate8(order);
     }
-
-    void cmpps_mr(uint8_t order, const void* address, XMMRegisterID dst)
-    {
-        spew("cmpps      $%u, %p, %s", order, address, nameFPReg(dst));
-        m_formatter.twoByteOp(OP2_CMPPS_VpsWps, address, (RegisterID)dst);
+    void vcmpps_mr(uint8_t order, const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vcmpps", VEX_PS, OP2_CMPPS_VpsWps, address, src0, dst);
         m_formatter.immediate8(order);
     }
 
     void rcpps_rr(XMMRegisterID src, XMMRegisterID dst){
         spew("rcpps      %s, %s", nameFPReg(src), nameFPReg(dst));
         m_formatter.twoByteOp(OP2_RCPPS_VpsWps, (RegisterID)src, (RegisterID)dst);
     }
     void rcpps_mr(int offset, RegisterID base, XMMRegisterID dst){
@@ -2759,50 +2745,43 @@ public:
 
     void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("addsd      %s, %s", nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
     }
 
-    void addss_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("addss      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("addsd      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, offset, base, (RegisterID)dst);
-    }
-
-    void addss_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("addss      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, offset, base, (RegisterID)dst);
-    }
-
-    void addsd_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("addsd      %p, %s", address, nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, address, (RegisterID)dst);
-    }
-    void addss_mr(const void* address, XMMRegisterID dst)
-    {
-        spew("addss      %p, %s", address, nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, address, (RegisterID)dst);
+    void vaddsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddsd", VEX_SD, OP2_ADDSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vaddss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddss", VEX_SS, OP2_ADDSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vaddsd_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddsd", VEX_SD, OP2_ADDSD_VsdWsd, offset, base, src0, dst);
+    }
+
+    void vaddss_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddss", VEX_SS, OP2_ADDSD_VsdWsd, offset, base, src0, dst);
+    }
+
+    void vaddsd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddsd", VEX_SD, OP2_ADDSD_VsdWsd, address, src0, dst);
+    }
+    void vaddss_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vaddss", VEX_SS, OP2_ADDSD_VsdWsd, address, src0, dst);
     }
 
     void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("cvtss2sd   %s, %s", nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp(OP2_CVTSS2SD_VsdEd, (RegisterID)src, (RegisterID)dst);
     }
@@ -3522,82 +3501,62 @@ public:
     void movdqa_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
     {
         spew("movdqa     %d(%s,%s,%d), %s",
              offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_MOVDQ_VdqWdq, offset, base, index, scale, (RegisterID)dst);
     }
 
-    void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("mulsd      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void mulss_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("mulss      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("mulsd      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, offset, base, (RegisterID)dst);
-    }
-
-    void mulss_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("mulss      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, offset, base, (RegisterID)dst);
+    void vmulsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulsd", VEX_SD, OP2_MULSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vmulss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulss", VEX_SS, OP2_MULSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vmulsd_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulsd", VEX_SD, OP2_MULSD_VsdWsd, offset, base, src0, dst);
+    }
+
+    void vmulss_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vmulss", VEX_SS, OP2_MULSD_VsdWsd, offset, base, src0, dst);
     }
 
     void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
     {
         FIXME_INSN_PRINTING;
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)src, (RegisterID)dst);
         m_formatter.immediate8(whichWord);
     }
 
-    void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("subsd      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void subss_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("subss      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("subsd      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, offset, base, (RegisterID)dst);
-    }
-
-    void subss_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("subss      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, offset, base, (RegisterID)dst);
+    void vsubsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubsd", VEX_SD, OP2_SUBSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vsubss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubss", VEX_SS, OP2_SUBSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vsubsd_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubsd", VEX_SD, OP2_SUBSD_VsdWsd, offset, base, src0, dst);
+    }
+
+    void vsubss_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vsubss", VEX_SS, OP2_SUBSD_VsdWsd, offset, base, src0, dst);
     }
 
     void ucomiss_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("ucomiss    %s, %s", nameFPReg(src), nameFPReg(dst));
         m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)src, (RegisterID)dst);
     }
 
@@ -3611,44 +3570,34 @@ public:
     void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("ucomisd    %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, offset, base, (RegisterID)dst);
     }
 
-    void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("divsd      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void divss_rr(XMMRegisterID src, XMMRegisterID dst)
-    {
-        spew("divss      %s, %s", nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)src, (RegisterID)dst);
-    }
-
-    void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("divsd      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F2);
-        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, offset, base, (RegisterID)dst);
-    }
-
-    void divss_mr(int offset, RegisterID base, XMMRegisterID dst)
-    {
-        spew("divss      %s0x%x(%s), %s",
-             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, offset, base, (RegisterID)dst);
+    void vdivsd_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivsd", VEX_SD, OP2_DIVSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vdivss_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivss", VEX_SS, OP2_DIVSD_VsdWsd, src1, src0, dst);
+    }
+
+    void vdivsd_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivsd", VEX_SD, OP2_DIVSD_VsdWsd, offset, base, src0, dst);
+    }
+
+    void vdivss_mr(int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        twoByteOpSimd("vdivss", VEX_SS, OP2_DIVSD_VsdWsd, offset, base, src0, dst);
     }
 
     void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("xorpd      %s, %s", nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)src, (RegisterID)dst);
     }
@@ -3815,33 +3764,37 @@ public:
         MOZ_ASSERT(lane < 4);
         spew("pextrd     $%x, %s, %s0x%x(%s)", lane, nameFPReg(src),
              PRETTY_PRINT_OFFSET(offset), nameIReg(base));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.threeByteOp(OP3_PEXTRD_EdVdqIb, ESCAPE_PEXTRD, offset, base, (RegisterID)src);
         m_formatter.immediate8(uint8_t(lane));
     }
 
-    void blendps_irr(unsigned imm, XMMRegisterID src, XMMRegisterID dst)
+    void vblendps_irr(unsigned imm, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        MOZ_ASSERT(imm < 16);
+        // Despite being a "ps" instruction, vblendps is encoded with the "pd" prefix.
+        threeByteOpSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_BLENDPS, src1, src0, dst);
+        m_formatter.immediate8(uint8_t(imm));
+    }
+
+    void vblendps_imr(unsigned imm, int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
     {
         MOZ_ASSERT(imm < 16);
-        spew("blendps    $%x, %s, %s", imm, nameFPReg(src), nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_66);
-        m_formatter.threeByteOp(OP3_BLENDPS_VpsWpsIb, ESCAPE_BLENDPS, (RegisterID)src, (RegisterID)dst);
+        // Despite being a "ps" instruction, vblendps is encoded with the "pd" prefix.
+        threeByteOpSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_BLENDPS, offset, base, src0, dst);
         m_formatter.immediate8(uint8_t(imm));
     }
 
-    void blendps_imr(unsigned imm, int offset, RegisterID base, XMMRegisterID dst)
-    {
-        MOZ_ASSERT(imm < 16);
-        spew("blendps    $%x, %s0x%x(%s), %s", imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base),
-             nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_66);
-        m_formatter.threeByteOp(OP3_BLENDPS_VpsWpsIb, ESCAPE_BLENDPS, offset, base, (RegisterID)dst);
-        m_formatter.immediate8(uint8_t(imm));
+    void vblendvps_rr(XMMRegisterID mask, XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
+        vblendvOpSimd(mask, src1, src0, dst);
+    }
+    void vblendvps_mr(XMMRegisterID mask, int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst) {
+        vblendvOpSimd(mask, offset, base, src0, dst);
     }
 
     void movsldup_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("movsldup   %s, %s", nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp(OP2_MOVSLDUP_VpsWps, (RegisterID)src, (RegisterID)dst);
     }
@@ -4260,37 +4213,262 @@ public:
     }
 
     static void setInt32(void* where, int32_t value)
     {
         reinterpret_cast<int32_t*>(where)[-1] = value;
     }
 
 private:
+    // Methods for encoding SIMD instructions via either legacy SSE encoding or
+    // VEX encoding.
+
+    bool useLegacySSEEncoding(XMMRegisterID src0, XMMRegisterID dst)
+    {
+        // If we don't have AVX or it's disabled, use the legacy SSE encoding.
+        if (!useVEX_) {
+            MOZ_ASSERT(src0 == dst);
+            return true;
+        }
+
+        // If src0 is the same as the output register, we might as well use
+        // the legacy SSE encoding, since it is smaller. However, this is only
+        // beneficial as long as we're not using ymm registers anywhere.
+        return src0 == dst;
+    }
+
+    bool useLegacySSEEncodingForVblendv(XMMRegisterID mask, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        // Similar to useLegacySSEEncoding, but for vblendv the Legacy SSE
+        // encoding also requires the mask to be in xmm0.
+
+        if (!useVEX_) {
+            MOZ_ASSERT(src0 == dst);
+            MOZ_ASSERT(mask == X86Registers::xmm0);
+            return true;
+        }
+
+        return src0 == dst && mask == X86Registers::xmm0;
+    }
+
+    const char *legacySSEOpName(const char *name)
+    {
+        MOZ_ASSERT(name[0] == 'v');
+        return name + 1;
+    }
+
+#ifdef JS_CODEGEN_X64
+    void twoByteRipOpSimd(const char *name, VexOperandType ty, TwoByteOpcodeID opcode,
+                          int ripOffset, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s?%+d(%%rip), %s", legacySSEOpName(name), ripOffset, nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.twoByteRipOp(opcode, ripOffset, src0);
+            return;
+        }
+
+        spew("%-11s?%+d(%%rip), %s, %s", name, ripOffset, nameFPReg(src0), nameFPReg(dst));
+        m_formatter.twoByteRipOpVex(ty, opcode, ripOffset, src0, dst);
+    }
+#endif
+
+    void twoByteOpSimd(const char *name, VexOperandType ty, TwoByteOpcodeID opcode,
+                       XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%s, %s", legacySSEOpName(name), nameFPReg(rm), nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.twoByteOp(opcode, (RegisterID)rm, src0);
+            return;
+        }
+
+        spew("%-11s%s, %s, %s", name, nameFPReg(rm), nameFPReg(src0), nameFPReg(dst));
+        m_formatter.twoByteOpVex(ty, opcode, (RegisterID)rm, src0, dst);
+    }
+
+    void twoByteOpSimd(const char *name, VexOperandType ty, TwoByteOpcodeID opcode,
+                       int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%s0x%x(%s), %s", legacySSEOpName(name),
+                 PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.twoByteOp(opcode, offset, base, src0);
+            return;
+        }
+
+        spew("%-11s%s0x%x(%s), %s, %s", name,
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(src0), nameFPReg(dst));
+        m_formatter.twoByteOpVex(ty, opcode, offset, base, src0, dst);
+    }
+
+    void twoByteOpSimd_disp32(const char *name, VexOperandType ty, TwoByteOpcodeID opcode,
+                              int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%s0x%x(%s), %s", legacySSEOpName(name),
+                 PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.twoByteOp_disp32(opcode, offset, base, src0);
+            return;
+        }
+
+        spew("%-11s%s0x%x(%s), %s, %s", name,
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(src0), nameFPReg(dst));
+        m_formatter.twoByteOpVex_disp32(ty, opcode, offset, base, src0, dst);
+    }
+
+    void twoByteOpSimd(const char *name, VexOperandType ty, TwoByteOpcodeID opcode,
+                       int offset, RegisterID base, RegisterID index, int scale,
+                       XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%s0x%x(%s,%s,%d), %s", legacySSEOpName(name),
+                 PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(index), scale,
+                 nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.twoByteOp(opcode, offset, base, index, scale, src0);
+            return;
+        }
+
+        spew("%-11s%s0x%x(%s,%s,%d), %s, %s", name, PRETTY_PRINT_OFFSET(offset), nameIReg(base),
+             nameIReg(index), scale, nameFPReg(src0), nameFPReg(dst));
+        m_formatter.twoByteOpVex(ty, opcode, offset, base, index, scale, src0, dst);
+    }
+
+    void twoByteOpSimd(const char *name, VexOperandType ty, TwoByteOpcodeID opcode,
+                       const void* address, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%p, %s", legacySSEOpName(name), address, nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.twoByteOp(opcode, address, src0);
+            return;
+        }
+
+        spew("%-11s%p, %s, %s", name, address, nameFPReg(src0), nameFPReg(dst));
+        m_formatter.twoByteOpVex(ty, opcode, address, src0, dst);
+    }
+
+    void threeByteOpSimd(const char *name, VexOperandType ty, ThreeByteOpcodeID opcode,
+                         ThreeByteEscape escape,
+                         XMMRegisterID rm, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%s, %s", legacySSEOpName(name), nameFPReg(rm), nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.threeByteOp(opcode, escape, (RegisterID)rm, src0);
+            return;
+        }
+
+        spew("%-11s%s, %s, %s", name, nameFPReg(rm), nameFPReg(src0), nameFPReg(dst));
+        m_formatter.threeByteOpVex(ty, opcode, escape, (RegisterID)rm, src0, dst);
+    }
+
+    void threeByteOpSimd(const char *name, VexOperandType ty, ThreeByteOpcodeID opcode,
+                         ThreeByteEscape escape,
+                         int offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
+    {
+        if (useLegacySSEEncoding(src0, dst)) {
+            spew("%-11s%s0x%x(%s), %s", legacySSEOpName(name),
+                 PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(src0));
+            m_formatter.legacySSEPrefix(ty);
+            m_formatter.threeByteOp(opcode, escape, offset, base, src0);
+            return;
+        }
+
+        spew("%-11s%s0x%x(%s), %s, %s", name,
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(src0), nameFPReg(dst));
+        m_formatter.threeByteOpVex(ty, opcode, escape, offset, base, src0, dst);
+    }
+
+    // Blendv is a three-byte op, but the VEX encoding has a different opcode
+    // than the SSE enc