| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 5408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5419 } | 5419 } |
| 5420 | 5420 |
| 5421 | 5421 |
| 5422 static i::Handle<i::String> NewExternalAsciiStringHandle( | 5422 static i::Handle<i::String> NewExternalAsciiStringHandle( |
| 5423 i::Isolate* isolate, | 5423 i::Isolate* isolate, |
| 5424 v8::String::ExternalAsciiStringResource* resource) { | 5424 v8::String::ExternalAsciiStringResource* resource) { |
| 5425 return isolate->factory()->NewExternalStringFromAscii(resource); | 5425 return isolate->factory()->NewExternalStringFromAscii(resource); |
| 5426 } | 5426 } |
| 5427 | 5427 |
| 5428 | 5428 |
| 5429 static bool RedirectToExternalString(i::Isolate* isolate, | |
| 5430 i::Handle<i::String> parent, | |
| 5431 i::Handle<i::String> external) { | |
| 5432 if (parent->IsConsString()) { | |
| 5433 i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent); | |
| 5434 cons->set_first(*external); | |
| 5435 cons->set_second(isolate->heap()->empty_string()); | |
| 5436 } else { | |
| 5437 ASSERT(parent->IsSlicedString()); | |
| 5438 i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent); | |
| 5439 slice->set_parent(*external); | |
| 5440 slice->set_offset(0); | |
| 5441 } | |
| 5442 return true; | |
| 5443 } | |
| 5444 | |
| 5445 | |
| 5446 Local<String> v8::String::NewExternal( | 5429 Local<String> v8::String::NewExternal( |
| 5447 Isolate* isolate, | 5430 Isolate* isolate, |
| 5448 v8::String::ExternalStringResource* resource) { | 5431 v8::String::ExternalStringResource* resource) { |
| 5449 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5432 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 5450 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); | 5433 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); |
| 5451 LOG_API(i_isolate, "String::NewExternal"); | 5434 LOG_API(i_isolate, "String::NewExternal"); |
| 5452 ENTER_V8(i_isolate); | 5435 ENTER_V8(i_isolate); |
| 5453 CHECK(resource && resource->data()); | 5436 CHECK(resource && resource->data()); |
| 5454 i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource); | 5437 i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource); |
| 5455 i_isolate->heap()->external_string_table()->AddString(*result); | 5438 i_isolate->heap()->external_string_table()->AddString(*result); |
| 5456 return Utils::ToLocal(result); | 5439 return Utils::ToLocal(result); |
| 5457 } | 5440 } |
| 5458 | 5441 |
| 5459 | 5442 |
| 5460 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { | 5443 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { |
| 5461 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5444 i::Handle<i::String> obj = Utils::OpenHandle(this); |
| 5462 i::Isolate* isolate = obj->GetIsolate(); | 5445 i::Isolate* isolate = obj->GetIsolate(); |
| 5463 if (i::StringShape(*obj).IsExternalTwoByte()) { | 5446 if (i::StringShape(*obj).IsExternalTwoByte()) { |
| 5464 return false; // Already an external string. | 5447 return false; // Already an external string. |
| 5465 } | 5448 } |
| 5466 ENTER_V8(isolate); | 5449 ENTER_V8(isolate); |
| 5467 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5450 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
| 5468 return false; | 5451 return false; |
| 5469 } | 5452 } |
| 5470 if (isolate->heap()->IsInGCPostProcessing()) { | 5453 if (isolate->heap()->IsInGCPostProcessing()) { |
| 5471 return false; | 5454 return false; |
| 5472 } | 5455 } |
| 5473 CHECK(resource && resource->data()); | 5456 CHECK(resource && resource->data()); |
| 5474 | 5457 |
| 5475 bool result; | 5458 bool result = obj->MakeExternal(resource); |
| 5476 i::Handle<i::String> external; | |
| 5477 if (isolate->heap()->old_pointer_space()->Contains(*obj)) { | |
| 5478 // We do not allow external strings in the old pointer space. Instead of | |
| 5479 // converting the string in-place, we keep the cons/sliced string and | |
| 5480 // point it to a newly-allocated external string. | |
| 5481 external = NewExternalStringHandle(isolate, resource); | |
| 5482 result = RedirectToExternalString(isolate, obj, external); | |
| 5483 } else { | |
| 5484 result = obj->MakeExternal(resource); | |
| 5485 external = obj; | |
| 5486 } | |
| 5487 | |
| 5488 if (result) { | 5459 if (result) { |
| 5489 ASSERT(external->IsExternalString()); | 5460 ASSERT(obj->IsExternalString()); |
| 5490 isolate->heap()->external_string_table()->AddString(*external); | 5461 isolate->heap()->external_string_table()->AddString(*obj); |
| 5491 } | 5462 } |
| 5492 return result; | 5463 return result; |
| 5493 } | 5464 } |
| 5494 | 5465 |
| 5495 | 5466 |
| 5496 Local<String> v8::String::NewExternal( | 5467 Local<String> v8::String::NewExternal( |
| 5497 Isolate* isolate, | 5468 Isolate* isolate, |
| 5498 v8::String::ExternalAsciiStringResource* resource) { | 5469 v8::String::ExternalAsciiStringResource* resource) { |
| 5499 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 5470 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 5500 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); | 5471 EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()"); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5517 } | 5488 } |
| 5518 ENTER_V8(isolate); | 5489 ENTER_V8(isolate); |
| 5519 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5490 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
| 5520 return false; | 5491 return false; |
| 5521 } | 5492 } |
| 5522 if (isolate->heap()->IsInGCPostProcessing()) { | 5493 if (isolate->heap()->IsInGCPostProcessing()) { |
| 5523 return false; | 5494 return false; |
| 5524 } | 5495 } |
| 5525 CHECK(resource && resource->data()); | 5496 CHECK(resource && resource->data()); |
| 5526 | 5497 |
| 5527 bool result; | 5498 bool result = obj->MakeExternal(resource); |
| 5528 i::Handle<i::String> external; | |
| 5529 if (isolate->heap()->old_pointer_space()->Contains(*obj)) { | |
| 5530 // We do not allow external strings in the old pointer space. Instead of | |
| 5531 // converting the string in-place, we keep the cons/sliced string and | |
| 5532 // point it to a newly-allocated external string. | |
| 5533 external = NewExternalAsciiStringHandle(isolate, resource); | |
| 5534 result = RedirectToExternalString(isolate, obj, external); | |
| 5535 } else { | |
| 5536 result = obj->MakeExternal(resource); | |
| 5537 external = obj; | |
| 5538 } | |
| 5539 | |
| 5540 if (result) { | 5499 if (result) { |
| 5541 ASSERT(external->IsExternalString()); | 5500 ASSERT(obj->IsExternalString()); |
| 5542 isolate->heap()->external_string_table()->AddString(*external); | 5501 isolate->heap()->external_string_table()->AddString(*obj); |
| 5543 } | 5502 } |
| 5544 return result; | 5503 return result; |
| 5545 } | 5504 } |
| 5546 | 5505 |
| 5547 | 5506 |
| 5548 bool v8::String::CanMakeExternal() { | 5507 bool v8::String::CanMakeExternal() { |
| 5549 if (!internal::FLAG_clever_optimizations) return false; | 5508 if (!internal::FLAG_clever_optimizations) return false; |
| 5550 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5509 i::Handle<i::String> obj = Utils::OpenHandle(this); |
| 5551 i::Isolate* isolate = obj->GetIsolate(); | 5510 i::Isolate* isolate = obj->GetIsolate(); |
| 5552 | 5511 |
| (...skipping 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7392 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7351 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
| 7393 Address callback_address = | 7352 Address callback_address = |
| 7394 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7353 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
| 7395 VMState<EXTERNAL> state(isolate); | 7354 VMState<EXTERNAL> state(isolate); |
| 7396 ExternalCallbackScope call_scope(isolate, callback_address); | 7355 ExternalCallbackScope call_scope(isolate, callback_address); |
| 7397 callback(info); | 7356 callback(info); |
| 7398 } | 7357 } |
| 7399 | 7358 |
| 7400 | 7359 |
| 7401 } } // namespace v8::internal | 7360 } } // namespace v8::internal |
| OLD | NEW |