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 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // This function is used for both construct and normal calls of Array. The only | 314 // This function is used for both construct and normal calls of Array. The only |
315 // difference between handling a construct call and a normal call is that for a | 315 // difference between handling a construct call and a normal call is that for a |
316 // construct call the constructor function in a1 needs to be preserved for | 316 // construct call the constructor function in a1 needs to be preserved for |
317 // entering the generic code. In both cases argc in a0 needs to be preserved. | 317 // entering the generic code. In both cases argc in a0 needs to be preserved. |
318 // Both registers are preserved by this code so no need to differentiate between | 318 // Both registers are preserved by this code so no need to differentiate between |
319 // construct call and normal call. | 319 // construct call and normal call. |
320 static void ArrayNativeCode(MacroAssembler* masm, | 320 static void ArrayNativeCode(MacroAssembler* masm, |
321 Label* call_generic_code) { | 321 Label* call_generic_code) { |
322 Counters* counters = masm->isolate()->counters(); | 322 Counters* counters = masm->isolate()->counters(); |
323 Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array, | 323 Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array, |
324 has_non_smi_element; | 324 has_non_smi_element, finish, cant_transition_map, not_double; |
325 | 325 |
326 // Check for array construction with zero arguments or one. | 326 // Check for array construction with zero arguments or one. |
327 __ Branch(&argc_one_or_more, ne, a0, Operand(zero_reg)); | 327 __ Branch(&argc_one_or_more, ne, a0, Operand(zero_reg)); |
328 // Handle construction of an empty array. | 328 // Handle construction of an empty array. |
329 __ bind(&empty_array); | 329 __ bind(&empty_array); |
330 AllocateEmptyJSArray(masm, | 330 AllocateEmptyJSArray(masm, |
331 a1, | 331 a1, |
332 a2, | 332 a2, |
333 a3, | 333 a3, |
334 t0, | 334 t0, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 // a3: JSArray | 410 // a3: JSArray |
411 // t0: elements_array storage start (untagged) | 411 // t0: elements_array storage start (untagged) |
412 // t1: elements_array_end (untagged) | 412 // t1: elements_array_end (untagged) |
413 // sp[0]: last argument | 413 // sp[0]: last argument |
414 | 414 |
415 Label loop, entry; | 415 Label loop, entry; |
416 __ Branch(USE_DELAY_SLOT, &entry); | 416 __ Branch(USE_DELAY_SLOT, &entry); |
417 __ mov(t3, sp); | 417 __ mov(t3, sp); |
418 __ bind(&loop); | 418 __ bind(&loop); |
419 __ lw(a2, MemOperand(t3)); | 419 __ lw(a2, MemOperand(t3)); |
420 __ Addu(t3, t3, kPointerSize); | |
421 if (FLAG_smi_only_arrays) { | 420 if (FLAG_smi_only_arrays) { |
422 __ JumpIfNotSmi(a2, &has_non_smi_element); | 421 __ JumpIfNotSmi(a2, &has_non_smi_element); |
423 } | 422 } |
| 423 __ Addu(t3, t3, kPointerSize); |
424 __ Addu(t1, t1, -kPointerSize); | 424 __ Addu(t1, t1, -kPointerSize); |
425 __ sw(a2, MemOperand(t1)); | 425 __ sw(a2, MemOperand(t1)); |
426 __ bind(&entry); | 426 __ bind(&entry); |
427 __ Branch(&loop, lt, t0, Operand(t1)); | 427 __ Branch(&loop, lt, t0, Operand(t1)); |
| 428 |
| 429 __ bind(&finish); |
428 __ mov(sp, t3); | 430 __ mov(sp, t3); |
429 | 431 |
430 // Remove caller arguments and receiver from the stack, setup return value and | 432 // Remove caller arguments and receiver from the stack, setup return value and |
431 // return. | 433 // return. |
432 // a0: argc | 434 // a0: argc |
433 // a3: JSArray | 435 // a3: JSArray |
434 // sp[0]: receiver | 436 // sp[0]: receiver |
435 __ Addu(sp, sp, Operand(kPointerSize)); | 437 __ Addu(sp, sp, Operand(kPointerSize)); |
436 __ mov(v0, a3); | 438 __ mov(v0, a3); |
437 __ Ret(); | 439 __ Ret(); |
438 | 440 |
439 __ bind(&has_non_smi_element); | 441 __ bind(&has_non_smi_element); |
| 442 // Double values are handled by the runtime. |
| 443 __ CheckMap( |
| 444 a2, t5, Heap::kHeapNumberMapRootIndex, ¬_double, DONT_DO_SMI_CHECK); |
| 445 __ bind(&cant_transition_map); |
440 __ UndoAllocationInNewSpace(a3, t0); | 446 __ UndoAllocationInNewSpace(a3, t0); |
441 __ b(call_generic_code); | 447 __ Branch(call_generic_code); |
| 448 |
| 449 __ bind(¬_double); |
| 450 // Transition FAST_SMI_ONLY_ELEMENTS to FAST_ELEMENTS. |
| 451 // a3: JSArray |
| 452 __ lw(a2, FieldMemOperand(a3, HeapObject::kMapOffset)); |
| 453 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, |
| 454 FAST_ELEMENTS, |
| 455 a2, |
| 456 t5, |
| 457 &cant_transition_map); |
| 458 __ sw(a2, FieldMemOperand(a3, HeapObject::kMapOffset)); |
| 459 __ RecordWriteField(a3, |
| 460 HeapObject::kMapOffset, |
| 461 a2, |
| 462 t5, |
| 463 kRAHasNotBeenSaved, |
| 464 kDontSaveFPRegs, |
| 465 EMIT_REMEMBERED_SET, |
| 466 OMIT_SMI_CHECK); |
| 467 Label loop2; |
| 468 __ bind(&loop2); |
| 469 __ lw(a2, MemOperand(t3)); |
| 470 __ Addu(t3, t3, kPointerSize); |
| 471 __ Subu(t1, t1, kPointerSize); |
| 472 __ sw(a2, MemOperand(t1)); |
| 473 __ Branch(&loop2, lt, t0, Operand(t1)); |
| 474 __ Branch(&finish); |
442 } | 475 } |
443 | 476 |
444 | 477 |
445 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 478 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
446 // ----------- S t a t e ------------- | 479 // ----------- S t a t e ------------- |
447 // -- a0 : number of arguments | 480 // -- a0 : number of arguments |
448 // -- ra : return address | 481 // -- ra : return address |
449 // -- sp[...]: constructor arguments | 482 // -- sp[...]: constructor arguments |
450 // ----------------------------------- | 483 // ----------------------------------- |
451 Label generic_array_code, one_or_more_arguments, two_or_more_arguments; | 484 Label generic_array_code, one_or_more_arguments, two_or_more_arguments; |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 __ bind(&dont_adapt_arguments); | 1789 __ bind(&dont_adapt_arguments); |
1757 __ Jump(a3); | 1790 __ Jump(a3); |
1758 } | 1791 } |
1759 | 1792 |
1760 | 1793 |
1761 #undef __ | 1794 #undef __ |
1762 | 1795 |
1763 } } // namespace v8::internal | 1796 } } // namespace v8::internal |
1764 | 1797 |
1765 #endif // V8_TARGET_ARCH_MIPS | 1798 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |