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

Side by Side Diff: src/runtime.cc

Issue 2814050: Version 2.2.23... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 10 years, 5 months 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/parser.cc ('k') | src/spaces.cc » ('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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 } while (matched); 2278 } while (matched);
2279 2279
2280 if (prev < length) { 2280 if (prev < length) {
2281 builder.AddSubjectSlice(prev, length); 2281 builder.AddSubjectSlice(prev, length);
2282 } 2282 }
2283 2283
2284 return *(builder.ToString()); 2284 return *(builder.ToString());
2285 } 2285 }
2286 2286
2287 2287
2288 template <typename ResultSeqString>
2289 static Object* StringReplaceRegExpWithEmptyString(String* subject,
2290 JSRegExp* regexp,
2291 JSArray* last_match_info) {
2292 ASSERT(subject->IsFlat());
2293
2294 HandleScope handles;
2295
2296 Handle<String> subject_handle(subject);
2297 Handle<JSRegExp> regexp_handle(regexp);
2298 Handle<JSArray> last_match_info_handle(last_match_info);
2299 Handle<Object> match = RegExpImpl::Exec(regexp_handle,
2300 subject_handle,
2301 0,
2302 last_match_info_handle);
2303 if (match.is_null()) return Failure::Exception();
2304 if (match->IsNull()) return *subject_handle;
2305
2306 ASSERT(last_match_info_handle->HasFastElements());
2307
2308 HandleScope loop_scope;
2309 int start, end;
2310 {
2311 AssertNoAllocation match_info_array_is_not_in_a_handle;
2312 FixedArray* match_info_array =
2313 FixedArray::cast(last_match_info_handle->elements());
2314
2315 start = RegExpImpl::GetCapture(match_info_array, 0);
2316 end = RegExpImpl::GetCapture(match_info_array, 1);
2317 }
2318
2319 int length = subject->length();
2320 int new_length = length - (end - start);
2321 if (new_length == 0) {
2322 return Heap::empty_string();
2323 }
2324 Handle<ResultSeqString> answer;
2325 if (ResultSeqString::kHasAsciiEncoding) {
2326 answer =
2327 Handle<ResultSeqString>::cast(Factory::NewRawAsciiString(new_length));
2328 } else {
2329 answer =
2330 Handle<ResultSeqString>::cast(Factory::NewRawTwoByteString(new_length));
2331 }
2332
2333 // If the regexp isn't global, only match once.
2334 if (!regexp_handle->GetFlags().is_global()) {
2335 if (start > 0) {
2336 String::WriteToFlat(*subject_handle,
2337 answer->GetChars(),
2338 0,
2339 start);
2340 }
2341 if (end < length) {
2342 String::WriteToFlat(*subject_handle,
2343 answer->GetChars() + start,
2344 end,
2345 length);
2346 }
2347 return *answer;
2348 }
2349
2350 int prev = 0; // Index of end of last match.
2351 int next = 0; // Start of next search (prev unless last match was empty).
2352 int position = 0;
2353
2354 do {
2355 if (prev < start) {
2356 // Add substring subject[prev;start] to answer string.
2357 String::WriteToFlat(*subject_handle,
2358 answer->GetChars() + position,
2359 prev,
2360 start);
2361 position += start - prev;
2362 }
2363 prev = end;
2364 next = end;
2365 // Continue from where the match ended, unless it was an empty match.
2366 if (start == end) {
2367 next++;
2368 if (next > length) break;
2369 }
2370 match = RegExpImpl::Exec(regexp_handle,
2371 subject_handle,
2372 next,
2373 last_match_info_handle);
2374 if (match.is_null()) return Failure::Exception();
2375 if (match->IsNull()) break;
2376
2377 ASSERT(last_match_info_handle->HasFastElements());
2378 HandleScope loop_scope;
2379 {
2380 AssertNoAllocation match_info_array_is_not_in_a_handle;
2381 FixedArray* match_info_array =
2382 FixedArray::cast(last_match_info_handle->elements());
2383 start = RegExpImpl::GetCapture(match_info_array, 0);
2384 end = RegExpImpl::GetCapture(match_info_array, 1);
2385 }
2386 } while (true);
2387
2388 if (prev < length) {
2389 // Add substring subject[prev;length] to answer string.
2390 String::WriteToFlat(*subject_handle,
2391 answer->GetChars() + position,
2392 prev,
2393 length);
2394 position += length - prev;
2395 }
2396
2397 if (position == 0) {
2398 return Heap::empty_string();
2399 }
2400
2401 // Shorten string and fill
2402 int string_size = ResultSeqString::SizeFor(position);
2403 int allocated_string_size = ResultSeqString::SizeFor(new_length);
2404 int delta = allocated_string_size - string_size;
2405
2406 answer->set_length(position);
2407 if (delta == 0) return *answer;
2408
2409 Address end_of_string = answer->address() + string_size;
2410 Heap::CreateFillerObjectAt(end_of_string, delta);
2411
2412 return *answer;
2413 }
2414
2415
2288 static Object* Runtime_StringReplaceRegExpWithString(Arguments args) { 2416 static Object* Runtime_StringReplaceRegExpWithString(Arguments args) {
2289 ASSERT(args.length() == 4); 2417 ASSERT(args.length() == 4);
2290 2418
2291 CONVERT_CHECKED(String, subject, args[0]); 2419 CONVERT_CHECKED(String, subject, args[0]);
2292 if (!subject->IsFlat()) { 2420 if (!subject->IsFlat()) {
2293 Object* flat_subject = subject->TryFlatten(); 2421 Object* flat_subject = subject->TryFlatten();
2294 if (flat_subject->IsFailure()) { 2422 if (flat_subject->IsFailure()) {
2295 return flat_subject; 2423 return flat_subject;
2296 } 2424 }
2297 subject = String::cast(flat_subject); 2425 subject = String::cast(flat_subject);
2298 } 2426 }
2299 2427
2300 CONVERT_CHECKED(String, replacement, args[2]); 2428 CONVERT_CHECKED(String, replacement, args[2]);
2301 if (!replacement->IsFlat()) { 2429 if (!replacement->IsFlat()) {
2302 Object* flat_replacement = replacement->TryFlatten(); 2430 Object* flat_replacement = replacement->TryFlatten();
2303 if (flat_replacement->IsFailure()) { 2431 if (flat_replacement->IsFailure()) {
2304 return flat_replacement; 2432 return flat_replacement;
2305 } 2433 }
2306 replacement = String::cast(flat_replacement); 2434 replacement = String::cast(flat_replacement);
2307 } 2435 }
2308 2436
2309 CONVERT_CHECKED(JSRegExp, regexp, args[1]); 2437 CONVERT_CHECKED(JSRegExp, regexp, args[1]);
2310 CONVERT_CHECKED(JSArray, last_match_info, args[3]); 2438 CONVERT_CHECKED(JSArray, last_match_info, args[3]);
2311 2439
2312 ASSERT(last_match_info->HasFastElements()); 2440 ASSERT(last_match_info->HasFastElements());
2313 2441
2442 if (replacement->length() == 0) {
2443 if (subject->HasOnlyAsciiChars()) {
2444 return StringReplaceRegExpWithEmptyString<SeqAsciiString>(
2445 subject, regexp, last_match_info);
2446 } else {
2447 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>(
2448 subject, regexp, last_match_info);
2449 }
2450 }
2451
2314 return StringReplaceRegExpWithString(subject, 2452 return StringReplaceRegExpWithString(subject,
2315 regexp, 2453 regexp,
2316 replacement, 2454 replacement,
2317 last_match_info); 2455 last_match_info);
2318 } 2456 }
2319 2457
2320 2458
2321 // Cap on the maximal shift in the Boyer-Moore implementation. By setting a 2459 // Cap on the maximal shift in the Boyer-Moore implementation. By setting a
2322 // limit, we can fix the size of tables. 2460 // limit, we can fix the size of tables.
2323 static const int kBMMaxShift = 0xff; 2461 static const int kBMMaxShift = 0xff;
(...skipping 3106 matching lines...) Expand 10 before | Expand all | Expand 10 after
5430 return Heap::nan_value(); 5568 return Heap::nan_value();
5431 } 5569 }
5432 5570
5433 5571
5434 static Object* Runtime_NumberAdd(Arguments args) { 5572 static Object* Runtime_NumberAdd(Arguments args) {
5435 NoHandleAllocation ha; 5573 NoHandleAllocation ha;
5436 ASSERT(args.length() == 2); 5574 ASSERT(args.length() == 2);
5437 5575
5438 CONVERT_DOUBLE_CHECKED(x, args[0]); 5576 CONVERT_DOUBLE_CHECKED(x, args[0]);
5439 CONVERT_DOUBLE_CHECKED(y, args[1]); 5577 CONVERT_DOUBLE_CHECKED(y, args[1]);
5440 return Heap::AllocateHeapNumber(x + y); 5578 return Heap::NumberFromDouble(x + y);
5441 } 5579 }
5442 5580
5443 5581
5444 static Object* Runtime_NumberSub(Arguments args) { 5582 static Object* Runtime_NumberSub(Arguments args) {
5445 NoHandleAllocation ha; 5583 NoHandleAllocation ha;
5446 ASSERT(args.length() == 2); 5584 ASSERT(args.length() == 2);
5447 5585
5448 CONVERT_DOUBLE_CHECKED(x, args[0]); 5586 CONVERT_DOUBLE_CHECKED(x, args[0]);
5449 CONVERT_DOUBLE_CHECKED(y, args[1]); 5587 CONVERT_DOUBLE_CHECKED(y, args[1]);
5450 return Heap::AllocateHeapNumber(x - y); 5588 return Heap::NumberFromDouble(x - y);
5451 } 5589 }
5452 5590
5453 5591
5454 static Object* Runtime_NumberMul(Arguments args) { 5592 static Object* Runtime_NumberMul(Arguments args) {
5455 NoHandleAllocation ha; 5593 NoHandleAllocation ha;
5456 ASSERT(args.length() == 2); 5594 ASSERT(args.length() == 2);
5457 5595
5458 CONVERT_DOUBLE_CHECKED(x, args[0]); 5596 CONVERT_DOUBLE_CHECKED(x, args[0]);
5459 CONVERT_DOUBLE_CHECKED(y, args[1]); 5597 CONVERT_DOUBLE_CHECKED(y, args[1]);
5460 return Heap::AllocateHeapNumber(x * y); 5598 return Heap::NumberFromDouble(x * y);
5461 } 5599 }
5462 5600
5463 5601
5464 static Object* Runtime_NumberUnaryMinus(Arguments args) { 5602 static Object* Runtime_NumberUnaryMinus(Arguments args) {
5465 NoHandleAllocation ha; 5603 NoHandleAllocation ha;
5466 ASSERT(args.length() == 1); 5604 ASSERT(args.length() == 1);
5467 5605
5468 CONVERT_DOUBLE_CHECKED(x, args[0]); 5606 CONVERT_DOUBLE_CHECKED(x, args[0]);
5469 return Heap::AllocateHeapNumber(-x); 5607 return Heap::NumberFromDouble(-x);
5470 } 5608 }
5471 5609
5472 5610
5473 static Object* Runtime_NumberDiv(Arguments args) { 5611 static Object* Runtime_NumberDiv(Arguments args) {
5474 NoHandleAllocation ha; 5612 NoHandleAllocation ha;
5475 ASSERT(args.length() == 2); 5613 ASSERT(args.length() == 2);
5476 5614
5477 CONVERT_DOUBLE_CHECKED(x, args[0]); 5615 CONVERT_DOUBLE_CHECKED(x, args[0]);
5478 CONVERT_DOUBLE_CHECKED(y, args[1]); 5616 CONVERT_DOUBLE_CHECKED(y, args[1]);
5479 return Heap::NumberFromDouble(x / y); 5617 return Heap::NumberFromDouble(x / y);
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
6061 NoHandleAllocation ha; 6199 NoHandleAllocation ha;
6062 ASSERT(args.length() == 2); 6200 ASSERT(args.length() == 2);
6063 Counters::math_pow.Increment(); 6201 Counters::math_pow.Increment();
6064 6202
6065 CONVERT_DOUBLE_CHECKED(x, args[0]); 6203 CONVERT_DOUBLE_CHECKED(x, args[0]);
6066 6204
6067 // If the second argument is a smi, it is much faster to call the 6205 // If the second argument is a smi, it is much faster to call the
6068 // custom powi() function than the generic pow(). 6206 // custom powi() function than the generic pow().
6069 if (args[1]->IsSmi()) { 6207 if (args[1]->IsSmi()) {
6070 int y = Smi::cast(args[1])->value(); 6208 int y = Smi::cast(args[1])->value();
6071 return Heap::AllocateHeapNumber(powi(x, y)); 6209 return Heap::NumberFromDouble(powi(x, y));
6072 } 6210 }
6073 6211
6074 CONVERT_DOUBLE_CHECKED(y, args[1]); 6212 CONVERT_DOUBLE_CHECKED(y, args[1]);
6075 6213
6076 if (!isinf(x)) { 6214 if (!isinf(x)) {
6077 if (y == 0.5) { 6215 if (y == 0.5) {
6078 // It's not uncommon to use Math.pow(x, 0.5) to compute the 6216 // It's not uncommon to use Math.pow(x, 0.5) to compute the
6079 // square root of a number. To speed up such computations, we 6217 // square root of a number. To speed up such computations, we
6080 // explictly check for this case and use the sqrt() function 6218 // explictly check for this case and use the sqrt() function
6081 // which is faster than pow(). 6219 // which is faster than pow().
(...skipping 4316 matching lines...) Expand 10 before | Expand all | Expand 10 after
10398 } else { 10536 } else {
10399 // Handle last resort GC and make sure to allow future allocations 10537 // Handle last resort GC and make sure to allow future allocations
10400 // to grow the heap without causing GCs (if possible). 10538 // to grow the heap without causing GCs (if possible).
10401 Counters::gc_last_resort_from_js.Increment(); 10539 Counters::gc_last_resort_from_js.Increment();
10402 Heap::CollectAllGarbage(false); 10540 Heap::CollectAllGarbage(false);
10403 } 10541 }
10404 } 10542 }
10405 10543
10406 10544
10407 } } // namespace v8::internal 10545 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698