Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(854)

Unified Diff: src/heap.cc

Issue 11593007: Replace the use CharacterStreams in Heap::AllocateSymbolInternal and String::ComputeHash (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: issues addressed Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 4cc47d0405a2dac3fad5b79c8fe9a692b46751af..e35f08f8430b5ea99cdd0aa3c73409f40e2b22fa 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3302,8 +3302,8 @@ static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString(
Heap* heap,
- uint32_t c1,
- uint32_t c2) {
+ uint16_t c1,
+ uint16_t c2) {
String* symbol;
// Numeric strings have a different hash algorithm not known by
// LookupTwoCharsSymbolIfExists, so we skip this step for such strings.
@@ -3352,8 +3352,8 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) {
// dictionary. Check whether we already have the string in the symbol
// table to prevent creation of many unneccesary strings.
if (length == 2) {
- unsigned c1 = first->Get(0);
- unsigned c2 = second->Get(0);
+ uint16_t c1 = first->Get(0);
+ uint16_t c2 = second->Get(0);
return MakeOrFindTwoCharacterString(this, c1, c2);
}
@@ -3467,8 +3467,8 @@ MaybeObject* Heap::AllocateSubString(String* buffer,
// Optimization for 2-byte strings often used as keys in a decompression
// dictionary. Check whether we already have the string in the symbol
// table to prevent creation of many unneccesary strings.
- unsigned c1 = buffer->Get(start);
- unsigned c2 = buffer->Get(start + 1);
+ uint16_t c1 = buffer->Get(start);
+ uint16_t c2 = buffer->Get(start + 1);
return MakeOrFindTwoCharacterString(this, c1, c2);
}
@@ -4623,27 +4623,77 @@ Map* Heap::SymbolMapForString(String* string) {
}
-MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
- int chars,
- uint32_t hash_field) {
- ASSERT(chars >= 0);
- // Ensure the chars matches the number of characters in the buffer.
- ASSERT(static_cast<unsigned>(chars) == buffer->Utf16Length());
- // Determine whether the string is ASCII.
- bool is_ascii = true;
- while (buffer->has_more()) {
- if (buffer->GetNext() > unibrow::Utf8::kMaxOneByteChar) {
- is_ascii = false;
- break;
+template<typename T>
+struct AllocateInternalSymbolHelper {
+ static void WriteOneByteData(T t, char* chars, int len);
+ static void WriteTwoByteData(T t, uint16_t* chars, int len);
+};
+
+
+template<>
+struct AllocateInternalSymbolHelper< Vector<const char> > {
+ static inline void WriteOneByteData(Vector<const char> vector,
+ char* chars,
+ int len) {
+ // Only works for ascii.
+ ASSERT(vector.length() == len);
+ memcpy(chars, vector.start(), len);
+ }
+
+ static inline void WriteTwoByteData(Vector<const char> vector,
+ uint16_t* chars,
+ int len) {
+ const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
+ unsigned stream_length = vector.length();
+ while (stream_length != 0) {
+ unsigned consumed = 0;
+ uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
+ ASSERT(c != unibrow::Utf8::kBadChar);
+ ASSERT(consumed <= stream_length);
+ stream_length -= consumed;
+ stream += consumed;
+ if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
+ len -= 2;
+ if (len < 0) break;
+ *chars++ = unibrow::Utf16::LeadSurrogate(c);
+ *chars++ = unibrow::Utf16::TrailSurrogate(c);
+ } else {
+ len -= 1;
+ if (len < 0) break;
+ *chars++ = c;
+ }
}
+ ASSERT(stream_length == 0);
+ ASSERT(len == 0);
}
- buffer->Rewind();
+};
+
+template<>
+struct AllocateInternalSymbolHelper<String*> {
+ static inline void WriteOneByteData(String* s, char* chars, int len) {
+ ASSERT(s->length() == len);
+ String::WriteToFlat(s, chars, 0, len);
+ }
+
+ static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
+ ASSERT(s->length() == len);
+ String::WriteToFlat(s, chars, 0, len);
+ }
+};
+
+
+template<bool is_one_byte, typename T>
+MaybeObject* Heap::AllocateInternalSymbol(T t,
+ int chars,
+ uint32_t hash_field) {
+ typedef AllocateInternalSymbolHelper<T> H;
+ ASSERT(chars >= 0);
// Compute map and object size.
int size;
Map* map;
- if (is_ascii) {
+ if (is_one_byte) {
if (chars > SeqOneByteString::kMaxLength) {
return Failure::OutOfMemoryException();
}
@@ -4673,21 +4723,26 @@ MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
ASSERT_EQ(size, answer->Size());
- // Fill in the characters.
- int i = 0;
- while (i < chars) {
- uint32_t character = buffer->GetNext();
- if (character > unibrow::Utf16::kMaxNonSurrogateCharCode) {
- answer->Set(i++, unibrow::Utf16::LeadSurrogate(character));
- answer->Set(i++, unibrow::Utf16::TrailSurrogate(character));
- } else {
- answer->Set(i++, character);
- }
+ if (is_one_byte) {
+ H::WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
+ } else {
+ H::WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
}
return answer;
}
+// Need explicit instantiations.
+template
+MaybeObject* Heap::AllocateInternalSymbol<true>(String*, int, uint32_t);
+template
+MaybeObject* Heap::AllocateInternalSymbol<false>(String*, int, uint32_t);
+template
+MaybeObject* Heap::AllocateInternalSymbol<false>(Vector<const char>,
+ int,
+ uint32_t);
+
+
MaybeObject* Heap::AllocateRawOneByteString(int length,
PretenureFlag pretenure) {
if (length < 0 || length > SeqOneByteString::kMaxLength) {
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698