Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp

Issue 2837873007: Tell V8 about the extra memory being held by FileReader objects. (Closed)
Patch Set: comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/fileapi/FileReaderLoader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 #include "platform/loader/fetch/ResourceError.h" 43 #include "platform/loader/fetch/ResourceError.h"
44 #include "platform/loader/fetch/ResourceRequest.h" 44 #include "platform/loader/fetch/ResourceRequest.h"
45 #include "platform/loader/fetch/ResourceResponse.h" 45 #include "platform/loader/fetch/ResourceResponse.h"
46 #include "platform/wtf/PassRefPtr.h" 46 #include "platform/wtf/PassRefPtr.h"
47 #include "platform/wtf/PtrUtil.h" 47 #include "platform/wtf/PtrUtil.h"
48 #include "platform/wtf/RefPtr.h" 48 #include "platform/wtf/RefPtr.h"
49 #include "platform/wtf/Vector.h" 49 #include "platform/wtf/Vector.h"
50 #include "platform/wtf/text/Base64.h" 50 #include "platform/wtf/text/Base64.h"
51 #include "platform/wtf/text/StringBuilder.h" 51 #include "platform/wtf/text/StringBuilder.h"
52 #include "public/platform/WebURLRequest.h" 52 #include "public/platform/WebURLRequest.h"
53 #include "v8/include/v8.h"
53 54
54 namespace blink { 55 namespace blink {
55 56
56 FileReaderLoader::FileReaderLoader(ReadType read_type, 57 FileReaderLoader::FileReaderLoader(ReadType read_type,
57 FileReaderLoaderClient* client) 58 FileReaderLoaderClient* client)
58 : read_type_(read_type), 59 : read_type_(read_type), client_(client) {}
59 client_(client),
60 is_raw_data_converted_(false),
61 string_result_(""),
62 finished_loading_(false),
63 bytes_loaded_(0),
64 total_bytes_(-1),
65 has_range_(false),
66 range_start_(0),
67 range_end_(0),
68 error_code_(FileError::kOK) {}
69 60
70 FileReaderLoader::~FileReaderLoader() { 61 FileReaderLoader::~FileReaderLoader() {
71 Cleanup(); 62 Cleanup();
63 UnadjustReportedMemoryUsageToV8();
72 if (!url_for_reading_.IsEmpty()) { 64 if (!url_for_reading_.IsEmpty()) {
73 BlobRegistry::RevokePublicBlobURL(url_for_reading_); 65 BlobRegistry::RevokePublicBlobURL(url_for_reading_);
74 } 66 }
75 } 67 }
76 68
77 void FileReaderLoader::Start(ExecutionContext* execution_context, 69 void FileReaderLoader::Start(ExecutionContext* execution_context,
78 PassRefPtr<BlobDataHandle> blob_data) { 70 PassRefPtr<BlobDataHandle> blob_data) {
79 DCHECK(execution_context); 71 DCHECK(execution_context);
80 // The blob is read by routing through the request handling layer given a 72 // The blob is read by routing through the request handling layer given a
81 // temporary public url. 73 // temporary public url.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 loader_->Cancel(); 128 loader_->Cancel();
137 loader_ = nullptr; 129 loader_ = nullptr;
138 } 130 }
139 131
140 // If we get any error, we do not need to keep a buffer around. 132 // If we get any error, we do not need to keep a buffer around.
141 if (error_code_) { 133 if (error_code_) {
142 raw_data_.reset(); 134 raw_data_.reset();
143 string_result_ = ""; 135 string_result_ = "";
144 is_raw_data_converted_ = true; 136 is_raw_data_converted_ = true;
145 decoder_.reset(); 137 decoder_.reset();
138 array_buffer_result_ = nullptr;
139 UnadjustReportedMemoryUsageToV8();
146 } 140 }
147 } 141 }
148 142
143 void FileReaderLoader::AdjustReportedMemoryUsageToV8(int64_t usage) {
144 if (!usage)
145 return;
146 memory_usage_reported_to_v8_ += usage;
147 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(usage);
148 DCHECK_GE(memory_usage_reported_to_v8_, 0);
149 }
150
151 void FileReaderLoader::UnadjustReportedMemoryUsageToV8() {
152 if (!memory_usage_reported_to_v8_)
153 return;
154 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
155 -memory_usage_reported_to_v8_);
156 memory_usage_reported_to_v8_ = 0;
157 }
158
149 void FileReaderLoader::DidReceiveResponse( 159 void FileReaderLoader::DidReceiveResponse(
150 unsigned long, 160 unsigned long,
151 const ResourceResponse& response, 161 const ResourceResponse& response,
152 std::unique_ptr<WebDataConsumerHandle> handle) { 162 std::unique_ptr<WebDataConsumerHandle> handle) {
153 DCHECK(!handle); 163 DCHECK(!handle);
154 if (response.HttpStatusCode() != 200) { 164 if (response.HttpStatusCode() != 200) {
155 Failed(HttpStatusCodeToErrorCode(response.HttpStatusCode())); 165 Failed(HttpStatusCodeToErrorCode(response.HttpStatusCode()));
156 return; 166 return;
157 } 167 }
158 168
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 233
224 unsigned bytes_appended = raw_data_->Append(data, data_length); 234 unsigned bytes_appended = raw_data_->Append(data, data_length);
225 if (!bytes_appended) { 235 if (!bytes_appended) {
226 raw_data_.reset(); 236 raw_data_.reset();
227 bytes_loaded_ = 0; 237 bytes_loaded_ = 0;
228 Failed(FileError::kNotReadableErr); 238 Failed(FileError::kNotReadableErr);
229 return; 239 return;
230 } 240 }
231 bytes_loaded_ += bytes_appended; 241 bytes_loaded_ += bytes_appended;
232 is_raw_data_converted_ = false; 242 is_raw_data_converted_ = false;
243 AdjustReportedMemoryUsageToV8(bytes_appended);
233 244
234 if (client_) 245 if (client_)
235 client_->DidReceiveData(); 246 client_->DidReceiveData();
236 } 247 }
237 248
238 void FileReaderLoader::DidFinishLoading(unsigned long, double) { 249 void FileReaderLoader::DidFinishLoading(unsigned long, double) {
239 if (read_type_ != kReadByClient && raw_data_) { 250 if (read_type_ != kReadByClient && raw_data_) {
240 raw_data_->ShrinkToFit(); 251 raw_data_->ShrinkToFit();
241 is_raw_data_converted_ = false; 252 is_raw_data_converted_ = false;
242 } 253 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 return FileError::kSecurityErr; 289 return FileError::kSecurityErr;
279 case 404: 290 case 404:
280 return FileError::kNotFoundErr; 291 return FileError::kNotFoundErr;
281 default: 292 default:
282 return FileError::kNotReadableErr; 293 return FileError::kNotReadableErr;
283 } 294 }
284 } 295 }
285 296
286 DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() { 297 DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
287 DCHECK_EQ(read_type_, kReadAsArrayBuffer); 298 DCHECK_EQ(read_type_, kReadAsArrayBuffer);
299 if (array_buffer_result_)
300 return array_buffer_result_;
288 301
289 // If the loading is not started or an error occurs, return an empty result. 302 // If the loading is not started or an error occurs, return an empty result.
290 if (!raw_data_ || error_code_) 303 if (!raw_data_ || error_code_)
291 return nullptr; 304 return nullptr;
292 305
293 if (array_buffer_result_)
294 return array_buffer_result_;
295
296 DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); 306 DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer());
297 if (finished_loading_) { 307 if (finished_loading_) {
298 array_buffer_result_ = result; 308 array_buffer_result_ = result;
309 AdjustReportedMemoryUsageToV8(-1 * raw_data_->ByteLength());
310 raw_data_.reset();
299 } 311 }
300 return result; 312 return result;
301 } 313 }
302 314
303 String FileReaderLoader::StringResult() { 315 String FileReaderLoader::StringResult() {
304 DCHECK_NE(read_type_, kReadAsArrayBuffer); 316 DCHECK_NE(read_type_, kReadAsArrayBuffer);
305 DCHECK_NE(read_type_, kReadByClient); 317 DCHECK_NE(read_type_, kReadByClient);
306 318
307 // If the loading is not started or an error occurs, return an empty result. 319 if (!raw_data_ || error_code_ || is_raw_data_converted_)
308 if (!raw_data_ || error_code_)
309 return string_result_;
310
311 // If already converted from the raw data, return the result now.
312 if (is_raw_data_converted_)
313 return string_result_; 320 return string_result_;
314 321
315 switch (read_type_) { 322 switch (read_type_) {
316 case kReadAsArrayBuffer: 323 case kReadAsArrayBuffer:
317 // No conversion is needed. 324 // No conversion is needed.
318 break; 325 return string_result_;
319 case kReadAsBinaryString: 326 case kReadAsBinaryString:
320 string_result_ = raw_data_->ToString(); 327 SetStringResult(raw_data_->ToString());
321 is_raw_data_converted_ = true;
322 break; 328 break;
323 case kReadAsText: 329 case kReadAsText:
324 ConvertToText(); 330 SetStringResult(ConvertToText());
325 break; 331 break;
326 case kReadAsDataURL: 332 case kReadAsDataURL:
327 // Partial data is not supported when reading as data URL. 333 // Partial data is not supported when reading as data URL.
328 if (finished_loading_) 334 if (finished_loading_)
329 ConvertToDataURL(); 335 SetStringResult(ConvertToDataURL());
330 break; 336 break;
331 default: 337 default:
332 NOTREACHED(); 338 NOTREACHED();
333 } 339 }
334 340
341 if (finished_loading_) {
342 DCHECK(is_raw_data_converted_);
343 AdjustReportedMemoryUsageToV8(-1 * raw_data_->ByteLength());
344 raw_data_.reset();
345 }
335 return string_result_; 346 return string_result_;
336 } 347 }
337 348
338 void FileReaderLoader::ConvertToText() { 349 void FileReaderLoader::SetStringResult(const String& result) {
350 AdjustReportedMemoryUsageToV8(-1 * string_result_.CharactersSizeInBytes());
339 is_raw_data_converted_ = true; 351 is_raw_data_converted_ = true;
352 string_result_ = result;
353 AdjustReportedMemoryUsageToV8(string_result_.CharactersSizeInBytes());
354 }
340 355
341 if (!bytes_loaded_) { 356 String FileReaderLoader::ConvertToText() {
342 string_result_ = ""; 357 if (!bytes_loaded_)
343 return; 358 return "";
344 }
345 359
346 // Decode the data. 360 // Decode the data.
347 // The File API spec says that we should use the supplied encoding if it is 361 // The File API spec says that we should use the supplied encoding if it is
348 // valid. However, we choose to ignore this requirement in order to be 362 // valid. However, we choose to ignore this requirement in order to be
349 // consistent with how WebKit decodes the web content: always has the BOM 363 // consistent with how WebKit decodes the web content: always has the BOM
350 // override the provided encoding. 364 // override the provided encoding.
351 // FIXME: consider supporting incremental decoding to improve the perf. 365 // FIXME: consider supporting incremental decoding to improve the perf.
352 StringBuilder builder; 366 StringBuilder builder;
353 if (!decoder_) 367 if (!decoder_)
354 decoder_ = TextResourceDecoder::Create( 368 decoder_ = TextResourceDecoder::Create(
355 "text/plain", encoding_.IsValid() ? encoding_ : UTF8Encoding()); 369 "text/plain", encoding_.IsValid() ? encoding_ : UTF8Encoding());
356 builder.Append(decoder_->Decode(static_cast<const char*>(raw_data_->Data()), 370 builder.Append(decoder_->Decode(static_cast<const char*>(raw_data_->Data()),
357 raw_data_->ByteLength())); 371 raw_data_->ByteLength()));
358 372
359 if (finished_loading_) 373 if (finished_loading_)
360 builder.Append(decoder_->Flush()); 374 builder.Append(decoder_->Flush());
361 375
362 string_result_ = builder.ToString(); 376 return builder.ToString();
363 } 377 }
364 378
365 void FileReaderLoader::ConvertToDataURL() { 379 String FileReaderLoader::ConvertToDataURL() {
366 is_raw_data_converted_ = true;
367
368 StringBuilder builder; 380 StringBuilder builder;
369 builder.Append("data:"); 381 builder.Append("data:");
370 382
371 if (!bytes_loaded_) { 383 if (!bytes_loaded_)
372 string_result_ = builder.ToString(); 384 return builder.ToString();
373 return;
374 }
375 385
376 builder.Append(data_type_); 386 builder.Append(data_type_);
377 builder.Append(";base64,"); 387 builder.Append(";base64,");
378 388
379 Vector<char> out; 389 Vector<char> out;
380 Base64Encode(static_cast<const char*>(raw_data_->Data()), 390 Base64Encode(static_cast<const char*>(raw_data_->Data()),
381 raw_data_->ByteLength(), out); 391 raw_data_->ByteLength(), out);
382 out.push_back('\0'); 392 out.push_back('\0');
383 builder.Append(out.data()); 393 builder.Append(out.data());
384 394
385 string_result_ = builder.ToString(); 395 return builder.ToString();
386 } 396 }
387 397
388 void FileReaderLoader::SetEncoding(const String& encoding) { 398 void FileReaderLoader::SetEncoding(const String& encoding) {
389 if (!encoding.IsEmpty()) 399 if (!encoding.IsEmpty())
390 encoding_ = WTF::TextEncoding(encoding); 400 encoding_ = WTF::TextEncoding(encoding);
391 } 401 }
392 402
393 } // namespace blink 403 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fileapi/FileReaderLoader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698