| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1399 StringBuilderConcatHelper(*subject_, | 1399 StringBuilderConcatHelper(*subject_, |
| 1400 char_buffer, | 1400 char_buffer, |
| 1401 *parts_, | 1401 *parts_, |
| 1402 part_count_); | 1402 part_count_); |
| 1403 } | 1403 } |
| 1404 return joined_string; | 1404 return joined_string; |
| 1405 } | 1405 } |
| 1406 | 1406 |
| 1407 | 1407 |
| 1408 void IncrementCharacterCount(int by) { | 1408 void IncrementCharacterCount(int by) { |
| 1409 if (character_count_ > Smi::kMaxValue - by) { | 1409 if (character_count_ > String::kMaxLength - by) { |
| 1410 V8::FatalProcessOutOfMemory("String.replace result too large."); | 1410 V8::FatalProcessOutOfMemory("String.replace result too large."); |
| 1411 } | 1411 } |
| 1412 character_count_ += by; | 1412 character_count_ += by; |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 private: | 1415 private: |
| 1416 | 1416 |
| 1417 Handle<String> NewRawAsciiString(int size) { | 1417 Handle<String> NewRawAsciiString(int size) { |
| 1418 CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String); | 1418 CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String); |
| 1419 } | 1419 } |
| (...skipping 1825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3245 while (buffer->has_more()) { | 3245 while (buffer->has_more()) { |
| 3246 uint16_t character = buffer->GetNext(); | 3246 uint16_t character = buffer->GetNext(); |
| 3247 if (character >= 256) { | 3247 if (character >= 256) { |
| 3248 escaped_length += 6; | 3248 escaped_length += 6; |
| 3249 } else if (IsNotEscaped(character)) { | 3249 } else if (IsNotEscaped(character)) { |
| 3250 escaped_length++; | 3250 escaped_length++; |
| 3251 } else { | 3251 } else { |
| 3252 escaped_length += 3; | 3252 escaped_length += 3; |
| 3253 } | 3253 } |
| 3254 // We don't allow strings that are longer than a maximal length. | 3254 // We don't allow strings that are longer than a maximal length. |
| 3255 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. |
| 3255 if (escaped_length > String::kMaxLength) { | 3256 if (escaped_length > String::kMaxLength) { |
| 3256 Top::context()->mark_out_of_memory(); | 3257 Top::context()->mark_out_of_memory(); |
| 3257 return Failure::OutOfMemoryException(); | 3258 return Failure::OutOfMemoryException(); |
| 3258 } | 3259 } |
| 3259 } | 3260 } |
| 3260 } | 3261 } |
| 3261 // No length change implies no change. Return original string if no change. | 3262 // No length change implies no change. Return original string if no change. |
| 3262 if (escaped_length == length) { | 3263 if (escaped_length == length) { |
| 3263 return source; | 3264 return source; |
| 3264 } | 3265 } |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3806 | 3807 |
| 3807 if (array_length == 0) { | 3808 if (array_length == 0) { |
| 3808 return Heap::empty_string(); | 3809 return Heap::empty_string(); |
| 3809 } else if (array_length == 1) { | 3810 } else if (array_length == 1) { |
| 3810 Object* first = fixed_array->get(0); | 3811 Object* first = fixed_array->get(0); |
| 3811 if (first->IsString()) return first; | 3812 if (first->IsString()) return first; |
| 3812 } | 3813 } |
| 3813 | 3814 |
| 3814 bool ascii = special->IsAsciiRepresentation(); | 3815 bool ascii = special->IsAsciiRepresentation(); |
| 3815 int position = 0; | 3816 int position = 0; |
| 3817 int increment = 0; |
| 3816 for (int i = 0; i < array_length; i++) { | 3818 for (int i = 0; i < array_length; i++) { |
| 3817 Object* elt = fixed_array->get(i); | 3819 Object* elt = fixed_array->get(i); |
| 3818 if (elt->IsSmi()) { | 3820 if (elt->IsSmi()) { |
| 3819 int len = Smi::cast(elt)->value(); | 3821 int len = Smi::cast(elt)->value(); |
| 3820 int pos = len >> 11; | 3822 int pos = len >> 11; |
| 3821 len &= 0x7ff; | 3823 len &= 0x7ff; |
| 3822 if (pos + len > special_length) { | 3824 if (pos + len > special_length) { |
| 3823 return Top::Throw(Heap::illegal_argument_symbol()); | 3825 return Top::Throw(Heap::illegal_argument_symbol()); |
| 3824 } | 3826 } |
| 3825 position += len; | 3827 increment = len; |
| 3826 } else if (elt->IsString()) { | 3828 } else if (elt->IsString()) { |
| 3827 String* element = String::cast(elt); | 3829 String* element = String::cast(elt); |
| 3828 int element_length = element->length(); | 3830 int element_length = element->length(); |
| 3829 position += element_length; | 3831 increment = element_length; |
| 3830 if (ascii && !element->IsAsciiRepresentation()) { | 3832 if (ascii && !element->IsAsciiRepresentation()) { |
| 3831 ascii = false; | 3833 ascii = false; |
| 3832 } | 3834 } |
| 3833 } else { | 3835 } else { |
| 3834 return Top::Throw(Heap::illegal_argument_symbol()); | 3836 return Top::Throw(Heap::illegal_argument_symbol()); |
| 3835 } | 3837 } |
| 3836 if (position > String::kMaxLength) { | 3838 if (increment > String::kMaxLength - position) { |
| 3837 Top::context()->mark_out_of_memory(); | 3839 Top::context()->mark_out_of_memory(); |
| 3838 return Failure::OutOfMemoryException(); | 3840 return Failure::OutOfMemoryException(); |
| 3839 } | 3841 } |
| 3842 position += increment; |
| 3840 } | 3843 } |
| 3841 | 3844 |
| 3842 int length = position; | 3845 int length = position; |
| 3843 Object* object; | 3846 Object* object; |
| 3844 | 3847 |
| 3845 if (ascii) { | 3848 if (ascii) { |
| 3846 object = Heap::AllocateRawAsciiString(length); | 3849 object = Heap::AllocateRawAsciiString(length); |
| 3847 if (object->IsFailure()) return object; | 3850 if (object->IsFailure()) return object; |
| 3848 SeqAsciiString* answer = SeqAsciiString::cast(object); | 3851 SeqAsciiString* answer = SeqAsciiString::cast(object); |
| 3849 StringBuilderConcatHelper(special, | 3852 StringBuilderConcatHelper(special, |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5225 * | 5228 * |
| 5226 * An index limit is used to deal with the situation that a result array | 5229 * An index limit is used to deal with the situation that a result array |
| 5227 * length overflows 32-bit non-negative integer. | 5230 * length overflows 32-bit non-negative integer. |
| 5228 */ | 5231 */ |
| 5229 class ArrayConcatVisitor { | 5232 class ArrayConcatVisitor { |
| 5230 public: | 5233 public: |
| 5231 ArrayConcatVisitor(Handle<FixedArray> storage, | 5234 ArrayConcatVisitor(Handle<FixedArray> storage, |
| 5232 uint32_t index_limit, | 5235 uint32_t index_limit, |
| 5233 bool fast_elements) : | 5236 bool fast_elements) : |
| 5234 storage_(storage), index_limit_(index_limit), | 5237 storage_(storage), index_limit_(index_limit), |
| 5235 fast_elements_(fast_elements), index_offset_(0) { } | 5238 index_offset_(0), fast_elements_(fast_elements) { } |
| 5236 | 5239 |
| 5237 void visit(uint32_t i, Handle<Object> elm) { | 5240 void visit(uint32_t i, Handle<Object> elm) { |
| 5238 uint32_t index = i + index_offset_; | 5241 if (i >= index_limit_ - index_offset_) return; |
| 5239 if (index >= index_limit_) return; | 5242 uint32_t index = index_offset_ + i; |
| 5240 | 5243 |
| 5241 if (fast_elements_) { | 5244 if (fast_elements_) { |
| 5242 ASSERT(index < static_cast<uint32_t>(storage_->length())); | 5245 ASSERT(index < static_cast<uint32_t>(storage_->length())); |
| 5243 storage_->set(index, *elm); | 5246 storage_->set(index, *elm); |
| 5244 | 5247 |
| 5245 } else { | 5248 } else { |
| 5246 Handle<NumberDictionary> dict = Handle<NumberDictionary>::cast(storage_); | 5249 Handle<NumberDictionary> dict = Handle<NumberDictionary>::cast(storage_); |
| 5247 Handle<NumberDictionary> result = | 5250 Handle<NumberDictionary> result = |
| 5248 Factory::DictionaryAtNumberPut(dict, index, elm); | 5251 Factory::DictionaryAtNumberPut(dict, index, elm); |
| 5249 if (!result.is_identical_to(dict)) | 5252 if (!result.is_identical_to(dict)) |
| 5250 storage_ = result; | 5253 storage_ = result; |
| 5251 } | 5254 } |
| 5252 } | 5255 } |
| 5253 | 5256 |
| 5254 void increase_index_offset(uint32_t delta) { | 5257 void increase_index_offset(uint32_t delta) { |
| 5255 index_offset_ += delta; | 5258 if (index_limit_ - index_offset_ < delta) { |
| 5259 index_offset_ = index_limit_; |
| 5260 } else { |
| 5261 index_offset_ += delta; |
| 5262 } |
| 5256 } | 5263 } |
| 5257 | 5264 |
| 5258 Handle<FixedArray> storage() { return storage_; } | 5265 Handle<FixedArray> storage() { return storage_; } |
| 5259 | 5266 |
| 5260 private: | 5267 private: |
| 5261 Handle<FixedArray> storage_; | 5268 Handle<FixedArray> storage_; |
| 5269 // Limit on the accepted indices. Elements with indices larger than the |
| 5270 // limit are ignored by the visitor. |
| 5262 uint32_t index_limit_; | 5271 uint32_t index_limit_; |
| 5272 // Index after last seen index. Always less than or equal to index_limit_. |
| 5273 uint32_t index_offset_; |
| 5263 bool fast_elements_; | 5274 bool fast_elements_; |
| 5264 uint32_t index_offset_; | |
| 5265 }; | 5275 }; |
| 5266 | 5276 |
| 5267 | 5277 |
| 5268 template<class ExternalArrayClass, class ElementType> | 5278 template<class ExternalArrayClass, class ElementType> |
| 5269 static uint32_t IterateExternalArrayElements(Handle<JSObject> receiver, | 5279 static uint32_t IterateExternalArrayElements(Handle<JSObject> receiver, |
| 5270 bool elements_are_ints, | 5280 bool elements_are_ints, |
| 5271 bool elements_are_guaranteed_smis, | 5281 bool elements_are_guaranteed_smis, |
| 5272 uint32_t range, | 5282 uint32_t range, |
| 5273 ArrayConcatVisitor* visitor) { | 5283 ArrayConcatVisitor* visitor) { |
| 5274 Handle<ExternalArrayClass> array( | 5284 Handle<ExternalArrayClass> array( |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5426 | 5436 |
| 5427 /** | 5437 /** |
| 5428 * A helper function that visits elements of an Array object, and elements | 5438 * A helper function that visits elements of an Array object, and elements |
| 5429 * on its prototypes. | 5439 * on its prototypes. |
| 5430 * | 5440 * |
| 5431 * Elements on prototypes are visited first, and only elements whose indices | 5441 * Elements on prototypes are visited first, and only elements whose indices |
| 5432 * less than Array length are visited. | 5442 * less than Array length are visited. |
| 5433 * | 5443 * |
| 5434 * If a ArrayConcatVisitor object is given, the visitor is called with | 5444 * If a ArrayConcatVisitor object is given, the visitor is called with |
| 5435 * parameters, element's index + visitor_index_offset and the element. | 5445 * parameters, element's index + visitor_index_offset and the element. |
| 5446 * |
| 5447 * The returned number of elements is an upper bound on the actual number |
| 5448 * of elements added. If the same element occurs in more than one object |
| 5449 * in the array's prototype chain, it will be counted more than once, but |
| 5450 * will only occur once in the result. |
| 5436 */ | 5451 */ |
| 5437 static uint32_t IterateArrayAndPrototypeElements(Handle<JSArray> array, | 5452 static uint32_t IterateArrayAndPrototypeElements(Handle<JSArray> array, |
| 5438 ArrayConcatVisitor* visitor) { | 5453 ArrayConcatVisitor* visitor) { |
| 5439 uint32_t range = static_cast<uint32_t>(array->length()->Number()); | 5454 uint32_t range = static_cast<uint32_t>(array->length()->Number()); |
| 5440 Handle<Object> obj = array; | 5455 Handle<Object> obj = array; |
| 5441 | 5456 |
| 5442 static const int kEstimatedPrototypes = 3; | 5457 static const int kEstimatedPrototypes = 3; |
| 5443 List< Handle<JSObject> > objects(kEstimatedPrototypes); | 5458 List< Handle<JSObject> > objects(kEstimatedPrototypes); |
| 5444 | 5459 |
| 5445 // Visit prototype first. If an element on the prototype is shadowed by | 5460 // Visit prototype first. If an element on the prototype is shadowed by |
| 5446 // the inheritor using the same index, the ArrayConcatVisitor visits | 5461 // the inheritor using the same index, the ArrayConcatVisitor visits |
| 5447 // the prototype element before the shadowing element. | 5462 // the prototype element before the shadowing element. |
| 5448 // The visitor can simply overwrite the old value by new value using | 5463 // The visitor can simply overwrite the old value by new value using |
| 5449 // the same index. This follows Array::concat semantics. | 5464 // the same index. This follows Array::concat semantics. |
| 5450 while (!obj->IsNull()) { | 5465 while (!obj->IsNull()) { |
| 5451 objects.Add(Handle<JSObject>::cast(obj)); | 5466 objects.Add(Handle<JSObject>::cast(obj)); |
| 5452 obj = Handle<Object>(obj->GetPrototype()); | 5467 obj = Handle<Object>(obj->GetPrototype()); |
| 5453 } | 5468 } |
| 5454 | 5469 |
| 5455 uint32_t nof_elements = 0; | 5470 uint32_t nof_elements = 0; |
| 5456 for (int i = objects.length() - 1; i >= 0; i--) { | 5471 for (int i = objects.length() - 1; i >= 0; i--) { |
| 5457 Handle<JSObject> obj = objects[i]; | 5472 Handle<JSObject> obj = objects[i]; |
| 5458 nof_elements += | 5473 uint32_t encountered_elements = |
| 5459 IterateElements(Handle<JSObject>::cast(obj), range, visitor); | 5474 IterateElements(Handle<JSObject>::cast(obj), range, visitor); |
| 5475 |
| 5476 if (encountered_elements > JSObject::kMaxElementCount - nof_elements) { |
| 5477 nof_elements = JSObject::kMaxElementCount; |
| 5478 } else { |
| 5479 nof_elements += encountered_elements; |
| 5480 } |
| 5460 } | 5481 } |
| 5461 | 5482 |
| 5462 return nof_elements; | 5483 return nof_elements; |
| 5463 } | 5484 } |
| 5464 | 5485 |
| 5465 | 5486 |
| 5466 /** | 5487 /** |
| 5467 * A helper function of Runtime_ArrayConcat. | 5488 * A helper function of Runtime_ArrayConcat. |
| 5468 * | 5489 * |
| 5469 * The first argument is an Array of arrays and objects. It is the | 5490 * The first argument is an Array of arrays and objects. It is the |
| 5470 * same as the arguments array of Array::concat JS function. | 5491 * same as the arguments array of Array::concat JS function. |
| 5471 * | 5492 * |
| 5472 * If an argument is an Array object, the function visits array | 5493 * If an argument is an Array object, the function visits array |
| 5473 * elements. If an argument is not an Array object, the function | 5494 * elements. If an argument is not an Array object, the function |
| 5474 * visits the object as if it is an one-element array. | 5495 * visits the object as if it is an one-element array. |
| 5475 * | 5496 * |
| 5476 * If the result array index overflows 32-bit integer, the rounded | 5497 * If the result array index overflows 32-bit unsigned integer, the rounded |
| 5477 * non-negative number is used as new length. For example, if one | 5498 * non-negative number is used as new length. For example, if one |
| 5478 * array length is 2^32 - 1, second array length is 1, the | 5499 * array length is 2^32 - 1, second array length is 1, the |
| 5479 * concatenated array length is 0. | 5500 * concatenated array length is 0. |
| 5501 * TODO(lrn) Change length behavior to ECMAScript 5 specification (length |
| 5502 * is one more than the last array index to get a value assigned). |
| 5480 */ | 5503 */ |
| 5481 static uint32_t IterateArguments(Handle<JSArray> arguments, | 5504 static uint32_t IterateArguments(Handle<JSArray> arguments, |
| 5482 ArrayConcatVisitor* visitor) { | 5505 ArrayConcatVisitor* visitor) { |
| 5483 uint32_t visited_elements = 0; | 5506 uint32_t visited_elements = 0; |
| 5484 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 5507 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
| 5485 | 5508 |
| 5486 for (uint32_t i = 0; i < num_of_args; i++) { | 5509 for (uint32_t i = 0; i < num_of_args; i++) { |
| 5487 Handle<Object> obj(arguments->GetElement(i)); | 5510 Handle<Object> obj(arguments->GetElement(i)); |
| 5488 if (obj->IsJSArray()) { | 5511 if (obj->IsJSArray()) { |
| 5489 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 5512 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
| 5490 uint32_t len = static_cast<uint32_t>(array->length()->Number()); | 5513 uint32_t len = static_cast<uint32_t>(array->length()->Number()); |
| 5491 uint32_t nof_elements = | 5514 uint32_t nof_elements = |
| 5492 IterateArrayAndPrototypeElements(array, visitor); | 5515 IterateArrayAndPrototypeElements(array, visitor); |
| 5493 // Total elements of array and its prototype chain can be more than | 5516 // Total elements of array and its prototype chain can be more than |
| 5494 // the array length, but ArrayConcat can only concatenate at most | 5517 // the array length, but ArrayConcat can only concatenate at most |
| 5495 // the array length number of elements. | 5518 // the array length number of elements. We use the length as an estimate |
| 5496 visited_elements += (nof_elements > len) ? len : nof_elements; | 5519 // for the actual number of elements added. |
| 5520 uint32_t added_elements = (nof_elements > len) ? len : nof_elements; |
| 5521 if (JSArray::kMaxElementCount - visited_elements < added_elements) { |
| 5522 visited_elements = JSArray::kMaxElementCount; |
| 5523 } else { |
| 5524 visited_elements += added_elements; |
| 5525 } |
| 5497 if (visitor) visitor->increase_index_offset(len); | 5526 if (visitor) visitor->increase_index_offset(len); |
| 5498 | |
| 5499 } else { | 5527 } else { |
| 5500 if (visitor) { | 5528 if (visitor) { |
| 5501 visitor->visit(0, obj); | 5529 visitor->visit(0, obj); |
| 5502 visitor->increase_index_offset(1); | 5530 visitor->increase_index_offset(1); |
| 5503 } | 5531 } |
| 5504 visited_elements++; | 5532 if (visited_elements < JSArray::kMaxElementCount) { |
| 5533 visited_elements++; |
| 5534 } |
| 5505 } | 5535 } |
| 5506 } | 5536 } |
| 5507 return visited_elements; | 5537 return visited_elements; |
| 5508 } | 5538 } |
| 5509 | 5539 |
| 5510 | 5540 |
| 5511 /** | 5541 /** |
| 5512 * Array::concat implementation. | 5542 * Array::concat implementation. |
| 5513 * See ECMAScript 262, 15.4.4.4. | 5543 * See ECMAScript 262, 15.4.4.4. |
| 5544 * TODO(lrn): Fix non-compliance for very large concatenations and update to |
| 5545 * following the ECMAScript 5 specification. |
| 5514 */ | 5546 */ |
| 5515 static Object* Runtime_ArrayConcat(Arguments args) { | 5547 static Object* Runtime_ArrayConcat(Arguments args) { |
| 5516 ASSERT(args.length() == 1); | 5548 ASSERT(args.length() == 1); |
| 5517 HandleScope handle_scope; | 5549 HandleScope handle_scope; |
| 5518 | 5550 |
| 5519 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); | 5551 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); |
| 5520 Handle<JSArray> arguments(arg_arrays); | 5552 Handle<JSArray> arguments(arg_arrays); |
| 5521 | 5553 |
| 5522 // Pass 1: estimate the number of elements of the result | 5554 // Pass 1: estimate the number of elements of the result |
| 5523 // (it could be more than real numbers if prototype has elements). | 5555 // (it could be more than real numbers if prototype has elements). |
| 5524 uint32_t result_length = 0; | 5556 uint32_t result_length = 0; |
| 5525 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 5557 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
| 5526 | 5558 |
| 5527 { AssertNoAllocation nogc; | 5559 { AssertNoAllocation nogc; |
| 5528 for (uint32_t i = 0; i < num_of_args; i++) { | 5560 for (uint32_t i = 0; i < num_of_args; i++) { |
| 5529 Object* obj = arguments->GetElement(i); | 5561 Object* obj = arguments->GetElement(i); |
| 5562 uint32_t length_estimate; |
| 5530 if (obj->IsJSArray()) { | 5563 if (obj->IsJSArray()) { |
| 5531 result_length += | 5564 length_estimate = |
| 5532 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); | 5565 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); |
| 5533 } else { | 5566 } else { |
| 5534 result_length++; | 5567 length_estimate = 1; |
| 5535 } | 5568 } |
| 5569 if (JSObject::kMaxElementCount - result_length < length_estimate) { |
| 5570 result_length = JSObject::kMaxElementCount; |
| 5571 break; |
| 5572 } |
| 5573 result_length += length_estimate; |
| 5536 } | 5574 } |
| 5537 } | 5575 } |
| 5538 | 5576 |
| 5539 // Allocate an empty array, will set length and content later. | 5577 // Allocate an empty array, will set length and content later. |
| 5540 Handle<JSArray> result = Factory::NewJSArray(0); | 5578 Handle<JSArray> result = Factory::NewJSArray(0); |
| 5541 | 5579 |
| 5542 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); | 5580 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); |
| 5543 // If estimated number of elements is more than half of length, a | 5581 // If estimated number of elements is more than half of length, a |
| 5544 // fixed array (fast case) is more time and space-efficient than a | 5582 // fixed array (fast case) is more time and space-efficient than a |
| 5545 // dictionary. | 5583 // dictionary. |
| (...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7858 } else { | 7896 } else { |
| 7859 // Handle last resort GC and make sure to allow future allocations | 7897 // Handle last resort GC and make sure to allow future allocations |
| 7860 // to grow the heap without causing GCs (if possible). | 7898 // to grow the heap without causing GCs (if possible). |
| 7861 Counters::gc_last_resort_from_js.Increment(); | 7899 Counters::gc_last_resort_from_js.Increment(); |
| 7862 Heap::CollectAllGarbage(false); | 7900 Heap::CollectAllGarbage(false); |
| 7863 } | 7901 } |
| 7864 } | 7902 } |
| 7865 | 7903 |
| 7866 | 7904 |
| 7867 } } // namespace v8::internal | 7905 } } // namespace v8::internal |
| OLD | NEW |