Commit 93af0c35 authored by michaeln's avatar michaeln Committed by Commit bot

Tell V8 about the extra memory being held by FileReader objects.

BUG=114548

Review-Url: https://codereview.chromium.org/2837873007
Cr-Commit-Position: refs/heads/master@{#468550}
parent b87a7474
...@@ -50,25 +50,17 @@ ...@@ -50,25 +50,17 @@
#include "platform/wtf/text/Base64.h" #include "platform/wtf/text/Base64.h"
#include "platform/wtf/text/StringBuilder.h" #include "platform/wtf/text/StringBuilder.h"
#include "public/platform/WebURLRequest.h" #include "public/platform/WebURLRequest.h"
#include "v8/include/v8.h"
namespace blink { namespace blink {
FileReaderLoader::FileReaderLoader(ReadType read_type, FileReaderLoader::FileReaderLoader(ReadType read_type,
FileReaderLoaderClient* client) FileReaderLoaderClient* client)
: read_type_(read_type), : read_type_(read_type), client_(client) {}
client_(client),
is_raw_data_converted_(false),
string_result_(""),
finished_loading_(false),
bytes_loaded_(0),
total_bytes_(-1),
has_range_(false),
range_start_(0),
range_end_(0),
error_code_(FileError::kOK) {}
FileReaderLoader::~FileReaderLoader() { FileReaderLoader::~FileReaderLoader() {
Cleanup(); Cleanup();
UnadjustReportedMemoryUsageToV8();
if (!url_for_reading_.IsEmpty()) { if (!url_for_reading_.IsEmpty()) {
BlobRegistry::RevokePublicBlobURL(url_for_reading_); BlobRegistry::RevokePublicBlobURL(url_for_reading_);
} }
...@@ -143,9 +135,27 @@ void FileReaderLoader::Cleanup() { ...@@ -143,9 +135,27 @@ void FileReaderLoader::Cleanup() {
string_result_ = ""; string_result_ = "";
is_raw_data_converted_ = true; is_raw_data_converted_ = true;
decoder_.reset(); decoder_.reset();
array_buffer_result_ = nullptr;
UnadjustReportedMemoryUsageToV8();
} }
} }
void FileReaderLoader::AdjustReportedMemoryUsageToV8(int64_t usage) {
if (!usage)
return;
memory_usage_reported_to_v8_ += usage;
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(usage);
DCHECK_GE(memory_usage_reported_to_v8_, 0);
}
void FileReaderLoader::UnadjustReportedMemoryUsageToV8() {
if (!memory_usage_reported_to_v8_)
return;
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
-memory_usage_reported_to_v8_);
memory_usage_reported_to_v8_ = 0;
}
void FileReaderLoader::DidReceiveResponse( void FileReaderLoader::DidReceiveResponse(
unsigned long, unsigned long,
const ResourceResponse& response, const ResourceResponse& response,
...@@ -230,6 +240,7 @@ void FileReaderLoader::DidReceiveData(const char* data, unsigned data_length) { ...@@ -230,6 +240,7 @@ void FileReaderLoader::DidReceiveData(const char* data, unsigned data_length) {
} }
bytes_loaded_ += bytes_appended; bytes_loaded_ += bytes_appended;
is_raw_data_converted_ = false; is_raw_data_converted_ = false;
AdjustReportedMemoryUsageToV8(bytes_appended);
if (client_) if (client_)
client_->DidReceiveData(); client_->DidReceiveData();
...@@ -285,17 +296,18 @@ FileError::ErrorCode FileReaderLoader::HttpStatusCodeToErrorCode( ...@@ -285,17 +296,18 @@ FileError::ErrorCode FileReaderLoader::HttpStatusCodeToErrorCode(
DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() { DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
DCHECK_EQ(read_type_, kReadAsArrayBuffer); DCHECK_EQ(read_type_, kReadAsArrayBuffer);
if (array_buffer_result_)
return array_buffer_result_;
// If the loading is not started or an error occurs, return an empty result. // If the loading is not started or an error occurs, return an empty result.
if (!raw_data_ || error_code_) if (!raw_data_ || error_code_)
return nullptr; return nullptr;
if (array_buffer_result_)
return array_buffer_result_;
DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer());
if (finished_loading_) { if (finished_loading_) {
array_buffer_result_ = result; array_buffer_result_ = result;
AdjustReportedMemoryUsageToV8(-1 * raw_data_->ByteLength());
raw_data_.reset();
} }
return result; return result;
} }
...@@ -304,44 +316,46 @@ String FileReaderLoader::StringResult() { ...@@ -304,44 +316,46 @@ String FileReaderLoader::StringResult() {
DCHECK_NE(read_type_, kReadAsArrayBuffer); DCHECK_NE(read_type_, kReadAsArrayBuffer);
DCHECK_NE(read_type_, kReadByClient); DCHECK_NE(read_type_, kReadByClient);
// If the loading is not started or an error occurs, return an empty result. if (!raw_data_ || error_code_ || is_raw_data_converted_)
if (!raw_data_ || error_code_)
return string_result_;
// If already converted from the raw data, return the result now.
if (is_raw_data_converted_)
return string_result_; return string_result_;
switch (read_type_) { switch (read_type_) {
case kReadAsArrayBuffer: case kReadAsArrayBuffer:
// No conversion is needed. // No conversion is needed.
break; return string_result_;
case kReadAsBinaryString: case kReadAsBinaryString:
string_result_ = raw_data_->ToString(); SetStringResult(raw_data_->ToString());
is_raw_data_converted_ = true;
break; break;
case kReadAsText: case kReadAsText:
ConvertToText(); SetStringResult(ConvertToText());
break; break;
case kReadAsDataURL: case kReadAsDataURL:
// Partial data is not supported when reading as data URL. // Partial data is not supported when reading as data URL.
if (finished_loading_) if (finished_loading_)
ConvertToDataURL(); SetStringResult(ConvertToDataURL());
break; break;
default: default:
NOTREACHED(); NOTREACHED();
} }
if (finished_loading_) {
DCHECK(is_raw_data_converted_);
AdjustReportedMemoryUsageToV8(-1 * raw_data_->ByteLength());
raw_data_.reset();
}
return string_result_; return string_result_;
} }
void FileReaderLoader::ConvertToText() { void FileReaderLoader::SetStringResult(const String& result) {
AdjustReportedMemoryUsageToV8(-1 * string_result_.CharactersSizeInBytes());
is_raw_data_converted_ = true; is_raw_data_converted_ = true;
string_result_ = result;
AdjustReportedMemoryUsageToV8(string_result_.CharactersSizeInBytes());
}
if (!bytes_loaded_) { String FileReaderLoader::ConvertToText() {
string_result_ = ""; if (!bytes_loaded_)
return; return "";
}
// Decode the data. // Decode the data.
// The File API spec says that we should use the supplied encoding if it is // The File API spec says that we should use the supplied encoding if it is
...@@ -359,19 +373,15 @@ void FileReaderLoader::ConvertToText() { ...@@ -359,19 +373,15 @@ void FileReaderLoader::ConvertToText() {
if (finished_loading_) if (finished_loading_)
builder.Append(decoder_->Flush()); builder.Append(decoder_->Flush());
string_result_ = builder.ToString(); return builder.ToString();
} }
void FileReaderLoader::ConvertToDataURL() { String FileReaderLoader::ConvertToDataURL() {
is_raw_data_converted_ = true;
StringBuilder builder; StringBuilder builder;
builder.Append("data:"); builder.Append("data:");
if (!bytes_loaded_) { if (!bytes_loaded_)
string_result_ = builder.ToString(); return builder.ToString();
return;
}
builder.Append(data_type_); builder.Append(data_type_);
builder.Append(";base64,"); builder.Append(";base64,");
...@@ -382,7 +392,7 @@ void FileReaderLoader::ConvertToDataURL() { ...@@ -382,7 +392,7 @@ void FileReaderLoader::ConvertToDataURL() {
out.push_back('\0'); out.push_back('\0');
builder.Append(out.data()); builder.Append(out.data());
string_result_ = builder.ToString(); return builder.ToString();
} }
void FileReaderLoader::SetEncoding(const String& encoding) { void FileReaderLoader::SetEncoding(const String& encoding) {
......
...@@ -112,10 +112,13 @@ class CORE_EXPORT FileReaderLoader final : public ThreadableLoaderClient { ...@@ -112,10 +112,13 @@ class CORE_EXPORT FileReaderLoader final : public ThreadableLoaderClient {
FileReaderLoader(ReadType, FileReaderLoaderClient*); FileReaderLoader(ReadType, FileReaderLoaderClient*);
void Cleanup(); void Cleanup();
void AdjustReportedMemoryUsageToV8(int64_t usage);
void UnadjustReportedMemoryUsageToV8();
void Failed(FileError::ErrorCode); void Failed(FileError::ErrorCode);
void ConvertToText(); String ConvertToText();
void ConvertToDataURL(); String ConvertToDataURL();
void SetStringResult(const String&);
static FileError::ErrorCode HttpStatusCodeToErrorCode(int); static FileError::ErrorCode HttpStatusCodeToErrorCode(int);
...@@ -128,7 +131,7 @@ class CORE_EXPORT FileReaderLoader final : public ThreadableLoaderClient { ...@@ -128,7 +131,7 @@ class CORE_EXPORT FileReaderLoader final : public ThreadableLoaderClient {
Persistent<ThreadableLoader> loader_; Persistent<ThreadableLoader> loader_;
std::unique_ptr<ArrayBufferBuilder> raw_data_; std::unique_ptr<ArrayBufferBuilder> raw_data_;
bool is_raw_data_converted_; bool is_raw_data_converted_ = false;
Persistent<DOMArrayBuffer> array_buffer_result_; Persistent<DOMArrayBuffer> array_buffer_result_;
String string_result_; String string_result_;
...@@ -136,20 +139,20 @@ class CORE_EXPORT FileReaderLoader final : public ThreadableLoaderClient { ...@@ -136,20 +139,20 @@ class CORE_EXPORT FileReaderLoader final : public ThreadableLoaderClient {
// The decoder used to decode the text data. // The decoder used to decode the text data.
std::unique_ptr<TextResourceDecoder> decoder_; std::unique_ptr<TextResourceDecoder> decoder_;
bool finished_loading_; bool finished_loading_ = false;
long long bytes_loaded_; long long bytes_loaded_ = 0;
// If the total size of the resource is unknown, m_totalBytes is set to -1 // If the total size of the resource is unknown, m_totalBytes is set to -1
// until completion of loading, and the buffer for receiving data is set to // until completion of loading, and the buffer for receiving data is set to
// dynamically grow. Otherwise, m_totalBytes is set to the total size and // dynamically grow. Otherwise, m_totalBytes is set to the total size and
// the buffer for receiving data of m_totalBytes is allocated and never grow // the buffer for receiving data of m_totalBytes is allocated and never grow
// even when extra data is appeneded. // even when extra data is appeneded.
long long total_bytes_; long long total_bytes_ = -1;
int64_t memory_usage_reported_to_v8_ = 0;
bool has_range_ = false;
unsigned range_start_ = 0;
unsigned range_end_ = 0;
bool has_range_; FileError::ErrorCode error_code_ = FileError::kOK;
unsigned range_start_;
unsigned range_end_;
FileError::ErrorCode error_code_;
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment