Chromium Code Reviews| 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 | 108 |
| 110 bool AstRawString::AsArrayIndex(uint32_t* index) const { | 109 bool AstRawString::AsArrayIndex(uint32_t* index) const { |
| 111 if (!string_.is_null()) | 110 if ((hash_ & Name::kIsNotArrayIndexMask) != 0) return false; |
|
marja
2016/08/10 08:33:17
I was trying to follow which part sets this, and i
| |
| 112 return string_->AsArrayIndex(index); | 111 if (length() <= Name::kMaxCachedArrayIndexLength) { |
| 113 if (!is_one_byte() || literal_bytes_.length() == 0 || | 112 *index = Name::ArrayIndexValueBits::decode(hash_); |
| 114 literal_bytes_.length() > String::kMaxArrayIndexSize) | 113 } else { |
| 115 return false; | 114 OneByteStringStream stream(literal_bytes_); |
| 116 OneByteStringStream stream(literal_bytes_); | 115 CHECK(StringToArrayIndex(&stream, index)); |
| 117 return StringToArrayIndex(&stream, index); | 116 } |
| 117 return true; | |
| 118 } | 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; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 DisallowHeapAllocation no_gc; | 245 DisallowHeapAllocation no_gc; |
| 246 String::FlatContent content = literal->GetFlatContent(); | 246 String::FlatContent content = literal->GetFlatContent(); |
| 247 if (content.IsOneByte()) { | 247 if (content.IsOneByte()) { |
| 248 result = GetOneByteStringInternal(content.ToOneByteVector()); | 248 result = GetOneByteStringInternal(content.ToOneByteVector()); |
| 249 } else { | 249 } else { |
| 250 DCHECK(content.IsTwoByte()); | 250 DCHECK(content.IsTwoByte()); |
| 251 result = GetTwoByteStringInternal(content.ToUC16Vector()); | 251 result = GetTwoByteStringInternal(content.ToUC16Vector()); |
| 252 } | 252 } |
| 253 } | 253 } |
| 254 isolate_ = saved_isolate; | 254 isolate_ = saved_isolate; |
| 255 if (isolate_) result->Internalize(isolate_); | 255 if (strings_ != nullptr && isolate_) { |
| 256 // Only the string we are creating is uninternalized at this point. | |
| 257 DCHECK_EQ(result, strings_); | |
| 258 DCHECK_NULL(strings_->next()); | |
| 259 result->Internalize(isolate_); | |
| 260 ResetStrings(); | |
| 261 } | |
| 256 return result; | 262 return result; |
| 257 } | 263 } |
| 258 | 264 |
| 259 | 265 |
| 260 const AstConsString* AstValueFactory::NewConsString( | 266 const AstConsString* AstValueFactory::NewConsString( |
| 261 const AstString* left, const AstString* right) { | 267 const AstString* left, const AstString* right) { |
| 262 // This Vector will be valid as long as the Collector is alive (meaning that | 268 // This Vector will be valid as long as the Collector is alive (meaning that |
| 263 // the AstRawString will not be moved). | 269 // the AstRawString will not be moved). |
| 264 AstConsString* new_string = new (zone_) AstConsString(left, right); | 270 AstConsString* new_string = new (zone_) AstConsString(left, right); |
| 265 CHECK(new_string != nullptr); | 271 CHECK(new_string != nullptr); |
| 266 strings_.Add(new_string); | 272 AddString(new_string); |
| 267 if (isolate_) { | |
| 268 new_string->Internalize(isolate_); | |
| 269 } | |
| 270 return new_string; | 273 return new_string; |
| 271 } | 274 } |
| 272 | 275 |
| 273 | 276 |
| 274 void AstValueFactory::Internalize(Isolate* isolate) { | 277 void AstValueFactory::Internalize(Isolate* isolate) { |
| 275 if (isolate_) { | 278 if (isolate_) { |
| 279 DCHECK_NULL(strings_); | |
| 280 DCHECK_NULL(values_); | |
| 276 // Everything is already internalized. | 281 // Everything is already internalized. |
| 277 return; | 282 return; |
| 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 |