NS_IMETHODIMP
nsCompartmentInfo::GetCompartments(nsIArray** aCompartments)
{
  JSRuntime* rt;
  nsCOMPtr<nsIJSRuntimeService> svc(do_GetService("@mozilla.org/js/xpc/RuntimeService;1"));
  NS_ENSURE_TRUE(svc, NS_ERROR_FAILURE);
  svc->GetRuntime(&rt);
  nsCOMPtr<nsIMutableArray> compartments = do_CreateInstance(NS_ARRAY_CONTRACTID);
  CompartmentStatsVector stats;
  if (!JS_GetCompartmentStats(rt, stats))
    return NS_ERROR_OUT_OF_MEMORY;

  size_t num = stats.length();
  for (size_t pos = 0; pos < num; pos++) {
    nsString addonId;
    if (stats[pos].addonId) {
      AssignJSFlatString(addonId, (JSFlatString*)stats[pos].addonId);
    } else {
      addonId.AssignLiteral("<non-addon>");
    }

    uint32_t cpowTime = xpc::GetCompartmentCPOWMicroseconds(stats[pos].compartment);
    nsCString compartmentName(stats[pos].compartmentName);
    NS_ConvertUTF8toUTF16 name(compartmentName);
    compartments->AppendElement(new nsCompartment(name, addonId, stats[pos].time, cpowTime), false);
  }
  compartments.forget(aCompartments);
  return NS_OK;
}
Beispiel #2
0
void
FileReader::OnLoadEndArrayBuffer()
{
  AutoJSAPI jsapi;
  if (!jsapi.Init(GetParentObject())) {
    FreeDataAndDispatchError(NS_ERROR_FAILURE);
    return;
  }

  RootResultArrayBuffer();

  JSContext* cx = jsapi.cx();

  mResultArrayBuffer = JS_NewArrayBufferWithContents(cx, mDataLen, mFileData);
  if (mResultArrayBuffer) {
    mFileData = nullptr; // Transfer ownership
    FreeDataAndDispatchSuccess();
    return;
  }

  // Let's handle the error status.

  JS::Rooted<JS::Value> exceptionValue(cx);
  if (!JS_GetPendingException(cx, &exceptionValue) ||
      // This should not really happen, exception should always be an object.
      !exceptionValue.isObject()) {
    JS_ClearPendingException(jsapi.cx());
    FreeDataAndDispatchError(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  JS_ClearPendingException(jsapi.cx());

  JS::Rooted<JSObject*> exceptionObject(cx, &exceptionValue.toObject());
  JSErrorReport* er = JS_ErrorFromException(cx, exceptionObject);
  if (!er || er->message()) {
    FreeDataAndDispatchError(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  nsAutoString errorName;
  JSFlatString* name = js::GetErrorTypeName(cx, er->exnType);
  if (name) {
    AssignJSFlatString(errorName, name);
  }

  nsAutoCString errorMsg(er->message().c_str());
  nsAutoCString errorNameC = NS_LossyConvertUTF16toASCII(errorName);
  // XXX Code selected arbitrarily
  mError =
    new DOMException(NS_ERROR_DOM_INVALID_STATE_ERR, errorMsg,
                     errorNameC, DOMException_Binding::INVALID_STATE_ERR);

  FreeDataAndDispatchError();
}
/* static */ void
nsPerformanceSnapshot::GetAddonId(JSContext*,
                                  JS::Handle<JSObject*> global,
                                  nsAString& addonId)
{
  addonId.AssignLiteral("");

  JSAddonId* jsid = AddonIdOfObject(global);
  if (!jsid) {
    return;
  }
  AssignJSFlatString(addonId, (JSFlatString*)jsid);
}
bool
nsPerformanceStatsService::GetPerformanceGroups(JSContext* cx, JSGroupVector& out) {
  JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
  if (!global) {
    // While it is possible for a compartment to have no global
    // (e.g. atoms), this compartment is not very interesting for us.
    return true;
  }

  // All compartments belong to the top group.
  out.append(mTopGroup);

  nsAutoString name;
  CompartmentName(cx, global, name);
  bool isSystem = nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(global));

  // Find out if the compartment is executed by an add-on. If so, its
  // duration should count towards the total duration of the add-on.
  JSAddonId* jsaddonId = AddonIdOfObject(global);
  nsString addonId;
  if (jsaddonId) {
    AssignJSFlatString(addonId, (JSFlatString*)jsaddonId);
    auto entry = mAddonIdToGroup.PutEntry(addonId);
    if (!entry->mGroup) {
      nsString addonName = name;
      addonName.AppendLiteral(" (as addon ");
      addonName.Append(addonId);
      addonName.AppendLiteral(")");
      entry->mGroup =
        nsPerformanceGroup::Make(mRuntime, this,
                                 addonName, addonId, 0,
                                 mProcessId, isSystem,
                                 nsPerformanceGroup::GroupScope::ADDON);
    }
    out.append(entry->mGroup);
  }

  // Find out if the compartment is executed by a window. If so, its
  // duration should count towards the total duration of the window.
  nsCOMPtr<nsPIDOMWindow> ptop = GetPrivateWindow(cx);
  uint64_t windowId = 0;
  if (ptop) {
    windowId = ptop->WindowID();
    auto entry = mWindowIdToGroup.PutEntry(windowId);
    if (!entry->mGroup) {
      nsString windowName = name;
      windowName.AppendLiteral(" (as window ");
      windowName.AppendInt(windowId);
      windowName.AppendLiteral(")");
      entry->mGroup =
        nsPerformanceGroup::Make(mRuntime, this,
                                 windowName, EmptyString(), windowId,
                                 mProcessId, isSystem,
                                 nsPerformanceGroup::GroupScope::WINDOW);
    }
    out.append(entry->mGroup);
  }

  // All compartments have their own group.
  auto group =
    nsPerformanceGroup::Make(mRuntime, this,
                             name, addonId, windowId,
                             mProcessId, isSystem,
                             nsPerformanceGroup::GroupScope::COMPARTMENT);
  out.append(group);

  return true;
}