OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2777 | 2777 |
2778 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | 2778 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
2779 #ifdef DEBUG | 2779 #ifdef DEBUG |
2780 int original_height = frame_->height(); | 2780 int original_height = frame_->height(); |
2781 #endif | 2781 #endif |
2782 VirtualFrame::SpilledScope spilled_scope; | 2782 VirtualFrame::SpilledScope spilled_scope; |
2783 Comment cmnt(masm_, "[ ArrayLiteral"); | 2783 Comment cmnt(masm_, "[ ArrayLiteral"); |
2784 | 2784 |
2785 // Load the function of this activation. | 2785 // Load the function of this activation. |
2786 __ ldr(r2, frame_->Function()); | 2786 __ ldr(r2, frame_->Function()); |
2787 // Literals array. | 2787 // Load the literals array of the function. |
2788 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); | 2788 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); |
2789 // Literal index. | |
2790 __ mov(r1, Operand(Smi::FromInt(node->literal_index()))); | 2789 __ mov(r1, Operand(Smi::FromInt(node->literal_index()))); |
2791 // Constant elements. | |
2792 __ mov(r0, Operand(node->constant_elements())); | 2790 __ mov(r0, Operand(node->constant_elements())); |
2793 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit()); | 2791 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit()); |
| 2792 int length = node->values()->length(); |
2794 if (node->depth() > 1) { | 2793 if (node->depth() > 1) { |
2795 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); | 2794 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 2795 } else if (length > FastCloneShallowArrayStub::kMaximumLength) { |
| 2796 frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
2796 } else { | 2797 } else { |
2797 frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 2798 FastCloneShallowArrayStub stub(length); |
| 2799 frame_->CallStub(&stub, 3); |
2798 } | 2800 } |
2799 frame_->EmitPush(r0); // save the result | 2801 frame_->EmitPush(r0); // save the result |
2800 // r0: created object literal | 2802 // r0: created object literal |
2801 | 2803 |
2802 // Generate code to set the elements in the array that are not | 2804 // Generate code to set the elements in the array that are not |
2803 // literals. | 2805 // literals. |
2804 for (int i = 0; i < node->values()->length(); i++) { | 2806 for (int i = 0; i < node->values()->length(); i++) { |
2805 Expression* value = node->values()->at(i); | 2807 Expression* value = node->values()->at(i); |
2806 | 2808 |
2807 // If value is a literal the property value is already set in the | 2809 // If value is a literal the property value is already set in the |
(...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4517 __ mov(cp, r0); | 4519 __ mov(cp, r0); |
4518 __ pop(); | 4520 __ pop(); |
4519 __ Ret(); | 4521 __ Ret(); |
4520 | 4522 |
4521 // Need to collect. Call into runtime system. | 4523 // Need to collect. Call into runtime system. |
4522 __ bind(&gc); | 4524 __ bind(&gc); |
4523 __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1); | 4525 __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1); |
4524 } | 4526 } |
4525 | 4527 |
4526 | 4528 |
| 4529 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
| 4530 // Stack layout on entry: |
| 4531 // |
| 4532 // [sp]: constant elements. |
| 4533 // [sp + kPointerSize]: literal index. |
| 4534 // [sp + (2 * kPointerSize)]: literals array. |
| 4535 |
| 4536 // All sizes here are multiples of kPointerSize. |
| 4537 int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0; |
| 4538 int size = JSArray::kSize + elements_size; |
| 4539 |
| 4540 // Load boilerplate object into r3 and check if we need to create a |
| 4541 // boilerplate. |
| 4542 Label slow_case; |
| 4543 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); |
| 4544 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); |
| 4545 __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 4546 __ ldr(r3, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 4547 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 4548 __ cmp(r3, ip); |
| 4549 __ b(eq, &slow_case); |
| 4550 |
| 4551 // Allocate both the JS array and the elements array in one big |
| 4552 // allocation. This avoids multiple limit checks. |
| 4553 __ AllocateInNewSpace(size / kPointerSize, |
| 4554 r0, |
| 4555 r1, |
| 4556 r2, |
| 4557 &slow_case, |
| 4558 TAG_OBJECT); |
| 4559 |
| 4560 // Copy the JS array part. |
| 4561 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
| 4562 if ((i != JSArray::kElementsOffset) || (length_ == 0)) { |
| 4563 __ ldr(r1, FieldMemOperand(r3, i)); |
| 4564 __ str(r1, FieldMemOperand(r0, i)); |
| 4565 } |
| 4566 } |
| 4567 |
| 4568 if (length_ > 0) { |
| 4569 // Get hold of the elements array of the boilerplate and setup the |
| 4570 // elements pointer in the resulting object. |
| 4571 __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset)); |
| 4572 __ add(r2, r0, Operand(JSArray::kSize)); |
| 4573 __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset)); |
| 4574 |
| 4575 // Copy the elements array. |
| 4576 for (int i = 0; i < elements_size; i += kPointerSize) { |
| 4577 __ ldr(r1, FieldMemOperand(r3, i)); |
| 4578 __ str(r1, FieldMemOperand(r2, i)); |
| 4579 } |
| 4580 } |
| 4581 |
| 4582 // Return and remove the on-stack parameters. |
| 4583 __ add(sp, sp, Operand(3 * kPointerSize)); |
| 4584 __ Ret(); |
| 4585 |
| 4586 __ bind(&slow_case); |
| 4587 ExternalReference runtime(Runtime::kCreateArrayLiteralShallow); |
| 4588 __ TailCallRuntime(runtime, 3, 1); |
| 4589 } |
| 4590 |
| 4591 |
4527 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz | 4592 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz |
4528 // instruction. On pre-ARM5 hardware this routine gives the wrong answer for 0 | 4593 // instruction. On pre-ARM5 hardware this routine gives the wrong answer for 0 |
4529 // (31 instead of 32). | 4594 // (31 instead of 32). |
4530 static void CountLeadingZeros( | 4595 static void CountLeadingZeros( |
4531 MacroAssembler* masm, | 4596 MacroAssembler* masm, |
4532 Register source, | 4597 Register source, |
4533 Register scratch, | 4598 Register scratch, |
4534 Register zeros) { | 4599 Register zeros) { |
4535 #ifdef CAN_USE_ARMV5_INSTRUCTIONS | 4600 #ifdef CAN_USE_ARMV5_INSTRUCTIONS |
4536 __ clz(zeros, source); // This instruction is only supported after ARM5. | 4601 __ clz(zeros, source); // This instruction is only supported after ARM5. |
(...skipping 2932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7469 | 7534 |
7470 // Just jump to runtime to add the two strings. | 7535 // Just jump to runtime to add the two strings. |
7471 __ bind(&string_add_runtime); | 7536 __ bind(&string_add_runtime); |
7472 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); | 7537 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); |
7473 } | 7538 } |
7474 | 7539 |
7475 | 7540 |
7476 #undef __ | 7541 #undef __ |
7477 | 7542 |
7478 } } // namespace v8::internal | 7543 } } // namespace v8::internal |
OLD | NEW |