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

Side by Side Diff: src/runtime.cc

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