Modified: trunk/Source/_javascript_Core/ChangeLog (243868 => 243869)
--- trunk/Source/_javascript_Core/ChangeLog 2019-04-04 14:16:05 UTC (rev 243868)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-04-04 15:41:07 UTC (rev 243869)
@@ -1,5 +1,58 @@
2019-04-04 Tadeu Zagallo <[email protected]>
+ Cache bytecode for jsc.cpp helpers and fix CachedStringImpl
+ https://bugs.webkit.org/show_bug.cgi?id=196409
+
+ Reviewed by Saam Barati.
+
+ Some of the helpers in jsc.cpp, such as `functionRunString`, were stll using
+ using `makeSource` instead of `jscSource`, which does not use the ShellSourceProvider
+ and therefore does not write the bytecode cache to disk.
+
+ Changing that revealed a bug in bytecode cache. The Encoder keeps a mapping
+ of pointers to offsets of already cached objects, in order to avoid caching
+ the same object twice. Similarly, the Decoder keeps a mapping from offsets
+ to pointers, in order to avoid creating multiple objects in memory for the
+ same cached object. The following was happening:
+ 1) A StringImpl* S was cached as CachedPtr<CachedStringImpl> at offset O. We add
+ an entry in the Encoder mapping that S has already been encoded at O.
+ 2) We cache StringImpl* S again, but now as CachedPtr<CachedUniquedStringImpl>.
+ We find an entry in the Encoder mapping for S, and return the offset O. However,
+ the object cached at O is a CachedPtr<CachedStringImpl> (i.e. not Uniqued).
+
+ 3) When decoding, there are 2 possibilities:
+ 3.1) We find S for the first time through a CachedPtr<CachedStringImpl>. In
+ this case, everything works as expected since we add an entry in the decoder
+ mapping from the offset O to the decoded StringImpl* S. The next time we find
+ S through the uniqued version, we'll return the already decoded S.
+ 3.2) We find S through a CachedPtr<CachedUniquedStringImpl>. Now we have a
+ problem, since the CachedPtr has the offset of a CachedStringImpl (not uniqued),
+ which has a different shape and we crash.
+
+ We fix this by making CachedStringImpl and CachedUniquedStringImpl share the
+ same implementation. Since it doesn't matter whether a string is uniqued for
+ encoding, and we always decode strings as uniqued either way, they can be used
+ interchangeably.
+
+ * jsc.cpp:
+ (functionRunString):
+ (functionLoadString):
+ (functionDollarAgentStart):
+ (functionCheckModuleSyntax):
+ (runInteractive):
+ * runtime/CachedTypes.cpp:
+ (JSC::CachedUniquedStringImplBase::decode const):
+ (JSC::CachedFunctionExecutable::rareData const):
+ (JSC::CachedCodeBlock::rareData const):
+ (JSC::CachedFunctionExecutable::encode):
+ (JSC::CachedCodeBlock<CodeBlockType>::encode):
+ (JSC::CachedUniquedStringImpl::encode): Deleted.
+ (JSC::CachedUniquedStringImpl::decode const): Deleted.
+ (JSC::CachedStringImpl::encode): Deleted.
+ (JSC::CachedStringImpl::decode const): Deleted.
+
+2019-04-04 Tadeu Zagallo <[email protected]>
+
UnlinkedCodeBlock constructor from cache should initialize m_didOptimize
https://bugs.webkit.org/show_bug.cgi?id=196396
Modified: trunk/Source/_javascript_Core/jsc.cpp (243868 => 243869)
--- trunk/Source/_javascript_Core/jsc.cpp 2019-04-04 14:16:05 UTC (rev 243868)
+++ trunk/Source/_javascript_Core/jsc.cpp 2019-04-04 15:41:07 UTC (rev 243869)
@@ -1459,7 +1459,7 @@
vm, Identifier::fromString(globalObject->globalExec(), "arguments"), array);
NakedPtr<Exception> exception;
- evaluate(globalObject->globalExec(), makeSource(source, exec->callerSourceOrigin()), JSValue(), exception);
+ evaluate(globalObject->globalExec(), jscSource(source, exec->callerSourceOrigin()), JSValue(), exception);
if (exception) {
scope.throwException(globalObject->globalExec(), exception);
@@ -1499,7 +1499,7 @@
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
NakedPtr<Exception> evaluationException;
- JSValue result = evaluate(globalObject->globalExec(), makeSource(sourceCode, exec->callerSourceOrigin()), JSValue(), evaluationException);
+ JSValue result = evaluate(globalObject->globalExec(), jscSource(sourceCode, exec->callerSourceOrigin()), JSValue(), evaluationException);
if (evaluationException)
throwException(exec, scope, evaluationException);
return JSValue::encode(result);
@@ -1843,7 +1843,7 @@
NakedPtr<Exception> evaluationException;
JSValue result;
- result = evaluate(globalObject->globalExec(), makeSource(sourceCode, SourceOrigin("worker"_s)), JSValue(), evaluationException);
+ result = evaluate(globalObject->globalExec(), jscSource(sourceCode, SourceOrigin("worker"_s)), JSValue(), evaluationException);
if (evaluationException)
result = evaluationException->value();
checkException(globalObject->globalExec(), globalObject, true, evaluationException, result, commandLine, success);
@@ -2185,7 +2185,7 @@
stopWatch.start();
ParserError error;
- bool validSyntax = checkModuleSyntax(exec, makeSource(source, { }, URL(), TextPosition(), SourceProviderSourceType::Module), error);
+ bool validSyntax = checkModuleSyntax(exec, jscSource(source, { }, URL(), TextPosition(), SourceProviderSourceType::Module), error);
RETURN_IF_EXCEPTION(scope, encodedJSValue());
stopWatch.stop();
@@ -2624,7 +2624,7 @@
break;
source = source + String::fromUTF8(line);
source = source + '\n';
- checkSyntax(vm, makeSource(source, sourceOrigin), error);
+ checkSyntax(vm, jscSource(source, sourceOrigin), error);
if (!line[0]) {
free(line);
break;
@@ -2640,7 +2640,7 @@
NakedPtr<Exception> evaluationException;
- JSValue returnValue = evaluate(globalObject->globalExec(), makeSource(source, sourceOrigin), JSValue(), evaluationException);
+ JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(source, sourceOrigin), JSValue(), evaluationException);
#else
printf("%s", interactivePrompt);
Vector<char, 256> line;
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (243868 => 243869)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-04-04 14:16:05 UTC (rev 243868)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-04-04 15:41:07 UTC (rev 243869)
@@ -575,7 +575,8 @@
CachedVector<CachedPair<Key, Value>> m_entries;
};
-class CachedUniquedStringImpl : public VariableLengthObject<UniquedStringImpl> {
+template<typename T>
+class CachedUniquedStringImplBase : public VariableLengthObject<T> {
public:
void encode(Encoder& encoder, const StringImpl& string)
{
@@ -631,8 +632,8 @@
}
if (m_is8Bit)
- return create(this->buffer<LChar>());
- return create(this->buffer<UChar>());
+ return create(this->template buffer<LChar>());
+ return create(this->template buffer<UChar>());
}
private:
@@ -642,22 +643,9 @@
unsigned m_length;
};
-class CachedStringImpl : public VariableLengthObject<StringImpl> {
-public:
- void encode(Encoder& encoder, const StringImpl& impl)
- {
- m_uniquedStringImpl.encode(encoder, impl);
- }
+class CachedUniquedStringImpl : public CachedUniquedStringImplBase<UniquedStringImpl> { };
+class CachedStringImpl : public CachedUniquedStringImplBase<StringImpl> { };
- StringImpl* decode(Decoder& decoder) const
- {
- return m_uniquedStringImpl.decode(decoder);
- }
-
-private:
- CachedUniquedStringImpl m_uniquedStringImpl;
-};
-
class CachedString : public VariableLengthObject<String> {
public:
void encode(Encoder& encoder, const String& string)
@@ -1572,7 +1560,7 @@
Identifier ecmaName(Decoder& decoder) const { return m_ecmaName.decode(decoder); }
Identifier inferredName(Decoder& decoder) const { return m_inferredName.decode(decoder); }
- UnlinkedFunctionExecutable::RareData* rareData(Decoder& decoder) const { return m_rareData.decodeAsPtr(decoder); }
+ UnlinkedFunctionExecutable::RareData* rareData(Decoder& decoder) const { return m_rareData.decode(decoder); }
const CachedWriteBarrier<CachedFunctionCodeBlock, UnlinkedFunctionCodeBlock>& unlinkedCodeBlockForCall() const { return m_unlinkedCodeBlockForCall; }
const CachedWriteBarrier<CachedFunctionCodeBlock, UnlinkedFunctionCodeBlock>& unlinkedCodeBlockForConstruct() const { return m_unlinkedCodeBlockForConstruct; }
@@ -1602,7 +1590,7 @@
unsigned m_superBinding : 1;
unsigned m_derivedContextType: 2;
- CachedOptional<CachedFunctionExecutableRareData> m_rareData;
+ CachedPtr<CachedFunctionExecutableRareData> m_rareData;
CachedIdentifier m_name;
CachedIdentifier m_ecmaName;
@@ -1655,7 +1643,7 @@
SourceParseMode parseMode() const { return m_parseMode; }
unsigned codeType() const { return m_codeType; }
- UnlinkedCodeBlock::RareData* rareData(Decoder& decoder) const { return m_rareData.decodeAsPtr(decoder); }
+ UnlinkedCodeBlock::RareData* rareData(Decoder& decoder) const { return m_rareData.decode(decoder); }
private:
VirtualRegister m_thisRegister;
@@ -1690,7 +1678,7 @@
CachedMetadataTable m_metadata;
- CachedOptional<CachedCodeBlockRareData> m_rareData;
+ CachedPtr<CachedCodeBlockRareData> m_rareData;
CachedString m_sourceURLDirective;
CachedString m_sourceMappingURLDirective;
@@ -1955,7 +1943,7 @@
m_superBinding = executable.m_superBinding;
m_derivedContextType = executable.m_derivedContextType;
- m_rareData.encode(encoder, executable.m_rareData);
+ m_rareData.encode(encoder, executable.m_rareData.get());
m_name.encode(encoder, executable.name());
m_ecmaName.encode(encoder, executable.ecmaName());
@@ -2060,7 +2048,7 @@
m_linkTimeConstants[i] = codeBlock.m_linkTimeConstants[i];
m_metadata.encode(encoder, codeBlock.m_metadata.get());
- m_rareData.encode(encoder, codeBlock.m_rareData);
+ m_rareData.encode(encoder, codeBlock.m_rareData.get());
m_sourceURLDirective.encode(encoder, codeBlock.m_sourceURLDirective.impl());
m_sourceMappingURLDirective.encode(encoder, codeBlock.m_sourceURLDirective.impl());