Merge last green changeset from inbound to mozilla-central
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 02 Apr 2012 10:41:37 -0700
changeset 94151 95df15895e025d95b8df37abb01650a3e126059e
parent 94121 f4fe6a11813922d3d25564d2d1240e55073e2ba0 (current diff)
parent 94150 16a7a0838a28a15a0bac4df8379c7d4fec2605ae (diff)
child 94165 4abc7c28b048d7ef0832b8c82b109696935d0528
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
first release with
nightly linux32
95df15895e02 / 14.0a1 / 20120403031251 / files
nightly linux64
95df15895e02 / 14.0a1 / 20120403031251 / files
nightly mac
95df15895e02 / 14.0a1 / 20120403031251 / files
nightly win32
95df15895e02 / 14.0a1 / 20120403031251 / files
nightly win64
95df15895e02 / 14.0a1 / 20120403031251 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last green changeset from inbound to mozilla-central
accessible/src/msaa/CAccessibleAction.cpp
accessible/src/msaa/CAccessibleAction.h
dom/base/nsGlobalWindow.cpp
extensions/universalchardet/tests/bug631751be_text.html
js/xpconnect/tests/mochitest/test_bug462428.html
mobile/android/base/gfx/PlaceholderLayerClient.java
mobile/android/components/UpdatePrompt.js
toolkit/mozapps/update/updater/progressui_null.cpp
--- a/accessible/public/nsIAccessible.idl
+++ b/accessible/public/nsIAccessible.idl
@@ -54,17 +54,17 @@ interface nsIAccessibleRelation;
  * accessibility APIs like MSAA and ATK. Contains the sum of what's needed
  * to support IAccessible as well as ATK's generic accessibility objects.
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
  * nodes in the DOM tree -- such as documents, focusable elements and text.
  * Mozilla creates the implementations of nsIAccessible on demand.
  * See http://www.mozilla.org/projects/ui/accessibility for more information.
  */
-[scriptable, uuid(e7c44e0d-736e-4ead-afee-b51f4b574020)]
+[scriptable, uuid(46d422d1-c92f-4536-bdef-f77bc8350ec7)]
 interface nsIAccessible : nsISupports
 {
   /**
    * Parent node in accessible tree.
    */
   readonly attribute nsIAccessible parent;
 
   /**
@@ -99,23 +99,16 @@ interface nsIAccessible : nsISupports
 
   /**
    * The 0-based index of this accessible in its parent's list of children,
    * or -1 if this accessible does not have a parent.
    */
   readonly attribute long indexInParent;
 
   /**
-   * The innerHTML for the HTML element associated with this accessible if applicable.
-   * This is a text string of all the markup inside the DOM
-   * node, not including the start and end tag for the node.
-   */
-  readonly attribute DOMString innerHTML;
-
-  /**
    * The DOM node this nsIAccessible is associated with.
    */
   readonly attribute nsIDOMNode DOMNode;
 
   /**
    * The document accessible that this access node resides in.
    */
   readonly attribute nsIAccessibleDocument document;
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -96,17 +96,20 @@ AccEvent::GetNode()
     mNode = mAccessible->GetNode();
 
   return mNode;
 }
 
 nsDocAccessible*
 AccEvent::GetDocAccessible()
 {
-  nsINode *node = GetNode();
+  if (mAccessible)
+    return mAccessible->Document();
+
+  nsINode* node = GetNode();
   if (node)
     return GetAccService()->GetDocAccessible(node->OwnerDoc());
 
   return nsnull;
 }
 
 already_AddRefed<nsAccEvent>
 AccEvent::CreateXPCOMObject()
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -592,16 +592,32 @@ nsAccessibilityService::UpdateText(nsIPr
                                    nsIContent* aContent)
 {
   nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
   if (document)
     document->UpdateText(aContent);
 }
 
 void
+nsAccessibilityService::TreeViewChanged(nsIPresShell* aPresShell,
+                                        nsIContent* aContent,
+                                        nsITreeView* aView)
+{
+  nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
+  if (document) {
+    nsAccessible* accessible = document->GetAccessible(aContent);
+    if (accessible) {
+      nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
+      if (treeAcc) 
+        treeAcc->TreeViewChanged(aView);
+    }
+  }
+}
+
+void
 nsAccessibilityService::UpdateListBullet(nsIPresShell* aPresShell,
                                          nsIContent* aHTMLListItemContent,
                                          bool aHasBullet)
 {
   nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
   if (document) {
     nsAccessible* accessible = document->GetAccessible(aHTMLListItemContent);
     if (accessible) {
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -44,16 +44,17 @@
 #include "a11yGeneric.h"
 #include "nsAccDocManager.h"
 
 #include "mozilla/a11y/FocusManager.h"
 
 #include "nsIObserver.h"
 
 class nsImageFrame;
+class nsITreeView;
 
 namespace mozilla {
 namespace a11y {
 
 /**
  * Return focus manager.
  */
 FocusManager* FocusMgr();
@@ -148,16 +149,22 @@ public:
                                     nsIContent* aEndChild);
 
   virtual void ContentRemoved(nsIPresShell* aPresShell, nsIContent* aContainer,
                               nsIContent* aChild);
 
   virtual void UpdateText(nsIPresShell* aPresShell, nsIContent* aContent);
 
   /**
+   * Update XUL:tree accessible tree when treeview is changed.
+   */
+  void TreeViewChanged(nsIPresShell* aPresShell, nsIContent* aContent,
+                       nsITreeView* aView);
+
+  /**
    * Update list bullet accessible.
    */
   virtual void UpdateListBullet(nsIPresShell* aPresShell,
                                 nsIContent* aHTMLListItemContent,
                                 bool aHasBullet);
 
   /**
    * Update the image map.
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -259,27 +259,16 @@ nsAccessible::GetRootDocument(nsIAccessi
   NS_ENSURE_ARG_POINTER(aRootDocument);
 
   nsRootAccessible* rootDocument = RootAccessible();
   NS_IF_ADDREF(*aRootDocument = rootDocument);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessible::GetInnerHTML(nsAString& aInnerHTML)
-{
-  aInnerHTML.Truncate();
-
-  nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
-  NS_ENSURE_TRUE(htmlElement, NS_ERROR_NULL_POINTER);
-
-  return htmlElement->GetInnerHTML(aInnerHTML);
-}
-
-NS_IMETHODIMP
 nsAccessible::GetLanguage(nsAString& aLanguage)
 {
   Language(aLanguage);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetName(nsAString& aName)
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -437,23 +437,16 @@ NS_IMETHODIMP
 nsApplicationAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
 {
   NS_ENSURE_ARG_POINTER(aRootDocument);
   *aRootDocument = nsnull;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsApplicationAccessible::GetInnerHTML(nsAString &aInnerHTML)
-{
-  aInnerHTML.Truncate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsApplicationAccessible::ScrollTo(PRUint32 aScrollType)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsApplicationAccessible::ScrollToPoint(PRUint32 aCoordinateType,
                                        PRInt32 aX, PRInt32 aY)
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -68,17 +68,16 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessible
   NS_SCRIPTABLE NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode);
   NS_SCRIPTABLE NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
   NS_SCRIPTABLE NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
-  NS_SCRIPTABLE NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   NS_SCRIPTABLE NS_IMETHOD ScrollTo(PRUint32 aScrollType);
   NS_SCRIPTABLE NS_IMETHOD ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY);
   NS_SCRIPTABLE NS_IMETHOD GetLanguage(nsAString& aLanguage);
   NS_IMETHOD GetParent(nsIAccessible **aParent);
   NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
   NS_IMETHOD GetName(nsAString &aName);
   NS_IMETHOD GetValue(nsAString &aValue);
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -224,18 +224,16 @@ const char* const docEvents[] = {
   "mouseover",
 #endif
   // capture Form change events 
   "select",
   // capture ValueChange events (fired whenever value changes, immediately after, whether focus moves or not)
   "ValueChange",
   // capture AlertActive events (fired whenever alert pops up)
   "AlertActive",
-  // add ourself as a TreeViewChanged listener (custom event fired in nsTreeBodyFrame.cpp)
-  "TreeViewChanged",
   "TreeRowCountChanged",
   "TreeInvalidated",
   // add ourself as a OpenStateChange listener (custom event fired in tree.xml)
   "OpenStateChange",
   // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
   "CheckboxStateChange",
   // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp  & radio.xml)
   "RadioStateChange",
@@ -389,21 +387,16 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
 
 #ifdef MOZ_XUL
   nsRefPtr<nsXULTreeAccessible> treeAcc;
   if (targetNode->IsElement() &&
       targetNode->AsElement()->NodeInfo()->Equals(nsGkAtoms::tree,
                                                   kNameSpaceID_XUL)) {
     treeAcc = do_QueryObject(accessible);
     if (treeAcc) {
-      if (eventType.EqualsLiteral("TreeViewChanged")) {
-        treeAcc->TreeViewChanged();
-        return;
-      }
-
       if (eventType.EqualsLiteral("TreeRowCountChanged")) {
         HandleTreeRowCountChangedEvent(aDOMEvent, treeAcc);
         return;
       }
 
       if (eventType.EqualsLiteral("TreeInvalidated")) {
         HandleTreeInvalidatedEvent(aDOMEvent, treeAcc);
         return;
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -113,35 +113,28 @@ nsTextEquivUtils::AppendTextEquivFromCon
                                              nsAString *aString)
 {
   // Prevent recursion which can cause infinite loops.
   if (gInitiatorAcc)
     return NS_OK;
 
   gInitiatorAcc = aInitiatorAcc;
 
-  nsIPresShell* shell = nsCoreUtils::GetPresShellFor(aContent);
-  if (!shell) {
-    NS_ASSERTION(true, "There is no presshell!");
-    gInitiatorAcc = nsnull;
-    return NS_ERROR_UNEXPECTED;
-  }
-
   // If the given content is not visible or isn't accessible then go down
   // through the DOM subtree otherwise go down through accessible subtree and
   // calculate the flat string.
   nsIFrame *frame = aContent->GetPrimaryFrame();
   bool isVisible = frame && frame->GetStyleVisibility()->IsVisible();
 
   nsresult rv = NS_ERROR_FAILURE;
   bool goThroughDOMSubtree = true;
 
   if (isVisible) {
     nsAccessible* accessible =
-      GetAccService()->GetAccessible(aContent, shell);
+      gInitiatorAcc->Document()->GetAccessible(aContent);
     if (accessible) {
       rv = AppendFromAccessible(accessible, aString);
       goThroughDOMSubtree = false;
     }
   }
 
   if (goThroughDOMSubtree)
     rv = AppendFromDOMNode(aContent, aString);
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -352,17 +352,17 @@ GetNativeFromGeckoAccessible(nsIAccessib
 
 - (id <mozAccessible>)parent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if (mParent)
     return mParent;
 
-  nsCOMPtr<nsIAccessible> accessibleParent(mGeckoAccessible->GetUnignoredParent());
+  nsAccessible* accessibleParent = mGeckoAccessible->GetUnignoredParent();
   if (accessibleParent) {
     id nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
     if (nativeParent)
       return mParent = GetClosestInterestingAccessible(nativeParent);
   }
   
   // GetUnignoredParent() returns null when there is no unignored accessible all the way up to
   // the root accessible. so we'll have to return whatever native accessible is above our root accessible 
--- a/accessible/src/mac/nsAccessibleWrap.h
+++ b/accessible/src/mac/nsAccessibleWrap.h
@@ -95,17 +95,17 @@ public: // construction, destruction
   inline bool HasPopup () 
     { return (NativeState() & mozilla::a11y::states::HASPOPUP); }
   
   /**
    * Returns this accessible's all children, adhering to "flat" accessibles by 
    * not returning their children.
    */
   void GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> >& aChildrenArray);
-  virtual already_AddRefed<nsIAccessible> GetUnignoredParent();
+  nsAccessible* GetUnignoredParent() const;
     
 protected:
 
   virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
   /**
    * Return true if the parent doesn't have children to expose to AT.
    */
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -276,31 +276,25 @@ nsAccessibleWrap::GetUnignoredChildren(n
         }
       }
     } else
       // simply add the element, since it's not ignored.
       aChildrenArray.AppendElement(childAcc);
   }
 }
 
-already_AddRefed<nsIAccessible>
-nsAccessibleWrap::GetUnignoredParent()
+nsAccessible*
+nsAccessibleWrap::GetUnignoredParent() const
 {
+  // Go up the chain to find a parent that is not ignored.
   nsAccessibleWrap* parentWrap = static_cast<nsAccessibleWrap*>(Parent());
-  if (!parentWrap)
-    return nsnull;
+  while (parentWrap && parentWrap->IsIgnored()) 
+    parentWrap = static_cast<nsAccessibleWrap*>(parentWrap->Parent());
     
-  // recursively return the parent, until we find one that is not ignored.
-  if (parentWrap->IsIgnored())
-    return parentWrap->GetUnignoredParent();
-  
-  nsIAccessible *outValue = nsnull;
-  NS_IF_ADDREF(outValue = parentWrap);
-  
-  return outValue;
+  return parentWrap;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibleWrap protected
 
 bool
 nsAccessibleWrap::AncestorIsFlat()
 {
--- a/accessible/src/mac/nsRoleMap.h
+++ b/accessible/src/mac/nsRoleMap.h
@@ -37,136 +37,136 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #import <Cocoa/Cocoa.h>
 
 #include "nsIAccessible.h"
 
 static const NSString* AXRoles [] = {
-  NSAccessibilityUnknownRole,                   // ROLE_NOTHING
-  NSAccessibilityUnknownRole,                   // ROLE_TITLEBAR. (irrelevant on OS X; windows are always native.)
-  NSAccessibilityMenuBarRole,                   // ROLE_MENUBAR. (irrelevant on OS X; the menubar will always be native and on the top of the screen.)
-  NSAccessibilityScrollBarRole,                 // ROLE_SCROLLBAR. we might need to make this its own mozAccessible, to support the children objects (valueindicator, down/up buttons).
-  NSAccessibilitySplitterRole,                  // ROLE_GRIP
-  NSAccessibilityUnknownRole,                   // ROLE_SOUND. unused on OS X
-  NSAccessibilityUnknownRole,                   // ROLE_CURSOR. unused on OS X
-  NSAccessibilityUnknownRole,                   // ROLE_CARET. unused on OS X
-  NSAccessibilityWindowRole,                    // ROLE_ALERT
-  NSAccessibilityWindowRole,                    // ROLE_WINDOW. irrelevant on OS X; all window a11y is handled by the system.
-  NSAccessibilityScrollAreaRole,                // ROLE_INTERNAL_FRAME
-  NSAccessibilityMenuRole,                      // ROLE_MENUPOPUP. the parent of menuitems
-  NSAccessibilityMenuItemRole,                  // ROLE_MENUITEM.
-  @"AXHelpTag",                                 // ROLE_TOOLTIP. 10.4+ only, so we re-define the constant.
-  NSAccessibilityGroupRole,                     // ROLE_APPLICATION. unused on OS X. the system will take care of this.
-  @"AXWebArea",                                 // ROLE_DOCUMENT
-  NSAccessibilityGroupRole,                     // ROLE_PANE
-  NSAccessibilityUnknownRole,                   // ROLE_CHART
-  NSAccessibilityWindowRole,                    // ROLE_DIALOG. there's a dialog subrole.
-  NSAccessibilityUnknownRole,                   // ROLE_BORDER. unused on OS X
-  NSAccessibilityGroupRole,                     // ROLE_GROUPING
-  NSAccessibilityUnknownRole,                   // ROLE_SEPARATOR
-  NSAccessibilityToolbarRole,                   // ROLE_TOOLBAR
-  NSAccessibilityUnknownRole,                   // ROLE_STATUSBAR. doesn't exist on OS X (a status bar is its parts; a progressbar, a label, etc.)
-  NSAccessibilityGroupRole,                     // ROLE_TABLE
-  NSAccessibilityGroupRole,                     // ROLE_COLUMNHEADER
-  NSAccessibilityGroupRole,                     // ROLE_ROWHEADER
-  NSAccessibilityColumnRole,                    // ROLE_COLUMN
-  NSAccessibilityRowRole,                       // ROLE_ROW
-  NSAccessibilityGroupRole,                     // ROLE_CELL
-  @"AXLink",                                    // ROLE_LINK. 10.4+ the attr first define in SDK 10.4, so we define it here too. ROLE_LINK
-  @"AXHelpTag",                                 // ROLE_HELPBALLOON
-  NSAccessibilityUnknownRole,                   // ROLE_CHARACTER. unused on OS X
-  NSAccessibilityListRole,                      // ROLE_LIST
-  NSAccessibilityRowRole,                       // ROLE_LISTITEM
-  NSAccessibilityOutlineRole,                   // ROLE_OUTLINE
-  NSAccessibilityRowRole,                       // ROLE_OUTLINEITEM. XXX: use OutlineRow as subrole.
-  NSAccessibilityRadioButtonRole,               // ROLE_PAGETAB
-  NSAccessibilityGroupRole,                     // ROLE_PROPERTYPAGE
-  NSAccessibilityUnknownRole,                   // ROLE_INDICATOR
-  NSAccessibilityImageRole,                     // ROLE_GRAPHIC
-  NSAccessibilityStaticTextRole,                // ROLE_STATICTEXT
-  NSAccessibilityStaticTextRole,                // ROLE_TEXT_LEAF
-  NSAccessibilityButtonRole,                    // ROLE_PUSHBUTTON
-  NSAccessibilityCheckBoxRole,                  // ROLE_CHECKBUTTON
-  NSAccessibilityRadioButtonRole,               // ROLE_RADIOBUTTON
-  NSAccessibilityPopUpButtonRole,               // ROLE_COMBOBOX
-  NSAccessibilityPopUpButtonRole,               // ROLE_DROPLIST.
-  NSAccessibilityProgressIndicatorRole,         // ROLE_PROGRESSBAR
-  NSAccessibilityUnknownRole,                   // ROLE_DIAL
-  NSAccessibilityUnknownRole,                   // ROLE_HOTKEYFIELD
-  NSAccessibilitySliderRole,                    // ROLE_SLIDER
-  NSAccessibilityIncrementorRole,               // ROLE_SPINBUTTON. subroles: Increment/Decrement.
-  NSAccessibilityUnknownRole,                   // ROLE_DIAGRAM
-  NSAccessibilityUnknownRole,                   // ROLE_ANIMATION
-  NSAccessibilityUnknownRole,                   // ROLE_EQUATION
-  NSAccessibilityPopUpButtonRole,               // ROLE_BUTTONDROPDOWN.
-  NSAccessibilityMenuButtonRole,                // ROLE_BUTTONMENU
-  NSAccessibilityGroupRole,                     // ROLE_BUTTONDROPDOWNGRID
-  NSAccessibilityUnknownRole,                   // ROLE_WHITESPACE
-  NSAccessibilityTabGroupRole,                  // ROLE_PAGETABLIST
-  NSAccessibilityUnknownRole,                   // ROLE_CLOCK. unused on OS X
-  NSAccessibilityButtonRole,                    // ROLE_SPLITBUTTON
-  NSAccessibilityUnknownRole,                   // ROLE_IPADDRESS
-  NSAccessibilityStaticTextRole,                // ROLE_ACCEL_LABEL
-  NSAccessibilityUnknownRole,                   // ROLE_ARROW
-  NSAccessibilityImageRole,                     // ROLE_CANVAS
-  NSAccessibilityMenuItemRole,                  // ROLE_CHECK_MENU_ITEM
-  NSAccessibilityColorWellRole,                 // ROLE_COLOR_CHOOSER
-  NSAccessibilityUnknownRole,                   // ROLE_DATE_EDITOR
-  NSAccessibilityImageRole,                     // ROLE_DESKTOP_ICON
-  NSAccessibilityUnknownRole,                   // ROLE_DESKTOP_FRAME
-  NSAccessibilityBrowserRole,                   // ROLE_DIRECTORY_PANE
-  NSAccessibilityUnknownRole,                   // ROLE_FILE_CHOOSER. unused on OS X
-  NSAccessibilityUnknownRole,                   // ROLE_FONT_CHOOSER
-  NSAccessibilityUnknownRole,                   // ROLE_CHROME_WINDOW. unused on OS X
-  NSAccessibilityGroupRole,                     // ROLE_GLASS_PANE
-  NSAccessibilityUnknownRole,                   // ROLE_HTML_CONTAINER
-  NSAccessibilityImageRole,                     // ROLE_ICON
-  NSAccessibilityStaticTextRole,                // ROLE_LABEL
-  NSAccessibilityGroupRole,                     // ROLE_LAYERED_PANE
-  NSAccessibilityGroupRole,                     // ROLE_OPTION_PANE
-  NSAccessibilityTextFieldRole,                 // ROLE_PASSWORD_TEXT
-  NSAccessibilityUnknownRole,                   // ROLE_POPUP_MENU. unused
-  NSAccessibilityMenuItemRole,                  // ROLE_RADIO_MENU_ITEM
-  NSAccessibilityGroupRole,                     // ROLE_ROOT_PANE
-  NSAccessibilityScrollAreaRole,                // ROLE_SCROLL_PANE
-  NSAccessibilitySplitGroupRole,                // ROLE_SPLIT_PANE
-  NSAccessibilityUnknownRole,                   // ROLE_TABLE_COLUMN_HEADER
-  NSAccessibilityUnknownRole,                   // ROLE_TABLE_ROW_HEADER
-  NSAccessibilityMenuItemRole,                  // ROLE_TEAR_OFF_MENU_ITEM
-  NSAccessibilityUnknownRole,                   // ROLE_TERMINAL
-  NSAccessibilityGroupRole,                     // ROLE_TEXT_CONTAINER
-  NSAccessibilityButtonRole,                    // ROLE_TOGGLE_BUTTON
-  NSAccessibilityTableRole,                     // ROLE_TREE_TABLE
-  NSAccessibilityUnknownRole,                   // ROLE_VIEWPORT
-  NSAccessibilityGroupRole,                     // ROLE_HEADER
-  NSAccessibilityGroupRole,                     // ROLE_FOOTER
-  NSAccessibilityGroupRole,                     // ROLE_PARAGRAPH
-  @"AXRuler",                                   // ROLE_RULER. 10.4+ only, so we re-define the constant.
-  NSAccessibilityUnknownRole,                   // ROLE_AUTOCOMPLETE
-  NSAccessibilityTextFieldRole,                 // ROLE_EDITBAR
-  NSAccessibilityTextFieldRole,                 // ROLE_ENTRY
-  NSAccessibilityStaticTextRole,                // ROLE_CAPTION
-  NSAccessibilityScrollAreaRole,                // ROLE_DOCUMENT_FRAME
-  @"AXHeading",                                 // ROLE_HEADING
-  NSAccessibilityGroupRole,                     // ROLE_PAG
-  NSAccessibilityGroupRole,                     // ROLE_SECTION
-  NSAccessibilityUnknownRole,                   // ROLE_REDUNDANT_OBJECT
-  NSAccessibilityGroupRole,                     // ROLE_FORM
-  NSAccessibilityUnknownRole,                   // ROLE_IME
-  NSAccessibilityUnknownRole,                   // ROLE_APP_ROOT. unused on OS X
-  NSAccessibilityMenuItemRole,                  // ROLE_PARENT_MENUITEM
-  NSAccessibilityGroupRole,                     // ROLE_CALENDAR
-  NSAccessibilityMenuRole,                      // ROLE_COMBOBOX_LIST
-  NSAccessibilityMenuItemRole,                  // ROLE_COMBOBOX_OPTION
-  NSAccessibilityImageRole,                     // ROLE_IMAGE_MAP
-  NSAccessibilityRowRole,                       // ROLE_OPTION
-  NSAccessibilityRowRole,                       // ROLE_RICH_OPTION
-  NSAccessibilityListRole,                      // ROLE_LISTBOX
-  NSAccessibilityUnknownRole,                   // ROLE_FLAT_EQUATION
-  NSAccessibilityGroupRole,                     // ROLE_GRID_CELL
-  NSAccessibilityGroupRole,                     // ROLE_EMBEDDED_OBJECT
-  NSAccessibilityGroupRole,                     // ROLE_NOTE
-  NSAccessibilityGroupRole,                     // ROLE_FIGURE
-  NSAccessibilityCheckBoxRole,                  // ROLE_CHECK_RICH_OPTION
-  @"ROLE_LAST_ENTRY"                            // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)!
+  NSAccessibilityUnknownRole,                   // roles::NOTHING              0
+  NSAccessibilityUnknownRole,                   // roles::TITLEBAR             1      Irrelevant on OS X; windows are always native.
+  NSAccessibilityScrollBarRole,                 // roles::SCROLLBAR            3      We might need to make this its own mozAccessible, to support the children objects (valueindicator, down/up buttons).
+  NSAccessibilityMenuBarRole,                   // roles::MENUBAR              2      Irrelevant on OS X; the menubar will always be native and on the top of the screen.
+  NSAccessibilitySplitterRole,                  // roles::GRIP                 4
+  NSAccessibilityUnknownRole,                   // roles::SOUND                5      Unused on OS X.
+  NSAccessibilityUnknownRole,                   // roles::CURSOR               6      Unused on OS X.
+  NSAccessibilityUnknownRole,                   // roles::CARET                7      Unused on OS X.
+  NSAccessibilityWindowRole,                    // roles::ALERT                8
+  NSAccessibilityWindowRole,                    // roles::WINDOW               9      Irrelevant on OS X; all window a11y is handled by the system.
+  NSAccessibilityScrollAreaRole,                // roles::INTERNAL_FRAME       10
+  NSAccessibilityMenuRole,                      // roles::MENUPOPUP            11     The parent of menuitems.
+  NSAccessibilityMenuItemRole,                  // roles::MENUITEM             12
+  @"AXHelpTag",                                 // roles::TOOLTIP              13     10.4+ only, so we re-define the constant.
+  NSAccessibilityGroupRole,                     // roles::APPLICATION          14     Unused on OS X. the system will take care of this.
+  @"AXWebArea",                                 // roles::DOCUMENT             15
+  NSAccessibilityGroupRole,                     // roles::PANE                 16
+  NSAccessibilityUnknownRole,                   // roles::CHART                17
+  NSAccessibilityWindowRole,                    // roles::DIALOG               18     There's a dialog subrole.
+  NSAccessibilityUnknownRole,                   // roles::BORDER               19     Unused on OS X.
+  NSAccessibilityGroupRole,                     // roles::GROUPING             20
+  NSAccessibilityUnknownRole,                   // roles::SEPARATOR            21
+  NSAccessibilityToolbarRole,                   // roles::TOOLBAR              22
+  NSAccessibilityUnknownRole,                   // roles::STATUSBAR            23     Doesn't exist on OS X (a status bar is its parts; a progressbar, a label, etc.)
+  NSAccessibilityGroupRole,                     // roles::TABLE                24
+  NSAccessibilityGroupRole,                     // roles::COLUMNHEADER         25
+  NSAccessibilityGroupRole,                     // roles::ROWHEADER            26
+  NSAccessibilityColumnRole,                    // roles::COLUMN               27
+  NSAccessibilityRowRole,                       // roles::ROW                  28
+  NSAccessibilityGroupRole,                     // roles::CELL                 29
+  @"AXLink",                                    // roles::LINK                 30     10.4+ the attr first define in SDK 10.4, so we define it here too. ROLE_LINK
+  @"AXHelpTag",                                 // roles::HELPBALLOON          31
+  NSAccessibilityUnknownRole,                   // roles::CHARACTER            32     Unused on OS X.
+  NSAccessibilityListRole,                      // roles::LIST                 33
+  NSAccessibilityRowRole,                       // roles::LISTITEM             34
+  NSAccessibilityOutlineRole,                   // roles::OUTLINE              35
+  NSAccessibilityRowRole,                       // roles::OUTLINEITEM          36     XXX: use OutlineRow as subrole.
+  NSAccessibilityRadioButtonRole,               // roles::PAGETAB              37
+  NSAccessibilityGroupRole,                     // roles::PROPERTYPAGE         38
+  NSAccessibilityUnknownRole,                   // roles::INDICATOR            39
+  NSAccessibilityImageRole,                     // roles::GRAPHIC              40
+  NSAccessibilityStaticTextRole,                // roles::STATICTEXT           41
+  NSAccessibilityStaticTextRole,                // roles::TEXT_LEAF            42
+  NSAccessibilityButtonRole,                    // roles::PUSHBUTTON           43
+  NSAccessibilityCheckBoxRole,                  // roles::CHECKBUTTON          44
+  NSAccessibilityRadioButtonRole,               // roles::RADIOBUTTON          45
+  NSAccessibilityPopUpButtonRole,               // roles::COMBOBOX             46
+  NSAccessibilityPopUpButtonRole,               // roles::DROPLIST             47
+  NSAccessibilityProgressIndicatorRole,         // roles::PROGRESSBAR          48
+  NSAccessibilityUnknownRole,                   // roles::DIAL                 49
+  NSAccessibilityUnknownRole,                   // roles::HOTKEYFIELD          50
+  NSAccessibilitySliderRole,                    // roles::SLIDER               51
+  NSAccessibilityIncrementorRole,               // roles::SPINBUTTON           52     Subroles: Increment/Decrement.
+  NSAccessibilityUnknownRole,                   // roles::DIAGRAM              53
+  NSAccessibilityUnknownRole,                   // roles::ANIMATION            54
+  NSAccessibilityUnknownRole,                   // roles::EQUATION             55
+  NSAccessibilityPopUpButtonRole,               // roles::BUTTONDROPDOWN       56
+  NSAccessibilityMenuButtonRole,                // roles::BUTTONMENU           57
+  NSAccessibilityGroupRole,                     // roles::BUTTONDROPDOWNGRID   58
+  NSAccessibilityUnknownRole,                   // roles::WHITESPACE           59
+  NSAccessibilityTabGroupRole,                  // roles::PAGETABLIST          60
+  NSAccessibilityUnknownRole,                   // roles::CLOCK                61     Unused on OS X
+  NSAccessibilityButtonRole,                    // roles::SPLITBUTTON          62
+  NSAccessibilityUnknownRole,                   // roles::IPADDRESS            63
+  NSAccessibilityStaticTextRole,                // roles::ACCEL_LABEL          64
+  NSAccessibilityUnknownRole,                   // roles::ARROW                65
+  NSAccessibilityImageRole,                     // roles::CANVAS               66
+  NSAccessibilityMenuItemRole,                  // roles::CHECK_MENU_ITEM      67
+  NSAccessibilityColorWellRole,                 // roles::COLOR_CHOOSER        68
+  NSAccessibilityUnknownRole,                   // roles::DATE_EDITOR          69 
+  NSAccessibilityImageRole,                     // roles::DESKTOP_ICON         70
+  NSAccessibilityUnknownRole,                   // roles::DESKTOP_FRAME        71
+  NSAccessibilityBrowserRole,                   // roles::DIRECTORY_PANE       72
+  NSAccessibilityUnknownRole,                   // roles::FILE_CHOOSER         73     Unused on OS X
+  NSAccessibilityUnknownRole,                   // roles::FONT_CHOOSER         74
+  NSAccessibilityUnknownRole,                   // roles::CHROME_WINDOW        75     Unused on OS X
+  NSAccessibilityGroupRole,                     // roles::GLASS_PANE           76
+  NSAccessibilityUnknownRole,                   // roles::HTML_CONTAINER       77
+  NSAccessibilityImageRole,                     // roles::ICON                 78
+  NSAccessibilityStaticTextRole,                // roles::LABEL                79
+  NSAccessibilityGroupRole,                     // roles::LAYERED_PANE         80
+  NSAccessibilityGroupRole,                     // roles::OPTION_PANE          81
+  NSAccessibilityTextFieldRole,                 // roles::PASSWORD_TEXT        82
+  NSAccessibilityUnknownRole,                   // roles::POPUP_MENU           83     Unused
+  NSAccessibilityMenuItemRole,                  // roles::RADIO_MENU_ITEM      84
+  NSAccessibilityGroupRole,                     // roles::ROOT_PANE            85
+  NSAccessibilityScrollAreaRole,                // roles::SCROLL_PANE          86
+  NSAccessibilitySplitGroupRole,                // roles::SPLIT_PANE           87
+  NSAccessibilityUnknownRole,                   // roles::TABLE_COLUMN_HEADER  88
+  NSAccessibilityUnknownRole,                   // roles::TABLE_ROW_HEADER     89
+  NSAccessibilityMenuItemRole,                  // roles::TEAR_OFF_MENU_ITEM   90
+  NSAccessibilityUnknownRole,                   // roles::TERMINAL             91
+  NSAccessibilityGroupRole,                     // roles::TEXT_CONTAINER       92
+  NSAccessibilityButtonRole,                    // roles::TOGGLE_BUTTON        93
+  NSAccessibilityTableRole,                     // roles::TREE_TABLE           94
+  NSAccessibilityUnknownRole,                   // roles::VIEWPORT             95
+  NSAccessibilityGroupRole,                     // roles::HEADER               96
+  NSAccessibilityGroupRole,                     // roles::FOOTER               97
+  NSAccessibilityGroupRole,                     // roles::PARAGRAPH            98
+  @"AXRuler",                                   // roles::RULER                99     10.4+ only, so we re-define the constant.
+  NSAccessibilityComboBoxRole,                  // roles::AUTOCOMPLETE         100
+  NSAccessibilityTextFieldRole,                 // roles::EDITBAR              101
+  NSAccessibilityTextFieldRole,                 // roles::ENTRY                102
+  NSAccessibilityStaticTextRole,                // roles::CAPTION              103
+  NSAccessibilityScrollAreaRole,                // roles::DOCUMENT_FRAME       104
+  @"AXHeading",                                 // roles::HEADING              105
+  NSAccessibilityGroupRole,                     // roles::PAGE                 106
+  NSAccessibilityGroupRole,                     // roles::SECTION              107
+  NSAccessibilityUnknownRole,                   // roles::REDUNDANT_OBJECT     108
+  NSAccessibilityGroupRole,                     // roles::FORM                 109
+  NSAccessibilityUnknownRole,                   // roles::IME                  110
+  NSAccessibilityUnknownRole,                   // roles::APP_ROOT             111    Unused on OS X
+  NSAccessibilityMenuItemRole,                  // roles::PARENT_MENUITEM      112
+  NSAccessibilityGroupRole,                     // roles::CALENDAR             113
+  NSAccessibilityMenuRole,                      // roles::COMBOBOX_LIST        114
+  NSAccessibilityMenuItemRole,                  // roles::COMBOBOX_OPTION      115
+  NSAccessibilityImageRole,                     // roles::IMAGE_MAP            116
+  NSAccessibilityRowRole,                       // roles::OPTION               117
+  NSAccessibilityRowRole,                       // roles::RICH_OPTION          118
+  NSAccessibilityListRole,                      // roles::LISTBOX              119
+  NSAccessibilityUnknownRole,                   // roles::FLAT_EQUATION        120
+  NSAccessibilityGroupRole,                     // roles::GRID_CELL            121
+  NSAccessibilityGroupRole,                     // roles::EMBEDDED_OBJECT      122
+  NSAccessibilityGroupRole,                     // roles::NOTE                 123
+  NSAccessibilityGroupRole,                     // roles::FIGURE               124
+  NSAccessibilityCheckBoxRole,                  // roles::CHECK_RICH_OPTION    125
+  @"ROLE_LAST_ENTRY"                            // roles::LAST_ENTRY                  Bogus role that will never be shown (just marks the end of this array)!
 };
--- a/accessible/src/msaa/CAccessibleHyperlink.cpp
+++ b/accessible/src/msaa/CAccessibleHyperlink.cpp
@@ -59,17 +59,17 @@ CAccessibleHyperlink::QueryInterface(REF
     if (!thisObj->IsLink())
       return E_NOINTERFACE;
 
     *ppv = static_cast<IAccessibleHyperlink*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
-  return CAccessibleAction::QueryInterface(iid, ppv);
+  return ia2AccessibleAction::QueryInterface(iid, ppv);
 }
 
 // IAccessibleHyperlink
 
 STDMETHODIMP
 CAccessibleHyperlink::get_anchor(long aIndex, VARIANT *aAnchor)
 {
 __try {
--- a/accessible/src/msaa/CAccessibleHyperlink.h
+++ b/accessible/src/msaa/CAccessibleHyperlink.h
@@ -38,29 +38,29 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _ACCESSIBLE_HYPERLINK_H
 #define _ACCESSIBLE_HYPERLINK_H
 
 #include "nsISupports.h"
 
-#include "CAccessibleAction.h"
+#include "ia2AccessibleAction.h"
 #include "AccessibleHyperlink.h"
 
-class CAccessibleHyperlink: public CAccessibleAction,
+class CAccessibleHyperlink: public ia2AccessibleAction,
                             public IAccessibleHyperlink
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleAction
-  FORWARD_IACCESSIBLEACTION(CAccessibleAction)
+  FORWARD_IACCESSIBLEACTION(ia2AccessibleAction)
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_anchor(
       /* [in] */ long index,
       /* [retval][out] */ VARIANT *anchor);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_anchorTarget(
       /* [in] */ long index,
       /* [retval][out] */ VARIANT *anchorTarget);
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -58,17 +58,17 @@ CPPSRCS = \
   nsXULMenuAccessibleWrap.cpp \
   nsXULListboxAccessibleWrap.cpp \
   nsXULTreeGridAccessibleWrap.cpp \
   nsHyperTextAccessibleWrap.cpp \
   nsHTMLImageAccessibleWrap.cpp \
   nsHTMLTableAccessibleWrap.cpp \
   nsApplicationAccessibleWrap.cpp \
   nsWinUtils.cpp \
-  CAccessibleAction.cpp \
+  ia2AccessibleAction.cpp \
   CAccessibleImage.cpp \
   CAccessibleComponent.cpp \
   CAccessibleText.cpp \
   CAccessibleEditableText.cpp \
   CAccessibleHyperlink.cpp \
   CAccessibleHypertext.cpp \
   ia2AccessibleRelation.cpp \
   CAccessibleTable.cpp \
@@ -87,17 +87,17 @@ EXPORTS = \
   nsARIAGridAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
   nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   nsApplicationAccessibleWrap.h \
-  CAccessibleAction.h \
+  ia2AccessibleAction.h \
   CAccessibleImage.h \
   CAccessibleComponent.h \
   CAccessibleText.h \
   CAccessibleEditableText.h \
   CAccessibleHyperlink.h \
   CAccessibleHypertext.h \
   CAccessibleTable.h \
   CAccessibleTableCell.h \
rename from accessible/src/msaa/CAccessibleAction.cpp
rename to accessible/src/msaa/ia2AccessibleAction.cpp
--- a/accessible/src/msaa/CAccessibleAction.cpp
+++ b/accessible/src/msaa/ia2AccessibleAction.cpp
@@ -33,84 +33,84 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "CAccessibleAction.h"
+#include "ia2AccessibleAction.h"
 
 #include "AccessibleAction_i.c"
 
-#include "nsAccessible.h"
+#include "nsAccessibleWrap.h"
 
 // IUnknown
 
 STDMETHODIMP
-CAccessibleAction::QueryInterface(REFIID iid, void** ppv)
+ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleAction == iid) {
     *ppv = static_cast<IAccessibleAction*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
 }
 
 // IAccessibleAction
 
 STDMETHODIMP
-CAccessibleAction::nActions(long* aActionCount)
+ia2AccessibleAction::nActions(long* aActionCount)
 {
 __try {
   if (!aActionCount)
     return E_INVALIDARG;
 
   *aActionCount = 0;
 
-  nsRefPtr<nsAccessible> acc(do_QueryObject(this));
-  if (!acc || acc->IsDefunct())
+  nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
+  if (acc->IsDefunct())
     return E_FAIL;
 
   *aActionCount = acc->ActionCount();
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleAction::doAction(long aActionIndex)
+ia2AccessibleAction::doAction(long aActionIndex)
 {
 __try {
-  nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
-  if (!acc)
+  nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
+  if (acc->IsDefunct())
     return E_FAIL;
 
   PRUint8 index = static_cast<PRUint8>(aActionIndex);
   nsresult rv = acc->DoAction(index);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
+ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
 {
 __try {
   *aDescription = NULL;
 
-  nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
-  if (!acc)
+  nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
+  if (acc->IsDefunct())
     return E_FAIL;
 
   nsAutoString description;
   PRUint8 index = static_cast<PRUint8>(aActionIndex);
   nsresult rv = acc->GetActionDescription(index, description);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
@@ -121,34 +121,34 @@ CAccessibleAction::get_description(long 
                                       description.Length());
   return *aDescription ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
+ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
                                   BSTR **aKeyBinding,
                                   long *aNumBinding)
 {
 __try {
   if (!aKeyBinding)
     return E_INVALIDARG;
   *aKeyBinding = NULL;
 
   if (!aNumBinding)
     return E_INVALIDARG;
   *aNumBinding = 0;
 
   if (aActionIndex != 0 || aNumMaxBinding < 1)
     return E_INVALIDARG;
 
-  nsRefPtr<nsAccessible> acc(do_QueryObject(this));
-  if (!acc || acc->IsDefunct())
+  nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
+  if (acc->IsDefunct())
     return E_FAIL;
 
   // Expose keyboard shortcut if it's not exposed via MSAA keyboard shortcut.
   KeyBinding keyBinding = acc->AccessKey();
   if (keyBinding.IsEmpty())
     return S_FALSE;
 
   keyBinding = acc->KeyboardShortcut();
@@ -171,23 +171,23 @@ CAccessibleAction::get_keyBinding(long a
   *aNumBinding = 1;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleAction::get_name(long aActionIndex, BSTR *aName)
+ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName)
 {
 __try {
   *aName = NULL;
 
-  nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
-  if (!acc)
+  nsAccessibleWrap* acc = static_cast<nsAccessibleWrap*>(this);
+  if (acc->IsDefunct())
     return E_FAIL;
 
   nsAutoString name;
   PRUint8 index = static_cast<PRUint8>(aActionIndex);
   nsresult rv = acc->GetActionName(index, name);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
@@ -197,17 +197,17 @@ CAccessibleAction::get_name(long aAction
   *aName = ::SysAllocStringLen(name.get(), name.Length());
   return *aName ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
+ia2AccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
 {
 __try {
   *aLocalizedName = NULL;
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return E_NOTIMPL;
 }
 
rename from accessible/src/msaa/CAccessibleAction.h
rename to accessible/src/msaa/ia2AccessibleAction.h
--- a/accessible/src/msaa/CAccessibleAction.h
+++ b/accessible/src/msaa/ia2AccessibleAction.h
@@ -40,17 +40,17 @@
 
 #ifndef _ACCESSIBLE_ACTION_H
 #define _ACCESSIBLE_ACTION_H
 
 #include "nsISupports.h"
 
 #include "AccessibleAction.h"
 
-class CAccessibleAction: public IAccessibleAction
+class ia2AccessibleAction: public IAccessibleAction
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleAction
   virtual HRESULT STDMETHODCALLTYPE nActions(
@@ -72,19 +72,16 @@ public:
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_name(
       /* [in] */ long actionIndex,
       /* [retval][out] */ BSTR *name);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_localizedName(
       /* [in] */ long actionIndex,
       /* [retval][out] */ BSTR *localizedName);
 
-  // nsISupports
-  NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
-
 };
 
 
 #define FORWARD_IACCESSIBLEACTION(Class)                                       \
 virtual HRESULT STDMETHODCALLTYPE nActions(long *nActions)                     \
 {                                                                              \
   return Class::nActions(nActions);                                            \
 }                                                                              \
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -683,33 +683,33 @@ nsXULTreeAccessible::TreeViewInvalidated
       NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!");
 
       treeitemAcc->RowInvalidated(aStartCol, endCol);
     }
   }
 }
 
 void
-nsXULTreeAccessible::TreeViewChanged()
+nsXULTreeAccessible::TreeViewChanged(nsITreeView* aView)
 {
   if (IsDefunct())
     return;
 
   // Fire reorder event on tree accessible on accessible tree (do not fire
   // show/hide events on tree items because it can be expensive to fire them for
   // each tree item.
   nsRefPtr<AccEvent> reorderEvent =
     new AccEvent(nsIAccessibleEvent::EVENT_REORDER, this, eAutoDetect,
                  AccEvent::eCoalesceFromSameSubtree);
   if (reorderEvent)
     Document()->FireDelayedAccessibleEvent(reorderEvent);
 
   // Clear cache.
   ClearCache(mAccessibleCache);
-  mTree->GetView(getter_AddRefs(mTreeView));
+  mTreeView = aView;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: protected implementation
 
 already_AddRefed<nsAccessible>
 nsXULTreeAccessible::CreateTreeItemAccessible(PRInt32 aRow)
 {
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -141,17 +141,17 @@ public:
    *                    index
    */
   void TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
                            PRInt32 aStartCol, PRInt32 aEndCol);
 
   /**
    * Invalidates children created for previous tree view.
    */
-  void TreeViewChanged();
+  void TreeViewChanged(nsITreeView* aView);
 
 protected:
   /**
    * Creates tree item accessible for the given row index.
    */
   virtual already_AddRefed<nsAccessible> CreateTreeItemAccessible(PRInt32 aRow);
 
   nsCOMPtr<nsITreeBoxObject> mTree;
--- a/accessible/tests/mochitest/events/test_tree.xul
+++ b/accessible/tests/mochitest/events/test_tree.xul
@@ -1,20 +1,15 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
-<!--
-  Bug 368835 - fire TreeViewChanged/TreeRowCountChanged events.
-  Bug 308564 - no accessibility events when data in a tree row changes.
--->
-
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        title="DOM TreeViewChanged/TreeRowCountChanged and a11y name change events.">
+        title="DOM TreeRowCountChanged and a11y name change events.">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 
   <script type="application/javascript"
           src="../treeview.js" />
 
   <script type="application/javascript"
@@ -24,30 +19,16 @@
 
   <script type="application/javascript">
   <![CDATA[
 
     ////////////////////////////////////////////////////////////////////////////
     // Invoker's checkers
 
     /**
-     * Check TreeViewChanged event and run through accessible tree to ensure
-     * it's created.
-     */
-    function treeViewChangedChecker(aMsg)
-    {
-      this.type = "TreeViewChanged";
-      this.target = gTree;
-      this.getID = function getID()
-      {
-        return "TreeViewChanged";
-      }
-    }
-
-    /**
      * Check TreeRowCountChanged event.
      */
     function rowCountChangedChecker(aMsg, aIdx, aCount)
     {
       this.type = "TreeRowCountChanged";
       this.target = gTree;
       this.check = function check(aEvent)
       {
@@ -115,29 +96,28 @@
         return aMsg + "name changed";
       }
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
 
     /**
-     * Set tree view and process TreeViewChanged handler.
+     * Set tree view.
      */
     function setTreeView()
     {
       this.invoke = function setTreeView_invoke()
       {
         gTreeBox.view = gView;
       }
 
       this.getID = function setTreeView_getID() { return "set tree view"; }
 
       this.eventSeq = [
-        new treeViewChangedChecker(),
         new invokerChecker(EVENT_REORDER, gTree)
       ];
     };
 
     /**
      * Insert row at 0 index and checks TreeRowCountChanged and TreeInvalidated
      * event.
      */
@@ -293,16 +273,21 @@
          title="Fire TreeViewChanged/TreeRowCountChanged events.">
         Mozilla Bug 368835
       </a><br/>
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=308564"
          title="No accessibility events when data in a tree row changes.">
         Mozilla Bug 308564
       </a>
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=739524"
+         title="replace TreeViewChanged DOM event on direct call from XUL tree.">
+        Mozilla Bug 739524
+      </a>
       <p id="display"></p>
       <div id="content" style="display: none">
       </div>
       <pre id="test">
       </pre>
     </body>
 
     <vbox id="debug"/>
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -301,20 +301,39 @@ var shell = {
           screen.mozEnabled = false;
         }
       } else {
         screen.mozEnabled = true;
       }
     }
   }
   let idleTimeout = Services.prefs.getIntPref("power.screen.timeout");
-  if (idleTimeout) {
-    Services.idle.addIdleObserver(idleHandler, idleTimeout);
-    power.addWakeLockListener(wakeLockHandler);
+  let request = navigator.mozSettings.getLock().get("power.screen.timeout");
+  request.onsuccess = function onSuccess() {
+    idleTimeout = request.result["power.screen.timeout"] || idleTimeout;
+    if (idleTimeout) {
+      Services.idle.addIdleObserver(idleHandler, idleTimeout);
+      power.addWakeLockListener(wakeLockHandler);
+    }
   }
+  request.onerror = function onError() {
+    if (idleTimeout) {
+      Services.idle.addIdleObserver(idleHandler, idleTimeout);
+      power.addWakeLockListener(wakeLockHandler);
+    }
+  }
+  // XXX We may override other's callback here, but this is the only
+  // user of mozSettings in shell.js at this moment.
+  navigator.mozSettings.onsettingchange = function onSettingChange(e) {
+    if (e.settingName == "power.screen.timeout" && e.settingValue) {
+      Services.idle.removeIdleObserver(idleHandler, idleTimeout);
+      idleTimeout = e.settingValue;
+      Services.idle.addIdleObserver(idleHandler, idleTimeout);
+    }
+  };
 })();
 
 function nsBrowserAccess() {
 }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow]),
 
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -173,36 +173,20 @@ enum {
   NODE_HAS_ACCESSKEY           = 0x00020000U,
 
   // Set if the node is handling a click.
   NODE_HANDLING_CLICK          = 0x00040000U,
 
   // Set if the node has had :hover selectors matched against it
   NODE_HAS_RELEVANT_HOVER_RULES = 0x00080000U,
 
-  // Two bits for the script-type ID.  Not enough to represent all
-  // nsIProgrammingLanguage values, but we don't care.  In practice,
-  // we can represent the ones we want, and we can fail the others at
-  // runtime.
-  NODE_SCRIPT_TYPE_OFFSET =               20,
-
-  NODE_SCRIPT_TYPE_SIZE =                  2,
-
-  NODE_SCRIPT_TYPE_MASK =  (1 << NODE_SCRIPT_TYPE_SIZE) - 1,
-
   // Remaining bits are node type specific.
-  NODE_TYPE_SPECIFIC_BITS_OFFSET =
-    NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE
+  NODE_TYPE_SPECIFIC_BITS_OFFSET =        20
 };
 
-PR_STATIC_ASSERT(PRUint32(nsIProgrammingLanguage::JAVASCRIPT) <=
-                   PRUint32(NODE_SCRIPT_TYPE_MASK));
-PR_STATIC_ASSERT(PRUint32(nsIProgrammingLanguage::PYTHON) <=
-                   PRUint32(NODE_SCRIPT_TYPE_MASK));
-
 // Useful inline function for getting a node given an nsIContent and an
 // nsIDocument.  Returns the first argument cast to nsINode if it is non-null,
 // otherwise returns the second (which may be null).  We use type variables
 // instead of nsIContent* and nsIDocument* because the actual types must be
 // known for the cast to work.
 template<class C, class D>
 inline nsINode* NODE_FROM(C& aContent, D& aDocument)
 {
@@ -286,18 +270,18 @@ private:
 // Categories of node properties
 // 0 is global.
 #define DOM_USER_DATA         1
 #define DOM_USER_DATA_HANDLER 2
 #define SMIL_MAPPED_ATTR_ANIMVAL 3
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0x458300ed, 0xe418, 0x4577, \
-  { 0x89, 0xd7, 0xfe, 0xf1, 0x34, 0xf3, 0x52, 0x19 } }
+{ 0x772e7e52, 0xfadf, 0x4962, \
+  { 0x8d, 0x96, 0x58, 0xfe, 0x75, 0x68, 0xaf, 0xa8 } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsIDOMEventTarget,
                 public nsWrapperCache
@@ -1038,32 +1022,16 @@ public:
   }
 
   /**
    * Implementation is in nsIDocument.h, because it needs to cast from
    * nsIDocument* to nsINode*.
    */
   nsIDocument* GetOwnerDocument() const;
 
-  /**
-   * The default script type (language) ID for this node.
-   * All nodes must support fetching the default script language.
-   */
-  virtual PRUint32 GetScriptTypeID() const
-  { return nsIProgrammingLanguage::JAVASCRIPT; }
-
-  /**
-   * Not all nodes support setting a new default language.
-   */
-  NS_IMETHOD SetScriptTypeID(PRUint32 aLang)
-  {
-    NS_NOTREACHED("SetScriptTypeID not implemented");
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
   nsresult Normalize();
 
   /**
    * Get the base URI for any relative URIs within this piece of
    * content. Generally, this is the document's base URI, but certain
    * content carries a local base for backward compatibility, and XML
    * supports setting a per-node base URI.
    *
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3099,32 +3099,16 @@ nsDocument::SetHeaderData(nsIAtom* aHead
       *lastPtr = new nsDocHeaderData(aHeaderField, aData);
     }
   }
 
   if (aHeaderField == nsGkAtoms::headerContentLanguage) {
     CopyUTF16toUTF8(aData, mContentLanguage);
   }
 
-  // Set the default script-type on the root element.
-  if (aHeaderField == nsGkAtoms::headerContentScriptType) {
-    Element *root = GetRootElement();
-    if (root) {
-      // Get the script-type ID for this value.
-      nsresult rv;
-      nsCOMPtr<nsIScriptRuntime> runtime;
-      rv = NS_GetScriptRuntime(aData, getter_AddRefs(runtime));
-      if (NS_FAILED(rv) || runtime == nsnull) {
-        NS_WARNING("The script-type is unknown");
-      } else {
-        root->SetScriptTypeID(runtime->GetScriptTypeID());
-      }
-    }
-  }
-
   if (aHeaderField == nsGkAtoms::headerDefaultStyle) {
     // Only mess with our stylesheets if we don't have a lastStyleSheetSet, per
     // spec.
     if (DOMStringIsNull(mLastStyleSheetSet)) {
       // Calling EnableStyleSheetsForSetInternal, not SetSelectedStyleSheetSet,
       // per spec.  The idea here is that we're changing our preferred set and
       // that shouldn't change the value of lastStyleSheetSet.  Also, we're
       // using the Internal version so we can update the CSSLoader and not have
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -504,18 +504,16 @@ class nsDocument : public nsIDocument,
 {
 public:
   typedef mozilla::dom::Element Element;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
-  using nsINode::GetScriptTypeID;
-
   virtual void Reset(nsIChannel *aChannel, nsILoadGroup *aLoadGroup);
   virtual void ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
                           nsIPrincipal* aPrincipal);
 
   // StartDocumentLoad is pure virtual so that subclasses must override it.
   // The nsDocument StartDocumentLoad does some setup, but does NOT set
   // *aDocListener; this is the job of subclasses.
   virtual nsresult StartDocumentLoad(const char* aCommand,
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2495,19 +2495,16 @@ nsGenericElement::nsGenericElement(alrea
 {
   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE ||
                     (mNodeInfo->NodeType() ==
                        nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
                      mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
                                        kNameSpaceID_None)),
                     "Bad NodeType in aNodeInfo");
 
-  // Set the default scriptID to JS - but skip SetScriptTypeID as it
-  // does extra work we know isn't necessary here...
-  SetFlags((nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET));
   SetIsElement();
 }
 
 nsGenericElement::~nsGenericElement()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
   if (GetParent()) {
@@ -3719,40 +3716,16 @@ nsGenericElement::GetBindingParent() con
 }
 
 bool
 nsGenericElement::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~eCONTENT);
 }
 
-//----------------------------------------------------------------------
-
-PRUint32
-nsGenericElement::GetScriptTypeID() const
-{
-    PtrBits flags = GetFlags();
-
-    return (flags >> NODE_SCRIPT_TYPE_OFFSET) & NODE_SCRIPT_TYPE_MASK;
-}
-
-NS_IMETHODIMP
-nsGenericElement::SetScriptTypeID(PRUint32 aLang)
-{
-    if ((aLang & NODE_SCRIPT_TYPE_MASK) != aLang) {
-        NS_ERROR("script ID too large!");
-        return NS_ERROR_FAILURE;
-    }
-    /* SetFlags will just mask in the specific flags set, leaving existing
-       ones alone.  So we must clear all the bits first */
-    UnsetFlags(NODE_SCRIPT_TYPE_MASK << NODE_SCRIPT_TYPE_OFFSET);
-    SetFlags(aLang << NODE_SCRIPT_TYPE_OFFSET);
-    return NS_OK;
-}
-
 nsresult
 nsGenericElement::InsertChildAt(nsIContent* aKid,
                                 PRUint32 aIndex,
                                 bool aNotify)
 {
   NS_PRECONDITION(aKid, "null ptr");
 
   return doInsertChildAt(aKid, aIndex, aNotify, mAttrsAndChildren);
@@ -5157,19 +5130,18 @@ nsGenericElement::AddScriptEventListener
   bool defer = true;
   nsEventListenerManager* manager = GetEventListenerManagerForAttr(aEventName,
                                                                    &defer);
   if (!manager) {
     return NS_OK;
   }
 
   defer = defer && aDefer; // only defer if everyone agrees...
-  PRUint32 lang = GetScriptTypeID();
-  manager->AddScriptEventListener(aEventName, aValue, lang, defer,
-                                  !nsContentUtils::IsChromeDoc(ownerDoc));
+  manager->AddScriptEventListener(aEventName, aValue, nsIProgrammingLanguage::JAVASCRIPT,
+                                  defer, !nsContentUtils::IsChromeDoc(ownerDoc));
   return NS_OK;
 }
 
 
 //----------------------------------------------------------------------
 
 const nsAttrName*
 nsGenericElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -338,19 +338,16 @@ public:
   virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
                               bool aNotify);
   virtual bool TextIsOnlyWhitespace();
   virtual void AppendTextTo(nsAString& aResult);
   virtual nsIContent *GetBindingParent() const;
   virtual bool IsNodeOfType(PRUint32 aFlags) const;
   virtual bool IsLink(nsIURI** aURI) const;
 
-  virtual PRUint32 GetScriptTypeID() const;
-  NS_IMETHOD SetScriptTypeID(PRUint32 aLang);
-
   virtual void DestroyContent();
   virtual void SaveSubtreeState();
 
   virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
   {
     return nsnull;
   }
   virtual nsIDOMCSSStyleDeclaration* GetSMILOverrideStyle();
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -43,16 +43,17 @@
 #include "nscore.h"
 #include "nsRange.h"
 
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentFragment.h"
+#include "nsIDOMDocumentType.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMText.h"
 #include "nsDOMError.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMNodeList.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
@@ -1521,16 +1522,36 @@ nsresult nsRange::CutContents(nsIDOMDocu
   // Save the range end points locally to avoid interference
   // of Range gravity during our edits!
 
   nsCOMPtr<nsIDOMNode> startContainer = do_QueryInterface(mStartParent);
   PRInt32              startOffset = mStartOffset;
   nsCOMPtr<nsIDOMNode> endContainer = do_QueryInterface(mEndParent);
   PRInt32              endOffset = mEndOffset;
 
+  if (retval) {
+    // For extractContents(), abort early if there's a doctype (bug 719533).
+    // This can happen only if the common ancestor is a document, in which case
+    // we just need to find its doctype child and check if that's in the range.
+    nsCOMPtr<nsIDOMDocument> commonAncestorDocument(do_QueryInterface(commonAncestor));
+    if (commonAncestorDocument) {
+      nsCOMPtr<nsIDOMDocumentType> doctype;
+      rv = commonAncestorDocument->GetDoctype(getter_AddRefs(doctype));
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      if (doctype &&
+          nsContentUtils::ComparePoints(startContainer, startOffset,
+                                        doctype.get(), 0) < 0 &&
+          nsContentUtils::ComparePoints(doctype.get(), 0,
+                                        endContainer, endOffset) < 0) {
+        return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+      }
+    }
+  }
+
   // Create and initialize a subtree iterator that will give
   // us all the subtrees within the range.
 
   RangeSubtreeIterator iter;
 
   rv = iter.Init(this);
   if (NS_FAILED(rv)) return rv;
 
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -424,18 +424,17 @@ nsScriptLoader::ProcessScriptElement(nsI
   if (!context || !context->GetScriptsEnabled()) {
     return false;
   }
 
   // Default script language is whatever the root element specifies
   // (which may come from a header or http-meta tag), or if there
   // is no root element, from the script global object.
   Element* rootElement = mDocument->GetRootElement();
-  PRUint32 typeID = rootElement ? rootElement->GetScriptTypeID() :
-                                  context->GetScriptTypeID();
+  PRUint32 typeID = nsIProgrammingLanguage::JAVASCRIPT;
   PRUint32 version = 0;
   nsAutoString language, type, src;
   nsresult rv = NS_OK;
 
   // Check the type attribute to determine language and version.
   // If type exists, it trumps the deprecated 'language='
   aElement->GetScriptType(type);
   if (!type.IsEmpty()) {
@@ -471,17 +470,17 @@ nsScriptLoader::ProcessScriptElement(nsI
       // Use the object factory to locate a matching language.
       nsCOMPtr<nsIScriptRuntime> runtime;
       rv = NS_GetScriptRuntime(mimeType, getter_AddRefs(runtime));
       if (NS_FAILED(rv) || runtime == nsnull) {
         // Failed to get the explicitly specified language
         NS_WARNING("Failed to find a scripting language");
         typeID = nsIProgrammingLanguage::UNKNOWN;
       } else
-        typeID = runtime->GetScriptTypeID();
+        typeID = nsIProgrammingLanguage::JAVASCRIPT;
     }
     if (typeID != nsIProgrammingLanguage::UNKNOWN) {
       // Get the version string, and ensure the language supports it.
       nsAutoString versionName;
       rv = parser.GetParameter("version", versionName);
       if (NS_FAILED(rv)) {
         // no version attribute - version remains 0.
         if (rv != NS_ERROR_INVALID_ARG)
@@ -551,18 +550,16 @@ nsScriptLoader::ProcessScriptElement(nsI
   // this isn't a priority.!
   // See also similar code in nsXULContentSink.cpp
   if (typeID != nsIProgrammingLanguage::JAVASCRIPT &&
       !nsContentUtils::IsChromeDoc(mDocument)) {
     NS_WARNING("Untrusted language called from non-chrome - ignored");
     return false;
   }
 
-  scriptContent->SetScriptTypeID(typeID);
-
   // Step 14. in the HTML5 spec
 
   nsRefPtr<nsScriptLoadRequest> request;
   if (aElement->GetScriptExternal()) {
     // external script
     nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
     if (!scriptURI) {
       return false;
@@ -881,18 +878,17 @@ nsScriptLoader::EvaluateScript(nsScriptL
   if (!pwin || !pwin->IsInnerWindow()) {
     return NS_ERROR_FAILURE;
   }
   nsCOMPtr<nsIScriptGlobalObject> globalObject = do_QueryInterface(pwin);
   NS_ASSERTION(globalObject, "windows must be global objects");
 
   // Get the script-type to be used by this element.
   NS_ASSERTION(scriptContent, "no content - what is default script-type?");
-  PRUint32 stid = scriptContent ? scriptContent->GetScriptTypeID() :
-                                  nsIProgrammingLanguage::JAVASCRIPT;
+
   // and make sure we are setup for this type of script.
   rv = globalObject->EnsureScriptEnvironment();
   if (NS_FAILED(rv))
     return rv;
 
   // Make sure context is a strong reference since we access it after
   // we've executed a script, which may cause all other references to
   // the context to go away.
@@ -920,30 +916,19 @@ nsScriptLoader::EvaluateScript(nsScriptL
                                url.get(), aRequest->mLineNo,
                                JSVersion(aRequest->mJSVersion), nsnull,
                                &isUndefined);
 
   // Put the old script back in case it wants to do anything else.
   mCurrentScript = oldCurrent;
 
   JSContext *cx = nsnull; // Initialize this to keep GCC happy.
-  if (stid == nsIProgrammingLanguage::JAVASCRIPT) {
-    cx = context->GetNativeContext();
-    ::JS_BeginRequest(cx);
-    NS_ASSERTION(!::JS_IsExceptionPending(cx),
-                 "JS_ReportPendingException wasn't called in EvaluateString");
-  }
-
+  cx = context->GetNativeContext();
+  JSAutoRequest ar(cx);
   context->SetProcessingScriptTag(oldProcessingScriptTag);
-
-  if (stid == nsIProgrammingLanguage::JAVASCRIPT) {
-    NS_ASSERTION(!::JS_IsExceptionPending(cx),
-                 "JS_ReportPendingException wasn't called");
-    ::JS_EndRequest(cx);
-  }
   return rv;
 }
 
 void
 nsScriptLoader::ProcessPendingRequestsAsync()
 {
   if (mParserBlockingRequest || !mPendingChildLoaders.IsEmpty()) {
     nsCOMPtr<nsIRunnable> ev = NS_NewRunnableMethod(this,
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -574,16 +574,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug738108.html \
 		test_bug366944.html \
 		test_bug650386_redirect_301.html \
 		test_bug650386_redirect_302.html \
 		test_bug650386_redirect_303.html \
 		test_bug650386_redirect_307.html \
 		file_bug650386_content.sjs \
 		file_bug650386_report.sjs \
+		test_bug719533.html \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug719533.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=719544
+-->
+<title>Test for Bug 719544</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=719544">Mozilla Bug 719544</a>
+<script>
+
+/** Test for Bug 719544 **/
+var threw = false;
+var origLength = document.childNodes.length;
+try {
+  var range = document.createRange();
+  range.selectNodeContents(document);
+  range.extractContents();
+} catch(e) {
+  threw = true;
+  is(Object.getPrototypeOf(e), DOMException.prototype,
+     "Must throw DOMException");
+  is(e.name, "HierarchyRequestError", "Must throw HierarchyRequestError");
+}
+ok(threw, "Must throw");
+is(document.childNodes.length, origLength, "Must preserve original children");
+
+</script>
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -1042,21 +1042,16 @@ nsEventListenerManager::GetJSEventListen
 
   *vp = JSVAL_NULL;
 
   if (!ls) {
     return;
   }
 
   nsIJSEventListener *listener = ls->GetJSListener();
-  if (listener->GetEventContext()->GetScriptTypeID() !=
-        nsIProgrammingLanguage::JAVASCRIPT) {
-    // Not JS, so no point doing anything with it.
-    return;
-  }
     
   if (ls->mHandlerIsString) {
     CompileEventHandlerInternal(ls, true, nsnull);
   }
 
   *vp = OBJECT_TO_JSVAL(listener->GetHandler());
 }
 
--- a/content/media/nsMediaCache.cpp
+++ b/content/media/nsMediaCache.cpp
@@ -143,18 +143,20 @@ public:
 #endif
   {
     MOZ_COUNT_CTOR(nsMediaCache);
   }
   ~nsMediaCache() {
     NS_ASSERTION(mStreams.IsEmpty(), "Stream(s) still open!");
     Truncate();
     NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?");
-    mFileCache->Close();
-    mFileCache = nsnull;
+    if (mFileCache) {
+      mFileCache->Close();
+      mFileCache = nsnull;
+    }
     MOZ_COUNT_DTOR(nsMediaCache);
   }
 
   // Main thread only. Creates the backing cache file. If this fails,
   // then the cache is still in a semi-valid state; mFD will be null,
   // so all I/O on the cache file will fail.
   nsresult Init();
   // Shut down the global cache if it's no longer needed. We shut down
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -266,19 +266,16 @@ XBL_ProtoErrorReporter(JSContext *cx,
 
 void
 nsXBLDocGlobalObject::SetContext(nsIScriptContext *aScriptContext)
 {
   if (!aScriptContext) {
     mScriptContext = nsnull;
     return;
   }
-  NS_ASSERTION(aScriptContext->GetScriptTypeID() ==
-                                        nsIProgrammingLanguage::JAVASCRIPT,
-               "xbl is not multi-language");
   aScriptContext->WillInitializeContext();
   // NOTE: We init this context with a NULL global, so we automatically
   // hook up to the existing nsIScriptGlobalObject global setup by
   // nsGlobalWindow.
   DebugOnly<nsresult> rv;
   rv = aScriptContext->InitContext();
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Script Language's InitContext failed");
   aScriptContext->SetGCOnDestruction(false);
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -283,20 +283,16 @@ nsXULElement::Create(nsXULPrototypeEleme
         }
         if (aPrototype->mHasClassAttribute) {
             element->SetFlags(NODE_MAY_HAVE_CLASS);
         }
         if (aPrototype->mHasStyleAttribute) {
             element->SetMayHaveStyle();
         }
 
-        NS_ASSERTION(aPrototype->mScriptTypeID != nsIProgrammingLanguage::UNKNOWN,
-                    "Need to know the language!");
-        element->SetScriptTypeID(aPrototype->mScriptTypeID);
-
         if (aIsScriptable) {
             // Check each attribute on the prototype to see if we need to do
             // any additional processing and hookup that would otherwise be
             // done 'automagically' by SetAttr().
             for (PRUint32 i = 0; i < aPrototype->mNumAttributes; ++i) {
                 element->AddListenerFor(aPrototype->mAttributes[i].mName,
                                         true);
             }
@@ -413,27 +409,22 @@ nsresult
 nsXULElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
     *aResult = nsnull;
 
     // If we have a prototype, so will our clone.
     nsRefPtr<nsXULElement> element;
     if (mPrototype) {
         element = nsXULElement::Create(mPrototype, aNodeInfo, true);
-        NS_ASSERTION(GetScriptTypeID() == mPrototype->mScriptTypeID,
+        NS_ASSERTION(nsIProgrammingLanguage::JAVASCRIPT == mPrototype->mScriptTypeID,
                      "Didn't get the default language from proto?");
     }
     else {
         nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
         element = new nsXULElement(ni.forget());
-        if (element) {
-        	// If created from a prototype, we will already have the script
-        	// language specified by the proto - otherwise copy it directly
-        	element->SetScriptTypeID(GetScriptTypeID());
-        }
     }
 
     if (!element) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     // XXX TODO: set up RDF generic builder n' stuff if there is a
     // 'datasources' attribute? This is really kind of tricky,
@@ -1097,23 +1088,23 @@ nsXULElement::AfterSetAttr(PRInt32 aName
 {
     if (aNamespaceID == kNameSpaceID_None) {
         // XXX UnsetAttr handles more attributes than we do. See bug 233642.
 
         // Add popup and event listeners. We can't call AddListenerFor since
         // the attribute isn't set yet.
         MaybeAddPopupListener(aName);
         if (nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL) && aValue) {
-            // If mPrototype->mScriptTypeID != GetScriptTypeID(), it means
+            // If mPrototype->mScriptTypeID != nsIProgrammingLanguage::JAVASCRIPT, it means
             // we are resolving an overlay with a different default script
             // language.  We can't defer compilation of those handlers as
             // we will have lost the script language (storing it on each
             // nsXULPrototypeAttribute is expensive!)
             bool defer = mPrototype == nsnull ||
-                           mPrototype->mScriptTypeID == GetScriptTypeID();
+                           mPrototype->mScriptTypeID == nsIProgrammingLanguage::JAVASCRIPT;
             if (aValue->Type() == nsAttrValue::eString) {
                 AddScriptEventListener(aName, aValue->GetStringValue(), defer);
             } else {
                 nsAutoString body;
                 aValue->ToString(body);
                 AddScriptEventListener(aName, body, defer);
             }
         }
@@ -2513,17 +2504,17 @@ nsXULElement::RecompileScriptEventListen
         GetAttr(kNameSpaceID_None, attr, value);
         AddScriptEventListener(attr, value, true);
     }
 
     if (mPrototype) {
         // If we have a prototype, the node we are binding to should
         // have the same script-type - otherwise we will compile the
         // event handlers incorrectly.
-        NS_ASSERTION(mPrototype->mScriptTypeID == GetScriptTypeID(),
+        NS_ASSERTION(mPrototype->mScriptTypeID == nsIProgrammingLanguage::JAVASCRIPT,
                      "Prototype and node confused about default language?");
 
         count = mPrototype->mNumAttributes;
         for (i = 0; i < count; ++i) {
             const nsAttrName &name = mPrototype->mAttributes[i].mName;
 
             // Eventlistenener-attributes are always in the null namespace
             if (!name.IsAtom()) {
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -798,17 +798,17 @@ XULContentSinkImpl::SetElementScriptType
     for (i=0;i<aAttrLen;i++) {
         const nsDependentString key(aAttributes[i*2]);
         if (key.EqualsLiteral("script-type")) {
             const nsDependentString value(aAttributes[i*2+1]);
             if (!value.IsEmpty()) {
                 nsCOMPtr<nsIScriptRuntime> runtime;
                 rv = NS_GetScriptRuntime(value, getter_AddRefs(runtime));
                 if (NS_SUCCEEDED(rv))
-                    element->mScriptTypeID = runtime->GetScriptTypeID();
+                    element->mScriptTypeID = nsIProgrammingLanguage::JAVASCRIPT;
                 else {
                     // probably just a bad language name (typo, etc)
                     NS_WARNING("Failed to load the node's script language!");
                     // Leave the default language as unknown - we don't want js
                     // trying to execute this stuff.
                     NS_ASSERTION(element->mScriptTypeID == nsIProgrammingLanguage::UNKNOWN,
                                  "Default script type should be unknown");
                 }
@@ -1025,17 +1025,17 @@ XULContentSinkImpl::OpenScript(const PRU
               // Use the script object factory to locate the language.
               nsCOMPtr<nsIScriptRuntime> runtime;
               rv = NS_GetScriptRuntime(mimeType, getter_AddRefs(runtime));
               if (NS_FAILED(rv) || runtime == nsnull) {
                   // Failed to get the explicitly specified language
                   NS_WARNING("Failed to find a scripting language");
                   langID = nsIProgrammingLanguage::UNKNOWN;
               } else
-                  langID = runtime->GetScriptTypeID();
+                  langID = nsIProgrammingLanguage::JAVASCRIPT;
           }
 
           if (langID != nsIProgrammingLanguage::UNKNOWN) {
             // Get the version string, and ensure the language supports it.
             nsAutoString versionName;
             rv = parser.GetParameter("version", versionName);
             if (NS_FAILED(rv)) {
               if (rv != NS_ERROR_INVALID_ARG)
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -754,20 +754,16 @@ nsXULDocument::SynchronizeBroadcastListe
         mDelayedBroadcasters.AppendElement(delayedUpdate);
         MaybeBroadcast();
         return;
     }
     nsCOMPtr<nsIContent> broadcaster = do_QueryInterface(aBroadcaster);
     nsCOMPtr<nsIContent> listener = do_QueryInterface(aListener);
     bool notify = mDocumentLoaded || mHandlingDelayedBroadcasters;
 
-    // We may be copying event handlers etc, so we must also copy
-    // the script-type to the listener.
-    listener->SetScriptTypeID(broadcaster->GetScriptTypeID());
-
     if (aAttr.EqualsLiteral("*")) {
         PRUint32 count = broadcaster->GetAttrCount();
         nsTArray<nsAttrNameInfo> attributes(count);
         for (PRUint32 i = 0; i < count; ++i) {
             const nsAttrName* attrName = broadcaster->GetAttrNameAt(i);
             PRInt32 nameSpaceID = attrName->NamespaceID();
             nsIAtom* name = attrName->LocalName();
 
@@ -3630,18 +3626,16 @@ nsresult
 nsXULDocument::ExecuteScript(nsIScriptContext * aContext, JSScript* aScriptObject)
 {
     NS_PRECONDITION(aScriptObject != nsnull && aContext != nsnull, "null ptr");
     if (! aScriptObject || ! aContext)
         return NS_ERROR_NULL_POINTER;
 
     NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
 
-    NS_ABORT_IF_FALSE(aContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT,
-                      "Should have a JavaScript nsIScriptContext.");
     // Execute the precompiled script with the given version
     JSObject* global = mScriptGlobalObject->GetGlobalJSObject();
     return aContext->ExecuteScript(aScriptObject, global, nsnull, nsnull);
 }
 
 nsresult
 nsXULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
 {
@@ -3941,24 +3935,17 @@ nsXULDocument::OverlayForwardReference::
         // with the same id in the base document.
         target = mDocument->GetElementById(id);
 
         // If we can't find the element in the document, defer the hookup
         // until later.
         if (!target)
             return eResolve_Later;
 
-        // While merging, set the default script language of the element to be
-        // the language from the overlay - attributes will then be correctly
-        // hooked up with the appropriate language (while child nodes ignore
-        // the default language - they have it in their proto.
-        PRUint32 oldDefLang = target->GetScriptTypeID();
-        target->SetScriptTypeID(mOverlay->GetScriptTypeID());
         rv = Merge(target, mOverlay, notify);
-        target->SetScriptTypeID(oldDefLang);
         if (NS_FAILED(rv)) return eResolve_Error;
     }
 
     // Check if 'target' is still in our document --- it might not be!
     if (!notify && target->GetCurrentDoc() == mDocument) {
         // Add child and any descendants to the element map
         // XXX this is bogus, the content in 'target' might already be
         // in the document
--- a/dom/base/nsDOMScriptObjectFactory.cpp
+++ b/dom/base/nsDOMScriptObjectFactory.cpp
@@ -154,17 +154,17 @@ nsDOMScriptObjectFactory::GetScriptRunti
   if (NS_FAILED(rv)) {
     if (aLanguageName.Equals(NS_LITERAL_STRING("application/javascript")))
       return GetScriptRuntimeByID(nsIProgrammingLanguage::JAVASCRIPT, aLanguage);
     // Not JS and nothing else we know about.
     NS_WARNING("No script language registered for this mime-type");
     return NS_ERROR_FACTORY_NOT_REGISTERED;
   }
   // And stash it away in our array for fast lookup by ID.
-  PRUint32 lang_ndx = NS_STID_INDEX(lang->GetScriptTypeID());
+  PRUint32 lang_ndx = NS_STID_INDEX(nsIProgrammingLanguage::JAVASCRIPT);
   if (mLanguageArray[lang_ndx] == nsnull) {
     mLanguageArray[lang_ndx] = lang;
   } else {
     // All languages are services - we should have an identical object!
     NS_ASSERTION(mLanguageArray[lang_ndx] == lang,
                  "Got a different language for this ID???");
   }
   *aLanguage = lang;
@@ -208,17 +208,17 @@ nsDOMScriptObjectFactory::GetIDForScript
                                              PRUint32 *aScriptTypeID)
 {
   nsCOMPtr<nsIScriptRuntime> languageRuntime;
   nsresult rv;
   rv = GetScriptRuntime(aLanguageName, getter_AddRefs(languageRuntime));
   if (NS_FAILED(rv))
     return rv;
 
-  *aScriptTypeID = languageRuntime->GetScriptTypeID();
+  *aScriptTypeID = nsIProgrammingLanguage::JAVASCRIPT;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMScriptObjectFactory::NewScriptGlobalObject(bool aIsChrome,
                                                 bool aIsModalContentWindow,
                                                 nsIScriptGlobalObject **aGlobal)
 {
--- a/dom/base/nsDOMScriptObjectHolder.h
+++ b/dom/base/nsDOMScriptObjectHolder.h
@@ -118,16 +118,16 @@ public:
                  "Must have identical languages!");
     nsresult rv = drop();
     if (NS_FAILED(rv))
       return rv;
     return set(other.mObject);
   }
   // Get the language ID.
   PRUint32 getScriptTypeID() const {
-    return mContext->GetScriptTypeID();
+    return nsIProgrammingLanguage::JAVASCRIPT;
   }
 protected:
   T* mObject;
   nsCOMPtr<nsIScriptContext> mContext;
 };
 
 #endif // nsDOMScriptObjectHolder_h__
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9259,18 +9259,17 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
       continue;
     }
 
     // The timeout is on the list to run at this depth, go ahead and
     // process it.
 
     // Get the script context (a strong ref to prevent it going away)
     // for this timeout and ensure the script language is enabled.
-    nsCOMPtr<nsIScriptContext> scx = GetScriptContextInternal(
-                                timeout->mScriptHandler->GetScriptTypeID());
+    nsCOMPtr<nsIScriptContext> scx = GetContextInternal();
 
     if (!scx) {
       // No context means this window was closed or never properly
       // initialized for this language.
       continue;
     }
 
     // The "scripts disabled" concept is still a little vague wrt
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -71,35 +71,32 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0xdfaea249, 0xaaad, 0x48bd, \
-  { 0xb8, 0x04, 0x92, 0xad, 0x30, 0x88, 0xd0, 0xc6 } }
+{ 0xf1c8c13e, 0xc23b, 0x434e, \
+  { 0xa4, 0x77, 0xe0, 0x2f, 0xc3, 0x73, 0xf8, 0x71 } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
  */
 class nsIScriptContext : public nsIScriptContextPrincipal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTCONTEXT_IID)
 
-  /* Get the ID of this language. */
-  virtual PRUint32 GetScriptTypeID() = 0;
-
   virtual void SetGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0;
 
   /**
    * Compile and execute a script.
    *
    * @param aScript a string representing the script to be executed
    * @param aScopeObject a script object for the scope to execute in, or
    *                     nsnull to use a default scope
--- a/dom/base/nsIScriptRuntime.h
+++ b/dom/base/nsIScriptRuntime.h
@@ -35,32 +35,28 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsIScriptRuntime_h__
 #define nsIScriptRuntime_h__
 
 #include "nsIScriptContext.h"
 
 #define NS_ISCRIPTRUNTIME_IID \
-{ 0x2c8d774e, 0xb52a, 0x43ec, \
-  { 0x8e, 0xbc, 0x82, 0x75, 0xb9, 0x34, 0x20, 0x57 } }
+{ 0xb146580f, 0x55f7, 0x4d97, \
+  { 0x8a, 0xbb, 0x4a, 0x50, 0xb0, 0xa8, 0x04, 0x97 } }
 
 /**
  * A singleton language environment for an application.  Responsible for
  * initializing and cleaning up the global language environment, and a factory
  * for language contexts
  */
 class nsIScriptRuntime : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTRUNTIME_IID)
-  /*
-   * Return the language ID of this script language
-   */
-  virtual PRUint32 GetScriptTypeID() = 0;
 
   /* Parses a "version string" for the language into a bit-mask used by
    * the language implementation.  If the specified version is not supported
    * an error should be returned.  If the specified version is blank, a default
    * version should be assumed
    */
   virtual nsresult ParseVersion(const nsString &aVersionStr, PRUint32 *verFlags) = 0;
   
--- a/dom/base/nsIScriptTimeoutHandler.h
+++ b/dom/base/nsIScriptTimeoutHandler.h
@@ -37,32 +37,29 @@
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsIScriptTimeoutHandler_h___
 #define nsIScriptTimeoutHandler_h___
 
 class nsIArray;
 
 #define NS_ISCRIPTTIMEOUTHANDLER_IID \
-{ 0xd60ec934, 0x0c75, 0x4777, \
-  { 0xba, 0x41, 0xb8, 0x2f, 0x37, 0xc9, 0x13, 0x56 } }
+{ 0xcaf520a5, 0x8078, 0x4cba, \
+  { 0x8a, 0xb9, 0xb6, 0x8a, 0x12, 0x43, 0x4f, 0x05 } }
 
 /**
  * Abstraction of the script objects etc required to do timeouts in a
  * language agnostic way.
  */
 
 class nsIScriptTimeoutHandler : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTTIMEOUTHANDLER_IID)
 
-  // Get the script-type (language) implementing this timeout.
-  virtual PRUint32 GetScriptTypeID() = 0;
-
   // Get a script object for the language suitable for passing back to
   // the language's context as an event handler.  If this returns nsnull,
   // GetHandlerText() will be called to get the string.
   virtual JSObject *GetScriptObject() = 0;
 
   // Get the handler text of not a compiled object.
   virtual const PRUnichar *GetHandlerText() = 0;
 
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -69,19 +69,16 @@ public:
   virtual ~nsJSContext();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSContext,
                                                          nsIScriptContext)
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal();
 
-  virtual PRUint32 GetScriptTypeID()
-    { return nsIProgrammingLanguage::JAVASCRIPT; }
-
   virtual void SetGlobalObject(nsIScriptGlobalObject* aGlobalObject)
   {
     mGlobalObjectRef = aGlobalObject;
   }
 
   virtual nsresult EvaluateString(const nsAString& aScript,
                                   JSObject* aScopeObject,
                                   nsIPrincipal *principal,
@@ -324,20 +321,16 @@ class nsJSRuntime : public nsIScriptRunt
 public:
   // let people who can see us use our runtime for convenience.
   static JSRuntime *sRuntime;
 
 public:
   // nsISupports
   NS_DECL_ISUPPORTS
 
-  virtual PRUint32 GetScriptTypeID() {
-    return nsIProgrammingLanguage::JAVASCRIPT;
-  }
-
   virtual already_AddRefed<nsIScriptContext> CreateContext();
 
   virtual nsresult ParseVersion(const nsString &aVersionStr, PRUint32 *flags);
 
   virtual nsresult DropScriptObject(void *object);
   virtual nsresult HoldScriptObject(void *object);
   
   static void Startup();
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -71,20 +71,16 @@ public:
   virtual JSObject *GetScriptObject() {
     return mFunObj;
   }
   virtual void GetLocation(const char **aFileName, PRUint32 *aLineNo) {
     *aFileName = mFileName.get();
     *aLineNo = mLineNo;
   }
 
-  virtual PRUint32 GetScriptTypeID() {
-        return nsIProgrammingLanguage::JAVASCRIPT;
-  }
-
   virtual nsIArray *GetArgv() {
     return mArgv;
   }
 
   nsresult Init(nsGlobalWindow *aWindow, bool *aIsInterval,
                 PRInt32 *aInterval);
 
   void ReleaseJSObjects();
--- a/dom/src/events/nsJSEventListener.cpp
+++ b/dom/src/events/nsJSEventListener.cpp
@@ -105,19 +105,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSEventListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSEventListener)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(tmp->mContext->GetScriptTypeID(),
+  NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT,
                                                  mScopeObject)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(tmp->mContext->GetScriptTypeID(),
+  NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT,
                                                  mHandler)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsJSEventListener)
   return tmp->IsBlackForCC();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsJSEventListener)
@@ -135,18 +135,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSEventListener)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSEventListener)
 
 bool
 nsJSEventListener::IsBlackForCC()
 {
-  if ((mContext && mContext->GetScriptTypeID() ==
-         nsIProgrammingLanguage::JAVASCRIPT) &&
+  if (mContext &&
       (!mScopeObject || !xpc_IsGrayGCThing(mScopeObject)) &&
       (!mHandler || !xpc_IsGrayGCThing(mHandler))) {
     nsIScriptGlobalObject* sgo =
       static_cast<nsJSContext*>(mContext.get())->GetCachedGlobalObject();
     return sgo && sgo->IsBlackForCC();
   }
   return false;
 }
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -72,29 +72,34 @@ BoxBlurHorizontal(unsigned char* aInput,
                   int32_t aRows,
                   const IntRect& aSkipRect)
 {
     MOZ_ASSERT(aWidth > 0);
 
     int32_t boxSize = aLeftLobe + aRightLobe + 1;
     bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
                                   aWidth <= aSkipRect.XMost();
+    if (boxSize == 1) {
+        memcpy(aOutput, aInput, aWidth*aRows);
+        return;
+    }
+    PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
 
     for (int32_t y = 0; y < aRows; y++) {
         // Check whether the skip rect intersects this row. If the skip
         // rect covers the whole surface in this row, we can avoid
         // this row entirely (and any others along the skip rect).
         bool inSkipRectY = y >= aSkipRect.y &&
                            y < aSkipRect.YMost();
         if (inSkipRectY && skipRectCoversWholeRow) {
             y = aSkipRect.YMost() - 1;
             continue;
         }
 
-        int32_t alphaSum = 0;
+        uint32_t alphaSum = 0;
         for (int32_t i = 0; i < boxSize; i++) {
             int32_t pos = i - aLeftLobe;
             // See assertion above; if aWidth is zero, then we would have no
             // valid position to clamp to.
             pos = max(pos, 0);
             pos = min(pos, aWidth - 1);
             alphaSum += aInput[aWidth * y + pos];
         }
@@ -118,17 +123,17 @@ BoxBlurHorizontal(unsigned char* aInput,
                     pos = min(pos, aWidth - 1);
                     alphaSum += aInput[aWidth * y + pos];
                 }
             }
             int32_t tmp = x - aLeftLobe;
             int32_t last = max(tmp, 0);
             int32_t next = min(tmp + boxSize, aWidth - 1);
 
-            aOutput[aWidth * y + x] = alphaSum / boxSize;
+            aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
 
             alphaSum += aInput[aWidth * y + next] -
                         aInput[aWidth * y + last];
         }
     }
 }
 
 /**
@@ -145,26 +150,31 @@ BoxBlurVertical(unsigned char* aInput,
                 int32_t aRows,
                 const IntRect& aSkipRect)
 {
     MOZ_ASSERT(aRows > 0);
 
     int32_t boxSize = aTopLobe + aBottomLobe + 1;
     bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
                                      aRows <= aSkipRect.YMost();
+    if (boxSize == 1) {
+        memcpy(aOutput, aInput, aWidth*aRows);
+        return;
+    }
+    PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
 
     for (int32_t x = 0; x < aWidth; x++) {
         bool inSkipRectX = x >= aSkipRect.x &&
                            x < aSkipRect.XMost();
         if (inSkipRectX && skipRectCoversWholeColumn) {
             x = aSkipRect.XMost() - 1;
             continue;
         }
 
-        int32_t alphaSum = 0;
+        uint32_t alphaSum = 0;
         for (int32_t i = 0; i < boxSize; i++) {
             int32_t pos = i - aTopLobe;
             // See assertion above; if aRows is zero, then we would have no
             // valid position to clamp to.
             pos = max(pos, 0);
             pos = min(pos, aRows - 1);
             alphaSum += aInput[aWidth * pos + x];
         }
@@ -184,17 +194,17 @@ BoxBlurVertical(unsigned char* aInput,
                     pos = min(pos, aRows - 1);
                     alphaSum += aInput[aWidth * pos + x];
                 }
             }
             int32_t tmp = y - aTopLobe;
             int32_t last = max(tmp, 0);
             int32_t next = min(tmp + boxSize, aRows - 1);
 
-            aOutput[aWidth * y + x] = alphaSum/boxSize;
+            aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
 
             alphaSum += aInput[aWidth * next + x] -
                         aInput[aWidth * last + x];
         }
     }
 }
 
 static void ComputeLobes(int32_t aRadius, int32_t aLobes[3][2])
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -875,33 +875,31 @@ RasterImage::GetFrame(PRUint32 aWhichFra
     return NS_ERROR_FAILURE;
 
   // Disallowed in the API
   if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
     return NS_ERROR_FAILURE;
 
   nsresult rv = NS_OK;
 
-  if (mDecoded) {
-    // If we have decoded data, and it is not a perfect match for what we are
-    // looking for, we must discard to be able to generate the proper data.
-    PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
-    if (desiredDecodeFlags != mFrameDecodeFlags) {
-      // if we can't discard, then we're screwed; we have no way
-      // to re-decode.  Similarly if we aren't allowed to do a sync
-      // decode.
-      if (!(aFlags & FLAG_SYNC_DECODE))
-        return NS_ERROR_NOT_AVAILABLE;
-      if (!CanForciblyDiscard() || mDecoder || mAnim)
-        return NS_ERROR_NOT_AVAILABLE;
-  
-      ForceDiscard();
-  
-      mFrameDecodeFlags = desiredDecodeFlags;
-    }
+  // If we have decoded data, and it is not a perfect match for what we are
+  // looking for, we must discard to be able to generate the proper data.
+  PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
+  if (desiredDecodeFlags != mFrameDecodeFlags) {
+    // if we can't discard, then we're screwed; we have no way
+    // to re-decode.  Similarly if we aren't allowed to do a sync
+    // decode.
+    if (!(aFlags & FLAG_SYNC_DECODE))
+      return NS_ERROR_NOT_AVAILABLE;
+    if (!CanForciblyDiscard() || mDecoder || mAnim)
+      return NS_ERROR_NOT_AVAILABLE;
+
+    ForceDiscard();
+
+    mFrameDecodeFlags = desiredDecodeFlags;
   }
 
   // If the caller requested a synchronous decode, do it
   if (aFlags & FLAG_SYNC_DECODE) {
     rv = SyncDecode();
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Debugger-wrap-01.js
@@ -0,0 +1,34 @@
+// Debugger.prototype.wrap creates only one Debugger.Object instance for each debuggee object.
+var g = newGlobal('new-compartment');
+var dbg = new Debugger(g);
+
+g.eval("var x = { 'now playing': 'Joy Division' };");
+g.eval("var y = { 'mood': 'bleak' };");
+
+wx = dbg.wrap(g.x);
+assertEq(wx, dbg.wrap(g.x));
+assertEq(wx === g.x, false);
+assertEq("now playing" in wx, false);
+assertEq(wx.getOwnPropertyNames().indexOf("now playing"), 0);
+wx.commentary = "deconstruction";
+assertEq("deconstruction" in g.x, false);
+
+wy = dbg.wrap(g.y);
+assertEq(wy === wx, false);
+wy.commentary = "reconstruction";
+assertEq(wx.commentary, "deconstruction");
+
+// Separate debuggers get separate wrappers, but they both view the same underlying object.
+var dbg2 = new Debugger(g);
+w2x = dbg2.wrap(g.x);
+assertEq(wx === w2x, false);
+w2x.defineProperty("breadcrumb", { value: "pumpernickel" });
+assertEq(wx.getOwnPropertyDescriptor("breadcrumb").value, "pumpernickel");
+
+// Trying to wrap things that aren't objects should pass them through unchanged.
+assertEq(dbg.wrap("foonting turlingdromes"), "foonting turlingdromes");
+assertEq(dbg.wrap(true), true);
+assertEq(dbg.wrap(false), false);
+assertEq(dbg.wrap(null), null);
+assertEq(dbg.wrap(1729), 1729);
+assertEq(dbg.wrap(undefined), undefined);
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -183,28 +183,28 @@ ScriptAnalysis::analyzeBytecode(JSContex
      */
 
     PodZero(escapedSlots, numSlots);
 
     if (script->usesEval || script->mayNeedArgsObj() || script->compartment()->debugMode()) {
         for (unsigned i = 0; i < nargs; i++)
             escapedSlots[ArgSlot(i)] = true;
     } else {
-        for (unsigned i = 0; i < script->nClosedArgs; i++) {
+        for (uint32_t i = 0; i < script->nClosedArgs(); i++) {
             unsigned arg = script->getClosedArg(i);
             JS_ASSERT(arg < nargs);
             escapedSlots[ArgSlot(arg)] = true;
         }
     }
 
     if (script->usesEval || script->compartment()->debugMode()) {
         for (unsigned i = 0; i < script->nfixed; i++)
             escapedSlots[LocalSlot(script, i)] = true;
     } else {
-        for (uint32_t i = 0; i < script->nClosedVars; i++) {
+        for (uint32_t i = 0; i < script->nClosedVars(); i++) {
             unsigned local = script->getClosedVar(i);
             JS_ASSERT(local < script->nfixed);
             escapedSlots[LocalSlot(script, local)] = true;
         }
     }
 
     /*
      * If the script is in debug mode, JS_SetFrameReturnValue can be called at
@@ -213,23 +213,23 @@ ScriptAnalysis::analyzeBytecode(JSContex
     if (cx->compartment->debugMode())
         usesReturnValue_ = true;
 
     bool heavyweight = script->function() && script->function()->isHeavyweight();
 
     isCompileable = true;
 
     isInlineable = true;
-    if (script->nClosedArgs || script->nClosedVars || heavyweight ||
+    if (script->nClosedArgs() || script->nClosedVars() || heavyweight ||
         script->usesEval || script->mayNeedArgsObj() || cx->compartment->debugMode()) {
         isInlineable = false;
     }
 
     modifiesArguments_ = false;
-    if (script->nClosedArgs || heavyweight)
+    if (script->nClosedArgs() || heavyweight)
         modifiesArguments_ = true;
 
     canTrackVars = true;
 
     /*
      * If we are in the middle of one or more jumps, the offset of the highest
      * target jumping over this bytecode.  Includes implicit jumps from
      * try/catch/finally blocks.
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -759,17 +759,17 @@ JSRuntime::JSRuntime()
     gcSliceCallback(NULL),
     gcFinalizeCallback(NULL),
     gcMallocBytes(0),
     gcBlackRootsTraceOp(NULL),
     gcBlackRootsData(NULL),
     gcGrayRootsTraceOp(NULL),
     gcGrayRootsData(NULL),
     autoGCRooters(NULL),
-    scriptPCCounters(NULL),
+    scriptAndCountsVector(NULL),
     NaNValue(UndefinedValue()),
     negativeInfinityValue(UndefinedValue()),
     positiveInfinityValue(UndefinedValue()),
     emptyString(NULL),
     debugMode(false),
     profilingScripts(false),
     hadOutOfMemory(false),
     data(NULL),
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -99,19 +99,16 @@ namespace js {
 
 namespace mjit {
 class JaegerCompartment;
 }
 
 class WeakMapBase;
 class InterpreterFrames;
 
-class ScriptOpcodeCounts;
-struct ScriptOpcodeCountsPair;
-
 /*
  * GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
  * given pc in a script. We use the script->code pointer to tag the cache,
  * instead of the script address itself, so that source notes are always found
  * by offset from the bytecode with which they were generated.
  */
 struct GSNCache {
     typedef HashMap<jsbytecode *,
@@ -130,17 +127,17 @@ struct GSNCache {
 inline GSNCache *
 GetGSNCache(JSContext *cx);
 
 struct PendingProxyOperation {
     PendingProxyOperation   *next;
     JSObject                *object;
 };
 
-typedef Vector<ScriptOpcodeCountsPair, 0, SystemAllocPolicy> ScriptOpcodeCountsVector;
+typedef Vector<ScriptAndCounts, 0, SystemAllocPolicy> ScriptAndCountsVector;
 
 struct ConservativeGCData
 {
     /*
      * The GC scans conservatively between ThreadData::nativeStackBase and
      * nativeStackTop unless the latter is NULL.
      */
     uintptr_t           *nativeStackTop;
@@ -458,17 +455,17 @@ struct JSRuntime : js::RuntimeFriendFiel
     void                *gcBlackRootsData;
     JSTraceDataOp       gcGrayRootsTraceOp;
     void                *gcGrayRootsData;
 
     /* Stack of thread-stack-allocated GC roots. */
     js::AutoGCRooter   *autoGCRooters;
 
     /* Strong references on scripts held for PCCount profiling API. */
-    js::ScriptOpcodeCountsVector *scriptPCCounters;
+    js::ScriptAndCountsVector *scriptAndCountsVector;
 
     /* Well-known numbers held for use by this runtime's contexts. */
     js::Value           NaNValue;
     js::Value           negativeInfinityValue;
     js::Value           positiveInfinityValue;
 
     JSAtom              *emptyString;
 
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -1593,17 +1593,17 @@ JS_DumpBytecode(JSContext *cx, JSScript 
     fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename, script->lineno);
 #endif
 }
 
 extern JS_PUBLIC_API(void)
 JS_DumpPCCounts(JSContext *cx, JSScript *script)
 {
 #if defined(DEBUG)
-    JS_ASSERT(script->pcCounters);
+    JS_ASSERT(script->scriptCounts);
 
     Sprinter sprinter(cx);
     if (!sprinter.init())
         return;
 
     fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename, script->lineno);
     js_DumpPCCounts(cx, script, &sprinter);
     fputs(sprinter.string(), stdout);
@@ -1636,17 +1636,17 @@ JS_DumpCompartmentBytecode(JSContext *cx
         JS_DumpBytecode(cx, scripts[i]);
 }
 
 JS_PUBLIC_API(void)
 JS_DumpCompartmentPCCounts(JSContext *cx)
 {
     for (CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
-        if (script->pcCounters)
+        if (script->scriptCounts)
             JS_DumpPCCounts(cx, script);
     }
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_UnwrapObject(JSObject *obj)
 {
     return UnwrapObject(obj);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2339,20 +2339,20 @@ MarkRuntime(JSTracer *trc, bool useSaved
         MarkConservativeStackRoots(trc, useSavedRoots);
 
     for (RootRange r = rt->gcRootsHash.all(); !r.empty(); r.popFront())
         gc_root_traversal(trc, r.front());
 
     for (GCLocks::Range r = rt->gcLocksHash.all(); !r.empty(); r.popFront())
         gc_lock_traversal(r.front(), trc);
 
-    if (rt->scriptPCCounters) {
-        ScriptOpcodeCountsVector &vec = *rt->scriptPCCounters;
+    if (rt->scriptAndCountsVector) {
+        ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
         for (size_t i = 0; i < vec.length(); i++)
-            MarkScriptRoot(trc, &vec[i].script, "scriptPCCounters");
+            MarkScriptRoot(trc, &vec[i].script, "scriptAndCountsVector");
     }
 
     js_TraceAtomState(trc);
     rt->staticStrings.trace(trc);
 
     for (ContextIter acx(rt); !acx.done(); acx.next())
         acx->mark(trc);
 
@@ -2361,21 +2361,21 @@ MarkRuntime(JSTracer *trc, bool useSaved
             c->markTypes(trc);
 
         /* During a GC, these are treated as weak pointers. */
         if (!IS_GC_MARKING_TRACER(trc)) {
             if (c->watchpointMap)
                 c->watchpointMap->markAll(trc);
         }
 
-        /* Do not discard scripts with counters while profiling. */
+        /* Do not discard scripts with counts while profiling. */
         if (rt->profilingScripts) {
             for (CellIterUnderGC i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
                 JSScript *script = i.get<JSScript>();
-                if (script->pcCounters) {
+                if (script->scriptCounts) {
                     MarkScriptRoot(trc, &script, "profilingScripts");
                     JS_ASSERT(script == i.get<JSScript>());
                 }
             }
         }
     }
 
 #ifdef JS_METHODJIT
@@ -4491,110 +4491,110 @@ static void ReleaseAllJITCode(JSContext 
         }
     }
 #endif
 }
 
 /*
  * There are three possible PCCount profiling states:
  *
- * 1. None: Neither scripts nor the runtime have counter information.
- * 2. Profile: Active scripts have counter information, the runtime does not.
- * 3. Query: Scripts do not have counter information, the runtime does.
+ * 1. None: Neither scripts nor the runtime have count information.
+ * 2. Profile: Active scripts have count information, the runtime does not.
+ * 3. Query: Scripts do not have count information, the runtime does.
  *
  * When starting to profile scripts, counting begins immediately, with all JIT
- * code discarded and recompiled with counters as necessary. Active interpreter
+ * code discarded and recompiled with counts as necessary. Active interpreter
  * frames will not begin profiling until they begin executing another script
  * (via a call or return).
  *
  * The below API functions manage transitions to new states, according
  * to the table below.
  *
  *                                  Old State
  *                          -------------------------
  * Function                 None      Profile   Query
  * --------
  * StartPCCountProfiling    Profile   Profile   Profile
  * StopPCCountProfiling     None      Query     Query
  * PurgePCCounts            None      None      None
  */
 
 static void
-ReleaseScriptPCCounters(JSContext *cx)
+ReleaseScriptCounts(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
-    JS_ASSERT(rt->scriptPCCounters);
-
-    ScriptOpcodeCountsVector &vec = *rt->scriptPCCounters;
+    JS_ASSERT(rt->scriptAndCountsVector);
+
+    ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
 
     for (size_t i = 0; i < vec.length(); i++)
-        vec[i].counters.destroy(cx);
-
-    cx->delete_(rt->scriptPCCounters);
-    rt->scriptPCCounters = NULL;
+        vec[i].scriptCounts.destroy(cx);
+
+    cx->delete_(rt->scriptAndCountsVector);
+    rt->scriptAndCountsVector = NULL;
 }
 
 JS_FRIEND_API(void)
 StartPCCountProfiling(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
     if (rt->profilingScripts)
         return;
 
-    if (rt->scriptPCCounters)
-        ReleaseScriptPCCounters(cx);
+    if (rt->scriptAndCountsVector)
+        ReleaseScriptCounts(cx);
 
     ReleaseAllJITCode(cx);
 
     rt->profilingScripts = true;
 }
 
 JS_FRIEND_API(void)
 StopPCCountProfiling(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
     if (!rt->profilingScripts)
         return;
-    JS_ASSERT(!rt->scriptPCCounters);
+    JS_ASSERT(!rt->scriptAndCountsVector);
 
     ReleaseAllJITCode(cx);
 
-    ScriptOpcodeCountsVector *vec = cx->new_<ScriptOpcodeCountsVector>(SystemAllocPolicy());
+    ScriptAndCountsVector *vec = cx->new_<ScriptAndCountsVector>(SystemAllocPolicy());
     if (!vec)
         return;
 
     for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
         for (CellIter i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
-            if (script->pcCounters && script->types) {
-                ScriptOpcodeCountsPair info;
+            if (script->scriptCounts && script->types) {
+                ScriptAndCounts info;
                 info.script = script;
-                info.counters.steal(script->pcCounters);
+                info.scriptCounts.steal(script->scriptCounts);
                 if (!vec->append(info))
-                    info.counters.destroy(cx);
+                    info.scriptCounts.destroy(cx);
             }
         }
     }
 
     rt->profilingScripts = false;
-    rt->scriptPCCounters = vec;
+    rt->scriptAndCountsVector = vec;
 }
 
 JS_FRIEND_API(void)
 PurgePCCounts(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
-    if (!rt->scriptPCCounters)
+    if (!rt->scriptAndCountsVector)
         return;
     JS_ASSERT(!rt->profilingScripts);
 
-    ReleaseScriptPCCounters(cx);
+    ReleaseScriptCounts(cx);
 }
 
 } /* namespace js */
 
 JS_PUBLIC_API(void)
 JS_IterateCompartments(JSRuntime *rt, void *data,
                        JSIterateCompartmentCallback compartmentCallback)
 {
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1283,19 +1283,19 @@ js::Interpret(JSContext *cx, StackFrame 
 {
     JSAutoResolveFlags rf(cx, RESOLVE_INFER);
 
     gc::MaybeVerifyBarriers(cx, true);
 
     JS_ASSERT(!cx->compartment->activeAnalysis);
 
 #if JS_THREADED_INTERP
-#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->pcCounters, jumpTable == interruptJumpTable)
+#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->scriptCounts, jumpTable == interruptJumpTable)
 #else
-#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->pcCounters, switchMask == -1)
+#define CHECK_PCCOUNT_INTERRUPTS() JS_ASSERT_IF(script->scriptCounts, switchMask == -1)
 #endif
 
     /*
      * Macros for threaded interpreter loop
      */
 #if JS_THREADED_INTERP
     static void *const normalJumpTable[] = {
 # define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
@@ -1460,17 +1460,17 @@ js::Interpret(JSContext *cx, StackFrame 
         DO_OP();                                                              \
     JS_END_MACRO
 
 #define SET_SCRIPT(s)                                                         \
     JS_BEGIN_MACRO                                                            \
         script = (s);                                                         \
         if (script->hasAnyBreakpointsOrStepMode())                            \
             ENABLE_INTERRUPTS();                                              \
-        if (script->pcCounters)                                               \
+        if (script->scriptCounts)                                             \
             ENABLE_INTERRUPTS();                                              \
         JS_ASSERT_IF(interpMode == JSINTERP_SKIP_TRAP,                        \
                      script->hasAnyBreakpointsOrStepMode());                  \
     JS_END_MACRO
 
 #define CHECK_INTERRUPT_HANDLER()                                             \
     JS_BEGIN_MACRO                                                            \
         if (cx->runtime->debugHooks.interruptHook)                            \
@@ -1604,24 +1604,24 @@ js::Interpret(JSContext *cx, StackFrame 
 #else /* !JS_THREADED_INTERP */
   case -1:
     JS_ASSERT(switchMask == -1);
 #endif /* !JS_THREADED_INTERP */
     {
         bool moreInterrupts = false;
 
         if (cx->runtime->profilingScripts) {
-            if (!script->pcCounters)
-                script->initCounts(cx);
+            if (!script->scriptCounts)
+                script->initScriptCounts(cx);
             moreInterrupts = true;
         }
 
-        if (script->pcCounters) {
-            OpcodeCounts counts = script->getCounts(regs.pc);
-            counts.get(OpcodeCounts::BASE_INTERP)++;
+        if (script->scriptCounts) {
+            PCCounts counts = script->getPCCounts(regs.pc);
+            counts.get(PCCounts::BASE_INTERP)++;
             moreInterrupts = true;
         }
 
         JSInterruptHook hook = cx->runtime->debugHooks.interruptHook;
         if (hook || script->stepModeEnabled()) {
             Value rval;
             JSTrapStatus status = JSTRAP_CONTINUE;
             if (hook)
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -224,17 +224,17 @@ js::StackDefs(JSScript *script, jsbyteco
 static const char * countBaseNames[] = {
     "interp",
     "mjit",
     "mjit_calls",
     "mjit_code",
     "mjit_pics"
 };
 
-JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) == OpcodeCounts::BASE_COUNT);
+JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) == PCCounts::BASE_LIMIT);
 
 static const char * countAccessNames[] = {
     "infer_mono",
     "infer_di",
     "infer_poly",
     "infer_barrier",
     "infer_nobarrier",
     "observe_undefined",
@@ -242,107 +242,107 @@ static const char * countAccessNames[] =
     "observe_boolean",
     "observe_int32",
     "observe_double",
     "observe_string",
     "observe_object"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
-                 JS_ARRAY_LENGTH(countAccessNames) == OpcodeCounts::ACCESS_COUNT);
+                 JS_ARRAY_LENGTH(countAccessNames) == PCCounts::ACCESS_LIMIT);
 
 static const char * countElementNames[] = {
     "id_int",
     "id_double",
     "id_other",
     "id_unknown",
     "elem_typed",
     "elem_packed",
     "elem_dense",
     "elem_other"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
                  JS_ARRAY_LENGTH(countAccessNames) +
-                 JS_ARRAY_LENGTH(countElementNames) == OpcodeCounts::ELEM_COUNT);
+                 JS_ARRAY_LENGTH(countElementNames) == PCCounts::ELEM_LIMIT);
 
 static const char * countPropertyNames[] = {
     "prop_static",
     "prop_definite",
     "prop_other"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
                  JS_ARRAY_LENGTH(countAccessNames) +
-                 JS_ARRAY_LENGTH(countPropertyNames) == OpcodeCounts::PROP_COUNT);
+                 JS_ARRAY_LENGTH(countPropertyNames) == PCCounts::PROP_LIMIT);
 
 static const char * countArithNames[] = {
     "arith_int",
     "arith_double",
     "arith_other",
     "arith_unknown",
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
-                 JS_ARRAY_LENGTH(countArithNames) == OpcodeCounts::ARITH_COUNT);
+                 JS_ARRAY_LENGTH(countArithNames) == PCCounts::ARITH_LIMIT);
 
 /* static */ const char *
-OpcodeCounts::countName(JSOp op, size_t which)
+PCCounts::countName(JSOp op, size_t which)
 {
     JS_ASSERT(which < numCounts(op));
 
-    if (which < BASE_COUNT)
+    if (which < BASE_LIMIT)
         return countBaseNames[which];
 
     if (accessOp(op)) {
-        if (which < ACCESS_COUNT)
-            return countAccessNames[which - BASE_COUNT];
+        if (which < ACCESS_LIMIT)
+            return countAccessNames[which - BASE_LIMIT];
         if (elementOp(op))
-            return countElementNames[which - ACCESS_COUNT];
+            return countElementNames[which - ACCESS_LIMIT];
         if (propertyOp(op))
-            return countPropertyNames[which - ACCESS_COUNT];
+            return countPropertyNames[which - ACCESS_LIMIT];
         JS_NOT_REACHED("bad op");
         return NULL;
     }
 
     if (arithOp(op))
-        return countArithNames[which - BASE_COUNT];
+        return countArithNames[which - BASE_LIMIT];
 
     JS_NOT_REACHED("bad op");
     return NULL;
 }
 
 #ifdef DEBUG
 
 JS_FRIEND_API(void)
 js_DumpPCCounts(JSContext *cx, JSScript *script, js::Sprinter *sp)
 {
-    JS_ASSERT(script->pcCounters);
+    JS_ASSERT(script->scriptCounts);
 
     jsbytecode *pc = script->code;
     while (pc < script->code + script->length) {
         JSOp op = JSOp(*pc);
 
         int len = js_CodeSpec[op].length;
         jsbytecode *next = (len != -1) ? pc + len : pc + js_GetVariableBytecodeLength(pc);
 
         if (!js_Disassemble1(cx, script, pc, pc - script->code, true, sp))
             return;
 
-        size_t total = OpcodeCounts::numCounts(op);
-        double *raw = script->getCounts(pc).rawCounts();
+        size_t total = PCCounts::numCounts(op);
+        double *raw = script->getPCCounts(pc).rawCounts();
 
         Sprint(sp, "                  {");
         bool printed = false;
         for (size_t i = 0; i < total; i++) {
             double val = raw[i];
             if (val) {
                 if (printed)
                     Sprint(sp, ", ");
-                Sprint(sp, "\"%s\": %.0f", OpcodeCounts::countName(op, i), val);
+                Sprint(sp, "\"%s\": %.0f", PCCounts::countName(op, i), val);
                 printed = true;
             }
         }
         Sprint(sp, "}\n");
 
         pc = next;
     }
 }
@@ -5992,20 +5992,20 @@ IsValidBytecodeOffset(JSContext *cx, JSS
     return false;
 }
 
 JS_FRIEND_API(size_t)
 GetPCCountScriptCount(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
-    if (!rt->scriptPCCounters)
+    if (!rt->scriptAndCountsVector)
         return 0;
 
-    return rt->scriptPCCounters->length();
+    return rt->scriptAndCountsVector->length();
 }
 
 enum MaybeComma {NO_COMMA, COMMA};
 
 static void
 AppendJSONProperty(StringBuffer &buf, const char *name, MaybeComma comma = COMMA)
 {
     if (comma)
@@ -6029,22 +6029,22 @@ AppendArrayJSONProperties(JSContext *cx,
     }
 }
 
 JS_FRIEND_API(JSString *)
 GetPCCountScriptSummary(JSContext *cx, size_t index)
 {
     JSRuntime *rt = cx->runtime;
 
-    if (!rt->scriptPCCounters || index >= rt->scriptPCCounters->length()) {
+    if (!rt->scriptAndCountsVector || index >= rt->scriptAndCountsVector->length()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
         return NULL;
     }
 
-    ScriptOpcodeCountsPair info = (*rt->scriptPCCounters)[index];
+    ScriptAndCounts info = (*rt->scriptAndCountsVector)[index];
     JSScript *script = info.script;
 
     /*
      * OOM on buffer appends here will not be caught immediately, but since
      * StringBuffer uses a ContextAllocPolicy will trigger an exception on the
      * context if they occur, which we'll catch before returning.
      */
     StringBuffer buf(cx);
@@ -6065,45 +6065,45 @@ GetPCCountScriptSummary(JSContext *cx, s
         if (atom) {
             AppendJSONProperty(buf, "name");
             if (!(str = JS_ValueToSource(cx, StringValue(atom))))
                 return NULL;
             buf.append(str);
         }
     }
 
-    double baseTotals[OpcodeCounts::BASE_COUNT] = {0.0};
-    double accessTotals[OpcodeCounts::ACCESS_COUNT - OpcodeCounts::BASE_COUNT] = {0.0};
-    double elementTotals[OpcodeCounts::ELEM_COUNT - OpcodeCounts::ACCESS_COUNT] = {0.0};
-    double propertyTotals[OpcodeCounts::PROP_COUNT - OpcodeCounts::ACCESS_COUNT] = {0.0};
-    double arithTotals[OpcodeCounts::ARITH_COUNT - OpcodeCounts::BASE_COUNT] = {0.0};
+    double baseTotals[PCCounts::BASE_LIMIT] = {0.0};
+    double accessTotals[PCCounts::ACCESS_LIMIT - PCCounts::BASE_LIMIT] = {0.0};
+    double elementTotals[PCCounts::ELEM_LIMIT - PCCounts::ACCESS_LIMIT] = {0.0};
+    double propertyTotals[PCCounts::PROP_LIMIT - PCCounts::ACCESS_LIMIT] = {0.0};
+    double arithTotals[PCCounts::ARITH_LIMIT - PCCounts::BASE_LIMIT] = {0.0};
 
     for (unsigned i = 0; i < script->length; i++) {
-        OpcodeCounts &counts = info.getCounts(script->code + i);
+        PCCounts &counts = info.getPCCounts(script->code + i);
         if (!counts)
             continue;
 
         JSOp op = (JSOp)script->code[i];
-        unsigned numCounts = OpcodeCounts::numCounts(op);
+        unsigned numCounts = PCCounts::numCounts(op);
 
         for (unsigned j = 0; j < numCounts; j++) {
             double value = counts.get(j);
-            if (j < OpcodeCounts::BASE_COUNT) {
+            if (j < PCCounts::BASE_LIMIT) {
                 baseTotals[j] += value;
-            } else if (OpcodeCounts::accessOp(op)) {
-                if (j < OpcodeCounts::ACCESS_COUNT)
-                    accessTotals[j - OpcodeCounts::BASE_COUNT] += value;
-                else if (OpcodeCounts::elementOp(op))
-                    elementTotals[j - OpcodeCounts::ACCESS_COUNT] += value;
-                else if (OpcodeCounts::propertyOp(op))
-                    propertyTotals[j - OpcodeCounts::ACCESS_COUNT] += value;
+            } else if (PCCounts::accessOp(op)) {
+                if (j < PCCounts::ACCESS_LIMIT)
+                    accessTotals[j - PCCounts::BASE_LIMIT] += value;
+                else if (PCCounts::elementOp(op))
+                    elementTotals[j - PCCounts::ACCESS_LIMIT] += value;
+                else if (PCCounts::propertyOp(op))
+                    propertyTotals[j - PCCounts::ACCESS_LIMIT] += value;
                 else
                     JS_NOT_REACHED("Bad opcode");
-            } else if (OpcodeCounts::arithOp(op)) {
-                arithTotals[j - OpcodeCounts::BASE_COUNT] += value;
+            } else if (PCCounts::arithOp(op)) {
+                arithTotals[j - PCCounts::BASE_LIMIT] += value;
             } else {
                 JS_NOT_REACHED("Bad opcode");
             }
         }
     }
 
     AppendJSONProperty(buf, "totals");
     buf.append('{');
@@ -6133,17 +6133,17 @@ GetPCCountScriptSummary(JSContext *cx, s
 struct AutoDestroyPrinter
 {
     JSPrinter *jp;
     AutoDestroyPrinter(JSPrinter *jp) : jp(jp) {}
     ~AutoDestroyPrinter() { js_DestroyPrinter(jp); }
 };
 
 static bool
-GetPCCountJSON(JSContext *cx, const ScriptOpcodeCountsPair &info, StringBuffer &buf)
+GetPCCountJSON(JSContext *cx, const ScriptAndCounts &info, StringBuffer &buf)
 {
     JSScript *script = info.script;
 
     buf.append('{');
     AppendJSONProperty(buf, "text", NO_COMMA);
 
     Vector<DecompiledOpcode> decompiledOpcodes(cx);
     if (!decompiledOpcodes.reserve(script->length))
@@ -6231,27 +6231,27 @@ GetPCCountJSON(JSContext *cx, const Scri
         if (text && *text != 0) {
             AppendJSONProperty(buf, "text");
             JSString *str = JS_NewStringCopyZ(cx, text);
             if (!str || !(str = JS_ValueToSource(cx, StringValue(str))))
                 return false;
             buf.append(str);
         }
 
-        OpcodeCounts &counts = info.getCounts(pc);
-        unsigned numCounts = OpcodeCounts::numCounts(op);
+        PCCounts &counts = info.getPCCounts(pc);
+        unsigned numCounts = PCCounts::numCounts(op);
 
         AppendJSONProperty(buf, "counts");
         buf.append('{');
 
         MaybeComma comma = NO_COMMA;
         for (unsigned i = 0; i < numCounts; i++) {
             double value = counts.get(i);
             if (value > 0) {
-                AppendJSONProperty(buf, OpcodeCounts::countName(op, i), comma);
+                AppendJSONProperty(buf, PCCounts::countName(op, i), comma);
                 comma = COMMA;
                 NumberValueToStringBuffer(cx, DoubleValue(value), buf);
             }
         }
 
         buf.append('}');
         buf.append('}');
     }
@@ -6262,22 +6262,22 @@ GetPCCountJSON(JSContext *cx, const Scri
     return !cx->isExceptionPending();
 }
 
 JS_FRIEND_API(JSString *)
 GetPCCountScriptContents(JSContext *cx, size_t index)
 {
     JSRuntime *rt = cx->runtime;
 
-    if (!rt->scriptPCCounters || index >= rt->scriptPCCounters->length()) {
+    if (!rt->scriptAndCountsVector || index >= rt->scriptAndCountsVector->length()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
         return NULL;
     }
 
-    const ScriptOpcodeCountsPair &info = (*rt->scriptPCCounters)[index];
+    const ScriptAndCounts &info = (*rt->scriptAndCountsVector)[index];
     JSScript *script = info.script;
 
     StringBuffer buf(cx);
 
     if (!script->function() && !script->compileAndGo)
         return buf.finishString();
 
     {
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -516,20 +516,20 @@ FlowsIntoNext(JSOp op)
 {
     /* JSOP_YIELD is considered to flow into the next instruction, like JSOP_CALL. */
     return op != JSOP_STOP && op != JSOP_RETURN && op != JSOP_RETRVAL && op != JSOP_THROW &&
            op != JSOP_GOTO && op != JSOP_RETSUB;
 }
 
 /*
  * Counts accumulated for a single opcode in a script. The counts tracked vary
- * between opcodes, and this structure ensures that counts are accessed in
- * a coherent fashion.
+ * between opcodes, and this structure ensures that counts are accessed in a
+ * coherent fashion.
  */
-class OpcodeCounts
+class PCCounts
 {
     friend struct ::JSScript;
     double *counts;
 #ifdef DEBUG
     size_t capacity;
 #endif
 
  public:
@@ -537,105 +537,105 @@ class OpcodeCounts
     enum BaseCounts {
         BASE_INTERP = 0,
         BASE_METHODJIT,
 
         BASE_METHODJIT_STUBS,
         BASE_METHODJIT_CODE,
         BASE_METHODJIT_PICS,
 
-        BASE_COUNT
+        BASE_LIMIT
     };
 
     enum AccessCounts {
-        ACCESS_MONOMORPHIC = BASE_COUNT,
+        ACCESS_MONOMORPHIC = BASE_LIMIT,
         ACCESS_DIMORPHIC,
         ACCESS_POLYMORPHIC,
 
         ACCESS_BARRIER,
         ACCESS_NOBARRIER,
 
         ACCESS_UNDEFINED,
         ACCESS_NULL,
         ACCESS_BOOLEAN,
         ACCESS_INT32,
         ACCESS_DOUBLE,
         ACCESS_STRING,
         ACCESS_OBJECT,
 
-        ACCESS_COUNT
+        ACCESS_LIMIT
     };
 
     static bool accessOp(JSOp op) {
         /*
          * Access ops include all name, element and property reads, as well as
          * SETELEM and SETPROP (for ElementCounts/PropertyCounts alignment).
          */
         if (op == JSOP_SETELEM || op == JSOP_SETPROP)
             return true;
         int format = js_CodeSpec[op].format;
         return !!(format & (JOF_NAME | JOF_GNAME | JOF_ELEM | JOF_PROP))
             && !(format & (JOF_SET | JOF_INCDEC));
     }
 
     enum ElementCounts {
-        ELEM_ID_INT = ACCESS_COUNT,
+        ELEM_ID_INT = ACCESS_LIMIT,
         ELEM_ID_DOUBLE,
         ELEM_ID_OTHER,
         ELEM_ID_UNKNOWN,
 
         ELEM_OBJECT_TYPED,
         ELEM_OBJECT_PACKED,
         ELEM_OBJECT_DENSE,
         ELEM_OBJECT_OTHER,
 
-        ELEM_COUNT
+        ELEM_LIMIT
     };
 
     static bool elementOp(JSOp op) {
         return accessOp(op) && (JOF_MODE(js_CodeSpec[op].format) == JOF_ELEM);
     }
 
     enum PropertyCounts {
-        PROP_STATIC = ACCESS_COUNT,
+        PROP_STATIC = ACCESS_LIMIT,
         PROP_DEFINITE,
         PROP_OTHER,
 
-        PROP_COUNT
+        PROP_LIMIT
     };
 
     static bool propertyOp(JSOp op) {
         return accessOp(op) && (JOF_MODE(js_CodeSpec[op].format) == JOF_PROP);
     }
 
     enum ArithCounts {
-        ARITH_INT = BASE_COUNT,
+        ARITH_INT = BASE_LIMIT,
         ARITH_DOUBLE,
         ARITH_OTHER,
         ARITH_UNKNOWN,
 
-        ARITH_COUNT
+        ARITH_LIMIT
     };
 
     static bool arithOp(JSOp op) {
         return !!(js_CodeSpec[op].format & (JOF_INCDEC | JOF_ARITH));
     }
 
     static size_t numCounts(JSOp op)
     {
         if (accessOp(op)) {
             if (elementOp(op))
-                return ELEM_COUNT;
+                return ELEM_LIMIT;
             if (propertyOp(op))
-                return PROP_COUNT;
-            return ACCESS_COUNT;
+                return PROP_LIMIT;
+            return ACCESS_LIMIT;
         }
         if (arithOp(op))
-            return ARITH_COUNT;
-        return BASE_COUNT;
+            return ARITH_LIMIT;
+        return BASE_LIMIT;
     }
 
     static const char *countName(JSOp op, size_t which);
 
     double *rawCounts() { return counts; }
 
     double& get(size_t which) {
         JS_ASSERT(which < capacity);
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -400,25 +400,24 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
         UsesEval,
         MayNeedArgsObj,
         NeedsArgsObj,
         OwnFilename,
         ParentFilename
     };
 
     uint32_t length, lineno, nslots;
-    uint32_t natoms, nsrcnotes, ntrynotes, nobjects, nregexps, nconsts, i;
-    uint32_t prologLength, version, encodedClosedCount;
-    uint16_t nClosedArgs = 0, nClosedVars = 0;
+    uint32_t natoms, nsrcnotes, ntrynotes, nobjects, nregexps, nconsts, nClosedArgs, nClosedVars, i;
+    uint32_t prologLength, version;
     uint32_t nTypeSets = 0;
     uint32_t scriptBits = 0;
 
     JSContext *cx = xdr->cx();
     JSScript *script;
-    nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = 0;
+    nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = nClosedArgs = nClosedVars = 0;
     jssrcnote *notes = NULL;
 
     /* XDR arguments, local vars, and upvars. */
     uint16_t nargs, nvars;
 #if defined(DEBUG) || defined(__GNUC__) /* quell GCC overwarning */
     script = NULL;
     nargs = nvars = Bindings::BINDING_COUNT_LIMIT;
 #endif
@@ -528,28 +527,27 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
         lineno = script->lineno;
         nslots = (uint32_t)script->nslots;
         nslots = (uint32_t)((script->staticLevel << 16) | script->nslots);
         natoms = script->natoms;
 
         notes = script->notes();
         nsrcnotes = script->numNotes();
 
+        if (JSScript::isValidOffset(script->constsOffset))
+            nconsts = script->consts()->length;
         if (JSScript::isValidOffset(script->objectsOffset))
             nobjects = script->objects()->length;
         if (JSScript::isValidOffset(script->regexpsOffset))
             nregexps = script->regexps()->length;
         if (JSScript::isValidOffset(script->trynotesOffset))
             ntrynotes = script->trynotes()->length;
-        if (JSScript::isValidOffset(script->constOffset))
-            nconsts = script->consts()->length;
-
-        nClosedArgs = script->nClosedArgs;
-        nClosedVars = script->nClosedVars;
-        encodedClosedCount = (nClosedArgs << 16) | nClosedVars;
+        /* no globals when encoding;  see assertion above */
+        nClosedArgs = script->nClosedArgs();
+        nClosedVars = script->nClosedVars();
 
         nTypeSets = script->nTypeSets;
 
         if (script->noScriptRval)
             scriptBits |= (1 << NoScriptRval);
         if (script->savedCallerFun)
             scriptBits |= (1 << SavedCallerFun);
         if (script->strictModeCode)
@@ -592,27 +590,26 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
     if (!xdr->codeUint32(&ntrynotes))
         return JS_FALSE;
     if (!xdr->codeUint32(&nobjects))
         return JS_FALSE;
     if (!xdr->codeUint32(&nregexps))
         return JS_FALSE;
     if (!xdr->codeUint32(&nconsts))
         return JS_FALSE;
-    if (!xdr->codeUint32(&encodedClosedCount))
+    if (!xdr->codeUint32(&nClosedArgs))
+        return JS_FALSE;
+    if (!xdr->codeUint32(&nClosedVars))
         return JS_FALSE;
     if (!xdr->codeUint32(&nTypeSets))
         return JS_FALSE;
     if (!xdr->codeUint32(&scriptBits))
         return JS_FALSE;
 
     if (mode == XDR_DECODE) {
-        nClosedArgs = encodedClosedCount >> 16;
-        nClosedVars = encodedClosedCount & 0xFFFF;
-
         /* Note: version is packed into the 32b space with another 16b value. */
         JSVersion version_ = JSVersion(version & JS_BITMASK(16));
         JS_ASSERT((version_ & VersionFlags::FULL_MASK) == unsigned(version_));
         script = JSScript::NewScript(cx, length, nsrcnotes, natoms, nobjects,
                                      nregexps, ntrynotes, nconsts, 0, nClosedArgs,
                                      nClosedVars, nTypeSets, version_);
         if (!script)
             return JS_FALSE;
@@ -710,21 +707,21 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
             *objp = tmp;
         }
     }
     for (i = 0; i != nregexps; ++i) {
         if (!XDRScriptRegExpObject(xdr, &script->regexps()->vector[i]))
             return false;
     }
     for (i = 0; i != nClosedArgs; ++i) {
-        if (!xdr->codeUint32(&script->closedSlots[i]))
+        if (!xdr->codeUint32(&script->closedArgs()->vector[i]))
             return false;
     }
     for (i = 0; i != nClosedVars; ++i) {
-        if (!xdr->codeUint32(&script->closedSlots[nClosedArgs + i]))
+        if (!xdr->codeUint32(&script->closedVars()->vector[i]))
             return false;
     }
 
     if (ntrynotes != 0) {
         /*
          * We combine tn->kind and tn->stackDepth when serializing as XDR is not
          * efficient when serializing small integer types.
          */
@@ -759,78 +756,78 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
         for (i = 0; i != nconsts; ++i) {
             if (!XDRScriptConst(xdr, &vector[i]))
                 return false;
         }
     }
 
     if (mode == XDR_DECODE) {
         if (cx->hasRunOption(JSOPTION_PCCOUNT))
-            (void) script->initCounts(cx);
+            (void) script->initScriptCounts(cx);
         *scriptp = script;
     }
 
     return true;
 }
 
 template bool
 js::XDRScript(XDRState<XDR_ENCODE> *xdr, JSScript **scriptp, JSScript *parentScript);
 
 template bool
 js::XDRScript(XDRState<XDR_DECODE> *xdr, JSScript **scriptp, JSScript *parentScript);
 
 bool
-JSScript::initCounts(JSContext *cx)
+JSScript::initScriptCounts(JSContext *cx)
 {
-    JS_ASSERT(!pcCounters);
+    JS_ASSERT(!scriptCounts);
 
-    size_t count = 0;
+    size_t n = 0;
 
     jsbytecode *pc, *next;
     for (pc = code; pc < code + length; pc = next) {
-        count += OpcodeCounts::numCounts(JSOp(*pc));
+        n += PCCounts::numCounts(JSOp(*pc));
         next = pc + GetBytecodeLength(pc);
     }
 
-    size_t bytes = (length * sizeof(OpcodeCounts)) + (count * sizeof(double));
+    size_t bytes = (length * sizeof(PCCounts)) + (n * sizeof(double));
     char *cursor = (char *) cx->calloc_(bytes);
     if (!cursor)
         return false;
 
     DebugOnly<char *> base = cursor;
 
-    pcCounters.counts = (OpcodeCounts *) cursor;
-    cursor += length * sizeof(OpcodeCounts);
+    scriptCounts.pcCountsVector = (PCCounts *) cursor;
+    cursor += length * sizeof(PCCounts);
 
     for (pc = code; pc < code + length; pc = next) {
-        pcCounters.counts[pc - code].counts = (double *) cursor;
-        size_t capacity = OpcodeCounts::numCounts(JSOp(*pc));
+        scriptCounts.pcCountsVector[pc - code].counts = (double *) cursor;
+        size_t capacity = PCCounts::numCounts(JSOp(*pc));
 #ifdef DEBUG
-        pcCounters.counts[pc - code].capacity = capacity;
+        scriptCounts.pcCountsVector[pc - code].capacity = capacity;
 #endif
         cursor += capacity * sizeof(double);
         next = pc + GetBytecodeLength(pc);
     }
 
     JS_ASSERT(size_t(cursor - base) == bytes);
 
     /* Enable interrupts in any interpreter frames running on this script. */
     InterpreterFrames *frames;
     for (frames = cx->runtime->interpreterFrames; frames; frames = frames->older)
         frames->enableInterruptsIfRunning(this);
 
     return true;
 }
 
 void
-JSScript::destroyCounts(JSContext *cx)
+JSScript::destroyScriptCounts(JSContext *cx)
 {
-    if (pcCounters) {
-        cx->free_(pcCounters.counts);
-        pcCounters.counts = NULL;
+    if (scriptCounts) {
+        cx->free_(scriptCounts.pcCountsVector);
+        scriptCounts.pcCountsVector = NULL;
     }
 }
 
 /*
  * Shared script filename management.
  */
 
 const char *
@@ -903,99 +900,141 @@ js::FreeScriptFilenames(JSCompartment *c
     ScriptFilenameTable &table = comp->scriptFilenameTable;
     for (ScriptFilenameTable::Enum e(table); !e.empty(); e.popFront())
         Foreground::free_(e.front());
 
     table.clear();
 }
 
 /*
- * JSScript data structures memory alignment:
+ * JSScript::data has a complex, manually-controlled, memory layout.
+ *
+ * First are some optional array headers.  They are optional because they
+ * often aren't needed, i.e. the corresponding arrays often have zero elements.
+ * Each header has an offset in JSScript that indicates its location within
+ * |data|; that offset is INVALID_OFFSET if the array header is not present.
+ * Each header also has an accessor function in JSScript.
+ *
+ * Array type       Array elements  Offset            Accessor
+ * ----------       --------------  ------            --------
+ * JSConstArray     Consts          constsOffset      consts()
+ * JSObjectArray    Objects         objectsOffset     objects()
+ * JSObjectArray    Regexps         regexpsOffset     regexps()
+ * JSTryNoteArray   Try notes       tryNotesOffset    trynotes()
+ * GlobalSlotArray  Globals         globalsOffset     globals()
+ * ClosedSlotArray  ClosedArgs      closedArgsOffset  closedArgs()
+ * ClosedSlotArray  ClosedVars      closedVarsOffset  closedVars()
+ *
+ * Then are the elements of several arrays.  
+ * - Most of these arrays have headers listed above (if present).  For each of
+ *   these, the array pointer and the array length is stored in the header.  
+ * - The remaining arrays have pointers and lengths that are stored directly in
+ *   JSScript.  This is because, unlike the others, they are nearly always
+ *   non-zero length and so the optional-header space optimization isn't
+ *   worthwhile.
+ *
+ * Array elements   Pointed to by         Length
+ * --------------   -------------         ------
+ * Consts           consts()->vector      consts()->length
+ * Atoms            atoms                 natoms
+ * Objects          objects()->vector     objects()->length
+ * Regexps          regexps()->vector     regexps()->length
+ * Try notes        trynotes()->vector    trynotes()->length
+ * Globals          globals()->vector     globals()->length
+ * Closed args      closedArgs()->vector  closedArgs()->length
+ * Closed vars      closedVars()->vector  closedVars()->length
+ * Bytecodes        code                  length
+ * Source notes     notes()               numNotes() * sizeof(jssrcnote)  
  *
- * JSScript
- * JSObjectArray    script objects' descriptor if JSScript.objectsOffset != 0,
- *                    use script->objects() to access it.
- * JSObjectArray    script regexps' descriptor if JSScript.regexpsOffset != 0,
- *                    use script->regexps() to access it.
- * JSTryNoteArray   script try notes' descriptor if JSScript.tryNotesOffset
- *                    != 0, use script->trynotes() to access it.
- * JSAtom *a[]      array of JSScript.natoms atoms pointed by
- *                    JSScript.atoms if any.
- * JSObject *o[]    array of script->objects()->length objects if any
- *                    pointed by script->objects()->vector.
- * JSObject *r[]    array of script->regexps()->length regexps if any
- *                    pointed by script->regexps()->vector.
- * JSTryNote t[]    array of script->trynotes()->length try notes if any
- *                    pointed by script->trynotes()->vector.
- * jsbytecode b[]   script bytecode pointed by JSScript.code.
- * jssrcnote  s[]   script source notes, use script->notes() to access it
+ * IMPORTANT: This layout has two key properties.
+ * - It ensures that everything has sufficient alignment;  in particular, the
+ *   consts() elements need jsval alignment.
+ * - It ensures there are no gaps between elements, which saves space and makes
+ *   manual layout easy.  In particular, in the second part, arrays with larger
+ *   elements precede arrays with smaller elements.
  *
- * The alignment avoids gaps between entries as alignment requirement for each
- * subsequent structure or array is the same or divides the alignment
- * requirement for the previous one.
- *
- * The followings asserts checks that assuming that the alignment requirement
- * for JSObjectArray and JSTryNoteArray are sizeof(void *) and for JSTryNote
- * it is sizeof(uint32_t) as the structure consists of 3 uint32_t fields.
+ * The following static assertions check these properties.
  */
-JS_STATIC_ASSERT(sizeof(JSScript) % sizeof(void *) == 0);
-JS_STATIC_ASSERT(sizeof(JSObjectArray) % sizeof(void *) == 0);
-JS_STATIC_ASSERT(sizeof(JSTryNoteArray) == sizeof(JSObjectArray));
-JS_STATIC_ASSERT(sizeof(JSAtom *) == sizeof(JSObject *));
-JS_STATIC_ASSERT(sizeof(JSObject *) % sizeof(uint32_t) == 0);
-JS_STATIC_ASSERT(sizeof(JSTryNote) == 3 * sizeof(uint32_t));
-JS_STATIC_ASSERT(sizeof(uint32_t) % sizeof(jsbytecode) == 0);
-JS_STATIC_ASSERT(sizeof(jsbytecode) % sizeof(jssrcnote) == 0);
+
+#define KEEPS_JSVAL_ALIGNMENT(T) \
+    (JS_ALIGNMENT_OF(jsval) % JS_ALIGNMENT_OF(T) == 0 && \
+     sizeof(T) % sizeof(jsval) == 0)
+
+#define HAS_JSVAL_ALIGNMENT(T) \
+    (JS_ALIGNMENT_OF(jsval) == JS_ALIGNMENT_OF(T) && \
+     sizeof(T) == sizeof(jsval))
+
+#define NO_PADDING_BETWEEN_ENTRIES(T1, T2) \
+    (JS_ALIGNMENT_OF(T1) % JS_ALIGNMENT_OF(T2) == 0)
+
+/*
+ * These assertions ensure that there is no padding between the array headers,
+ * and also that the consts() elements (which follow immediately afterward) are
+ * jsval-aligned.  (There is an assumption that |data| itself is jsval-aligned;
+ * we check this below).
+ */
+JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(JSConstArray));
+JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(JSObjectArray));     /* there are two of these */
+JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(JSTryNoteArray));
+JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(GlobalSlotArray));
+JS_STATIC_ASSERT(KEEPS_JSVAL_ALIGNMENT(ClosedSlotArray));   /* there are two of these */
+
+/* These assertions ensure there is no padding required between array elements. */
+JS_STATIC_ASSERT(HAS_JSVAL_ALIGNMENT(HeapValue));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(HeapValue, JSAtom *));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(JSAtom *, HeapPtrObject));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(HeapPtrObject, HeapPtrObject));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(HeapPtrObject, JSTryNote));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(JSTryNote, GlobalSlotArray::Entry));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(GlobalSlotArray::Entry, uint32_t));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(uint32_t, uint32_t));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(uint32_t, jsbytecode));
+JS_STATIC_ASSERT(NO_PADDING_BETWEEN_ENTRIES(jsbytecode, jssrcnote));
 
 /*
  * Check that uint8_t offsets is enough to reach any optional array allocated
- * after JSScript. For that we check that the maximum possible offset for
- * JSConstArray, that last optional array, still fits 1 byte and do not
- * coincide with INVALID_OFFSET.
+ * within |data|. For that we check that the maximum possible offset for the
+ * closedVars array -- the last optional array -- still fits in 1 byte and does
+ * not coincide with INVALID_OFFSET.
  */
-JS_STATIC_ASSERT(sizeof(JSObjectArray) +
+JS_STATIC_ASSERT(sizeof(JSConstArray) +
+                 sizeof(JSObjectArray) +
                  sizeof(JSObjectArray) +
                  sizeof(JSTryNoteArray) +
-                 sizeof(js::GlobalSlotArray)
+                 sizeof(js::GlobalSlotArray) +
+                 sizeof(js::ClosedSlotArray)
                  < JSScript::INVALID_OFFSET);
 JS_STATIC_ASSERT(JSScript::INVALID_OFFSET <= 255);
 
 JSScript *
 JSScript::NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
                     uint32_t nobjects, uint32_t nregexps,
                     uint32_t ntrynotes, uint32_t nconsts, uint32_t nglobals,
                     uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets, JSVersion version)
 {
-    size_t size = sizeof(JSAtom *) * natoms;
+    size_t size = 0;
+
+    if (nconsts != 0)
+        size += sizeof(JSConstArray) + nconsts * sizeof(Value);
+    size += sizeof(JSAtom *) * natoms;
     if (nobjects != 0)
         size += sizeof(JSObjectArray) + nobjects * sizeof(JSObject *);
     if (nregexps != 0)
         size += sizeof(JSObjectArray) + nregexps * sizeof(JSObject *);
     if (ntrynotes != 0)
         size += sizeof(JSTryNoteArray) + ntrynotes * sizeof(JSTryNote);
     if (nglobals != 0)
         size += sizeof(GlobalSlotArray) + nglobals * sizeof(GlobalSlotArray::Entry);
-    uint32_t totalClosed = nClosedArgs + nClosedVars;
-    if (totalClosed != 0)
-        size += totalClosed * sizeof(uint32_t);
+    if (nClosedArgs != 0)
+        size += sizeof(ClosedSlotArray) + nClosedArgs * sizeof(uint32_t);
+    if (nClosedVars != 0)
+        size += sizeof(ClosedSlotArray) + nClosedVars * sizeof(uint32_t);
 
-    /*
-     * To esnure jsval alignment for the const array we place it immediately
-     * after JSSomethingArray structs as their sizes all divide sizeof(jsval).
-     * This works as long as the data itself is allocated with proper
-     * alignment which we ensure below.
-     */
-    JS_STATIC_ASSERT(sizeof(JSObjectArray) % sizeof(jsval) == 0);
-    JS_STATIC_ASSERT(sizeof(JSTryNoteArray) % sizeof(jsval) == 0);
-    JS_STATIC_ASSERT(sizeof(GlobalSlotArray) % sizeof(jsval) == 0);
-    JS_STATIC_ASSERT(sizeof(JSConstArray) % sizeof(jsval) == 0);
-    if (nconsts != 0)
-        size += sizeof(JSConstArray) + nconsts * sizeof(Value);
-
-    size += length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote);
+    size += length * sizeof(jsbytecode);
+    size += nsrcnotes * sizeof(jssrcnote);
 
     /*
      * We assume that calloc aligns on sizeof(Value) if the size we ask to
      * allocate divides sizeof(Value).
      */
     JS_STATIC_ASSERT(sizeof(Value) == sizeof(double));
     uint8_t *data = static_cast<uint8_t *>(cx->calloc_(JS_ROUNDUP(size, sizeof(Value))));
     if (!data)
@@ -1003,25 +1042,28 @@ JSScript::NewScript(JSContext *cx, uint3
 
     JSScript *script = js_NewGCScript(cx);
     if (!script) {
         Foreground::free_(data);
         return NULL;
     }
 
     PodZero(script);
-#ifdef JS_CRASH_DIAGNOSTICS
-    script->cookie1[0] = script->cookie2[0] = JS_SCRIPT_COOKIE;
-#endif
     script->data  = data;
     script->length = length;
     script->version = version;
     new (&script->bindings) Bindings(cx);
 
     uint8_t *cursor = data;
+    if (nconsts != 0) {
+        script->constsOffset = uint8_t(cursor - data);
+        cursor += sizeof(JSConstArray);
+    } else {
+        script->constsOffset = JSScript::INVALID_OFFSET;
+    }
     if (nobjects != 0) {
         script->objectsOffset = uint8_t(cursor - data);
         cursor += sizeof(JSObjectArray);
     } else {
         script->objectsOffset = JSScript::INVALID_OFFSET;
     }
     if (nregexps != 0) {
         script->regexpsOffset = uint8_t(cursor - data);
@@ -1036,29 +1078,29 @@ JSScript::NewScript(JSContext *cx, uint3
         script->trynotesOffset = JSScript::INVALID_OFFSET;
     }
     if (nglobals != 0) {
         script->globalsOffset = uint8_t(cursor - data);
         cursor += sizeof(GlobalSlotArray);
     } else {
         script->globalsOffset = JSScript::INVALID_OFFSET;
     }
-    JS_ASSERT(cursor - data < 0xFF);
-    if (nconsts != 0) {
-        script->constOffset = uint8_t(cursor - data);
-        cursor += sizeof(JSConstArray);
+    if (nClosedArgs != 0) {
+        script->closedArgsOffset = uint8_t(cursor - data);
+        cursor += sizeof(ClosedSlotArray);
     } else {
-        script->constOffset = JSScript::INVALID_OFFSET;
+        script->closedArgsOffset = JSScript::INVALID_OFFSET;
     }
-
-    JS_STATIC_ASSERT(sizeof(JSObjectArray) +
-                     sizeof(JSObjectArray) +
-                     sizeof(JSTryNoteArray) +
-                     sizeof(GlobalSlotArray) < 0xFF);
-
+    JS_ASSERT(cursor - data < 0xFF);
+    if (nClosedVars != 0) {
+        script->closedVarsOffset = uint8_t(cursor - data);
+        cursor += sizeof(ClosedSlotArray);
+    } else {
+        script->closedVarsOffset = JSScript::INVALID_OFFSET;
+    }
 
     if (nconsts != 0) {
         JS_ASSERT(reinterpret_cast<uintptr_t>(cursor) % sizeof(jsval) == 0);
         script->consts()->length = nconsts;
         script->consts()->vector = (HeapValue *)cursor;
         cursor += nconsts * sizeof(script->consts()->vector[0]);
     }
 
@@ -1091,21 +1133,26 @@ JSScript::NewScript(JSContext *cx, uint3
     }
 
     if (nglobals != 0) {
         script->globals()->length = nglobals;
         script->globals()->vector = reinterpret_cast<GlobalSlotArray::Entry *>(cursor);
         cursor += nglobals * sizeof(script->globals()->vector[0]);
     }
 
-    if (totalClosed != 0) {
-        script->nClosedArgs = nClosedArgs;
-        script->nClosedVars = nClosedVars;
-        script->closedSlots = reinterpret_cast<uint32_t *>(cursor);
-        cursor += totalClosed * sizeof(uint32_t);
+    if (nClosedArgs != 0) {
+        script->closedArgs()->length = nClosedArgs;
+        script->closedArgs()->vector = reinterpret_cast<uint32_t *>(cursor);
+        cursor += nClosedArgs * sizeof(script->closedArgs()->vector[0]);
+    }
+
+    if (nClosedVars != 0) {
+        script->closedVars()->length = nClosedVars;
+        script->closedVars()->vector = reinterpret_cast<uint32_t *>(cursor);
+        cursor += nClosedVars * sizeof(script->closedVars()->vector[0]);
     }
 
     JS_ASSERT(nTypeSets <= UINT16_MAX);
     script->nTypeSets = uint16_t(nTypeSets);
 
     script->code = (jsbytecode *)cursor;
     JS_ASSERT(cursor + length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote) == data + size);
 
@@ -1227,22 +1274,20 @@ JSScript::NewScriptFromEmitter(JSContext
         }
     }
 
     if (bce->globalUses.length()) {
         PodCopy<GlobalSlotArray::Entry>(script->globals()->vector, &bce->globalUses[0],
                                         bce->globalUses.length());
     }
 
-    if (script->nClosedArgs)
-        PodCopy<uint32_t>(script->closedSlots, &bce->closedArgs[0], script->nClosedArgs);
-    if (script->nClosedVars) {
-        PodCopy<uint32_t>(&script->closedSlots[script->nClosedArgs], &bce->closedVars[0],
-                          script->nClosedVars);
-    }
+    if (nClosedArgs)
+        PodCopy<uint32_t>(script->closedArgs()->vector, &bce->closedArgs[0], nClosedArgs);
+    if (nClosedVars)
+        PodCopy<uint32_t>(script->closedVars()->vector, &bce->closedVars[0], nClosedVars);
 
     script->bindings.transfer(cx, &bce->bindings);
 
     fun = NULL;
     if (bce->inFunction()) {
         /*
          * We initialize fun->script() to be the script constructed above
          * so that the debugger has a valid fun->script().
@@ -1284,17 +1329,17 @@ JSScript::NewScriptFromEmitter(JSContext
             compileAndGoGlobal = script->globalObject;
             if (!compileAndGoGlobal)
                 compileAndGoGlobal = &bce->scopeChain()->global();
         }
         Debugger::onNewScript(cx, script, compileAndGoGlobal);
     }
 
     if (cx->hasRunOption(JSOPTION_PCCOUNT))
-        (void) script->initCounts(cx);
+        (void) script->initScriptCounts(cx);
 
     return script;
 }
 
 size_t
 JSScript::computedSizeOfData()
 {
     uint8_t *dataEnd = code + length * sizeof(jsbytecode) + numNotes() * sizeof(jssrcnote);
@@ -1341,51 +1386,35 @@ js_CallDestroyScriptHook(JSContext *cx, 
         return;
 
     if (JSDestroyScriptHook hook = cx->runtime->debugHooks.destroyScriptHook)
         hook(cx, script, cx->runtime->debugHooks.destroyScriptHookData);
     script->callDestroyHook = false;
     JS_ClearScriptTraps(cx, script);
 }
 
-#ifdef JS_CRASH_DIAGNOSTICS
-
-void
-JSScript::CheckScript(JSScript *prev)
-{
-    if (cookie1[0] != JS_SCRIPT_COOKIE || cookie2[0] != JS_SCRIPT_COOKIE) {
-        crash::StackBuffer<sizeof(JSScript), 0x87> buf1(this);
-        crash::StackBuffer<sizeof(JSScript), 0x88> buf2(prev);
-        JS_OPT_ASSERT(false);
-    }
-}
-
-#endif /* JS_CRASH_DIAGNOSTICS */
-
 void
 JSScript::finalize(JSContext *cx, bool background)
 {
-    CheckScript(NULL);
-
     js_CallDestroyScriptHook(cx, this);
 
     JS_ASSERT_IF(principals, originPrincipals);
     if (principals)
         JS_DropPrincipals(cx->runtime, principals);
     if (originPrincipals)
         JS_DropPrincipals(cx->runtime, originPrincipals);
 
     if (types)
         types->destroy();
 
 #ifdef JS_METHODJIT
     mjit::ReleaseScriptCode(cx, this);
 #endif
 
-    destroyCounts(cx);
+    destroyScriptCounts(cx);
 
     if (sourceMap)
         cx->free_(sourceMap);
 
     if (debug) {
         jsbytecode *end = code + length;
         for (jsbytecode *pc = code; pc < end; pc++) {
             if (BreakpointSite *site = getBreakpointSite(pc)) {
@@ -1628,22 +1657,16 @@ js::CloneScript(JSContext *cx, JSScript 
 
     JSScript *newScript;
     if (!XDRScript(&decoder, &newScript, NULL))
         return NULL;
 
     return newScript;
 }
 
-void
-JSScript::copyClosedSlotsTo(JSScript *other)
-{
-    js_memcpy(other->closedSlots, closedSlots, nClosedArgs + nClosedVars);
-}
-
 bool
 JSScript::ensureHasDebug(JSContext *cx)
 {
     if (debug)
         return true;
 
     size_t nbytes = offsetof(DebugScript, breakpoints) + length * sizeof(BreakpointSite*);
     debug = (DebugScript *) cx->calloc_(nbytes);
@@ -1800,18 +1823,16 @@ JSScript::clearTraps(JSContext *cx)
         if (site)
             site->clearTrap(cx);
     }
 }
 
 void
 JSScript::markChildren(JSTracer *trc)
 {
-    CheckScript(NULL);
-
     JS_ASSERT_IF(trc->runtime->gcCheckCompartment,
                  compartment() == trc->runtime->gcCheckCompartment);
 
     for (uint32_t i = 0; i < natoms; ++i) {
         if (atoms[i])
             MarkStringUnbarriered(trc, &atoms[i], "atom");
     }
 
@@ -1820,17 +1841,17 @@ JSScript::markChildren(JSTracer *trc)
         MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
     }
 
     if (JSScript::isValidOffset(regexpsOffset)) {
         JSObjectArray *objarray = regexps();
         MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
     }
 
-    if (JSScript::isValidOffset(constOffset)) {
+    if (JSScript::isValidOffset(constsOffset)) {
         JSConstArray *constarray = consts();
         MarkValueRange(trc, constarray->length, constarray->vector, "consts");
     }
 
     if (function())
         MarkObject(trc, &function_, "function");
 
     if (!isCachedEval && globalObject)
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -96,16 +96,21 @@ struct GlobalSlotArray {
     struct Entry {
         uint32_t    atomIndex;  /* index into atom table */
         uint32_t    slot;       /* global obj slot number */
     };
     Entry           *vector;
     uint32_t        length;
 };
 
+struct ClosedSlotArray {
+    uint32_t        *vector;    /* array of closed slots */
+    uint32_t        length;     /* count of closed slots */
+};
+
 struct Shape;
 
 enum BindingKind { NONE, ARGUMENT, VARIABLE, CONSTANT };
 
 /*
  * Formal parameters and local variables are stored in a shape tree
  * path encapsulated within this class.  This class represents bindings for
  * both function and top-level scripts (the latter is needed to track names in
@@ -271,37 +276,42 @@ namespace JSC {
 
 namespace js { namespace mjit { struct JITScript; } }
 #endif
 
 namespace js {
 
 namespace analyze { class ScriptAnalysis; }
 
-class ScriptOpcodeCounts
+class ScriptCounts
 {
     friend struct ::JSScript;
-    friend struct ScriptOpcodeCountsPair;
-    OpcodeCounts *counts;
+    friend struct ScriptAndCounts;
+    /*
+     * This points to a single block that holds an array of PCCounts followed
+     * by an array of doubles.  Each element in the PCCounts array has a
+     * pointer into the array of doubles.
+     */
+    PCCounts *pcCountsVector;
 
  public:
 
-    ScriptOpcodeCounts() : counts(NULL) {
+    ScriptCounts() : pcCountsVector(NULL) {
     }
 
     inline void destroy(JSContext *cx);
 
-    void steal(ScriptOpcodeCounts &other) {
+    void steal(ScriptCounts &other) {
         *this = other;
         js::PodZero(&other);
     }
 
-    // Boolean conversion, for 'if (counters) ...'
+    // Boolean conversion, for 'if (scriptCounts) ...'
     operator void*() const {
-        return counts;
+        return pcCountsVector;
     }
 };
 
 class DebugScript
 {
     friend struct ::JSScript;
 
     /*
@@ -324,72 +334,147 @@ class DebugScript
 };
 
 } /* namespace js */
 
 static const uint32_t JS_SCRIPT_COOKIE = 0xc00cee;
 
 struct JSScript : public js::gc::Cell
 {
+  private:
+    static const uint32_t stepFlagMask = 0x80000000U;
+    static const uint32_t stepCountMask = 0x7fffffffU;
+
+  /*
+   * We order fields according to their size in order to avoid wasting space
+   * for alignment.
+   */
+
+  /* Larger-than-word-sized fields. */
+
+  public:
+    js::Bindings    bindings;   /* names of top-level variables in this script
+                                   (and arguments if this is a function script) */
+
+  /* Word-sized fields. */
+
+  public:
+    jsbytecode      *code;      /* bytecodes and their immediate operands */
+    uint8_t         *data;      /* pointer to variable-length data array (see 
+                                   comment above NewScript() for details) */
+
+    const char      *filename;  /* source filename or null */
+    JSAtom          **atoms;    /* maps immediate index to literal struct */
+
+    JSPrincipals    *principals;/* principals for this script */
+    JSPrincipals    *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
+
+    jschar          *sourceMap; /* source map file or null */
+
     /*
-     * Two successively less primitive ways to make a new JSScript.  The first
-     * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
-     * NewScriptFromEmitter, calls this optional debugger hook.
-     *
-     * The NewScript function can't know whether the script it creates belongs
-     * to a function, or is top-level or eval code, but the debugger wants access
-     * to the newly made script's function, if any -- so callers of NewScript
-     * are responsible for notifying the debugger after successfully creating any
-     * kind (function or other) of new JSScript.
+     * A global object for the script.
+     * - All scripts returned by JSAPI functions (JS_CompileScript,
+     *   JS_CompileUTF8File, etc.) have a non-null globalObject.
+     * - A function script has a globalObject if the function comes from a
+     *   compile-and-go script.
+     * - Temporary scripts created by obj_eval, JS_EvaluateScript, and
+     *   similar functions never have the globalObject field set; for such
+     *   scripts the global should be extracted from the JS frame that
+     *   execute scripts.
      */
-    static JSScript *NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
-                               uint32_t nobjects, uint32_t nregexps,
-                               uint32_t ntrynotes, uint32_t nconsts, uint32_t nglobals,
-                               uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets,
-                               JSVersion version);
+    js::HeapPtr<js::GlobalObject, JSScript*> globalObject;
+
+    /* Execution and profiling information for JIT code in the script. */
+    js::ScriptCounts scriptCounts;
+
+    /* Persistent type information retained across GCs. */
+    js::types::TypeScript *types;
+
+#ifdef JS_METHODJIT
+    // Fast-cached pointers to make calls faster. These are also used to
+    // quickly test whether there is JIT code; a NULL value means no
+    // compilation has been attempted. A JS_UNJITTABLE_SCRIPT value means
+    // compilation failed. Any value is the arity-check entry point.
+    void *jitArityCheckNormal;
+    void *jitArityCheckCtor;
+
+    js::mjit::JITScript *jitNormal;   /* Extra JIT info for normal scripts */
+    js::mjit::JITScript *jitCtor;     /* Extra JIT info for constructors */
+#endif
 
-    static JSScript *NewScriptFromEmitter(JSContext *cx, js::BytecodeEmitter *bce);
+  private:
+    js::DebugScript     *debug;
+    js::HeapPtrFunction function_;
+
+    size_t          useCount;   /* Number of times the script has been called
+                                 * or has had backedges taken. Reset if the
+                                 * script's JIT code is forcibly discarded. */
+#if JS_BITS_PER_WORD == 32
+    void *padding_;
+#endif
 
-#ifdef JS_CRASH_DIAGNOSTICS
+    /* 32-bit fields. */
+
+  public:
+    uint32_t        length;     /* length of code vector */
+
+    uint32_t        lineno;     /* base line number of script */
+
+    uint32_t        mainOffset; /* offset of main entry point from code, after
+                                   predef'ing prolog */
+
+    uint32_t        natoms;     /* length of atoms array */
+
+#ifdef DEBUG
     /*
-     * Make sure that the cookie size does not affect the GC alignment
-     * requirements.
+     * Unique identifier within the compartment for this script, used for
+     * printing analysis information.
      */
-    uint32_t        cookie1[Cell::CellSize / sizeof(uint32_t)];
+    uint32_t        id_;
+  private:
+    uint32_t        idpad;
+  public:
 #endif
-    jsbytecode      *code;      /* bytecodes and their immediate operands */
-    uint8_t         *data;      /* pointer to variable-length data array */
 
-    uint32_t        length;     /* length of code vector */
+    /* 16-bit fields. */
+
   private:
     uint16_t        version;    /* JS version under which script was compiled */
 
   public:
     uint16_t        nfixed;     /* number of slots besides stack operands in
                                    slot array */
+
+    uint16_t        nTypeSets;  /* number of type sets used in this script for
+                                   dynamic type monitoring */
+
+    uint16_t        nslots;     /* vars plus maximum stack depth */
+    uint16_t        staticLevel;/* static level for display maintenance */
+
+    /* 8-bit fields. */
+
     /*
      * Offsets to various array structures from the end of this script, or
      * JSScript::INVALID_OFFSET if the array has length 0.
      */
+  public:
+    uint8_t         constsOffset;   /* offset to the array of constants */
     uint8_t         objectsOffset;  /* offset to the array of nested function,
                                        block, scope, xml and one-time regexps
                                        objects */
     uint8_t         regexpsOffset;  /* offset to the array of to-be-cloned
                                        regexps  */
     uint8_t         trynotesOffset; /* offset to the array of try notes */
     uint8_t         globalsOffset;  /* offset to the array of global slots */
-    uint8_t         constOffset;    /* offset to the array of constants */
-
-    uint16_t        nTypeSets;      /* number of type sets used in this script for
-                                       dynamic type monitoring */
+    uint8_t         closedArgsOffset; /* offset to the array of closed args */
+    uint8_t         closedVarsOffset; /* offset to the array of closed vars */
 
-    uint32_t        lineno;     /* base line number of script */
+    /* 1-bit fields. */
 
-    uint32_t        mainOffset; /* offset of main entry point from code, after
-                                   predef'ing prolog */
+  public:
     bool            noScriptRval:1; /* no need for result value of last
                                        expression statement */
     bool            savedCallerFun:1; /* can call getCallerFunction() */
     bool            strictModeCode:1; /* code is in strict mode */
     bool            compileAndGo:1;   /* script was compiled with TCF_COMPILE_N_GO */
     bool            usesEval:1;       /* script uses eval() */
     bool            warnedAboutTwoArgumentEval:1; /* have warned about use of
                                                      obsolete eval(s, o) in
@@ -423,110 +508,64 @@ struct JSScript : public js::gc::Cell
      * analyzeBytecode and analyzeSSA. To avoid the complexity of spurious
      * argument objects creation, we maintain the invariant that needsArgsObj()
      * is only queried after this analysis has occurred (analyzedArgsUsage()).
      */
   private:
     bool            mayNeedArgsObj_:1;
     bool            analyzedArgsUsage_:1;
     bool            needsArgsObj_:1;
+
+    /* End of fields.  Start methods. */
+
+    /*
+     * Two successively less primitive ways to make a new JSScript.  The first
+     * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
+     * NewScriptFromEmitter, calls this optional debugger hook.
+     *
+     * The NewScript function can't know whether the script it creates belongs
+     * to a function, or is top-level or eval code, but the debugger wants access
+     * to the newly made script's function, if any -- so callers of NewScript
+     * are responsible for notifying the debugger after successfully creating any
+     * kind (function or other) of new JSScript.
+     */
   public:
+    static JSScript *NewScript(JSContext *cx, uint32_t length, uint32_t nsrcnotes, uint32_t natoms,
+                               uint32_t nobjects, uint32_t nregexps,
+                               uint32_t ntrynotes, uint32_t nconsts, uint32_t nglobals,
+                               uint16_t nClosedArgs, uint16_t nClosedVars, uint32_t nTypeSets,
+                               JSVersion version);
+    static JSScript *NewScriptFromEmitter(JSContext *cx, js::BytecodeEmitter *bce);
+
     bool mayNeedArgsObj() const { return mayNeedArgsObj_; }
     bool analyzedArgsUsage() const { return analyzedArgsUsage_; }
     bool needsArgsObj() const { JS_ASSERT(analyzedArgsUsage()); return needsArgsObj_; }
     void setNeedsArgsObj(bool needsArgsObj);
     bool applySpeculationFailed(JSContext *cx);
 
     void setMayNeedArgsObj() {
         mayNeedArgsObj_ = true;
     }
 
-    uint32_t        natoms;     /* length of atoms array */
-    uint16_t        nslots;     /* vars plus maximum stack depth */
-    uint16_t        staticLevel;/* static level for display maintenance */
-
-    uint16_t        nClosedArgs; /* number of args which are closed over. */
-    uint16_t        nClosedVars; /* number of vars which are closed over. */
-
-    const char      *filename;  /* source filename or null */
-    JSAtom          **atoms;    /* maps immediate index to literal struct */
-  private:
-    size_t          useCount;  /* Number of times the script has been called
-                                 * or has had backedges taken. Reset if the
-                                 * script's JIT code is forcibly discarded. */
-  public:
-    js::Bindings    bindings;   /* names of top-level variables in this script
-                                   (and arguments if this is a function script) */
-    JSPrincipals    *principals;/* principals for this script */
-    JSPrincipals    *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
-    jschar          *sourceMap; /* source map file or null */
-
-    /*
-     * A global object for the script.
-     * - All scripts returned by JSAPI functions (JS_CompileScript,
-     *   JS_CompileUTF8File, etc.) have a non-null globalObject.
-     * - A function script has a globalObject if the function comes from a
-     *   compile-and-go script.
-     * - Temporary scripts created by obj_eval, JS_EvaluateScript, and
-     *   similar functions never have the globalObject field set; for such
-     *   scripts the global should be extracted from the JS frame that
-     *   execute scripts.
-     */
-    js::HeapPtr<js::GlobalObject, JSScript*> globalObject;
-
     /* Hash table chaining for JSCompartment::evalCache. */
-    JSScript        *&evalHashLink() { return *globalObject.unsafeGetUnioned(); }
-
-    uint32_t        *closedSlots; /* vector of closed slots; args first, then vars. */
-
-    /* Execution and profiling information for JIT code in the script. */
-    js::ScriptOpcodeCounts pcCounters;
-
-  private:
-    js::DebugScript     *debug;
-    js::HeapPtrFunction function_;
-  public:
+    JSScript *&evalHashLink() { return *globalObject.unsafeGetUnioned(); }
 
     /*
      * Original compiled function for the script, if it has a function.
      * NULL for global and eval scripts.
      */
     JSFunction *function() const { return function_; }
     void setFunction(JSFunction *fun);
 
-#ifdef JS_CRASH_DIAGNOSTICS
-    /* All diagnostic fields must be multiples of Cell::CellSize. */
-    uint32_t        cookie2[Cell::CellSize / sizeof(uint32_t)];
-
-    void CheckScript(JSScript *prev);
-#else
-    void CheckScript(JSScript *prev) {}
-#endif /* !JS_CRASH_DIAGNOSTICS */
-
 #ifdef DEBUG
-    /*
-     * Unique identifier within the compartment for this script, used for
-     * printing analysis information.
-     */
-    uint32_t id_;
-    uint32_t idpad;
     unsigned id();
 #else
     unsigned id() { return 0; }
 #endif
 
-    /* Persistent type information retained across GCs. */
-    js::types::TypeScript *types;
-
-#if JS_BITS_PER_WORD == 32
-  private:
-    void *padding_;
-  public:
-#endif
-
     /* Ensure the script has a TypeScript. */
     inline bool ensureHasTypes(JSContext *cx);
 
     /*
      * Ensure the script has scope and bytecode analysis information.
      * Performed when the script first runs, or first runs after a TypeScript
      * GC purge. If scope is NULL then the script must already have types with
      * scope information.
@@ -560,28 +599,16 @@ struct JSScript : public js::gc::Cell
     }
 
   private:
     bool makeTypes(JSContext *cx);
     bool makeAnalysis(JSContext *cx);
   public:
 
 #ifdef JS_METHODJIT
-    // Fast-cached pointers to make calls faster. These are also used to
-    // quickly test whether there is JIT code; a NULL value means no
-    // compilation has been attempted. A JS_UNJITTABLE_SCRIPT value means
-    // compilation failed. Any value is the arity-check entry point.
-    void *jitArityCheckNormal;
-    void *jitArityCheckCtor;
-
-    js::mjit::JITScript *jitNormal;   /* Extra JIT info for normal scripts */
-    js::mjit::JITScript *jitCtor;     /* Extra JIT info for constructors */
-#endif
-
-#ifdef JS_METHODJIT
     bool hasJITCode() {
         return jitNormal || jitCtor;
     }
 
     // These methods are implemented in MethodJIT.h.
     inline void **nativeMap(bool constructing);
     inline void *nativeCodeForPC(bool constructing, jsbytecode *pc);
 
@@ -595,27 +622,25 @@ struct JSScript : public js::gc::Cell
     void resetUseCount() { useCount = 0; }
 
     /*
      * Size of the JITScript and all sections.  If |mallocSizeOf| is NULL, the
      * size is computed analytically.  (This method is implemented in
      * MethodJIT.cpp.)
      */
     size_t sizeOfJitScripts(JSMallocSizeOfFun mallocSizeOf);
-
 #endif
 
-    /* Counter accessors. */
-    js::OpcodeCounts getCounts(jsbytecode *pc) {
+    js::PCCounts getPCCounts(jsbytecode *pc) {
         JS_ASSERT(size_t(pc - code) < length);
-        return pcCounters.counts[pc - code];
+        return scriptCounts.pcCountsVector[pc - code];
     }
 
-    bool initCounts(JSContext *cx);
-    void destroyCounts(JSContext *cx);
+    bool initScriptCounts(JSContext *cx);
+    void destroyScriptCounts(JSContext *cx);
 
     jsbytecode *main() {
         return code + mainOffset;
     }
 
     /*
      * computedSizeOfData() is the in-use size of all the data sections.
      * sizeOfData() is the size of the block allocated to hold all the data sections
@@ -627,16 +652,21 @@ struct JSScript : public js::gc::Cell
     uint32_t numNotes();  /* Number of srcnote slots in the srcnotes section */
 
     /* Script notes are allocated right after the code. */
     jssrcnote *notes() { return (jssrcnote *)(code + length); }
 
     static const uint8_t INVALID_OFFSET = 0xFF;
     static bool isValidOffset(uint8_t offset) { return offset != INVALID_OFFSET; }
 
+    JSConstArray *consts() {
+        JS_ASSERT(isValidOffset(constsOffset));
+        return reinterpret_cast<JSConstArray *>(data + constsOffset);
+    }
+
     JSObjectArray *objects() {
         JS_ASSERT(isValidOffset(objectsOffset));
         return reinterpret_cast<JSObjectArray *>(data + objectsOffset);
     }
 
     JSObjectArray *regexps() {
         JS_ASSERT(isValidOffset(regexpsOffset));
         return reinterpret_cast<JSObjectArray *>(data + regexpsOffset);
@@ -647,19 +677,32 @@ struct JSScript : public js::gc::Cell
         return reinterpret_cast<JSTryNoteArray *>(data + trynotesOffset);
     }
 
     js::GlobalSlotArray *globals() {
         JS_ASSERT(isValidOffset(globalsOffset));
         return reinterpret_cast<js::GlobalSlotArray *>(data + globalsOffset);
     }
 
-    JSConstArray *consts() {
-        JS_ASSERT(isValidOffset(constOffset));
-        return reinterpret_cast<JSConstArray *>(data + constOffset);
+    js::ClosedSlotArray *closedArgs() {
+        JS_ASSERT(isValidOffset(closedArgsOffset));
+        return reinterpret_cast<js::ClosedSlotArray *>(data + closedArgsOffset);
+    }
+
+    js::ClosedSlotArray *closedVars() {
+        JS_ASSERT(isValidOffset(closedVarsOffset));
+        return reinterpret_cast<js::ClosedSlotArray *>(data + closedVarsOffset);
+    }
+
+    uint32_t nClosedArgs() {
+        return isValidOffset(closedArgsOffset) ? closedArgs()->length : 0;
+    }
+
+    uint32_t nClosedVars() {
+        return isValidOffset(closedVarsOffset) ? closedVars()->length : 0;
     }
 
     JSAtom *getAtom(size_t index) {
         JS_ASSERT(index < natoms);
         return atoms[index];
     }
 
     js::PropertyName *getName(size_t index) {
@@ -690,31 +733,28 @@ struct JSScript : public js::gc::Cell
     /*
      * The isEmpty method tells whether this script has code that computes any
      * result (not return value, result AKA normal completion value) other than
      * JSVAL_VOID, or any other effects.
      */
     inline bool isEmpty() const;
 
     uint32_t getClosedArg(uint32_t index) {
-        JS_ASSERT(index < nClosedArgs);
-        return closedSlots[index];
+        js::ClosedSlotArray *arr = closedArgs();
+        JS_ASSERT(index < arr->length);
+        return arr->vector[index];
     }
 
     uint32_t getClosedVar(uint32_t index) {
-        JS_ASSERT(index < nClosedVars);
-        return closedSlots[nClosedArgs + index];
+        js::ClosedSlotArray *arr = closedVars();
+        JS_ASSERT(index < arr->length);
+        return arr->vector[index];
     }
 
-    void copyClosedSlotsTo(JSScript *other);
-
   private:
-    static const uint32_t stepFlagMask = 0x80000000U;
-    static const uint32_t stepCountMask = 0x7fffffffU;
-
     /*
      * Attempt to recompile with or without single-stepping support, as directed
      * by stepModeEnabled().
      */
     bool recompileForStepMode(JSContext *cx);
 
     /* Attempt to change this->stepMode to |newValue|. */
     bool tryNewStepMode(JSContext *cx, uint32_t newValue);
@@ -808,41 +848,27 @@ extern void
 MarkScriptFilename(const char *filename);
 
 extern void
 SweepScriptFilenames(JSCompartment *comp);
 
 extern void
 FreeScriptFilenames(JSCompartment *comp);
 
-struct ScriptOpcodeCountsPair
+struct ScriptAndCounts
 {
     JSScript *script;
-    ScriptOpcodeCounts counters;
+    ScriptCounts scriptCounts;
 
-    OpcodeCounts &getCounts(jsbytecode *pc) const {
+    PCCounts &getPCCounts(jsbytecode *pc) const {
         JS_ASSERT(unsigned(pc - script->code) < script->length);
-        return counters.counts[pc - script->code];
+        return scriptCounts.pcCountsVector[pc - script->code];
     }
 };
 
-#ifdef JS_CRASH_DIAGNOSTICS
-
-void
-CheckScript(JSScript *script, JSScript *prev);
-
-#else
-
-inline void
-CheckScript(JSScript *script, JSScript *prev)
-{
-}
-
-#endif /* !JS_CRASH_DIAGNOSTICS */
-
 } /* namespace js */
 
 /*
  * To perturb as little code as possible, we introduce a js_GetSrcNote lookup
  * cache without adding an explicit cx parameter.  Thus js_GetSrcNote becomes
  * a macro that uses cx from its calls' lexical environments.
  */
 #define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc)
--- a/js/src/jsscriptinlines.h
+++ b/js/src/jsscriptinlines.h
@@ -134,20 +134,19 @@ CurrentScriptFileLineOrigin(JSContext *c
         *origin = script->originPrincipals;
         return;
     }
 
     CurrentScriptFileLineOriginSlow(cx, file, linenop, origin);
 }
 
 inline void
-ScriptOpcodeCounts::destroy(JSContext *cx)
+ScriptCounts::destroy(JSContext *cx)
 {
-    if (counts)
-        cx->free_(counts);
+    cx->free_(pcCountsVector);
 }
 
 } // namespace js
 
 inline void
 JSScript::setFunction(JSFunction *fun)
 {
     function_ = fun;
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -61,16 +61,27 @@ js_memcpy(void *dst_, const void *src_, 
 
     return memcpy(dst, src, len);
 }
 
 #ifdef __cplusplus
 namespace js {
 
 template <class T>
+struct AlignmentTestStruct
+{
+    char c;
+    T t;
+};
+
+/* This macro determines the alignment requirements of a type. */
+#define JS_ALIGNMENT_OF(t_) \
+  (sizeof(js::AlignmentTestStruct<t_>) - sizeof(t_))
+
+template <class T>
 class AlignedPtrAndFlag
 {
     uintptr_t bits;
 
   public:
     AlignedPtrAndFlag(T *t, bool flag) {
         JS_ASSERT((uintptr_t(t) & 1) == 0);
         bits = uintptr_t(t) | uintptr_t(flag);
--- a/js/src/methodjit/BaseAssembler.h
+++ b/js/src/methodjit/BaseAssembler.h
@@ -1361,38 +1361,38 @@ static const JSC::MacroAssembler::Regist
             uint32_t nfixed = templateObject->numFixedSlots();
             storePtr(ImmPtr(templateObject->getPrivate()),
                      Address(result, JSObject::getPrivateDataOffset(nfixed)));
         }
 
         return jump;
     }
 
-    /* Add the value stored in 'value' to the accumulator 'counter'. */
-    void addCounter(const double *value, double *counter, RegisterID scratch)
+    /* Add the value stored in 'value' to the accumulator 'count'. */
+    void addCount(const double *value, double *count, RegisterID scratch)
     {
         loadDouble(value, Registers::FPConversionTemp);
-        move(ImmPtr(counter), scratch);
+        move(ImmPtr(count), scratch);
         addDouble(Address(scratch), Registers::FPConversionTemp);
         storeDouble(Registers::FPConversionTemp, Address(scratch));
     }
 
-    /* Add one to the accumulator 'counter'. */
-    void bumpCounter(double *counter, RegisterID scratch)
+    /* Add one to the accumulator |count|. */
+    void bumpCount(double *count, RegisterID scratch)
     {
-        addCounter(&oneDouble, counter, scratch);
+        addCount(&oneDouble, count, scratch);
     }
 
     /* Bump the stub call count for script/pc if they are being counted. */
-    void bumpStubCounter(JSScript *script, jsbytecode *pc, RegisterID scratch)
+    void bumpStubCount(JSScript *script, jsbytecode *pc, RegisterID scratch)
     {
-        if (script->pcCounters) {
-            OpcodeCounts counts = script->getCounts(pc);
-            double *counter = &counts.get(OpcodeCounts::BASE_METHODJIT_STUBS);
-            bumpCounter(counter, scratch);
+        if (script->scriptCounts) {
+            PCCounts counts = script->getPCCounts(pc);
+            double *count = &counts.get(PCCounts::BASE_METHODJIT_STUBS);
+            bumpCount(count, scratch);
         }
     }
 
     static const double oneDouble;
 };
 
 /* Return f<true> if the script is strict mode code, f<false> otherwise. */
 #define STRICT_VARIANT(f)                                                     \
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -399,18 +399,18 @@ mjit::Compiler::scanInlineCalls(uint32_t
     }
 
     return Compile_Okay;
 }
 
 CompileStatus
 mjit::Compiler::pushActiveFrame(JSScript *script, uint32_t argc)
 {
-    if (cx->runtime->profilingScripts && !script->pcCounters)
-        script->initCounts(cx);
+    if (cx->runtime->profilingScripts && !script->scriptCounts)
+        script->initScriptCounts(cx);
 
     ActiveFrame *newa = OffTheBooks::new_<ActiveFrame>(cx);
     if (!newa) {
         js_ReportOutOfMemory(cx);
         return Compile_Error;
     }
 
     newa->parent = a;
@@ -533,17 +533,17 @@ mjit::Compiler::performCompilation()
     {
         types::AutoEnterCompilation enter(cx, outerScript, isConstructing, chunkIndex);
 
         CHECK_STATUS(checkAnalysis(outerScript));
         if (inlining())
             CHECK_STATUS(scanInlineCalls(CrossScriptSSA::OUTER_FRAME, 0));
         CHECK_STATUS(pushActiveFrame(outerScript, 0));
 
-        if (outerScript->pcCounters || Probes::wantNativeAddressInfo(cx)) {
+        if (outerScript->scriptCounts || Probes::wantNativeAddressInfo(cx)) {
             size_t length = ssa.frameLength(ssa.numFrames() - 1);
             pcLengths = (PCLengthEntry *) OffTheBooks::calloc_(sizeof(pcLengths[0]) * length);
             if (!pcLengths)
                 return Compile_Error;
         }
 
         if (chunkIndex == 0)
             CHECK_STATUS(generatePrologue());
@@ -1370,21 +1370,18 @@ mjit::Compiler::finishThisUp()
     JS_ASSERT(outerScript == script);
 
     chunk->code = JSC::MacroAssemblerCodeRef(result, execPool, masm.size() + stubcc.size());
     chunk->pcLengths = pcLengths;
 
     if (chunkIndex == 0) {
         jit->invokeEntry = result;
         if (script->function()) {
-            jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress();
             jit->argsCheckEntry = stubCode.locationOf(argsCheckLabel).executableAddress();
             jit->fastEntry = fullCode.locationOf(invokeLabel).executableAddress();
-            void *&addr = isConstructing ? script->jitArityCheckCtor : script->jitArityCheckNormal;
-            addr = jit->arityCheckEntry;
         }
     }
 
     /*
      * WARNING: mics(), callICs() et al depend on the ordering of these
      * variable-length sections.  See JITChunk's declaration for details.
      */
 
@@ -2112,22 +2109,22 @@ mjit::Compiler::generateMethod()
 
         /* Don't compile fat opcodes, run the decomposed version instead. */
         if (js_CodeSpec[op].format & JOF_DECOMPOSE) {
             PC += js_CodeSpec[op].length;
             continue;
         }
 
         Label codeStart = masm.label();
-        bool countersUpdated = false;
+        bool countsUpdated = false;
         bool arithUpdated = false;
 
         JSValueType arithFirstUseType = JSVAL_TYPE_UNKNOWN;
         JSValueType arithSecondUseType = JSVAL_TYPE_UNKNOWN;
-        if (script->pcCounters && !!(js_CodeSpec[op].format & JOF_ARITH)) {
+        if (script->scriptCounts && !!(js_CodeSpec[op].format & JOF_ARITH)) {
             if (GetUseCount(script, PC - script->code) == 1) {
                 FrameEntry *use = frame.peek(-1);
                 /*
                  * Pretend it's a binary operation and the second operand has
                  * the same type as the first one.
                  */
                 if (use->isTypeKnown())
                     arithFirstUseType = arithSecondUseType = use->getKnownType();
@@ -2137,22 +2134,22 @@ mjit::Compiler::generateMethod()
                     arithFirstUseType = use->getKnownType();
                 use = frame.peek(-2);
                 if (use->isTypeKnown())
                     arithSecondUseType = use->getKnownType();
             }
         }
 
         /*
-         * Update PC counters for jump opcodes at their start, so that we don't
+         * Update PC counts for jump opcodes at their start, so that we don't
          * miss them when taking the jump. This is delayed for other opcodes,
          * as we want to skip updating for ops we didn't generate any code for.
          */
-        if (script->pcCounters && JOF_OPTYPE(op) == JOF_JUMP)
-            updatePCCounters(PC, &codeStart, &countersUpdated);
+        if (script->scriptCounts && JOF_OPTYPE(op) == JOF_JUMP)
+            updatePCCounts(PC, &codeStart, &countsUpdated);
 
     /**********************
      * BEGIN COMPILER OPS *
      **********************/
 
         lastPC = PC;
 
         switch (op) {
@@ -2177,18 +2174,18 @@ mjit::Compiler::generateMethod()
 
             FrameEntry *fe = frame.peek(-1);
             frame.storeTo(fe, Address(JSFrameReg, StackFrame::offsetOfReturnValue()), true);
             frame.pop();
           }
           END_CASE(JSOP_POPV)
 
           BEGIN_CASE(JSOP_RETURN)
-            if (script->pcCounters)
-                updatePCCounters(PC, &codeStart, &countersUpdated);
+            if (script->scriptCounts)
+                updatePCCounts(PC, &codeStart, &countsUpdated);
             emitReturn(frame.peek(-1));
             fallthrough = false;
           END_CASE(JSOP_RETURN)
 
           BEGIN_CASE(JSOP_GOTO)
           BEGIN_CASE(JSOP_DEFAULT)
           {
             unsigned targetOffset = FollowBranch(cx, script, PC - script->code);
@@ -2333,32 +2330,32 @@ mjit::Compiler::generateMethod()
 
           BEGIN_CASE(JSOP_LT)
           BEGIN_CASE(JSOP_LE)
           BEGIN_CASE(JSOP_GT)
           BEGIN_CASE(JSOP_GE)
           BEGIN_CASE(JSOP_EQ)
           BEGIN_CASE(JSOP_NE)
           {
-           if (script->pcCounters) {
-               updateArithCounters(PC, NULL, arithFirstUseType, arithSecondUseType);
+           if (script->scriptCounts) {
+               updateArithCounts(PC, NULL, arithFirstUseType, arithSecondUseType);
                arithUpdated = true;
            }
 
             /* Detect fusions. */
             jsbytecode *next = &PC[JSOP_GE_LENGTH];
             JSOp fused = JSOp(*next);
             if ((fused != JSOP_IFEQ && fused != JSOP_IFNE) || analysis->jumpTarget(next))
                 fused = JSOP_NOP;
 
             /* Get jump target, if any. */
             jsbytecode *target = NULL;
             if (fused != JSOP_NOP) {
-                if (script->pcCounters)
-                    updatePCCounters(PC, &codeStart, &countersUpdated);
+                if (script->scriptCounts)
+                    updatePCCounts(PC, &codeStart, &countsUpdated);
                 target = next + GET_JUMP_OFFSET(next);
                 fixDoubleTypes(target);
             }
 
             BoolStub stub = NULL;
             switch (op) {
               case JSOP_LT:
                 stub = stubs::LessThan;
@@ -2570,30 +2567,30 @@ mjit::Compiler::generateMethod()
           BEGIN_CASE(JSOP_CALLPROP)
           BEGIN_CASE(JSOP_LENGTH)
             if (!jsop_getprop(script->getName(GET_UINT32_INDEX(PC)), knownPushedType(0)))
                 return Compile_Error;
           END_CASE(JSOP_GETPROP)
 
           BEGIN_CASE(JSOP_GETELEM)
           BEGIN_CASE(JSOP_CALLELEM)
-            if (script->pcCounters)
-                updateElemCounters(PC, frame.peek(-2), frame.peek(-1));
+            if (script->scriptCounts)
+                updateElemCounts(PC, frame.peek(-2), frame.peek(-1));
             if (!jsop_getelem())
                 return Compile_Error;
           END_CASE(JSOP_GETELEM)
 
           BEGIN_CASE(JSOP_TOID)
             jsop_toid();
           END_CASE(JSOP_TOID)
 
           BEGIN_CASE(JSOP_SETELEM)
           {
-            if (script->pcCounters)
-                updateElemCounters(PC, frame.peek(-3), frame.peek(-2));
+            if (script->scriptCounts)
+                updateElemCounts(PC, frame.peek(-3), frame.peek(-2));
             jsbytecode *next = &PC[JSOP_SETELEM_LENGTH];
             bool pop = (JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next));
             if (!jsop_setelem(pop))
                 return Compile_Error;
           }
           END_CASE(JSOP_SETELEM);
 
           BEGIN_CASE(JSOP_EVAL)
@@ -2620,19 +2617,19 @@ mjit::Compiler::generateMethod()
                     return status;
             }
             if (!done && inlining()) {
                 CompileStatus status = inlineScriptedFunction(GET_ARGC(PC), callingNew);
                 if (status == Compile_Okay)
                     done = true;
                 else if (status != Compile_InlineAbort)
                     return status;
-                if (script->pcCounters) {
+                if (script->scriptCounts) {
                     /* Code generated while inlining has been accounted for. */
-                    updatePCCounters(PC, &codeStart, &countersUpdated);
+                    updatePCCounts(PC, &codeStart, &countsUpdated);
                 }
             }
 
             FrameSize frameSize;
             frameSize.initStatic(frame.totalDepth(), GET_ARGC(PC));
 
             if (!done) {
                 JaegerSpew(JSpew_Insns, " --- SCRIPTED CALL --- \n");
@@ -2709,18 +2706,18 @@ mjit::Compiler::generateMethod()
           BEGIN_CASE(JSOP_TABLESWITCH)
             /*
              * Note: there is no need to syncForBranch for the various targets of
              * switch statement. The liveness analysis has already marked these as
              * allocated with no registers in use. There is also no need to fix
              * double types, as we don't track types of slots in scripts with
              * switch statements (could be fixed).
              */
-            if (script->pcCounters)
-                updatePCCounters(PC, &codeStart, &countersUpdated);
+            if (script->scriptCounts)
+                updatePCCounts(PC, &codeStart, &countsUpdated);
 #if defined JS_CPU_ARM /* Need to implement jump(BaseIndex) for ARM */
             frame.syncAndKillEverything();
             masm.move(ImmPtr(PC), Registers::ArgReg1);
 
             /* prepareStubCall() is not needed due to syncAndForgetEverything() */
             INLINE_STUBCALL(stubs::TableSwitch, REJOIN_NONE);
             frame.pop();
 
@@ -2729,18 +2726,18 @@ mjit::Compiler::generateMethod()
             if (!jsop_tableswitch(PC))
                 return Compile_Error;
 #endif
             PC += js_GetVariableBytecodeLength(PC);
             break;
           END_CASE(JSOP_TABLESWITCH)
 
           BEGIN_CASE(JSOP_LOOKUPSWITCH)
-            if (script->pcCounters)
-                updatePCCounters(PC, &codeStart, &countersUpdated);
+            if (script->scriptCounts)
+                updatePCCounts(PC, &codeStart, &countsUpdated);
             frame.syncAndForgetEverything();
             masm.move(ImmPtr(PC), Registers::ArgReg1);
 
             /* prepareStubCall() is not needed due to syncAndForgetEverything() */
             INLINE_STUBCALL(stubs::LookupSwitch, REJOIN_NONE);
             frame.pop();
 
             masm.jump(Registers::ReturnReg);
@@ -2758,33 +2755,33 @@ mjit::Compiler::generateMethod()
             // X cond
 
             if (!jsop_ifneq(JSOP_IFNE, PC + GET_JUMP_OFFSET(PC)))
                 return Compile_Error;
           END_CASE(JSOP_CASE)
 
           BEGIN_CASE(JSOP_STRICTEQ)
           BEGIN_CASE(JSOP_STRICTNE)
-            if (script->pcCounters) {
-                updateArithCounters(PC, NULL, arithFirstUseType, arithSecondUseType);
+            if (script->scriptCounts) {
+                updateArithCounts(PC, NULL, arithFirstUseType, arithSecondUseType);
                 arithUpdated = true;
             }
             jsop_stricteq(op);
           END_CASE(JSOP_STRICTEQ)
 
           BEGIN_CASE(JSOP_ITER)
             if (!iter(GET_UINT8(PC)))
                 return Compile_Error;
           END_CASE(JSOP_ITER)
 
           BEGIN_CASE(JSOP_MOREITER)
           {
             /* At the byte level, this is always fused with IFNE or IFNEX. */
-            if (script->pcCounters)
-                updatePCCounters(PC, &codeStart, &countersUpdated);
+            if (script->scriptCounts)
+                updatePCCounts(PC, &codeStart, &countsUpdated);
             jsbytecode *target = &PC[JSOP_MOREITER_LENGTH];
             JSOp next = JSOp(*target);
             JS_ASSERT(next == JSOP_IFNE);
 
             target += GET_JUMP_OFFSET(target);
 
             fixDoubleTypes(target);
             if (!iterMore(target))
@@ -2899,50 +2896,50 @@ mjit::Compiler::generateMethod()
             jsop_initelem();
             frame.popn(2);
           END_CASE(JSOP_INITELEM)
 
           BEGIN_CASE(JSOP_INCARG)
           BEGIN_CASE(JSOP_DECARG)
           BEGIN_CASE(JSOP_ARGINC)
           BEGIN_CASE(JSOP_ARGDEC)
-            if (script->pcCounters) {
+            if (script->scriptCounts) {
                 restoreVarType();
                 FrameEntry *fe = frame.getArg(GET_SLOTNO(PC));
                 if (fe->isTypeKnown())
                     arithFirstUseType = fe->getKnownType();
             }
 
             if (!jsop_arginc(op, GET_SLOTNO(PC)))
                 return Compile_Retry;
 
-            if (script->pcCounters) {
+            if (script->scriptCounts) {
                 FrameEntry *fe = frame.getArg(GET_SLOTNO(PC));
-                updateArithCounters(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
+                updateArithCounts(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
                 arithUpdated = true;
             }
           END_CASE(JSOP_ARGDEC)
 
           BEGIN_CASE(JSOP_INCLOCAL)
           BEGIN_CASE(JSOP_DECLOCAL)
           BEGIN_CASE(JSOP_LOCALINC)
           BEGIN_CASE(JSOP_LOCALDEC)
-            if (script->pcCounters) {
+            if (script->scriptCounts) {
                 restoreVarType();
                 FrameEntry *fe = frame.getLocal(GET_SLOTNO(PC));
                 if (fe->isTypeKnown())
                     arithFirstUseType = fe->getKnownType();
             }
 
             if (!jsop_localinc(op, GET_SLOTNO(PC)))
                 return Compile_Retry;
 
-            if (script->pcCounters) {
+            if (script->scriptCounts) {
                 FrameEntry *fe = frame.getLocal(GET_SLOTNO(PC));
-                updateArithCounters(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
+                updateArithCounts(PC, fe, arithFirstUseType, JSVAL_TYPE_INT32);
                 arithUpdated = true;
             }
           END_CASE(JSOP_LOCALDEC)
 
           BEGIN_CASE(JSOP_BINDNAME)
             jsop_bindname(script->getName(GET_UINT32_INDEX(PC)));
           END_CASE(JSOP_BINDNAME)
 
@@ -3112,18 +3109,18 @@ mjit::Compiler::generateMethod()
           }
           END_CASE(JSOP_OBJECT)
 
           BEGIN_CASE(JSOP_UINT24)
             frame.push(Value(Int32Value((int32_t) GET_UINT24(PC))));
           END_CASE(JSOP_UINT24)
 
           BEGIN_CASE(JSOP_STOP)
-            if (script->pcCounters)
-                updatePCCounters(PC, &codeStart, &countersUpdated);
+            if (script->scriptCounts)
+                updatePCCounts(PC, &codeStart, &countsUpdated);
             emitReturn(NULL);
             goto done;
           END_CASE(JSOP_STOP)
 
           BEGIN_CASE(JSOP_GETXPROP)
             if (!jsop_xname(script->getName(GET_UINT32_INDEX(PC))))
                 return Compile_Error;
           END_CASE(JSOP_GETXPROP)
@@ -3190,42 +3187,42 @@ mjit::Compiler::generateMethod()
                 FrameEntry *fe = frame.getStack(opinfo->stackDepth - nuses + i);
                 if (fe) {
                     /* fe may be NULL for conditionally pushed entries, e.g. JSOP_AND */
                     frame.extra(fe).types = analysis->pushedTypes(lastPC - script->code, i);
                 }
             }
         }
 
-        if (script->pcCounters) {
+        if (script->scriptCounts) {
             size_t length = masm.size() - masm.distanceOf(codeStart);
             bool typesUpdated = false;
 
             /* Update information about the type of value pushed by arithmetic ops. */
             if ((js_CodeSpec[op].format & JOF_ARITH) && !arithUpdated) {
                 FrameEntry *pushed = NULL;
                 if (PC == lastPC + GetBytecodeLength(lastPC))
                     pushed = frame.peek(-1);
-                updateArithCounters(lastPC, pushed, arithFirstUseType, arithSecondUseType);
+                updateArithCounts(lastPC, pushed, arithFirstUseType, arithSecondUseType);
                 typesUpdated = true;
             }
 
             /* Update information about the result type of access operations. */
-            if (OpcodeCounts::accessOp(op) &&
+            if (PCCounts::accessOp(op) &&
                 op != JSOP_SETPROP && op != JSOP_SETELEM) {
                 FrameEntry *fe = (GetDefCount(script, lastPC - script->code) == 1)
                     ? frame.peek(-1)
                     : frame.peek(-2);
                 updatePCTypes(lastPC, fe);
                 typesUpdated = true;
             }
 
-            if (countersUpdated || typesUpdated || length != 0) {
-                if (!countersUpdated)
-                    updatePCCounters(lastPC, &codeStart, &countersUpdated);
+            if (countsUpdated || typesUpdated || length != 0) {
+                if (!countsUpdated)
+                    updatePCCounts(lastPC, &codeStart, &countsUpdated);
 
                 if (pcLengths) {
                     /* Fill in the amount of inline code generated for the op. */
                     uint32_t offset = ssa.frameLength(a->inlineIndex) + lastPC - script->code;
                     pcLengths[offset].codeLength += length;
                 }
             }
         } else if (pcLengths) {
@@ -3241,19 +3238,19 @@ mjit::Compiler::generateMethod()
   done:
     return Compile_Okay;
 }
 
 #undef END_CASE
 #undef BEGIN_CASE
 
 void
-mjit::Compiler::updatePCCounters(jsbytecode *pc, Label *start, bool *updated)
+mjit::Compiler::updatePCCounts(jsbytecode *pc, Label *start, bool *updated)
 {
-    JS_ASSERT(script->pcCounters);
+    JS_ASSERT(script->scriptCounts);
 
     /*
      * Bump the METHODJIT count for the opcode, read the METHODJIT_CODE_LENGTH
      * and METHODJIT_PICS_LENGTH counts, indicating the amounts of inline path
      * code and generated code, respectively, and add them to the accumulated
      * total for the op.
      */
     uint32_t offset = ssa.frameLength(a->inlineIndex) + pc - script->code;
@@ -3262,28 +3259,28 @@ mjit::Compiler::updatePCCounters(jsbytec
      * Base register for addresses, we can't use AbsoluteAddress in all places.
      * This may hold a live value, so write it out to the top of the stack
      * first. This cannot overflow the stack, as space is always reserved for
      * an extra callee frame.
      */
     RegisterID reg = Registers::ReturnReg;
     masm.storePtr(reg, frame.addressOfTop());
 
-    OpcodeCounts counts = script->getCounts(pc);
-
-    double *code = &counts.get(OpcodeCounts::BASE_METHODJIT_CODE);
+    PCCounts counts = script->getPCCounts(pc);
+
+    double *code = &counts.get(PCCounts::BASE_METHODJIT_CODE);
     double *codeLength = &pcLengths[offset].codeLength;
-    masm.addCounter(codeLength, code, reg);
-
-    double *pics = &counts.get(OpcodeCounts::BASE_METHODJIT_PICS);
+    masm.addCount(codeLength, code, reg);
+
+    double *pics = &counts.get(PCCounts::BASE_METHODJIT_PICS);
     double *picsLength = &pcLengths[offset].picsLength;
-    masm.addCounter(picsLength, pics, reg);
-
-    double *counter = &counts.get(OpcodeCounts::BASE_METHODJIT);
-    masm.bumpCounter(counter, reg);
+    masm.addCount(picsLength, pics, reg);
+
+    double *count = &counts.get(PCCounts::BASE_METHODJIT);
+    masm.bumpCount(count, reg);
 
     /* Reload the base register's original value. */
     masm.loadPtr(frame.addressOfTop(), reg);
 
     /* The start label should reflect the code for the op, not instrumentation. */
     *start = masm.label();
     *updated = true;
 }
@@ -3305,194 +3302,194 @@ HasPayloadType(types::TypeSet *types)
     return (flags == types::TYPE_FLAG_UNDEFINED)
         || (flags == types::TYPE_FLAG_NULL)
         || (flags == types::TYPE_FLAG_BOOLEAN);
 }
 
 void
 mjit::Compiler::updatePCTypes(jsbytecode *pc, FrameEntry *fe)
 {
-    JS_ASSERT(script->pcCounters);
+    JS_ASSERT(script->scriptCounts);
 
     /*
-     * Get a temporary register, as for updatePCCounters. Don't overlap with
+     * Get a temporary register, as for updatePCCounts. Don't overlap with
      * the backing store for the entry's type tag, if there is one.
      */
     RegisterID reg = Registers::ReturnReg;
     if (frame.peekTypeInRegister(fe) && reg == frame.tempRegForType(fe)) {
         JS_STATIC_ASSERT(Registers::ReturnReg != Registers::ArgReg1);
         reg = Registers::ArgReg1;
     }
     masm.push(reg);
 
-    OpcodeCounts counts = script->getCounts(pc);
-
-    /* Update the counters for pushed type tags and possible access types. */
+    PCCounts counts = script->getPCCounts(pc);
+
+    /* Update the counts for pushed type tags and possible access types. */
     if (fe->isTypeKnown()) {
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_MONOMORPHIC), reg);
-        OpcodeCounts::AccessCounts counter = OpcodeCounts::ACCESS_OBJECT;
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_MONOMORPHIC), reg);
+        PCCounts::AccessCounts count = PCCounts::ACCESS_OBJECT;
         switch (fe->getKnownType()) {
-          case JSVAL_TYPE_UNDEFINED:  counter = OpcodeCounts::ACCESS_UNDEFINED;  break;
-          case JSVAL_TYPE_NULL:       counter = OpcodeCounts::ACCESS_NULL;       break;
-          case JSVAL_TYPE_BOOLEAN:    counter = OpcodeCounts::ACCESS_BOOLEAN;    break;
-          case JSVAL_TYPE_INT32:      counter = OpcodeCounts::ACCESS_INT32;      break;
-          case JSVAL_TYPE_DOUBLE:     counter = OpcodeCounts::ACCESS_DOUBLE;     break;
-          case JSVAL_TYPE_STRING:     counter = OpcodeCounts::ACCESS_STRING;     break;
-          case JSVAL_TYPE_OBJECT:     counter = OpcodeCounts::ACCESS_OBJECT;     break;
+          case JSVAL_TYPE_UNDEFINED:  count = PCCounts::ACCESS_UNDEFINED;  break;
+          case JSVAL_TYPE_NULL:       count = PCCounts::ACCESS_NULL;       break;
+          case JSVAL_TYPE_BOOLEAN:    count = PCCounts::ACCESS_BOOLEAN;    break;
+          case JSVAL_TYPE_INT32:      count = PCCounts::ACCESS_INT32;      break;
+          case JSVAL_TYPE_DOUBLE:     count = PCCounts::ACCESS_DOUBLE;     break;
+          case JSVAL_TYPE_STRING:     count = PCCounts::ACCESS_STRING;     break;
+          case JSVAL_TYPE_OBJECT:     count = PCCounts::ACCESS_OBJECT;     break;
           default:;
         }
-        if (counter)
-            masm.bumpCounter(&counts.get(counter), reg);
+        if (count)
+            masm.bumpCount(&counts.get(count), reg);
     } else {
         types::TypeSet *types = frame.extra(fe).types;
         if (types && HasPayloadType(types))
-            masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_DIMORPHIC), reg);
+            masm.bumpCount(&counts.get(PCCounts::ACCESS_DIMORPHIC), reg);
         else
-            masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_POLYMORPHIC), reg);
+            masm.bumpCount(&counts.get(PCCounts::ACCESS_POLYMORPHIC), reg);
 
         frame.loadTypeIntoReg(fe, reg);
 
         Jump j = masm.testUndefined(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_UNDEFINED), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_UNDEFINED), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
 
         j = masm.testNull(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_NULL), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_NULL), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
 
         j = masm.testBoolean(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_BOOLEAN), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_BOOLEAN), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
 
         j = masm.testInt32(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_INT32), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_INT32), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
 
         j = masm.testDouble(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_DOUBLE), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_DOUBLE), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
 
         j = masm.testString(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_STRING), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_STRING), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
 
         j = masm.testObject(Assembler::NotEqual, reg);
-        masm.bumpCounter(&counts.get(OpcodeCounts::ACCESS_OBJECT), reg);
+        masm.bumpCount(&counts.get(PCCounts::ACCESS_OBJECT), reg);
         frame.loadTypeIntoReg(fe, reg);
         j.linkTo(masm.label(), &masm);
     }
 
-    /* Update the counter for accesses with type barriers. */
+    /* Update the count for accesses with type barriers. */
     if (js_CodeSpec[*pc].format & JOF_TYPESET) {
-        double *counter = &counts.get(hasTypeBarriers(pc)
-                                      ? OpcodeCounts::ACCESS_BARRIER
-                                      : OpcodeCounts::ACCESS_NOBARRIER);
-        masm.bumpCounter(counter, reg);
+        double *count = &counts.get(hasTypeBarriers(pc)
+                                      ? PCCounts::ACCESS_BARRIER
+                                      : PCCounts::ACCESS_NOBARRIER);
+        masm.bumpCount(count, reg);
     }
 
     /* Reload the base register's original value. */
     masm.pop(reg);
 }
 
 void
-mjit::Compiler::updateArithCounters(jsbytecode *pc, FrameEntry *fe,
-                                    JSValueType firstUseType, JSValueType secondUseType)
+mjit::Compiler::updateArithCounts(jsbytecode *pc, FrameEntry *fe,
+                                  JSValueType firstUseType, JSValueType secondUseType)
 {
-    JS_ASSERT(script->pcCounters);
+    JS_ASSERT(script->scriptCounts);
 
     RegisterID reg = Registers::ReturnReg;
     masm.push(reg);
 
     /*
-     * What counter we bump for arithmetic expressions depend on the
+     * What count we bump for arithmetic expressions depend on the
      * known types of its operands.
      *
      * ARITH_INT: operands are known ints, result is int
      * ARITH_OVERFLOW: operands are known ints, result is double
      * ARITH_DOUBLE: either operand is a known double, result is double
      * ARITH_OTHER: operands are monomorphic but not int or double
      * ARITH_UNKNOWN: operands are polymorphic
      */
 
-    OpcodeCounts::ArithCounts counter;
+    PCCounts::ArithCounts count;
     if (firstUseType == JSVAL_TYPE_INT32 && secondUseType == JSVAL_TYPE_INT32 &&
         (!fe || fe->isNotType(JSVAL_TYPE_DOUBLE))) {
-        counter = OpcodeCounts::ARITH_INT;
+        count = PCCounts::ARITH_INT;
     } else if (firstUseType == JSVAL_TYPE_INT32 || firstUseType == JSVAL_TYPE_DOUBLE ||
                secondUseType == JSVAL_TYPE_INT32 || secondUseType == JSVAL_TYPE_DOUBLE) {
-        counter = OpcodeCounts::ARITH_DOUBLE;
+        count = PCCounts::ARITH_DOUBLE;
     } else if (firstUseType != JSVAL_TYPE_UNKNOWN && secondUseType != JSVAL_TYPE_UNKNOWN &&
                (!fe || fe->isTypeKnown())) {
-        counter = OpcodeCounts::ARITH_OTHER;
+        count = PCCounts::ARITH_OTHER;
     } else {
-        counter = OpcodeCounts::ARITH_UNKNOWN;
-    }
-
-    masm.bumpCounter(&script->getCounts(pc).get(counter), reg);
+        count = PCCounts::ARITH_UNKNOWN;
+    }
+
+    masm.bumpCount(&script->getPCCounts(pc).get(count), reg);
     masm.pop(reg);
 }
 
 void
-mjit::Compiler::updateElemCounters(jsbytecode *pc, FrameEntry *obj, FrameEntry *id)
+mjit::Compiler::updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id)
 {
-    JS_ASSERT(script->pcCounters);
+    JS_ASSERT(script->scriptCounts);
 
     RegisterID reg = Registers::ReturnReg;
     masm.push(reg);
 
-    OpcodeCounts counts = script->getCounts(pc);
-
-    OpcodeCounts::ElementCounts counter;
+    PCCounts counts = script->getPCCounts(pc);
+
+    PCCounts::ElementCounts count;
     if (id->isTypeKnown()) {
         switch (id->getKnownType()) {
-          case JSVAL_TYPE_INT32:   counter = OpcodeCounts::ELEM_ID_INT;     break;
-          case JSVAL_TYPE_DOUBLE:  counter = OpcodeCounts::ELEM_ID_DOUBLE;  break;
-          default:                 counter = OpcodeCounts::ELEM_ID_OTHER;   break;
+          case JSVAL_TYPE_INT32:   count = PCCounts::ELEM_ID_INT;     break;
+          case JSVAL_TYPE_DOUBLE:  count = PCCounts::ELEM_ID_DOUBLE;  break;
+          default:                 count = PCCounts::ELEM_ID_OTHER;   break;
         }
     } else {
-        counter = OpcodeCounts::ELEM_ID_UNKNOWN;
-    }
-    masm.bumpCounter(&counts.get(counter), reg);
+        count = PCCounts::ELEM_ID_UNKNOWN;
+    }
+    masm.bumpCount(&counts.get(count), reg);
 
     if (obj->mightBeType(JSVAL_TYPE_OBJECT)) {
         types::TypeSet *types = frame.extra(obj).types;
         if (types && !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_TYPED_ARRAY) &&
             types->getTypedArrayType(cx) != TypedArray::TYPE_MAX) {
-            counter = OpcodeCounts::ELEM_OBJECT_TYPED;
+            count = PCCounts::ELEM_OBJECT_TYPED;
         } else if (types && !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY)) {
             if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY))
-                counter = OpcodeCounts::ELEM_OBJECT_PACKED;
+                count = PCCounts::ELEM_OBJECT_PACKED;
             else
-                counter = OpcodeCounts::ELEM_OBJECT_DENSE;
+                count = PCCounts::ELEM_OBJECT_DENSE;
         } else {
-            counter = OpcodeCounts::ELEM_OBJECT_OTHER;
+            count = PCCounts::ELEM_OBJECT_OTHER;
         }
-        masm.bumpCounter(&counts.get(counter), reg);
+        masm.bumpCount(&counts.get(count), reg);
     } else {
-        masm.bumpCounter(&counts.get(OpcodeCounts::ELEM_OBJECT_OTHER), reg);
+        masm.bumpCount(&counts.get(PCCounts::ELEM_OBJECT_OTHER), reg);
     }
 
     masm.pop(reg);
 }
 
 void
-mjit::Compiler::bumpPropCounter(jsbytecode *pc, int counter)
+mjit::Compiler::bumpPropCount(jsbytecode *pc, int count)
 {
     /* Don't accumulate counts for property ops fused with other ops. */
     if (!(js_CodeSpec[*pc].format & JOF_PROP))
         return;
     RegisterID reg = Registers::ReturnReg;
     masm.push(reg);
-    masm.bumpCounter(&script->getCounts(pc).get(counter), reg);
+    masm.bumpCount(&script->getPCCounts(pc).get(count), reg);
     masm.pop(reg);
 }
 
 JSC::MacroAssembler::Label
 mjit::Compiler::labelOf(jsbytecode *pc, uint32_t inlineIndex)
 {
     ActiveFrame *a = (inlineIndex == UINT32_MAX) ? outer : inlineFrames[inlineIndex];
     JS_ASSERT(uint32_t(pc - a->script->code) < a->script->length);
@@ -3823,17 +3820,17 @@ mjit::Compiler::prepareStubCall(Uses use
     JaegerSpew(JSpew_Insns, " ---- FRAME SYNCING DONE ---- \n");
 }
 
 JSC::MacroAssembler::Call
 mjit::Compiler::emitStubCall(void *ptr, DataLabelPtr *pinline)
 {
     JaegerSpew(JSpew_Insns, " ---- CALLING STUB ---- \n");
 
-    masm.bumpStubCounter(script, PC, Registers::tempCallReg());
+    masm.bumpStubCount(script, PC, Registers::tempCallReg());
 
     Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
                                   ptr, outerPC(), pinline, frame.totalDepth());
     JaegerSpew(JSpew_Insns, " ---- END STUB CALL ---- \n");
     return cl;
 }
 
 void
@@ -4804,18 +4801,18 @@ mjit::Compiler::emitStubCmpOp(BoolStub s
 void
 mjit::Compiler::jsop_setprop_slow(PropertyName *name)
 {
     prepareStubCall(Uses(2));
     masm.move(ImmPtr(name), Registers::ArgReg1);
     INLINE_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
     JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
     frame.shimmy(1);
-    if (script->pcCounters)
-        bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
+    if (script->scriptCounts)
+        bumpPropCount(PC, PCCounts::PROP_OTHER);
 }
 
 void
 mjit::Compiler::jsop_getprop_slow(PropertyName *name, bool forPrototype)
 {
     /* See ::jsop_getprop */
     RejoinState rejoin = forPrototype ? REJOIN_THIS_PROTOTYPE : REJOIN_GETTER;
 
@@ -4824,18 +4821,18 @@ mjit::Compiler::jsop_getprop_slow(Proper
     INLINE_STUBCALL(forPrototype ? stubs::GetPropNoCache : stubs::GetProp, rejoin);
 
     if (!forPrototype)
         testPushedType(rejoin, -1, /* ool = */ false);
 
     frame.pop();
     frame.pushSynced(JSVAL_TYPE_UNKNOWN);
 
-    if (script->pcCounters)
-        bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
+    if (script->scriptCounts)
+        bumpPropCount(PC, PCCounts::PROP_OTHER);
 }
 
 #ifdef JS_MONOIC
 void
 mjit::Compiler::passMICAddress(GlobalNameICInfo &ic)
 {
     ic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
 }
@@ -4892,18 +4889,18 @@ mjit::Compiler::jsop_getprop(PropertyNam
         /* Check if this is an array we can make a loop invariant entry for. */
         if (loop && loop->generatingInvariants()) {
             CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
             FrameEntry *fe = loop->invariantLength(topv);
             if (fe) {
                 frame.learnType(fe, JSVAL_TYPE_INT32, false);
                 frame.pop();
                 frame.pushCopyOf(fe);
-                if (script->pcCounters)
-                    bumpPropCounter(PC, OpcodeCounts::PROP_STATIC);
+                if (script->scriptCounts)
+                    bumpPropCount(PC, PCCounts::PROP_STATIC);
                 return true;
             }
         }
 
         types::TypeSet *types = analysis->poppedTypes(PC, 0);
 
         /*
          * Check if we are accessing the 'length' property of a known dense array.
@@ -4922,18 +4919,18 @@ mjit::Compiler::jsop_getprop(PropertyNam
                     testPushedType(rejoin, -1);
             }
             RegisterID result = frame.allocReg();
             RegisterID reg = frame.tempRegForData(top);
             frame.pop();
             masm.loadPtr(Address(reg, JSObject::offsetOfElements()), result);
             masm.load32(Address(result, ObjectElements::offsetOfLength()), result);
             frame.pushTypedPayload(JSVAL_TYPE_INT32, result);
-            if (script->pcCounters)
-                bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
+            if (script->scriptCounts)
+                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
             if (!isObject)
                 stubcc.rejoin(Changes(1));
             return true;
         }
 
         /*
          * Check if we're accessing the 'length' property of a typed array.
          * The typed array length always fits in an int32.
@@ -4948,32 +4945,32 @@ mjit::Compiler::jsop_getprop(PropertyNam
                 OOL_STUBCALL(stubs::GetProp, rejoin);
                 if (rejoin == REJOIN_GETTER)
                     testPushedType(rejoin, -1);
             }
             RegisterID reg = frame.copyDataIntoReg(top);
             frame.pop();
             masm.loadPayload(Address(reg, TypedArray::lengthOffset()), reg);
             frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
-            if (script->pcCounters)
-                bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
+            if (script->scriptCounts)
+                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
             if (!isObject)
                 stubcc.rejoin(Changes(1));
             return true;
         }
 
         /*
          * Check if we are accessing the 'length' of the lazy arguments for the
          * current frame.
          */
         if (types->isLazyArguments(cx)) {
             frame.pop();
             frame.pushWord(Address(JSFrameReg, StackFrame::offsetOfNumActual()), JSVAL_TYPE_INT32);
-            if (script->pcCounters)
-                bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
+            if (script->scriptCounts)
+                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
             return true;
         }
     }
 
     /* If the access will definitely be fetching a particular value, nop it. */
     bool testObject;
     JSObject *singleton =
         (*PC == JSOP_GETPROP || *PC == JSOP_CALLPROP) ? pushedSingleton(0) : NULL;
@@ -4986,35 +4983,35 @@ mjit::Compiler::jsop_getprop(PropertyNam
             stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
             OOL_STUBCALL(stubs::GetProp, REJOIN_FALLTHROUGH);
             testPushedType(REJOIN_FALLTHROUGH, -1);
         }
 
         frame.pop();
         frame.push(ObjectValue(*singleton));
 
-        if (script->pcCounters && cx->typeInferenceEnabled())
-            bumpPropCounter(PC, OpcodeCounts::PROP_STATIC);
+        if (script->scriptCounts && cx->typeInferenceEnabled())
+            bumpPropCount(PC, PCCounts::PROP_STATIC);
 
         if (testObject)
             stubcc.rejoin(Changes(1));
 
         return true;
     }
 
     /* Check if this is a property access we can make a loop invariant entry for. */
     if (loop && loop->generatingInvariants() && !hasTypeBarriers(PC)) {
         CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
         if (FrameEntry *fe = loop->invariantProperty(topv, ATOM_TO_JSID(name))) {
             if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
                 frame.learnType(fe, knownType, false);
             frame.pop();
             frame.pushCopyOf(fe);
-            if (script->pcCounters)
-                bumpPropCounter(PC, OpcodeCounts::PROP_STATIC);
+            if (script->scriptCounts)
+                bumpPropCount(PC, PCCounts::PROP_STATIC);
             return true;
         }
     }
 
     /* If the incoming type will never PIC, take slow path. */
     if (top->isNotType(JSVAL_TYPE_OBJECT)) {
         jsop_getprop_slow(name, forPrototype);
         return true;
@@ -5051,18 +5048,18 @@ mjit::Compiler::jsop_getprop(PropertyNam
                 stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
                 OOL_STUBCALL(stubs::GetProp, rejoin);
                 if (rejoin == REJOIN_GETTER)
                     testPushedType(rejoin, -1);
             }
             RegisterID reg = frame.tempRegForData(top);
             frame.pop();
 
-            if (script->pcCounters)
-                bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
+            if (script->scriptCounts)
+                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
 
             Address address(reg, JSObject::getFixedSlotOffset(slot));
             BarrierState barrier = pushAddressMaybeBarrier(address, knownType, false);
             if (!isObject)
                 stubcc.rejoin(Changes(1));
             finishBarrier(barrier, rejoin, 0);
 
             return true;
@@ -5070,18 +5067,18 @@ mjit::Compiler::jsop_getprop(PropertyNam
     }
 
     /* Check for a dynamic dispatch. */
     if (cx->typeInferenceEnabled()) {
         if (*PC == JSOP_CALLPROP && jsop_getprop_dispatch(name))
             return true;
     }
 
-    if (script->pcCounters)
-        bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
+    if (script->scriptCounts)
+        bumpPropCount(PC, PCCounts::PROP_OTHER);
 
     /*
      * These two must be loaded first. The objReg because the string path
      * wants to read it, and the shapeReg because it could cause a spill that
      * the string path wouldn't sink back.
      */
     RegisterID objReg = frame.copyDataIntoReg(top);
     RegisterID shapeReg = frame.allocReg();
@@ -5432,18 +5429,18 @@ mjit::Compiler::jsop_getprop_dispatch(Pr
     stubcc.leave();
     stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
     OOL_STUBCALL(stubs::GetProp, REJOIN_FALLTHROUGH);
     testPushedType(REJOIN_FALLTHROUGH, -1);
 
     frame.pop();
     frame.pushTypedPayload(JSVAL_TYPE_OBJECT, pushreg);
 
-    if (script->pcCounters)
-        bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
+    if (script->scriptCounts)
+        bumpPropCount(PC, PCCounts::PROP_DEFINITE);
 
     stubcc.rejoin(Changes(2));
     return true;
 }
 
 bool
 mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
 {
@@ -5535,24 +5532,24 @@ mjit::Compiler::jsop_setprop(PropertyNam
                 stubcc.leave();
                 stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
                 OOL_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
             }
             frame.storeTo(rhs, Address(reg, JSObject::getFixedSlotOffset(slot)), popGuaranteed);
             frame.shimmy(1);
             if (!isObject)
                 stubcc.rejoin(Changes(1));
-            if (script->pcCounters)
-                bumpPropCounter(PC, OpcodeCounts::PROP_DEFINITE);
+            if (script->scriptCounts)
+                bumpPropCount(PC, PCCounts::PROP_DEFINITE);
             return true;
         }
     }
 
-    if (script->pcCounters)
-        bumpPropCounter(PC, OpcodeCounts::PROP_OTHER);
+    if (script->scriptCounts)
+        bumpPropCount(PC, PCCounts::PROP_OTHER);
 
     JSOp op = JSOp(*PC);
 
 #ifdef JSGC_INCREMENTAL_MJ
     /* Write barrier. We don't have type information for JSOP_SETNAME. */
     if (cx->compartment->needsBarrier() &&
         (!types || op == JSOP_SETNAME || types->propertyNeedsBarrier(cx, id)))
     {
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -559,22 +559,22 @@ private:
   private:
     CompileStatus performCompilation();
     CompileStatus generatePrologue();
     CompileStatus generateMethod();
     CompileStatus generateEpilogue();
     CompileStatus finishThisUp();
     CompileStatus pushActiveFrame(JSScript *script, uint32_t argc);
     void popActiveFrame();
-    void updatePCCounters(jsbytecode *pc, Label *start, bool *updated);
+    void updatePCCounts(jsbytecode *pc, Label *start, bool *updated);
     void updatePCTypes(jsbytecode *pc, FrameEntry *fe);
-    void updateArithCounters(jsbytecode *pc, FrameEntry *fe,
+    void updateArithCounts(jsbytecode *pc, FrameEntry *fe,
                              JSValueType firstUseType, JSValueType secondUseType);
-    void updateElemCounters(jsbytecode *pc, FrameEntry *obj, FrameEntry *id);
-    void bumpPropCounter(jsbytecode *pc, int counter);
+    void updateElemCounts(jsbytecode *pc, FrameEntry *obj, FrameEntry *id);
+    void bumpPropCount(jsbytecode *pc, int count);
 
     /* Analysis helpers. */
     CompileStatus prepareInferenceTypes(JSScript *script, ActiveFrame *a);
     void ensureDoubleArguments();
     void markUndefinedLocal(uint32_t offset, uint32_t i);
     void markUndefinedLocals();
     void fixDoubleTypes(jsbytecode *target);
     void watchGlobalReallocation();
--- a/js/src/methodjit/MethodJIT.cpp
+++ b/js/src/methodjit/MethodJIT.cpp
@@ -1357,17 +1357,16 @@ JITScript::destroyChunk(JSContext *cx, u
     if (chunkIndex == 0) {
         if (argsCheckPool) {
             argsCheckPool->release();
             argsCheckPool = NULL;
         }
 
         invokeEntry = NULL;
         fastEntry = NULL;
-        arityCheckEntry = NULL;
         argsCheckEntry = NULL;
 
         if (script->jitNormal == this)
             script->jitArityCheckNormal = NULL;
         else
             script->jitArityCheckCtor = NULL;
 
         // Fixup any ICs still referring to this chunk.
--- a/js/src/methodjit/MethodJIT.h
+++ b/js/src/methodjit/MethodJIT.h
@@ -801,17 +801,16 @@ struct CrossChunkEdge
 };
 
 struct JITScript
 {
     JSScript        *script;
 
     void            *invokeEntry;       /* invoke address */
     void            *fastEntry;         /* cached entry, fastest */
-    void            *arityCheckEntry;   /* arity check address */
     void            *argsCheckEntry;    /* arguments check address */
 
     /* List of inline caches jumping to the fastEntry. */
     JSCList         callers;
 
     uint32_t        nchunks;
     uint32_t        nedges;
 
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -621,17 +621,17 @@ class CallCompiler : public BaseCompiler
         /*
          * Write the rejoin state to indicate this is a compilation call made
          * from an IC (the recompiler cannot detect calls made from ICs
          * automatically).
          */
         masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), false)),
                       FrameAddress(offsetof(VMFrame, stubRejoin)));
 
-        masm.bumpStubCounter(f.script(), f.pc(), Registers::tempCallReg());
+        masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
 
         /* Try and compile. On success we get back the nmap pointer. */
         void *compilePtr = JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction);
         DataLabelPtr inlined;
         if (ic.frameSize.isStatic()) {
             masm.move(Imm32(ic.frameSize.staticArgc()), Registers::ArgReg1);
             masm.fallibleVMCall(cx->typeInferenceEnabled(),
                                 compilePtr, f.regs.pc, &inlined, ic.frameSize.staticLocalSlots());
@@ -845,25 +845,25 @@ class CallCompiler : public BaseCompiler
          * store the return value than FASTCALLs, and without additional
          * information we cannot tell which one is active on a VMFrame.
          */
         masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), true)),
                       FrameAddress(offsetof(VMFrame, stubRejoin)));
 
         /* N.B. After this call, the frame will have a dynamic frame size. */
         if (ic.frameSize.isDynamic()) {
-            masm.bumpStubCounter(f.script(), f.pc(), Registers::tempCallReg());
+            masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
             masm.fallibleVMCall(cx->typeInferenceEnabled(),
                                 JS_FUNC_TO_DATA_PTR(void *, ic::SplatApplyArgs),
                                 f.regs.pc, NULL, initialFrameDepth);
         }
 
         Registers tempRegs = Registers::tempCallRegMask();
         RegisterID t0 = tempRegs.takeAnyReg().reg();
-        masm.bumpStubCounter(f.script(), f.pc(), t0);
+        masm.bumpStubCount(f.script(), f.pc(), t0);
 
         int32_t storeFrameDepth = ic.frameSize.isStatic() ? initialFrameDepth : -1;
         masm.setupFallibleABICall(cx->typeInferenceEnabled(), f.regs.pc, storeFrameDepth);
 
         /* Grab cx. */
 #ifdef JS_CPU_X86
         RegisterID cxReg = tempRegs.takeAnyReg().reg();
 #else
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1073,17 +1073,17 @@ class GetPropCompiler : public PICStubCo
         if (tempRegs.hasReg(pic.objReg)) {
             tempRegs.takeReg(pic.objReg);
         } else {
             holdObjReg = tempRegs.takeAnyReg().reg();
             masm.move(pic.objReg, holdObjReg);
         }
 
         RegisterID t0 = tempRegs.takeAnyReg().reg();
-        masm.bumpStubCounter(f.script(), f.pc(), t0);
+        masm.bumpStubCount(f.script(), f.pc(), t0);
 
         /*
          * Initialize vp, which is either a slot in the object (the holder,
          * actually, which must equal the object here) or undefined.
          * Use vp == sp (which for CALLPROP will actually be the original
          * sp + 1), to avoid clobbering stack values.
          */
         int32_t vpOffset = (char *) f.regs.sp - (char *) f.fp();
--- a/js/src/methodjit/StubCompiler.cpp
+++ b/js/src/methodjit/StubCompiler.cpp
@@ -174,17 +174,17 @@ StubCompiler::emitStubCall(void *ptr, Re
 {
     return emitStubCall(ptr, rejoin, uses, frame.totalDepth());
 }
 
 JSC::MacroAssembler::Call
 StubCompiler::emitStubCall(void *ptr, RejoinState rejoin, Uses uses, int32_t slots)
 {
     JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n");
-    masm.bumpStubCounter(cc.script, cc.PC, Registers::tempCallReg());
+    masm.bumpStubCount(cc.script, cc.PC, Registers::tempCallReg());
     DataLabelPtr inlinePatch;
     Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
                                   ptr, cc.outerPC(), &inlinePatch, slots);
     JaegerSpew(JSpew_Insns, " ---- END SLOW CALL CODE ---- \n");
 
     /* Add the call site for debugging and recompilation. */
     Compiler::InternalCallSite site(masm.callReturnOffset(cl),
                                     cc.inlineIndex(), cc.inlinePC(),
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2110,16 +2110,39 @@ Debugger::findScripts(JSContext *cx, uns
             return false;
         result->setDenseArrayElement(i, ObjectValue(*scriptObject));
     }
 
     args.rval().setObject(*result);
     return true;
 }
 
+JSBool
+Debugger::wrap(JSContext *cx, unsigned argc, Value *vp)
+{
+    REQUIRE_ARGC("Debugger.prototype.wrap", 1);
+    THIS_DEBUGGER(cx, argc, vp, "wrap", args, dbg);
+
+    /* Wrapping a non-object returns the value unchanged. */
+    if (!args[0].isObject()) {
+        args.rval() = args[0];
+        return true;
+    }
+
+    JSObject *obj = dbg->unwrapDebuggeeArgument(cx, args[0]);
+    if (!obj)
+        return false;
+
+    args.rval() = args[0];
+    if (!dbg->wrapDebuggeeValue(cx, &args.rval()))
+        return false;
+
+    return true;
+}
+
 JSPropertySpec Debugger::properties[] = {
     JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
     JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
             Debugger::setOnDebuggerStatement, 0),
     JS_PSGS("onExceptionUnwind", Debugger::getOnExceptionUnwind,
             Debugger::setOnExceptionUnwind, 0),
     JS_PSGS("onNewScript", Debugger::getOnNewScript, Debugger::setOnNewScript, 0),
     JS_PSGS("onEnterFrame", Debugger::getOnEnterFrame, Debugger::setOnEnterFrame, 0),
@@ -2131,16 +2154,17 @@ JSPropertySpec Debugger::properties[] = 
 JSFunctionSpec Debugger::methods[] = {
     JS_FN("addDebuggee", Debugger::addDebuggee, 1, 0),
     JS_FN("removeDebuggee", Debugger::removeDebuggee, 1, 0),
     JS_FN("hasDebuggee", Debugger::hasDebuggee, 1, 0),
     JS_FN("getDebuggees", Debugger::getDebuggees, 0, 0),
     JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
     JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 1, 0),
     JS_FN("findScripts", Debugger::findScripts, 1, 0),
+    JS_FN("wrap", Debugger::wrap, 1, 0),
     JS_FS_END
 };
 
 
 /*** Debugger.Script *****************************************************************************/
 
 static inline JSScript *
 GetScriptReferent(JSObject *obj)
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -196,16 +196,17 @@ class Debugger {
     static JSBool setUncaughtExceptionHook(JSContext *cx, unsigned argc, Value *vp);
     static JSBool addDebuggee(JSContext *cx, unsigned argc, Value *vp);
     static JSBool removeDebuggee(JSContext *cx, unsigned argc, Value *vp);
     static JSBool hasDebuggee(JSContext *cx, unsigned argc, Value *vp);
     static JSBool getDebuggees(JSContext *cx, unsigned argc, Value *vp);
     static JSBool getNewestFrame(JSContext *cx, unsigned argc, Value *vp);
     static JSBool clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp);
     static JSBool findScripts(JSContext *cx, unsigned argc, Value *vp);
+    static JSBool wrap(JSContext *cx, unsigned argc, Value *vp);
     static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
     static JSPropertySpec properties[];
     static JSFunctionSpec methods[];
 
     JSObject *getHook(Hook hook) const;
     bool hasAnyLiveHooks() const;
 
     static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, Value *vp);
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -94,27 +94,27 @@ js_PutCallObject(StackFrame *fp)
             } else {
                 /*
                  * For each arg & var that is closed over, copy it from the stack
                  * into the call object. We use initArg/VarUnchecked because,
                  * when you call a getter on a call object, js_NativeGetInline
                  * caches the return value in the slot, so we can't assert that
                  * it's undefined.
                  */
-                uint32_t nclosed = script->nClosedArgs;
+                uint32_t nclosed = script->nClosedArgs();
                 for (uint32_t i = 0; i < nclosed; i++) {
                     uint32_t e = script->getClosedArg(i);
 #ifdef JS_GC_ZEAL
                     callobj.setArg(e, fp->formalArg(e));
 #else
                     callobj.initArgUnchecked(e, fp->formalArg(e));
 #endif
                 }
 
-                nclosed = script->nClosedVars;
+                nclosed = script->nClosedVars();
                 for (uint32_t i = 0; i < nclosed; i++) {
                     uint32_t e = script->getClosedVar(i);
 #ifdef JS_GC_ZEAL
                     callobj.setVar(e, fp->slots()[e]);
 #else
                     callobj.initVarUnchecked(e, fp->slots()[e]);
 #endif
                 }
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -98,16 +98,19 @@
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsEventDispatcher.h"
 #include "nsDisplayList.h"
 #include "nsTreeBoxObject.h"
 #include "nsRenderingContext.h"
 #include "nsIScriptableRegion.h"
 
+#ifdef ACCESSIBILITY
+#include "nsAccessibilityService.h"
+#endif
 #ifdef IBMBIDI
 #include "nsBidiUtils.h"
 #endif
 
 using namespace mozilla;
 
 // Enumeration function that cancels all the image requests in our cache
 static PLDHashOperator
@@ -514,16 +517,21 @@ nsTreeBodyFrame::SetView(nsITreeView * a
   mView = aView;
  
   // Changing the view causes us to refetch our data.  This will
   // necessarily entail a full invalidation of the tree.
   Invalidate();
  
   nsIContent *treeContent = GetBaseElement();
   if (treeContent) {
+#ifdef ACCESSIBILITY
+    nsAccessibilityService* accService = nsIPresShell::AccService();
+    if (accService)
+      accService->TreeViewChanged(PresContext()->GetPresShell(), treeContent, mView);
+#endif
     FireDOMEvent(NS_LITERAL_STRING("TreeViewChanged"), treeContent);
   }
 
   if (mView) {
     // Give the view a new empty selection object to play with, but only if it
     // doesn't have one already.
     nsCOMPtr<nsITreeSelection> sel;
     mView->GetSelection(getter_AddRefs(sel));
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -42,17 +42,16 @@ package org.mozilla.gecko;
 
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.gfx.FloatSize;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
 import org.mozilla.gecko.gfx.IntSize;
 import org.mozilla.gecko.gfx.Layer;
 import org.mozilla.gecko.gfx.LayerController;
 import org.mozilla.gecko.gfx.LayerView;
-import org.mozilla.gecko.gfx.PlaceholderLayerClient;
 import org.mozilla.gecko.gfx.RectUtils;
 import org.mozilla.gecko.gfx.SurfaceTextureLayer;
 import org.mozilla.gecko.gfx.ViewportMetrics;
 import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
 import org.mozilla.gecko.Tab.HistoryEntry;
 
 import java.io.*;
 import java.util.*;
@@ -107,20 +106,17 @@ abstract public class GeckoApp
     public static final String ACTION_ALERT_CLICK   = "org.mozilla.gecko.ACTION_ALERT_CLICK";
     public static final String ACTION_ALERT_CLEAR   = "org.mozilla.gecko.ACTION_ALERT_CLEAR";
     public static final String ACTION_WEBAPP        = "org.mozilla.gecko.WEBAPP";
     public static final String ACTION_DEBUG         = "org.mozilla.gecko.DEBUG";
     public static final String ACTION_BOOKMARK      = "org.mozilla.gecko.BOOKMARK";
     public static final String ACTION_LOAD          = "org.mozilla.gecko.LOAD";
     public static final String ACTION_UPDATE        = "org.mozilla.gecko.UPDATE";
     public static final String ACTION_INIT_PW       = "org.mozilla.gecko.INIT_PW";
-    public static final String SAVED_STATE_URI      = "uri";
     public static final String SAVED_STATE_TITLE    = "title";
-    public static final String SAVED_STATE_VIEWPORT = "viewport";
-    public static final String SAVED_STATE_SCREEN   = "screen";
     public static final String SAVED_STATE_SESSION  = "session";
 
     StartupMode mStartupMode = null;
     private LinearLayout mMainLayout;
     private RelativeLayout mGeckoLayout;
     public static SurfaceView cameraView;
     public static GeckoApp mAppContext;
     public static boolean mDOMFullScreen = false;
@@ -137,25 +133,21 @@ abstract public class GeckoApp
     private BroadcastReceiver mBatteryReceiver;
 
     public static BrowserToolbar mBrowserToolbar;
     public static DoorHangerPopup mDoorHangerPopup;
     public static FormAssistPopup mFormAssistPopup;
     public Favicons mFavicons;
 
     private static LayerController mLayerController;
-    private static PlaceholderLayerClient mPlaceholderLayerClient;
     private static GeckoLayerClient mLayerClient;
     private AboutHomeContent mAboutHomeContent;
     private static AbsoluteLayout mPluginContainer;
 
     public String mLastTitle;
-    public String mLastSnapshotUri;
-    public String mLastViewport;
-    public byte[] mLastScreen;
     private int mOwnActivityDepth = 0;
     private boolean mRestoreSession = false;
     private boolean mInitialized = false;
 
     private static final String HANDLER_MSG_TYPE = "type";
     private static final int HANDLER_MSG_TYPE_INITIALIZE = 1;
 
     static class ExtraMenuItem implements MenuItem.OnMenuItemClickListener {
@@ -541,97 +533,51 @@ abstract public class GeckoApp
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         if (mOwnActivityDepth > 0)
             return; // we're showing one of our own activities and likely won't get paged out
 
         if (outState == null)
             outState = new Bundle();
 
-        new SessionSnapshotRunnable(null).run();
-
         outState.putString(SAVED_STATE_TITLE, mLastTitle);
-        outState.putString(SAVED_STATE_VIEWPORT, mLastViewport);
-        outState.putByteArray(SAVED_STATE_SCREEN, mLastScreen);
         outState.putBoolean(SAVED_STATE_SESSION, true);
     }
 
-    public class SessionSnapshotRunnable implements Runnable {
-        Tab mThumbnailTab;
-        SessionSnapshotRunnable(Tab thumbnailTab) {
-            mThumbnailTab = thumbnailTab;
-        }
-
-        public void run() {
-            if (mLayerClient == null)
-                return;
-
-            synchronized (mLayerClient) {
-                if (!Tabs.getInstance().isSelectedTab(mThumbnailTab))
-                    return;
-
-                HistoryEntry lastHistoryEntry = mThumbnailTab.getLastHistoryEntry();
-                if (lastHistoryEntry == null)
-                    return;
-
-                ViewportMetrics viewportMetrics = mLayerClient.getGeckoViewportMetrics();
-                // If we don't have viewport metrics, the screenshot won't be right so bail
-                if (viewportMetrics == null)
-                    return;
-                
-                String viewportJSON = viewportMetrics.toJSON();
-                // If the title, uri and viewport haven't changed, the old screenshot is probably valid
-                // Ordering of .equals() below is important since mLast* variables may be null
-                if (viewportJSON.equals(mLastViewport) &&
-                    lastHistoryEntry.mTitle.equals(mLastTitle) &&
-                    lastHistoryEntry.mUri.equals(mLastSnapshotUri))
-                    return; 
-
-                mLastViewport = viewportJSON;
-                mLastTitle = lastHistoryEntry.mTitle;
-                mLastSnapshotUri = lastHistoryEntry.mUri;
-                getAndProcessThumbnailForTab(mThumbnailTab, true);
-            }
-        }
-    }
-
-    void getAndProcessThumbnailForTab(final Tab tab, boolean forceBigSceenshot) {
+    void getAndProcessThumbnailForTab(final Tab tab) {
         boolean isSelectedTab = Tabs.getInstance().isSelectedTab(tab);
         final Bitmap bitmap = isSelectedTab ? mLayerClient.getBitmap() : null;
         
         if (bitmap != null) {
             ByteArrayOutputStream bos = new ByteArrayOutputStream();
             bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos);
             processThumbnail(tab, bitmap, bos.toByteArray());
         } else {
             if (tab.getState() == Tab.STATE_DELAYED) {
                 byte[] thumbnail = BrowserDB.getThumbnailForUrl(getContentResolver(), tab.getURL());
                 if (thumbnail != null)
                     processThumbnail(tab, null, thumbnail);
                 return;
             }
 
-            mLastScreen = null;
-            View view = mLayerController.getView();
-            int sw = forceBigSceenshot ? view.getWidth() : tab.getMinScreenshotWidth();
-            int sh = forceBigSceenshot ? view.getHeight(): tab.getMinScreenshotHeight();
-            int dw = forceBigSceenshot ? sw : tab.getThumbnailWidth();
-            int dh = forceBigSceenshot ? sh : tab.getThumbnailHeight();
+            int sw = tab.getMinScreenshotWidth();
+            int sh = tab.getMinScreenshotHeight();
+            int dw = tab.getThumbnailWidth();
+            int dh = tab.getThumbnailHeight();
             GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), sw, sh, dw, dh));
         }
     }
     
     void processThumbnail(Tab thumbnailTab, Bitmap bitmap, byte[] compressed) {
         if (Tabs.getInstance().isSelectedTab(thumbnailTab)) {
             if (compressed == null) {
                 ByteArrayOutputStream bos = new ByteArrayOutputStream();
                 bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos);
                 compressed = bos.toByteArray();
             }
-            mLastScreen = compressed;
         }
 
         if ("about:home".equals(thumbnailTab.getURL())) {
             thumbnailTab.updateThumbnail(null);
             return;
         }
         try {
             if (bitmap == null)
@@ -1249,21 +1195,16 @@ abstract public class GeckoApp
 
         mMainHandler.post(new Runnable() {
             public void run() {
                 if (Tabs.getInstance().isSelectedTab(tab))
                     mBrowserToolbar.setProgressVisibility(false);
                 Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.STOP);
             }
         });
-
-        if (Tabs.getInstance().isSelectedTab(tab)) {
-            Runnable r = new SessionSnapshotRunnable(tab);
-            GeckoAppShell.getHandler().postDelayed(r, 500);
-        }
     }
 
     void handleShowToast(final String message, final String duration) {
         mMainHandler.post(new Runnable() {
             public void run() {
                 Toast toast;
                 if (duration.equals("long"))
                     toast = Toast.makeText(mAppContext, message, Toast.LENGTH_LONG);
@@ -1614,18 +1555,16 @@ abstract public class GeckoApp
             enableStrictMode();
         }
 
         GeckoAppShell.loadMozGlue();
         mMainHandler = new GeckoAppHandler();
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
         if (savedInstanceState != null) {
             mLastTitle = savedInstanceState.getString(SAVED_STATE_TITLE);
-            mLastViewport = savedInstanceState.getString(SAVED_STATE_VIEWPORT);
-            mLastScreen = savedInstanceState.getByteArray(SAVED_STATE_SCREEN);
             mRestoreSession = savedInstanceState.getBoolean(SAVED_STATE_SESSION);
         }
 
         LayoutInflater.from(this).setFactory(GeckoViewsFactory.getInstance());
 
         super.onCreate(savedInstanceState);
 
         mOrientation = getResources().getConfiguration().orientation;
@@ -1658,18 +1597,16 @@ abstract public class GeckoApp
         String action = intent.getAction();
         String args = intent.getStringExtra("args");
         if (args != null && args.contains("-profile")) {
             Pattern p = Pattern.compile("(?:-profile\\s*)(\\w*)(\\s*)");
             Matcher m = p.matcher(args);
             if (m.find()) {
                 mProfile = GeckoProfile.get(this, m.group(1));
                 mLastTitle = null;
-                mLastViewport = null;
-                mLastScreen = null;
             }
         }
 
         if (ACTION_UPDATE.equals(action) || args != null && args.contains("-alert update-app")) {
             Log.i(LOGTAG,"onCreate: Update request");
             checkAndLaunchUpdate();
         }
 
@@ -1743,21 +1680,18 @@ abstract public class GeckoApp
              * checkerboard.
              *
              * TODO: Fall back to a built-in screenshot of the Fennec Start page for a nice first-
              * run experience, perhaps?
              */
             mLayerController = new LayerController(this);
             View v = mLayerController.getView();
 
-            mPlaceholderLayerClient = new PlaceholderLayerClient(mLayerController, mLastViewport);
-            if (!mPlaceholderLayerClient.loadScreenshot()) {
-                // Instead of flickering the checkerboard, show a white screen until Gecko paints
-                v.setBackgroundColor(Color.WHITE);
-            }
+            // Instead of flickering the checkerboard, show a white screen until Gecko paints
+            v.setBackgroundColor(Color.WHITE);
 
             mGeckoLayout.addView(v, 0);
         }
 
         mPluginContainer = (AbsoluteLayout) findViewById(R.id.plugin_container);
 
         mDoorHangerPopup = new DoorHangerPopup(this);
         mFormAssistPopup = (FormAssistPopup) findViewById(R.id.form_assist_popup);
@@ -2036,19 +1970,16 @@ abstract public class GeckoApp
         return uri;
     }
 
     @Override
     public void onPause()
     {
         Log.i(LOGTAG, "pause");
 
-        Runnable r = new SessionSnapshotRunnable(null);
-        GeckoAppShell.getHandler().post(r);
-
         GeckoAppShell.sendEventToGecko(GeckoEvent.createPauseEvent(mOwnActivityDepth));
         // The user is navigating away from this activity, but nothing
         // has come to the foreground yet; for Gecko, we may want to
         // stop repainting, for example.
 
         // Whatever we do here should be fast, because we're blocking
         // the next activity from showing up until we finish.
 
@@ -2818,19 +2749,16 @@ abstract public class GeckoApp
     }
 
     public void onStatusChanged(String provider, int status, Bundle extras)
     {
     }
 
 
     private void connectGeckoLayerClient() {
-        if (mPlaceholderLayerClient != null)
-            mPlaceholderLayerClient.destroy();
-
         LayerController layerController = getLayerController();
         layerController.setLayerClient(mLayerClient);
     }
 
     public class GeckoAppHandler extends Handler {
         @Override
         public void handleMessage(Message message) {
             Bundle bundle = message.getData();
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -130,17 +130,16 @@ FENNEC_JAVA_FILES = \
   gfx/InputConnectionHandler.java \
   gfx/IntSize.java \
   gfx/Layer.java \
   gfx/LayerController.java \
   gfx/LayerRenderer.java \
   gfx/LayerView.java \
   gfx/NinePatchTileLayer.java \
   gfx/PanningPerfAPI.java \
-  gfx/PlaceholderLayerClient.java \
   gfx/PointUtils.java \
   gfx/RectUtils.java \
   gfx/ScrollbarLayer.java \
   gfx/SingleTileLayer.java \
   gfx/SurfaceTextureLayer.java \
   gfx/TextLayer.java \
   gfx/TextureGenerator.java \
   gfx/TextureReaper.java \
--- a/mobile/android/base/Tabs.java
+++ b/mobile/android/base/Tabs.java
@@ -305,17 +305,17 @@ public class Tabs implements GeckoEventL
     }
 
     public void refreshThumbnails() {
         Iterator<Tab> iterator = tabs.values().iterator();
         while (iterator.hasNext()) {
             final Tab tab = iterator.next();
             GeckoAppShell.getHandler().post(new Runnable() {
                 public void run() {
-                    GeckoApp.mAppContext.getAndProcessThumbnailForTab(tab, false);
+                    GeckoApp.mAppContext.getAndProcessThumbnailForTab(tab);
                 }
             });
         }
     }
 
     public interface OnTabsChangedListener {
         public void onTabChanged(Tab tab, TabEvents msg);
     }
--- a/mobile/android/base/gfx/GeckoLayerClient.java
+++ b/mobile/android/base/gfx/GeckoLayerClient.java
@@ -206,18 +206,22 @@ public class GeckoLayerClient implements
             default:
             case UPDATE:
                 newMetrics = messageMetrics;
                 // Keep the old viewport size
                 newMetrics.setSize(oldMetrics.getSize());
                 mLayerController.abortPanZoomAnimation();
                 break;
             case PAGE_SIZE:
+                // adjust the page dimensions to account for differences in zoom
+                // between the rendered content (which is what Gecko tells us)
+                // and our zoom level (which may have diverged).
+                float scaleFactor = oldMetrics.zoomFactor / messageMetrics.getZoomFactor();
                 newMetrics = new ViewportMetrics(oldMetrics);
-                newMetrics.setPageSize(messageMetrics.getPageSize());
+                newMetrics.setPageSize(messageMetrics.getPageSize().scale(scaleFactor));
                 break;
             }
 
             mLayerController.post(new Runnable() {
                 public void run() {
                     mGeckoViewport = newMetrics;
                 }
             });
deleted file mode 100644
--- a/mobile/android/base/gfx/PlaceholderLayerClient.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.GeckoApp;
-import org.mozilla.gecko.GeckoAppShell;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.Log;
-import org.json.JSONException;
-import org.json.JSONObject;
-import java.io.ByteArrayInputStream;
-import java.nio.ByteBuffer;
-
-/**
- * A stand-in for Gecko that renders cached content of the previous page. We use this until Gecko
- * is up, then we hand off control to it.
- */
-public class PlaceholderLayerClient {
-    private static final String LOGTAG = "PlaceholderLayerClient";
-
-    private final LayerController mLayerController;
-
-    private ViewportMetrics mViewport;
-    private boolean mViewportUnknown;
-    private int mWidth, mHeight, mFormat;
-    private ByteBuffer mBuffer;
-
-    public PlaceholderLayerClient(LayerController controller, String lastViewport) {
-        mLayerController = controller;
-
-        mViewportUnknown = true;
-        if (lastViewport != null) {
-            try {
-                JSONObject viewportObject = new JSONObject(lastViewport);
-                mViewport = new ViewportMetrics(viewportObject);
-                mViewportUnknown = false;
-            } catch (JSONException e) {
-                Log.e(LOGTAG, "Error parsing saved viewport!");
-                mViewport = new ViewportMetrics();
-            }
-        } else {
-            mViewport = new ViewportMetrics();
-        }
-    }
-
-    public void destroy() {
-        if (mBuffer != null) {
-            GeckoAppShell.freeDirectBuffer(mBuffer);
-            mBuffer = null;
-        }
-    }
-
-    public boolean loadScreenshot() {
-        if (GeckoApp.mAppContext.mLastScreen == null)
-            return false;
-
-        Bitmap bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(GeckoApp.mAppContext.mLastScreen));
-        if (bitmap == null)
-            return false;
-
-        Bitmap.Config config = bitmap.getConfig();
-
-        mWidth = bitmap.getWidth();
-        mHeight = bitmap.getHeight();
-        mFormat = CairoUtils.bitmapConfigToCairoFormat(config);
-
-        int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
-        mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * bpp);
-
-        bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
-
-        if (mViewportUnknown) {
-            mViewport.setPageSize(new FloatSize(mWidth, mHeight));
-            mLayerController.setPageSize(mViewport.getPageSize());
-        }
-
-        BufferedCairoImage image = new BufferedCairoImage(mBuffer, mWidth, mHeight, mFormat);
-        SingleTileLayer tileLayer = new SingleTileLayer(image);
-
-        tileLayer.beginTransaction();   // calling thread irrelevant; nobody else has a ref to tileLayer yet
-        try {
-            Point origin = PointUtils.round(mViewport.getOrigin());
-            tileLayer.setPosition(new Rect(origin.x, origin.y, origin.x + mWidth, origin.y + mHeight));
-        } finally {
-            tileLayer.endTransaction();
-        }
-
-        mLayerController.setRoot(tileLayer);
-        return true;
-    }
-}
--- a/mobile/android/base/ui/PanZoomController.java
+++ b/mobile/android/base/ui/PanZoomController.java
@@ -529,16 +529,19 @@ public class PanZoomController
     PointF getDisplacement() {
         return new PointF(mX.resetDisplacement(), mY.resetDisplacement());
     }
 
     private void updatePosition() {
         mX.displace();
         mY.displace();
         PointF displacement = getDisplacement();
+        if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
+            return;
+        }
         if (! mSubscroller.scrollBy(displacement)) {
             synchronized (mController) {
                 mController.scrollBy(displacement);
             }
         }
     }
 
     private abstract class AnimationRunnable implements Runnable {
--- a/netwerk/base/public/nsIApplicationCache.idl
+++ b/netwerk/base/public/nsIApplicationCache.idl
@@ -93,33 +93,16 @@ interface nsIApplicationCacheNamespace :
     /**
      * Data associated with this namespace, such as a fallback.  URI data should
      * use the asciiSpec of the URI.
      */
     readonly attribute ACString data;
 };
 
 /**
- * Callback for asynchronized methods for nsIApplicationCache.
- */
-[scriptable, uuid(062c8061-7c31-44a4-bd8d-302772e4a7eb)]
-interface nsIApplicationCacheAsyncCallback : nsISupports
-{
-    const long APP_CACHE_REQUEST_SUCCESS = 0;
-    const long APP_CACHE_REQUEST_ERROR = 1;
-
-    /**
-     * Callback function with result code.  It should be a nsresult.
-     *
-     * @param aState is an error code, one of APP_CACHE_REQUEST_*.
-     */
-    void handleAsyncCompletion(in PRUint32 aState);
-};
-
-/**
  * Application caches store resources for offline use.  Each
  * application cache has a unique client ID for use with
  * nsICacheService::openSession() to access the cache's entries.
  *
  * Each entry in the application cache can be marked with a set of
  * types, as discussed in the WHAT-WG offline applications
  * specification.
  *
@@ -200,21 +183,16 @@ interface nsIApplicationCache : nsISuppo
     /**
      * Discard this application cache.  Removes all cached resources
      * for this cache.  If this is the active application cache for the
      * group, the group will be removed.
      */
     void discard();
 
     /**
-     * Discard this application cache in asynchronized.
-     */
-    void discardAsync([optional] in nsIApplicationCacheAsyncCallback aCallback);
-
-    /**
      * Adds item types to a given entry.
      */
     void markEntry(in ACString key, in unsigned long typeBits);
 
     /**
      * Removes types from a given entry.  If the resulting entry has
      * no types left, the entry is removed.
      */
--- a/netwerk/cache/nsDiskCacheDeviceSQL.cpp
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.cpp
@@ -54,20 +54,18 @@
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "nsCRT.h"
 #include "nsArrayUtils.h"
 #include "nsIArray.h"
 #include "nsIVariant.h"
 #include "nsThreadUtils.h"
 
-#include "mozIStoragePendingStatement.h"
 #include "mozIStorageService.h"
 #include "mozIStorageStatement.h"
-#include "mozIStorageStatementCallback.h"
 #include "mozIStorageFunction.h"
 #include "mozStorageHelper.h"
 
 #include "nsICacheVisitor.h"
 #include "nsISeekableStream.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Telemetry.h"
@@ -130,37 +128,27 @@ class AutoResetStatement
 
 class EvictionObserver
 {
   public:
   EvictionObserver(mozIStorageConnection *db,
                    nsOfflineCacheEvictionFunction *evictionFunction)
     : mDB(db), mEvictionFunction(evictionFunction)
     {
-      if (mEvictionFunction->AddObserver() != 1) {
-	// not first observer
-	return;
-      }
-
       mDB->ExecuteSimpleSQL(
           NS_LITERAL_CSTRING("CREATE TEMP TRIGGER cache_on_delete AFTER DELETE"
                              " ON moz_cache FOR EACH ROW BEGIN SELECT"
                              " cache_eviction_observer("
                              "  OLD.key, OLD.generation);"
                              " END;"));
       mEvictionFunction->Reset();
     }
 
     ~EvictionObserver()
     {
-      if (mEvictionFunction->RemoveObserver() != 0) {
-	// not last observer
-	return;
-      }
-
       mDB->ExecuteSimpleSQL(
         NS_LITERAL_CSTRING("DROP TRIGGER cache_on_delete;"));
       mEvictionFunction->Reset();
     }
 
     void Apply() { return mEvictionFunction->Apply(); }
 
   private:
@@ -181,167 +169,16 @@ class EvictionObserver
  */
 static PRUint64
 DCacheHash(const char * key)
 {
   // initval 0x7416f295 was chosen randomly
   return (PRUint64(nsDiskCache::Hash(key, 0)) << 32) | nsDiskCache::Hash(key, 0x7416f295);
 }
 
-/**
- * EvictAsyncHandler
- */
-class EvictAsyncHandler : public mozIStorageStatementCallback
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_MOZISTORAGESTATEMENTCALLBACK
-
-  EvictAsyncHandler();
-  ~EvictAsyncHandler();
-
-  nsresult Init(const char *aClientID,
-		nsIApplicationCacheAsyncCallback *aCallback,
-		mozIStorageConnection *aDB,
-		nsOfflineCacheEvictionFunction *aEvictionFunction) {
-    mClientID = NS_strdup(aClientID);
-    if (mClientID == NULL)
-      return NS_ERROR_OUT_OF_MEMORY;
-
-    mCallback = aCallback;
-    mDB = aDB;
-    mEvictionFunction = aEvictionFunction;
-
-    return NS_OK;
-  }
-
-  nsresult Start() {
-    mEvictionObserver = new EvictionObserver(mDB, mEvictionFunction);
-    HandleCompletion(mozIStorageStatementCallback::REASON_FINISHED);
-
-    return NS_OK;
-  }
-
-private:
-  void ReportError() {
-    mCallback->HandleAsyncCompletion(nsIApplicationCacheAsyncCallback::APP_CACHE_REQUEST_ERROR);
-  }
-
-  void ReportSuccess() {
-    mCallback->HandleAsyncCompletion(nsIApplicationCacheAsyncCallback::APP_CACHE_REQUEST_SUCCESS);
-  }
-
-private:
-  const char *mClientID;
-  nsCOMPtr<mozIStorageConnection> mDB;
-  nsCOMPtr<nsIApplicationCacheAsyncCallback> mCallback;
-  nsRefPtr<nsOfflineCacheEvictionFunction> mEvictionFunction;
-  EvictionObserver *mEvictionObserver;
-
-  /* Current step in the receipt to complete a eviction. */
-  int mStep;
-};
-
-NS_IMPL_ISUPPORTS1(EvictAsyncHandler, mozIStorageStatementCallback)
-
-EvictAsyncHandler::EvictAsyncHandler() :
-  mClientID(NULL), mEvictionFunction(NULL), mStep(0)
-{
-}
-
-EvictAsyncHandler::~EvictAsyncHandler() {
-  if (mClientID)
-      NS_Free((void *)mClientID);
-  if (mEvictionObserver)
-    delete mEvictionObserver;
-}
-
-NS_IMETHODIMP
-EvictAsyncHandler::HandleResult(mozIStorageResultSet *aResultSet) {
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-EvictAsyncHandler::HandleError(mozIStorageError *aError) {
-  return NS_OK;
-}
-
-static nsresult
-EvictEntriesSteps(mozIStorageConnection *mDB,
-		  const char *clientID,
-		  int step,
-		  mozIStorageStatement **aStatement);
-
-NS_IMETHODIMP
-EvictAsyncHandler::HandleCompletion(unsigned short aReason) {
-  if (aReason != mozIStorageStatementCallback::REASON_FINISHED) {
-    mCallback->HandleAsyncCompletion(nsIApplicationCacheAsyncCallback::APP_CACHE_REQUEST_ERROR);
-    return NS_OK;
-  }
-
-  nsresult rv;
-  nsCOMPtr<mozIStorageStatement> statement;
-  rv = EvictEntriesSteps(mDB, mClientID, mStep++, getter_AddRefs(statement));
-  if (NS_FAILED(rv)) {
-    ReportError();
-    return NS_OK;
-  }
-
-  if (statement) {
-    nsCOMPtr<mozIStoragePendingStatement> pending;
-    rv = statement->ExecuteAsync(this, getter_AddRefs(pending));
-    if (NS_FAILED(rv)) {
-      ReportError();
-    }
-  } else {
-    // Complete the eviction, no more commands.
-    mEvictionObserver->Apply();
-    ReportSuccess();
-  }
-
-  return NS_OK;
-}
-
-/**
- * RemoveFilesAsync removes files in a separated thread.
- */
-class RemoveFilesAsync : public nsRunnable
-{
-public:
-  /**
-   * @param aItems is an array of nsIFile to remove.
-   */
-  RemoveFilesAsync(nsCOMArray<nsIFile> &aItems) :
-    mItems(aItems) {}
-  ~RemoveFilesAsync();
-
-  NS_IMETHOD Run();
-
-private:
-  nsCOMArray<nsIFile> mItems;
-  nsCOMPtr<nsIThread> mIOThread;
-};
-
-RemoveFilesAsync::~RemoveFilesAsync() {
-}
-
-NS_IMETHODIMP
-RemoveFilesAsync::Run() {
-  for (PRInt32 i = 0; i < mItems.Count(); i++) {
-#if defined(PR_LOGGING)
-    nsCAutoString path;
-    mItems[i]->GetNativePath(path);
-    LOG(("  removing %s\n", path.get()));
-#endif
-
-    mItems[i]->Remove(false);
-  }
-  return NS_OK;
-}
-
 /******************************************************************************
  * nsOfflineCacheEvictionFunction
  */
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsOfflineCacheEvictionFunction, mozIStorageFunction)
 
 // helper function for directly exposing the same data file binding
 // path algorithm used in nsOfflineCacheBinding::Create
@@ -399,27 +236,26 @@ nsOfflineCacheEvictionFunction::OnFuncti
   return NS_OK;
 }
 
 void
 nsOfflineCacheEvictionFunction::Apply()
 {
   LOG(("nsOfflineCacheEvictionFunction::Apply\n"));
 
-  if (!mIOThread) {
-    nsresult rv;
-
-    rv = NS_NewThread(getter_AddRefs(mIOThread));
-    NS_ASSERTION(NS_SUCCEEDED(rv), "fail to create a new thread");
+  for (PRInt32 i = 0; i < mItems.Count(); i++) {
+#if defined(PR_LOGGING)
+    nsCAutoString path;
+    mItems[i]->GetNativePath(path);
+    LOG(("  removing %s\n", path.get()));
+#endif
+
+    mItems[i]->Remove(false);
   }
 
-  nsCOMPtr<RemoveFilesAsync> removeFiles = new RemoveFilesAsync(mItems);
-  NS_ASSERTION(removeFiles, "fail to instantiate RemoveFilesAsync");
-  mIOThread->Dispatch(removeFiles, NS_DISPATCH_NORMAL);
-
   Reset();
 }
 
 /******************************************************************************
  * nsOfflineCacheDeviceInfo
  */
 
 class nsOfflineCacheDeviceInfo : public nsICacheDeviceInfo
@@ -859,32 +695,16 @@ nsApplicationCache::Discard()
   {
     mDevice->DeactivateGroup(mGroup);
   }
 
   return mDevice->EvictEntries(mClientID.get());
 }
 
 NS_IMETHODIMP
-nsApplicationCache::DiscardAsync(nsIApplicationCacheAsyncCallback *aCallback)
-{
-  NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
-  NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
-
-  mValid = false;
-
-  if (mDevice->IsActiveCache(mGroup, mClientID))
-  {
-    mDevice->DeactivateGroup(mGroup);
-  }
-
-  return mDevice->EvictEntriesAsync(mClientID.get(), aCallback);
-}
-
-NS_IMETHODIMP
 nsApplicationCache::MarkEntry(const nsACString &key,
                               PRUint32 typeBits)
 {
   NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
   NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
 
   return mDevice->MarkEntry(mClientID, key, typeBits);
 }
@@ -1907,112 +1727,92 @@ nsOfflineCacheDevice::Visit(nsICacheVisi
     if (NS_FAILED(rv) || !keepGoing)
       break;
   }
 
   info->mRec = nsnull;
   return NS_OK;
 }
 
-static const char *sEvictCmdsClientID[] = {
-  "DELETE FROM moz_cache WHERE ClientID=? AND Flags = 0;",
-  "DELETE FROM moz_cache_groups WHERE ActiveClientID=?;",
-  "DELETE FROM moz_cache_namespaces WHERE ClientID=?",
-  NULL
-};
-
-static const char *sEvictCmds[] = {
-  "DELETE FROM moz_cache WHERE Flags = 0;",
-  "DELETE FROM moz_cache_groups;",
-  "DELETE FROM moz_cache_namespaces;",
-  NULL
-};
-
-/**
- * Create SQL statement for every step of eviction of cache entries.
- *
- * @param mDB is the database connection used for the eviction.
- * @param clientID is the clientID of cache entries being evicting.
- * @param step is the number of current step. (start from 0)
- * @param statement is a pointer to return the stathement.
- */
-static nsresult
-EvictEntriesSteps(mozIStorageConnection *mDB,
-		  const char *clientID,
-		  int step,
-		  mozIStorageStatement **aStatement)
-{
-  const char **cmds = clientID ? sEvictCmdsClientID : sEvictCmds;
-  const char *cmd = cmds[step];
-
-  if (cmd == NULL) {
-    *aStatement = NULL;
-    return NS_OK;
-  }
-
-  // called to evict all entries matching the given clientID.
-
-  nsresult rv;
-  nsCOMPtr<mozIStorageStatement> statement;
-  rv = mDB->CreateStatement(nsDependentCString(cmd),
-			    getter_AddRefs(statement));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (clientID) {
-    rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  *aStatement = statement.forget().get();
-
-  return NS_OK;
-}
-
 nsresult
 nsOfflineCacheDevice::EvictEntries(const char *clientID)
 {
   LOG(("nsOfflineCacheDevice::EvictEntries [cid=%s]\n",
        clientID ? clientID : ""));
 
-  int step = 0;
-  nsresult rv = NS_OK;;
+  // called to evict all entries matching the given clientID.
 
   // need trigger to fire user defined function after a row is deleted
   // so we can delete the corresponding data file.
   EvictionObserver evictionObserver(mDB, mEvictionFunction);
 
   nsCOMPtr<mozIStorageStatement> statement;
-  while (1) {
-    rv = EvictEntriesSteps(mDB, clientID, step++, getter_AddRefs(statement));
-    if (NS_FAILED(rv)) break;
-
-    if (!statement) break;	// finish
-
-    statement->Execute();
-    if (NS_FAILED(rv)) break;
+  nsresult rv;
+  if (clientID)
+  {
+    rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE ClientID=? AND Flags = 0;"),
+                              getter_AddRefs(statement));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->Execute();
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_groups WHERE ActiveClientID=?;"),
+                              getter_AddRefs(statement));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->Execute();
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  else
+  {
+    rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache WHERE Flags = 0;"),
+                              getter_AddRefs(statement));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->Execute();
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_groups;"),
+                              getter_AddRefs(statement));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->Execute();
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   evictionObserver.Apply();
 
-  return rv;
-}
-
-nsresult
-nsOfflineCacheDevice::EvictEntriesAsync(const char *clientID,
-					nsIApplicationCacheAsyncCallback *aCallback)
-{
-  LOG(("nsOfflineCacheDevice::EvictEntriesAsync [cid=%s]\n",
-       clientID ? clientID : ""));
-
-  EvictAsyncHandler *evictAsyncHandler = new EvictAsyncHandler();
-  if (evictAsyncHandler == NULL)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  evictAsyncHandler->Init(clientID, aCallback, mDB, mEvictionFunction);
-  evictAsyncHandler->Start();
+  statement = nsnull;
+  // Also evict any namespaces associated with this clientID.
+  if (clientID)
+  {
+    rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_namespaces WHERE ClientID=?"),
+                              getter_AddRefs(statement));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = statement->BindUTF8StringByIndex(0, nsDependentCString(clientID));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  else
+  {
+    rv = mDB->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_cache_namespaces;"),
+                              getter_AddRefs(statement));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  rv = statement->Execute();
+  NS_ENSURE_SUCCESS(rv, rv);
+
   return NS_OK;
 }
 
 nsresult
 nsOfflineCacheDevice::MarkEntry(const nsCString &clientID,
                                 const nsACString &key,
                                 PRUint32 typeBits)
 {
--- a/netwerk/cache/nsDiskCacheDeviceSQL.h
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.h
@@ -72,31 +72,24 @@ private:
 
 class nsOfflineCacheEvictionFunction : public mozIStorageFunction {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_MOZISTORAGEFUNCTION
 
   nsOfflineCacheEvictionFunction(nsOfflineCacheDevice *device)
     : mDevice(device)
-    , mObserverCount(0)
   {}
 
   void Reset() { mItems.Clear(); }
   void Apply();
 
-  int AddObserver() { return ++mObserverCount; }
-  int RemoveObserver() { return --mObserverCount; }
-
 private:
   nsOfflineCacheDevice *mDevice;
   nsCOMArray<nsIFile> mItems;
-  nsCOMPtr<nsIThread> mIOThread;
-
-  int mObserverCount;
 
 };
 
 class nsOfflineCacheDevice : public nsCacheDevice
                            , public nsIApplicationCacheService
 {
 public:
   nsOfflineCacheDevice();
@@ -133,19 +126,16 @@ public:
                                           nsIFile **        result);
 
   virtual nsresult        OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize);
   
   virtual nsresult        Visit(nsICacheVisitor * visitor);
 
   virtual nsresult        EvictEntries(const char * clientID);
 
-  virtual nsresult EvictEntriesAsync(const char * clientID,
-				     nsIApplicationCacheAsyncCallback *aCallback);
-
   /* Entry ownership */
   nsresult                GetOwnerDomains(const char *        clientID,
                                           PRUint32 *          count,
                                           char ***            domains);
   nsresult                GetOwnerURIs(const char *           clientID,
                                        const nsACString &     ownerDomain,
                                        PRUint32 *             count,
                                        char ***               uris);
--- a/security/coreconf/coreconf.dep
+++ b/security/coreconf/coreconf.dep
@@ -37,9 +37,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_13_3_RTM
+NSS_3_13_4_BETA1
--- a/security/nss/TAG-INFO-CKBI
+++ b/security/nss/TAG-INFO-CKBI
@@ -1,1 +1,1 @@
-NSS_3_13_3_RTM
+NSS_3_13_4_BETA1
--- a/security/nss/cmd/addbuiltin/addbuiltin.c
+++ b/security/nss/cmd/addbuiltin/addbuiltin.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Tool for converting builtin CA certs.
  *
- * $Id: addbuiltin.c,v 1.16 2011/04/13 00:10:21 rrelyea%redhat.com Exp $
+ * $Id: addbuiltin.c,v 1.17 2012/03/10 12:10:44 kaie%kuix.de Exp $
  */
 
 #include "nssrenam.h"
 #include "nss.h"
 #include "cert.h"
 #include "certdb.h"
 #include "secutil.h"
 #include "pk11func.h"
@@ -86,96 +86,211 @@ char *getTrustString(unsigned int trust)
     return "CKT_NSS_TRUST_UNKNOWN"; /* not reached */
 }
 
 static const SEC_ASN1Template serialTemplate[] = {
     { SEC_ASN1_INTEGER, offsetof(CERTCertificate,serialNumber) },
     { 0 }
 };
 
+void print_crl_info(CERTName *name, SECItem *serial)
+{
+    PRBool saveWrapeState = SECU_GetWrapEnabled();
+    SECU_EnableWrap(PR_FALSE);
+
+    SECU_PrintNameQuotesOptional(stdout, name, "# Issuer", 0, PR_FALSE);
+    printf("\n");
+    
+    SECU_PrintInteger(stdout, serial, "# Serial Number", 0);
+
+    SECU_EnableWrap(saveWrapeState);
+}
+
 static SECStatus
-ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust)
+ConvertCRLEntry(SECItem *sdder, PRInt32 crlentry, char *nickname)
+{
+    int rv;
+    PRArenaPool *arena = NULL;
+    CERTSignedCrl *newCrl = NULL;
+    CERTCrlEntry *entry;
+    
+    CERTName *name = NULL;
+    SECItem *derName = NULL;
+    SECItem *serial = NULL;
+    
+    rv = SEC_ERROR_NO_MEMORY;
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if (!arena)
+    	return rv;
+
+    newCrl = CERT_DecodeDERCrlWithFlags(arena, sdder, SEC_CRL_TYPE,
+					CRL_DECODE_DEFAULT_OPTIONS);
+    if (!newCrl)
+    	return SECFailure;
+    
+    name = &newCrl->crl.name;
+    derName = &newCrl->crl.derName;
+    
+    if (newCrl->crl.entries != NULL) {
+	PRInt32 iv = 0;
+	while ((entry = newCrl->crl.entries[iv++]) != NULL) {
+	    if (crlentry == iv) {
+		serial = &entry->serialNumber;
+		break;
+	    }
+	}
+    }
+    
+    if (!name || !derName || !serial)
+    	return SECFailure;
+    
+    printf("\n# Distrust \"%s\"\n",nickname);
+    print_crl_info(name, serial);
+
+    printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
+    printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
+    printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
+    printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
+    printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
+    
+    printf("CKA_ISSUER MULTILINE_OCTAL\n");
+    dumpbytes(derName->data,derName->len);
+    printf("END\n");
+    printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
+    printf("\\002\\%03o", serial->len); /* 002: type integer; len >=3 digits */
+    dumpbytes(serial->data,serial->len);
+    printf("END\n");
+    
+    printf("CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED\n");
+    printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED\n");
+    printf("CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED\n");
+    printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE\n");
+
+    PORT_FreeArena (arena, PR_FALSE);
+    return rv;
+}
+
+void print_info(SECItem *sdder, CERTCertificate *c)
+{
+    PRBool saveWrapeState = SECU_GetWrapEnabled();
+    SECU_EnableWrap(PR_FALSE);
+
+    SECU_PrintNameQuotesOptional(stdout, &c->issuer, "# Issuer", 0, PR_FALSE);
+    printf("\n");
+    
+    SECU_PrintInteger(stdout, &c->serialNumber, "# Serial Number", 0);
+
+    SECU_PrintNameQuotesOptional(stdout, &c->subject, "# Subject", 0, PR_FALSE);
+    printf("\n");
+
+    SECU_PrintTimeChoice(stdout, &c->validity.notBefore, "# Not Valid Before", 0);
+    SECU_PrintTimeChoice(stdout, &c->validity.notAfter,  "# Not Valid After ", 0);
+    
+    SECU_PrintFingerprints(stdout, sdder, "# Fingerprint", 0);
+
+    SECU_EnableWrap(saveWrapeState);
+}
+
+static SECStatus
+ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust,
+                   PRBool excludeCert, PRBool excludeHash)
 {
     SECStatus rv = SECSuccess;
     CERTCertificate *cert;
     unsigned char sha1_hash[SHA1_LENGTH];
     unsigned char md5_hash[MD5_LENGTH];
     SECItem *serial = NULL;
+    PRBool step_up = PR_FALSE;
+    const char *trust_info;
 
     cert = CERT_DecodeDERCertificate(sdder, PR_FALSE, nickname);
     if (!cert) {
 	return SECFailure;
     }
     serial = SEC_ASN1EncodeItem(NULL,NULL,cert,serialTemplate);
     if (!serial) {
 	return SECFailure;
     }
+    
+    if (!excludeCert) {
+	printf("\n#\n# Certificate \"%s\"\n#\n",nickname);
+	print_info(sdder, cert);
+	printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n");
+	printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
+	printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
+	printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
+	printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
+	printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n");
+	printf("CKA_SUBJECT MULTILINE_OCTAL\n");
+	dumpbytes(cert->derSubject.data,cert->derSubject.len);
+	printf("END\n");
+	printf("CKA_ID UTF8 \"0\"\n");
+	printf("CKA_ISSUER MULTILINE_OCTAL\n");
+	dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
+	printf("END\n");
+	printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
+	dumpbytes(serial->data,serial->len);
+	printf("END\n");
+	printf("CKA_VALUE MULTILINE_OCTAL\n");
+	dumpbytes(sdder->data,sdder->len);
+	printf("END\n");
+    }
+    
+    if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags) 
+         == CERTDB_TERMINAL_RECORD)
+      trust_info = "Distrust";
+    else
+      trust_info = "Trust for";
+    
+    printf("\n# %s \"%s\"\n", trust_info, nickname);
+    print_info(sdder, cert);
 
-    printf("\n#\n# Certificate \"%s\"\n#\n",nickname);
-    printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n");
-    printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
-    printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
-    printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
-    printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
-    printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n");
-    printf("CKA_SUBJECT MULTILINE_OCTAL\n");
-    dumpbytes(cert->derSubject.data,cert->derSubject.len);
-    printf("END\n");
-    printf("CKA_ID UTF8 \"0\"\n");
-    printf("CKA_ISSUER MULTILINE_OCTAL\n");
-    dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
-    printf("END\n");
-    printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
-    dumpbytes(serial->data,serial->len);
-    printf("END\n");
-    printf("CKA_VALUE MULTILINE_OCTAL\n");
-    dumpbytes(sdder->data,sdder->len);
-    printf("END\n");
-
-    PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len);
-    PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len);
-    printf("\n# Trust for Certificate \"%s\"\n",nickname);
     printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
     printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
     printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
     printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
     printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
-    printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n");
-    dumpbytes(sha1_hash,SHA1_LENGTH);
-    printf("END\n");
-    printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n");
-    dumpbytes(md5_hash,MD5_LENGTH);
-    printf("END\n");
+    
+    if (!excludeHash) {
+	PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len);
+	printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n");
+	dumpbytes(sha1_hash,SHA1_LENGTH);
+	printf("END\n");
+	PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len);
+	printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n");
+	dumpbytes(md5_hash,MD5_LENGTH);
+	printf("END\n");
+    }
 
     printf("CKA_ISSUER MULTILINE_OCTAL\n");
     dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
     printf("END\n");
     printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
     dumpbytes(serial->data,serial->len);
     printf("END\n");
     
     printf("CKA_TRUST_SERVER_AUTH CK_TRUST %s\n",
-				 getTrustString(trust->sslFlags));
+				getTrustString(trust->sslFlags));
     printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST %s\n",
-				 getTrustString(trust->emailFlags));
+				getTrustString(trust->emailFlags));
     printf("CKA_TRUST_CODE_SIGNING CK_TRUST %s\n",
-				 getTrustString(trust->objectSigningFlags));
+				getTrustString(trust->objectSigningFlags));
 #ifdef notdef
     printf("CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NSS_TRUSTED\n");
     printf("CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
     printf("CKA_TRUST_NON_REPUDIATION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
     printf("CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
     printf("CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
     printf("CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
     printf("CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
 #endif
+    
+    step_up = (trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
     printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL %s\n",
-                trust->sslFlags & CERTDB_GOVT_APPROVED_CA ? 
-                "CK_TRUE" : "CK_FALSE");
-
+                step_up ? "CK_TRUE" : "CK_FALSE");
 
     PORT_Free(sdder->data);
     return(rv);
 
 }
 
 void printheader() {
     printf("# \n"
@@ -210,17 +325,17 @@ void printheader() {
 "# use your version of this file under the terms of the MPL, indicate your\n"
 "# decision by deleting the provisions above and replace them with the notice\n"
 "# and other provisions required by the GPL or the LGPL. If you do not delete\n"
 "# the provisions above, a recipient may use your version of this file under\n"
 "# the terms of any one of the MPL, the GPL or the LGPL.\n"
 "#\n"
 "# ***** END LICENSE BLOCK *****\n"
      "#\n"
-     "CVS_ID \"@(#) $RCSfile: addbuiltin.c,v $ $Revision: 1.16 $ $Date: 2011/04/13 00:10:21 $\"\n"
+     "CVS_ID \"@(#) $RCSfile: addbuiltin.c,v $ $Revision: 1.17 $ $Date: 2012/03/10 12:10:44 $\"\n"
      "\n"
      "#\n"
      "# certdata.txt\n"
      "#\n"
      "# This file contains the object definitions for the certs and other\n"
      "# information \"built into\" NSS.\n"
      "#\n"
      "# Object definitions:\n"
@@ -280,69 +395,127 @@ void printheader() {
      "CKA_TOKEN CK_BBOOL CK_TRUE\n"
      "CKA_PRIVATE CK_BBOOL CK_FALSE\n"
      "CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"
      "CKA_LABEL UTF8 \"Mozilla Builtin Roots\"\n");
 }
 
 static void Usage(char *progName)
 {
-    fprintf(stderr, "%s -n nickname -t trust [-i certfile]\n", progName);
+    fprintf(stderr, "%s -t trust -n nickname [-i certfile] [-c] [-h]\n", progName);
     fprintf(stderr, 
             "\tRead a der-encoded cert from certfile or stdin, and output\n"
             "\tit to stdout in a format suitable for the builtin root module.\n"
-            "\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n"
-            "\t(pipe through atob if the cert is b64-encoded)\n", progName);
-    fprintf(stderr, "%-15s nickname to assign to builtin cert.\n", 
+            "\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n",
+            progName);
+    fprintf(stderr, "%s -D -n label [-i certfile]\n", progName);
+    fprintf(stderr, 
+            "\tRead a der-encoded cert from certfile or stdin, and output\n"
+            "\ta distrust record.\n"
+	    "\t(-D is equivalent to -t p,p,p -c -h)\n");
+    fprintf(stderr, "%s -C -e crl-entry-number -n label [-i crlfile]\n", progName);
+    fprintf(stderr, 
+            "\tRead a CRL from crlfile or stdin, and output\n"
+            "\ta distrust record (issuer+serial).\n"
+	    "\t(-C implies -c -h)\n");
+    fprintf(stderr, "%-15s trust flags (cCTpPuw).\n", "-t trust");
+    fprintf(stderr, "%-15s nickname to assign to builtin cert, or\n", 
                     "-n nickname");
-    fprintf(stderr, "%-15s trust flags (cCTpPuw).\n", "-t trust");
-    fprintf(stderr, "%-15s file to read (default stdin)\n", "-i certfile");
+    fprintf(stderr, "%-15s a label for the distrust record.\n", "");
+    fprintf(stderr, "%-15s exclude the certificate (only add a trust record)\n", "-c");
+    fprintf(stderr, "%-15s exclude hash from trust record\n", "-h");
+    fprintf(stderr, "%-15s     (useful to distrust any matching issuer/serial)\n", "");
+    fprintf(stderr, "%-15s     (not allowed when adding positive trust)\n", "");
+    fprintf(stderr, "%-15s a CRL entry number, as shown by \"crlutil -S\"\n", "-e");
+    fprintf(stderr, "%-15s input file to read (default stdin)\n", "-i file");
+    fprintf(stderr, "%-15s     (pipe through atob if the cert is b64-encoded)\n", "");
     exit(-1);
 }
 
 enum {
     opt_Input = 0,
     opt_Nickname,
-    opt_Trust
+    opt_Trust,
+    opt_Distrust,
+    opt_ExcludeCert,
+    opt_ExcludeHash,
+    opt_DistrustCRL,
+    opt_CRLEnry
 };
 
 static secuCommandFlag addbuiltin_options[] =
 {
-	{ /* opt_Input         */  'i', PR_TRUE, 0, PR_FALSE },
-	{ /* opt_Nickname      */  'n', PR_TRUE, 0, PR_FALSE },
-	{ /* opt_Trust         */  't', PR_TRUE, 0, PR_FALSE }
+	{ /* opt_Input         */  'i', PR_TRUE,  0, PR_FALSE },
+	{ /* opt_Nickname      */  'n', PR_TRUE,  0, PR_FALSE },
+	{ /* opt_Trust         */  't', PR_TRUE,  0, PR_FALSE },
+        { /* opt_Distrust      */  'D', PR_FALSE, 0, PR_FALSE },
+        { /* opt_ExcludeCert   */  'c', PR_FALSE, 0, PR_FALSE },
+        { /* opt_ExcludeHash   */  'h', PR_FALSE, 0, PR_FALSE },
+        { /* opt_DistrustCRL   */  'C', PR_FALSE, 0, PR_FALSE },
+        { /* opt_CRLEnry       */  'e', PR_TRUE,  0, PR_FALSE },
 };
 
 int main(int argc, char **argv)
 {
     SECStatus rv;
-    char *nickname;
-    char *trusts;
+    char *nickname = NULL;
+    char *trusts = NULL;
     char *progName;
     PRFileDesc *infile;
     CERTCertTrust trust = { 0 };
-    SECItem derCert = { 0 };
+    SECItem derItem = { 0 };
+    PRInt32 crlentry = 0;
+    PRInt32 mutuallyExclusiveOpts = 0;
+    PRBool decodeTrust = PR_FALSE;
 
     secuCommand addbuiltin = { 0 };
     addbuiltin.numOptions = sizeof(addbuiltin_options)/sizeof(secuCommandFlag);
     addbuiltin.options = addbuiltin_options;
 
     progName = strrchr(argv[0], '/');
     progName = progName ? progName+1 : argv[0];
 
     rv = SECU_ParseCommandLine(argc, argv, progName, &addbuiltin);
 
     if (rv != SECSuccess)
 	Usage(progName);
+    
+    if (addbuiltin.options[opt_Trust].activated)
+      ++mutuallyExclusiveOpts;
+    if (addbuiltin.options[opt_Distrust].activated)
+      ++mutuallyExclusiveOpts;
+    if (addbuiltin.options[opt_DistrustCRL].activated)
+      ++mutuallyExclusiveOpts;
 
-    if (!addbuiltin.options[opt_Nickname].activated &&
-        !addbuiltin.options[opt_Trust].activated) {
-	fprintf(stderr, "%s: you must specify both a nickname and trust.\n",
-		progName);
-	Usage(progName);
+    if (mutuallyExclusiveOpts != 1) {
+        fprintf(stderr, "%s: you must specify exactly one of -t or -D or -C\n",
+                progName);
+        Usage(progName);
+    }
+    
+    if (addbuiltin.options[opt_DistrustCRL].activated) {
+	if (!addbuiltin.options[opt_CRLEnry].activated) {
+	    fprintf(stderr, "%s: you must specify the CRL entry number.\n",
+		    progName);
+	    Usage(progName);
+	}
+	else {
+	    crlentry = atoi(addbuiltin.options[opt_CRLEnry].arg);
+	    if (crlentry < 1) {
+		fprintf(stderr, "%s: The CRL entry number must be > 0.\n",
+			progName);
+		Usage(progName);
+	    }
+	}
+    }
+
+    if (!addbuiltin.options[opt_Nickname].activated) {
+        fprintf(stderr, "%s: you must specify parameter -n (a nickname or a label).\n",
+                progName);
+        Usage(progName);
     }
 
     if (addbuiltin.options[opt_Input].activated) {
 	infile = PR_Open(addbuiltin.options[opt_Input].arg, PR_RDONLY, 00660);
 	if (!infile) {
 	    fprintf(stderr, "%s: failed to open input file.\n", progName);
 	    exit(1);
 	}
@@ -360,34 +533,66 @@ int main(int argc, char **argv)
 	            progName);
 	    exit(1);
 	}
 #endif
 	infile = PR_STDIN;
     }
 
     nickname = strdup(addbuiltin.options[opt_Nickname].arg);
-    trusts = strdup(addbuiltin.options[opt_Trust].arg);
-
+    
     NSS_NoDB_Init(NULL);
 
-    rv = CERT_DecodeTrustString(&trust, trusts);
-    if (rv) {
-	fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName);
-	Usage(progName);
+    if (addbuiltin.options[opt_Distrust].activated ||
+        addbuiltin.options[opt_DistrustCRL].activated) {
+      addbuiltin.options[opt_ExcludeCert].activated = PR_TRUE;
+      addbuiltin.options[opt_ExcludeHash].activated = PR_TRUE;
+    }
+    
+    if (addbuiltin.options[opt_Distrust].activated) {
+        trusts = strdup("p,p,p");
+	decodeTrust = PR_TRUE;
+    }
+    else if (addbuiltin.options[opt_Trust].activated) {
+        trusts = strdup(addbuiltin.options[opt_Trust].arg);
+	decodeTrust = PR_TRUE;
+    }
+    
+    if (decodeTrust) {
+	rv = CERT_DecodeTrustString(&trust, trusts);
+	if (rv) {
+	    fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName);
+	    Usage(progName);
+	}
+    }
+    
+    if (addbuiltin.options[opt_Trust].activated &&
+        addbuiltin.options[opt_ExcludeHash].activated) {
+	if ((trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) 
+	    != CERTDB_TERMINAL_RECORD) {
+	    fprintf(stderr, "%s: Excluding the hash only allowed with distrust.\n", progName);
+	    Usage(progName);
+	}
     }
 
-    SECU_FileToItem(&derCert, infile);
+    SECU_FileToItem(&derItem, infile);
     
     /*printheader();*/
-
-    rv = ConvertCertificate(&derCert, nickname, &trust);
-    if (rv) {
-	fprintf(stderr, "%s: failed to convert certificate.\n", progName);
-	exit(1);
+    
+    if (addbuiltin.options[opt_DistrustCRL].activated) {
+	rv = ConvertCRLEntry(&derItem, crlentry, nickname);
+    }
+    else {
+	rv = ConvertCertificate(&derItem, nickname, &trust, 
+				addbuiltin.options[opt_ExcludeCert].activated,
+				addbuiltin.options[opt_ExcludeHash].activated);
+	if (rv) {
+	    fprintf(stderr, "%s: failed to convert certificate.\n", progName);
+	    exit(1);
+	}
     }
     
     if (NSS_Shutdown() != SECSuccess) {
         exit(1);
     }
 
     return(SECSuccess);
 }
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -1166,17 +1166,17 @@ static void luC(enum usage_level ul, con
     FPS "%-20s Create authority key ID extension\n",
         "   -3 ");
     FPS "%-20s Create crl distribution point extension\n",
         "   -4 ");
     FPS "%-20s \n"
               "%-20s Create netscape cert type extension. Possible keywords:\n"
               "%-20s \"sslClient\", \"sslServer\", \"smime\", \"objectSigning\",\n"
               "%-20s \"sslCA\", \"smimeCA\", \"objectSigningCA\", \"critical\".\n",
-        "   -5 | -nsCertType keyword,keyword,... ", "", "", "");
+        "   -5 | --nsCertType keyword,keyword,... ", "", "", "");
     FPS "%-20s \n"
               "%-20s Create extended key usage extension. Possible keywords:\n"
               "%-20s \"serverAuth\", \"clientAuth\",\"codeSigning\",\n"
               "%-20s \"emailProtection\", \"timeStamp\",\"ocspResponder\",\n"
               "%-20s \"stepUp\", \"critical\"\n",
         "   -6 | --extKeyUsage keyword,keyword,...", "", "", "", "");
     FPS "%-20s Create an email subject alt name extension\n",
         "   -7 emailAddrs");
--- a/security/nss/cmd/crlutil/crlutil.c
+++ b/security/nss/cmd/crlutil/crlutil.c
@@ -308,16 +308,47 @@ SECStatus ImportCRL (CERTCertDBHandle *c
     }
   loser:
     if (slot) {
         PK11_FreeSlot(slot);
     }
     return (rv);
 }
 
+SECStatus DumpCRL(PRFileDesc *inFile)
+{
+    int rv;
+    PRArenaPool *arena = NULL;
+    CERTSignedCrl *newCrl = NULL;
+    
+    SECItem crlDER;
+    crlDER.data = NULL;
+
+    /* Read in the entire file specified with the -f argument */
+    rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
+    if (rv != SECSuccess) {
+	SECU_PrintError(progName, "unable to read input file");
+	return (SECFailure);
+    }
+    
+    rv = SEC_ERROR_NO_MEMORY;
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if (!arena)
+    	return rv;
+
+    newCrl = CERT_DecodeDERCrlWithFlags(arena, &crlDER, SEC_CRL_TYPE,
+					CRL_DECODE_DEFAULT_OPTIONS);
+    if (!newCrl)
+    	return SECFailure;
+    
+    SECU_PrintCRLInfo (stdout, &newCrl->crl, "CRL file contents", 0);
+    
+    PORT_FreeArena (arena, PR_FALSE);
+    return rv;
+}
 
 static CERTCertificate*
 FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl,
                 char *certNickName)
 {                   
     CERTCertificate *cert = NULL, *certTemp = NULL;
     SECStatus rv = SECFailure;
     CERTAuthKeyID* authorityKeyID = NULL;
@@ -751,24 +782,25 @@ GenerateCRL (CERTCertDBHandle *certHandl
     return (rv);
 }
 
 static void Usage(char *progName)
 {
     fprintf(stderr,
 	    "Usage:  %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
 	    "        %s -D -n nickname [-d keydir] [-P dbprefix]\n"
+	    "        %s -S -i crl\n"
 	    "        %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B] "
             "[-p pwd-file] -w [pwd-string]\n"
 	    "        %s -E -t crlType [-d keydir] [-P dbprefix]\n"
 	    "        %s -T\n"
 	    "        %s -G|-M -c crl-init-file -n nickname [-i crl] [-u url] "
             "[-d keydir] [-P dbprefix] [-Z alg] ] [-p pwd-file] -w [pwd-string] "
             "[-a] [-B]\n",
-	    progName, progName, progName, progName, progName, progName);
+	    progName, progName, progName, progName, progName, progName, progName);
 
     fprintf (stderr, "%-15s List CRL\n", "-L");
     fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
 	    "-n nickname");
     fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 	    "-d keydir");
     fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
 	    "-P dbprefix");
@@ -783,16 +815,20 @@ static void Usage(char *progName)
 	    "-P dbprefix");
 
     fprintf (stderr, "%-15s Erase all CRLs of specified type from hte cert database\n", "-E");
     fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
     fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 	    "-d keydir");
     fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
 	    "-P dbprefix");
+    
+    fprintf (stderr, "%-15s Show contents of a CRL file (without database)\n", "-S");
+    fprintf(stderr, "%-20s Specify the file which contains the CRL to show\n",
+	    "-i crl");
 
     fprintf (stderr, "%-15s Import a CRL to the cert database\n", "-I");    
     fprintf(stderr, "%-20s Specify the file which contains the CRL to import\n",
 	    "-i crl");
     fprintf(stderr, "%-20s Specify the url.\n", "-u url");
     fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
     fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 	    "-d keydir");
@@ -830,25 +866,24 @@ static void Usage(char *progName)
     fprintf(stderr, "%-20s Specify the url.\n", "-u url");
     fprintf(stderr, "\n%-20s Bypass CA certificate checks.\n", "-B");
 
     exit(-1);
 }
 
 int main(int argc, char **argv)
 {
-    SECItem privKeyDER;
     CERTCertDBHandle *certHandle;
-    FILE *certFile;
     PRFileDesc *inFile;
     PRFileDesc *inCrlInitFile = NULL;
     int generateCRL;
     int modifyCRL;
     int listCRL;
     int importCRL;
+    int showFileCRL;
     int deleteCRL;
     int rv;
     char *nickName;
     char *url;
     char *dbPrefix = "";
     char *alg = NULL;
     char *outFile = NULL;
     char *slotName = NULL;
@@ -867,27 +902,25 @@ int main(int argc, char **argv)
     PRBool readonly = PR_FALSE;
 
     secuPWData  pwdata          = { PW_NONE, 0 };
 
     progName = strrchr(argv[0], '/');
     progName = progName ? progName+1 : argv[0];
 
     rv = 0;
-    deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = 0;
-    certFile = NULL;
+    deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0;
     inFile = NULL;
     nickName = url = NULL;
-    privKeyDER.data = NULL;
     certHandle = NULL;
     crlType = SEC_CRL_TYPE;
     /*
      * Parse command line arguments
      */
-    optstate = PL_CreateOptState(argc, argv, "sqBCDGILMTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
+    optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	switch (optstate->option) {
 	  case '?':
 	    Usage(progName);
 	    break;
 
           case 'T':
             test = PR_TRUE;
@@ -911,16 +944,20 @@ int main(int argc, char **argv)
 
 	  case 'D':
 	      deleteCRL = 1;
 	      break;
 
 	  case 'I':
 	      importCRL = 1;
 	      break;
+	      
+	  case 'S':
+	      showFileCRL = 1;
+	      break;
 	           
 	  case 'C':
 	  case 'L':
 	      listCRL = 1;
 	      break;
 
 	  case 'P':
  	    dbPrefix = strdup(optstate->value);
@@ -982,20 +1019,17 @@ int main(int argc, char **argv)
 	  case 'r': {
 	    const char* str = optstate->value;
 	    if (str && atoi(str)>0)
 		iterations = atoi(str);
 	    }
 	    break;
 	    
 	  case 't': {
-	    char *type;
-	    
-	    type = strdup(optstate->value);
-	    crlType = atoi (type);
+	    crlType = atoi(optstate->value);
 	    if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
 		PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName);
 		PL_DestroyOptState(optstate);
 		return -1;
 	    }
 	    break;
 
 	  case 'q':
@@ -1013,35 +1047,42 @@ int main(int argc, char **argv)
 
           }
 	}
     }
     PL_DestroyOptState(optstate);
 
     if (deleteCRL && !nickName) Usage (progName);
     if (importCRL && !inFile) Usage (progName);
+    if (showFileCRL && !inFile) Usage (progName);
     if ((generateCRL && !nickName) ||
         (modifyCRL && !inFile && !nickName)) Usage (progName);
-    if (!(listCRL || deleteCRL || importCRL || generateCRL ||
+    if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL ||
 	  modifyCRL || test || erase)) Usage (progName);
 
-    if (listCRL) {
+    if (listCRL || showFileCRL) {
         readonly = PR_TRUE;
     }
     
     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
 
     PK11_SetPasswordFunc(SECU_GetModulePassword);
 
-    secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
-			       "secmod.db", readonly ? NSS_INIT_READONLY : 0);
-    if (secstatus != SECSuccess) {
-	SECU_PrintPRandOSError(progName);
-	return -1;
+    if (showFileCRL) {
+	NSS_NoDB_Init(NULL);
     }
+    else {
+	secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
+				"secmod.db", readonly ? NSS_INIT_READONLY : 0);
+	if (secstatus != SECSuccess) {
+	    SECU_PrintPRandOSError(progName);
+	    return -1;
+	}
+    }
+    
     SECU_RegisterDynamicOids();
 
     certHandle = CERT_GetDefaultCertDB();
     if (certHandle == NULL) {
 	SECU_PrintError(progName, "unable to open the cert db");	    	
 	/*ignoring return value of NSS_Shutdown() as code returns -1*/
 	(void) NSS_Shutdown();
 	return (-1);
@@ -1054,16 +1095,19 @@ int main(int argc, char **argv)
 	if (deleteCRL) 
 	    DeleteCRL (certHandle, nickName, crlType);
 	else if (listCRL) {
 	    rv = ListCRL (certHandle, nickName, crlType);
 	}
 	else if (importCRL) {
 	    rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
 			    decodeOptions, &pwdata);
+	}
+	else if (showFileCRL) {
+	    rv = DumpCRL (inFile);
 	} else if (generateCRL || modifyCRL) {
 	    if (!inCrlInitFile)
 		inCrlInitFile = PR_STDIN;
 	    rv = GenerateCRL (certHandle, nickName, inCrlInitFile,
 			      inFile, outFile, ascii,  slotName,
 			      importOptions, alg, quiet,
 			      decodeOptions, url, &pwdata,
 			      modifyCRL);
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -81,16 +81,29 @@ static char consoleName[] =  {
     "CON:"
 #endif
 #endif
 };
 
 #include "nssutil.h"
 #include "ssl.h"
 
+static PRBool wrapEnabled = PR_TRUE;
+
+void
+SECU_EnableWrap(PRBool enable)
+{
+    wrapEnabled = enable;
+}
+
+PRBool
+SECU_GetWrapEnabled()
+{
+    return wrapEnabled;
+}
 
 void 
 SECU_PrintErrMsg(FILE *out, int level, char *progName, char *msg, ...)
 {
     va_list args;
     PRErrorCode err = PORT_GetError();
     const char * errString = SECU_Strerror(err);
 
@@ -784,21 +797,25 @@ SECU_PrintAsHex(FILE *out, SECItem *data
     unsigned i;
     int column;
     PRBool isString     = PR_TRUE;
     PRBool isWhiteSpace = PR_TRUE;
     PRBool printedHex   = PR_FALSE;
     unsigned int limit = 15;
 
     if ( m ) {
-	SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+	SECU_Indent(out, level); fprintf(out, "%s:", m);
 	level++;
+	if (wrapEnabled)
+	    fprintf(out, "\n");
     }
-    
-    SECU_Indent(out, level); column = level*INDENT_MULT;
+
+    if (wrapEnabled) {
+	SECU_Indent(out, level); column = level*INDENT_MULT;
+    }
     if (!data->len) {
 	fprintf(out, "(empty)\n");
 	return;
     }
     /* take a pass to see if it's all printable. */
     for (i = 0; i < data->len; i++) {
 	unsigned char val = data->data[i];
         if (!val || !isprint(val)) {
@@ -821,17 +838,18 @@ SECU_PrintAsHex(FILE *out, SECItem *data
 	if (i != data->len - 1) {
 	    fprintf(out, "%02x:", data->data[i]);
 	    column += 3;
 	} else {
 	    fprintf(out, "%02x", data->data[i]);
 	    column += 2;
 	    break;
 	}
-	if (column > 76 || (i % 16 == limit)) {
+	if (wrapEnabled &&
+	    (column > 76 || (i % 16 == limit))) {
 	    secu_Newline(out);
 	    SECU_Indent(out, level); 
 	    column = level*INDENT_MULT;
 	    limit = i % 16;
 	}
       }
       printedHex = PR_TRUE;
     }
@@ -844,17 +862,17 @@ SECU_PrintAsHex(FILE *out, SECItem *data
 	    unsigned char val = data->data[i];
 
 	    if (val) {
 		fprintf(out,"%c",val);
 		column++;
 	    } else {
 		column = 77;
 	    }
-	    if (column > 76) {
+	    if (wrapEnabled && column > 76) {
 		secu_Newline(out);
         	SECU_Indent(out, level); column = level*INDENT_MULT;
 	    }
 	}
     }
 	    
     if (column != level*INDENT_MULT) {
 	secu_Newline(out);
@@ -970,47 +988,59 @@ SECU_PrintInteger(FILE *out, SECItem *i,
 	    fprintf(out, "%s: %d (0x%x)\n", m, iv, iv);
 	} else {
 	    fprintf(out, "%d (0x%x)\n", iv, iv);
 	}
     }
 }
 
 static void
-secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
+secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m, 
+				  int level, PRBool quotes)
 {
     int column;
     unsigned int i;
 
     if ( m ) {
 	SECU_Indent(out, level); fprintf(out, "%s: ", m);
 	column = (level * INDENT_MULT) + strlen(m) + 2;
 	level++;
     } else {
 	SECU_Indent(out, level); 
 	column = level*INDENT_MULT;
     }
-    fprintf(out, "\""); column++;
+    if (quotes) {
+	fprintf(out, "\""); column++;
+    }
 
     for (i = 0; i < si->len; i++) {
 	unsigned char val = si->data[i];
-	if (column > 76) {
+	if (wrapEnabled && column > 76) {
 	    secu_Newline(out);
 	    SECU_Indent(out, level); column = level*INDENT_MULT;
 	}
 
 	fprintf(out,"%c", printable[val]); column++;
     }
 
-    fprintf(out, "\""); column++;
-    if (column != level*INDENT_MULT || column > 76) {
+    if (quotes) {
+	fprintf(out, "\""); column++;
+    }
+    if (wrapEnabled &&
+        (column != level*INDENT_MULT || column > 76)) {
 	secu_Newline(out);
     }
 }
 
+static void
+secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
+{
+    secu_PrintRawStringQuotesOptional(out, si, m, level, PR_TRUE);
+}
+
 void
 SECU_PrintString(FILE *out, SECItem *si, char *m, int level)
 {
     SECItem my = *si;
 
     if (SECSuccess != SECU_StripTagAndLength(&my) || !my.len)
     	return;
     secu_PrintRawString(out, &my, m, level);
@@ -2404,17 +2434,18 @@ SECU_PrintRDN(FILE *out, CERTRDN *rdn, c
     name.arena = NULL;
     name.rdns  = rdns;
     rdns[0] = rdn;
     rdns[1] = NULL;
     SECU_PrintName(out, &name, msg, level);
 }
 
 void
-SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
+SECU_PrintNameQuotesOptional(FILE *out, CERTName *name, const char *msg, 
+			     int level, PRBool quotes)
 {
     char *nameStr = NULL;
     char *str;
     SECItem my;
 
     if (!name) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return;
@@ -2425,26 +2456,32 @@ SECU_PrintName(FILE *out, CERTName *name
 	str = nameStr = CERT_NameToAscii(name);
     }
     if (!str) {
     	str = "!Invalid AVA!";
     }
     my.data = (unsigned char *)str;
     my.len  = PORT_Strlen(str);
 #if 1
-    secu_PrintRawString(out, &my, msg, level);
+    secu_PrintRawStringQuotesOptional(out, &my, msg, level, quotes);
 #else
     SECU_Indent(out, level); fprintf(out, "%s: ", msg);
     fprintf(out, str);
     secu_Newline(out);
 #endif
     PORT_Free(nameStr);
 }
 
 void
+SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
+{
+    SECU_PrintNameQuotesOptional(out, name, msg, level, PR_TRUE);
+}
+
+void
 printflags(char *trusts, unsigned int flags)
 {
     if (flags & CERTDB_VALID_CA)
 	if (!(flags & CERTDB_TRUSTED_CA) &&
 	    !(flags & CERTDB_TRUSTED_CLIENT_CA))
 	    PORT_Strcat(trusts, "c");
     if (flags & CERTDB_TERMINAL_RECORD)
 	if (!(flags & CERTDB_TRUSTED))
@@ -2748,33 +2785,48 @@ SECU_PrintFingerprints(FILE *out, SECIte
     SECItem fpItem;
 
     /* print MD5 fingerprint */
     memset(fingerprint, 0, sizeof fingerprint);
     rv = PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
     fpItem.data = fingerprint;
     fpItem.len = MD5_LENGTH;
     fpStr = CERT_Hexify(&fpItem, 1);
-    SECU_Indent(out, level);  fprintf(out, "%s (MD5):\n", m);
-    SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+    SECU_Indent(out, level);  fprintf(out, "%s (MD5):", m);
+    if (wrapEnabled) {
+	fprintf(out, "\n");
+	SECU_Indent(out, level+1);
+    }
+    else {
+	fprintf(out, " ");
+    }
+    fprintf(out, "%s\n", fpStr);
     PORT_Free(fpStr);
     fpStr = NULL;
     if (rv != SECSuccess && !err)
 	err = PORT_GetError();
 
     /* print SHA1 fingerprint */
     memset(fingerprint, 0, sizeof fingerprint);
     rv = PK11_HashBuf(SEC_OID_SHA1,fingerprint, derCert->data, derCert->len);
     fpItem.data = fingerprint;
     fpItem.len = SHA1_LENGTH;
     fpStr = CERT_Hexify(&fpItem, 1);
-    SECU_Indent(out, level);  fprintf(out, "%s (SHA1):\n", m);
-    SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
+    SECU_Indent(out, level);  fprintf(out, "%s (SHA1):", m);
+    if (wrapEnabled) {
+	fprintf(out, "\n");
+	SECU_Indent(out, level+1);
+    }
+    else {
+	fprintf(out, " ");
+    }
+    fprintf(out, "%s\n", fpStr);
     PORT_Free(fpStr);
-    fprintf(out, "\n");
+    if (wrapEnabled)
+	fprintf(out, "\n");
 
     if (err) 
 	PORT_SetError(err);
     if (err || rv != SECSuccess)
 	return SECFailure;
 
     return 0;
 }
@@ -2902,17 +2954,17 @@ SECU_PrintCRLInfo(FILE *out, CERTCrl *cr
     SECU_PrintName(out, &(crl->name), "Issuer", level + 1);
     SECU_PrintTimeChoice(out, &(crl->lastUpdate), "This Update", level + 1);
     if (crl->nextUpdate.data && crl->nextUpdate.len) /* is optional */
 	SECU_PrintTimeChoice(out, &(crl->nextUpdate), "Next Update", level + 1);
     
     if (crl->entries != NULL) {
 	iv = 0;
 	while ((entry = crl->entries[iv++]) != NULL) {
-	    sprintf(om, "Entry (%x):\n", iv); 
+	    sprintf(om, "Entry %d (0x%x):\n", iv, iv); 
 	    SECU_Indent(out, level + 1); fputs(om, out);
 	    SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
 			      level + 2);
 	    SECU_PrintTimeChoice(out, &(entry->revocationDate), 
 	                         "Revocation Date", level + 2);
 	    SECU_PrintExtensions(out, entry->extensions, 
 	                         "Entry Extensions", level + 2);
 	}
--- a/security/nss/cmd/lib/secutil.h
+++ b/security/nss/cmd/lib/secutil.h
@@ -163,16 +163,19 @@ extern char *SECU_ConfigDirectory(const 
 ** Basic callback function for SSL_GetClientAuthDataHook
 */
 extern int
 SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
 		       struct CERTDistNamesStr *caNames,
 		       struct CERTCertificateStr **pRetCert,
 		       struct SECKEYPrivateKeyStr **pRetKey);
 
+extern PRBool SECU_GetWrapEnabled();
+extern void SECU_EnableWrap(PRBool enable);
+
 /* print out an error message */
 extern void SECU_PrintError(char *progName, char *msg, ...);
 
 /* print out a system error message */
 extern void SECU_PrintSystemError(char *progName, char *msg, ...);
 
 /* revalidate the cert and print information about cert verification
  * failure at time == now */
@@ -308,16 +311,19 @@ extern void SECU_PrintAny(FILE *out, SEC
 
 extern void SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level);
 extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
                                  char *msg, int level);
 
 extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
 				 char *msg, int level);
 
+extern void SECU_PrintNameQuotesOptional(FILE *out, CERTName *name, 
+					 const char *msg, int level, 
+					 PRBool quotes);
 extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg,
                            int level);
 extern void SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level);
 
 #ifdef SECU_GetPassword
 /* Convert a High public Key to a Low public Key */
 extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
 #endif
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -798,16 +798,18 @@ PRBool hasSidCache     = PR_FALSE;
 PRBool disableStepDown = PR_FALSE;
 PRBool bypassPKCS11    = PR_FALSE;
 PRBool disableLocking  = PR_FALSE;
 PRBool testbypass      = PR_FALSE;
 PRBool enableSessionTickets = PR_FALSE;
 PRBool enableCompression    = PR_FALSE;
 PRBool failedToNegotiateName  = PR_FALSE;
 static char  *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
+static int                  virtServerNameIndex = 1;
+
 
 static const char stopCmd[] = { "GET /stop " };
 static const char getCmd[]  = { "GET " };
 static const char EOFmsg[]  = { "EOF\r\n\r\n\r\n" };
 static const char outHeader[] = {
     "HTTP/1.0 200 OK\r\n"
     "Server: Generic Web Server\r\n"
     "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
@@ -1701,20 +1703,22 @@ server_main(
 
     if (enableCompression) {
 	rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE);
 	if (rv != SECSuccess) {
 	    errExit("error enabling compression ");
 	}
     }
 
-    rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
-                                 (void*)&virtServerNameArray);
-    if (rv != SECSuccess) {
-        errExit("error enabling SNI extension ");
+    if (virtServerNameIndex >1) {
+        rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
+                                     (void*)&virtServerNameArray);
+        if (rv != SECSuccess) {
+            errExit("error enabling SNI extension ");
+        }
     }
 
     for (kea = kt_rsa; kea < kt_kea_size; kea++) {
 	if (cert[kea] != NULL) {
 	    secStatus = SSL_ConfigSecureServer(model_sock, 
 	    		cert[kea], privKey[kea], kea);
 	    if (secStatus != SECSuccess)
 		errExit("SSL_ConfigSecureServer");
@@ -1930,17 +1934,16 @@ main(int argc, char **argv)
     PRThread             *loggerThread = NULL;
     PRBool               debugCache = PR_FALSE; /* bug 90518 */
     char                 emptyString[] = { "" };
     char*                certPrefix = emptyString;
     PRUint32             protos = 0;
     SSL3Statistics      *ssl3stats;
     PRUint32             i;
     secuPWData  pwdata = { PW_NONE, 0 };
-    int                  virtServerNameIndex = 1;
     char                *expectedHostNameVal = NULL;
 
     tmp = strrchr(argv[0], '/');
     tmp = tmp ? tmp + 1 : argv[0];
     progName = strrchr(tmp, '\\');
     progName = progName ? progName + 1 : tmp;
 
     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
--- a/security/nss/cmd/symkeyutil/symkeyutil.c
+++ b/security/nss/cmd/symkeyutil/symkeyutil.c
@@ -745,17 +745,17 @@ main(int argc, char **argv)
 	          "%s Couldn't read key ID file (%s).\n",
 	           progName, symKeyUtil.options[opt_WrapKeyIDFile].arg);
 	    return 255;
 	}
     }
 
     /*  -P certdb name prefix */
     if (symKeyUtil.options[opt_dbPrefix].activated)
-	certPrefix = strdup(symKeyUtil.options[opt_dbPrefix].arg);
+	certPrefix = symKeyUtil.options[opt_dbPrefix].arg;
 
     /*  Check number of commands entered.  */
     commandsEntered = 0;
     for (i=0; i< symKeyUtil.numCommands; i++) {
 	if (symKeyUtil.commands[i].activated) {
 	    commandToRun = symKeyUtil.commands[i].flag;
 	    commandsEntered++;
 	}
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Certificate handling code
  *
- * $Id: certdb.c,v 1.120 2011/11/17 00:20:20 bsmith%mozilla.com Exp $
+ * $Id: certdb.c,v 1.121 2012/03/23 03:25:57 wtc%google.com Exp $
  */
 
 #include "nssilock.h"
 #include "prmon.h"
 #include "prtime.h"
 #include "cert.h"
 #include "certi.h"
 #include "secder.h"
@@ -591,16 +591,30 @@ cert_ComputeCertType(CERTCertificate *ce
 	    SECSuccess){
 	    if (basicConstraintPresent == PR_TRUE &&
 		(basicConstraint.isCA)) {
 		nsCertType |= NS_CERT_TYPE_SSL_CA;
 	    } else {
 		nsCertType |= NS_CERT_TYPE_SSL_SERVER;
 	    }
 	}
+	/*
+	 * Treat certs with step-up OID as also having SSL server type.
+ 	 * COMODO needs this behaviour until June 2020.  See Bug 737802.
+	 */
+	if (findOIDinOIDSeqByTagNum(extKeyUsage, 
+				    SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==
+	    SECSuccess){
+	    if (basicConstraintPresent == PR_TRUE &&
+		(basicConstraint.isCA)) {
+		nsCertType |= NS_CERT_TYPE_SSL_CA;
+	    } else {
+		nsCertType |= NS_CERT_TYPE_SSL_SERVER;
+	    }
+	}
 	if (findOIDinOIDSeqByTagNum(extKeyUsage,
 				    SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
 	    SECSuccess){
 	    if (basicConstraintPresent == PR_TRUE &&
 		(basicConstraint.isCA)) {
 		nsCertType |= NS_CERT_TYPE_SSL_CA;
 	    } else {
 		nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
--- a/security/nss/lib/certdb/stanpcertdb.c
+++ b/security/nss/lib/certdb/stanpcertdb.c
@@ -626,17 +626,17 @@ CERT_FindCertByDERCert(CERTCertDBHandle 
 	                                                       &encoding);
 	if (!c) return NULL;
     }
     return STAN_GetCERTCertificateOrRelease(c);
 }
 
 static CERTCertificate *
 common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, 
-                                             char *name,
+                                             const char *name,
                                              PRBool anyUsage,
                                              SECCertUsage lookingForUsage)
 {
     NSSCryptoContext *cc;
     NSSCertificate *c, *ct;
     CERTCertificate *cert = NULL;
     NSSUsage usage;
     CERTCertList *certlist;
--- a/security/nss/lib/certhigh/certvfypkix.c
+++ b/security/nss/lib/certhigh/certvfypkix.c
@@ -1421,18 +1421,18 @@ cleanup:
 
 struct fake_PKIX_PL_CertStruct {
         CERTCertificate *nssCert;
 };
 
 /* This needs to be part of the PKIX_PL_* */
 /* This definitely needs to go away, and be replaced with
    a real accessor function in PKIX */
-CERTCertificate *
-cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert, void *plContext)
+static CERTCertificate *
+cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
 {
     struct fake_PKIX_PL_CertStruct *fcert = NULL;
 
     fcert = (struct fake_PKIX_PL_CertStruct*)pkix_cert;
 
     return CERT_DupCertificate(fcert->nssCert);
 }
 
@@ -2212,32 +2212,38 @@ do {
     }
 
     error = PKIX_ValidateResult_GetTrustAnchor( valResult, &trustAnchor,
                                                 plContext);
     if (error != NULL) {
         goto cleanup;
     }
 
-    error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert,
-                                                plContext);
-    if (error != NULL) {
-        goto cleanup;
+    if (trustAnchor != NULL) {
+        error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert,
+                                                 plContext);
+        if (error != NULL) {
+            goto cleanup;
+        }
     }
 
 #ifdef PKIX_OBJECT_LEAK_TEST
     /* Can not continue if error was generated but not returned.
      * Jumping to cleanup. */
     if (errorGenerated) goto cleanup;
 #endif /* PKIX_OBJECT_LEAK_TEST */
 
     oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor);
     if (oparam != NULL) {
-        oparam->value.pointer.cert = 
-                cert_NSSCertFromPKIXCert(trustAnchorCert,plContext);
+        if (trustAnchorCert != NULL) {
+            oparam->value.pointer.cert =
+                    cert_NSSCertFromPKIXCert(trustAnchorCert);
+        } else {
+            oparam->value.pointer.cert = NULL;
+        }
     }
 
     error = PKIX_BuildResult_GetCertChain( buildResult, &builtCertList,
                                                 plContext);
     if (error != NULL) {
         goto cleanup;
     }
 
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -34,17 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Implementation of OCSP services, for both client and server.
  * (XXX, really, mostly just for client right now, but intended to do both.)
  *
- * $Id: ocsp.c,v 1.67 2011/08/10 12:31:52 kaie%kuix.de Exp $
+ * $Id: ocsp.c,v 1.69 2012/03/14 22:26:53 wtc%google.com Exp $
  */
 
 #include "prerror.h"
 #include "prprf.h"
 #include "plarena.h"
 #include "prnetdb.h"
 
 #include "seccomon.h"
@@ -291,17 +291,17 @@ dumpCertID(CERTOCSPCertID *certID)
     printHexString("OCSP certID serial", &certID->serialNumber);
 }
 #endif
 
 SECStatus
 SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
 {
     if (!OCSP_Global.monitor) {
-      PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+      PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
       return SECFailure;
     }
     
     PR_EnterMonitor(OCSP_Global.monitor);
     OCSP_Global.defaultHttpClientFcn = fcnTable;
     PR_ExitMonitor(OCSP_Global.monitor);
     
     return SECSuccess;
@@ -310,17 +310,17 @@ SEC_RegisterDefaultHttpClient(const SEC_
 SECStatus
 CERT_RegisterAlternateOCSPAIAInfoCallBack(
 			CERT_StringFromCertFcn   newCallback,
 			CERT_StringFromCertFcn * oldCallback)
 {
     CERT_StringFromCertFcn old;
 
     if (!OCSP_Global.monitor) {
-      PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+      PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
       return SECFailure;
     }
 
     PR_EnterMonitor(OCSP_Global.monitor);
     old = OCSP_Global.alternateOCSPAIAFcn;
     OCSP_Global.alternateOCSPAIAFcn = newCallback;
     PR_ExitMonitor(OCSP_Global.monitor);
     if (oldCallback)
@@ -986,17 +986,17 @@ SECStatus OCSP_ShutdownGlobal(void)
  * A return value of NULL means: 
  *   The application did not register it's own HTTP client.
  */
 const SEC_HttpClientFcn *SEC_GetRegisteredHttpClient()
 {
     const SEC_HttpClientFcn *retval;
 
     if (!OCSP_Global.monitor) {
-      PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+      PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
       return NULL;
     }
 
     PR_EnterMonitor(OCSP_Global.monitor);
     retval = OCSP_Global.defaultHttpClientFcn;
     PR_ExitMonitor(OCSP_Global.monitor);
     
     return retval;
@@ -2695,20 +2695,20 @@ ocspSignature *
 ocsp_GetResponseSignature(CERTOCSPResponse *response)
 {
     ocspBasicOCSPResponse *basic;
 
     PORT_Assert(response != NULL);
     if (NULL == response->responseBytes) {
         return NULL;
     }
-    PORT_Assert(response->responseBytes != NULL);
-    PORT_Assert(response->responseBytes->responseTypeTag
-		== SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
-
+    if (response->responseBytes->responseTypeTag
+        != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
+        return NULL;
+    }
     basic = response->responseBytes->decodedResponse.basic;
     PORT_Assert(basic != NULL);
 
     return &(basic->responseSignature);
 }
 
 
 /*
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: secvfy.c,v 1.25 2011/10/22 14:35:42 wtc%google.com Exp $ */
+/* $Id: secvfy.c,v 1.28 2012/02/25 14:32:45 kaie%kuix.de Exp $ */
 
 #include <stdio.h>
 #include "cryptohi.h"
 #include "sechash.h"
 #include "keyhi.h"
 #include "secasn1.h"
 #include "secoid.h"
 #include "pk11func.h"
@@ -295,21 +295,23 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
 	    PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
 	    return SECFailure;
 	}
 	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 	if (arena == NULL) {
 	    return SECFailure;
 	}
 	rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, param);
-	if (rv != SECSuccess) {
-	    PORT_FreeArena(arena, PR_FALSE);
+	if (rv == SECSuccess) {
+            *hashalg = SECOID_FindOIDTag(&oid);
+        }
+        PORT_FreeArena(arena, PR_FALSE);
+        if (rv != SECSuccess) {
 	    return rv;
 	}
-	*hashalg = SECOID_FindOIDTag(&oid);
 	/* only accept hash algorithms */
 	if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) {
 	    /* error set by HASH_GetHashTypeByOidTag */
 	    return SECFailure;
 	}
 	break;
       /* we don't implement MD4 hashes */
       case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
--- a/security/nss/lib/freebl/blapi.h
+++ b/security/nss/lib/freebl/blapi.h
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: blapi.h,v 1.43 2011/10/29 23:28:45 wtc%google.com Exp $ */
+/* $Id: blapi.h,v 1.45 2012/03/28 22:38:27 rrelyea%redhat.com Exp $ */
 
 #ifndef _BLAPI_H_
 #define _BLAPI_H_
 
 #include "blapit.h"
 #include "hasht.h"
 #include "alghmac.h"
 
@@ -207,26 +207,31 @@ extern SECStatus DH_NewKey(DHParams *   
 /* 
 ** DH_Derive does the Diffie-Hellman phase 2 calculation, using the 
 ** other party's publicValue, and the prime and our privateValue.
 ** maxOutBytes is the requested length of the generated secret in bytes.  
 ** A zero value means produce a value of any length up to the size of 
 ** the prime.   If successful, derivedSecret->data is set 
 ** to the address of the newly allocated buffer containing the derived 
 ** secret, and derivedSecret->len is the size of the secret produced.
-** The size of the secret produced will never be larger than the length
-** of the prime, and it may be smaller than maxOutBytes.
+** The size of the secret produced will depend on the value of outBytes.
+** If outBytes is 0, the key length will be all the significant bytes of
+** the derived secret (leading zeros are dropped). This length could be less
+** than the length of the prime. If outBytes is nonzero, the length of the
+** produced key will be outBytes long. If the key is truncated, the most
+** significant bytes are truncated. If it is expanded, zero bytes are added
+** at the beginning.
 ** It is the caller's responsibility to free the allocated buffer 
 ** containing the derived secret.
 */
 extern SECStatus DH_Derive(SECItem *    publicValue, 
 		           SECItem *    prime, 
 			   SECItem *    privateValue, 
 			   SECItem *    derivedSecret,
-			   unsigned int maxOutBytes);
+			   unsigned int outBytes);
 
 /* 
 ** KEA_CalcKey returns octet string with the private key for a dual
 ** Diffie-Helman  key generation as specified for government key exchange.
 */
 extern SECStatus KEA_Derive(SECItem *prime, 
                             SECItem *public1, 
                             SECItem *public2, 
--- a/security/nss/lib/freebl/blapit.h
+++ b/security/nss/lib/freebl/blapit.h
@@ -33,17 +33,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: blapit.h,v 1.25 2012/01/13 16:53:15 emaldona%redhat.com Exp $ */
+/* $Id: blapit.h,v 1.26 2012/03/28 22:35:14 rrelyea%redhat.com Exp $ */
 
 #ifndef _BLAPIT_H_
 #define _BLAPIT_H_
 
 #include "seccomon.h"
 #include "prlink.h"
 #include "plarena.h"
 #include "ecl-exp.h"
@@ -137,17 +137,17 @@
 /*
  * These values come from the initial key size limits from the PKCS #11
  * module. They may be arbitrarily adjusted to any value freebl supports.
  */
 #define RSA_MIN_MODULUS_BITS   128
 #define RSA_MAX_MODULUS_BITS  8192
 #define RSA_MAX_EXPONENT_BITS   64
 #define DH_MIN_P_BITS	       128
-#define DH_MAX_P_BITS         2236
+#define DH_MAX_P_BITS         3072
 
 /*
  * The FIPS 186 algorithm for generating primes P and Q allows only 9
  * distinct values for the length of P, and only one value for the
  * length of Q.
  * The algorithm uses a variable j to indicate which of the 9 lengths
  * of P is to be used.
  * The following table relates j to the lengths of P and Q in bits.
--- a/security/nss/lib/freebl/dh.c
+++ b/security/nss/lib/freebl/dh.c
@@ -33,17 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Diffie-Hellman parameter generation, key generation, and secret derivation.
  * KEA secret generation and verification.
  *
- * $Id: dh.c,v 1.9 2010/07/20 01:26:02 wtc%google.com Exp $
+ * $Id: dh.c,v 1.10 2012/03/28 22:35:14 rrelyea%redhat.com Exp $
  */
 #ifdef FREEBL_NO_DEPEND
 #include "stubs.h"
 #endif
 
 #include "prerr.h"
 #include "secerr.h"
 
@@ -210,17 +210,17 @@ cleanup:
     return rv;
 }
 
 SECStatus 
 DH_Derive(SECItem *publicValue, 
           SECItem *prime, 
           SECItem *privateValue, 
           SECItem *derivedSecret, 
-          unsigned int maxOutBytes)
+          unsigned int outBytes)
 {
     mp_int p, Xa, Yb, ZZ;
     mp_err err = MP_OKAY;
     int len = 0;
     unsigned int nb;
     unsigned char *secret = NULL;
     if (!publicValue || !prime || !privateValue || !derivedSecret) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -246,25 +246,34 @@ DH_Derive(SECItem *publicValue,
         err = MP_BADARG;
         goto cleanup;
     }
     /* allocate a buffer which can hold the entire derived secret. */
     secret = PORT_Alloc(len);
     /* grab the derived secret */
     err = mp_to_unsigned_octets(&ZZ, secret, len);
     if (err >= 0) err = MP_OKAY;
-    /* Take minimum of bytes requested and bytes in derived secret,
-    ** if maxOutBytes is 0 take all of the bytes from the derived secret.
+    /* 
+    ** if outBytes is 0 take all of the bytes from the derived secret.
+    ** if outBytes is not 0 take exactly outBytes from the derived secret, zero
+    ** pad at the beginning if necessary, and truncate beginning bytes 
+    ** if necessary.
     */
-    if (maxOutBytes > 0)
-	nb = PR_MIN(len, maxOutBytes);
+    if (outBytes > 0)
+	nb = outBytes;
     else
 	nb = len;
     SECITEM_AllocItem(NULL, derivedSecret, nb);
-    memcpy(derivedSecret->data, secret, nb);
+    if (len < nb) {
+	unsigned int offset = nb - len;
+	memset(derivedSecret->data, 0, offset);
+	memcpy(derivedSecret->data + offset, secret, len);
+    } else {
+	memcpy(derivedSecret->data, secret + len - nb, nb);
+    }
 cleanup:
     mp_clear(&p);
     mp_clear(&Xa);
     mp_clear(&Yb);
     mp_clear(&ZZ);
     if (secret) {
 	/* free the buffer allocated for the full secret. */
 	PORT_ZFree(secret, len);
--- a/security/nss/lib/libpkix/pkix/results/pkix_valresult.c
+++ b/security/nss/lib/libpkix/pkix/results/pkix_valresult.c
@@ -84,16 +84,18 @@ pkix_ValidateResult_Equals(
         PKIX_PL_Object *second,
         PKIX_Boolean *pResult,
         void *plContext)
 {
         PKIX_UInt32 secondType;
         PKIX_Boolean cmpResult;
         PKIX_ValidateResult *firstValResult = NULL;
         PKIX_ValidateResult *secondValResult = NULL;
+        PKIX_TrustAnchor *firstAnchor = NULL;
+        PKIX_TrustAnchor *secondAnchor = NULL;
         PKIX_PolicyNode *firstTree = NULL;
         PKIX_PolicyNode *secondTree = NULL;
 
         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Equals");
         PKIX_NULLCHECK_THREE(first, second, pResult);
 
         PKIX_CHECK(pkix_CheckType(first, PKIX_VALIDATERESULT_TYPE, plContext),
                 PKIX_FIRSTOBJECTNOTVALIDATERESULT);
@@ -112,47 +114,46 @@ pkix_ValidateResult_Equals(
                 ((PKIX_PL_Object *)firstValResult->pubKey,
                 (PKIX_PL_Object *)secondValResult->pubKey,
                 &cmpResult,
                 plContext),
                 PKIX_OBJECTEQUALSFAILED);
 
         if (!cmpResult) goto cleanup;
 
-        PKIX_CHECK(PKIX_PL_Object_Equals
-                ((PKIX_PL_Object *)firstValResult->anchor,
-                (PKIX_PL_Object *)secondValResult->anchor,
-                &cmpResult,
-                plContext),
-                PKIX_OBJECTEQUALSFAILED);
+        firstAnchor = firstValResult->anchor;
+        secondAnchor = secondValResult->anchor;
+
+        if ((firstAnchor != NULL) && (secondAnchor != NULL)) {
+                PKIX_CHECK(PKIX_PL_Object_Equals
+                        ((PKIX_PL_Object *)firstAnchor,
+                        (PKIX_PL_Object *)secondAnchor,
+                        &cmpResult,
+                        plContext),
+                        PKIX_OBJECTEQUALSFAILED);
+        } else {
+                cmpResult = (firstAnchor == secondAnchor);
+        }
 
         if (!cmpResult) goto cleanup;
 
         firstTree = firstValResult->policyTree;
         secondTree = secondValResult->policyTree;
 
         if ((firstTree != NULL) && (secondTree != NULL)) {
                 PKIX_CHECK(PKIX_PL_Object_Equals
                         ((PKIX_PL_Object *)firstTree,
                         (PKIX_PL_Object *)secondTree,
                         &cmpResult,
                         plContext),
                         PKIX_OBJECTEQUALSFAILED);
         } else {
-                if (PKIX_EXACTLY_ONE_NULL(firstTree, secondTree)) {
-                        cmpResult = PKIX_FALSE;
-                }
+                cmpResult = (firstTree == secondTree);
         }
 
-        /*
-         * The remaining case is that both are null,
-         * which we consider equality.
-         *      cmpResult = PKIX_TRUE;
-         */
-
         *pResult = cmpResult;
 
 cleanup:
 
         PKIX_RETURN(VALIDATERESULT);
 }
 
 /*
@@ -165,36 +166,38 @@ pkix_ValidateResult_Hashcode(
         PKIX_UInt32 *pHashcode,
         void *plContext)
 {
         PKIX_ValidateResult *valResult = NULL;
         PKIX_UInt32 hash = 0;
         PKIX_UInt32 pubKeyHash = 0;
         PKIX_UInt32 anchorHash = 0;
         PKIX_UInt32 policyTreeHash = 0;
-        PKIX_PolicyNode *policyTree = NULL;
 
         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Hashcode");
         PKIX_NULLCHECK_TWO(object, pHashcode);
 
         PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
                 PKIX_OBJECTNOTVALIDATERESULT);
 
         valResult = (PKIX_ValidateResult*)object;
 
         PKIX_CHECK(PKIX_PL_Object_Hashcode
                 ((PKIX_PL_Object *)valResult->pubKey, &pubKeyHash, plContext),
                 PKIX_OBJECTHASHCODEFAILED);
 
-        PKIX_CHECK(PKIX_PL_Object_Hashcode
-                ((PKIX_PL_Object *)valResult->anchor, &anchorHash, plContext),
-                PKIX_OBJECTHASHCODEFAILED);
+        if (valResult->anchor) {
+                PKIX_CHECK(PKIX_PL_Object_Hashcode
+                        ((PKIX_PL_Object *)valResult->anchor,
+                        &anchorHash,
+                        plContext),
+                        PKIX_OBJECTHASHCODEFAILED);
+        }
 
-        policyTree = valResult->policyTree;
-        if (policyTree) {
+        if (valResult->policyTree) {
                 PKIX_CHECK(PKIX_PL_Object_Hashcode
                         ((PKIX_PL_Object *)valResult->policyTree,
                         &policyTreeHash,
                         plContext),
                         PKIX_OBJECTHASHCODEFAILED);
         }
 
         hash = 31*(31 * pubKeyHash + anchorHash) + policyTreeHash;
@@ -236,37 +239,45 @@ pkix_ValidateResult_ToString(
                 "]\n";
 
         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_ToString");
         PKIX_NULLCHECK_TWO(object, pString);
 
         PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
                 PKIX_OBJECTNOTVALIDATERESULT);
 
+        PKIX_CHECK(PKIX_PL_String_Create
+                (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
+                PKIX_STRINGCREATEFAILED);
+
         valResult = (PKIX_ValidateResult*)object;
 
         anchor = valResult->anchor;
 
-        PKIX_CHECK(PKIX_PL_String_Create
-                (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
-                PKIX_STRINGCREATEFAILED);
-
-        PKIX_CHECK(PKIX_PL_Object_ToString
-                ((PKIX_PL_Object *)anchor, &anchorString, plContext),
-                PKIX_OBJECTTOSTRINGFAILED);
+        if (anchor) {
+                PKIX_CHECK(PKIX_PL_Object_ToString
+                        ((PKIX_PL_Object *)anchor, &anchorString, plContext),
+                        PKIX_OBJECTTOSTRINGFAILED);
+        } else {
+                PKIX_CHECK(PKIX_PL_String_Create
+                        (PKIX_ESCASCII,
+                        asciiNullString,
+                        0,
+                        &anchorString,
+                        plContext),
+                        PKIX_STRINGCREATEFAILED);
+        }
 
         pubKey = valResult->pubKey;
 
         PKIX_CHECK(PKIX_PL_Object_ToString
                 ((PKIX_PL_Object *)pubKey, &pubKeyString, plContext),
                 PKIX_OBJECTTOSTRINGFAILED);
 
-        PKIX_CHECK(PKIX_ValidateResult_GetPolicyTree
-                (valResult, &policyTree, plContext),
-                PKIX_VALIDATERESULTGETPOLICYTREEFAILED);
+        policyTree = valResult->policyTree;
 
         if (policyTree) {
                 PKIX_CHECK(PKIX_PL_Object_ToString
                         ((PKIX_PL_Object *)policyTree, &treeString, plContext),
                         PKIX_OBJECTTOSTRINGFAILED);
         } else {
                 PKIX_CHECK(PKIX_PL_String_Create
                         (PKIX_ESCASCII,
@@ -288,17 +299,16 @@ pkix_ValidateResult_ToString(
 
         *pString = valResultString;
 
 cleanup:
 
         PKIX_DECREF(formatString);
         PKIX_DECREF(anchorString);
         PKIX_DECREF(pubKeyString);
-        PKIX_DECREF(policyTree);
         PKIX_DECREF(treeString);
 
         PKIX_RETURN(VALIDATERESULT);
 }
 
 /*
  * FUNCTION: pkix_ValidateResult_RegisterSelf
  * DESCRIPTION:
@@ -342,17 +352,17 @@ pkix_ValidateResult_RegisterSelf(void *p
  *  Creates a new ValidateResult Object using the PublicKey pointed to by
  *  "pubKey", the TrustAnchor pointed to by "anchor", and the PolicyNode
  *  pointed to by "policyTree", and stores it at "pResult".
  *
  * PARAMETERS
  *  "pubKey"
  *      PublicKey of the desired ValidateResult. Must be non-NULL.
  *  "anchor"
- *      TrustAnchor of the desired Validateresult. Must be non-NULL.
+ *      TrustAnchor of the desired Validateresult. May be NULL.
  *  "policyTree"
  *      PolicyNode of the desired ValidateResult; may be NULL
  *  "pResult"
  *      Address where object pointer will be stored. Must be non-NULL.
  *  "plContext"
  *      Platform-specific context pointer.
  * THREAD SAFETY:
  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -366,17 +376,17 @@ pkix_ValidateResult_Create(
         PKIX_TrustAnchor *anchor,
         PKIX_PolicyNode *policyTree,
         PKIX_ValidateResult **pResult,
         void *plContext)
 {
         PKIX_ValidateResult *result = NULL;
 
         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Create");
-        PKIX_NULLCHECK_THREE(pubKey, anchor, pResult);
+        PKIX_NULLCHECK_TWO(pubKey, pResult);
 
         PKIX_CHECK(PKIX_PL_Object_Alloc
                     (PKIX_VALIDATERESULT_TYPE,
                     sizeof (PKIX_ValidateResult),
                     (PKIX_PL_Object **)&result,
                     plContext),
                     PKIX_COULDNOTCREATEVALIDATERESULTOBJECT);
 
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c
@@ -170,17 +170,17 @@ cleanup:
  *  "prevCert"
  *      Address of Cert just traversed. Must be non-NULL.
  *  "traversedSubjNames"
  *      Address of List of GeneralNames that have been traversed.
  *      Must be non-NULL.
  *  "trustChain"
  *      Address of List of certificates traversed. Must be non-NULL.
  *  "parentState"
- *      Address of previous ForwardBuilder state
+ *      Address of previous ForwardBuilderState
  *  "pState"
  *      Address where ForwardBuilderState will be stored. Must be non-NULL.
  *  "plContext"
  *      Platform-specific context pointer.
  * THREAD SAFETY:
  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  * RETURNS:
  *  Returns NULL if the function succeeds.
@@ -3151,17 +3151,17 @@ fatal:
 }
 
 /*
  * FUNCTION: pkix_Build_InitiateBuildChain
  * DESCRIPTION:
  *
  *  This function initiates the search for a BuildChain, using the parameters
  *  provided in "procParams" and, if continuing a search that was suspended
- *  for I/O, using the ForwardBuilderState pointed to by "state".
+ *  for I/O, using the ForwardBuilderState pointed to by "pState".
  *
  *  If a successful chain is built, this function stores the BuildResult at
  *  "pBuildResult". Alternatively, if an operation using non-blocking I/O
  *  is in progress and the operation has not been completed, this function
  *  stores the platform-dependent non-blocking I/O context (nbioContext) at
  *  "pNBIOContext", the FowardBuilderState at "pState", and NULL at
  *  "pBuildResult". Finally, if chain building was unsuccessful, this function
  *  stores NULL at both "pState" and at "pBuildResult".
@@ -3226,17 +3226,16 @@ pkix_Build_InitiateBuildChain(
         PKIX_PL_PublicKey *targetPubKey = NULL;
         void *nbioContext = NULL;
         BuildConstants buildConstants;
 
         PKIX_List *tentativeChain = NULL;
         PKIX_ValidateResult *valResult = NULL;
         PKIX_BuildResult *buildResult = NULL;
         PKIX_List *certList = NULL;
-        PKIX_TrustAnchor *matchingAnchor = NULL;
         PKIX_ForwardBuilderState *state = NULL;
         PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
         PKIX_CertSelector_MatchCallback selectorCallback = NULL;
         PKIX_Boolean trusted = PKIX_FALSE;
         PKIX_PL_AIAMgr *aiaMgr = NULL;
 
         PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain");
         PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult);
@@ -3341,19 +3340,16 @@ pkix_Build_InitiateBuildChain(
                 PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
             }
 
             PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted
                     (targetCert,
                     &trusted, 
                     plContext),
                     PKIX_CERTISCERTTRUSTEDFAILED);
-            /* future: look at the |trusted| flag and force success. We only
-             * want to do this if we aren't validating against a policy (like
-             * EV). */
 
             PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
                     (targetCert,
                     &targetSubjNames,
                     plContext),
                     PKIX_CERTGETALLSUBJECTNAMESFAILED);
     
             PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
@@ -3401,16 +3397,46 @@ pkix_Build_InitiateBuildChain(
                                 pkixErrorClass = PKIX_FATAL_ERROR;
                                 goto cleanup;
                             }
                     }
                     pkixErrorCode = PKIX_CERTCHECKVALIDITYFAILED;
                     goto cleanup;
                 }
             }
+
+            /* If the EE cert is trusted, force success. We only want to do
+             * this if we aren't validating against a policy (like EV). */
+            if (trusted && procParams->initialPolicies == NULL) {
+                if (pVerifyNode != NULL) {
+                    PKIX_Error *tempResult =
+                        pkix_VerifyNode_Create(targetCert, 0, NULL,
+                                               pVerifyNode,
+                                               plContext);
+                    if (tempResult) {
+                        pkixErrorResult = tempResult;
+                        pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
+                        pkixErrorClass = PKIX_FATAL_ERROR;
+                        goto cleanup;
+                    }
+                }
+                PKIX_CHECK(pkix_ValidateResult_Create
+                        (targetPubKey, NULL /* anchor */,
+                         NULL /* policyTree */, &valResult, plContext),
+                        PKIX_VALIDATERESULTCREATEFAILED);
+                PKIX_CHECK(
+                    pkix_BuildResult_Create(valResult, tentativeChain,
+                                            &buildResult, plContext),
+                    PKIX_BUILDRESULTCREATEFAILED);
+                *pBuildResult = buildResult;
+                /* Note that *pState is NULL.   The only side effect is that
+                 * the cert chain won't be cached in PKIX_BuildChain, which
+                 * is fine. */
+                goto cleanup;
+            }
     
             PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
                     (procParams, &certStores, plContext),
                     PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
     
             PKIX_CHECK(PKIX_List_GetLength
                     (certStores, &numCertStores, plContext),
                     PKIX_LISTGETLENGTHFAILED);
@@ -3574,21 +3600,19 @@ pkix_Build_InitiateBuildChain(
                     (state->buildConstants.targetCert,
                     &targetSubjNames,
                     plContext),
                     PKIX_CERTGETALLSUBJECTNAMESFAILED);
         }
 
         state->status = BUILD_INITIAL;
 
-        if (!matchingAnchor) {
-                pkixErrorResult =
-                    pkix_BuildForwardDepthFirstSearch(&nbioContext, state,
-                                                      &valResult, plContext);
-        }
+        pkixErrorResult =
+            pkix_BuildForwardDepthFirstSearch(&nbioContext, state,
+                                              &valResult, plContext);
 
         /* non-null nbioContext means the build would block */
         if (pkixErrorResult == NULL && nbioContext != NULL) {
 
                 *pNBIOContext = nbioContext;
                 *pBuildResult = NULL;
 
         /* no valResult means the build has failed */
@@ -3623,17 +3647,16 @@ cleanup:
         PKIX_DECREF(userCheckers);
         PKIX_DECREF(hintCerts);
         PKIX_DECREF(firstHintCert);
         PKIX_DECREF(testDate);
         PKIX_DECREF(targetPubKey);
         PKIX_DECREF(tentativeChain);
         PKIX_DECREF(valResult);
         PKIX_DECREF(certList);
-        PKIX_DECREF(matchingAnchor);
         PKIX_DECREF(trustedCert);
         PKIX_DECREF(state);
         PKIX_DECREF(aiaMgr);
 
         PKIX_RETURN(BUILD);
 }
 
 /*
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
@@ -1664,23 +1664,23 @@ cleanup:
  */
 PKIX_Error *
 PKIX_PL_Cert_GetVersion(
         PKIX_PL_Cert *cert,
         PKIX_UInt32 *pVersion,
         void *plContext)
 {
         CERTCertificate *nssCert = NULL;
-        PKIX_UInt32 myVersion = 1;
+        PKIX_UInt32 myVersion = 0;  /* v1 */
 
         PKIX_ENTER(CERT, "PKIX_PL_Cert_GetVersion");
         PKIX_NULLCHECK_THREE(cert, cert->nssCert, pVersion);
 
         nssCert = cert->nssCert;
-        if (nssCert->version.data) {
+        if (nssCert->version.len != 0) {
                 myVersion = *(nssCert->version.data);
         }
 
         if (myVersion > 2){
                 PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3);
         }
 
         *pVersion = myVersion;
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
@@ -46,17 +46,20 @@
 
 #include "pkix_pl_common.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct PKIX_PL_CertStruct {
-        CERTCertificate *nssCert;
+        CERTCertificate *nssCert;  /* Must be the first field.  The
+                                    * cert_NSSCertFromPKIXCert function in
+                                    * lib/certhigh/certvfypkix.c depends on
+                                    * this. */
         CERTGeneralName *nssSubjAltNames;
         PLArenaPool *arenaNameConstraints;
         PKIX_PL_X500Name *issuer;
         PKIX_PL_X500Name *subject;
         PKIX_List *subjAltNames;
         PKIX_Boolean subjAltNamesAbsent;
         PKIX_PL_OID *publicKeyAlgId;
         PKIX_PL_PublicKey *publicKey;
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: nss.h,v 1.91 2012/02/18 23:22:43 kaie%kuix.de Exp $ */
+/* $Id: nss.h,v 1.92 2012/02/22 10:00:08 kaie%kuix.de Exp $ */
 
 #ifndef __nss_h_
 #define __nss_h_
 
 /* The private macro _NSS_ECC_STRING is for NSS internal use only. */
 #ifdef NSS_ENABLE_ECC
 #ifdef NSS_ECC_MORE_THAN_SUITE_B
 #define _NSS_ECC_STRING " Extended ECC"
@@ -61,22 +61,22 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.13.3.0" _NSS_ECC_STRING _NSS_CUSTOMIZED
+#define NSS_VERSION  "3.13.4.0" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   13
-#define NSS_VPATCH   3
+#define NSS_VPATCH   4
 #define NSS_VBUILD   0
-#define NSS_BETA     PR_FALSE
+#define NSS_BETA     PR_TRUE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
 
 /*
--- a/security/nss/lib/pk11wrap/pk11auth.c
+++ b/security/nss/lib/pk11wrap/pk11auth.c
@@ -160,17 +160,17 @@ PK11_CheckUserPassword(PK11SlotInfo *slo
     } else if (pw == NULL) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     } else {
 	len = PORT_Strlen(pw);
     }
 
     /*
-     * If the token does't need a login, don't try to relogin beause the
+     * If the token doesn't need a login, don't try to relogin because the
      * effect is undefined. It's not clear what it means to check a non-empty
      * password with such a token, so treat that as an error.
      */
     if (!slot->needLogin) {
         if (len == 0) {
             rv = SECSuccess;
         } else {
             PORT_SetError(SEC_ERROR_BAD_PASSWORD);
--- a/security/nss/lib/pk11wrap/pk11merge.c
+++ b/security/nss/lib/pk11wrap/pk11merge.c
@@ -1104,17 +1104,17 @@ pk11_mergeTrust(PK11SlotInfo *targetSlot
 	    CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH,
 	    CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION, 
 	    CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, 
 	    CKA_TRUST_TIME_STAMPING
 	};
 	CK_ULONG trustAttrsCount = 
 		sizeof(trustAttrs)/sizeof(trustAttrs[0]);
 
-	int i;
+	CK_ULONG i;
 	CK_ATTRIBUTE targetTemplate, sourceTemplate;
 
 	/* existing trust record, merge the two together */
         for (i=0; i < trustAttrsCount; i++) {
 	    targetTemplate.type = sourceTemplate.type = trustAttrs[i];
 	    targetTemplate.pValue = sourceTemplate.pValue = NULL;
 	    targetTemplate.ulValueLen = sourceTemplate.ulValueLen = 0;
 	    PK11_GetAttributes(arena, sourceSlot, id, &sourceTemplate, 1);
--- a/security/nss/lib/pk11wrap/pk11sdr.c
+++ b/security/nss/lib/pk11wrap/pk11sdr.c
@@ -106,17 +106,17 @@ padBlock(SECItem *data, int blockSize, S
   return rv;
 }
 
 static SECStatus
 unpadBlock(SECItem *data, int blockSize, SECItem *result)
 {
   SECStatus rv = SECSuccess;
   int padLength;
-  int i;
+  unsigned int i;
 
   result->data = 0;
   result->len = 0;
 
   /* Remove the padding from the end if the input data */
   if (data->len == 0 || data->len % blockSize  != 0) { rv = SECFailure; goto loser; }
 
   padLength = data->data[data->len-1];
--- a/security/nss/lib/pkcs12/p12e.c
+++ b/security/nss/lib/pkcs12/p12e.c
@@ -45,16 +45,18 @@
 #include "secpkcs7.h"
 #include "secasn1.h"
 #include "secerr.h"
 #include "pk11func.h"
 #include "p12plcy.h"
 #include "p12local.h"
 #include "prcpucfg.h"
 
+extern const int NSS_PBE_DEFAULT_ITERATION_COUNT; /* defined in p7create.c */
+
 /*
 ** This PKCS12 file encoder uses numerous nested ASN.1 and PKCS7 encoder
 ** contexts.  It can be difficult to keep straight.  Here's a picture:
 **
 **  "outer"  ASN.1 encoder.  The output goes to the library caller's CB.
 **  "middle" PKCS7 encoder.  Feeds    the "outer" ASN.1 encoder.
 **  "middle" ASN1  encoder.  Encodes  the encrypted aSafes. 
 **                           Feeds    the "middle" P7 encoder above.
@@ -1251,18 +1253,19 @@ SEC_PKCS12AddKeyForCert(SEC_PKCS12Export
 	/* we want to make sure to take the key out of the key slot */
 	if(PK11_IsInternal(p12ctxt->slot)) {
 	    slot = PK11_GetInternalKeySlot();
 	} else {
 	    slot = PK11_ReferenceSlot(p12ctxt->slot);
 	}
 
 	epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm, 
-						  &uniPwitem, cert, 1, 
-						  p12ctxt->wincx);
+					    &uniPwitem, cert,
+					    NSS_PBE_DEFAULT_ITERATION_COUNT,
+					    p12ctxt->wincx);
 	PK11_FreeSlot(slot);
 	if(!epki) {
 	    PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
 	    goto loser;
 	}   
 	
 	keyItem = PORT_ArenaZAlloc(p12ctxt->arena, 
 				  sizeof(SECKEYEncryptedPrivateKeyInfo));
@@ -1600,30 +1603,36 @@ sec_pkcs12_encoder_start_context(SEC_PKC
 		goto loser;
 	    }
 	    if(SECITEM_CopyItem(p12exp->arena, &(p12enc->mac.macSalt), salt) 
 			!= SECSuccess) {
 		/* XXX salt is leaked */
 		PORT_SetError(SEC_ERROR_NO_MEMORY);
 		goto loser;
 	    }   
+	    if (!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->mac.iter),
+				       NSS_PBE_DEFAULT_ITERATION_COUNT)) {
+		/* XXX salt is leaked */
+		goto loser;
+	    }
 
 	    /* generate HMAC key */
 	    if(!sec_pkcs12_convert_item_to_unicode(NULL, &pwd, 
 			p12exp->integrityInfo.pwdInfo.password, PR_TRUE, 
 			PR_TRUE, PR_TRUE)) {
 		/* XXX salt is leaked */
 		goto loser;
 	    }
 	    /*
 	     * This code only works with PKCS #12 Mac using PKCS #5 v1
 	     * PBA keygens. PKCS #5 v2 support will require a change to
 	     * the PKCS #12 spec.
 	     */
-	    params = PK11_CreatePBEParams(salt, &pwd, 1);
+	    params = PK11_CreatePBEParams(salt, &pwd,
+                                          NSS_PBE_DEFAULT_ITERATION_COUNT);
 	    SECITEM_ZfreeItem(salt, PR_TRUE);
 	    SECITEM_ZfreeItem(&pwd, PR_FALSE);
 
 	    /* get the PBA Mechanism to generate the key */
 	    switch (p12exp->integrityInfo.pwdInfo.algorithm) {
 	    case SEC_OID_SHA1:
 		integrityMechType = CKM_PBA_SHA1_WITH_SHA1_HMAC; break;
 	    case SEC_OID_MD5:
--- a/security/nss/lib/pkcs7/p7create.c
+++ b/security/nss/lib/pkcs7/p7create.c
@@ -32,31 +32,33 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * PKCS7 creation.
  *
- * $Id: p7create.c,v 1.9 2008/02/03 06:08:48 nelson%bolyard.com Exp $
+ * $Id: p7create.c,v 1.10 2012/03/19 22:16:34 kaie%kuix.de Exp $
  */
 
 #include "p7local.h"
 
 #include "cert.h"
 #include "secasn1.h"
 #include "secitem.h"
 #include "secoid.h"
 #include "pk11func.h"
 #include "prtime.h"
 #include "secerr.h"
 #include "secder.h"
 #include "secpkcs5.h"
 
+const int NSS_PBE_DEFAULT_ITERATION_COUNT = 2000; /* used in p12e.c too */
+
 static SECStatus
 sec_pkcs7_init_content_info (SEC_PKCS7ContentInfo *cinfo, PRArenaPool *poolp,
 			     SECOidTag kind, PRBool detached)
 {
     void *thing;
     int version;
     SECItem *versionp;
     SECStatus rv;
@@ -1288,17 +1290,19 @@ SEC_PKCS7CreateEncryptedData (SECOidTag 
         /* Assume password-based-encryption.  
          * Note: we can't generate pkcs5v2 from this interface.
          * PK11_CreateBPEAlgorithmID generates pkcs5v2 by accepting
          * non-PBE oids and assuming that they are pkcs5v2 oids, but
          * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular
          * CMS encrypted data, so we can't tell SEC_PKCS7CreateEncryptedtedData
          * to create pkcs5v2 PBEs */
 	SECAlgorithmID *pbe_algid;
-	pbe_algid = PK11_CreatePBEAlgorithmID (algorithm, 1, NULL);
+	pbe_algid = PK11_CreatePBEAlgorithmID(algorithm,
+                                              NSS_PBE_DEFAULT_ITERATION_COUNT,
+                                              NULL);
 	if (pbe_algid == NULL) {
 	    rv = SECFailure;
 	} else {
 	    rv = SECOID_CopyAlgorithmID (cinfo->poolp, algid, pbe_algid);
 	    SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE);
 	}
     }
 
--- a/security/nss/lib/smime/smimeutil.c
+++ b/security/nss/lib/smime/smimeutil.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Stuff specific to S/MIME policy and interoperability.
  *
- * $Id: smimeutil.c,v 1.22 2011/08/21 01:14:18 wtc%google.com Exp $
+ * $Id: smimeutil.c,v 1.23 2012/03/01 18:33:11 kaie%kuix.de Exp $
  */
 
 #include "secmime.h"
 #include "secoid.h"
 #include "pk11func.h"
 #include "ciferfam.h"	/* for CIPHER_FAMILY symbols */
 #include "secasn1.h"
 #include "secitem.h"
@@ -147,17 +147,18 @@ typedef struct {
 static smime_cipher_map_entry smime_cipher_map[] = {
 /*    cipher			algtag			parms		enabled  allowed */
 /*    ---------------------------------------------------------------------------------- */
     { SMIME_RC2_CBC_40,		SEC_OID_RC2_CBC,	&param_int40,	PR_TRUE, PR_TRUE },
     { SMIME_DES_CBC_56,		SEC_OID_DES_CBC,	NULL,		PR_TRUE, PR_TRUE },
     { SMIME_RC2_CBC_64,		SEC_OID_RC2_CBC,	&param_int64,	PR_TRUE, PR_TRUE },
     { SMIME_RC2_CBC_128,	SEC_OID_RC2_CBC,	&param_int128,	PR_TRUE, PR_TRUE },
     { SMIME_DES_EDE3_168,	SEC_OID_DES_EDE3_CBC,	NULL,		PR_TRUE, PR_TRUE },
-    { SMIME_AES_CBC_128,	SEC_OID_AES_128_CBC,	NULL,		PR_TRUE, PR_TRUE }
+    { SMIME_AES_CBC_128,	SEC_OID_AES_128_CBC,	NULL,		PR_TRUE, PR_TRUE },
+    { SMIME_AES_CBC_256,	SEC_OID_AES_256_CBC,	NULL,		PR_TRUE, PR_TRUE }
 };
 static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);
 
 /*
  * smime_mapi_by_cipher - find index into smime_cipher_map by cipher
  */
 static int
 smime_mapi_by_cipher(unsigned long cipher)
@@ -267,16 +268,19 @@ nss_smime_get_cipher_for_alg_and_key(SEC
 	c = SMIME_DES_CBC_56;
 	break;
     case SEC_OID_DES_EDE3_CBC:
 	c = SMIME_DES_EDE3_168;
 	break;
     case SEC_OID_AES_128_CBC:
 	c = SMIME_AES_CBC_128;
 	break;
+    case SEC_OID_AES_256_CBC:
+	c = SMIME_AES_CBC_256;
+	break;
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
 	return SECFailure;
     }
     *cipher = c;
     return SECSuccess;
 }
 
@@ -521,16 +525,19 @@ smime_keysize_by_cipher (unsigned long w
 	break;
       case SMIME_RC2_CBC_64:
 	keysize = 64;
 	break;
       case SMIME_RC2_CBC_128:
       case SMIME_AES_CBC_128:
 	keysize = 128;
 	break;
+      case SMIME_AES_CBC_256:
+	keysize = 256;
+	break;
       case SMIME_DES_CBC_56:
       case SMIME_DES_EDE3_168:
 	/*
 	 * These are special; since the key size is fixed, we actually
 	 * want to *avoid* specifying a key size.
 	 */
 	keysize = 0;
 	break;
--- a/security/nss/lib/softoken/legacydb/lgcreate.c
+++ b/security/nss/lib/softoken/legacydb/lgcreate.c
@@ -811,21 +811,26 @@ static NSSLOWKEYPrivateKey *lg_mkSecretK
      *   private exponent - CKA_VALUE (the key itself)
      *   coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
      *      is used for the key.
      *   all others - set to integer 0
      */
     privKey->keyType = NSSLOWKEYRSAKey;
 
     /* The modulus is set to the key id of the symmetric key */
-    crv = lg_Attribute2SecItem(arena, CKA_ID, templ, count, 
-				&privKey->u.rsa.modulus);
-    if (crv != CKR_OK) goto loser;
+    privKey->u.rsa.modulus.data =
+		(unsigned char *) PORT_ArenaAlloc(arena, pubkey->len);
+    if (privKey->u.rsa.modulus.data == NULL) {
+	crv = CKR_HOST_MEMORY;
+	goto loser;
+    }
+    privKey->u.rsa.modulus.len = pubkey->len;
+    PORT_Memcpy(privKey->u.rsa.modulus.data, pubkey->data, pubkey->len);
 
-    /* The public exponent is set to 0 length to indicate a special key */
+    /* The public exponent is set to 0 to indicate a special key */
     privKey->u.rsa.publicExponent.len = sizeof derZero;
     privKey->u.rsa.publicExponent.data = derZero;
 
     /* The private exponent is the actual key value */
     crv = lg_PrivAttr2SecItem(arena, CKA_VALUE, templ, count,
 				&privKey->u.rsa.privateExponent, sdbpw);
     if (crv != CKR_OK) goto loser;
 
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -52,16 +52,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.13.3.0" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.13.4.0" SOFTOKEN_ECC_STRING " Beta"
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   13
-#define SOFTOKEN_VPATCH   3
+#define SOFTOKEN_VPATCH   4
 #define SOFTOKEN_VBUILD   0
-#define SOFTOKEN_BETA     PR_FALSE
+#define SOFTOKEN_BETA     PR_TRUE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -1,8 +1,9 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * SSL3 Protocol
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
@@ -34,17 +35,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: ssl3con.c,v 1.164 2012/02/17 09:50:04 kaie%kuix.de Exp $ */
+/* $Id: ssl3con.c,v 1.167 2012/03/06 02:23:25 wtc%google.com Exp $ */
 
 #include "cert.h"
 #include "ssl.h"
 #include "cryptohi.h"	/* for DSAU_ stuff */
 #include "keyhi.h"
 #include "secder.h"
 #include "secitem.h"
 
@@ -136,18 +137,18 @@ static ssl3CipherSuiteCfg cipherSuites[s
 #ifdef NSS_ENABLE_ECC
  { TLS_ECDH_RSA_WITH_RC4_128_SHA,          SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { TLS_ECDH_ECDSA_WITH_RC4_128_SHA,        SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,    SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
 #endif /* NSS_ENABLE_ECC */
  { TLS_RSA_WITH_SEED_CBC_SHA,              SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, 
  { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,  	   SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { SSL_RSA_WITH_RC4_128_SHA,               SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { SSL_RSA_WITH_RC4_128_MD5,               SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_WITH_RC4_128_SHA,               SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { TLS_RSA_WITH_AES_128_CBC_SHA,     	   SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
 
 #ifdef NSS_ENABLE_ECC
  { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,  SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,    SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
 #endif /* NSS_ENABLE_ECC */
  { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
  { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -1427,17 +1428,17 @@ ssl3_InitCompressionContext(ssl3CipherSp
 /* Initialize encryption and MAC contexts for pending spec.
  * Master Secret already is derived in spec->msItem
  * Caller holds Spec write lock.
  */
 static SECStatus
 ssl3_InitPendingContextsBypass(sslSocket *ss)
 {
       ssl3CipherSpec  *  pwSpec;
-const ssl3BulkCipherDef *cipher_def;
+      const ssl3BulkCipherDef *cipher_def;
       void *             serverContext = NULL;
       void *             clientContext = NULL;
       BLapiInitContextFunc initFn = (BLapiInitContextFunc)NULL;
       int                mode     = 0;
       unsigned int       optArg1  = 0;
       unsigned int       optArg2  = 0;
       PRBool             server_encrypts = ss->sec.isServer;
       CK_ULONG           macLength;
@@ -1616,17 +1617,17 @@ ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype
 /* Initialize encryption and MAC contexts for pending spec.
  * Master Secret already is derived.
  * Caller holds Spec write lock.
  */
 static SECStatus
 ssl3_InitPendingContextsPKCS11(sslSocket *ss)
 {
       ssl3CipherSpec  *  pwSpec;
-const ssl3BulkCipherDef *cipher_def;
+      const ssl3BulkCipherDef *cipher_def;
       PK11Context *      serverContext = NULL;
       PK11Context *      clientContext = NULL;
       SECItem *          param;
       CK_MECHANISM_TYPE  mechanism;
       CK_MECHANISM_TYPE  mac_mech;
       CK_ULONG           macLength;
       CK_ULONG           effKeyBits;
       SECItem            iv;
@@ -7044,17 +7045,17 @@ ssl3_SendServerHello(sslSocket *ss)
 
     return SECSuccess;
 }
 
 
 static SECStatus
 ssl3_SendServerKeyExchange(sslSocket *ss)
 {
-const ssl3KEADef *     kea_def     = ss->ssl3.hs.kea_def;
+    const ssl3KEADef * kea_def     = ss->ssl3.hs.kea_def;
     SECStatus          rv          = SECFailure;
     int                length;
     PRBool             isTLS;
     SECItem            signed_hash = {siBuffer, NULL, 0};
     SSL3Hashes         hashes;
     SECKEYPublicKey *  sdPub;	/* public key for step-down */
 
     SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
@@ -7143,17 +7144,17 @@ loser:
 }
 
 
 static SECStatus
 ssl3_SendCertificateRequest(sslSocket *ss)
 {
     SECItem *      name;
     CERTDistNames *ca_list;
-const uint8 *      certTypes;
+    const uint8 *  certTypes;
     SECItem *      names	= NULL;
     SECStatus      rv;
     int            length;
     int            i;
     int            calen	= 0;
     int            nnames	= 0;
     int            certTypesLength;
 
@@ -7487,17 +7488,17 @@ double_bypass:
  * ssl3 ClientKeyExchange message from the remote client
  * Caller must hold Handshake and RecvBuf locks.
  */
 static SECStatus
 ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
 {
     SECKEYPrivateKey *serverKey         = NULL;
     SECStatus         rv;
-const ssl3KEADef *    kea_def;
+    const ssl3KEADef *kea_def;
     ssl3KeyPair     *serverKeyPair      = NULL;
 #ifdef NSS_ENABLE_ECC
     SECKEYPublicKey *serverPubKey       = NULL;
 #endif /* NSS_ENABLE_ECC */
 
     SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
 		SSL_GETPID(), ss->fd));
 
@@ -8607,29 +8608,27 @@ xmit_loser:
 
     rv = ssl3_FinishHandshake(ss);
     return rv;
 }
 
 SECStatus
 ssl3_FinishHandshake(sslSocket * ss)
 {
-    SECStatus rv;
-
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
     PORT_Assert( ss->ssl3.hs.restartTarget == NULL );
 
     /* The first handshake is now completed. */
     ss->handshake           = NULL;
     ss->firstHsDone         = PR_TRUE;
 
-    if (ss->sec.ci.sid->cached == never_cached &&
-	!ss->opt.noCache && ss->sec.cache && ss->ssl3.hs.cacheSID) {
+    if (ss->ssl3.hs.cacheSID) {
 	(*ss->sec.cache)(ss->sec.ci.sid);
+	ss->ssl3.hs.cacheSID = PR_FALSE;
     }
 
     ss->ssl3.hs.ws = idle_handshake;
 
     /* Do the handshake callback for sslv3 here, if we cannot false start. */
     if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
 	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
     }
@@ -8940,17 +8939,17 @@ ssl3_HandleHandshake(sslSocket *ss, sslB
  *
  * This function aquires and releases the SSL3Handshake Lock, holding the
  * lock around any calls to functions that handle records other than
  * Application Data records.
  */
 SECStatus
 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
 {
-const ssl3BulkCipherDef *cipher_def;
+    const ssl3BulkCipherDef *cipher_def;
     ssl3CipherSpec *     crSpec;
     SECStatus            rv;
     unsigned int         hashBytes		= MAX_MAC_LENGTH + 1;
     unsigned int         padding_length;
     PRBool               isTLS;
     PRBool               padIsBad               = PR_FALSE;
     SSL3ContentType      rType;
     SSL3Opaque           hash[MAX_MAC_LENGTH];
--- a/security/nss/lib/ssl/ssl3ext.c
+++ b/security/nss/lib/ssl/ssl3ext.c
@@ -36,17 +36,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* TLS extension code moved here from ssl3ecc.c */
-/* $Id: ssl3ext.c,v 1.21 2012/02/15 21:52:08 kaie%kuix.de Exp $ */
+/* $Id: ssl3ext.c,v 1.22 2012/03/12 19:14:12 wtc%google.com Exp $ */
 
 #include "nssrenam.h"
 #include "nss.h"
 #include "ssl.h"
 #include "sslproto.h"
 #include "sslimpl.h"
 #include "pk11pub.h"
 #include "blapi.h"
@@ -587,42 +587,41 @@ ssl3_ValidateNextProtoNego(const unsigne
 static SECStatus
 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
 				  SECItem *data)
 {
     SECStatus rv;
     unsigned char resultBuffer[255];
     SECItem result = { siBuffer, resultBuffer, 0 };
 
-    if (ss->firstHsDone) {
-	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
-	return SECFailure;
-    }
+    PORT_Assert(!ss->firstHsDone);
 
     rv = ssl3_ValidateNextProtoNego(data->data, data->len);
     if (rv != SECSuccess)
 	return rv;
 
     /* ss->nextProtoCallback cannot normally be NULL if we negotiated the
      * extension. However, It is possible that an application erroneously
      * cleared the callback between the time we sent the ClientHello and now.
      */
     PORT_Assert(ss->nextProtoCallback != NULL);
     if (!ss->nextProtoCallback) {
+	/* XXX Use a better error code. This is an application error, not an
+	 * NSS bug. */
 	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 	return SECFailure;
     }
 
     rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
 			       result.data, &result.len, sizeof resultBuffer);
     if (rv != SECSuccess)
 	return rv;
     /* If the callback wrote more than allowed to |result| it has corrupted our
      * stack. */
-    if (result.len > sizeof result) {
+    if (result.len > sizeof resultBuffer) {
 	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
 	return SECFailure;
     }
 
     SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
     return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
 }
 
--- a/security/nss/lib/ssl/sslcon.c
+++ b/security/nss/lib/ssl/sslcon.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslcon.c,v 1.45 2011/11/19 21:58:21 bsmith%mozilla.com Exp $ */
+/* $Id: sslcon.c,v 1.46 2012/03/01 01:58:22 wtc%google.com Exp $ */
 
 #include "nssrenam.h"
 #include "cert.h"
 #include "secitem.h"
 #include "sechash.h"
 #include "cryptohi.h"		/* for SGN_ funcs */
 #include "keyhi.h" 		/* for SECKEY_ high level functions. */
 #include "ssl.h"
@@ -1430,17 +1430,17 @@ ssl2_CreateSessionCypher(sslSocket *ss, 
     SECItem           writeKey;
 
     void *readcx = 0;
     void *writecx = 0;
     readKey.data = 0;
     writeKey.data = 0;
 
     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-    if((ss->sec.ci.sid == 0))
+    if (ss->sec.ci.sid == 0)
     	goto sec_loser;	/* don't crash if asserts are off */
 
     /* Trying to cut down on all these switch statements that should be tables.
      * So, test cipherType once, here, and then use tables below. 
      */
     switch (cipherType) {
     case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
     case SSL_CK_RC4_128_WITH_MD5:
--- a/security/nss/lib/ssl/sslenum.c
+++ b/security/nss/lib/ssl/sslenum.c
@@ -34,32 +34,35 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslenum.c,v 1.17 2010/02/10 18:07:21 wtc%google.com Exp $ */
+/* $Id: sslenum.c,v 1.18 2012/03/06 00:26:31 wtc%google.com Exp $ */
 
 #include "ssl.h"
 #include "sslproto.h"
 
 /*
  * The ciphers are listed in the following order:
  * - stronger ciphers before weaker ciphers
  * - national ciphers before international ciphers
  * - faster ciphers before slower ciphers
  *
  * National ciphers such as Camellia are listed before international ciphers
  * such as AES and RC4 to allow servers that prefer Camellia to negotiate
  * Camellia without having to disable AES and RC4, which are needed for
  * interoperability with clients that don't yet implement Camellia.
  *
+ * The ordering of cipher suites in this table must match the ordering in
+ * the cipherSuites table in ssl3con.c.
+ *
  * If new ECC cipher suites are added, also update the ssl3CipherSuite arrays
  * in ssl3ecc.c.
  */
 const PRUint16 SSL_ImplementedCiphers[] = {
     /* 256-bit */
 #ifdef NSS_ENABLE_ECC
     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
@@ -90,18 +93,18 @@ const PRUint16 SSL_ImplementedCiphers[] 
 #ifdef NSS_ENABLE_ECC
     TLS_ECDH_RSA_WITH_RC4_128_SHA,
     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
 #endif /* NSS_ENABLE_ECC */
     TLS_RSA_WITH_SEED_CBC_SHA,
     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+    SSL_RSA_WITH_RC4_128_SHA,
     SSL_RSA_WITH_RC4_128_MD5,
-    SSL_RSA_WITH_RC4_128_SHA,
     TLS_RSA_WITH_AES_128_CBC_SHA,
 
     /* 112-bit 3DES */
 #ifdef NSS_ENABLE_ECC
     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
 #endif /* NSS_ENABLE_ECC */
     SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
--- a/security/nss/lib/ssl/sslinfo.c
+++ b/security/nss/lib/ssl/sslinfo.c
@@ -29,17 +29,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslinfo.c,v 1.24 2010/09/02 01:12:57 wtc%google.com Exp $ */
+/* $Id: sslinfo.c,v 1.25 2012/03/06 00:26:31 wtc%google.com Exp $ */
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
 
 static const char *
 ssl_GetCompressionMethodName(SSLCompressionMethod compression)
 {
     switch (compression) {
@@ -175,18 +175,18 @@ static const SSLCipherSuiteInfo suiteInf
 
 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA),          S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA),      S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA),      S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA),             S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA),     S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
+{0,CS(SSL_RSA_WITH_RC4_128_SHA),              S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
 {0,CS(SSL_RSA_WITH_RC4_128_MD5),              S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
-{0,CS(SSL_RSA_WITH_RC4_128_SHA),              S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA),          S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
 
 {0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA),     S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
 {0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA),     S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA),    S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
 {0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA),         S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
 
 {0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA),          S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslsecur.c,v 1.57 2012/02/15 21:52:08 kaie%kuix.de Exp $ */
+/* $Id: sslsecur.c,v 1.58 2012/03/01 18:36:35 kaie%kuix.de Exp $ */
 #include "cert.h"
 #include "secitem.h"
 #include "keyhi.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
 #include "secoid.h"	/* for SECOID_GetALgorithmTag */
 #include "pk11func.h"	/* for PK11_GenerateRandom */
@@ -1398,17 +1398,17 @@ SSL_InvalidateSession(PRFileDesc *fd)
 {
     sslSocket *   ss = ssl_FindSocket(fd);
     SECStatus     rv = SECFailure;
 
     if (ss) {
 	ssl_Get1stHandshakeLock(ss);
 	ssl_GetSSL3HandshakeLock(ss);
 
-	if (ss->sec.ci.sid) {
+	if (ss->sec.ci.sid && ss->sec.uncache) {
 	    ss->sec.uncache(ss->sec.ci.sid);
 	    rv = SECSuccess;
 	}
 
 	ssl_ReleaseSSL3HandshakeLock(ss);
 	ssl_Release1stHandshakeLock(ss);
     }
     return rv;
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -35,17 +35,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslsock.c,v 1.82 2012/02/15 21:52:08 kaie%kuix.de Exp $ */
+/* $Id: sslsock.c,v 1.82.2.1 2012/03/31 23:16:38 wtc%google.com Exp $ */
 #include "seccomon.h"
 #include "cert.h"
 #include "keyhi.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
 #include "nspr.h"
 #include "private/pprio.h"
@@ -1298,17 +1298,17 @@ SSL_SetNextProtoCallback(PRFileDesc *fd,
     ssl_GetSSL3HandshakeLock(ss);
     ss->nextProtoCallback = callback;
     ss->nextProtoArg = arg;
     ssl_ReleaseSSL3HandshakeLock(ss);
 
     return SECSuccess;
 }
 
-/* NextProtoStandardCallback is set as an NPN callback for the case when
+/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when
  * SSL_SetNextProtoNego is used.
  */
 static SECStatus
 ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
 			  const unsigned char *protos, unsigned int protos_len,
 			  unsigned char *protoOut, unsigned int *protoOutLen,
 			  unsigned int protoMaxLen)
 {
@@ -1344,22 +1344,22 @@ ssl_NextProtoNegoCallback(void *arg, PRF
 	i += 1 + (unsigned int)protos[i];
     }
 
 pick_first:
     ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
     result = ss->opt.nextProtoNego.data;
 
 found:
-    *protoOutLen = result[0];
     if (protoMaxLen < result[0]) {
 	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
 	return SECFailure;
     }
     memcpy(protoOut, result + 1, result[0]);
+    *protoOutLen = result[0];
     return SECSuccess;
 }
 
 SECStatus
 SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
 		     unsigned int length)
 {
     sslSocket *ss;
@@ -1403,23 +1403,22 @@ SSL_GetNextProto(PRFileDesc *fd, SSLNext
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     }
 
     *state = ss->ssl3.nextProtoState;
 
     if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
 	ss->ssl3.nextProto.data) {
-	*bufLen = ss->ssl3.nextProto.len;
-	if (*bufLen > bufLenMax) {
+	if (ss->ssl3.nextProto.len > bufLenMax) {
 	    PORT_SetError(SEC_ERROR_OUTPUT_LEN);
-	    *bufLen = 0;
 	    return SECFailure;
 	}
 	PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len);
+	*bufLen = ss->ssl3.nextProto.len;
     } else {
 	*bufLen = 0;
     }
 
     return SECSuccess;
 }
 
 PRFileDesc *
--- a/security/nss/lib/util/ciferfam.h
+++ b/security/nss/lib/util/ciferfam.h
@@ -33,17 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * ciferfam.h - cipher familie IDs used for configuring ciphers for export
  *              control
  *
- * $Id: ciferfam.h,v 1.4 2007/10/12 01:44:50 julien.pierre.boogz%sun.com Exp $
+ * $Id: ciferfam.h,v 1.5 2012/03/01 18:33:11 kaie%kuix.de Exp $
  */
 
 #ifndef _CIFERFAM_H_
 #define _CIFERFAM_H_
 
 #include "utilrename.h"
 /* Cipher Suite "Families" */
 #define CIPHER_FAMILY_PKCS12			"PKCS12"
@@ -67,16 +67,17 @@
  * needs to be made smarter at the same time.
  */
 #define	SMIME_RC2_CBC_40		(CIPHER_FAMILYID_SMIME | 0001)
 #define	SMIME_RC2_CBC_64		(CIPHER_FAMILYID_SMIME | 0002)
 #define	SMIME_RC2_CBC_128		(CIPHER_FAMILYID_SMIME | 0003)
 #define	SMIME_DES_CBC_56		(CIPHER_FAMILYID_SMIME | 0011)
 #define	SMIME_DES_EDE3_168		(CIPHER_FAMILYID_SMIME | 0012)
 #define	SMIME_AES_CBC_128		(CIPHER_FAMILYID_SMIME | 0013)
+#define	SMIME_AES_CBC_256		(CIPHER_FAMILYID_SMIME | 0014)
 #define	SMIME_RC5PAD_64_16_40		(CIPHER_FAMILYID_SMIME | 0021)
 #define	SMIME_RC5PAD_64_16_64		(CIPHER_FAMILYID_SMIME | 0022)
 #define	SMIME_RC5PAD_64_16_128		(CIPHER_FAMILYID_SMIME | 0023)
 #define	SMIME_FORTEZZA			(CIPHER_FAMILYID_SMIME | 0031)
 
 /* PKCS12 "Cipher Suites" */
 
 #define	PKCS12_RC2_CBC_40		(CIPHER_FAMILYID_PKCS12 | 0001)
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -46,22 +46,22 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.13.3.0"
+#define NSSUTIL_VERSION  "3.13.4.0 Beta"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   13
-#define NSSUTIL_VPATCH   3
+#define NSSUTIL_VPATCH   4
 #define NSSUTIL_VBUILD   0
-#define NSSUTIL_BETA     PR_FALSE
+#define NSSUTIL_BETA     PR_TRUE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
 extern const char *NSSUTIL_GetVersion(void);
 
--- a/security/nss/lib/util/quickder.c
+++ b/security/nss/lib/util/quickder.c
@@ -810,65 +810,82 @@ static SECStatus DecodeItem(void* dest,
         }
         else
         {
             /* handle all other types as "save" */
             /* we should only get here for primitive universal types */
             SECItem newtemp = temp;
             rv = GetItem(&newtemp, &temp, PR_FALSE);
             save = PR_TRUE;
-            if ((SECSuccess == rv) && SEC_ASN1_UNIVERSAL == (kind & SEC_ASN1_CLASS_MASK))
-            switch (kind & SEC_ASN1_TAGNUM_MASK)
+            if ((SECSuccess == rv) &&
+                SEC_ASN1_UNIVERSAL == (kind & SEC_ASN1_CLASS_MASK))
             {
-            /* special cases of primitive types */
-            case SEC_ASN1_INTEGER:
+                unsigned long tagnum = kind & SEC_ASN1_TAGNUM_MASK;
+                if ( temp.len == 0 && (tagnum == SEC_ASN1_BOOLEAN ||
+                                       tagnum == SEC_ASN1_INTEGER ||
+                                       tagnum == SEC_ASN1_BIT_STRING ||
+                                       tagnum == SEC_ASN1_OBJECT_ID ||
+                                       tagnum == SEC_ASN1_ENUMERATED ||
+                                       tagnum == SEC_ASN1_UTC_TIME ||
+                                       tagnum == SEC_ASN1_GENERALIZED_TIME) )
                 {
-                    /* remove leading zeroes if the caller requested siUnsignedInteger
-                       This is to allow RSA key operations to work */
-                    SECItem* destItem = (SECItem*) ((char*)dest + templateEntry->offset);
-                    if (destItem && (siUnsignedInteger == destItem->type))
+                    /* these types MUST have at least one content octet */
+                    PORT_SetError(SEC_ERROR_BAD_DER);
+                    rv = SECFailure;
+                }
+                else
+                switch (tagnum)
+                {
+                /* special cases of primitive types */
+                case SEC_ASN1_INTEGER:
                     {
-                        while (temp.len > 1 && temp.data[0] == 0)
-                        {              /* leading 0 */
-                            temp.data++;
-                            temp.len--;
+                        /* remove leading zeroes if the caller requested
+                           siUnsignedInteger
+                           This is to allow RSA key operations to work */
+                        SECItem* destItem = (SECItem*) ((char*)dest +
+                                            templateEntry->offset);
+                        if (destItem && (siUnsignedInteger == destItem->type))
+                        {
+                            while (temp.len > 1 && temp.data[0] == 0)
+                            {              /* leading 0 */
+                                temp.data++;
+                                temp.len--;
+                            }
                         }
+                        break;
                     }
-                    break;
-                }
 
-            case SEC_ASN1_BIT_STRING:
-                {
-                    /* change the length in the SECItem to be the number of bits */
-                    if (temp.len && temp.data)
+                case SEC_ASN1_BIT_STRING:
                     {
-                        temp.len = (temp.len-1)*8 - ((*(unsigned char*)temp.data) & 0x7);
-                        temp.data = (unsigned char*)(temp.data+1);
+                        /* change the length in the SECItem to be the number
+                           of bits */
+                        temp.len = (temp.len-1)*8 - (temp.data[0] & 0x7);
+                        temp.data += 1;
+                        break;
                     }
-                    break;
-                }
 
-            default:
-                {
-                    break;
+                default:
+                    {
+                        break;
+                    }
                 }
             }
         }
     }
 
     if ((SECSuccess == rv) && (PR_TRUE == save))
     {
         SECItem* destItem = (SECItem*) ((char*)dest + templateEntry->offset);
         if (destItem)
         {
             /* we leave the type alone in the destination SECItem.
                If part of the destination was allocated by the decoder, in
                cases of POINTER, SET OF and SEQUENCE OF, then type is set to
                siBuffer due to the use of PORT_ArenaZAlloc*/
-            destItem->data = temp.data;
+            destItem->data = temp.len ? temp.data : NULL;
             destItem->len = temp.len;
         }
         else
         {
             PORT_SetError(SEC_ERROR_INVALID_ARGS);
             rv = SECFailure;
         }
     }
--- a/security/nss/lib/util/secitem.c
+++ b/security/nss/lib/util/secitem.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Support routines for SECItem data structure.
  *
- * $Id: secitem.c,v 1.16 2011/07/22 21:22:40 wtc%google.com Exp $
+ * $Id: secitem.c,v 1.17 2012/03/23 03:12:16 wtc%google.com Exp $
  */
 
 #include "seccomon.h"
 #include "secitem.h"
 #include "base64.h"
 #include "secerr.h"
 
 SECItem *
@@ -148,30 +148,30 @@ SECITEM_ReallocItem(PRArenaPool *arena, 
 
     return SECSuccess;
 }
 
 SECComparison
 SECITEM_CompareItem(const SECItem *a, const SECItem *b)
 {
     unsigned m;
-    SECComparison rv;
+    int rv;
 
     if (a == b)
     	return SECEqual;
     if (!a || !a->len || !a->data) 
         return (!b || !b->len || !b->data) ? SECEqual : SECLessThan;
     if (!b || !b->len || !b->data) 
     	return SECGreaterThan;
 
     m = ( ( a->len < b->len ) ? a->len : b->len );
     
-    rv = (SECComparison) PORT_Memcmp(a->data, b->data, m);
+    rv = PORT_Memcmp(a->data, b->data, m);
     if (rv) {
-	return rv;
+	return rv < 0 ? SECLessThan : SECGreaterThan;
     }
     if (a->len < b->len) {
 	return SECLessThan;
     }
     if (a->len == b->len) {
 	return SECEqual;
     }
     return SECGreaterThan;
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -1120,20 +1120,19 @@ nsOfflineManifestItem::OnStopRequest(nsI
 
     return nsOfflineCacheUpdateItem::OnStopRequest(aRequest, aContext, aStatus);
 }
 
 //-----------------------------------------------------------------------------
 // nsOfflineCacheUpdate::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS3(nsOfflineCacheUpdate,
+NS_IMPL_ISUPPORTS2(nsOfflineCacheUpdate,
                    nsIOfflineCacheUpdateObserver,
-                   nsIOfflineCacheUpdate,
-                   nsIApplicationCacheAsyncCallback)
+                   nsIOfflineCacheUpdate)
 
 //-----------------------------------------------------------------------------
 // nsOfflineCacheUpdate <public>
 //-----------------------------------------------------------------------------
 
 nsOfflineCacheUpdate::nsOfflineCacheUpdate()
     : mState(STATE_UNINITIALIZED)
     , mOwner(nsnull)
@@ -1443,25 +1442,36 @@ nsOfflineCacheUpdate::LoadCompleted()
         PRUint32 dummy_cache_type;
         rv = mApplicationCache->GetTypes(item->mCacheKey, &dummy_cache_type);
         bool item_doomed = NS_FAILED(rv); // can not find it? -> doomed
 
         if (item_doomed &&
             mPinnedEntryRetriesCount < kPinnedEntryRetriesLimit &&
             (item->mItemType & (nsIApplicationCache::ITEM_EXPLICIT |
                                 nsIApplicationCache::ITEM_FALLBACK))) {
-        rv = item->Cancel();
-
-        if (NS_SUCCEEDED(rv)) {
-            mPinnedEntryRetriesCount++;
-            // Do a retrying for current item, so mCurrentItem is not advanced.
-            rv = EvictOneNonPinnedAsync();
+            rv = EvictOneNonPinned();
+            if (NS_FAILED(rv)) {
+                mSucceeded = false;
+                NotifyState(nsIOfflineCacheUpdateObserver::STATE_ERROR);
+                Finish();
+                return;
             }
 
-        if (NS_SUCCEEDED(rv)) return;
+            rv = item->Cancel();
+            if (NS_FAILED(rv)) {
+                mSucceeded = false;
+                NotifyState(nsIOfflineCacheUpdateObserver::STATE_ERROR);
+                Finish();
+                return;
+            }
+
+            mPinnedEntryRetriesCount++;
+            // Retry current item, so mCurrentItem is not advanced.
+            ProcessNextURI();
+            return;
         }
     }
 
     // Advance to next item.
     mCurrentItem++;
     mPinnedEntryRetriesCount = 0;
 
     // Check for failures.  3XX, 4XX and 5XX errors on items explicitly
@@ -1876,18 +1886,17 @@ nsOfflineCacheUpdate::Finish()
 
     NotifyState(nsIOfflineCacheUpdateObserver::STATE_FINISHED);
 
     return rv;
 }
 
 static nsresult
 EvictOneOfCacheGroups(nsIApplicationCacheService *cacheService,
-                      PRUint32 count, const char * const *groups,
-                      nsIApplicationCacheAsyncCallback *aCallback)
+                      PRUint32 count, const char * const *groups)
 {
     nsresult rv;
     unsigned int i;
 
     for (i = 0; i < count; i++) {
         nsCOMPtr<nsIURI> uri;
         rv = NS_NewURI(getter_AddRefs(uri), groups[i]);
         NS_ENSURE_SUCCESS(rv, rv);
@@ -1901,47 +1910,39 @@ EvictOneOfCacheGroups(nsIApplicationCach
 
         bool pinned;
         rv = nsOfflineCacheUpdateService::OfflineAppPinnedForURI(uri,
                                                                  NULL,
                                                                  &pinned);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (!pinned) {
-            // Call HandleAsyncCompletion() when the task is completed.
-            rv = cache->DiscardAsync(aCallback);
-           return NS_OK;
+            rv = cache->Discard();
+            return NS_OK;
         }
     }
 
     return NS_ERROR_FILE_NOT_FOUND;
 }
 
-/**
- * Evict one of non-pinned cache group in asynchronized.
- *
- * This method returns immediately.  It will start an async task to
- * evict a selected cache group.  HandleAsyncCompletion() will be
- * called while the eviction is completed.
- */
- nsresult
-nsOfflineCacheUpdate::EvictOneNonPinnedAsync()
+nsresult
+nsOfflineCacheUpdate::EvictOneNonPinned()
 {
     nsresult rv;
 
     nsCOMPtr<nsIApplicationCacheService> cacheService =
         do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRUint32 count;
     char **groups;
     rv = cacheService->GetGroupsTimeOrdered(&count, &groups);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = EvictOneOfCacheGroups(cacheService, count, groups, this);
+    rv = EvictOneOfCacheGroups(cacheService, count, groups);
 
     NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, groups);
     return rv;
 }
 
 //-----------------------------------------------------------------------------
 // nsOfflineCacheUpdate::nsIOfflineCacheUpdate
 //-----------------------------------------------------------------------------
@@ -2153,24 +2154,8 @@ nsOfflineCacheUpdate::UpdateStateChanged
     return rv;
 }
 
 NS_IMETHODIMP
 nsOfflineCacheUpdate::ApplicationCacheAvailable(nsIApplicationCache *applicationCache)
 {
     return AssociateDocuments(applicationCache);
 }
-
-//-----------------------------------------------------------------------------
-// nsOfflineCacheUpdate::nsIApplicationCacheAsyncCallback
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-nsOfflineCacheUpdate::HandleAsyncCompletion(PRUint32 aState) {
-    if (aState != APP_CACHE_REQUEST_SUCCESS) {
-        mSucceeded = false;
-        NotifyState(nsIOfflineCacheUpdateObserver::STATE_ERROR);
-        Finish();
-        return NS_OK;
-    }
-
-    return ProcessNextURI();
-}
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -208,23 +208,21 @@ class nsOfflineCacheUpdateOwner
 {
 public:
     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate) = 0;
 };
 
 class nsOfflineCacheUpdate : public nsIOfflineCacheUpdate
                            , public nsIOfflineCacheUpdateObserver
                            , public nsOfflineCacheUpdateOwner
-                           , public nsIApplicationCacheAsyncCallback
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOFFLINECACHEUPDATE
     NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
-    NS_DECL_NSIAPPLICATIONCACHEASYNCCALLBACK
 
     nsOfflineCacheUpdate();
     ~nsOfflineCacheUpdate();
 
     static nsresult GetCacheKey(nsIURI *aURI, nsACString &aKey);
 
     nsresult Init();
 
@@ -255,17 +253,17 @@ private:
     nsresult AssociateDocuments(nsIApplicationCache* cache);
 
     nsresult GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
     nsresult NotifyState(PRUint32 state);
     nsresult Finish();
     nsresult FinishNoNotify();
 
     // Find one non-pinned cache group and evict it.
-    nsresult EvictOneNonPinnedAsync();
+    nsresult EvictOneNonPinned();
 
     enum {
         STATE_UNINITIALIZED,
         STATE_INITIALIZED,
         STATE_CHECKING,
         STATE_DOWNLOADING,
         STATE_CANCELLED,
         STATE_FINISHED