Implement new config for smaller device

* In small config, we turn off SyntaxChecker for small binary size
* CompressibleString should get VMInstance instead of Context
* If ICU is disabled, we don't need unicode information in yarr
* Remove unused variable in yarr(RegExpJitTables)
* Fix lz4 compile error

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2020-08-05 17:55:27 +09:00 committed by Hyukwoo Park
commit ccdf475f9b
18 changed files with 186 additions and 2741 deletions

View file

@ -85,6 +85,18 @@ IF (${ESCARGOT_OUTPUT} STREQUAL "shared_lib" AND ${ESCARGOT_HOST} STREQUAL "andr
SET (ESCARGOT_LDFLAGS ${ESCARGOT_LDFLAGS} -shared)
ENDIF()
IF (NOT DEFINED ESCARGOT_SMALL_CONFIG)
SET (ESCARGOT_SMALL_CONFIG OFF)
ENDIF()
IF (NOT DEFINED ESCARGOT_GC_SMALL_CONFIG)
SET (ESCARGOT_GC_SMALL_CONFIG OFF)
ENDIF()
IF (${ESCARGOT_SMALL_CONFIG} STREQUAL "ON")
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DESCARGOT_SMALL_CONFIG)
ENDIF()
IF (NOT DEFINED ESCARGOT_LIBICU_SUPPORT)
SET (ESCARGOT_LIBICU_SUPPORT ON)
ENDIF()
@ -132,6 +144,9 @@ IF (${ESCARGOT_HOST} STREQUAL "tizen_obs")
ENDIF()
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DENABLE_COMPRESSIBLE_STRING)
IF (${ESCARGOT_SMALL_CONFIG} STREQUAL "ON")
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DLZ4_MEMORY_USAGE=16 -DLZ4_HEAPMODE=1)
ENDIF()
IF (ESCARGOT_CODE_CACHE)
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DENABLE_CODE_CACHE)

View file

@ -73,6 +73,10 @@ SET (ESCARGOT_SRC_LIST
# GCUTIL
SET (GCUTIL_CFLAGS ${ESCARGOT_GCUTIL_CFLAGS})
IF (${ESCARGOT_GC_SMALL_CONFIG} STREQUAL "ON")
SET (GCUTIL_CFLAGS ${GCUTIL_CFLAGS} -DSMALL_CONFIG)
ENDIF()
IF (${ESCARGOT_OUTPUT} STREQUAL "shared_lib")
SET (GCUTIL_CFLAGS ${GCUTIL_CFLAGS} ${ESCARGOT_CXXFLAGS_SHAREDLIB})
ELSEIF (${ESCARGOT_OUTPUT} STREQUAL "static_lib")

View file

@ -277,24 +277,24 @@ bool StringRef::isCompressibleStringEnabled()
}
#if defined(ENABLE_COMPRESSIBLE_STRING)
StringRef* StringRef::createFromUTF8ToCompressibleString(ContextRef* context, const char* s, size_t len)
StringRef* StringRef::createFromUTF8ToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
{
return toRef(String::fromUTF8ToCompressibleString(toImpl(context), s, len));
return toRef(String::fromUTF8ToCompressibleString(toImpl(instance), s, len));
}
StringRef* StringRef::createFromUTF16ToCompressibleString(ContextRef* context, const char16_t* s, size_t len)
StringRef* StringRef::createFromUTF16ToCompressibleString(VMInstanceRef* instance, const char16_t* s, size_t len)
{
return toRef(new CompressibleString(toImpl(context), s, len));
return toRef(new CompressibleString(toImpl(instance), s, len));
}
StringRef* StringRef::createFromASCIIToCompressibleString(ContextRef* context, const char* s, size_t len)
StringRef* StringRef::createFromASCIIToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
{
return toRef(new CompressibleString(toImpl(context), s, len));
return toRef(new CompressibleString(toImpl(instance), s, len));
}
StringRef* StringRef::createFromLatin1ToCompressibleString(ContextRef* context, const unsigned char* s, size_t len)
StringRef* StringRef::createFromLatin1ToCompressibleString(VMInstanceRef* instance, const unsigned char* s, size_t len)
{
return toRef(new CompressibleString(toImpl(context), s, len));
return toRef(new CompressibleString(toImpl(instance), s, len));
}
void* StringRef::allocateStringDataBufferForCompressibleString(size_t byteLength)
@ -302,32 +302,32 @@ void* StringRef::allocateStringDataBufferForCompressibleString(size_t byteLength
return CompressibleString::allocateStringDataBuffer(byteLength);
}
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr)
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr, size_t byteLength)
{
CompressibleString::deallocateStringDataBuffer(ptr);
CompressibleString::deallocateStringDataBuffer(ptr, byteLength);
}
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(ContextRef* context, void* buffer, size_t stringLen, bool is8Bit)
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(VMInstanceRef* instance, void* buffer, size_t stringLen, bool is8Bit)
{
return toRef(new CompressibleString(toImpl(context), buffer, stringLen, is8Bit));
return toRef(new CompressibleString(toImpl(instance), buffer, stringLen, is8Bit));
}
#else
StringRef* StringRef::createFromUTF8ToCompressibleString(ContextRef* context, const char* s, size_t len)
StringRef* StringRef::createFromUTF8ToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
{
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
}
StringRef* StringRef::createFromASCIIToCompressibleString(ContextRef* context, const char* s, size_t len)
StringRef* StringRef::createFromASCIIToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
{
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
}
StringRef* StringRef::createFromLatin1ToCompressibleString(ContextRef* context, const unsigned char* s, size_t len)
StringRef* StringRef::createFromLatin1ToCompressibleString(VMInstanceRef* instance, const unsigned char* s, size_t len)
{
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
RELEASE_ASSERT_NOT_REACHED();
@ -341,13 +341,13 @@ void* StringRef::allocateStringDataBufferForCompressibleString(size_t byteLength
return nullptr;
}
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr)
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr, size_t byteLength)
{
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
RELEASE_ASSERT_NOT_REACHED();
}
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(ContextRef* context, void* buffer, size_t stringLen, bool is8Bit)
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(VMInstanceRef* instance, void* buffer, size_t stringLen, bool is8Bit)
{
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
RELEASE_ASSERT_NOT_REACHED();

View file

@ -808,15 +808,14 @@ public:
static StringRef* createExternalFromUTF16(const char16_t* s, size_t len);
// you can use these functions only if you enabled source compression
// you don't need to use CompressibleString when string is small(~128KB)
static bool isCompressibleStringEnabled();
static StringRef* createFromUTF8ToCompressibleString(ContextRef* context, const char* s, size_t len);
static StringRef* createFromUTF16ToCompressibleString(ContextRef* context, const char16_t* s, size_t len);
static StringRef* createFromASCIIToCompressibleString(ContextRef* context, const char* s, size_t len);
static StringRef* createFromLatin1ToCompressibleString(ContextRef* context, const unsigned char* s, size_t len);
static StringRef* createFromUTF8ToCompressibleString(VMInstanceRef* instance, const char* s, size_t len);
static StringRef* createFromUTF16ToCompressibleString(VMInstanceRef* instance, const char16_t* s, size_t len);
static StringRef* createFromASCIIToCompressibleString(VMInstanceRef* instance, const char* s, size_t len);
static StringRef* createFromLatin1ToCompressibleString(VMInstanceRef* instance, const unsigned char* s, size_t len);
static void* allocateStringDataBufferForCompressibleString(size_t byteLength);
static void deallocateStringDataBufferForCompressibleString(void* ptr);
static StringRef* createFromAlreadyAllocatedBufferToCompressibleString(ContextRef* context, void* buffer, size_t stringLen, bool is8Bit /* is ASCII or Latin1 */);
static void deallocateStringDataBufferForCompressibleString(void* ptr, size_t byteLength);
static StringRef* createFromAlreadyAllocatedBufferToCompressibleString(VMInstanceRef* instance, void* buffer, size_t stringLen, bool is8Bit /* is ASCII or Latin1 */);
static StringRef* emptyString();

View file

@ -508,9 +508,13 @@ public:
SyntaxChecker()
: m_valueStringLiteral()
{
#if defined(ESCARGOT_SMALL_CONFIG)
ASSERT_NOT_REACHED();
#endif
}
bool isNodeGenerator() { return false; }
bool willGenerateByteCode() { return false; }
SyntaxNode createIdentifierNode(const AtomicString& name)
{
return SyntaxNode(ASTNodeType::Identifier, name);
@ -658,11 +662,27 @@ public:
MAKE_STACK_ALLOCATED();
NodeGenerator(ASTAllocator& allocator)
NodeGenerator(ASTAllocator& allocator
#if defined(ESCARGOT_SMALL_CONFIG)
,
bool willGenerateByteCode = true
#endif
)
: m_allocator(allocator)
#if defined(ESCARGOT_SMALL_CONFIG)
, m_willGenerateByteCode(willGenerateByteCode)
#endif
{
}
bool willGenerateByteCode()
{
#if defined(ESCARGOT_SMALL_CONFIG)
return m_willGenerateByteCode;
#else
return true;
#endif
}
bool isNodeGenerator() { return true; }
IdentifierNode* createIdentifierNode(const AtomicString& name)
{
@ -869,6 +889,9 @@ public:
private:
ASTAllocator& m_allocator;
#if defined(ESCARGOT_SMALL_CONFIG)
bool m_willGenerateByteCode;
#endif
};
} // Escargot

View file

@ -57,8 +57,14 @@
#define ASTSentinelNode typename ASTBuilder::ASTSentinelNode
#define ASTNodeList typename ASTBuilder::ASTNodeList
#if defined(ESCARGOT_SMALL_CONFIG)
#define NEW_FUNCTION_AST_BUILDER() NodeGenerator newBuilder(this->allocator, false);
#else
#define NEW_FUNCTION_AST_BUILDER() SyntaxChecker newBuilder;
#endif
#define BEGIN_FUNCTION_SCANNING(name) \
SyntaxChecker newBuilder; \
NEW_FUNCTION_AST_BUILDER() \
auto oldSubCodeBlockIndex = ++this->subCodeBlockIndex; \
auto oldScopeContext = pushScopeContext(name); \
LexicalBlockIndex lexicalBlockIndexBefore = this->lexicalBlockIndex; \
@ -1025,7 +1031,7 @@ public:
ALLOC_TOKEN(token);
this->nextToken(token);
// raw = this->getTokenRaw(token);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
if (token->type == Token::NumericLiteralToken) {
double d = token->valueNumberLiteral(this->scanner);
if (this->context->inLoop || d == 0) {
@ -1050,7 +1056,7 @@ public:
// raw = this->getTokenRaw(token);
{
bool value = token->relatedSource(this->scanner->source) == "true";
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
this->insertNumeralLiteral(Value(value));
}
return this->finalize(node, builder.createLiteralNode(Value(value)));
@ -1065,7 +1071,7 @@ public:
this->nextToken(token);
// token.value = null;
// raw = this->getTokenRaw(token);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
this->insertNumeralLiteral(Value(Value::Null));
}
return this->finalize(node, builder.createLiteralNode(Value(Value::Null)));
@ -1388,7 +1394,7 @@ public:
{
// parseFormalParameters only scans the parameter list of function
// should be invoked only during the global parsing (program)
ASSERT(!builder.isNodeGenerator() && !this->isParsingSingleFunction);
ASSERT(!builder.willGenerateByteCode() && !this->isParsingSingleFunction);
bool oldInParameterParsing = this->context->inParameterParsing;
bool oldInParameterNameParsing = this->context->inParameterNameParsing;
@ -1590,14 +1596,16 @@ public:
{
Value v;
if (builder.isNodeGenerator()) {
if (token->type == Token::NumericLiteralToken) {
double d = token->valueNumberLiteral(this->scanner);
if (this->context->inLoop || d == 0) {
this->insertNumeralLiteral(Value(d));
if (builder.willGenerateByteCode()) {
if (token->type == Token::NumericLiteralToken) {
double d = token->valueNumberLiteral(this->scanner);
if (this->context->inLoop || d == 0) {
this->insertNumeralLiteral(Value(d));
}
v = Value(d);
} else {
v = token->valueStringLiteralToValue(this->scanner);
}
v = Value(d);
} else {
v = token->valueStringLiteralToValue(this->scanner);
}
} else {
if (token->type == Token::StringLiteralToken) {
@ -2272,7 +2280,7 @@ public:
} else if (this->lookahead.type == Token::TemplateToken && this->lookahead.valueTemplate->head) {
ASTNode quasi = this->parseTemplateLiteral(builder, true);
ASTNode convertedNode = builder.convertTaggedTemplateExpressionToCallExpression(quasi, exprNode, this->taggedTemplateExpressionIndex, this->currentScopeContext, escargotContext->staticStrings().raw);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
this->taggedTemplateExpressionIndex++;
}
@ -2343,7 +2351,7 @@ public:
} else if (this->lookahead.type == Token::TemplateToken && this->lookahead.valueTemplate->head) {
ASTNode quasi = this->parseTemplateLiteral(builder, true);
ASTNode convertedNode = builder.convertTaggedTemplateExpressionToCallExpression(quasi, exprNode, this->taggedTemplateExpressionIndex, this->currentScopeContext, escargotContext->staticStrings().raw);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
this->taggedTemplateExpressionIndex++;
}
@ -2973,8 +2981,11 @@ public:
this->parseFunctionSourceElements(newBuilder);
} else {
auto oldNameCallback = this->nameDeclaredCallback;
#if defined(ESCARGOT_SMALL_CONFIG)
this->isolateCoverGrammar(newBuilder, &Parser::parseAssignmentExpression<ASTBuilder, false>);
#else
this->isolateCoverGrammar(newBuilder, &Parser::parseAssignmentExpression<SyntaxChecker, false>);
#endif
this->currentScopeContext->m_bodyEndLOC.index = this->lastMarker.index;
#if !(defined NDEBUG) || defined ESCARGOT_DEBUGGER
@ -4605,7 +4616,7 @@ public:
{
// parseFunctionSourceElements only scans the body of function
// should be invoked only during the global parsing (program)
ASSERT(!builder.isNodeGenerator() && !this->isParsingSingleFunction);
ASSERT(!builder.willGenerateByteCode() && !this->isParsingSingleFunction);
// return empty node because the function body node is never used now
ASTNode result = nullptr;
@ -4722,7 +4733,7 @@ public:
}
}
// in global scope, await is allowed
if (UNLIKELY(isAsync && !builder.isNodeGenerator())) {
if (UNLIKELY(isAsync && !builder.willGenerateByteCode())) {
if (id->asIdentifier()->name().string()->equals("await")) {
this->throwUnexpectedToken(*token, Messages::UnexpectedReserved);
}
@ -4930,7 +4941,7 @@ public:
}
}
// in global scope, await is allowed
if (UNLIKELY(isAsync && !builder.isNodeGenerator())) {
if (UNLIKELY(isAsync && !builder.willGenerateByteCode())) {
if (id->asIdentifier()->name().string()->equals("await")) {
this->throwUnexpectedToken(*token, Messages::UnexpectedReserved);
}
@ -5633,7 +5644,7 @@ public:
// import {bar}
specifiers = this->parseNamedImports(builder);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
for (ASTSentinelNode specifier = specifiers.begin(); specifier != specifiers.end(); specifier = specifier->next()) {
Script::ImportEntry entry;
entry.m_importName = specifier->astNode()->asImportSpecifier()->imported()->name();
@ -5645,7 +5656,7 @@ public:
// import * as foo
specifiers.append(this->allocator, this->parseImportNamespaceSpecifier(builder));
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
Script::ImportEntry entry;
entry.m_importName = this->escargotContext->staticStrings().asciiTable[(unsigned char)'*'];
entry.m_localName = specifiers.back()->astNode()->asImportNamespaceSpecifier()->local()->name();
@ -5655,7 +5666,7 @@ public:
// import foo
specifiers.append(this->allocator, this->parseImportDefaultSpecifier(builder));
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
Script::ImportEntry entry;
entry.m_importName = this->escargotContext->staticStrings().stringDefault;
entry.m_localName = specifiers.back()->astNode()->asImportDefaultSpecifier()->local()->name();
@ -5668,7 +5679,7 @@ public:
// import foo, * as foo
specifiers.append(this->allocator, this->parseImportNamespaceSpecifier(builder));
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
Script::ImportEntry entry;
entry.m_importName = this->escargotContext->staticStrings().asciiTable[(unsigned char)'*'];
entry.m_localName = specifiers.back()->astNode()->asImportNamespaceSpecifier()->local()->name();
@ -5678,7 +5689,7 @@ public:
// import foo, {bar}
auto v = this->parseNamedImports(builder);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
for (ASTSentinelNode n = v.begin(); n != v.end(); n = n->next()) {
Script::ImportEntry entry;
entry.m_importName = n->astNode()->asImportSpecifier()->imported()->name();
@ -5706,7 +5717,7 @@ public:
}
this->consumeSemicolon();
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
for (size_t i = 0; i < importEntrys.size(); i++) {
importEntrys[i].m_moduleRequest = src->asLiteral()->value().asString();
addDeclaredNameIntoContext(importEntrys[i].m_localName, this->lexicalBlockIndex, KeywordKind::ConstKeyword);
@ -5821,7 +5832,7 @@ public:
// export default function () {}
ASTNode declaration = this->parseFunctionDeclaration<ASTBuilder, true>(builder);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
Script::ExportEntry entry;
entry.m_exportName = this->escargotContext->staticStrings().stringDefault;
AtomicString fnName = declaration->asFunctionDeclaration()->functionName();
@ -5835,7 +5846,7 @@ public:
// export default class foo {}
auto classNode = this->parseClassExpression(builder);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
this->addImplicitName(classNode, this->escargotContext->staticStrings().stringDefault);
Script::ExportEntry entry;
@ -5889,7 +5900,7 @@ public:
}
ASTNode src = this->parseModuleSpecifier(builder);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
Script::ExportEntry entry;
entry.m_exportName = this->escargotContext->staticStrings().stringDefault;
entry.m_moduleRequest = src->asLiteral()->value().asString();
@ -5922,7 +5933,7 @@ public:
ASTNode src = this->parseModuleSpecifier(builder);
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
Script::ExportEntry entry;
entry.m_exportName = name;
entry.m_moduleRequest = src->asLiteral()->value().asString();
@ -5941,7 +5952,7 @@ public:
// export var f = 1;
auto oldNameCallback = this->nameDeclaredCallback;
AtomicStringVector declaredNames;
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
this->nameDeclaredCallback = [&declaredNames](AtomicString name, LexicalBlockIndex, KeywordKind, bool) {
for (size_t i = 0; i < declaredNames.size(); i++) {
if (declaredNames[i] == name) {
@ -6013,7 +6024,7 @@ public:
this->consumeSemicolon();
}
if (builder.isNodeGenerator()) {
if (builder.willGenerateByteCode()) {
for (ASTSentinelNode specifier = specifiers.begin(); specifier != specifiers.end(); specifier = specifier->next()) {
Script::ExportEntry entry;
if (seenFrom) {
@ -6237,6 +6248,7 @@ FunctionNode* parseSingleFunction(::Escargot::Context* ctx, InterpretedCodeBlock
NodeGenerator builder(ctx->astAllocator());
parser.trackUsingNames = false;
parser.context->inFunctionBody = true;
parser.context->allowLexicalDeclaration = true;
parser.context->allowSuperCall = true;
parser.context->allowSuperProperty = true;

View file

@ -100,6 +100,13 @@ void ArrayBufferObject::allocateBuffer(ExecutionState& state, size_t bytelength)
void ArrayBufferObject::attachBuffer(ExecutionState& state, void* buffer, size_t bytelength)
{
ASSERT(isDetachedBuffer());
// if buffer is null, the ArrayBuffer object still seems deatched
if (buffer == nullptr) {
ASSERT(bytelength == 0);
buffer = m_context->vmInstance()->platform()->onArrayBufferObjectDataBufferMalloc(m_context, this, 0);
}
m_data = (uint8_t*)buffer;
m_bytelength = bytelength;
}

View file

@ -33,68 +33,68 @@ void* CompressibleString::operator new(size_t size)
static GC_descr descr;
if (!typeInited) {
GC_word obj_bitmap[GC_BITMAP_SIZE(CompressibleString)] = { 0 };
GC_set_bit(obj_bitmap, GC_WORD_OFFSET(CompressibleString, m_context));
GC_set_bit(obj_bitmap, GC_WORD_OFFSET(CompressibleString, m_vmInstance));
descr = GC_make_descriptor(obj_bitmap, GC_WORD_LEN(CompressibleString));
typeInited = true;
}
return GC_MALLOC_EXPLICITLY_TYPED(size, descr);
}
CompressibleString::CompressibleString(Context* context)
CompressibleString::CompressibleString(VMInstance* instance)
: String()
, m_isOwnerMayFreed(false)
, m_isCompressed(false)
, m_context(context)
, m_vmInstance(instance)
, m_lastUsedTickcount(fastTickCount())
{
m_bufferData.hasSpecialImpl = true;
auto& v = context->vmInstance()->compressibleStrings();
auto& v = instance->compressibleStrings();
v.push_back(this);
GC_REGISTER_FINALIZER_NO_ORDER(this, [](void* obj, void*) {
CompressibleString* self = (CompressibleString*)obj;
if (self->isCompressed()) {
self->m_compressedData.~CompressedDataVector();
} else {
deallocateStringDataBuffer(const_cast<void*>(self->m_bufferData.buffer));
deallocateStringDataBuffer(const_cast<void*>(self->m_bufferData.buffer), self->m_bufferData.length * (self->m_bufferData.has8BitContent ? 1 : 2));
}
if (!self->m_isOwnerMayFreed) {
self->m_context->vmInstance()->compressibleStringsUncomressedBufferSize() -= self->decomressedBufferSize();
self->m_vmInstance->compressibleStringsUncomressedBufferSize() -= self->decomressedBufferSize();
auto& v = self->m_context->vmInstance()->compressibleStrings();
auto& v = self->m_vmInstance->compressibleStrings();
v.erase(std::find(v.begin(), v.end(), self));
}
},
nullptr, nullptr, nullptr);
}
CompressibleString::CompressibleString(Context* context, const char* str, size_t len)
: CompressibleString(context)
CompressibleString::CompressibleString(VMInstance* instance, const char* str, size_t len)
: CompressibleString(instance)
{
char* buf = (char*)allocateStringDataBuffer(sizeof(char) * len);
memcpy(buf, str, len);
initBufferAccessData(buf, len, true);
}
CompressibleString::CompressibleString(Context* context, const LChar* str, size_t len)
: CompressibleString(context)
CompressibleString::CompressibleString(VMInstance* instance, const LChar* str, size_t len)
: CompressibleString(instance)
{
char* buf = (char*)allocateStringDataBuffer(sizeof(char) * len);
memcpy(buf, str, len);
initBufferAccessData(buf, len, true);
}
CompressibleString::CompressibleString(Context* context, const char16_t* str, size_t len)
: CompressibleString(context)
CompressibleString::CompressibleString(VMInstance* instance, const char16_t* str, size_t len)
: CompressibleString(instance)
{
char* buf = (char*)allocateStringDataBuffer(sizeof(char) * len * 2);
memcpy(buf, str, len * 2);
initBufferAccessData(buf, len, false);
}
CompressibleString::CompressibleString(Context* context, void* buffer, size_t stringLength, bool is8bit)
: CompressibleString(context)
CompressibleString::CompressibleString(VMInstance* instance, void* buffer, size_t stringLength, bool is8bit)
: CompressibleString(instance)
{
initBufferAccessData(buffer, stringLength, is8bit);
}
@ -105,7 +105,7 @@ void CompressibleString::initBufferAccessData(void* data, size_t len, bool is8bi
m_bufferData.length = len;
m_bufferData.buffer = data;
m_context->vmInstance()->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
m_vmInstance->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
}
UTF8StringDataNonGCStd CompressibleString::toNonGCUTF8StringData(int options) const
@ -138,7 +138,7 @@ void* CompressibleString::allocateStringDataBuffer(size_t byteLength)
return malloc(byteLength);
}
void CompressibleString::deallocateStringDataBuffer(void* ptr)
void CompressibleString::deallocateStringDataBuffer(void* ptr, size_t byteLength)
{
free(ptr);
}
@ -182,9 +182,9 @@ bool CompressibleString::compressWorker(void* callerSP)
#if defined(STACK_GROWS_DOWN)
size_t* start = (size_t*)((size_t)callerSP & ~(sizeof(size_t) - 1));
size_t* end = (size_t*)m_context->vmInstance()->stackStartAddress();
size_t* end = (size_t*)m_vmInstance->stackStartAddress();
#else
size_t* start = (size_t*)m_context->vmInstance()->stackStartAddress();
size_t* start = (size_t*)m_vmInstance->stackStartAddress();
size_t* end = (size_t*)((size_t)callerSP & ~(sizeof(size_t) - 1));
#endif
@ -217,13 +217,22 @@ bool CompressibleString::compressWorker(void* callerSP)
m_compressedData.push_back(std::vector<char>(compBuffer.get(), compBuffer.get() + compressedLength));
}
m_context->vmInstance()->compressibleStringsUncomressedBufferSize() -= decomressedBufferSize();
m_vmInstance->compressibleStringsUncomressedBufferSize() -= decomressedBufferSize();
// immediately free the original string after compression when there is no reference on stack
deallocateStringDataBuffer(const_cast<void*>(m_bufferData.buffer));
deallocateStringDataBuffer(const_cast<void*>(m_bufferData.buffer), m_bufferData.length * (m_bufferData.has8BitContent ? 1 : 2));
m_bufferData.bufferAs8Bit = nullptr;
m_isCompressed = true;
/*
size_t compressedSize = 0;
for (size_t i = 0; i < m_compressedData.size(); i ++) {
compressedSize += m_compressedData[i].size();
}
ESCARGOT_LOG_INFO("CompressibleString::compressWorker %fKB -> %fKB\n", originByteLength / 1024.f, compressedSize / 1024.f);
*/
return true;
}
@ -255,7 +264,7 @@ void CompressibleString::decompressWorker()
m_bufferData.bufferAs8Bit = const_cast<const char*>(dstBuffer);
m_isCompressed = false;
m_context->vmInstance()->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
m_vmInstance->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
}
}

View file

@ -26,21 +26,21 @@
namespace Escargot {
class Context;
class VMInstance;
class CompressibleString : public String {
friend class VMInstance;
public:
// 8bit string constructor
CompressibleString(Context* context, const char* str, size_t len);
CompressibleString(Context* context, const LChar* str, size_t len);
CompressibleString(VMInstance* instance, const char* str, size_t len);
CompressibleString(VMInstance* instance, const LChar* str, size_t len);
// 16bit string constructor
CompressibleString(Context* context, const char16_t* str, size_t len);
CompressibleString(VMInstance* instance, const char16_t* str, size_t len);
// from already allocated buffer
CompressibleString(Context* context, void* buffer, size_t stringLength, bool is8bit);
CompressibleString(VMInstance* instance, void* buffer, size_t stringLength, bool is8bit);
virtual bool isCompressibleString() override
{
@ -80,13 +80,13 @@ public:
void operator delete[](void*) = delete;
static void* allocateStringDataBuffer(size_t byteLength);
static void deallocateStringDataBuffer(void* ptr);
static void deallocateStringDataBuffer(void* ptr, size_t byteLength);
bool compress();
void decompress();
private:
CompressibleString(Context* context);
CompressibleString(VMInstance* instance);
void initBufferAccessData(void* data, size_t len, bool is8bit);
@ -106,7 +106,7 @@ private:
bool m_isOwnerMayFreed;
bool m_isCompressed;
Context* m_context;
VMInstance* m_vmInstance;
uint64_t m_lastUsedTickcount;
typedef std::vector<std::vector<char>> CompressedDataVector;
CompressedDataVector m_compressedData;

View file

@ -637,13 +637,13 @@ String* String::fromUTF8(const char* src, size_t len)
}
#if defined(ENABLE_COMPRESSIBLE_STRING)
String* String::fromUTF8ToCompressibleString(Context* context, const char* src, size_t len)
String* String::fromUTF8ToCompressibleString(VMInstance* instance, const char* src, size_t len)
{
if (isAllASCII(src, len)) {
return new CompressibleString(context, src, len);
return new CompressibleString(instance, src, len);
} else {
auto s = utf8StringToUTF16StringNonGC(src, len);
return new CompressibleString(context, s.data(), s.length());
return new CompressibleString(instance, s.data(), s.length());
}
}
#endif

View file

@ -76,7 +76,7 @@ class Latin1String;
class UTF16String;
class RopeString;
class StringView;
class Context;
class VMInstance;
class StringWriteOption {
public:
@ -281,7 +281,7 @@ public:
}
static String* fromUTF8(const char* src, size_t len);
#if defined(ENABLE_COMPRESSIBLE_STRING)
static String* fromUTF8ToCompressibleString(Context* context, const char* src, size_t len);
static String* fromUTF8ToCompressibleString(VMInstance* instance, const char* src, size_t len);
#endif
size_t length() const

View file

@ -482,6 +482,7 @@ void VMInstance::enterIdleMode()
GC_gcollect_and_unmap();
#if defined(ENABLE_COMPRESSIBLE_STRING)
// ESCARGOT_LOG_INFO("compressibleStringsUncomressedBufferSize before %lfKB\n", m_compressibleStringsUncomressedBufferSize/1024.f);
auto& currentAllocatedCompressibleStrings = compressibleStrings();
const size_t& currentAllocatedCompressibleStringsCount = currentAllocatedCompressibleStrings.size();
@ -490,6 +491,7 @@ void VMInstance::enterIdleMode()
currentAllocatedCompressibleStrings[i]->compress();
}
}
// ESCARGOT_LOG_INFO("compressibleStringsUncomressedBufferSize after %lfKB\n", m_compressibleStringsUncomressedBufferSize/1024.f);
#endif

View file

@ -178,9 +178,9 @@ static OptionalRef<StringRef> builtinHelperFileRead(OptionalRef<ExecutionStateRe
if (StringRef::isCompressibleStringEnabled()) {
if (state) {
if (hasNonLatin1Content) {
src = StringRef::createFromUTF8ToCompressibleString(state->context(), utf8Str.data(), utf8Str.length());
src = StringRef::createFromUTF8ToCompressibleString(state->context()->vmInstance(), utf8Str.data(), utf8Str.length());
} else {
src = StringRef::createFromLatin1ToCompressibleString(state->context(), str.data(), str.length());
src = StringRef::createFromLatin1ToCompressibleString(state->context()->vmInstance(), str.data(), str.length());
}
} else {
if (hasNonLatin1Content) {

View file

@ -179,9 +179,9 @@ static OptionalRef<StringRef> builtinHelperFileRead(OptionalRef<ExecutionStateRe
if (StringRef::isCompressibleStringEnabled()) {
if (state) {
if (hasNonLatin1Content) {
src = StringRef::createFromUTF8ToCompressibleString(state->context(), utf8Str.data(), utf8Str.length());
src = StringRef::createFromUTF8ToCompressibleString(state->context()->vmInstance(), utf8Str.data(), utf8Str.length());
} else {
src = StringRef::createFromLatin1ToCompressibleString(state->context(), str.data(), str.length());
src = StringRef::createFromLatin1ToCompressibleString(state->context()->vmInstance(), str.data(), str.length());
}
} else {
if (hasNonLatin1Content) {

View file

@ -1385,7 +1385,7 @@ int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutp
{
int result;
#if (LZ4_HEAPMODE)
LZ4_stream_t* ctxPtr = ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
LZ4_stream_t* ctxPtr = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
if (ctxPtr == NULL)
return 0;
#else

File diff suppressed because it is too large Load diff

View file

@ -68,16 +68,7 @@ public:
// they may have an optional m_table for faster lookups (which must match the
// specified matches and ranges)
CharacterClass()
: m_table(0)
, m_tableInverted(false)
, m_hasNonBMPCharacters(false)
, m_anyCharacter(false)
{
}
CharacterClass(const char* table, bool inverted)
: m_table(table)
, m_tableInverted(inverted)
, m_hasNonBMPCharacters(false)
: m_hasNonBMPCharacters(false)
, m_anyCharacter(false)
{
}
@ -86,8 +77,6 @@ public:
, m_ranges(ranges)
, m_matchesUnicode(matchesUnicode)
, m_rangesUnicode(rangesUnicode)
, m_table(0)
, m_tableInverted(false)
, m_hasNonBMPCharacters(false)
, m_anyCharacter(false)
{
@ -98,8 +87,6 @@ public:
Vector<UChar32> m_matchesUnicode;
Vector<CharacterRange> m_rangesUnicode;
const char* m_table;
bool m_tableInverted : 1;
bool m_hasNonBMPCharacters : 1;
bool m_anyCharacter : 1;
};

View file

@ -60,10 +60,13 @@ struct HashTable {
}
};
#if defined(ENABLE_ICU)
#include "UnicodePatternTables.h"
#endif
Optional<BuiltInCharacterClassID> unicodeMatchPropertyValue(WTF::String unicodePropertyName, WTF::String unicodePropertyValue)
{
#if defined(ENABLE_ICU)
int propertyIndex = -1;
if (unicodePropertyName == "Script" || unicodePropertyName == "sc")
@ -77,10 +80,14 @@ Optional<BuiltInCharacterClassID> unicodeMatchPropertyValue(WTF::String unicodeP
return nullptr;
return Optional<BuiltInCharacterClassID>(static_cast<BuiltInCharacterClassID>(static_cast<int>(BuiltInCharacterClassID::BaseUnicodePropertyID) + propertyIndex));
#else
return nullptr;
#endif
}
Optional<BuiltInCharacterClassID> unicodeMatchProperty(WTF::String unicodePropertyValue)
{
#if defined(ENABLE_ICU)
int propertyIndex = -1;
propertyIndex = binaryPropertyHashTable.entry(unicodePropertyValue);
@ -91,13 +98,21 @@ Optional<BuiltInCharacterClassID> unicodeMatchProperty(WTF::String unicodeProper
return nullptr;
return Optional<BuiltInCharacterClassID>(static_cast<BuiltInCharacterClassID>(static_cast<int>(BuiltInCharacterClassID::BaseUnicodePropertyID) + propertyIndex));
#else
return nullptr;
#endif
}
std::unique_ptr<CharacterClass> createUnicodeCharacterClassFor(BuiltInCharacterClassID unicodeClassID)
{
#if defined(ENABLE_ICU)
unsigned unicodePropertyIndex = static_cast<unsigned>(unicodeClassID) - static_cast<unsigned>(BuiltInCharacterClassID::BaseUnicodePropertyID);
return createFunctions[unicodePropertyIndex]();
#else
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
#endif
}
}
} // namespace JSC::Yarr