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 if (!string_.is_null()) return; | |
101 if (literal_bytes_.length() == 0) { | 100 if (literal_bytes_.length() == 0) { |
102 string_ = isolate->factory()->empty_string(); | 101 string_ = isolate->factory()->empty_string(); |
103 } else { | 102 } else { |
104 AstRawStringInternalizationKey key(this); | 103 AstRawStringInternalizationKey key(this); |
105 string_ = StringTable::LookupKey(isolate, &key); | 104 string_ = StringTable::LookupKey(isolate, &key); |
106 } | 105 } |
107 } | 106 } |
108 | 107 |
109 bool AstRawString::AsArrayIndex(uint32_t* index, | 108 bool AstRawString::AsArrayIndex(uint32_t* index) const { |
110 HandleDereferenceMode deref_mode) const { | 109 // The StringHasher will set up the hash in such a way that we can use it to |
111 if (deref_mode == HandleDereferenceMode::kAllowed && !string_.is_null()) | 110 // figure out whether the string is convertible to an array index. |
112 return string_->AsArrayIndex(index); | 111 if ((hash_ & Name::kIsNotArrayIndexMask) != 0) return false; |
113 if (!is_one_byte() || literal_bytes_.length() == 0 || | 112 if (length() <= Name::kMaxCachedArrayIndexLength) { |
114 literal_bytes_.length() > String::kMaxArrayIndexSize) | 113 *index = Name::ArrayIndexValueBits::decode(hash_); |
115 return false; | 114 } else { |
116 OneByteStringStream stream(literal_bytes_); | 115 OneByteStringStream stream(literal_bytes_); |
117 return StringToArrayIndex(&stream, index); | 116 CHECK(StringToArrayIndex(&stream, index)); |
| 117 } |
| 118 return true; |
118 } | 119 } |
119 | 120 |
120 | |
121 bool AstRawString::IsOneByteEqualTo(const char* data) const { | 121 bool AstRawString::IsOneByteEqualTo(const char* data) const { |
122 int length = static_cast<int>(strlen(data)); | 122 int length = static_cast<int>(strlen(data)); |
123 if (is_one_byte() && literal_bytes_.length() == length) { | 123 if (is_one_byte() && literal_bytes_.length() == length) { |
124 const char* token = reinterpret_cast<const char*>(literal_bytes_.start()); | 124 const char* token = reinterpret_cast<const char*>(literal_bytes_.start()); |
125 return !strncmp(token, data, length); | 125 return !strncmp(token, data, length); |
126 } | 126 } |
127 return false; | 127 return false; |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 void AstConsString::Internalize(Isolate* isolate) { | 131 void AstConsString::Internalize(Isolate* isolate) { |
132 // AstRawStrings are internalized before AstConsStrings so left and right are | 132 // AstRawStrings are internalized before AstConsStrings so left and right are |
133 // already internalized. | 133 // already internalized. |
134 string_ = isolate->factory() | 134 string_ = isolate->factory() |
135 ->NewConsString(left_->string(), right_->string()) | 135 ->NewConsString(left_->string(), right_->string()) |
136 .ToHandleChecked(); | 136 .ToHandleChecked(); |
137 } | 137 } |
138 | 138 |
139 bool AstValue::IsPropertyName(HandleDereferenceMode deref_mode) const { | 139 bool AstValue::IsPropertyName() const { |
140 if (type_ == STRING) { | 140 if (type_ == STRING) { |
141 uint32_t index; | 141 uint32_t index; |
142 return !string_->AsArrayIndex(&index, deref_mode); | 142 return !string_->AsArrayIndex(&index); |
143 } | 143 } |
144 return false; | 144 return false; |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 bool AstValue::BooleanValue() const { | 148 bool AstValue::BooleanValue() const { |
149 switch (type_) { | 149 switch (type_) { |
150 case STRING: | 150 case STRING: |
151 DCHECK(string_ != NULL); | 151 DCHECK(string_ != NULL); |
152 return !string_->IsEmpty(); | 152 return !string_->IsEmpty(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 DisallowHeapAllocation no_gc; | 244 DisallowHeapAllocation no_gc; |
245 String::FlatContent content = literal->GetFlatContent(); | 245 String::FlatContent content = literal->GetFlatContent(); |
246 if (content.IsOneByte()) { | 246 if (content.IsOneByte()) { |
247 result = GetOneByteStringInternal(content.ToOneByteVector()); | 247 result = GetOneByteStringInternal(content.ToOneByteVector()); |
248 } else { | 248 } else { |
249 DCHECK(content.IsTwoByte()); | 249 DCHECK(content.IsTwoByte()); |
250 result = GetTwoByteStringInternal(content.ToUC16Vector()); | 250 result = GetTwoByteStringInternal(content.ToUC16Vector()); |
251 } | 251 } |
252 } | 252 } |
253 isolate_ = saved_isolate; | 253 isolate_ = saved_isolate; |
254 if (isolate_) result->Internalize(isolate_); | 254 if (strings_ != nullptr && isolate_) { |
| 255 // Only the string we are creating is uninternalized at this point. |
| 256 DCHECK_EQ(result, strings_); |
| 257 DCHECK_NULL(strings_->next()); |
| 258 result->Internalize(isolate_); |
| 259 ResetStrings(); |
| 260 } |
255 return result; | 261 return result; |
256 } | 262 } |
257 | 263 |
258 | 264 |
259 const AstConsString* AstValueFactory::NewConsString( | 265 const AstConsString* AstValueFactory::NewConsString( |
260 const AstString* left, const AstString* right) { | 266 const AstString* left, const AstString* right) { |
261 // This Vector will be valid as long as the Collector is alive (meaning that | 267 // This Vector will be valid as long as the Collector is alive (meaning that |
262 // the AstRawString will not be moved). | 268 // the AstRawString will not be moved). |
263 AstConsString* new_string = new (zone_) AstConsString(left, right); | 269 AstConsString* new_string = new (zone_) AstConsString(left, right); |
264 CHECK(new_string != nullptr); | 270 CHECK(new_string != nullptr); |
265 strings_.Add(new_string); | 271 AddString(new_string); |
266 if (isolate_) { | |
267 new_string->Internalize(isolate_); | |
268 } | |
269 return new_string; | 272 return new_string; |
270 } | 273 } |
271 | 274 |
272 | 275 |
273 void AstValueFactory::Internalize(Isolate* isolate) { | 276 void AstValueFactory::Internalize(Isolate* isolate) { |
274 if (isolate_) { | 277 if (isolate_) { |
| 278 DCHECK_NULL(strings_); |
| 279 DCHECK_NULL(values_); |
275 // Everything is already internalized. | 280 // Everything is already internalized. |
276 return; | 281 return; |
277 } | 282 } |
278 | 283 |
279 // Strings need to be internalized before values, because values refer to | 284 // Strings need to be internalized before values, because values refer to |
280 // strings. | 285 // strings. |
281 for (int i = 0; i < strings_.length(); ++i) { | 286 for (AstString* current = strings_; current != nullptr;) { |
282 strings_[i]->Internalize(isolate); | 287 AstString* next = current->next(); |
| 288 current->Internalize(isolate); |
| 289 current = next; |
283 } | 290 } |
284 for (int i = 0; i < values_.length(); ++i) { | 291 for (AstValue* current = values_; current != nullptr;) { |
285 values_[i]->Internalize(isolate); | 292 AstValue* next = current->next(); |
| 293 current->Internalize(isolate); |
| 294 current = next; |
286 } | 295 } |
287 isolate_ = isolate; | 296 isolate_ = isolate; |
| 297 ResetStrings(); |
| 298 values_ = nullptr; |
288 } | 299 } |
289 | 300 |
290 | 301 |
291 const AstValue* AstValueFactory::NewString(const AstRawString* string) { | 302 const AstValue* AstValueFactory::NewString(const AstRawString* string) { |
292 AstValue* value = new (zone_) AstValue(string); | 303 AstValue* value = new (zone_) AstValue(string); |
293 CHECK(string != nullptr); | 304 CHECK(string != nullptr); |
294 if (isolate_) { | 305 return AddValue(value); |
295 value->Internalize(isolate_); | |
296 } | |
297 values_.Add(value); | |
298 return value; | |
299 } | 306 } |
300 | 307 |
301 | 308 |
302 const AstValue* AstValueFactory::NewSymbol(const char* name) { | 309 const AstValue* AstValueFactory::NewSymbol(const char* name) { |
303 AstValue* value = new (zone_) AstValue(name); | 310 AstValue* value = new (zone_) AstValue(name); |
304 if (isolate_) { | 311 return AddValue(value); |
305 value->Internalize(isolate_); | |
306 } | |
307 values_.Add(value); | |
308 return value; | |
309 } | 312 } |
310 | 313 |
311 | 314 |
312 const AstValue* AstValueFactory::NewNumber(double number, bool with_dot) { | 315 const AstValue* AstValueFactory::NewNumber(double number, bool with_dot) { |
313 AstValue* value = new (zone_) AstValue(number, with_dot); | 316 AstValue* value = new (zone_) AstValue(number, with_dot); |
314 if (isolate_) { | 317 return AddValue(value); |
315 value->Internalize(isolate_); | |
316 } | |
317 values_.Add(value); | |
318 return value; | |
319 } | 318 } |
320 | 319 |
321 | 320 |
322 const AstValue* AstValueFactory::NewSmi(int number) { | 321 const AstValue* AstValueFactory::NewSmi(int number) { |
323 AstValue* value = | 322 AstValue* value = |
324 new (zone_) AstValue(AstValue::SMI, number); | 323 new (zone_) AstValue(AstValue::SMI, number); |
325 if (isolate_) { | 324 return AddValue(value); |
326 value->Internalize(isolate_); | |
327 } | |
328 values_.Add(value); | |
329 return value; | |
330 } | 325 } |
331 | 326 |
332 | 327 #define GENERATE_VALUE_GETTER(value, initializer) \ |
333 #define GENERATE_VALUE_GETTER(value, initializer) \ | 328 if (!value) { \ |
334 if (!value) { \ | 329 value = AddValue(new (zone_) AstValue(initializer)); \ |
335 value = new (zone_) AstValue(initializer); \ | 330 } \ |
336 if (isolate_) { \ | |
337 value->Internalize(isolate_); \ | |
338 } \ | |
339 values_.Add(value); \ | |
340 } \ | |
341 return value; | 331 return value; |
342 | 332 |
343 | |
344 const AstValue* AstValueFactory::NewBoolean(bool b) { | 333 const AstValue* AstValueFactory::NewBoolean(bool b) { |
345 if (b) { | 334 if (b) { |
346 GENERATE_VALUE_GETTER(true_value_, true); | 335 GENERATE_VALUE_GETTER(true_value_, true); |
347 } else { | 336 } else { |
348 GENERATE_VALUE_GETTER(false_value_, false); | 337 GENERATE_VALUE_GETTER(false_value_, false); |
349 } | 338 } |
350 } | 339 } |
351 | 340 |
352 | 341 |
353 const AstValue* AstValueFactory::NewNull() { | 342 const AstValue* AstValueFactory::NewNull() { |
(...skipping 23 matching lines...) Expand all Loading... |
377 base::HashMap::Entry* entry = string_table_.LookupOrInsert(&key, hash); | 366 base::HashMap::Entry* entry = string_table_.LookupOrInsert(&key, hash); |
378 if (entry->value == NULL) { | 367 if (entry->value == NULL) { |
379 // Copy literal contents for later comparison. | 368 // Copy literal contents for later comparison. |
380 int length = literal_bytes.length(); | 369 int length = literal_bytes.length(); |
381 byte* new_literal_bytes = zone_->NewArray<byte>(length); | 370 byte* new_literal_bytes = zone_->NewArray<byte>(length); |
382 memcpy(new_literal_bytes, literal_bytes.start(), length); | 371 memcpy(new_literal_bytes, literal_bytes.start(), length); |
383 AstRawString* new_string = new (zone_) AstRawString( | 372 AstRawString* new_string = new (zone_) AstRawString( |
384 is_one_byte, Vector<const byte>(new_literal_bytes, length), hash); | 373 is_one_byte, Vector<const byte>(new_literal_bytes, length), hash); |
385 CHECK(new_string != nullptr); | 374 CHECK(new_string != nullptr); |
386 entry->key = new_string; | 375 entry->key = new_string; |
387 strings_.Add(new_string); | 376 AddString(new_string); |
388 if (isolate_) { | |
389 new_string->Internalize(isolate_); | |
390 } | |
391 entry->value = reinterpret_cast<void*>(1); | 377 entry->value = reinterpret_cast<void*>(1); |
392 } | 378 } |
393 return reinterpret_cast<AstRawString*>(entry->key); | 379 return reinterpret_cast<AstRawString*>(entry->key); |
394 } | 380 } |
395 | 381 |
396 | 382 |
397 bool AstValueFactory::AstRawStringCompare(void* a, void* b) { | 383 bool AstValueFactory::AstRawStringCompare(void* a, void* b) { |
398 const AstRawString* lhs = static_cast<AstRawString*>(a); | 384 const AstRawString* lhs = static_cast<AstRawString*>(a); |
399 const AstRawString* rhs = static_cast<AstRawString*>(b); | 385 const AstRawString* rhs = static_cast<AstRawString*>(b); |
400 DCHECK_EQ(lhs->hash(), rhs->hash()); | 386 DCHECK_EQ(lhs->hash(), rhs->hash()); |
(...skipping 18 matching lines...) Expand all Loading... |
419 length) == 0; | 405 length) == 0; |
420 } else { | 406 } else { |
421 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l), | 407 return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l), |
422 reinterpret_cast<const uint16_t*>(r), | 408 reinterpret_cast<const uint16_t*>(r), |
423 length) == 0; | 409 length) == 0; |
424 } | 410 } |
425 } | 411 } |
426 } | 412 } |
427 } // namespace internal | 413 } // namespace internal |
428 } // namespace v8 | 414 } // namespace v8 |
OLD | NEW |