| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 16299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16310 Handle<Object> AsHandle(Isolate* isolate) override { | 16310 Handle<Object> AsHandle(Isolate* isolate) override { |
| 16311 // Internalize the string if possible. | 16311 // Internalize the string if possible. |
| 16312 MaybeHandle<Map> maybe_map = | 16312 MaybeHandle<Map> maybe_map = |
| 16313 isolate->factory()->InternalizedStringMapForString(string_); | 16313 isolate->factory()->InternalizedStringMapForString(string_); |
| 16314 Handle<Map> map; | 16314 Handle<Map> map; |
| 16315 if (maybe_map.ToHandle(&map)) { | 16315 if (maybe_map.ToHandle(&map)) { |
| 16316 string_->set_map_no_write_barrier(*map); | 16316 string_->set_map_no_write_barrier(*map); |
| 16317 DCHECK(string_->IsInternalizedString()); | 16317 DCHECK(string_->IsInternalizedString()); |
| 16318 return string_; | 16318 return string_; |
| 16319 } | 16319 } |
| 16320 // External strings get special treatment, to avoid copying their contents. | 16320 if (FLAG_thin_strings) { |
| 16321 if (string_->IsExternalOneByteString()) { | 16321 // External strings get special treatment, to avoid copying their |
| 16322 return isolate->factory() | 16322 // contents. |
| 16323 ->InternalizeExternalString<ExternalOneByteString>(string_); | 16323 if (string_->IsExternalOneByteString()) { |
| 16324 } else if (string_->IsExternalTwoByteString()) { | 16324 return isolate->factory() |
| 16325 return isolate->factory() | 16325 ->InternalizeExternalString<ExternalOneByteString>(string_); |
| 16326 ->InternalizeExternalString<ExternalTwoByteString>(string_); | 16326 } else if (string_->IsExternalTwoByteString()) { |
| 16327 return isolate->factory() |
| 16328 ->InternalizeExternalString<ExternalTwoByteString>(string_); |
| 16329 } |
| 16327 } | 16330 } |
| 16328 // Otherwise allocate a new internalized string. | 16331 // Otherwise allocate a new internalized string. |
| 16329 return isolate->factory()->NewInternalizedStringImpl( | 16332 return isolate->factory()->NewInternalizedStringImpl( |
| 16330 string_, string_->length(), string_->hash_field()); | 16333 string_, string_->length(), string_->hash_field()); |
| 16331 } | 16334 } |
| 16332 | 16335 |
| 16333 static uint32_t StringHash(Object* obj) { | 16336 static uint32_t StringHash(Object* obj) { |
| 16334 return String::cast(obj)->Hash(); | 16337 return String::cast(obj)->Hash(); |
| 16335 } | 16338 } |
| 16336 | 16339 |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17347 return handle(Handle<ThinString>::cast(string)->actual(), isolate); | 17350 return handle(Handle<ThinString>::cast(string)->actual(), isolate); |
| 17348 } | 17351 } |
| 17349 if (string->IsConsString() && string->IsFlat()) { | 17352 if (string->IsConsString() && string->IsFlat()) { |
| 17350 string = handle(Handle<ConsString>::cast(string)->first(), isolate); | 17353 string = handle(Handle<ConsString>::cast(string)->first(), isolate); |
| 17351 if (string->IsInternalizedString()) return string; | 17354 if (string->IsInternalizedString()) return string; |
| 17352 } | 17355 } |
| 17353 | 17356 |
| 17354 InternalizedStringKey key(string); | 17357 InternalizedStringKey key(string); |
| 17355 Handle<String> result = LookupKey(isolate, &key); | 17358 Handle<String> result = LookupKey(isolate, &key); |
| 17356 | 17359 |
| 17357 if (string->IsExternalString()) { | 17360 if (FLAG_thin_strings) { |
| 17358 if (result->IsExternalOneByteString()) { | 17361 if (string->IsExternalString()) { |
| 17359 MigrateExternalStringResource<ExternalOneByteString>(isolate, string, | 17362 if (result->IsExternalOneByteString()) { |
| 17360 result); | 17363 MigrateExternalStringResource<ExternalOneByteString>(isolate, string, |
| 17361 } else if (result->IsExternalTwoByteString()) { | 17364 result); |
| 17362 MigrateExternalStringResource<ExternalTwoByteString>(isolate, string, | 17365 } else if (result->IsExternalTwoByteString()) { |
| 17363 result); | 17366 MigrateExternalStringResource<ExternalTwoByteString>(isolate, string, |
| 17364 } else { | 17367 result); |
| 17365 // If the external string is duped into an existing non-external | 17368 } else { |
| 17366 // internalized string, free its resource (it's about to be rewritten | 17369 // If the external string is duped into an existing non-external |
| 17367 // into a ThinString below). | 17370 // internalized string, free its resource (it's about to be rewritten |
| 17368 isolate->heap()->FinalizeExternalString(*string); | 17371 // into a ThinString below). |
| 17372 isolate->heap()->FinalizeExternalString(*string); |
| 17373 } |
| 17369 } | 17374 } |
| 17370 } | |
| 17371 | 17375 |
| 17372 // The LookupKey() call above tries to internalize the string in-place. | 17376 // The LookupKey() call above tries to internalize the string in-place. |
| 17373 // In cases where that wasn't possible (e.g. new-space strings), turn them | 17377 // In cases where that wasn't possible (e.g. new-space strings), turn them |
| 17374 // into ThinStrings referring to their internalized versions now. | 17378 // into ThinStrings referring to their internalized versions now. |
| 17375 if (!string->IsInternalizedString()) { | 17379 if (!string->IsInternalizedString()) { |
| 17376 DisallowHeapAllocation no_gc; | 17380 DisallowHeapAllocation no_gc; |
| 17377 bool one_byte = result->IsOneByteRepresentation(); | 17381 bool one_byte = result->IsOneByteRepresentation(); |
| 17378 Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map() | 17382 Handle<Map> map = one_byte |
| 17379 : isolate->factory()->thin_string_map(); | 17383 ? isolate->factory()->thin_one_byte_string_map() |
| 17380 int old_size = string->Size(); | 17384 : isolate->factory()->thin_string_map(); |
| 17381 DCHECK(old_size >= ThinString::kSize); | 17385 int old_size = string->Size(); |
| 17382 string->synchronized_set_map(*map); | 17386 DCHECK(old_size >= ThinString::kSize); |
| 17383 Handle<ThinString> thin = Handle<ThinString>::cast(string); | 17387 string->synchronized_set_map(*map); |
| 17384 thin->set_actual(*result); | 17388 Handle<ThinString> thin = Handle<ThinString>::cast(string); |
| 17385 Address thin_end = thin->address() + ThinString::kSize; | 17389 thin->set_actual(*result); |
| 17386 int size_delta = old_size - ThinString::kSize; | 17390 Address thin_end = thin->address() + ThinString::kSize; |
| 17387 if (size_delta != 0) { | 17391 int size_delta = old_size - ThinString::kSize; |
| 17388 Heap* heap = isolate->heap(); | 17392 if (size_delta != 0) { |
| 17389 heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo); | 17393 Heap* heap = isolate->heap(); |
| 17390 heap->AdjustLiveBytes(*thin, -size_delta); | 17394 heap->CreateFillerObjectAt(thin_end, size_delta, |
| 17395 ClearRecordedSlots::kNo); |
| 17396 heap->AdjustLiveBytes(*thin, -size_delta); |
| 17397 } |
| 17398 } |
| 17399 } else { // !FLAG_thin_strings |
| 17400 if (string->IsConsString()) { |
| 17401 Handle<ConsString> cons = Handle<ConsString>::cast(string); |
| 17402 cons->set_first(*result); |
| 17403 cons->set_second(isolate->heap()->empty_string()); |
| 17404 } else if (string->IsSlicedString()) { |
| 17405 STATIC_ASSERT(ConsString::kSize == SlicedString::kSize); |
| 17406 DisallowHeapAllocation no_gc; |
| 17407 bool one_byte = result->IsOneByteRepresentation(); |
| 17408 Handle<Map> map = one_byte |
| 17409 ? isolate->factory()->cons_one_byte_string_map() |
| 17410 : isolate->factory()->cons_string_map(); |
| 17411 string->set_map(*map); |
| 17412 Handle<ConsString> cons = Handle<ConsString>::cast(string); |
| 17413 cons->set_first(*result); |
| 17414 cons->set_second(isolate->heap()->empty_string()); |
| 17391 } | 17415 } |
| 17392 } | 17416 } |
| 17393 return result; | 17417 return result; |
| 17394 } | 17418 } |
| 17395 | 17419 |
| 17396 | 17420 |
| 17397 Handle<String> StringTable::LookupKey(Isolate* isolate, HashTableKey* key) { | 17421 Handle<String> StringTable::LookupKey(Isolate* isolate, HashTableKey* key) { |
| 17398 Handle<StringTable> table = isolate->factory()->string_table(); | 17422 Handle<StringTable> table = isolate->factory()->string_table(); |
| 17399 int entry = table->FindEntry(key); | 17423 int entry = table->FindEntry(key); |
| 17400 | 17424 |
| (...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20026 // depend on this. | 20050 // depend on this. |
| 20027 return DICTIONARY_ELEMENTS; | 20051 return DICTIONARY_ELEMENTS; |
| 20028 } | 20052 } |
| 20029 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20053 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 20030 return kind; | 20054 return kind; |
| 20031 } | 20055 } |
| 20032 } | 20056 } |
| 20033 | 20057 |
| 20034 } // namespace internal | 20058 } // namespace internal |
| 20035 } // namespace v8 | 20059 } // namespace v8 |
| OLD | NEW |