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

Side by Side Diff: src/builtins.cc

Issue 10442015: Rollback of r11638, r11636 on trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 7 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/code-stubs.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 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 193
194 JSArray* array; 194 JSArray* array;
195 if (CalledAsConstructor(isolate)) { 195 if (CalledAsConstructor(isolate)) {
196 array = JSArray::cast((*args)[0]); 196 array = JSArray::cast((*args)[0]);
197 // Initialize elements and length in case later allocations fail so that the 197 // Initialize elements and length in case later allocations fail so that the
198 // array object is initialized in a valid state. 198 // array object is initialized in a valid state.
199 array->set_length(Smi::FromInt(0)); 199 array->set_length(Smi::FromInt(0));
200 array->set_elements(heap->empty_fixed_array()); 200 array->set_elements(heap->empty_fixed_array());
201 if (!FLAG_smi_only_arrays) { 201 if (!FLAG_smi_only_arrays) {
202 Context* global_context = isolate->context()->global_context(); 202 Context* global_context = isolate->context()->global_context();
203 if (array->GetElementsKind() == GetInitialFastElementsKind() && 203 if (array->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
204 !global_context->js_array_maps()->IsUndefined()) { 204 !global_context->object_js_array_map()->IsUndefined()) {
205 FixedArray* map_array = 205 array->set_map(Map::cast(global_context->object_js_array_map()));
206 FixedArray::cast(global_context->js_array_maps());
207 array->set_map(Map::cast(map_array->
208 get(TERMINAL_FAST_ELEMENTS_KIND)));
209 } 206 }
210 } 207 }
211 } else { 208 } else {
212 // Allocate the JS Array 209 // Allocate the JS Array
213 MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); 210 MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
214 if (!maybe_obj->To(&array)) return maybe_obj; 211 if (!maybe_obj->To(&array)) return maybe_obj;
215 } 212 }
216 213
217 // Optimize the case where there is one argument and the argument is a 214 // Optimize the case where there is one argument and the argument is a
218 // small smi. 215 // small smi.
219 if (args->length() == 2) { 216 if (args->length() == 2) {
220 Object* obj = (*args)[1]; 217 Object* obj = (*args)[1];
221 if (obj->IsSmi()) { 218 if (obj->IsSmi()) {
222 int len = Smi::cast(obj)->value(); 219 int len = Smi::cast(obj)->value();
223 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) { 220 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
224 Object* fixed_array; 221 Object* fixed_array;
225 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len); 222 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len);
226 if (!maybe_obj->ToObject(&fixed_array)) return maybe_obj; 223 if (!maybe_obj->ToObject(&fixed_array)) return maybe_obj;
227 } 224 }
228 ElementsKind elements_kind = array->GetElementsKind();
229 if (!IsFastHoleyElementsKind(elements_kind)) {
230 elements_kind = GetHoleyElementsKind(elements_kind);
231 MaybeObject* maybe_array =
232 array->TransitionElementsKind(elements_kind);
233 if (maybe_array->IsFailure()) return maybe_array;
234 }
235 // We do not use SetContent to skip the unnecessary elements type check. 225 // We do not use SetContent to skip the unnecessary elements type check.
236 array->set_elements(FixedArray::cast(fixed_array)); 226 array->set_elements(FixedArray::cast(fixed_array));
237 array->set_length(Smi::cast(obj)); 227 array->set_length(Smi::cast(obj));
238 return array; 228 return array;
239 } 229 }
240 } 230 }
241 // Take the argument as the length. 231 // Take the argument as the length.
242 { MaybeObject* maybe_obj = array->Initialize(0); 232 { MaybeObject* maybe_obj = array->Initialize(0);
243 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 233 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
244 } 234 }
245 return array->SetElementsLength((*args)[1]); 235 return array->SetElementsLength((*args)[1]);
246 } 236 }
247 237
248 // Optimize the case where there are no parameters passed. 238 // Optimize the case where there are no parameters passed.
249 if (args->length() == 1) { 239 if (args->length() == 1) {
250 return array->Initialize(JSArray::kPreallocatedArrayElements); 240 return array->Initialize(JSArray::kPreallocatedArrayElements);
251 } 241 }
252 242
253 // Set length and elements on the array. 243 // Set length and elements on the array.
254 int number_of_elements = args->length() - 1; 244 int number_of_elements = args->length() - 1;
255 MaybeObject* maybe_object = 245 MaybeObject* maybe_object =
256 array->EnsureCanContainElements(args, 1, number_of_elements, 246 array->EnsureCanContainElements(args, 1, number_of_elements,
257 ALLOW_CONVERTED_DOUBLE_ELEMENTS); 247 ALLOW_CONVERTED_DOUBLE_ELEMENTS);
258 if (maybe_object->IsFailure()) return maybe_object; 248 if (maybe_object->IsFailure()) return maybe_object;
259 249
260 // Allocate an appropriately typed elements array. 250 // Allocate an appropriately typed elements array.
261 MaybeObject* maybe_elms; 251 MaybeObject* maybe_elms;
262 ElementsKind elements_kind = array->GetElementsKind(); 252 ElementsKind elements_kind = array->GetElementsKind();
263 if (IsFastDoubleElementsKind(elements_kind)) { 253 if (elements_kind == FAST_DOUBLE_ELEMENTS) {
264 maybe_elms = heap->AllocateUninitializedFixedDoubleArray( 254 maybe_elms = heap->AllocateUninitializedFixedDoubleArray(
265 number_of_elements); 255 number_of_elements);
266 } else { 256 } else {
267 maybe_elms = heap->AllocateFixedArrayWithHoles(number_of_elements); 257 maybe_elms = heap->AllocateFixedArrayWithHoles(number_of_elements);
268 } 258 }
269 FixedArrayBase* elms; 259 FixedArrayBase* elms;
270 if (!maybe_elms->To<FixedArrayBase>(&elms)) return maybe_elms; 260 if (!maybe_elms->To<FixedArrayBase>(&elms)) return maybe_elms;
271 261
272 // Fill in the content 262 // Fill in the content
273 switch (array->GetElementsKind()) { 263 switch (array->GetElementsKind()) {
274 case FAST_HOLEY_SMI_ELEMENTS: 264 case FAST_SMI_ONLY_ELEMENTS: {
275 case FAST_SMI_ELEMENTS: {
276 FixedArray* smi_elms = FixedArray::cast(elms); 265 FixedArray* smi_elms = FixedArray::cast(elms);
277 for (int index = 0; index < number_of_elements; index++) { 266 for (int index = 0; index < number_of_elements; index++) {
278 smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER); 267 smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER);
279 } 268 }
280 break; 269 break;
281 } 270 }
282 case FAST_HOLEY_ELEMENTS:
283 case FAST_ELEMENTS: { 271 case FAST_ELEMENTS: {
284 AssertNoAllocation no_gc; 272 AssertNoAllocation no_gc;
285 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 273 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
286 FixedArray* object_elms = FixedArray::cast(elms); 274 FixedArray* object_elms = FixedArray::cast(elms);
287 for (int index = 0; index < number_of_elements; index++) { 275 for (int index = 0; index < number_of_elements; index++) {
288 object_elms->set(index, (*args)[index+1], mode); 276 object_elms->set(index, (*args)[index+1], mode);
289 } 277 }
290 break; 278 break;
291 } 279 }
292 case FAST_HOLEY_DOUBLE_ELEMENTS:
293 case FAST_DOUBLE_ELEMENTS: { 280 case FAST_DOUBLE_ELEMENTS: {
294 FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms); 281 FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms);
295 for (int index = 0; index < number_of_elements; index++) { 282 for (int index = 0; index < number_of_elements; index++) {
296 double_elms->set(index, (*args)[index+1]->Number()); 283 double_elms->set(index, (*args)[index+1]->Number());
297 } 284 }
298 break; 285 break;
299 } 286 }
300 default: 287 default:
301 UNREACHABLE(); 288 UNREACHABLE();
302 break; 289 break;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 405
419 406
420 MUST_USE_RESULT 407 MUST_USE_RESULT
421 static inline MaybeObject* EnsureJSArrayWithWritableFastElements( 408 static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
422 Heap* heap, Object* receiver, Arguments* args, int first_added_arg) { 409 Heap* heap, Object* receiver, Arguments* args, int first_added_arg) {
423 if (!receiver->IsJSArray()) return NULL; 410 if (!receiver->IsJSArray()) return NULL;
424 JSArray* array = JSArray::cast(receiver); 411 JSArray* array = JSArray::cast(receiver);
425 HeapObject* elms = array->elements(); 412 HeapObject* elms = array->elements();
426 Map* map = elms->map(); 413 Map* map = elms->map();
427 if (map == heap->fixed_array_map()) { 414 if (map == heap->fixed_array_map()) {
428 if (args == NULL || array->HasFastObjectElements()) return elms; 415 if (args == NULL || array->HasFastElements()) return elms;
429 if (array->HasFastDoubleElements()) { 416 if (array->HasFastDoubleElements()) {
430 ASSERT(elms == heap->empty_fixed_array()); 417 ASSERT(elms == heap->empty_fixed_array());
431 MaybeObject* maybe_transition = 418 MaybeObject* maybe_transition =
432 array->TransitionElementsKind(FAST_ELEMENTS); 419 array->TransitionElementsKind(FAST_ELEMENTS);
433 if (maybe_transition->IsFailure()) return maybe_transition; 420 if (maybe_transition->IsFailure()) return maybe_transition;
434 return elms; 421 return elms;
435 } 422 }
436 } else if (map == heap->fixed_cow_array_map()) { 423 } else if (map == heap->fixed_cow_array_map()) {
437 MaybeObject* maybe_writable_result = array->EnsureWritableFastElements(); 424 MaybeObject* maybe_writable_result = array->EnsureWritableFastElements();
438 if (args == NULL || array->HasFastObjectElements() || 425 if (args == NULL || array->HasFastElements() ||
439 maybe_writable_result->IsFailure()) { 426 maybe_writable_result->IsFailure()) {
440 return maybe_writable_result; 427 return maybe_writable_result;
441 } 428 }
442 } else { 429 } else {
443 return NULL; 430 return NULL;
444 } 431 }
445 432
446 // Need to ensure that the arguments passed in args can be contained in 433 // Need to ensure that the arguments passed in args can be contained in
447 // the array. 434 // the array.
448 int args_length = args->length(); 435 int args_length = args->length();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 509
523 if (new_length > elms->length()) { 510 if (new_length > elms->length()) {
524 // New backing storage is needed. 511 // New backing storage is needed.
525 int capacity = new_length + (new_length >> 1) + 16; 512 int capacity = new_length + (new_length >> 1) + 16;
526 Object* obj; 513 Object* obj;
527 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); 514 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
528 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 515 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
529 } 516 }
530 FixedArray* new_elms = FixedArray::cast(obj); 517 FixedArray* new_elms = FixedArray::cast(obj);
531 518
532 ElementsKind kind = array->GetElementsKind(); 519 CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
533 CopyObjectToObjectElements(elms, kind, 0, new_elms, kind, 0, len); 520 new_elms, FAST_ELEMENTS, 0, len);
534 FillWithHoles(heap, new_elms, new_length, capacity); 521 FillWithHoles(heap, new_elms, new_length, capacity);
535 522
536 elms = new_elms; 523 elms = new_elms;
537 } 524 }
538 525
539 // Add the provided values. 526 // Add the provided values.
540 AssertNoAllocation no_gc; 527 AssertNoAllocation no_gc;
541 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 528 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
542 for (int index = 0; index < to_add; index++) { 529 for (int index = 0; index < to_add; index++) {
543 elms->set(index + len, args[index + 1], mode); 530 elms->set(index + len, args[index + 1], mode);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); 581 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
595 if (maybe_elms_obj == NULL) 582 if (maybe_elms_obj == NULL)
596 return CallJsBuiltin(isolate, "ArrayShift", args); 583 return CallJsBuiltin(isolate, "ArrayShift", args);
597 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; 584 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
598 } 585 }
599 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { 586 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
600 return CallJsBuiltin(isolate, "ArrayShift", args); 587 return CallJsBuiltin(isolate, "ArrayShift", args);
601 } 588 }
602 FixedArray* elms = FixedArray::cast(elms_obj); 589 FixedArray* elms = FixedArray::cast(elms_obj);
603 JSArray* array = JSArray::cast(receiver); 590 JSArray* array = JSArray::cast(receiver);
604 ASSERT(array->HasFastSmiOrObjectElements()); 591 ASSERT(array->HasFastTypeElements());
605 592
606 int len = Smi::cast(array->length())->value(); 593 int len = Smi::cast(array->length())->value();
607 if (len == 0) return heap->undefined_value(); 594 if (len == 0) return heap->undefined_value();
608 595
609 // Get first element 596 // Get first element
610 Object* first = elms->get(0); 597 Object* first = elms->get(0);
611 if (first->IsTheHole()) { 598 if (first->IsTheHole()) {
612 first = heap->undefined_value(); 599 first = heap->undefined_value();
613 } 600 }
614 601
(...skipping 21 matching lines...) Expand all
636 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); 623 EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
637 if (maybe_elms_obj == NULL) 624 if (maybe_elms_obj == NULL)
638 return CallJsBuiltin(isolate, "ArrayUnshift", args); 625 return CallJsBuiltin(isolate, "ArrayUnshift", args);
639 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; 626 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
640 } 627 }
641 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { 628 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
642 return CallJsBuiltin(isolate, "ArrayUnshift", args); 629 return CallJsBuiltin(isolate, "ArrayUnshift", args);
643 } 630 }
644 FixedArray* elms = FixedArray::cast(elms_obj); 631 FixedArray* elms = FixedArray::cast(elms_obj);
645 JSArray* array = JSArray::cast(receiver); 632 JSArray* array = JSArray::cast(receiver);
646 ASSERT(array->HasFastSmiOrObjectElements()); 633 ASSERT(array->HasFastTypeElements());
647 634
648 int len = Smi::cast(array->length())->value(); 635 int len = Smi::cast(array->length())->value();
649 int to_add = args.length() - 1; 636 int to_add = args.length() - 1;
650 int new_length = len + to_add; 637 int new_length = len + to_add;
651 // Currently fixed arrays cannot grow too big, so 638 // Currently fixed arrays cannot grow too big, so
652 // we should never hit this case. 639 // we should never hit this case.
653 ASSERT(to_add <= (Smi::kMaxValue - len)); 640 ASSERT(to_add <= (Smi::kMaxValue - len));
654 641
655 MaybeObject* maybe_object = 642 MaybeObject* maybe_object =
656 array->EnsureCanContainElements(&args, 1, to_add, 643 array->EnsureCanContainElements(&args, 1, to_add,
657 DONT_ALLOW_DOUBLE_ELEMENTS); 644 DONT_ALLOW_DOUBLE_ELEMENTS);
658 if (maybe_object->IsFailure()) return maybe_object; 645 if (maybe_object->IsFailure()) return maybe_object;
659 646
660 if (new_length > elms->length()) { 647 if (new_length > elms->length()) {
661 // New backing storage is needed. 648 // New backing storage is needed.
662 int capacity = new_length + (new_length >> 1) + 16; 649 int capacity = new_length + (new_length >> 1) + 16;
663 Object* obj; 650 Object* obj;
664 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); 651 { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
665 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 652 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
666 } 653 }
667 FixedArray* new_elms = FixedArray::cast(obj); 654 FixedArray* new_elms = FixedArray::cast(obj);
668 ElementsKind kind = array->GetElementsKind(); 655 CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
669 CopyObjectToObjectElements(elms, kind, 0, new_elms, kind, to_add, len); 656 new_elms, FAST_ELEMENTS, to_add, len);
670 FillWithHoles(heap, new_elms, new_length, capacity); 657 FillWithHoles(heap, new_elms, new_length, capacity);
671 elms = new_elms; 658 elms = new_elms;
672 array->set_elements(elms); 659 array->set_elements(elms);
673 } else { 660 } else {
674 AssertNoAllocation no_gc; 661 AssertNoAllocation no_gc;
675 MoveElements(heap, &no_gc, elms, to_add, elms, 0, len); 662 MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
676 } 663 }
677 664
678 // Add the provided values. 665 // Add the provided values.
679 AssertNoAllocation no_gc; 666 AssertNoAllocation no_gc;
680 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 667 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
681 for (int i = 0; i < to_add; i++) { 668 for (int i = 0; i < to_add; i++) {
682 elms->set(i, args[i + 1], mode); 669 elms->set(i, args[i + 1], mode);
683 } 670 }
684 671
685 // Set the length. 672 // Set the length.
686 array->set_length(Smi::FromInt(new_length)); 673 array->set_length(Smi::FromInt(new_length));
687 return Smi::FromInt(new_length); 674 return Smi::FromInt(new_length);
688 } 675 }
689 676
690 677
691 BUILTIN(ArraySlice) { 678 BUILTIN(ArraySlice) {
692 Heap* heap = isolate->heap(); 679 Heap* heap = isolate->heap();
693 Object* receiver = *args.receiver(); 680 Object* receiver = *args.receiver();
694 FixedArray* elms; 681 FixedArray* elms;
695 int len = -1; 682 int len = -1;
696 if (receiver->IsJSArray()) { 683 if (receiver->IsJSArray()) {
697 JSArray* array = JSArray::cast(receiver); 684 JSArray* array = JSArray::cast(receiver);
698 if (!array->HasFastSmiOrObjectElements() || 685 if (!array->HasFastTypeElements() ||
699 !IsJSArrayFastElementMovingAllowed(heap, array)) { 686 !IsJSArrayFastElementMovingAllowed(heap, array)) {
700 return CallJsBuiltin(isolate, "ArraySlice", args); 687 return CallJsBuiltin(isolate, "ArraySlice", args);
701 } 688 }
702 689
703 elms = FixedArray::cast(array->elements()); 690 elms = FixedArray::cast(array->elements());
704 len = Smi::cast(array->length())->value(); 691 len = Smi::cast(array->length())->value();
705 } else { 692 } else {
706 // Array.slice(arguments, ...) is quite a common idiom (notably more 693 // Array.slice(arguments, ...) is quite a common idiom (notably more
707 // than 50% of invocations in Web apps). Treat it in C++ as well. 694 // than 50% of invocations in Web apps). Treat it in C++ as well.
708 Map* arguments_map = 695 Map* arguments_map =
709 isolate->context()->global_context()->arguments_boilerplate()->map(); 696 isolate->context()->global_context()->arguments_boilerplate()->map();
710 697
711 bool is_arguments_object_with_fast_elements = 698 bool is_arguments_object_with_fast_elements =
712 receiver->IsJSObject() 699 receiver->IsJSObject()
713 && JSObject::cast(receiver)->map() == arguments_map 700 && JSObject::cast(receiver)->map() == arguments_map
714 && JSObject::cast(receiver)->HasFastSmiOrObjectElements(); 701 && JSObject::cast(receiver)->HasFastTypeElements();
715 if (!is_arguments_object_with_fast_elements) { 702 if (!is_arguments_object_with_fast_elements) {
716 return CallJsBuiltin(isolate, "ArraySlice", args); 703 return CallJsBuiltin(isolate, "ArraySlice", args);
717 } 704 }
718 elms = FixedArray::cast(JSObject::cast(receiver)->elements()); 705 elms = FixedArray::cast(JSObject::cast(receiver)->elements());
719 Object* len_obj = JSObject::cast(receiver) 706 Object* len_obj = JSObject::cast(receiver)
720 ->InObjectPropertyAt(Heap::kArgumentsLengthIndex); 707 ->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
721 if (!len_obj->IsSmi()) { 708 if (!len_obj->IsSmi()) {
722 return CallJsBuiltin(isolate, "ArraySlice", args); 709 return CallJsBuiltin(isolate, "ArraySlice", args);
723 } 710 }
724 len = Smi::cast(len_obj)->value(); 711 len = Smi::cast(len_obj)->value();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 // Calculate the length of result array. 756 // Calculate the length of result array.
770 int result_len = Max(final - k, 0); 757 int result_len = Max(final - k, 0);
771 758
772 MaybeObject* maybe_array = 759 MaybeObject* maybe_array =
773 heap->AllocateJSArrayAndStorage(elements_kind, 760 heap->AllocateJSArrayAndStorage(elements_kind,
774 result_len, 761 result_len,
775 result_len); 762 result_len);
776 JSArray* result_array; 763 JSArray* result_array;
777 if (!maybe_array->To(&result_array)) return maybe_array; 764 if (!maybe_array->To(&result_array)) return maybe_array;
778 765
779 CopyObjectToObjectElements(elms, elements_kind, k, 766 CopyObjectToObjectElements(elms, FAST_ELEMENTS, k,
780 FixedArray::cast(result_array->elements()), 767 FixedArray::cast(result_array->elements()),
781 elements_kind, 0, result_len); 768 FAST_ELEMENTS, 0, result_len);
782 769
783 return result_array; 770 return result_array;
784 } 771 }
785 772
786 773
787 BUILTIN(ArraySplice) { 774 BUILTIN(ArraySplice) {
788 Heap* heap = isolate->heap(); 775 Heap* heap = isolate->heap();
789 Object* receiver = *args.receiver(); 776 Object* receiver = *args.receiver();
790 Object* elms_obj; 777 Object* elms_obj;
791 { MaybeObject* maybe_elms_obj = 778 { MaybeObject* maybe_elms_obj =
792 EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3); 779 EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3);
793 if (maybe_elms_obj == NULL) 780 if (maybe_elms_obj == NULL)
794 return CallJsBuiltin(isolate, "ArraySplice", args); 781 return CallJsBuiltin(isolate, "ArraySplice", args);
795 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; 782 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
796 } 783 }
797 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) { 784 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
798 return CallJsBuiltin(isolate, "ArraySplice", args); 785 return CallJsBuiltin(isolate, "ArraySplice", args);
799 } 786 }
800 FixedArray* elms = FixedArray::cast(elms_obj); 787 FixedArray* elms = FixedArray::cast(elms_obj);
801 JSArray* array = JSArray::cast(receiver); 788 JSArray* array = JSArray::cast(receiver);
802 ASSERT(array->HasFastSmiOrObjectElements()); 789 ASSERT(array->HasFastTypeElements());
803 790
804 int len = Smi::cast(array->length())->value(); 791 int len = Smi::cast(array->length())->value();
805 792
806 int n_arguments = args.length() - 1; 793 int n_arguments = args.length() - 1;
807 794
808 int relative_start = 0; 795 int relative_start = 0;
809 if (n_arguments > 0) { 796 if (n_arguments > 0) {
810 Object* arg1 = args[1]; 797 Object* arg1 = args[1];
811 if (arg1->IsSmi()) { 798 if (arg1->IsSmi()) {
812 relative_start = Smi::cast(arg1)->value(); 799 relative_start = Smi::cast(arg1)->value();
(...skipping 30 matching lines...) Expand all
843 ElementsKind elements_kind = 830 ElementsKind elements_kind =
844 JSObject::cast(receiver)->GetElementsKind(); 831 JSObject::cast(receiver)->GetElementsKind();
845 MaybeObject* maybe_array = 832 MaybeObject* maybe_array =
846 heap->AllocateJSArrayAndStorage(elements_kind, 833 heap->AllocateJSArrayAndStorage(elements_kind,
847 actual_delete_count, 834 actual_delete_count,
848 actual_delete_count); 835 actual_delete_count);
849 if (!maybe_array->To(&result_array)) return maybe_array; 836 if (!maybe_array->To(&result_array)) return maybe_array;
850 837
851 { 838 {
852 // Fill newly created array. 839 // Fill newly created array.
853 CopyObjectToObjectElements(elms, elements_kind, actual_start, 840 CopyObjectToObjectElements(elms, FAST_ELEMENTS, actual_start,
854 FixedArray::cast(result_array->elements()), 841 FixedArray::cast(result_array->elements()),
855 elements_kind, 0, actual_delete_count); 842 FAST_ELEMENTS, 0, actual_delete_count);
856 } 843 }
857 844
858 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; 845 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
859 int new_length = len - actual_delete_count + item_count; 846 int new_length = len - actual_delete_count + item_count;
860 847
861 bool elms_changed = false; 848 bool elms_changed = false;
862 if (item_count < actual_delete_count) { 849 if (item_count < actual_delete_count) {
863 // Shrink the array. 850 // Shrink the array.
864 const bool trim_array = !heap->lo_space()->Contains(elms) && 851 const bool trim_array = !heap->lo_space()->Contains(elms) &&
865 ((actual_start + item_count) < 852 ((actual_start + item_count) <
(...skipping 28 matching lines...) Expand all
894 int capacity = new_length + (new_length >> 1) + 16; 881 int capacity = new_length + (new_length >> 1) + 16;
895 Object* obj; 882 Object* obj;
896 { MaybeObject* maybe_obj = 883 { MaybeObject* maybe_obj =
897 heap->AllocateUninitializedFixedArray(capacity); 884 heap->AllocateUninitializedFixedArray(capacity);
898 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 885 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
899 } 886 }
900 FixedArray* new_elms = FixedArray::cast(obj); 887 FixedArray* new_elms = FixedArray::cast(obj);
901 888
902 { 889 {
903 // Copy the part before actual_start as is. 890 // Copy the part before actual_start as is.
904 ElementsKind kind = array->GetElementsKind(); 891 CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
905 CopyObjectToObjectElements(elms, kind, 0, 892 new_elms, FAST_ELEMENTS, 0, actual_start);
906 new_elms, kind, 0, actual_start);
907 const int to_copy = len - actual_delete_count - actual_start; 893 const int to_copy = len - actual_delete_count - actual_start;
908 CopyObjectToObjectElements(elms, kind, 894 CopyObjectToObjectElements(elms, FAST_ELEMENTS,
909 actual_start + actual_delete_count, 895 actual_start + actual_delete_count,
910 new_elms, kind, 896 new_elms, FAST_ELEMENTS,
911 actual_start + item_count, to_copy); 897 actual_start + item_count, to_copy);
912 } 898 }
913 899
914 FillWithHoles(heap, new_elms, new_length, capacity); 900 FillWithHoles(heap, new_elms, new_length, capacity);
915 901
916 elms = new_elms; 902 elms = new_elms;
917 elms_changed = true; 903 elms_changed = true;
918 } else { 904 } else {
919 AssertNoAllocation no_gc; 905 AssertNoAllocation no_gc;
920 MoveElements(heap, &no_gc, 906 MoveElements(heap, &no_gc,
(...skipping 26 matching lines...) Expand all
947 JSObject* array_proto = 933 JSObject* array_proto =
948 JSObject::cast(global_context->array_function()->prototype()); 934 JSObject::cast(global_context->array_function()->prototype());
949 if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) { 935 if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) {
950 return CallJsBuiltin(isolate, "ArrayConcat", args); 936 return CallJsBuiltin(isolate, "ArrayConcat", args);
951 } 937 }
952 938
953 // Iterate through all the arguments performing checks 939 // Iterate through all the arguments performing checks
954 // and calculating total length. 940 // and calculating total length.
955 int n_arguments = args.length(); 941 int n_arguments = args.length();
956 int result_len = 0; 942 int result_len = 0;
957 ElementsKind elements_kind = GetInitialFastElementsKind(); 943 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS;
958 for (int i = 0; i < n_arguments; i++) { 944 for (int i = 0; i < n_arguments; i++) {
959 Object* arg = args[i]; 945 Object* arg = args[i];
960 if (!arg->IsJSArray() || 946 if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastTypeElements()
961 !JSArray::cast(arg)->HasFastSmiOrObjectElements() || 947 || JSArray::cast(arg)->GetPrototype() != array_proto) {
962 JSArray::cast(arg)->GetPrototype() != array_proto) {
963 return CallJsBuiltin(isolate, "ArrayConcat", args); 948 return CallJsBuiltin(isolate, "ArrayConcat", args);
964 } 949 }
965 950
966 int len = Smi::cast(JSArray::cast(arg)->length())->value(); 951 int len = Smi::cast(JSArray::cast(arg)->length())->value();
967 952
968 // We shouldn't overflow when adding another len. 953 // We shouldn't overflow when adding another len.
969 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); 954 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
970 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); 955 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
971 USE(kHalfOfMaxInt); 956 USE(kHalfOfMaxInt);
972 result_len += len; 957 result_len += len;
973 ASSERT(result_len >= 0); 958 ASSERT(result_len >= 0);
974 959
975 if (result_len > FixedArray::kMaxLength) { 960 if (result_len > FixedArray::kMaxLength) {
976 return CallJsBuiltin(isolate, "ArrayConcat", args); 961 return CallJsBuiltin(isolate, "ArrayConcat", args);
977 } 962 }
978 963
979 if (!JSArray::cast(arg)->HasFastSmiElements()) { 964 if (!JSArray::cast(arg)->HasFastSmiOnlyElements()) {
980 if (IsFastSmiElementsKind(elements_kind)) { 965 elements_kind = FAST_ELEMENTS;
981 if (IsFastHoleyElementsKind(elements_kind)) {
982 elements_kind = FAST_HOLEY_ELEMENTS;
983 } else {
984 elements_kind = FAST_ELEMENTS;
985 }
986 }
987 }
988
989 if (JSArray::cast(arg)->HasFastHoleyElements()) {
990 elements_kind = GetHoleyElementsKind(elements_kind);
991 } 966 }
992 } 967 }
993 968
994 // Allocate result. 969 // Allocate result.
995 JSArray* result_array; 970 JSArray* result_array;
996 MaybeObject* maybe_array = 971 MaybeObject* maybe_array =
997 heap->AllocateJSArrayAndStorage(elements_kind, 972 heap->AllocateJSArrayAndStorage(elements_kind,
998 result_len, 973 result_len,
999 result_len); 974 result_len);
1000 if (!maybe_array->To(&result_array)) return maybe_array; 975 if (!maybe_array->To(&result_array)) return maybe_array;
1001 if (result_len == 0) return result_array; 976 if (result_len == 0) return result_array;
1002 977
1003 // Copy data. 978 // Copy data.
1004 int start_pos = 0; 979 int start_pos = 0;
1005 FixedArray* result_elms(FixedArray::cast(result_array->elements())); 980 FixedArray* result_elms(FixedArray::cast(result_array->elements()));
1006 for (int i = 0; i < n_arguments; i++) { 981 for (int i = 0; i < n_arguments; i++) {
1007 JSArray* array = JSArray::cast(args[i]); 982 JSArray* array = JSArray::cast(args[i]);
1008 int len = Smi::cast(array->length())->value(); 983 int len = Smi::cast(array->length())->value();
1009 FixedArray* elms = FixedArray::cast(array->elements()); 984 FixedArray* elms = FixedArray::cast(array->elements());
1010 CopyObjectToObjectElements(elms, elements_kind, 0, 985 CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
1011 result_elms, elements_kind, 986 result_elms, FAST_ELEMENTS,
1012 start_pos, len); 987 start_pos, len);
1013 start_pos += len; 988 start_pos += len;
1014 } 989 }
1015 ASSERT(start_pos == result_len); 990 ASSERT(start_pos == result_len);
1016 991
1017 return result_array; 992 return result_array;
1018 } 993 }
1019 994
1020 995
1021 // ----------------------------------------------------------------------------- 996 // -----------------------------------------------------------------------------
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 return Handle<Code>(code_address); \ 1678 return Handle<Code>(code_address); \
1704 } 1679 }
1705 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1680 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1706 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1681 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1707 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1682 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1708 #undef DEFINE_BUILTIN_ACCESSOR_C 1683 #undef DEFINE_BUILTIN_ACCESSOR_C
1709 #undef DEFINE_BUILTIN_ACCESSOR_A 1684 #undef DEFINE_BUILTIN_ACCESSOR_A
1710 1685
1711 1686
1712 } } // namespace v8::internal 1687 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/bootstrapper.cc ('k') | src/code-stubs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698