本文整理汇总了C++中JSString::length方法的典型用法代码示例。如果您正苦于以下问题:C++ JSString::length方法的具体用法?C++ JSString::length怎么用?C++ JSString::length使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类JSString
的用法示例。
在下文中一共展示了JSString::length方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: key
bool
JSCompartment::wrap(JSContext *cx, JSString **strp)
{
JS_ASSERT(!cx->runtime()->isAtomsCompartment(this));
JS_ASSERT(cx->compartment() == this);
/* If the string is already in this compartment, we are done. */
JSString *str = *strp;
if (str->zone() == zone())
return true;
/* If the string is an atom, we don't have to copy. */
if (str->isAtom()) {
JS_ASSERT(cx->runtime()->isAtomsZone(str->zone()));
return true;
}
/* Check the cache. */
RootedValue key(cx, StringValue(str));
if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
*strp = p->value().get().toString();
return true;
}
/*
* No dice. Make a copy, and cache it. Directly allocate the copy in the
* destination compartment, rather than first flattening it (and possibly
* allocating in source compartment), because we don't know whether the
* flattening will pay off later.
*/
JSString *copy;
if (str->hasPureChars()) {
copy = js_NewStringCopyN<CanGC>(cx, str->pureChars(), str->length());
} else {
ScopedJSFreePtr<jschar> copiedChars;
if (!str->copyNonPureCharsZ(cx, copiedChars))
return false;
copy = js_NewString<CanGC>(cx, copiedChars.forget(), str->length());
}
if (!copy)
return false;
if (!putWrapper(cx, key, StringValue(copy)))
return false;
*strp = copy;
return true;
}
示例2: visitChildren
void JSString::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
JSString* thisObject = jsCast<JSString*>(cell);
Base::visitChildren(thisObject, visitor);
MARK_LOG_MESSAGE1("[%u]: ", thisObject->length());
#if ENABLE(OBJECT_MARK_LOGGING)
if (!thisObject->isRope()) {
WTF::StringImpl* ourImpl = thisObject->m_value.impl();
if (ourImpl->is8Bit())
MARK_LOG_MESSAGE1("[8 %p]", ourImpl->characters8());
else
MARK_LOG_MESSAGE1("[16 %p]", ourImpl->characters16());
} else
MARK_LOG_MESSAGE0("[rope]: ");
#endif
if (thisObject->isRope())
static_cast<JSRopeString*>(thisObject)->visitFibers(visitor);
else {
StringImpl* impl = thisObject->m_value.impl();
ASSERT(impl);
visitor.reportExtraMemoryUsage(impl->costDuringGC());
}
}
示例3: length
// Overview: These functions convert a JSString from holding a string in rope form
// down to a simple String representation. It does so by building up the string
// backwards, since we want to avoid recursion, we expect that the tree structure
// representing the rope is likely imbalanced with more nodes down the left side
// (since appending to the string is likely more common) - and as such resolving
// in this fashion should minimize work queue size. (If we built the queue forwards
// we would likely have to place all of the constituent StringImpls into the
// Vector before performing any concatenation, but by working backwards we likely
// only fill the queue with the number of substrings at any given level in a
// rope-of-ropes.)
void JSRopeString::resolveRopeSlowCase8(LChar* buffer) const
{
LChar* position = buffer + length(); // We will be working backwards over the rope.
Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // Putting strings into a Vector is only OK because there are no GC points in this method.
for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i)
workQueue.append(fiber(i).get());
while (!workQueue.isEmpty()) {
JSString* currentFiber = workQueue.last();
workQueue.removeLast();
const LChar* characters;
if (currentFiber->isRope()) {
JSRopeString* currentFiberAsRope = static_cast<JSRopeString*>(currentFiber);
if (!currentFiberAsRope->isSubstring()) {
for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->fiber(i); ++i)
workQueue.append(currentFiberAsRope->fiber(i).get());
continue;
}
ASSERT(!currentFiberAsRope->substringBase()->isRope());
characters =
currentFiberAsRope->substringBase()->m_value.characters8() +
currentFiberAsRope->substringOffset();
} else
characters = currentFiber->m_value.characters8();
unsigned length = currentFiber->length();
position -= length;
StringImpl::copyChars(position, characters, length);
}
ASSERT(buffer == position);
}
示例4:
JSBool
EvalScriptVersion16(JSContext *cx, uintN argc, jsval *vp)
{
JS_ASSERT(argc == 1);
jsval *argv = JS_ARGV(cx, vp);
JS_ASSERT(JSVAL_IS_STRING(argv[0]));
JSString *str = JSVAL_TO_STRING(argv[0]);
const jschar *chars = str->getChars(cx);
JS_ASSERT(chars);
size_t len = str->length();
return callbackData->evalVersion(chars, len, JSVERSION_1_6);
}
示例5: equalToSingleCharacter
static TriState equalToSingleCharacter(JSValue value, UChar character)
{
if (!value.isString())
return FalseTriState;
JSString* jsString = asString(value);
if (jsString->length() != 1)
return FalseTriState;
const StringImpl* string = jsString->tryGetValueImpl();
if (!string)
return MixedTriState;
return triState(string->at(0) == character);
}
示例6: MakeFunction
JSObjectRef JSFunction::MakeFunction(const JSContext& js_context, const JSString& body, const std::vector<JSString>& parameter_names, const JSString& function_name, const JSString& source_url, int starting_line_number) {
JSValueRef exception { nullptr };
JSStringRef source_url_ref = (source_url.length() > 0) ? static_cast<JSStringRef>(source_url) : nullptr;
JSObjectRef js_object_ref = nullptr;
if (!parameter_names.empty()) {
std::vector<JSStringRef> parameter_name_array = detail::to_vector(parameter_names);
js_object_ref = JSObjectMakeFunction(static_cast<JSContextRef>(js_context), static_cast<JSStringRef>(function_name), static_cast<unsigned>(parameter_name_array.size()), ¶meter_name_array[0], static_cast<JSStringRef>(body), source_url_ref, starting_line_number, &exception);
} else {
js_object_ref = JSObjectMakeFunction(static_cast<JSContextRef>(js_context), static_cast<JSStringRef>(function_name), 0, nullptr, static_cast<JSStringRef>(body), source_url_ref, starting_line_number, &exception);
}
if (exception) {
// If this assert fails then we need to JSValueUnprotect
// js_object_ref.
assert(!js_object_ref);
detail::ThrowRuntimeError("JSFunction", JSValue(js_context, exception));
}
return js_object_ref;
}
示例7: CallArgsFromVp
/**
* Handles an assertion failure in self-hosted code just like an assertion
* failure in C++ code. Information about the failure can be provided in args[0].
*/
static bool
intrinsic_AssertionFailed(JSContext *cx, unsigned argc, Value *vp)
{
#ifdef DEBUG
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() > 0) {
// try to dump the informative string
JSString *str = ToString<CanGC>(cx, args[0]);
if (str) {
const jschar *chars = str->getChars(cx);
if (chars) {
fprintf(stderr, "Self-hosted JavaScript assertion info: ");
JSString::dumpChars(chars, str->length());
fputc('\n', stderr);
}
}
}
#endif
JS_ASSERT(false);
return false;
}
示例8:
bool
GetPropIRGenerator::tryAttachStringChar(ValOperandId valId, ValOperandId indexId)
{
MOZ_ASSERT(idVal_.isInt32());
if (!val_.isString())
return false;
JSString* str = val_.toString();
int32_t index = idVal_.toInt32();
if (size_t(index) >= str->length() ||
!str->isLinear() ||
str->asLinear().latin1OrTwoByteChar(index) >= StaticStrings::UNIT_STATIC_LIMIT)
{
return false;
}
StringOperandId strId = writer.guardIsString(valId);
Int32OperandId int32IndexId = writer.guardIsInt32(indexId);
writer.loadStringCharResult(strId, int32IndexId);
writer.returnFromIC();
return true;
}
示例9: detect
static JSBool
JO(JSContext *cx, Value *vp, StringifyContext *scx)
{
JSObject *obj = &vp->toObject();
CycleDetector detect(scx, obj);
if (!detect.init(cx))
return JS_FALSE;
if (!scx->sb.append('{'))
return JS_FALSE;
Value vec[3] = { NullValue(), NullValue(), NullValue() };
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(vec), vec);
Value& outputValue = vec[0];
Value& whitelistElement = vec[1];
AutoIdRooter idr(cx);
jsid& id = *idr.addr();
Value *keySource = vp;
bool usingWhitelist = false;
// if the replacer is an array, we use the keys from it
if (scx->replacer && JS_IsArrayObject(cx, scx->replacer)) {
usingWhitelist = true;
vec[2].setObject(*scx->replacer);
keySource = &vec[2];
}
JSBool memberWritten = JS_FALSE;
AutoIdVector props(cx);
if (!GetPropertyNames(cx, &keySource->toObject(), JSITER_OWNONLY, &props))
return JS_FALSE;
for (size_t i = 0, len = props.length(); i < len; i++) {
outputValue.setUndefined();
if (!usingWhitelist) {
if (!js_ValueToStringId(cx, IdToValue(props[i]), &id))
return JS_FALSE;
} else {
// skip non-index properties
jsuint index = 0;
if (!js_IdIsIndex(props[i], &index))
continue;
if (!scx->replacer->getProperty(cx, props[i], &whitelistElement))
return JS_FALSE;
if (!js_ValueToStringId(cx, whitelistElement, &id))
return JS_FALSE;
}
// We should have a string id by this point. Either from
// JS_Enumerate's id array, or by converting an element
// of the whitelist.
JS_ASSERT(JSID_IS_ATOM(id));
if (!JS_GetPropertyById(cx, obj, id, Jsvalify(&outputValue)))
return JS_FALSE;
if (outputValue.isObjectOrNull() && !js_TryJSON(cx, &outputValue))
return JS_FALSE;
// call this here, so we don't write out keys if the replacer function
// wants to elide the value.
if (!CallReplacerFunction(cx, id, obj, scx, &outputValue))
return JS_FALSE;
JSType type = JS_TypeOfValue(cx, Jsvalify(outputValue));
// elide undefined values and functions and XML
if (outputValue.isUndefined() || type == JSTYPE_FUNCTION || type == JSTYPE_XML)
continue;
// output a comma unless this is the first member to write
if (memberWritten && !scx->sb.append(','))
return JS_FALSE;
memberWritten = JS_TRUE;
if (!WriteIndent(cx, scx, scx->depth))
return JS_FALSE;
// Be careful below, this string is weakly rooted
JSString *s = js_ValueToString(cx, IdToValue(id));
if (!s)
return JS_FALSE;
JS::Anchor<JSString *> anchor(s);
size_t length = s->length();
const jschar *chars = s->getChars(cx);
if (!chars)
return JS_FALSE;
if (!write_string(cx, scx->sb, chars, length) ||
!scx->sb.append(':') ||
!(scx->gap.empty() || scx->sb.append(' ')) ||
!Str(cx, id, obj, scx, &outputValue, true)) {
return JS_FALSE;
}
//.........这里部分代码省略.........
示例10: switch
JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, void* thing,
JS::TraceKind kind, bool details)
{
const char* name = nullptr; /* silence uninitialized warning */
size_t n;
if (bufsize == 0)
return;
switch (kind) {
case JS::TraceKind::Object:
{
name = static_cast<JSObject*>(thing)->getClass()->name;
break;
}
case JS::TraceKind::Script:
name = "script";
break;
case JS::TraceKind::String:
name = ((JSString*)thing)->isDependent()
? "substring"
: "string";
break;
case JS::TraceKind::Symbol:
name = "symbol";
break;
case JS::TraceKind::BaseShape:
name = "base_shape";
break;
case JS::TraceKind::JitCode:
name = "jitcode";
break;
case JS::TraceKind::LazyScript:
name = "lazyscript";
break;
case JS::TraceKind::Shape:
name = "shape";
break;
case JS::TraceKind::ObjectGroup:
name = "object_group";
break;
default:
name = "INVALID";
break;
}
n = strlen(name);
if (n > bufsize - 1)
n = bufsize - 1;
js_memcpy(buf, name, n + 1);
buf += n;
bufsize -= n;
*buf = '\0';
if (details && bufsize > 2) {
switch (kind) {
case JS::TraceKind::Object:
{
JSObject* obj = (JSObject*)thing;
if (obj->is<JSFunction>()) {
JSFunction* fun = &obj->as<JSFunction>();
if (fun->displayAtom()) {
*buf++ = ' ';
bufsize--;
PutEscapedString(buf, bufsize, fun->displayAtom(), 0);
}
} else if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE) {
JS_snprintf(buf, bufsize, " %p", obj->as<NativeObject>().getPrivate());
} else {
JS_snprintf(buf, bufsize, " <no private>");
}
break;
}
case JS::TraceKind::Script:
{
JSScript* script = static_cast<JSScript*>(thing);
JS_snprintf(buf, bufsize, " %s:%" PRIuSIZE, script->filename(), script->lineno());
break;
}
case JS::TraceKind::String:
{
*buf++ = ' ';
bufsize--;
JSString* str = (JSString*)thing;
if (str->isLinear()) {
bool willFit = str->length() + strlen("<length > ") +
CountDecimalDigits(str->length()) < bufsize;
//.........这里部分代码省略.........
示例11: WrapForSameCompartment
//.........这里部分代码省略.........
/* Translate StopIteration singleton. */
if (obj->isStopIteration()) {
RootedValue vvp(cx, *vp);
bool result = js_FindClassObject(cx, JSProto_StopIteration, &vvp);
*vp = vvp;
return result;
}
/* Unwrap the object, but don't unwrap outer windows. */
obj = UnwrapObject(&vp->toObject(), /* stopAtOuter = */ true, &flags);
if (obj->compartment() == this)
return WrapForSameCompartment(cx, obj, vp);
if (cx->runtime->preWrapObjectCallback) {
obj = cx->runtime->preWrapObjectCallback(cx, global, obj, flags);
if (!obj)
return false;
}
if (obj->compartment() == this)
return WrapForSameCompartment(cx, obj, vp);
vp->setObject(*obj);
#ifdef DEBUG
{
JSObject *outer = GetOuterObject(cx, obj);
JS_ASSERT(outer && outer == obj);
}
#endif
}
RootedValue key(cx, *vp);
/* If we already have a wrapper for this value, use it. */
if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(key)) {
*vp = p->value;
if (vp->isObject()) {
RootedObject obj(cx, &vp->toObject());
JS_ASSERT(obj->isCrossCompartmentWrapper());
if (obj->getParent() != global) {
do {
if (!JSObject::setParent(cx, obj, global))
return false;
obj = obj->getProto();
} while (obj && obj->isCrossCompartmentWrapper());
}
}
return true;
}
if (vp->isString()) {
RootedValue orig(cx, *vp);
JSString *str = vp->toString();
const jschar *chars = str->getChars(cx);
if (!chars)
return false;
JSString *wrapped = js_NewStringCopyN(cx, chars, str->length());
if (!wrapped)
return false;
vp->setString(wrapped);
return crossCompartmentWrappers.put(orig, *vp);
}
RootedObject obj(cx, &vp->toObject());
/*
* Recurse to wrap the prototype. Long prototype chains will run out of
* stack, causing an error in CHECK_RECURSE.
*
* Wrapping the proto before creating the new wrapper and adding it to the
* cache helps avoid leaving a bad entry in the cache on OOM. But note that
* if we wrapped both proto and parent, we would get infinite recursion
* here (since Object.prototype->parent->proto leads to Object.prototype
* itself).
*/
RootedObject proto(cx, obj->getProto());
if (!wrap(cx, proto.address()))
return false;
/*
* We hand in the original wrapped object into the wrap hook to allow
* the wrap hook to reason over what wrappers are currently applied
* to the object.
*/
RootedObject wrapper(cx, cx->runtime->wrapObjectCallback(cx, obj, proto, global, flags));
if (!wrapper)
return false;
// We maintain the invariant that the key in the cross-compartment wrapper
// map is always directly wrapped by the value.
JS_ASSERT(Wrapper::wrappedObject(wrapper) == &key.get().toObject());
vp->setObject(*wrapper);
if (!crossCompartmentWrappers.put(key, *vp))
return false;
return true;
}
示例12: if
static void
StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKind,
size_t thingSize)
{
IteratorClosure *closure = static_cast<IteratorClosure *>(data);
RuntimeStats *rtStats = closure->rtStats;
ZoneStats *zStats = rtStats->currZoneStats;
switch (traceKind) {
case JSTRACE_OBJECT: {
JSObject *obj = static_cast<JSObject *>(thing);
CompartmentStats *cStats = GetCompartmentStats(obj->compartment());
if (obj->is<JSFunction>())
cStats->gcHeapObjectsFunction += thingSize;
else if (obj->is<ArrayObject>())
cStats->gcHeapObjectsDenseArray += thingSize;
else if (obj->isCrossCompartmentWrapper())
cStats->gcHeapObjectsCrossCompartmentWrapper += thingSize;
else
cStats->gcHeapObjectsOrdinary += thingSize;
JS::ObjectsExtraSizes objectsExtra;
obj->sizeOfExcludingThis(rtStats->mallocSizeOf_, &objectsExtra);
cStats->objectsExtra.add(objectsExtra);
// JSObject::sizeOfExcludingThis() doesn't measure objectsExtraPrivate,
// so we do it here.
if (ObjectPrivateVisitor *opv = closure->opv) {
nsISupports *iface;
if (opv->getISupports_(obj, &iface) && iface) {
cStats->objectsExtra.private_ += opv->sizeOfIncludingThis(iface);
}
}
break;
}
case JSTRACE_STRING: {
JSString *str = static_cast<JSString *>(thing);
size_t strSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf_);
// If we can't grow hugeStrings, let's just call this string non-huge.
// We're probably about to OOM anyway.
if (strSize >= JS::HugeStringInfo::MinSize() && zStats->hugeStrings.growBy(1)) {
zStats->gcHeapStringsNormal += thingSize;
JS::HugeStringInfo &info = zStats->hugeStrings.back();
info.length = str->length();
info.size = strSize;
PutEscapedString(info.buffer, sizeof(info.buffer), &str->asLinear(), 0);
} else if (str->isShort()) {
MOZ_ASSERT(strSize == 0);
zStats->gcHeapStringsShort += thingSize;
} else {
zStats->gcHeapStringsNormal += thingSize;
zStats->stringCharsNonHuge += strSize;
}
break;
}
case JSTRACE_SHAPE: {
Shape *shape = static_cast<Shape *>(thing);
CompartmentStats *cStats = GetCompartmentStats(shape->compartment());
size_t propTableSize, kidsSize;
shape->sizeOfExcludingThis(rtStats->mallocSizeOf_, &propTableSize, &kidsSize);
if (shape->inDictionary()) {
cStats->gcHeapShapesDict += thingSize;
cStats->shapesExtraDictTables += propTableSize;
JS_ASSERT(kidsSize == 0);
} else {
if (shape->base()->getObjectParent() == shape->compartment()->maybeGlobal()) {
cStats->gcHeapShapesTreeGlobalParented += thingSize;
} else {
cStats->gcHeapShapesTreeNonGlobalParented += thingSize;
}
cStats->shapesExtraTreeTables += propTableSize;
cStats->shapesExtraTreeShapeKids += kidsSize;
}
break;
}
case JSTRACE_BASE_SHAPE: {
BaseShape *base = static_cast<BaseShape *>(thing);
CompartmentStats *cStats = GetCompartmentStats(base->compartment());
cStats->gcHeapShapesBase += thingSize;
break;
}
case JSTRACE_SCRIPT: {
JSScript *script = static_cast<JSScript *>(thing);
CompartmentStats *cStats = GetCompartmentStats(script->compartment());
cStats->gcHeapScripts += thingSize;
cStats->scriptData += script->sizeOfData(rtStats->mallocSizeOf_);
#ifdef JS_ION
size_t baselineData = 0, baselineStubsFallback = 0;
ion::SizeOfBaselineData(script, rtStats->mallocSizeOf_, &baselineData,
&baselineStubsFallback);
cStats->baselineData += baselineData;
cStats->baselineStubsFallback += baselineStubsFallback;
cStats->ionData += ion::SizeOfIonData(script, rtStats->mallocSizeOf_);
#endif
//.........这里部分代码省略.........
示例13:
bool
JSCompartment::wrap(JSContext *cx, Value *vp)
{
JS_ASSERT(cx->compartment == this);
uintN flags = 0;
JS_CHECK_RECURSION(cx, return false);
/* Only GC things have to be wrapped or copied. */
if (!vp->isMarkable())
return true;
/* Static strings do not have to be wrapped. */
if (vp->isString() && JSString::isStatic(vp->toString()))
return true;
/* Unwrap incoming objects. */
if (vp->isObject()) {
JSObject *obj = &vp->toObject();
/* If the object is already in this compartment, we are done. */
if (obj->getCompartment(cx) == this)
return true;
/* Don't unwrap an outer window proxy. */
if (!obj->getClass()->ext.innerObject) {
obj = vp->toObject().unwrap(&flags);
OBJ_TO_OUTER_OBJECT(cx, obj);
if (!obj)
return false;
vp->setObject(*obj);
}
/* If the wrapped object is already in this compartment, we are done. */
if (obj->getCompartment(cx) == this)
return true;
}
/* If we already have a wrapper for this value, use it. */
if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(*vp)) {
*vp = p->value;
return true;
}
if (vp->isString()) {
Value orig = *vp;
JSString *str = vp->toString();
JSString *wrapped = js_NewStringCopyN(cx, str->chars(), str->length());
if (!wrapped)
return false;
vp->setString(wrapped);
return crossCompartmentWrappers.put(orig, *vp);
}
JSObject *obj = &vp->toObject();
/*
* Recurse to wrap the prototype. Long prototype chains will run out of
* stack, causing an error in CHECK_RECURSE.
*
* Wrapping the proto before creating the new wrapper and adding it to the
* cache helps avoid leaving a bad entry in the cache on OOM. But note that
* if we wrapped both proto and parent, we would get infinite recursion
* here (since Object.prototype->parent->proto leads to Object.prototype
* itself).
*/
JSObject *proto = obj->getProto();
if (!wrap(cx, &proto))
return false;
/*
* We hand in the original wrapped object into the wrap hook to allow
* the wrap hook to reason over what wrappers are currently applied
* to the object.
*/
JSObject *wrapper = cx->runtime->wrapObjectCallback(cx, obj, proto, flags);
if (!wrapper)
return false;
wrapper->setProto(proto);
vp->setObject(*wrapper);
if (!crossCompartmentWrappers.put(wrapper->getProxyPrivate(), *vp))
return false;
/*
* Wrappers should really be parented to the wrapped parent of the wrapped
* object, but in that case a wrapped global object would have a NULL
* parent without being a proper global object (JSCLASS_IS_GLOBAL). Instead,
* we parent all wrappers to the global object in their home compartment.
* This loses us some transparency, and is generally very cheesy.
*/
JSObject *global;
if (cx->hasfp()) {
global = cx->fp()->scopeChain().getGlobal();
} else {
global = cx->globalObject;
OBJ_TO_INNER_OBJECT(cx, global);
if (!global)
return false;
//.........这里部分代码省略.........
示例14: switch
JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing,
JSGCTraceKind kind, bool details)
{
const char *name = nullptr; /* silence uninitialized warning */
size_t n;
if (bufsize == 0)
return;
switch (kind) {
case JSTRACE_OBJECT:
{
name = static_cast<JSObject *>(thing)->getClass()->name;
break;
}
case JSTRACE_STRING:
name = ((JSString *)thing)->isDependent()
? "substring"
: "string";
break;
case JSTRACE_SCRIPT:
name = "script";
break;
case JSTRACE_LAZY_SCRIPT:
name = "lazyscript";
break;
case JSTRACE_JITCODE:
name = "jitcode";
break;
case JSTRACE_SHAPE:
name = "shape";
break;
case JSTRACE_BASE_SHAPE:
name = "base_shape";
break;
case JSTRACE_TYPE_OBJECT:
name = "type_object";
break;
}
n = strlen(name);
if (n > bufsize - 1)
n = bufsize - 1;
js_memcpy(buf, name, n + 1);
buf += n;
bufsize -= n;
*buf = '\0';
if (details && bufsize > 2) {
switch (kind) {
case JSTRACE_OBJECT:
{
JSObject *obj = (JSObject *)thing;
if (obj->is<JSFunction>()) {
JSFunction *fun = &obj->as<JSFunction>();
if (fun->displayAtom()) {
*buf++ = ' ';
bufsize--;
PutEscapedString(buf, bufsize, fun->displayAtom(), 0);
}
} else if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE) {
JS_snprintf(buf, bufsize, " %p", obj->getPrivate());
} else {
JS_snprintf(buf, bufsize, " <no private>");
}
break;
}
case JSTRACE_STRING:
{
*buf++ = ' ';
bufsize--;
JSString *str = (JSString *)thing;
if (str->isLinear()) {
bool willFit = str->length() + strlen("<length > ") +
CountDecimalDigits(str->length()) < bufsize;
n = JS_snprintf(buf, bufsize, "<length %d%s> ",
(int)str->length(),
willFit ? "" : " (truncated)");
buf += n;
bufsize -= n;
PutEscapedString(buf, bufsize, &str->asLinear(), 0);
}
else
JS_snprintf(buf, bufsize, "<rope: length %d>", (int)str->length());
break;
}
case JSTRACE_SCRIPT:
{
//.........这里部分代码省略.........
示例15: switch
static void
StatsCellCallback(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKind,
size_t thingSize)
{
IteratorClosure *closure = static_cast<IteratorClosure *>(data);
RuntimeStats *rtStats = closure->rtStats;
CompartmentStats *cStats = rtStats->currCompartmentStats;
switch (traceKind) {
case JSTRACE_OBJECT:
{
JSObject *obj = static_cast<JSObject *>(thing);
if (obj->isFunction()) {
cStats->gcHeapObjectsFunction += thingSize;
} else if (obj->isDenseArray()) {
cStats->gcHeapObjectsDenseArray += thingSize;
} else if (obj->isSlowArray()) {
cStats->gcHeapObjectsSlowArray += thingSize;
} else if (obj->isCrossCompartmentWrapper()) {
cStats->gcHeapObjectsCrossCompartmentWrapper += thingSize;
} else {
cStats->gcHeapObjectsOrdinary += thingSize;
}
size_t slotsSize, elementsSize, argumentsDataSize, regExpStaticsSize,
propertyIteratorDataSize;
obj->sizeOfExcludingThis(rtStats->mallocSizeOf, &slotsSize, &elementsSize,
&argumentsDataSize, ®ExpStaticsSize,
&propertyIteratorDataSize);
cStats->objectsExtraSlots += slotsSize;
cStats->objectsExtraElements += elementsSize;
cStats->objectsExtraArgumentsData += argumentsDataSize;
cStats->objectsExtraRegExpStatics += regExpStaticsSize;
cStats->objectsExtraPropertyIteratorData += propertyIteratorDataSize;
if (ObjectPrivateVisitor *opv = closure->opv) {
js::Class *clazz = js::GetObjectClass(obj);
if (clazz->flags & JSCLASS_HAS_PRIVATE &&
clazz->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS)
{
cStats->objectsExtraPrivate += opv->sizeOfIncludingThis(GetObjectPrivate(obj));
}
}
break;
}
case JSTRACE_STRING:
{
JSString *str = static_cast<JSString *>(thing);
size_t strSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf);
// If we can't grow hugeStrings, let's just call this string non-huge.
// We're probably about to OOM anyway.
if (strSize >= HugeStringInfo::MinSize() && cStats->hugeStrings.growBy(1)) {
cStats->gcHeapStringsNormal += thingSize;
HugeStringInfo &info = cStats->hugeStrings.back();
info.length = str->length();
info.size = strSize;
PutEscapedString(info.buffer, sizeof(info.buffer), &str->asLinear(), 0);
} else if (str->isShort()) {
MOZ_ASSERT(strSize == 0);
cStats->gcHeapStringsShort += thingSize;
} else {
cStats->gcHeapStringsNormal += thingSize;
cStats->stringCharsNonHuge += strSize;
}
break;
}
case JSTRACE_SHAPE:
{
Shape *shape = static_cast<Shape*>(thing);
size_t propTableSize, kidsSize;
shape->sizeOfExcludingThis(rtStats->mallocSizeOf, &propTableSize, &kidsSize);
if (shape->inDictionary()) {
cStats->gcHeapShapesDict += thingSize;
cStats->shapesExtraDictTables += propTableSize;
JS_ASSERT(kidsSize == 0);
} else {
if (shape->base()->getObjectParent() == shape->compartment()->maybeGlobal()) {
cStats->gcHeapShapesTreeGlobalParented += thingSize;
} else {
cStats->gcHeapShapesTreeNonGlobalParented += thingSize;
}
cStats->shapesExtraTreeTables += propTableSize;
cStats->shapesExtraTreeShapeKids += kidsSize;
}
break;
}
case JSTRACE_BASE_SHAPE:
{
cStats->gcHeapShapesBase += thingSize;
break;
}
case JSTRACE_SCRIPT:
{
JSScript *script = static_cast<JSScript *>(thing);
cStats->gcHeapScripts += thingSize;
cStats->scriptData += script->sizeOfData(rtStats->mallocSizeOf);
#ifdef JS_METHODJIT
cStats->jaegerData += script->sizeOfJitScripts(rtStats->mallocSizeOf);
# ifdef JS_ION
cStats->ionData += ion::MemoryUsed(script, rtStats->mallocSizeOf);
//.........这里部分代码省略.........