OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 } | 1266 } |
1267 #endif // DEBUG | 1267 #endif // DEBUG |
1268 Heap* heap = GetHeap(); | 1268 Heap* heap = GetHeap(); |
1269 int size = this->Size(); // Byte size of the original string. | 1269 int size = this->Size(); // Byte size of the original string. |
1270 if (size < ExternalString::kShortSize) { | 1270 if (size < ExternalString::kShortSize) { |
1271 return false; | 1271 return false; |
1272 } | 1272 } |
1273 bool is_ascii = this->IsOneByteRepresentation(); | 1273 bool is_ascii = this->IsOneByteRepresentation(); |
1274 bool is_internalized = this->IsInternalizedString(); | 1274 bool is_internalized = this->IsInternalizedString(); |
1275 | 1275 |
1276 // Morph the object to an external string by adjusting the map and | 1276 // Morph the string to an external string by replacing the map and |
1277 // reinitializing the fields. | 1277 // reinitializing the fields. This won't work if |
1278 if (size >= ExternalString::kSize) { | 1278 // - the space the existing string occupies is too small for a regular |
| 1279 // external string. |
| 1280 // - the existing string is in old pointer space and the backing store of |
| 1281 // the external string is not aligned. The GC cannot deal with fields |
| 1282 // containing an unaligned address that points to outside of V8's heap. |
| 1283 // In either case we resort to a short external string instead, omitting |
| 1284 // the field caching the address of the backing store. When we encounter |
| 1285 // short external strings in generated code, we need to bailout to runtime. |
| 1286 if (size < ExternalString::kSize || |
| 1287 (!IsAligned(reinterpret_cast<intptr_t>(resource->data()), kPointerSize) && |
| 1288 heap->old_pointer_space()->Contains(this))) { |
1279 this->set_map_no_write_barrier( | 1289 this->set_map_no_write_barrier( |
1280 is_internalized | 1290 is_internalized |
1281 ? (is_ascii | 1291 ? (is_ascii |
1282 ? heap->external_internalized_string_with_one_byte_data_map() | 1292 ? heap-> |
1283 : heap->external_internalized_string_map()) | 1293 short_external_internalized_string_with_one_byte_data_map() |
| 1294 : heap->short_external_internalized_string_map()) |
1284 : (is_ascii | 1295 : (is_ascii |
1285 ? heap->external_string_with_one_byte_data_map() | 1296 ? heap->short_external_string_with_one_byte_data_map() |
1286 : heap->external_string_map())); | 1297 : heap->short_external_string_map())); |
1287 } else { | 1298 } else { |
1288 this->set_map_no_write_barrier( | 1299 this->set_map_no_write_barrier( |
1289 is_internalized | 1300 is_internalized |
1290 ? (is_ascii | 1301 ? (is_ascii |
1291 ? heap-> | 1302 ? heap->external_internalized_string_with_one_byte_data_map() |
1292 short_external_internalized_string_with_one_byte_data_map() | 1303 : heap->external_internalized_string_map()) |
1293 : heap->short_external_internalized_string_map()) | 1304 : (is_ascii |
1294 : (is_ascii | 1305 ? heap->external_string_with_one_byte_data_map() |
1295 ? heap->short_external_string_with_one_byte_data_map() | 1306 : heap->external_string_map())); |
1296 : heap->short_external_string_map())); | |
1297 } | 1307 } |
1298 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 1308 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
1299 self->set_resource(resource); | 1309 self->set_resource(resource); |
1300 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 1310 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
1301 | 1311 |
1302 // Fill the remainder of the string with dead wood. | 1312 // Fill the remainder of the string with dead wood. |
1303 int new_size = this->Size(); // Byte size of the external String object. | 1313 int new_size = this->Size(); // Byte size of the external String object. |
1304 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1314 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
1305 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 1315 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { |
1306 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), | 1316 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), |
(...skipping 20 matching lines...) Expand all Loading... |
1327 resource->length() * sizeof(smart_chars[0])) == 0); | 1337 resource->length() * sizeof(smart_chars[0])) == 0); |
1328 } | 1338 } |
1329 #endif // DEBUG | 1339 #endif // DEBUG |
1330 Heap* heap = GetHeap(); | 1340 Heap* heap = GetHeap(); |
1331 int size = this->Size(); // Byte size of the original string. | 1341 int size = this->Size(); // Byte size of the original string. |
1332 if (size < ExternalString::kShortSize) { | 1342 if (size < ExternalString::kShortSize) { |
1333 return false; | 1343 return false; |
1334 } | 1344 } |
1335 bool is_internalized = this->IsInternalizedString(); | 1345 bool is_internalized = this->IsInternalizedString(); |
1336 | 1346 |
1337 // Morph the object to an external string by adjusting the map and | 1347 // Morph the string to an external string by replacing the map and |
1338 // reinitializing the fields. Use short version if space is limited. | 1348 // reinitializing the fields. This won't work if |
1339 if (size >= ExternalString::kSize) { | 1349 // - the space the existing string occupies is too small for a regular |
| 1350 // external string. |
| 1351 // - the existing string is in old pointer space and the backing store of |
| 1352 // the external string is not aligned. The GC cannot deal with fields |
| 1353 // containing an unaligned address that points to outside of V8's heap. |
| 1354 // In either case we resort to a short external string instead, omitting |
| 1355 // the field caching the address of the backing store. When we encounter |
| 1356 // short external strings in generated code, we need to bailout to runtime. |
| 1357 if (size < ExternalString::kSize || |
| 1358 (!IsAligned(reinterpret_cast<intptr_t>(resource->data()), kPointerSize) && |
| 1359 heap->old_pointer_space()->Contains(this))) { |
| 1360 this->set_map_no_write_barrier( |
| 1361 is_internalized ? heap->short_external_ascii_internalized_string_map() |
| 1362 : heap->short_external_ascii_string_map()); |
| 1363 } else { |
1340 this->set_map_no_write_barrier( | 1364 this->set_map_no_write_barrier( |
1341 is_internalized ? heap->external_ascii_internalized_string_map() | 1365 is_internalized ? heap->external_ascii_internalized_string_map() |
1342 : heap->external_ascii_string_map()); | 1366 : heap->external_ascii_string_map()); |
1343 } else { | |
1344 this->set_map_no_write_barrier( | |
1345 is_internalized ? heap->short_external_ascii_internalized_string_map() | |
1346 : heap->short_external_ascii_string_map()); | |
1347 } | 1367 } |
1348 ExternalAsciiString* self = ExternalAsciiString::cast(this); | 1368 ExternalAsciiString* self = ExternalAsciiString::cast(this); |
1349 self->set_resource(resource); | 1369 self->set_resource(resource); |
1350 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 1370 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
1351 | 1371 |
1352 // Fill the remainder of the string with dead wood. | 1372 // Fill the remainder of the string with dead wood. |
1353 int new_size = this->Size(); // Byte size of the external String object. | 1373 int new_size = this->Size(); // Byte size of the external String object. |
1354 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1374 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
1355 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 1375 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { |
1356 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), | 1376 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), |
(...skipping 15129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16486 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16506 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16487 static const char* error_messages_[] = { | 16507 static const char* error_messages_[] = { |
16488 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16508 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16489 }; | 16509 }; |
16490 #undef ERROR_MESSAGES_TEXTS | 16510 #undef ERROR_MESSAGES_TEXTS |
16491 return error_messages_[reason]; | 16511 return error_messages_[reason]; |
16492 } | 16512 } |
16493 | 16513 |
16494 | 16514 |
16495 } } // namespace v8::internal | 16515 } } // namespace v8::internal |
OLD | NEW |