Skip to content

Commit

Permalink
Bug 1591515 - Avoid delazification in js::FunctionToString r=tcampbell
Browse files Browse the repository at this point in the history
Differential Revision: https://phabricator.services.mozilla.com/D56625

--HG--
extra : moz-landing-system : lando
  • Loading branch information
evilpie committed Dec 11, 2019
1 parent 475cde4 commit 9e9249a
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 30 deletions.
8 changes: 4 additions & 4 deletions js/src/gc/Zone.h
Expand Up @@ -74,10 +74,10 @@ class MOZ_NON_TEMPORARY_CLASS ExternalStringCache {

class MOZ_NON_TEMPORARY_CLASS FunctionToStringCache {
struct Entry {
JSScript* script;
BaseScript* script;
JSString* string;

void set(JSScript* scriptArg, JSString* stringArg) {
void set(BaseScript* scriptArg, JSString* stringArg) {
script = scriptArg;
string = stringArg;
}
Expand All @@ -92,8 +92,8 @@ class MOZ_NON_TEMPORARY_CLASS FunctionToStringCache {
FunctionToStringCache() { purge(); }
void purge() { mozilla::PodArrayZero(entries_); }

MOZ_ALWAYS_INLINE JSString* lookup(JSScript* script) const;
MOZ_ALWAYS_INLINE void put(JSScript* script, JSString* string);
MOZ_ALWAYS_INLINE JSString* lookup(BaseScript* script) const;
MOZ_ALWAYS_INLINE void put(BaseScript* script, JSString* string);
};

} // namespace js
Expand Down
34 changes: 12 additions & 22 deletions js/src/vm/JSFunction.cpp
Expand Up @@ -822,7 +822,7 @@ static JSObject* CreateFunctionPrototype(JSContext* cx, JSProtoKey key) {
gc::AllocKind::FUNCTION, SingletonObject);
}

JSString* js::FunctionToStringCache::lookup(JSScript* script) const {
JSString* js::FunctionToStringCache::lookup(BaseScript* script) const {
for (size_t i = 0; i < NumEntries; i++) {
if (entries_[i].script == script) {
return entries_[i].string;
Expand All @@ -831,7 +831,7 @@ JSString* js::FunctionToStringCache::lookup(JSScript* script) const {
return nullptr;
}

void js::FunctionToStringCache::put(JSScript* script, JSString* string) {
void js::FunctionToStringCache::put(BaseScript* script, JSString* string) {
for (size_t i = NumEntries - 1; i > 0; i--) {
entries_[i] = entries_[i - 1];
}
Expand All @@ -841,48 +841,38 @@ void js::FunctionToStringCache::put(JSScript* script, JSString* string) {

JSString* js::FunctionToString(JSContext* cx, HandleFunction fun,
bool isToSource) {
if (fun->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, fun)) {
return nullptr;
}

if (IsAsmJSModule(fun)) {
return AsmJSModuleToString(cx, fun, isToSource);
}
if (IsAsmJSFunction(fun)) {
return AsmJSFunctionToString(cx, fun);
}

RootedScript script(cx);
if (fun->hasScript()) {
script = fun->nonLazyScript();
}

// Default class constructors are self-hosted, but have their source
// objects overridden to refer to the span of the class statement or
// expression. Non-default class constructors are never self-hosted. So,
// all class constructors always have source.
bool haveSource = fun->isInterpreted() &&
(fun->isClassConstructor() || !fun->isSelfHostedBuiltin());
// Self-hosted built-ins should not expose their source code.
bool haveSource = fun->isInterpreted() && !fun->isSelfHostedBuiltin();

// If we're in toSource mode, put parentheses around lambda functions so
// that eval returns lambda, not function statement.
bool addParentheses =
haveSource && isToSource && (fun->isLambda() && !fun->isArrow());

if (haveSource) {
if (!ScriptSource::loadSource(cx, script->scriptSource(), &haveSource)) {
if (!ScriptSource::loadSource(cx, fun->baseScript()->scriptSource(),
&haveSource)) {
return nullptr;
}
}

// Fast path for the common case, to avoid StringBuffer overhead.
if (!addParentheses && haveSource) {
FunctionToStringCache& cache = cx->zone()->functionToStringCache();
if (JSString* str = cache.lookup(script)) {
if (JSString* str = cache.lookup(fun->baseScript())) {
return str;
}

size_t start = script->toStringStart(), end = script->toStringEnd();
BaseScript* script = fun->baseScript();
size_t start = script->toStringStart();
size_t end = script->toStringEnd();
JSString* str =
(end - start <= ScriptSource::SourceDeflateLimit)
? script->scriptSource()->substring(cx, start, end)
Expand All @@ -891,7 +881,7 @@ JSString* js::FunctionToString(JSContext* cx, HandleFunction fun,
return nullptr;
}

cache.put(script, str);
cache.put(fun->baseScript(), str);
return str;
}

Expand All @@ -903,7 +893,7 @@ JSString* js::FunctionToString(JSContext* cx, HandleFunction fun,
}

if (haveSource) {
if (!script->appendSourceDataForToString(cx, out)) {
if (!fun->baseScript()->appendSourceDataForToString(cx, out)) {
return nullptr;
}
} else if (!isToSource) {
Expand Down
2 changes: 1 addition & 1 deletion js/src/vm/JSScript.cpp
Expand Up @@ -1992,7 +1992,7 @@ JSLinearString* JSScript::sourceData(JSContext* cx, HandleScript script) {
script->sourceEnd());
}

bool JSScript::appendSourceDataForToString(JSContext* cx, StringBuffer& buf) {
bool BaseScript::appendSourceDataForToString(JSContext* cx, StringBuffer& buf) {
MOZ_ASSERT(scriptSource()->hasSourceText());
return scriptSource()->appendSubstring(cx, buf, toStringStart(),
toStringEnd());
Expand Down
6 changes: 3 additions & 3 deletions js/src/vm/JSScript.h
Expand Up @@ -1900,6 +1900,9 @@ class BaseScript : public gc::TenuredCell {
uint32_t toStringStart() const { return toStringStart_; }
uint32_t toStringEnd() const { return toStringEnd_; }

MOZ_MUST_USE bool appendSourceDataForToString(JSContext* cx,
js::StringBuffer& buf);

#if defined(JS_BUILD_BINAST)
// Set the position of the function in the source code.
//
Expand Down Expand Up @@ -2882,9 +2885,6 @@ class JSScript : public js::BaseScript {

static JSLinearString* sourceData(JSContext* cx, JS::HandleScript script);

MOZ_MUST_USE bool appendSourceDataForToString(JSContext* cx,
js::StringBuffer& buf);

void setDefaultClassConstructorSpan(js::ScriptSourceObject* sourceObject,
uint32_t start, uint32_t end,
unsigned line, unsigned column);
Expand Down

0 comments on commit 9e9249a

Please sign in to comment.