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

Side by Side Diff: src/runtime.cc

Issue 80753003: Merged r17526, r17545, r17620, r17747 into 3.22 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.22
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.cc ('k') | src/unicode.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 6212 matching lines...) Expand 10 before | Expand all | Expand 10 after
6223 6223
6224 // Create a number object from the value. 6224 // Create a number object from the value.
6225 return isolate->heap()->NumberFromDouble(value); 6225 return isolate->heap()->NumberFromDouble(value);
6226 } 6226 }
6227 6227
6228 6228
6229 template <class Converter> 6229 template <class Converter>
6230 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( 6230 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
6231 Isolate* isolate, 6231 Isolate* isolate,
6232 String* s, 6232 String* s,
6233 String::Encoding result_encoding,
6233 int length, 6234 int length,
6234 int input_string_length, 6235 int input_string_length,
6235 unibrow::Mapping<Converter, 128>* mapping) { 6236 unibrow::Mapping<Converter, 128>* mapping) {
6236 // We try this twice, once with the assumption that the result is no longer 6237 // We try this twice, once with the assumption that the result is no longer
6237 // than the input and, if that assumption breaks, again with the exact 6238 // than the input and, if that assumption breaks, again with the exact
6238 // length. This may not be pretty, but it is nicer than what was here before 6239 // length. This may not be pretty, but it is nicer than what was here before
6239 // and I hereby claim my vaffel-is. 6240 // and I hereby claim my vaffel-is.
6240 // 6241 //
6241 // Allocate the resulting string. 6242 // Allocate the resulting string.
6242 // 6243 //
6243 // NOTE: This assumes that the upper/lower case of an ASCII 6244 // NOTE: This assumes that the upper/lower case of an ASCII
6244 // character is also ASCII. This is currently the case, but it 6245 // character is also ASCII. This is currently the case, but it
6245 // might break in the future if we implement more context and locale 6246 // might break in the future if we implement more context and locale
6246 // dependent upper/lower conversions. 6247 // dependent upper/lower conversions.
6247 Object* o; 6248 Object* o;
6248 { MaybeObject* maybe_o = s->IsOneByteRepresentation() 6249 { MaybeObject* maybe_o = result_encoding == String::ONE_BYTE_ENCODING
6249 ? isolate->heap()->AllocateRawOneByteString(length) 6250 ? isolate->heap()->AllocateRawOneByteString(length)
6250 : isolate->heap()->AllocateRawTwoByteString(length); 6251 : isolate->heap()->AllocateRawTwoByteString(length);
6251 if (!maybe_o->ToObject(&o)) return maybe_o; 6252 if (!maybe_o->ToObject(&o)) return maybe_o;
6252 } 6253 }
6253 String* result = String::cast(o); 6254 String* result = String::cast(o);
6254 bool has_changed_character = false; 6255 bool has_changed_character = false;
6255 6256
6257 DisallowHeapAllocation no_gc;
6258
6256 // Convert all characters to upper case, assuming that they will fit 6259 // Convert all characters to upper case, assuming that they will fit
6257 // in the buffer 6260 // in the buffer
6258 Access<ConsStringIteratorOp> op( 6261 Access<ConsStringIteratorOp> op(
6259 isolate->runtime_state()->string_iterator()); 6262 isolate->runtime_state()->string_iterator());
6260 StringCharacterStream stream(s, op.value()); 6263 StringCharacterStream stream(s, op.value());
6261 unibrow::uchar chars[Converter::kMaxWidth]; 6264 unibrow::uchar chars[Converter::kMaxWidth];
6262 // We can assume that the string is not empty 6265 // We can assume that the string is not empty
6263 uc32 current = stream.GetNext(); 6266 uc32 current = stream.GetNext();
6267 // y with umlauts is the only character that stops fitting into one-byte
6268 // when converting to uppercase.
6269 static const uc32 yuml_code = 0xff;
6270 bool ignore_yuml = result->IsSeqTwoByteString() || Converter::kIsToLower;
6264 for (int i = 0; i < length;) { 6271 for (int i = 0; i < length;) {
6265 bool has_next = stream.HasMore(); 6272 bool has_next = stream.HasMore();
6266 uc32 next = has_next ? stream.GetNext() : 0; 6273 uc32 next = has_next ? stream.GetNext() : 0;
6267 int char_length = mapping->get(current, next, chars); 6274 int char_length = mapping->get(current, next, chars);
6268 if (char_length == 0) { 6275 if (char_length == 0) {
6269 // The case conversion of this character is the character itself. 6276 // The case conversion of this character is the character itself.
6270 result->Set(i, current); 6277 result->Set(i, current);
6271 i++; 6278 i++;
6272 } else if (char_length == 1) { 6279 } else if (char_length == 1 && (ignore_yuml || current != yuml_code)) {
6273 // Common case: converting the letter resulted in one character. 6280 // Common case: converting the letter resulted in one character.
6274 ASSERT(static_cast<uc32>(chars[0]) != current); 6281 ASSERT(static_cast<uc32>(chars[0]) != current);
6275 result->Set(i, chars[0]); 6282 result->Set(i, chars[0]);
6276 has_changed_character = true; 6283 has_changed_character = true;
6277 i++; 6284 i++;
6278 } else if (length == input_string_length) { 6285 } else if (length == input_string_length) {
6286 bool found_yuml = (current == yuml_code);
6279 // We've assumed that the result would be as long as the 6287 // We've assumed that the result would be as long as the
6280 // input but here is a character that converts to several 6288 // input but here is a character that converts to several
6281 // characters. No matter, we calculate the exact length 6289 // characters. No matter, we calculate the exact length
6282 // of the result and try the whole thing again. 6290 // of the result and try the whole thing again.
6283 // 6291 //
6284 // Note that this leaves room for optimization. We could just 6292 // Note that this leaves room for optimization. We could just
6285 // memcpy what we already have to the result string. Also, 6293 // memcpy what we already have to the result string. Also,
6286 // the result string is the last object allocated we could 6294 // the result string is the last object allocated we could
6287 // "realloc" it and probably, in the vast majority of cases, 6295 // "realloc" it and probably, in the vast majority of cases,
6288 // extend the existing string to be able to hold the full 6296 // extend the existing string to be able to hold the full
6289 // result. 6297 // result.
6290 int next_length = 0; 6298 int next_length = 0;
6291 if (has_next) { 6299 if (has_next) {
6292 next_length = mapping->get(next, 0, chars); 6300 next_length = mapping->get(next, 0, chars);
6293 if (next_length == 0) next_length = 1; 6301 if (next_length == 0) next_length = 1;
6294 } 6302 }
6295 int current_length = i + char_length + next_length; 6303 int current_length = i + char_length + next_length;
6296 while (stream.HasMore()) { 6304 while (stream.HasMore()) {
6297 current = stream.GetNext(); 6305 current = stream.GetNext();
6306 found_yuml |= (current == yuml_code);
6298 // NOTE: we use 0 as the next character here because, while 6307 // NOTE: we use 0 as the next character here because, while
6299 // the next character may affect what a character converts to, 6308 // the next character may affect what a character converts to,
6300 // it does not in any case affect the length of what it convert 6309 // it does not in any case affect the length of what it convert
6301 // to. 6310 // to.
6302 int char_length = mapping->get(current, 0, chars); 6311 int char_length = mapping->get(current, 0, chars);
6303 if (char_length == 0) char_length = 1; 6312 if (char_length == 0) char_length = 1;
6304 current_length += char_length; 6313 current_length += char_length;
6305 if (current_length > Smi::kMaxValue) { 6314 if (current_length > Smi::kMaxValue) {
6306 isolate->context()->mark_out_of_memory(); 6315 isolate->context()->mark_out_of_memory();
6307 return Failure::OutOfMemoryException(0x13); 6316 return Failure::OutOfMemoryException(0x13);
6308 } 6317 }
6309 } 6318 }
6310 // Try again with the real length. 6319 // Try again with the real length. Return signed if we need
6311 return Smi::FromInt(current_length); 6320 // to allocate a two-byte string for y-umlaut to uppercase.
6321 return (found_yuml && !ignore_yuml) ? Smi::FromInt(-current_length)
6322 : Smi::FromInt(current_length);
6312 } else { 6323 } else {
6313 for (int j = 0; j < char_length; j++) { 6324 for (int j = 0; j < char_length; j++) {
6314 result->Set(i, chars[j]); 6325 result->Set(i, chars[j]);
6315 i++; 6326 i++;
6316 } 6327 }
6317 has_changed_character = true; 6328 has_changed_character = true;
6318 } 6329 }
6319 current = next; 6330 current = next;
6320 } 6331 }
6321 if (has_changed_character) { 6332 if (has_changed_character) {
(...skipping 25 matching lines...) Expand all
6347 // further simplified. 6358 // further simplified.
6348 ASSERT(0 < m && m < n); 6359 ASSERT(0 < m && m < n);
6349 // Has high bit set in every w byte less than n. 6360 // Has high bit set in every w byte less than n.
6350 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; 6361 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6351 // Has high bit set in every w byte greater than m. 6362 // Has high bit set in every w byte greater than m.
6352 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); 6363 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6353 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); 6364 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6354 } 6365 }
6355 6366
6356 6367
6357 enum AsciiCaseConversion { 6368 template<class Converter>
6358 ASCII_TO_LOWER, 6369 static bool FastAsciiConvert(char* dst,
6359 ASCII_TO_UPPER 6370 char* src,
6360 }; 6371 int length,
6361 6372 bool* changed_out) {
6362
6363 template <AsciiCaseConversion dir>
6364 struct FastAsciiConverter {
6365 static bool Convert(char* dst, char* src, int length, bool* changed_out) {
6366 #ifdef DEBUG 6373 #ifdef DEBUG
6367 char* saved_dst = dst; 6374 char* saved_dst = dst;
6368 char* saved_src = src; 6375 char* saved_src = src;
6369 #endif 6376 #endif
6370 // We rely on the distance between upper and lower case letters 6377 DisallowHeapAllocation no_gc;
6371 // being a known power of 2. 6378 // We rely on the distance between upper and lower case letters
6372 ASSERT('a' - 'A' == (1 << 5)); 6379 // being a known power of 2.
6373 // Boundaries for the range of input characters than require conversion. 6380 ASSERT('a' - 'A' == (1 << 5));
6374 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; 6381 // Boundaries for the range of input characters than require conversion.
6375 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; 6382 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6376 bool changed = false; 6383 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6377 uintptr_t or_acc = 0; 6384 bool changed = false;
6378 char* const limit = src + length; 6385 uintptr_t or_acc = 0;
6386 char* const limit = src + length;
6379 #ifdef V8_HOST_CAN_READ_UNALIGNED 6387 #ifdef V8_HOST_CAN_READ_UNALIGNED
6380 // Process the prefix of the input that requires no conversion one 6388 // Process the prefix of the input that requires no conversion one
6381 // (machine) word at a time. 6389 // (machine) word at a time.
6382 while (src <= limit - sizeof(uintptr_t)) { 6390 while (src <= limit - sizeof(uintptr_t)) {
6383 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); 6391 uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
6384 or_acc |= w; 6392 or_acc |= w;
6385 if (AsciiRangeMask(w, lo, hi) != 0) { 6393 if (AsciiRangeMask(w, lo, hi) != 0) {
6386 changed = true; 6394 changed = true;
6387 break; 6395 break;
6388 }
6389 *reinterpret_cast<uintptr_t*>(dst) = w;
6390 src += sizeof(uintptr_t);
6391 dst += sizeof(uintptr_t);
6392 } 6396 }
6393 // Process the remainder of the input performing conversion when 6397 *reinterpret_cast<uintptr_t*>(dst) = w;
6394 // required one word at a time. 6398 src += sizeof(uintptr_t);
6395 while (src <= limit - sizeof(uintptr_t)) { 6399 dst += sizeof(uintptr_t);
6396 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); 6400 }
6397 or_acc |= w; 6401 // Process the remainder of the input performing conversion when
6398 uintptr_t m = AsciiRangeMask(w, lo, hi); 6402 // required one word at a time.
6399 // The mask has high (7th) bit set in every byte that needs 6403 while (src <= limit - sizeof(uintptr_t)) {
6400 // conversion and we know that the distance between cases is 6404 uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
6401 // 1 << 5. 6405 or_acc |= w;
6402 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); 6406 uintptr_t m = AsciiRangeMask(w, lo, hi);
6403 src += sizeof(uintptr_t); 6407 // The mask has high (7th) bit set in every byte that needs
6404 dst += sizeof(uintptr_t); 6408 // conversion and we know that the distance between cases is
6409 // 1 << 5.
6410 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6411 src += sizeof(uintptr_t);
6412 dst += sizeof(uintptr_t);
6413 }
6414 #endif
6415 // Process the last few bytes of the input (or the whole input if
6416 // unaligned access is not supported).
6417 while (src < limit) {
6418 char c = *src;
6419 or_acc |= c;
6420 if (lo < c && c < hi) {
6421 c ^= (1 << 5);
6422 changed = true;
6405 } 6423 }
6406 #endif 6424 *dst = c;
6407 // Process the last few bytes of the input (or the whole input if 6425 ++src;
6408 // unaligned access is not supported). 6426 ++dst;
6409 while (src < limit) { 6427 }
6410 char c = *src; 6428 if ((or_acc & kAsciiMask) != 0) {
6411 or_acc |= c; 6429 return false;
6412 if (lo < c && c < hi) {
6413 c ^= (1 << 5);
6414 changed = true;
6415 }
6416 *dst = c;
6417 ++src;
6418 ++dst;
6419 }
6420 if ((or_acc & kAsciiMask) != 0) {
6421 return false;
6422 }
6423 #ifdef DEBUG
6424 CheckConvert(saved_dst, saved_src, length, changed);
6425 #endif
6426 *changed_out = changed;
6427 return true;
6428 } 6430 }
6429 6431
6432 ASSERT(CheckFastAsciiConvert(
6433 saved_dst, saved_src, length, changed, Converter::kIsToLower));
6434
6435 *changed_out = changed;
6436 return true;
6437 }
6438
6430 #ifdef DEBUG 6439 #ifdef DEBUG
6431 static void CheckConvert(char* dst, char* src, int length, bool changed) { 6440 static bool CheckFastAsciiConvert(char* dst,
6432 bool expected_changed = false; 6441 char* src,
6433 for (int i = 0; i < length; i++) { 6442 int length,
6434 if (dst[i] == src[i]) continue; 6443 bool changed,
6435 expected_changed = true; 6444 bool is_to_lower) {
6436 if (dir == ASCII_TO_LOWER) { 6445 bool expected_changed = false;
6437 ASSERT('A' <= src[i] && src[i] <= 'Z'); 6446 for (int i = 0; i < length; i++) {
6438 ASSERT(dst[i] == src[i] + ('a' - 'A')); 6447 if (dst[i] == src[i]) continue;
6439 } else { 6448 expected_changed = true;
6440 ASSERT(dir == ASCII_TO_UPPER); 6449 if (is_to_lower) {
6441 ASSERT('a' <= src[i] && src[i] <= 'z'); 6450 ASSERT('A' <= src[i] && src[i] <= 'Z');
6442 ASSERT(dst[i] == src[i] - ('a' - 'A')); 6451 ASSERT(dst[i] == src[i] + ('a' - 'A'));
6443 } 6452 } else {
6453 ASSERT('a' <= src[i] && src[i] <= 'z');
6454 ASSERT(dst[i] == src[i] - ('a' - 'A'));
6444 } 6455 }
6445 ASSERT(expected_changed == changed);
6446 } 6456 }
6457 return (expected_changed == changed);
6458 }
6447 #endif 6459 #endif
6448 };
6449
6450
6451 struct ToLowerTraits {
6452 typedef unibrow::ToLowercase UnibrowConverter;
6453
6454 typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter;
6455 };
6456
6457
6458 struct ToUpperTraits {
6459 typedef unibrow::ToUppercase UnibrowConverter;
6460
6461 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter;
6462 };
6463 6460
6464 } // namespace 6461 } // namespace
6465 6462
6466 6463
6467 template <typename ConvertTraits> 6464 template <class Converter>
6468 MUST_USE_RESULT static MaybeObject* ConvertCase( 6465 MUST_USE_RESULT static MaybeObject* ConvertCase(
6469 Arguments args, 6466 Arguments args,
6470 Isolate* isolate, 6467 Isolate* isolate,
6471 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { 6468 unibrow::Mapping<Converter, 128>* mapping) {
6472 SealHandleScope shs(isolate); 6469 SealHandleScope shs(isolate);
6473 CONVERT_ARG_CHECKED(String, s, 0); 6470 CONVERT_ARG_CHECKED(String, s, 0);
6474 s = s->TryFlattenGetString(); 6471 s = s->TryFlattenGetString();
6475 6472
6476 const int length = s->length(); 6473 const int length = s->length();
6477 // Assume that the string is not empty; we need this assumption later 6474 // Assume that the string is not empty; we need this assumption later
6478 if (length == 0) return s; 6475 if (length == 0) return s;
6479 6476
6480 // Simpler handling of ASCII strings. 6477 // Simpler handling of ASCII strings.
6481 // 6478 //
6482 // NOTE: This assumes that the upper/lower case of an ASCII 6479 // NOTE: This assumes that the upper/lower case of an ASCII
6483 // character is also ASCII. This is currently the case, but it 6480 // character is also ASCII. This is currently the case, but it
6484 // might break in the future if we implement more context and locale 6481 // might break in the future if we implement more context and locale
6485 // dependent upper/lower conversions. 6482 // dependent upper/lower conversions.
6486 if (s->IsSeqOneByteString()) { 6483 if (s->IsSeqOneByteString()) {
6487 Object* o; 6484 Object* o;
6488 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); 6485 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length);
6489 if (!maybe_o->ToObject(&o)) return maybe_o; 6486 if (!maybe_o->ToObject(&o)) return maybe_o;
6490 } 6487 }
6491 SeqOneByteString* result = SeqOneByteString::cast(o); 6488 SeqOneByteString* result = SeqOneByteString::cast(o);
6492 bool has_changed_character; 6489 bool has_changed_character;
6493 bool is_ascii = ConvertTraits::AsciiConverter::Convert( 6490 bool is_ascii = FastAsciiConvert<Converter>(
6494 reinterpret_cast<char*>(result->GetChars()), 6491 reinterpret_cast<char*>(result->GetChars()),
6495 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), 6492 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
6496 length, 6493 length,
6497 &has_changed_character); 6494 &has_changed_character);
6498 // If not ASCII, we discard the result and take the 2 byte path. 6495 // If not ASCII, we discard the result and take the 2 byte path.
6499 if (is_ascii) { 6496 if (is_ascii) {
6500 return has_changed_character ? result : s; 6497 return has_changed_character ? result : s;
6501 } 6498 }
6502 } 6499 }
6503 6500
6501 String::Encoding result_encoding = s->IsOneByteRepresentation()
6502 ? String::ONE_BYTE_ENCODING : String::TWO_BYTE_ENCODING;
6504 Object* answer; 6503 Object* answer;
6505 { MaybeObject* maybe_answer = 6504 { MaybeObject* maybe_answer = ConvertCaseHelper(
6506 ConvertCaseHelper(isolate, s, length, length, mapping); 6505 isolate, s, result_encoding, length, length, mapping);
6507 if (!maybe_answer->ToObject(&answer)) return maybe_answer; 6506 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6508 } 6507 }
6509 if (answer->IsSmi()) { 6508 if (answer->IsSmi()) {
6510 // Retry with correct length. 6509 int new_length = Smi::cast(answer)->value();
6511 { MaybeObject* maybe_answer = 6510 if (new_length < 0) {
6512 ConvertCaseHelper(isolate, 6511 result_encoding = String::TWO_BYTE_ENCODING;
6513 s, Smi::cast(answer)->value(), length, mapping); 6512 new_length = -new_length;
6514 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6515 } 6513 }
6514 MaybeObject* maybe_answer = ConvertCaseHelper(
6515 isolate, s, result_encoding, new_length, length, mapping);
6516 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6516 } 6517 }
6517 return answer; 6518 return answer;
6518 } 6519 }
6519 6520
6520 6521
6521 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { 6522 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
6522 return ConvertCase<ToLowerTraits>( 6523 return ConvertCase(
6523 args, isolate, isolate->runtime_state()->to_lower_mapping()); 6524 args, isolate, isolate->runtime_state()->to_lower_mapping());
6524 } 6525 }
6525 6526
6526 6527
6527 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) { 6528 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
6528 return ConvertCase<ToUpperTraits>( 6529 return ConvertCase(
6529 args, isolate, isolate->runtime_state()->to_upper_mapping()); 6530 args, isolate, isolate->runtime_state()->to_upper_mapping());
6530 } 6531 }
6531 6532
6532 6533
6533 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { 6534 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
6534 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff; 6535 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
6535 } 6536 }
6536 6537
6537 6538
6538 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) { 6539 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
(...skipping 8340 matching lines...) Expand 10 before | Expand all | Expand 10 after
14879 // Handle last resort GC and make sure to allow future allocations 14880 // Handle last resort GC and make sure to allow future allocations
14880 // to grow the heap without causing GCs (if possible). 14881 // to grow the heap without causing GCs (if possible).
14881 isolate->counters()->gc_last_resort_from_js()->Increment(); 14882 isolate->counters()->gc_last_resort_from_js()->Increment();
14882 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14883 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14883 "Runtime::PerformGC"); 14884 "Runtime::PerformGC");
14884 } 14885 }
14885 } 14886 }
14886 14887
14887 14888
14888 } } // namespace v8::internal 14889 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698