| Index: src/api.cc
|
| ===================================================================
|
| --- src/api.cc (revision 1251)
|
| +++ src/api.cc (working copy)
|
| @@ -2440,22 +2440,58 @@
|
|
|
| static void DisposeExternalString(v8::Persistent<v8::Value> obj,
|
| void* parameter) {
|
| - v8::String::ExternalStringResource* resource =
|
| - reinterpret_cast<v8::String::ExternalStringResource*>(parameter);
|
| - const size_t total_size = resource->length() * sizeof(*resource->data());
|
| - i::Counters::total_external_string_memory.Decrement(total_size);
|
| - delete resource;
|
| + i::ExternalTwoByteString* str =
|
| + i::ExternalTwoByteString::cast(*Utils::OpenHandle(*obj));
|
| +
|
| + // External symbols are deleted when they are pruned out of the symbol
|
| + // table. Generally external symbols are not registered with the weak handle
|
| + // callbacks unless they are upgraded to a symbol after being externalized.
|
| + if (!str->IsSymbol()) {
|
| + v8::String::ExternalStringResource* resource =
|
| + reinterpret_cast<v8::String::ExternalStringResource*>(parameter);
|
| + if (resource != NULL) {
|
| + const size_t total_size = resource->length() * sizeof(*resource->data());
|
| + i::Counters::total_external_string_memory.Decrement(total_size);
|
| +
|
| + // The object will continue to live in the JavaScript heap until the
|
| + // handle is entirely cleaned out by the next GC. For example the
|
| + // destructor for the resource below could bring it back to life again.
|
| + // Which is why we make sure to not have a dangling pointer here.
|
| + str->set_resource(NULL);
|
| + delete resource;
|
| + }
|
| + }
|
| +
|
| + // In any case we do not need this handle any longer.
|
| obj.Dispose();
|
| }
|
|
|
|
|
| static void DisposeExternalAsciiString(v8::Persistent<v8::Value> obj,
|
| void* parameter) {
|
| - v8::String::ExternalAsciiStringResource* resource =
|
| - reinterpret_cast<v8::String::ExternalAsciiStringResource*>(parameter);
|
| - const size_t total_size = resource->length() * sizeof(*resource->data());
|
| - i::Counters::total_external_string_memory.Decrement(total_size);
|
| - delete resource;
|
| + i::ExternalAsciiString* str =
|
| + i::ExternalAsciiString::cast(*Utils::OpenHandle(*obj));
|
| +
|
| + // External symbols are deleted when they are pruned out of the symbol
|
| + // table. Generally external symbols are not registered with the weak handle
|
| + // callbacks unless they are upgraded to a symbol after being externalized.
|
| + if (!str->IsSymbol()) {
|
| + v8::String::ExternalAsciiStringResource* resource =
|
| + reinterpret_cast<v8::String::ExternalAsciiStringResource*>(parameter);
|
| + if (resource != NULL) {
|
| + const size_t total_size = resource->length() * sizeof(*resource->data());
|
| + i::Counters::total_external_string_memory.Decrement(total_size);
|
| +
|
| + // The object will continue to live in the JavaScript heap until the
|
| + // handle is entirely cleaned out by the next GC. For example the
|
| + // destructor for the resource below could bring it back to life again.
|
| + // Which is why we make sure to not have a dangling pointer here.
|
| + str->set_resource(NULL);
|
| + delete resource;
|
| + }
|
| + }
|
| +
|
| + // In any case we do not need this handle any longer.
|
| obj.Dispose();
|
| }
|
|
|
| @@ -2475,6 +2511,24 @@
|
| }
|
|
|
|
|
| +bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
| + if (IsDeadCheck("v8::String::MakeExternal()")) return false;
|
| + if (this->IsExternal()) return false; // Already an external string.
|
| + i::Handle <i::String> obj = Utils::OpenHandle(this);
|
| + bool result = obj->MakeExternal(resource);
|
| + if (result && !obj->IsSymbol()) {
|
| + // Operation was successful and the string is not a symbol. In this case
|
| + // we need to make sure that the we call the destructor for the external
|
| + // resource when no strong references to the string remain.
|
| + i::Handle<i::Object> handle = i::GlobalHandles::Create(*obj);
|
| + i::GlobalHandles::MakeWeak(handle.location(),
|
| + resource,
|
| + &DisposeExternalString);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +
|
| Local<String> v8::String::NewExternal(
|
| v8::String::ExternalAsciiStringResource* resource) {
|
| EnsureInitialized("v8::String::NewExternal()");
|
| @@ -2490,6 +2544,25 @@
|
| }
|
|
|
|
|
| +bool v8::String::MakeExternal(
|
| + v8::String::ExternalAsciiStringResource* resource) {
|
| + if (IsDeadCheck("v8::String::MakeExternal()")) return false;
|
| + if (this->IsExternal()) return false; // Already an external string.
|
| + i::Handle <i::String> obj = Utils::OpenHandle(this);
|
| + bool result = obj->MakeExternal(resource);
|
| + if (result && !obj->IsSymbol()) {
|
| + // Operation was successful and the string is not a symbol. In this case
|
| + // we need to make sure that the we call the destructor for the external
|
| + // resource when no strong references to the string remain.
|
| + i::Handle<i::Object> handle = i::GlobalHandles::Create(*obj);
|
| + i::GlobalHandles::MakeWeak(handle.location(),
|
| + resource,
|
| + &DisposeExternalAsciiString);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +
|
| Local<v8::Object> v8::Object::New() {
|
| EnsureInitialized("v8::Object::New()");
|
| LOG_API("Object::New");
|
|
|