예제 #1
0
bool
StructTypeRepresentation::init(JSContext *cx,
                               AutoPropertyNameVector &names,
                               AutoObjectVector &typeReprOwners)
{
    JS_ASSERT(names.length() == typeReprOwners.length());
    fieldCount_ = names.length();

    // We compute alignment into the field `align_` directly in the
    // loop below, but not `size_` because we have to very careful
    // about overflow. For now, we always use a uint32_t for
    // consistency across build environments.
    uint32_t totalSize = 0;

    // These will be adjusted in the loop below:
    alignment_ = 1;
    opaque_ = false;

    for (size_t i = 0; i < names.length(); i++) {
        SizedTypeRepresentation *fieldTypeRepr =
            fromOwnerObject(*typeReprOwners[i])->asSized();

        if (fieldTypeRepr->opaque())
            opaque_ = true;

        uint32_t alignedSize = alignTo(totalSize, fieldTypeRepr->alignment());
        if (alignedSize < totalSize) {
            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                                 JSMSG_TYPEDOBJECT_TOO_BIG);
            return false;
        }

        new(fields() + i) StructField(i, names[i],
                                      fieldTypeRepr, alignedSize);
        alignment_ = js::Max(alignment_, fieldTypeRepr->alignment());

        uint32_t incrementedSize = alignedSize + fieldTypeRepr->size();
        if (incrementedSize < alignedSize) {
            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                                 JSMSG_TYPEDOBJECT_TOO_BIG);
            return false;
        }

        totalSize = incrementedSize;
    }

    uint32_t alignedSize = alignTo(totalSize, alignment_);
    if (alignedSize < totalSize) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                             JSMSG_TYPEDOBJECT_TOO_BIG);
        return false;
    }

    size_ = alignedSize;
    return true;
}
예제 #2
0
// Add the given set of globals as explicit roots in the given roots
// list. Returns false on OOM failure.
static bool
AddGlobalsAsRoots(AutoObjectVector& globals, ubi::RootList& roots)
{
  unsigned length = globals.length();
  for (unsigned i = 0; i < length; i++) {
    if (!roots.addRoot(ubi::Node(globals[i].get()),
                       MOZ_UTF16("heap snapshot global")))
    {
      return false;
    }
  }
  return true;
}
예제 #3
0
// If we are only taking a snapshot of the heap affected by the given set of
// globals, find the set of zones the globals are allocated within. Returns
// false on OOM failure.
static bool
PopulateZonesWithGlobals(ZoneSet& zones, AutoObjectVector& globals)
{
  if (!zones.init())
    return false;

  unsigned length = globals.length();
  for (unsigned i = 0; i < length; i++) {
    if (!zones.put(GetObjectZone(globals[i])))
      return false;
  }

  return true;
}
예제 #4
0
static bool
AddInnerLazyFunctionsFromScript(JSScript *script, AutoObjectVector &lazyFunctions)
{
    if (!script->hasObjects())
        return true;
    ObjectArray *objects = script->objects();
    for (size_t i = script->innerObjectsStart(); i < objects->length; i++) {
        JSObject *obj = objects->vector[i];
        if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpretedLazy()) {
            if (!lazyFunctions.append(obj))
                return false;
        }
    }
    return true;
}
예제 #5
0
static bool
AddLazyFunctionsForCompartment(JSContext* cx, AutoObjectVector& lazyFunctions, AllocKind kind)
{
    // Find all live root lazy functions in the compartment: those which have a
    // source object, indicating that they have a parent, and which do not have
    // an uncompiled enclosing script. The last condition is so that we don't
    // compile lazy scripts whose enclosing scripts failed to compile,
    // indicating that the lazy script did not escape the script.
    //
    // Some LazyScripts have a non-null |JSScript* script| pointer. We still
    // want to delazify in that case: this pointer is weak so the JSScript
    // could be destroyed at the next GC.

    for (auto i = cx->zone()->cellIter<JSObject>(kind); !i.done(); i.next()) {
        JSFunction* fun = &i->as<JSFunction>();

        // Sweeping is incremental; take care to not delazify functions that
        // are about to be finalized. GC things referenced by objects that are
        // about to be finalized (e.g., in slots) may already be freed.
        if (gc::IsAboutToBeFinalizedUnbarriered(&fun) ||
            fun->compartment() != cx->compartment())
        {
            continue;
        }

        if (fun->isInterpretedLazy()) {
            LazyScript* lazy = fun->lazyScriptOrNull();
            if (lazy && lazy->sourceObject() && !lazy->hasUncompiledEnclosingScript()) {
                if (!lazyFunctions.append(fun))
                    return false;
            }
        }
    }

    return true;
}
예제 #6
0
static bool
AddLazyFunctionsForCompartment(JSContext* cx, AutoObjectVector& lazyFunctions, AllocKind kind)
{
    // Find all live root lazy functions in the compartment: those which
    // have not been compiled, which have a source object, indicating that
    // they have a parent, and which do not have an uncompiled enclosing
    // script. The last condition is so that we don't compile lazy scripts
    // whose enclosing scripts failed to compile, indicating that the lazy
    // script did not escape the script.
    for (gc::ZoneCellIter i(cx->zone(), kind); !i.done(); i.next()) {
        JSObject* obj = i.get<JSObject>();

        // Sweeping is incremental; take care to not delazify functions that
        // are about to be finalized. GC things referenced by objects that are
        // about to be finalized (e.g., in slots) may already be freed.
        if (gc::IsObjectAboutToBeFinalized(&obj) ||
            obj->compartment() != cx->compartment() ||
            !obj->is<JSFunction>())
        {
            continue;
        }

        JSFunction* fun = &obj->as<JSFunction>();
        if (fun->isInterpretedLazy()) {
            LazyScript* lazy = fun->lazyScriptOrNull();
            if (lazy && lazy->sourceObject() && !lazy->maybeScript() &&
                !lazy->hasUncompiledEnclosingScript())
            {
                if (!lazyFunctions.append(fun))
                    return false;
            }
        }
    }

    return true;
}