OLD | NEW |
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 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 args.receiver(), | 399 args.receiver(), |
400 argc, | 400 argc, |
401 argv.start(), | 401 argv.start(), |
402 &pending_exception); | 402 &pending_exception); |
403 if (pending_exception) return Failure::Exception(); | 403 if (pending_exception) return Failure::Exception(); |
404 return *result; | 404 return *result; |
405 } | 405 } |
406 | 406 |
407 | 407 |
408 BUILTIN(ArrayPush) { | 408 BUILTIN(ArrayPush) { |
409 Heap* heap = isolate->heap(); | 409 HandleScope scope(isolate); |
410 Object* receiver = *args.receiver(); | 410 Handle<Object> receiver = args.receiver(); |
411 FixedArrayBase* elms_obj; | 411 Handle<Object> elms_or_null = |
412 MaybeObject* maybe_elms_obj = | 412 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 1); |
413 EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1); | 413 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); |
414 if (maybe_elms_obj == NULL) { | 414 if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPush", args); |
415 return CallJsBuiltin(isolate, "ArrayPush", args); | |
416 } | |
417 if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj; | |
418 | 415 |
419 JSArray* array = JSArray::cast(receiver); | 416 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null); |
| 417 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
420 ASSERT(!array->map()->is_observed()); | 418 ASSERT(!array->map()->is_observed()); |
421 | 419 |
422 ElementsKind kind = array->GetElementsKind(); | 420 ElementsKind kind = array->GetElementsKind(); |
423 | 421 |
424 if (IsFastSmiOrObjectElementsKind(kind)) { | 422 if (IsFastSmiOrObjectElementsKind(kind)) { |
425 FixedArray* elms = FixedArray::cast(elms_obj); | 423 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
426 | 424 |
427 int len = Smi::cast(array->length())->value(); | 425 int len = Smi::cast(array->length())->value(); |
428 int to_add = args.length() - 1; | 426 int to_add = args.length() - 1; |
429 if (to_add == 0) { | 427 if (to_add == 0) { |
430 return Smi::FromInt(len); | 428 return Smi::FromInt(len); |
431 } | 429 } |
432 // Currently fixed arrays cannot grow too big, so | 430 // Currently fixed arrays cannot grow too big, so |
433 // we should never hit this case. | 431 // we should never hit this case. |
434 ASSERT(to_add <= (Smi::kMaxValue - len)); | 432 ASSERT(to_add <= (Smi::kMaxValue - len)); |
435 | 433 |
436 int new_length = len + to_add; | 434 int new_length = len + to_add; |
437 | 435 |
438 if (new_length > elms->length()) { | 436 if (new_length > elms->length()) { |
439 // New backing storage is needed. | 437 // New backing storage is needed. |
440 int capacity = new_length + (new_length >> 1) + 16; | 438 int capacity = new_length + (new_length >> 1) + 16; |
441 FixedArray* new_elms; | 439 Handle<FixedArray> new_elms = |
442 MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); | 440 isolate->factory()->NewUninitializedFixedArray(capacity); |
443 if (!maybe_obj->To(&new_elms)) return maybe_obj; | |
444 | 441 |
445 ElementsAccessor* accessor = array->GetElementsAccessor(); | 442 ElementsAccessor* accessor = array->GetElementsAccessor(); |
446 MaybeObject* maybe_failure = accessor->CopyElements( | 443 accessor->CopyElements( |
447 NULL, 0, kind, new_elms, 0, | 444 Handle<JSObject>::null(), 0, kind, new_elms, 0, |
448 ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj); | 445 ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj); |
449 ASSERT(!maybe_failure->IsFailure()); | |
450 USE(maybe_failure); | |
451 | 446 |
452 elms = new_elms; | 447 elms = new_elms; |
453 } | 448 } |
454 | 449 |
455 // Add the provided values. | 450 // Add the provided values. |
456 DisallowHeapAllocation no_gc; | 451 DisallowHeapAllocation no_gc; |
457 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); | 452 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
458 for (int index = 0; index < to_add; index++) { | 453 for (int index = 0; index < to_add; index++) { |
459 elms->set(index + len, args[index + 1], mode); | 454 elms->set(index + len, args[index + 1], mode); |
460 } | 455 } |
461 | 456 |
462 if (elms != array->elements()) { | 457 if (*elms != array->elements()) { |
463 array->set_elements(elms); | 458 array->set_elements(*elms); |
464 } | 459 } |
465 | 460 |
466 // Set the length. | 461 // Set the length. |
467 array->set_length(Smi::FromInt(new_length)); | 462 array->set_length(Smi::FromInt(new_length)); |
468 return Smi::FromInt(new_length); | 463 return Smi::FromInt(new_length); |
469 } else { | 464 } else { |
470 int len = Smi::cast(array->length())->value(); | 465 int len = Smi::cast(array->length())->value(); |
471 int elms_len = elms_obj->length(); | 466 int elms_len = elms_obj->length(); |
472 | 467 |
473 int to_add = args.length() - 1; | 468 int to_add = args.length() - 1; |
474 if (to_add == 0) { | 469 if (to_add == 0) { |
475 return Smi::FromInt(len); | 470 return Smi::FromInt(len); |
476 } | 471 } |
477 // Currently fixed arrays cannot grow too big, so | 472 // Currently fixed arrays cannot grow too big, so |
478 // we should never hit this case. | 473 // we should never hit this case. |
479 ASSERT(to_add <= (Smi::kMaxValue - len)); | 474 ASSERT(to_add <= (Smi::kMaxValue - len)); |
480 | 475 |
481 int new_length = len + to_add; | 476 int new_length = len + to_add; |
482 | 477 |
483 FixedDoubleArray* new_elms; | 478 Handle<FixedDoubleArray> new_elms; |
484 | 479 |
485 if (new_length > elms_len) { | 480 if (new_length > elms_len) { |
486 // New backing storage is needed. | 481 // New backing storage is needed. |
487 int capacity = new_length + (new_length >> 1) + 16; | 482 int capacity = new_length + (new_length >> 1) + 16; |
488 MaybeObject* maybe_obj = | 483 new_elms = isolate->factory()->NewFixedDoubleArray(capacity); |
489 heap->AllocateUninitializedFixedDoubleArray(capacity); | |
490 if (!maybe_obj->To(&new_elms)) return maybe_obj; | |
491 | 484 |
492 ElementsAccessor* accessor = array->GetElementsAccessor(); | 485 ElementsAccessor* accessor = array->GetElementsAccessor(); |
493 MaybeObject* maybe_failure = accessor->CopyElements( | 486 accessor->CopyElements( |
494 NULL, 0, kind, new_elms, 0, | 487 Handle<JSObject>::null(), 0, kind, new_elms, 0, |
495 ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj); | 488 ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj); |
496 ASSERT(!maybe_failure->IsFailure()); | 489 |
497 USE(maybe_failure); | |
498 } else { | 490 } else { |
499 // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the | 491 // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the |
500 // empty_fixed_array. | 492 // empty_fixed_array. |
501 new_elms = FixedDoubleArray::cast(elms_obj); | 493 new_elms = Handle<FixedDoubleArray>::cast(elms_obj); |
502 } | 494 } |
503 | 495 |
504 // Add the provided values. | 496 // Add the provided values. |
505 DisallowHeapAllocation no_gc; | 497 DisallowHeapAllocation no_gc; |
506 int index; | 498 int index; |
507 for (index = 0; index < to_add; index++) { | 499 for (index = 0; index < to_add; index++) { |
508 Object* arg = args[index + 1]; | 500 Object* arg = args[index + 1]; |
509 new_elms->set(index + len, arg->Number()); | 501 new_elms->set(index + len, arg->Number()); |
510 } | 502 } |
511 | 503 |
512 if (new_elms != array->elements()) { | 504 if (*new_elms != array->elements()) { |
513 array->set_elements(new_elms); | 505 array->set_elements(*new_elms); |
514 } | 506 } |
515 | 507 |
516 // Set the length. | 508 // Set the length. |
517 array->set_length(Smi::FromInt(new_length)); | 509 array->set_length(Smi::FromInt(new_length)); |
518 return Smi::FromInt(new_length); | 510 return Smi::FromInt(new_length); |
519 } | 511 } |
520 } | 512 } |
521 | 513 |
522 | 514 |
523 // TODO(ishell): Temporary wrapper until handlified. | 515 // TODO(ishell): Temporary wrapper until handlified. |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 } | 1774 } |
1783 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1775 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1784 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1776 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1785 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1777 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
1786 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1778 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1787 #undef DEFINE_BUILTIN_ACCESSOR_C | 1779 #undef DEFINE_BUILTIN_ACCESSOR_C |
1788 #undef DEFINE_BUILTIN_ACCESSOR_A | 1780 #undef DEFINE_BUILTIN_ACCESSOR_A |
1789 | 1781 |
1790 | 1782 |
1791 } } // namespace v8::internal | 1783 } } // namespace v8::internal |
OLD | NEW |