OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 90 } |
91 | 91 |
92 void AstString::Internalize(Isolate* isolate) { | 92 void AstString::Internalize(Isolate* isolate) { |
93 if (IsRawStringBits::decode(bit_field_)) { | 93 if (IsRawStringBits::decode(bit_field_)) { |
94 return reinterpret_cast<AstRawString*>(this)->Internalize(isolate); | 94 return reinterpret_cast<AstRawString*>(this)->Internalize(isolate); |
95 } | 95 } |
96 return reinterpret_cast<AstConsString*>(this)->Internalize(isolate); | 96 return reinterpret_cast<AstConsString*>(this)->Internalize(isolate); |
97 } | 97 } |
98 | 98 |
99 void AstRawString::Internalize(Isolate* isolate) { | 99 void AstRawString::Internalize(Isolate* isolate) { |
100 // Skip over already internalized strings. | |
101 if (!string_.is_null()) return; | |
102 if (literal_bytes_.length() == 0) { | 100 if (literal_bytes_.length() == 0) { |
103 string_ = isolate->factory()->empty_string(); | 101 set_string(isolate->factory()->empty_string()); |
104 } else { | 102 } else { |
105 AstRawStringInternalizationKey key(this); | 103 AstRawStringInternalizationKey key(this); |
106 string_ = StringTable::LookupKey(isolate, &key); | 104 set_string(StringTable::LookupKey(isolate, &key)); |
107 } | 105 } |
108 } | 106 } |
109 | 107 |
110 bool AstRawString::AsArrayIndex(uint32_t* index) const { | 108 bool AstRawString::AsArrayIndex(uint32_t* index) const { |
111 // The StringHasher will set up the hash in such a way that we can use it to | 109 // The StringHasher will set up the hash in such a way that we can use it to |
112 // figure out whether the string is convertible to an array index. | 110 // figure out whether the string is convertible to an array index. |
113 if ((hash_ & Name::kIsNotArrayIndexMask) != 0) return false; | 111 if ((hash_ & Name::kIsNotArrayIndexMask) != 0) return false; |
114 if (length() <= Name::kMaxCachedArrayIndexLength) { | 112 if (length() <= Name::kMaxCachedArrayIndexLength) { |
115 *index = Name::ArrayIndexValueBits::decode(hash_); | 113 *index = Name::ArrayIndexValueBits::decode(hash_); |
116 } else { | 114 } else { |
117 OneByteStringStream stream(literal_bytes_); | 115 OneByteStringStream stream(literal_bytes_); |
118 CHECK(StringToArrayIndex(&stream, index)); | 116 CHECK(StringToArrayIndex(&stream, index)); |
119 } | 117 } |
120 return true; | 118 return true; |
121 } | 119 } |
122 | 120 |
123 bool AstRawString::IsOneByteEqualTo(const char* data) const { | 121 bool AstRawString::IsOneByteEqualTo(const char* data) const { |
124 int length = static_cast<int>(strlen(data)); | 122 int length = static_cast<int>(strlen(data)); |
125 if (is_one_byte() && literal_bytes_.length() == length) { | 123 if (is_one_byte() && literal_bytes_.length() == length) { |
126 const char* token = reinterpret_cast<const char*>(literal_bytes_.start()); | 124 const char* token = reinterpret_cast<const char*>(literal_bytes_.start()); |
127 return !strncmp(token, data, length); | 125 return !strncmp(token, data, length); |
128 } | 126 } |
129 return false; | 127 return false; |
130 } | 128 } |
131 | 129 |
132 | 130 |
133 void AstConsString::Internalize(Isolate* isolate) { | 131 void AstConsString::Internalize(Isolate* isolate) { |
134 // AstRawStrings are internalized before AstConsStrings so left and right are | 132 // AstRawStrings are internalized before AstConsStrings so left and right are |
135 // already internalized. | 133 // already internalized. |
136 string_ = isolate->factory() | 134 set_string(isolate->factory() |
137 ->NewConsString(left_->string(), right_->string()) | 135 ->NewConsString(left_->string(), right_->string()) |
138 .ToHandleChecked(); | 136 .ToHandleChecked()); |
139 } | 137 } |
140 | 138 |
141 bool AstValue::IsPropertyName() const { | 139 bool AstValue::IsPropertyName() const { |
142 if (type_ == STRING) { | 140 if (type_ == STRING) { |
143 uint32_t index; | 141 uint32_t index; |
144 return !string_->AsArrayIndex(&index); | 142 return !string_->AsArrayIndex(&index); |
145 } | 143 } |
146 return false; | 144 return false; |
147 } | 145 } |
148 | 146 |
(...skipping 23 matching lines...) Expand all Loading... |
172 return false; | 170 return false; |
173 } | 171 } |
174 UNREACHABLE(); | 172 UNREACHABLE(); |
175 return false; | 173 return false; |
176 } | 174 } |
177 | 175 |
178 | 176 |
179 void AstValue::Internalize(Isolate* isolate) { | 177 void AstValue::Internalize(Isolate* isolate) { |
180 switch (type_) { | 178 switch (type_) { |
181 case STRING: | 179 case STRING: |
182 DCHECK(string_ != NULL); | 180 DCHECK_NOT_NULL(string_); |
183 // Strings are already internalized. | 181 // Strings are already internalized. |
184 DCHECK(!string_->string().is_null()); | 182 DCHECK(!string_->string().is_null()); |
185 break; | 183 break; |
186 case SYMBOL: | 184 case SYMBOL: |
187 if (symbol_name_[0] == 'i') { | 185 if (symbol_name_[0] == 'i') { |
188 DCHECK_EQ(0, strcmp(symbol_name_, "iterator_symbol")); | 186 DCHECK_EQ(0, strcmp(symbol_name_, "iterator_symbol")); |
189 value_ = isolate->factory()->iterator_symbol(); | 187 set_value(isolate->factory()->iterator_symbol()); |
190 } else if (strcmp(symbol_name_, "hasInstance_symbol") == 0) { | 188 } else if (strcmp(symbol_name_, "hasInstance_symbol") == 0) { |
191 value_ = isolate->factory()->has_instance_symbol(); | 189 set_value(isolate->factory()->has_instance_symbol()); |
192 } else { | 190 } else { |
193 DCHECK_EQ(0, strcmp(symbol_name_, "home_object_symbol")); | 191 DCHECK_EQ(0, strcmp(symbol_name_, "home_object_symbol")); |
194 value_ = isolate->factory()->home_object_symbol(); | 192 set_value(isolate->factory()->home_object_symbol()); |
195 } | 193 } |
196 break; | 194 break; |
197 case NUMBER_WITH_DOT: | 195 case NUMBER_WITH_DOT: |
198 case NUMBER: | 196 case NUMBER: |
199 value_ = isolate->factory()->NewNumber(number_, TENURED); | 197 set_value(isolate->factory()->NewNumber(number_, TENURED)); |
200 break; | 198 break; |
201 case SMI_WITH_DOT: | 199 case SMI_WITH_DOT: |
202 case SMI: | 200 case SMI: |
203 value_ = handle(Smi::FromInt(smi_), isolate); | 201 set_value(handle(Smi::FromInt(smi_), isolate)); |
204 break; | 202 break; |
205 case BOOLEAN: | 203 case BOOLEAN: |
206 if (bool_) { | 204 if (bool_) { |
207 value_ = isolate->factory()->true_value(); | 205 set_value(isolate->factory()->true_value()); |
208 } else { | 206 } else { |
209 value_ = isolate->factory()->false_value(); | 207 set_value(isolate->factory()->false_value()); |
210 } | 208 } |
211 break; | 209 break; |
212 case NULL_TYPE: | 210 case NULL_TYPE: |
213 value_ = isolate->factory()->null_value(); | 211 set_value(isolate->factory()->null_value()); |
214 break; | 212 break; |
215 case THE_HOLE: | 213 case THE_HOLE: |
216 value_ = isolate->factory()->the_hole_value(); | 214 set_value(isolate->factory()->the_hole_value()); |
217 break; | 215 break; |
218 case UNDEFINED: | 216 case UNDEFINED: |
219 value_ = isolate->factory()->undefined_value(); | 217 set_value(isolate->factory()->undefined_value()); |
220 break; | 218 break; |
221 } | 219 } |
222 } | 220 } |
223 | 221 |
224 | 222 |
225 AstRawString* AstValueFactory::GetOneByteStringInternal( | 223 AstRawString* AstValueFactory::GetOneByteStringInternal( |
226 Vector<const uint8_t> literal) { | 224 Vector<const uint8_t> literal) { |
227 uint32_t hash = StringHasher::HashSequentialString<uint8_t>( | 225 uint32_t hash = StringHasher::HashSequentialString<uint8_t>( |
228 literal.start(), literal.length(), hash_seed_); | 226 literal.start(), literal.length(), hash_seed_); |
229 return GetString(hash, true, literal); | 227 return GetString(hash, true, literal); |
(...skipping 21 matching lines...) Expand all Loading... |
251 return result; | 249 return result; |
252 } | 250 } |
253 | 251 |
254 | 252 |
255 const AstConsString* AstValueFactory::NewConsString( | 253 const AstConsString* AstValueFactory::NewConsString( |
256 const AstString* left, const AstString* right) { | 254 const AstString* left, const AstString* right) { |
257 // This Vector will be valid as long as the Collector is alive (meaning that | 255 // This Vector will be valid as long as the Collector is alive (meaning that |
258 // the AstRawString will not be moved). | 256 // the AstRawString will not be moved). |
259 AstConsString* new_string = new (zone_) AstConsString(left, right); | 257 AstConsString* new_string = new (zone_) AstConsString(left, right); |
260 CHECK(new_string != nullptr); | 258 CHECK(new_string != nullptr); |
261 AddConsString(new_string); | 259 AddString(new_string); |
262 return new_string; | 260 return new_string; |
263 } | 261 } |
264 | 262 |
265 const AstRawString* AstValueFactory::ConcatStrings(const AstRawString* left, | 263 const AstRawString* AstValueFactory::ConcatStrings(const AstRawString* left, |
266 const AstRawString* right) { | 264 const AstRawString* right) { |
267 int left_length = left->length(); | 265 int left_length = left->length(); |
268 int right_length = right->length(); | 266 int right_length = right->length(); |
269 const unsigned char* left_data = left->raw_data(); | 267 const unsigned char* left_data = left->raw_data(); |
270 const unsigned char* right_data = right->raw_data(); | 268 const unsigned char* right_data = right->raw_data(); |
271 if (left->is_one_byte() && right->is_one_byte()) { | 269 if (left->is_one_byte() && right->is_one_byte()) { |
(...skipping 18 matching lines...) Expand all Loading... |
290 } else { | 288 } else { |
291 memcpy(buffer + left_length, right_data, 2 * right_length); | 289 memcpy(buffer + left_length, right_data, 2 * right_length); |
292 } | 290 } |
293 Vector<const uint16_t> literal(buffer, left_length + right_length); | 291 Vector<const uint16_t> literal(buffer, left_length + right_length); |
294 return GetTwoByteStringInternal(literal); | 292 return GetTwoByteStringInternal(literal); |
295 } | 293 } |
296 } | 294 } |
297 | 295 |
298 void AstValueFactory::Internalize(Isolate* isolate) { | 296 void AstValueFactory::Internalize(Isolate* isolate) { |
299 // Strings need to be internalized before values, because values refer to | 297 // Strings need to be internalized before values, because values refer to |
300 // strings. Internalize flat strings before cons strings since cons strings | 298 // strings. |
301 // may point to flat strings. | 299 for (AstString* current = strings_; current != nullptr;) { |
302 for (base::CustomMatcherHashMap::Entry* entry = string_table_.Start(); | 300 AstString* next = current->next(); |
303 entry != nullptr; entry = string_table_.Next(entry)) { | |
304 reinterpret_cast<AstRawString*>(entry->key)->Internalize(isolate); | |
305 } | |
306 | |
307 for (AstConsString* current = cons_strings_; current != nullptr;) { | |
308 AstConsString* next = current->next(); | |
309 current->Internalize(isolate); | 301 current->Internalize(isolate); |
310 current = next; | 302 current = next; |
311 } | 303 } |
312 | 304 |
313 for (AstValue* current = values_; current != nullptr;) { | 305 for (AstValue* current = values_; current != nullptr;) { |
314 AstValue* next = current->next(); | 306 AstValue* next = current->next(); |
315 current->Internalize(isolate); | 307 current->Internalize(isolate); |
316 current = next; | 308 current = next; |
317 } | 309 } |
318 ResetConsStrings(); | 310 ResetStrings(); |
319 values_ = nullptr; | 311 values_ = nullptr; |
320 } | 312 } |
321 | 313 |
322 | 314 |
323 const AstValue* AstValueFactory::NewString(const AstRawString* string) { | 315 const AstValue* AstValueFactory::NewString(const AstRawString* string) { |
324 AstValue* value = new (zone_) AstValue(string); | 316 AstValue* value = new (zone_) AstValue(string); |
325 CHECK(string != nullptr); | 317 CHECK_NOT_NULL(string); |
326 return AddValue(value); | 318 return AddValue(value); |
327 } | 319 } |
328 | 320 |
329 | 321 |
330 const AstValue* AstValueFactory::NewSymbol(const char* name) { | 322 const AstValue* AstValueFactory::NewSymbol(const char* name) { |
331 AstValue* value = new (zone_) AstValue(name); | 323 AstValue* value = new (zone_) AstValue(name); |
332 return AddValue(value); | 324 return AddValue(value); |
333 } | 325 } |
334 | 326 |
335 | 327 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 // return this AstRawString. | 377 // return this AstRawString. |
386 AstRawString key(is_one_byte, literal_bytes, hash); | 378 AstRawString key(is_one_byte, literal_bytes, hash); |
387 base::HashMap::Entry* entry = string_table_.LookupOrInsert(&key, hash); | 379 base::HashMap::Entry* entry = string_table_.LookupOrInsert(&key, hash); |
388 if (entry->value == NULL) { | 380 if (entry->value == NULL) { |
389 // Copy literal contents for later comparison. | 381 // Copy literal contents for later comparison. |
390 int length = literal_bytes.length(); | 382 int length = literal_bytes.length(); |
391 byte* new_literal_bytes = zone_->NewArray<byte>(length); | 383 byte* new_literal_bytes = zone_->NewArray<byte>(length); |
392 memcpy(new_literal_bytes, literal_bytes.start(), length); | 384 memcpy(new_literal_bytes, literal_bytes.start(), length); |
393 AstRawString* new_string = new (zone_) AstRawString( | 385 AstRawString* new_string = new (zone_) AstRawString( |
394 is_one_byte, Vector<const byte>(new_literal_bytes, length), hash); | 386 is_one_byte, Vector<const byte>(new_literal_bytes, length), hash); |
395 CHECK(new_string != nullptr); | 387 CHECK_NOT_NULL(new_string); |
| 388 AddString(new_string); |
396 entry->key = new_string; | 389 entry->key = new_string; |
397 entry->value = reinterpret_cast<void*>(1); | 390 entry->value = reinterpret_cast<void*>(1); |
398 } | 391 } |
399 return reinterpret_cast<AstRawString*>(entry->key); | 392 return reinterpret_cast<AstRawString*>(entry->key); |
400 } | 393 } |
401 | 394 |
402 | 395 |
403 bool AstValueFactory::AstRawStringCompare(void* a, void* b) { | 396 bool AstValueFactory::AstRawStringCompare(void* a, void* b) { |
404 const AstRawString* lhs = static_cast<AstRawString*>(a); | 397 const AstRawString* lhs = static_cast<AstRawString*>(a); |
405 const AstRawString* rhs = static_cast<AstRawString*>(b); | 398 const AstRawString* rhs = static_cast<AstRawString*>(b); |
(...skipping 19 matching lines...) Expand all Loading... |
425 length) == 0; | 418 length) == 0; |
426 } else { | 419 } else { |
427 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l), | 420 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l), |
428 reinterpret_cast<const uint16_t*>(r), | 421 reinterpret_cast<const uint16_t*>(r), |
429 length) == 0; | 422 length) == 0; |
430 } | 423 } |
431 } | 424 } |
432 } | 425 } |
433 } // namespace internal | 426 } // namespace internal |
434 } // namespace v8 | 427 } // namespace v8 |
OLD | NEW |