mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Reduce calling count of String::charAt
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
adcd8025b7
commit
c2ef5b9e12
10 changed files with 60 additions and 54 deletions
|
|
@ -344,9 +344,10 @@ static Value stringReplaceFastPathHelper(ExecutionState& state, String* string,
|
|||
{
|
||||
ASSERT(string && replaceString);
|
||||
|
||||
auto replaceStringBad = replaceString->bufferAccessData();
|
||||
bool hasDollar = false;
|
||||
for (size_t i = 0; i < replaceString->length(); i++) {
|
||||
if (replaceString->charAt(i) == '$') {
|
||||
for (size_t i = 0; i < replaceStringBad.length; i++) {
|
||||
if (replaceStringBad.charAt(i) == '$') {
|
||||
hasDollar = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -358,8 +359,7 @@ static Value stringReplaceFastPathHelper(ExecutionState& state, String* string,
|
|||
int32_t matchCount = result.m_matchResults.size();
|
||||
builder.appendSubString(string, 0, result.m_matchResults[0][0].m_start, &state);
|
||||
for (int32_t i = 0; i < matchCount; i++) {
|
||||
String* res = replaceString;
|
||||
builder.appendString(res, &state);
|
||||
builder.appendString(replaceString, &state);
|
||||
if (i < matchCount - 1) {
|
||||
builder.appendSubString(string, result.m_matchResults[i][0].m_end, result.m_matchResults[i + 1][0].m_start, &state);
|
||||
}
|
||||
|
|
@ -370,11 +370,11 @@ static Value stringReplaceFastPathHelper(ExecutionState& state, String* string,
|
|||
int32_t matchCount = result.m_matchResults.size();
|
||||
builder.appendSubString(string, 0, result.m_matchResults[0][0].m_start, &state);
|
||||
for (int32_t i = 0; i < matchCount; i++) {
|
||||
for (unsigned j = 0; j < replaceString->length(); j++) {
|
||||
if (replaceString->charAt(j) == '$' && (j + 1) < replaceString->length()) {
|
||||
char16_t c = replaceString->charAt(j + 1);
|
||||
for (unsigned j = 0; j < replaceStringBad.length; j++) {
|
||||
if (replaceStringBad.charAt(j) == '$' && (j + 1) < replaceStringBad.length) {
|
||||
char16_t c = replaceStringBad.charAt(j + 1);
|
||||
if (c == '$') {
|
||||
builder.appendChar(replaceString->charAt(j), &state);
|
||||
builder.appendChar(replaceStringBad.charAt(j), &state);
|
||||
} else if (c == '&') {
|
||||
builder.appendSubString(string, result.m_matchResults[i][0].m_start, result.m_matchResults[i][0].m_end, &state);
|
||||
} else if (c == '\'') {
|
||||
|
|
@ -384,8 +384,8 @@ static Value stringReplaceFastPathHelper(ExecutionState& state, String* string,
|
|||
} else if ('0' <= c && c <= '9') {
|
||||
size_t idx = c - '0';
|
||||
bool usePeek = false;
|
||||
if (j + 2 < replaceString->length()) {
|
||||
int peek = replaceString->charAt(j + 2) - '0';
|
||||
if (j + 2 < replaceStringBad.length) {
|
||||
int peek = replaceStringBad.charAt(j + 2) - '0';
|
||||
if (0 <= peek && peek <= 9) {
|
||||
idx *= 10;
|
||||
idx += peek;
|
||||
|
|
@ -412,7 +412,7 @@ static Value stringReplaceFastPathHelper(ExecutionState& state, String* string,
|
|||
}
|
||||
j++;
|
||||
} else {
|
||||
builder.appendChar(replaceString->charAt(j), &state);
|
||||
builder.appendChar(replaceStringBad.charAt(j), &state);
|
||||
}
|
||||
}
|
||||
if (i < matchCount - 1) {
|
||||
|
|
@ -717,11 +717,18 @@ static Value builtinStringSplit(ExecutionState& state, Value thisValue, size_t a
|
|||
splitMatchUsingStr = [](String* S, int q, String* R) -> Value {
|
||||
int s = S->length();
|
||||
int r = R->length();
|
||||
if (q + r > s)
|
||||
if (q + r > s) {
|
||||
return Value(false);
|
||||
for (int i = 0; i < r; i++)
|
||||
if (S->charAt(q + i) != R->charAt(i))
|
||||
}
|
||||
|
||||
auto sData = S->bufferAccessData();
|
||||
auto rData = R->bufferAccessData();
|
||||
|
||||
for (int i = 0; i < r; i++) {
|
||||
if (sData.charAt(q + i) != rData.charAt(i)) {
|
||||
return Value(false);
|
||||
}
|
||||
}
|
||||
return Value(q + r);
|
||||
};
|
||||
if (s == 0) {
|
||||
|
|
@ -1410,8 +1417,9 @@ static String* createHTML(ExecutionState& state, Value string, String* tag, Stri
|
|||
// ReturnIfAbrupt(V).
|
||||
// Let escapedV be the String value that is the same as V except that each occurrence of the code unit 0x0022 (QUOTATION MARK) in V has been replaced with the six code unit sequence """.
|
||||
StringBuilder sb;
|
||||
for (size_t i = 0; i < V->length(); i++) {
|
||||
char16_t ch = V->charAt(i);
|
||||
auto vData = V->bufferAccessData();
|
||||
for (size_t i = 0; i < vData.length; i++) {
|
||||
char16_t ch = vData.charAt(i);
|
||||
if (ch == 0x22) {
|
||||
sb.appendString(""");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -220,12 +220,13 @@ ExtendedNodeLOC ByteCodeBlock::computeNodeLOC(StringView src, ExtendedNodeLOC so
|
|||
size_t line = sourceElementStart.line;
|
||||
size_t column = sourceElementStart.column;
|
||||
size_t srcLength = src.length();
|
||||
auto bad = src.bufferAccessData();
|
||||
for (size_t i = 0; i < index && i < srcLength; i++) {
|
||||
char16_t c = src.charAt(i);
|
||||
char16_t c = bad.charAt(i);
|
||||
column++;
|
||||
if (EscargotLexer::isLineTerminator(c)) {
|
||||
// skip \r\n
|
||||
if (c == 13 && (i + 1 < index) && src.charAt(i + 1) == 10) {
|
||||
if (c == 13 && (i + 1 < index) && bad.charAt(i + 1) == 10) {
|
||||
i++;
|
||||
}
|
||||
line++;
|
||||
|
|
|
|||
|
|
@ -487,21 +487,11 @@ ParserStringView Scanner::SmallScannerResult::relatedSource(const ParserStringVi
|
|||
return ParserStringView(source, this->start, this->end);
|
||||
}
|
||||
|
||||
StringView Scanner::SmallScannerResult::relatedSource(const StringView& source) const
|
||||
{
|
||||
return StringView(source, this->start, this->end);
|
||||
}
|
||||
|
||||
ParserStringView Scanner::ScannerResult::relatedSource(const ParserStringView& source)
|
||||
{
|
||||
return ParserStringView(source, this->start, this->end);
|
||||
}
|
||||
|
||||
StringView Scanner::ScannerResult::relatedSource(const StringView& source)
|
||||
{
|
||||
return StringView(source, this->start, this->end);
|
||||
}
|
||||
|
||||
Value Scanner::ScannerResult::valueStringLiteralToValue(Scanner* scannerInstance)
|
||||
{
|
||||
ASSERT(this->type == Token::StringLiteralToken);
|
||||
|
|
|
|||
|
|
@ -533,7 +533,6 @@ public:
|
|||
}
|
||||
|
||||
ParserStringView relatedSource(const ParserStringView& source) const;
|
||||
StringView relatedSource(const StringView& source) const;
|
||||
};
|
||||
|
||||
// ScannerResult should be allocated on the stack by ALLOCA
|
||||
|
|
|
|||
|
|
@ -1476,7 +1476,7 @@ public:
|
|||
param = this->parsePatternWithDefault(builder, params);
|
||||
}
|
||||
for (size_t i = 0; i < params.size(); i++) {
|
||||
AtomicString as(this->escargotContext, params[i].relatedSource(this->scanner->sourceAsNormalView));
|
||||
AtomicString as(this->escargotContext, params[i].relatedSource(this->scanner->source));
|
||||
this->validateParam(options, params[i], as);
|
||||
}
|
||||
options.params.push_back(builder.convertToParameterSyntaxNode(param));
|
||||
|
|
@ -4233,7 +4233,7 @@ public:
|
|||
this->throwUnexpectedToken(this->lookahead);
|
||||
}
|
||||
this->nextToken();
|
||||
left = this->finalize(this->createNode(), builder.createIdentifierNode(AtomicString(this->escargotContext, keywordToken.relatedSource(this->scanner->sourceAsNormalView))));
|
||||
left = this->finalize(this->createNode(), builder.createIdentifierNode(AtomicString(this->escargotContext, keywordToken.relatedSource(this->scanner->source))));
|
||||
init = nullptr;
|
||||
type = statementTypeForIn;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -406,13 +406,14 @@ void StackTraceData::buildStackTrace(Context* context, StringBuilder& builder)
|
|||
size_t preLineSoFar = 0;
|
||||
size_t afterLineSoFar = 0;
|
||||
|
||||
auto bad = src->bufferAccessData();
|
||||
size_t start = loc.index;
|
||||
int64_t idx = (int64_t)start;
|
||||
while (start - idx < preLineMax) {
|
||||
if (idx == 0) {
|
||||
break;
|
||||
}
|
||||
if (src->charAt((size_t)idx) == '\r' || src->charAt((size_t)idx) == '\n') {
|
||||
if (bad.charAt((size_t)idx) == '\r' || bad.charAt((size_t)idx) == '\n') {
|
||||
idx++;
|
||||
break;
|
||||
}
|
||||
|
|
@ -422,27 +423,26 @@ void StackTraceData::buildStackTrace(Context* context, StringBuilder& builder)
|
|||
|
||||
idx = start;
|
||||
while (idx - start < afterLineMax) {
|
||||
if ((size_t)idx == src->length() - 1) {
|
||||
if ((size_t)idx == bad.length - 1) {
|
||||
break;
|
||||
}
|
||||
if (src->charAt((size_t)idx) == '\r' || src->charAt((size_t)idx) == '\n') {
|
||||
if (bad.charAt((size_t)idx) == '\r' || bad.charAt((size_t)idx) == '\n') {
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
afterLineSoFar = idx;
|
||||
|
||||
if (preLineSoFar <= afterLineSoFar && preLineSoFar <= src->length() && afterLineSoFar <= src->length()) {
|
||||
auto subSrc = src->substring(preLineSoFar, afterLineSoFar);
|
||||
if (preLineSoFar <= afterLineSoFar && preLineSoFar <= bad.length && afterLineSoFar <= bad.length) {
|
||||
builder.appendChar('\n');
|
||||
builder.appendString(subSrc);
|
||||
builder.appendSubString(src, preLineSoFar, afterLineSoFar);
|
||||
builder.appendChar('\n');
|
||||
std::string sourceCodePosition;
|
||||
for (size_t i = preLineSoFar; i < start; i++) {
|
||||
sourceCodePosition += " ";
|
||||
}
|
||||
sourceCodePosition += "^";
|
||||
builder.appendString(String::fromUTF8(sourceCodePosition.data(), sourceCodePosition.length()));
|
||||
builder.appendString(String::fromASCII(sourceCodePosition.data(), sourceCodePosition.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
#include "bignum-dtoa.h"
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
MAY_THREAD_LOCAL String* String::emptyString;
|
||||
|
||||
std::vector<std::string> split(const std::string& s, char seperator)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include <string>
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
// A type to hold a single Latin-1 character.
|
||||
typedef unsigned char LChar;
|
||||
|
||||
|
|
@ -416,8 +415,9 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
auto bad = bufferAccessData();
|
||||
for (size_t i = 0; i < srcLen; i++) {
|
||||
if (src[i] != charAt(i)) {
|
||||
if (src[i] != bad.charAt(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,9 +71,10 @@ public:
|
|||
UTF16StringData ret;
|
||||
size_t len = length();
|
||||
ret.resizeWithUninitializedValues(len);
|
||||
auto bad = bufferAccessData();
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ret[i] = charAt(i);
|
||||
ret[i] = bad.charAt(i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
32
third_party/yarr/WTFString.h
vendored
32
third_party/yarr/WTFString.h
vendored
|
|
@ -35,11 +35,13 @@ class String {
|
|||
public:
|
||||
String()
|
||||
: m_impl()
|
||||
, m_implBufferAccessData(Escargot::String::emptyString->bufferAccessData())
|
||||
{
|
||||
}
|
||||
|
||||
String(::Escargot::String* impl)
|
||||
: m_impl(impl)
|
||||
, m_implBufferAccessData(impl->bufferAccessData())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ public:
|
|||
if (isNull()) {
|
||||
return 0;
|
||||
}
|
||||
return m_impl->charAt(idx);
|
||||
return m_implBufferAccessData.charAt(idx);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t length() const
|
||||
|
|
@ -56,7 +58,7 @@ public:
|
|||
if (isNull()) {
|
||||
return 0;
|
||||
}
|
||||
return m_impl->length();
|
||||
return m_implBufferAccessData.length;
|
||||
}
|
||||
|
||||
bool equals(const String& src) const
|
||||
|
|
@ -75,10 +77,10 @@ public:
|
|||
if (isNull()) {
|
||||
return 0;
|
||||
}
|
||||
if (m_impl->is8Bit()) {
|
||||
return StringHasher::computeHashAndMaskTop8Bits(m_impl->characters8(), m_impl->length());
|
||||
if (m_implBufferAccessData.has8BitContent) {
|
||||
return StringHasher::computeHashAndMaskTop8Bits(m_implBufferAccessData.bufferAs8Bit, m_implBufferAccessData.length);
|
||||
} else {
|
||||
return StringHasher::computeHashAndMaskTop8Bits(m_impl->characters16(), m_impl->length());
|
||||
return StringHasher::computeHashAndMaskTop8Bits(m_implBufferAccessData.bufferAs16Bit, m_implBufferAccessData.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,8 +89,13 @@ public:
|
|||
if (isNull()) {
|
||||
return false;
|
||||
}
|
||||
char b[2] = { c, 0x0 };
|
||||
return m_impl->contains(b);
|
||||
|
||||
for (size_t i = 0; i < m_implBufferAccessData.length; i ++) {
|
||||
if (m_implBufferAccessData.charAt(i) == c) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isNull() const
|
||||
|
|
@ -101,7 +108,7 @@ public:
|
|||
if (isNull()) {
|
||||
return true;
|
||||
}
|
||||
return m_impl->is8Bit();
|
||||
return m_implBufferAccessData.has8BitContent;
|
||||
}
|
||||
|
||||
template <typename Any>
|
||||
|
|
@ -111,9 +118,9 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
if (is8Bit()) {
|
||||
return (Any*)m_impl->characters8();
|
||||
return (Any*)m_implBufferAccessData.bufferAs8Bit;
|
||||
} else {
|
||||
return (Any*)m_impl->characters16();
|
||||
return (Any*)m_implBufferAccessData.bufferAs16Bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +129,7 @@ public:
|
|||
if (isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_impl->characters8();
|
||||
return reinterpret_cast<const LChar*>(m_implBufferAccessData.bufferAs8Bit);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE const char16_t* characters16() const
|
||||
|
|
@ -130,7 +137,7 @@ public:
|
|||
if (isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_impl->characters16();
|
||||
return m_implBufferAccessData.bufferAs16Bit;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE::Escargot::String* impl()
|
||||
|
|
@ -149,6 +156,7 @@ public:
|
|||
|
||||
private:
|
||||
Optional<::Escargot::String*> m_impl;
|
||||
::Escargot::StringBufferAccessData m_implBufferAccessData;
|
||||
};
|
||||
|
||||
using StringView = const String&;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue