Implement compress CompressibleStrings on GC reclaim end event

* Compress CompressibleStrings on GC reclaim end event
  - if there is reference about data of CompressibleString on stack, we should give up compressing.
    we don't need to search heap space because I redesigned StringView
    (we should not store string buffer data on heap without owner)
* Redesign StringView
  - Don't save string buffer address as its member. because buffer of CompressibleString can be deleted
  - If we don't save string buffer address on StringView, parser performance may dropped.
    becuase parser access string data a lot.
    so I introduce ParserStringView. it saves buffer address. we should ParserStringView on parser only.
    we can save string buffer address while parsing. because GC is disabled while parsing.

* Enable CompressibleString always
* Implement cache of RegExpOptionStrings
* Implement finding system locale function on RuntimeICUBinder avoiding call uloc_getDefault.

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2019-12-26 10:20:10 +09:00 committed by Hyukwoo Park
commit caa0fbc3fe
32 changed files with 1020 additions and 394 deletions

View file

@ -110,20 +110,23 @@ void* RegExpObject::operator new(size_t size)
static String* escapeSlashInPattern(String* patternStr)
{
if (patternStr->length() == 0)
if (patternStr->length() == 0) {
return patternStr;
}
size_t len = patternStr->length();
auto accessData = patternStr->bufferAccessData();
const size_t& len = accessData.length;
bool slashFlag = false;
size_t i, start = 0;
StringBuilder builder;
while (true) {
for (i = 0; start + i < len; i++) {
if (UNLIKELY(patternStr->charAt(start + i) == '/') && i > 0) {
if (UNLIKELY(accessData.charAt(start + i) == '/') && i > 0) {
size_t backSlashCount = 0;
size_t s = start + i - 1;
while (true) {
if (patternStr->charAt(s) == '\\') {
if (accessData.charAt(s) == '\\') {
backSlashCount++;
if (s == 0) {
break;
@ -153,10 +156,11 @@ static String* escapeSlashInPattern(String* patternStr)
break;
}
}
if (!slashFlag)
if (!slashFlag) {
return patternStr;
else
} else {
return builder.finalize();
}
}
void RegExpObject::internalInit(ExecutionState& state, String* source)
@ -224,8 +228,9 @@ void RegExpObject::parseOption(ExecutionState& state, const String* optionString
{
this->m_option = RegExpObject::Option::None;
for (size_t i = 0; i < optionString->length(); i++) {
switch (optionString->charAt(i)) {
auto bufferAccessData = optionString->bufferAccessData();
for (size_t i = 0; i < bufferAccessData.length; i++) {
switch (bufferAccessData.charAt(i)) {
case 'g':
if (this->m_option & Option::Global)
ErrorObject::throwBuiltinError(state, ErrorObject::SyntaxError, "RegExp has multiple 'g' flags");