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

Side by Side Diff: src/builtins.cc

Issue 819001: Revert change to always call builtins for Array functions.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 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/bootstrapper.cc ('k') | src/contexts.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 ASSERT(proto->elements() == Heap::empty_fixed_array()); 312 ASSERT(proto->elements() == Heap::empty_fixed_array());
313 // Object.prototype 313 // Object.prototype
314 proto = JSObject::cast(proto->GetPrototype()); 314 proto = JSObject::cast(proto->GetPrototype());
315 if (proto != global_context->initial_object_prototype()) return false; 315 if (proto != global_context->initial_object_prototype()) return false;
316 if (proto->elements() != Heap::empty_fixed_array()) return false; 316 if (proto->elements() != Heap::empty_fixed_array()) return false;
317 ASSERT(proto->GetPrototype()->IsNull()); 317 ASSERT(proto->GetPrototype()->IsNull());
318 return true; 318 return true;
319 } 319 }
320 320
321 321
322 static bool IsJSArrayWithFastElements(Object* receiver,
323 FixedArray** elements) {
324 if (!receiver->IsJSArray()) {
325 return false;
326 }
327
328 JSArray* array = JSArray::cast(receiver);
329
330 HeapObject* elms = HeapObject::cast(array->elements());
331 if (elms->map() != Heap::fixed_array_map()) {
332 return false;
333 }
334
335 *elements = FixedArray::cast(elms);
336 return true;
337 }
338
339
340 static Object* CallJsBuiltin(const char* name, 322 static Object* CallJsBuiltin(const char* name,
341 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { 323 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
342 HandleScope handleScope; 324 HandleScope handleScope;
343 325
344 Handle<Object> js_builtin = 326 Handle<Object> js_builtin =
345 GetProperty(Handle<JSObject>(Top::global_context()->builtins()), 327 GetProperty(Handle<JSObject>(Top::global_context()->builtins()),
346 name); 328 name);
347 ASSERT(js_builtin->IsJSFunction()); 329 ASSERT(js_builtin->IsJSFunction());
348 Handle<JSFunction> function(Handle<JSFunction>::cast(js_builtin)); 330 Handle<JSFunction> function(Handle<JSFunction>::cast(js_builtin));
349 Vector<Object**> argv(Vector<Object**>::New(args.length() - 1)); 331 Vector<Object**> argv(Vector<Object**>::New(args.length() - 1));
350 int n_args = args.length() - 1; 332 int n_args = args.length() - 1;
351 for (int i = 0; i < n_args; i++) { 333 for (int i = 0; i < n_args; i++) {
352 argv[i] = &args[i + 1]; 334 argv[i] = &args[i + 1];
353 } 335 }
354 bool pending_exception = false; 336 bool pending_exception = false;
355 Handle<Object> result = Execution::Call(function, 337 Handle<Object> result = Execution::Call(function,
356 args.receiver(), 338 args.receiver(),
357 n_args, 339 n_args,
358 argv.start(), 340 argv.start(),
359 &pending_exception); 341 &pending_exception);
360 argv.Dispose(); 342 argv.Dispose();
361 if (pending_exception) return Failure::Exception(); 343 if (pending_exception) return Failure::Exception();
362 return *result; 344 return *result;
363 } 345 }
364 346
365 347
366 BUILTIN(ArrayPush) { 348 BUILTIN(ArrayPush) {
367 Object* receiver = *args.receiver(); 349 JSArray* array = JSArray::cast(*args.receiver());
368 FixedArray* elms = NULL; 350 ASSERT(array->HasFastElements());
369 if (!IsJSArrayWithFastElements(receiver, &elms)) {
370 return CallJsBuiltin("ArrayPush", args);
371 }
372 JSArray* array = JSArray::cast(receiver);
373 351
374 int len = Smi::cast(array->length())->value(); 352 int len = Smi::cast(array->length())->value();
375 int to_add = args.length() - 1; 353 int to_add = args.length() - 1;
376 if (to_add == 0) { 354 if (to_add == 0) {
377 return Smi::FromInt(len); 355 return Smi::FromInt(len);
378 } 356 }
379 // Currently fixed arrays cannot grow too big, so 357 // Currently fixed arrays cannot grow too big, so
380 // we should never hit this case. 358 // we should never hit this case.
381 ASSERT(to_add <= (Smi::kMaxValue - len)); 359 ASSERT(to_add <= (Smi::kMaxValue - len));
382 360
383 int new_length = len + to_add; 361 int new_length = len + to_add;
362 FixedArray* elms = FixedArray::cast(array->elements());
384 363
385 if (new_length > elms->length()) { 364 if (new_length > elms->length()) {
386 // New backing storage is needed. 365 // New backing storage is needed.
387 int capacity = new_length + (new_length >> 1) + 16; 366 int capacity = new_length + (new_length >> 1) + 16;
388 Object* obj = Heap::AllocateUninitializedFixedArray(capacity); 367 Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
389 if (obj->IsFailure()) return obj; 368 if (obj->IsFailure()) return obj;
390 FixedArray* new_elms = FixedArray::cast(obj); 369 FixedArray* new_elms = FixedArray::cast(obj);
391 370
392 AssertNoAllocation no_gc; 371 AssertNoAllocation no_gc;
393 CopyElements(&no_gc, new_elms, 0, elms, 0, len); 372 CopyElements(&no_gc, new_elms, 0, elms, 0, len);
(...skipping 10 matching lines...) Expand all
404 elms->set(index + len, args[index + 1], mode); 383 elms->set(index + len, args[index + 1], mode);
405 } 384 }
406 385
407 // Set the length. 386 // Set the length.
408 array->set_length(Smi::FromInt(new_length)); 387 array->set_length(Smi::FromInt(new_length));
409 return Smi::FromInt(new_length); 388 return Smi::FromInt(new_length);
410 } 389 }
411 390
412 391
413 BUILTIN(ArrayPop) { 392 BUILTIN(ArrayPop) {
414 Object* receiver = *args.receiver(); 393 JSArray* array = JSArray::cast(*args.receiver());
415 FixedArray* elms = NULL; 394 ASSERT(array->HasFastElements());
416 if (!IsJSArrayWithFastElements(receiver, &elms)) {
417 return CallJsBuiltin("ArrayPop", args);
418 }
419 JSArray* array = JSArray::cast(receiver);
420 395
421 int len = Smi::cast(array->length())->value(); 396 int len = Smi::cast(array->length())->value();
422 if (len == 0) return Heap::undefined_value(); 397 if (len == 0) return Heap::undefined_value();
423 398
424 // Get top element 399 // Get top element
400 FixedArray* elms = FixedArray::cast(array->elements());
425 Object* top = elms->get(len - 1); 401 Object* top = elms->get(len - 1);
426 402
427 // Set the length. 403 // Set the length.
428 array->set_length(Smi::FromInt(len - 1)); 404 array->set_length(Smi::FromInt(len - 1));
429 405
430 if (!top->IsTheHole()) { 406 if (!top->IsTheHole()) {
431 // Delete the top element. 407 // Delete the top element.
432 elms->set_the_hole(len - 1); 408 elms->set_the_hole(len - 1);
433 return top; 409 return top;
434 } 410 }
435 411
436 // Remember to check the prototype chain. 412 // Remember to check the prototype chain.
437 JSFunction* array_function = 413 JSFunction* array_function =
438 Top::context()->global_context()->array_function(); 414 Top::context()->global_context()->array_function();
439 JSObject* prototype = JSObject::cast(array_function->prototype()); 415 JSObject* prototype = JSObject::cast(array_function->prototype());
440 top = prototype->GetElement(len - 1); 416 top = prototype->GetElement(len - 1);
441 417
442 return top; 418 return top;
443 } 419 }
444 420
445 421
446 BUILTIN(ArrayShift) { 422 BUILTIN(ArrayShift) {
447 Object* receiver = *args.receiver(); 423 if (!ArrayPrototypeHasNoElements()) {
448 FixedArray* elms = NULL;
449 if (!IsJSArrayWithFastElements(receiver, &elms)
450 || !ArrayPrototypeHasNoElements()) {
451 return CallJsBuiltin("ArrayShift", args); 424 return CallJsBuiltin("ArrayShift", args);
452 } 425 }
453 JSArray* array = JSArray::cast(receiver); 426
427 JSArray* array = JSArray::cast(*args.receiver());
454 ASSERT(array->HasFastElements()); 428 ASSERT(array->HasFastElements());
455 429
456 int len = Smi::cast(array->length())->value(); 430 int len = Smi::cast(array->length())->value();
457 if (len == 0) return Heap::undefined_value(); 431 if (len == 0) return Heap::undefined_value();
458 432
433 FixedArray* elms = FixedArray::cast(array->elements());
434
459 // Get first element 435 // Get first element
460 Object* first = elms->get(0); 436 Object* first = elms->get(0);
461 if (first->IsTheHole()) { 437 if (first->IsTheHole()) {
462 first = Heap::undefined_value(); 438 first = Heap::undefined_value();
463 } 439 }
464 440
465 // Shift the elements. 441 // Shift the elements.
466 AssertNoAllocation no_gc; 442 AssertNoAllocation no_gc;
467 MoveElements(&no_gc, elms, 0, elms, 1, len - 1); 443 MoveElements(&no_gc, elms, 0, elms, 1, len - 1);
468 elms->set(len - 1, Heap::the_hole_value()); 444 elms->set(len - 1, Heap::the_hole_value());
469 445
470 // Set the length. 446 // Set the length.
471 array->set_length(Smi::FromInt(len - 1)); 447 array->set_length(Smi::FromInt(len - 1));
472 448
473 return first; 449 return first;
474 } 450 }
475 451
476 452
477 BUILTIN(ArrayUnshift) { 453 BUILTIN(ArrayUnshift) {
478 Object* receiver = *args.receiver(); 454 if (!ArrayPrototypeHasNoElements()) {
479 FixedArray* elms = NULL;
480 if (!IsJSArrayWithFastElements(receiver, &elms)
481 || !ArrayPrototypeHasNoElements()) {
482 return CallJsBuiltin("ArrayUnshift", args); 455 return CallJsBuiltin("ArrayUnshift", args);
483 } 456 }
484 JSArray* array = JSArray::cast(receiver); 457
458 JSArray* array = JSArray::cast(*args.receiver());
485 ASSERT(array->HasFastElements()); 459 ASSERT(array->HasFastElements());
486 460
487 int len = Smi::cast(array->length())->value(); 461 int len = Smi::cast(array->length())->value();
488 int to_add = args.length() - 1; 462 int to_add = args.length() - 1;
489 // Note that we cannot quit early if to_add == 0 as 463 // Note that we cannot quit early if to_add == 0 as
490 // values should be lifted from prototype into 464 // values should be lifted from prototype into
491 // the array. 465 // the array.
492 466
493 int new_length = len + to_add; 467 int new_length = len + to_add;
494 // Currently fixed arrays cannot grow too big, so 468 // Currently fixed arrays cannot grow too big, so
495 // we should never hit this case. 469 // we should never hit this case.
496 ASSERT(to_add <= (Smi::kMaxValue - len)); 470 ASSERT(to_add <= (Smi::kMaxValue - len));
497 471
472 FixedArray* elms = FixedArray::cast(array->elements());
473
498 if (new_length > elms->length()) { 474 if (new_length > elms->length()) {
499 // New backing storage is needed. 475 // New backing storage is needed.
500 int capacity = new_length + (new_length >> 1) + 16; 476 int capacity = new_length + (new_length >> 1) + 16;
501 Object* obj = Heap::AllocateUninitializedFixedArray(capacity); 477 Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
502 if (obj->IsFailure()) return obj; 478 if (obj->IsFailure()) return obj;
503 FixedArray* new_elms = FixedArray::cast(obj); 479 FixedArray* new_elms = FixedArray::cast(obj);
504 480
505 AssertNoAllocation no_gc; 481 AssertNoAllocation no_gc;
506 CopyElements(&no_gc, new_elms, to_add, elms, 0, len); 482 CopyElements(&no_gc, new_elms, to_add, elms, 0, len);
507 FillWithHoles(new_elms, new_length, capacity); 483 FillWithHoles(new_elms, new_length, capacity);
(...skipping 12 matching lines...) Expand all
520 elms->set(i, args[i + 1], mode); 496 elms->set(i, args[i + 1], mode);
521 } 497 }
522 498
523 // Set the length. 499 // Set the length.
524 array->set_length(Smi::FromInt(new_length)); 500 array->set_length(Smi::FromInt(new_length));
525 return Smi::FromInt(new_length); 501 return Smi::FromInt(new_length);
526 } 502 }
527 503
528 504
529 BUILTIN(ArraySlice) { 505 BUILTIN(ArraySlice) {
530 Object* receiver = *args.receiver(); 506 if (!ArrayPrototypeHasNoElements()) {
531 FixedArray* elms = NULL;
532 if (!IsJSArrayWithFastElements(receiver, &elms)
533 || !ArrayPrototypeHasNoElements()) {
534 return CallJsBuiltin("ArraySlice", args); 507 return CallJsBuiltin("ArraySlice", args);
535 } 508 }
536 JSArray* array = JSArray::cast(receiver); 509
510 JSArray* array = JSArray::cast(*args.receiver());
537 ASSERT(array->HasFastElements()); 511 ASSERT(array->HasFastElements());
538 512
539 int len = Smi::cast(array->length())->value(); 513 int len = Smi::cast(array->length())->value();
540 514
541 int n_arguments = args.length() - 1; 515 int n_arguments = args.length() - 1;
542 516
543 // Note carefully choosen defaults---if argument is missing, 517 // Note carefully choosen defaults---if argument is missing,
544 // it's undefined which gets converted to 0 for relative_start 518 // it's undefined which gets converted to 0 for relative_start
545 // and to len for relative_end. 519 // and to len for relative_end.
546 int relative_start = 0; 520 int relative_start = 0;
(...skipping 30 matching lines...) Expand all
577 } 551 }
578 552
579 Object* result = AllocateJSArray(); 553 Object* result = AllocateJSArray();
580 if (result->IsFailure()) return result; 554 if (result->IsFailure()) return result;
581 JSArray* result_array = JSArray::cast(result); 555 JSArray* result_array = JSArray::cast(result);
582 556
583 result = Heap::AllocateUninitializedFixedArray(result_len); 557 result = Heap::AllocateUninitializedFixedArray(result_len);
584 if (result->IsFailure()) return result; 558 if (result->IsFailure()) return result;
585 FixedArray* result_elms = FixedArray::cast(result); 559 FixedArray* result_elms = FixedArray::cast(result);
586 560
561 FixedArray* elms = FixedArray::cast(array->elements());
562
587 AssertNoAllocation no_gc; 563 AssertNoAllocation no_gc;
588 CopyElements(&no_gc, result_elms, 0, elms, k, result_len); 564 CopyElements(&no_gc, result_elms, 0, elms, k, result_len);
589 565
590 // Set elements. 566 // Set elements.
591 result_array->set_elements(result_elms); 567 result_array->set_elements(result_elms);
592 568
593 // Set the length. 569 // Set the length.
594 result_array->set_length(Smi::FromInt(result_len)); 570 result_array->set_length(Smi::FromInt(result_len));
595 return result_array; 571 return result_array;
596 } 572 }
597 573
598 574
599 BUILTIN(ArraySplice) { 575 BUILTIN(ArraySplice) {
600 Object* receiver = *args.receiver(); 576 if (!ArrayPrototypeHasNoElements()) {
601 FixedArray* elms = NULL;
602 if (!IsJSArrayWithFastElements(receiver, &elms)
603 || !ArrayPrototypeHasNoElements()) {
604 return CallJsBuiltin("ArraySplice", args); 577 return CallJsBuiltin("ArraySplice", args);
605 } 578 }
606 JSArray* array = JSArray::cast(receiver); 579
580 JSArray* array = JSArray::cast(*args.receiver());
607 ASSERT(array->HasFastElements()); 581 ASSERT(array->HasFastElements());
608 582
609 int len = Smi::cast(array->length())->value(); 583 int len = Smi::cast(array->length())->value();
610 584
611 int n_arguments = args.length() - 1; 585 int n_arguments = args.length() - 1;
612 586
613 // SpiderMonkey and JSC return undefined in the case where no 587 // SpiderMonkey and JSC return undefined in the case where no
614 // arguments are given instead of using the implicit undefined 588 // arguments are given instead of using the implicit undefined
615 // arguments. This does not follow ECMA-262, but we do the same for 589 // arguments. This does not follow ECMA-262, but we do the same for
616 // compatibility. 590 // compatibility.
(...skipping 20 matching lines...) Expand all
637 if (n_arguments > 1) { 611 if (n_arguments > 1) {
638 Object* arg2 = args[2]; 612 Object* arg2 = args[2];
639 if (arg2->IsSmi()) { 613 if (arg2->IsSmi()) {
640 delete_count = Smi::cast(arg2)->value(); 614 delete_count = Smi::cast(arg2)->value();
641 } else { 615 } else {
642 return CallJsBuiltin("ArraySplice", args); 616 return CallJsBuiltin("ArraySplice", args);
643 } 617 }
644 } 618 }
645 int actual_delete_count = Min(Max(delete_count, 0), len - actual_start); 619 int actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
646 620
621 FixedArray* elms = FixedArray::cast(array->elements());
622
647 JSArray* result_array = NULL; 623 JSArray* result_array = NULL;
648 if (actual_delete_count == 0) { 624 if (actual_delete_count == 0) {
649 Object* result = AllocateEmptyJSArray(); 625 Object* result = AllocateEmptyJSArray();
650 if (result->IsFailure()) return result; 626 if (result->IsFailure()) return result;
651 result_array = JSArray::cast(result); 627 result_array = JSArray::cast(result);
652 } else { 628 } else {
653 // Allocate result array. 629 // Allocate result array.
654 Object* result = AllocateJSArray(); 630 Object* result = AllocateJSArray();
655 if (result->IsFailure()) return result; 631 if (result->IsFailure()) return result;
656 result_array = JSArray::cast(result); 632 result_array = JSArray::cast(result);
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 if (entry->contains(pc)) { 1351 if (entry->contains(pc)) {
1376 return names_[i]; 1352 return names_[i];
1377 } 1353 }
1378 } 1354 }
1379 } 1355 }
1380 return NULL; 1356 return NULL;
1381 } 1357 }
1382 1358
1383 1359
1384 } } // namespace v8::internal 1360 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698