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 |