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

Side by Side Diff: src/runtime.cc

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