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 |