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

Side by Side Diff: src/runtime.cc

Issue 59853006: Fix y-umlaut to uppercase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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/heap.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 6176 matching lines...) Expand 10 before | Expand all | Expand 10 after
6187 6187
6188 // Create a number object from the value. 6188 // Create a number object from the value.
6189 return isolate->heap()->NumberFromDouble(value); 6189 return isolate->heap()->NumberFromDouble(value);
6190 } 6190 }
6191 6191
6192 6192
6193 template <class Converter> 6193 template <class Converter>
6194 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( 6194 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
6195 Isolate* isolate, 6195 Isolate* isolate,
6196 String* s, 6196 String* s,
6197 String::Encoding result_encoding,
6197 int length, 6198 int length,
6198 int input_string_length, 6199 int input_string_length,
6199 unibrow::Mapping<Converter, 128>* mapping) { 6200 unibrow::Mapping<Converter, 128>* mapping) {
6200 // We try this twice, once with the assumption that the result is no longer 6201 // We try this twice, once with the assumption that the result is no longer
6201 // than the input and, if that assumption breaks, again with the exact 6202 // than the input and, if that assumption breaks, again with the exact
6202 // length. This may not be pretty, but it is nicer than what was here before 6203 // length. This may not be pretty, but it is nicer than what was here before
6203 // and I hereby claim my vaffel-is. 6204 // and I hereby claim my vaffel-is.
6204 // 6205 //
6205 // Allocate the resulting string. 6206 // Allocate the resulting string.
6206 // 6207 //
6207 // NOTE: This assumes that the upper/lower case of an ASCII 6208 // NOTE: This assumes that the upper/lower case of an ASCII
6208 // character is also ASCII. This is currently the case, but it 6209 // character is also ASCII. This is currently the case, but it
Lasse Reichstein Nielsen 2013/11/06 21:19:42 Is "ASCII" here still relevant?
6209 // might break in the future if we implement more context and locale 6210 // might break in the future if we implement more context and locale
6210 // dependent upper/lower conversions. 6211 // dependent upper/lower conversions.
6211 Object* o; 6212 Object* o;
6212 { MaybeObject* maybe_o = s->IsOneByteRepresentation() 6213 { MaybeObject* maybe_o = result_encoding == String::ONE_BYTE_ENCODING
6213 ? isolate->heap()->AllocateRawOneByteString(length) 6214 ? isolate->heap()->AllocateRawOneByteString(length)
6214 : isolate->heap()->AllocateRawTwoByteString(length); 6215 : isolate->heap()->AllocateRawTwoByteString(length);
6215 if (!maybe_o->ToObject(&o)) return maybe_o; 6216 if (!maybe_o->ToObject(&o)) return maybe_o;
6216 } 6217 }
6217 String* result = String::cast(o); 6218 String* result = String::cast(o);
6218 bool has_changed_character = false; 6219 bool has_changed_character = false;
6219 6220
6221 DisallowHeapAllocation no_gc;
6222
6220 // Convert all characters to upper case, assuming that they will fit 6223 // Convert all characters to upper case, assuming that they will fit
6221 // in the buffer 6224 // in the buffer
6222 Access<ConsStringIteratorOp> op( 6225 Access<ConsStringIteratorOp> op(
6223 isolate->runtime_state()->string_iterator()); 6226 isolate->runtime_state()->string_iterator());
6224 StringCharacterStream stream(s, op.value()); 6227 StringCharacterStream stream(s, op.value());
6225 unibrow::uchar chars[Converter::kMaxWidth]; 6228 unibrow::uchar chars[Converter::kMaxWidth];
6226 // We can assume that the string is not empty 6229 // We can assume that the string is not empty
6227 uc32 current = stream.GetNext(); 6230 uc32 current = stream.GetNext();
6231 // y with umlauts is the only character that stops fitting into one-byte
6232 // when converting to uppercase.
6233 static const uc32 yuml_code = 0xff;
Sven Panne 2013/11/07 07:07:24 Hmmm, is this really the only case? Look e.g. at i
dcarney 2013/11/07 07:13:33 This code does not take locale into account. It's
6234 bool ignore_yuml = result->IsSeqTwoByteString() || Converter::kIsToLower;
6228 for (int i = 0; i < length;) { 6235 for (int i = 0; i < length;) {
6229 bool has_next = stream.HasMore(); 6236 bool has_next = stream.HasMore();
6230 uc32 next = has_next ? stream.GetNext() : 0; 6237 uc32 next = has_next ? stream.GetNext() : 0;
6231 int char_length = mapping->get(current, next, chars); 6238 int char_length = mapping->get(current, next, chars);
6232 if (char_length == 0) { 6239 if (char_length == 0) {
6233 // The case conversion of this character is the character itself. 6240 // The case conversion of this character is the character itself.
6234 result->Set(i, current); 6241 result->Set(i, current);
6235 i++; 6242 i++;
6236 } else if (char_length == 1) { 6243 } else if (char_length == 1 && (ignore_yuml || current != yuml_code)) {
6237 // Common case: converting the letter resulted in one character. 6244 // Common case: converting the letter resulted in one character.
6238 ASSERT(static_cast<uc32>(chars[0]) != current); 6245 ASSERT(static_cast<uc32>(chars[0]) != current);
6239 result->Set(i, chars[0]); 6246 result->Set(i, chars[0]);
6240 has_changed_character = true; 6247 has_changed_character = true;
6241 i++; 6248 i++;
6242 } else if (length == input_string_length) { 6249 } else if (length == input_string_length) {
6250 bool found_yuml = (current == yuml_code);
6243 // We've assumed that the result would be as long as the 6251 // We've assumed that the result would be as long as the
6244 // input but here is a character that converts to several 6252 // input but here is a character that converts to several
6245 // characters. No matter, we calculate the exact length 6253 // characters. No matter, we calculate the exact length
6246 // of the result and try the whole thing again. 6254 // of the result and try the whole thing again.
6247 // 6255 //
6248 // Note that this leaves room for optimization. We could just 6256 // Note that this leaves room for optimization. We could just
6249 // memcpy what we already have to the result string. Also, 6257 // memcpy what we already have to the result string. Also,
6250 // the result string is the last object allocated we could 6258 // the result string is the last object allocated we could
6251 // "realloc" it and probably, in the vast majority of cases, 6259 // "realloc" it and probably, in the vast majority of cases,
6252 // extend the existing string to be able to hold the full 6260 // extend the existing string to be able to hold the full
6253 // result. 6261 // result.
6254 int next_length = 0; 6262 int next_length = 0;
6255 if (has_next) { 6263 if (has_next) {
6256 next_length = mapping->get(next, 0, chars); 6264 next_length = mapping->get(next, 0, chars);
6257 if (next_length == 0) next_length = 1; 6265 if (next_length == 0) next_length = 1;
6258 } 6266 }
6259 int current_length = i + char_length + next_length; 6267 int current_length = i + char_length + next_length;
6260 while (stream.HasMore()) { 6268 while (stream.HasMore()) {
6261 current = stream.GetNext(); 6269 current = stream.GetNext();
6270 found_yuml |= (current == yuml_code);
6262 // NOTE: we use 0 as the next character here because, while 6271 // NOTE: we use 0 as the next character here because, while
6263 // the next character may affect what a character converts to, 6272 // the next character may affect what a character converts to,
6264 // it does not in any case affect the length of what it convert 6273 // it does not in any case affect the length of what it convert
6265 // to. 6274 // to.
6266 int char_length = mapping->get(current, 0, chars); 6275 int char_length = mapping->get(current, 0, chars);
6267 if (char_length == 0) char_length = 1; 6276 if (char_length == 0) char_length = 1;
6268 current_length += char_length; 6277 current_length += char_length;
6269 if (current_length > Smi::kMaxValue) { 6278 if (current_length > Smi::kMaxValue) {
6270 isolate->context()->mark_out_of_memory(); 6279 isolate->context()->mark_out_of_memory();
6271 return Failure::OutOfMemoryException(0x13); 6280 return Failure::OutOfMemoryException(0x13);
6272 } 6281 }
6273 } 6282 }
6274 // Try again with the real length. 6283 // Try again with the real length. Return signed if we need
6275 return Smi::FromInt(current_length); 6284 // to allocate a two-byte string for y-umlaut to uppercase.
6285 return (found_yuml && !ignore_yuml) ? Smi::FromInt(-current_length)
6286 : Smi::FromInt(current_length);
6276 } else { 6287 } else {
6277 for (int j = 0; j < char_length; j++) { 6288 for (int j = 0; j < char_length; j++) {
6278 result->Set(i, chars[j]); 6289 result->Set(i, chars[j]);
6279 i++; 6290 i++;
6280 } 6291 }
6281 has_changed_character = true; 6292 has_changed_character = true;
6282 } 6293 }
6283 current = next; 6294 current = next;
6284 } 6295 }
6285 if (has_changed_character) { 6296 if (has_changed_character) {
(...skipping 25 matching lines...) Expand all
6311 // further simplified. 6322 // further simplified.
6312 ASSERT(0 < m && m < n); 6323 ASSERT(0 < m && m < n);
6313 // Has high bit set in every w byte less than n. 6324 // Has high bit set in every w byte less than n.
6314 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; 6325 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6315 // Has high bit set in every w byte greater than m. 6326 // Has high bit set in every w byte greater than m.
6316 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); 6327 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6317 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); 6328 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6318 } 6329 }
6319 6330
6320 6331
6321 enum AsciiCaseConversion { 6332 template<class Converter>
6322 ASCII_TO_LOWER, 6333 static bool FastAsciiConvert(char* dst,
6323 ASCII_TO_UPPER 6334 char* src,
6324 }; 6335 int length,
6325 6336 bool* changed_out) {
6326
6327 template <AsciiCaseConversion dir>
6328 struct FastAsciiConverter {
6329 static bool Convert(char* dst, char* src, int length, bool* changed_out) {
6330 #ifdef DEBUG 6337 #ifdef DEBUG
6331 char* saved_dst = dst; 6338 char* saved_dst = dst;
6332 char* saved_src = src; 6339 char* saved_src = src;
6333 #endif 6340 #endif
6334 // We rely on the distance between upper and lower case letters 6341 DisallowHeapAllocation no_gc;
6335 // being a known power of 2. 6342 // We rely on the distance between upper and lower case letters
6336 ASSERT('a' - 'A' == (1 << 5)); 6343 // being a known power of 2.
6337 // Boundaries for the range of input characters than require conversion. 6344 ASSERT('a' - 'A' == (1 << 5));
6338 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; 6345 // Boundaries for the range of input characters than require conversion.
6339 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; 6346 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6340 bool changed = false; 6347 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6341 uintptr_t or_acc = 0; 6348 bool changed = false;
6342 char* const limit = src + length; 6349 uintptr_t or_acc = 0;
6350 char* const limit = src + length;
6343 #ifdef V8_HOST_CAN_READ_UNALIGNED 6351 #ifdef V8_HOST_CAN_READ_UNALIGNED
6344 // Process the prefix of the input that requires no conversion one 6352 // Process the prefix of the input that requires no conversion one
6345 // (machine) word at a time. 6353 // (machine) word at a time.
6346 while (src <= limit - sizeof(uintptr_t)) { 6354 while (src <= limit - sizeof(uintptr_t)) {
6347 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); 6355 uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
6348 or_acc |= w; 6356 or_acc |= w;
6349 if (AsciiRangeMask(w, lo, hi) != 0) { 6357 if (AsciiRangeMask(w, lo, hi) != 0) {
6350 changed = true; 6358 changed = true;
6351 break; 6359 break;
6352 }
6353 *reinterpret_cast<uintptr_t*>(dst) = w;
6354 src += sizeof(uintptr_t);
6355 dst += sizeof(uintptr_t);
6356 } 6360 }
6357 // Process the remainder of the input performing conversion when 6361 *reinterpret_cast<uintptr_t*>(dst) = w;
6358 // required one word at a time. 6362 src += sizeof(uintptr_t);
6359 while (src <= limit - sizeof(uintptr_t)) { 6363 dst += sizeof(uintptr_t);
6360 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); 6364 }
6361 or_acc |= w; 6365 // Process the remainder of the input performing conversion when
6362 uintptr_t m = AsciiRangeMask(w, lo, hi); 6366 // required one word at a time.
6363 // The mask has high (7th) bit set in every byte that needs 6367 while (src <= limit - sizeof(uintptr_t)) {
6364 // conversion and we know that the distance between cases is 6368 uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
6365 // 1 << 5. 6369 or_acc |= w;
6366 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); 6370 uintptr_t m = AsciiRangeMask(w, lo, hi);
6367 src += sizeof(uintptr_t); 6371 // The mask has high (7th) bit set in every byte that needs
6368 dst += sizeof(uintptr_t); 6372 // conversion and we know that the distance between cases is
6373 // 1 << 5.
6374 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6375 src += sizeof(uintptr_t);
6376 dst += sizeof(uintptr_t);
6377 }
6378 #endif
6379 // Process the last few bytes of the input (or the whole input if
6380 // unaligned access is not supported).
6381 while (src < limit) {
6382 char c = *src;
6383 or_acc |= c;
6384 if (lo < c && c < hi) {
6385 c ^= (1 << 5);
6386 changed = true;
6369 } 6387 }
6370 #endif 6388 *dst = c;
6371 // Process the last few bytes of the input (or the whole input if 6389 ++src;
6372 // unaligned access is not supported). 6390 ++dst;
6373 while (src < limit) { 6391 }
6374 char c = *src; 6392 if ((or_acc & kAsciiMask) != 0) {
6375 or_acc |= c; 6393 return false;
6376 if (lo < c && c < hi) {
6377 c ^= (1 << 5);
6378 changed = true;
6379 }
6380 *dst = c;
6381 ++src;
6382 ++dst;
6383 }
6384 if ((or_acc & kAsciiMask) != 0) {
6385 return false;
6386 }
6387 #ifdef DEBUG
6388 CheckConvert(saved_dst, saved_src, length, changed);
6389 #endif
6390 *changed_out = changed;
6391 return true;
6392 } 6394 }
6393 6395
6396 ASSERT(CheckFastAsciiConvert(
6397 saved_dst, saved_src, length, changed, Converter::kIsToLower));
6398
6399 *changed_out = changed;
6400 return true;
6401 }
6402
6394 #ifdef DEBUG 6403 #ifdef DEBUG
6395 static void CheckConvert(char* dst, char* src, int length, bool changed) { 6404 static bool CheckFastAsciiConvert(char* dst,
6396 bool expected_changed = false; 6405 char* src,
6397 for (int i = 0; i < length; i++) { 6406 int length,
6398 if (dst[i] == src[i]) continue; 6407 bool changed,
6399 expected_changed = true; 6408 bool is_to_lower) {
6400 if (dir == ASCII_TO_LOWER) { 6409 bool expected_changed = false;
6401 ASSERT('A' <= src[i] && src[i] <= 'Z'); 6410 for (int i = 0; i < length; i++) {
6402 ASSERT(dst[i] == src[i] + ('a' - 'A')); 6411 if (dst[i] == src[i]) continue;
6403 } else { 6412 expected_changed = true;
6404 ASSERT(dir == ASCII_TO_UPPER); 6413 if (is_to_lower) {
6405 ASSERT('a' <= src[i] && src[i] <= 'z'); 6414 ASSERT('A' <= src[i] && src[i] <= 'Z');
6406 ASSERT(dst[i] == src[i] - ('a' - 'A')); 6415 ASSERT(dst[i] == src[i] + ('a' - 'A'));
6407 } 6416 } else {
6417 ASSERT('a' <= src[i] && src[i] <= 'z');
6418 ASSERT(dst[i] == src[i] - ('a' - 'A'));
6408 } 6419 }
6409 ASSERT(expected_changed == changed);
6410 } 6420 }
6421 return (expected_changed == changed);
6422 }
6411 #endif 6423 #endif
6412 };
6413
6414
6415 struct ToLowerTraits {
6416 typedef unibrow::ToLowercase UnibrowConverter;
6417
6418 typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter;
6419 };
6420
6421
6422 struct ToUpperTraits {
6423 typedef unibrow::ToUppercase UnibrowConverter;
6424
6425 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter;
6426 };
6427 6424
6428 } // namespace 6425 } // namespace
6429 6426
6430 6427
6431 template <typename ConvertTraits> 6428 template <class Converter>
6432 MUST_USE_RESULT static MaybeObject* ConvertCase( 6429 MUST_USE_RESULT static MaybeObject* ConvertCase(
6433 Arguments args, 6430 Arguments args,
6434 Isolate* isolate, 6431 Isolate* isolate,
6435 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { 6432 unibrow::Mapping<Converter, 128>* mapping) {
6436 SealHandleScope shs(isolate); 6433 SealHandleScope shs(isolate);
6437 CONVERT_ARG_CHECKED(String, s, 0); 6434 CONVERT_ARG_CHECKED(String, s, 0);
6438 s = s->TryFlattenGetString(); 6435 s = s->TryFlattenGetString();
6439 6436
6440 const int length = s->length(); 6437 const int length = s->length();
6441 // Assume that the string is not empty; we need this assumption later 6438 // Assume that the string is not empty; we need this assumption later
6442 if (length == 0) return s; 6439 if (length == 0) return s;
6443 6440
6444 // Simpler handling of ASCII strings. 6441 // Simpler handling of ASCII strings.
6445 // 6442 //
6446 // NOTE: This assumes that the upper/lower case of an ASCII 6443 // NOTE: This assumes that the upper/lower case of an ASCII
6447 // character is also ASCII. This is currently the case, but it 6444 // character is also ASCII. This is currently the case, but it
6448 // might break in the future if we implement more context and locale 6445 // might break in the future if we implement more context and locale
6449 // dependent upper/lower conversions. 6446 // dependent upper/lower conversions.
6450 if (s->IsSeqOneByteString()) { 6447 if (s->IsSeqOneByteString()) {
6451 Object* o; 6448 Object* o;
6452 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); 6449 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length);
6453 if (!maybe_o->ToObject(&o)) return maybe_o; 6450 if (!maybe_o->ToObject(&o)) return maybe_o;
6454 } 6451 }
6455 SeqOneByteString* result = SeqOneByteString::cast(o); 6452 SeqOneByteString* result = SeqOneByteString::cast(o);
6456 bool has_changed_character; 6453 bool has_changed_character;
6457 bool is_ascii = ConvertTraits::AsciiConverter::Convert( 6454 bool is_ascii = FastAsciiConvert<Converter>(
6458 reinterpret_cast<char*>(result->GetChars()), 6455 reinterpret_cast<char*>(result->GetChars()),
6459 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), 6456 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
6460 length, 6457 length,
6461 &has_changed_character); 6458 &has_changed_character);
6462 // If not ASCII, we discard the result and take the 2 byte path. 6459 // If not ASCII, we discard the result and take the 2 byte path.
6463 if (is_ascii) { 6460 if (is_ascii) {
6464 return has_changed_character ? result : s; 6461 return has_changed_character ? result : s;
6465 } 6462 }
6466 } 6463 }
6467 6464
6465 String::Encoding result_encoding = s->IsOneByteRepresentationUnderneath()
6466 ? String::ONE_BYTE_ENCODING : String::TWO_BYTE_ENCODING;
6468 Object* answer; 6467 Object* answer;
6469 { MaybeObject* maybe_answer = 6468 { MaybeObject* maybe_answer = ConvertCaseHelper(
6470 ConvertCaseHelper(isolate, s, length, length, mapping); 6469 isolate, s, result_encoding, length, length, mapping);
6471 if (!maybe_answer->ToObject(&answer)) return maybe_answer; 6470 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6472 } 6471 }
6473 if (answer->IsSmi()) { 6472 if (answer->IsSmi()) {
6474 // Retry with correct length. 6473 int new_length = Smi::cast(answer)->value();
6475 { MaybeObject* maybe_answer = 6474 if (new_length < 0) {
6476 ConvertCaseHelper(isolate, 6475 result_encoding = String::TWO_BYTE_ENCODING;
6477 s, Smi::cast(answer)->value(), length, mapping); 6476 new_length = -new_length;
6478 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6479 } 6477 }
6478 MaybeObject* maybe_answer = ConvertCaseHelper(
6479 isolate, s, result_encoding, new_length, length, mapping);
6480 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6480 } 6481 }
6481 return answer; 6482 return answer;
6482 } 6483 }
6483 6484
6484 6485
6485 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { 6486 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
6486 return ConvertCase<ToLowerTraits>( 6487 return ConvertCase(
6487 args, isolate, isolate->runtime_state()->to_lower_mapping()); 6488 args, isolate, isolate->runtime_state()->to_lower_mapping());
6488 } 6489 }
6489 6490
6490 6491
6491 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) { 6492 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
6492 return ConvertCase<ToUpperTraits>( 6493 return ConvertCase(
6493 args, isolate, isolate->runtime_state()->to_upper_mapping()); 6494 args, isolate, isolate->runtime_state()->to_upper_mapping());
6494 } 6495 }
6495 6496
6496 6497
6497 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { 6498 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
6498 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff; 6499 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
6499 } 6500 }
6500 6501
6501 6502
6502 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) { 6503 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
(...skipping 8335 matching lines...) Expand 10 before | Expand all | Expand 10 after
14838 // Handle last resort GC and make sure to allow future allocations 14839 // Handle last resort GC and make sure to allow future allocations
14839 // to grow the heap without causing GCs (if possible). 14840 // to grow the heap without causing GCs (if possible).
14840 isolate->counters()->gc_last_resort_from_js()->Increment(); 14841 isolate->counters()->gc_last_resort_from_js()->Increment();
14841 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14842 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14842 "Runtime::PerformGC"); 14843 "Runtime::PerformGC");
14843 } 14844 }
14844 } 14845 }
14845 14846
14846 14847
14847 } } // namespace v8::internal 14848 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/unicode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698