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 4489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4500 | 4500 |
4501 // Load the argument on the stack and jump to the runtime. | 4501 // Load the argument on the stack and jump to the runtime. |
4502 Load(args->at(0)); | 4502 Load(args->at(0)); |
4503 | 4503 |
4504 NumberToStringStub stub; | 4504 NumberToStringStub stub; |
4505 frame_->CallStub(&stub, 1); | 4505 frame_->CallStub(&stub, 1); |
4506 frame_->EmitPush(r0); | 4506 frame_->EmitPush(r0); |
4507 } | 4507 } |
4508 | 4508 |
4509 | 4509 |
| 4510 class DeferredSwapElements: public DeferredCode { |
| 4511 public: |
| 4512 DeferredSwapElements(Register object, Register index1, Register index2) |
| 4513 : object_(object), index1_(index1), index2_(index2) { |
| 4514 set_comment("[ DeferredSwapElements"); |
| 4515 } |
| 4516 |
| 4517 virtual void Generate(); |
| 4518 |
| 4519 private: |
| 4520 Register object_, index1_, index2_; |
| 4521 }; |
| 4522 |
| 4523 |
| 4524 void DeferredSwapElements::Generate() { |
| 4525 __ push(object_); |
| 4526 __ push(index1_); |
| 4527 __ push(index2_); |
| 4528 __ CallRuntime(Runtime::kSwapElements, 3); |
| 4529 } |
| 4530 |
| 4531 |
4510 void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) { | 4532 void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) { |
4511 Comment cmnt(masm_, "[ GenerateSwapElements"); | 4533 Comment cmnt(masm_, "[ GenerateSwapElements"); |
4512 | 4534 |
4513 ASSERT_EQ(3, args->length()); | 4535 ASSERT_EQ(3, args->length()); |
4514 | 4536 |
4515 Load(args->at(0)); | 4537 Load(args->at(0)); |
4516 Load(args->at(1)); | 4538 Load(args->at(1)); |
4517 Load(args->at(2)); | 4539 Load(args->at(2)); |
4518 | 4540 |
4519 frame_->CallRuntime(Runtime::kSwapElements, 3); | 4541 Register index2 = r2; |
4520 frame_->EmitPush(r0); | 4542 Register index1 = r1; |
| 4543 Register object = r0; |
| 4544 Register tmp1 = r3; |
| 4545 Register tmp2 = r4; |
| 4546 |
| 4547 frame_->EmitPop(index2); |
| 4548 frame_->EmitPop(index1); |
| 4549 frame_->EmitPop(object); |
| 4550 |
| 4551 DeferredSwapElements* deferred = |
| 4552 new DeferredSwapElements(object, index1, index2); |
| 4553 |
| 4554 // Fetch the map and check if array is in fast case. |
| 4555 // Check that object doesn't require security checks and |
| 4556 // has no indexed interceptor. |
| 4557 __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE); |
| 4558 deferred->Branch(lt); |
| 4559 __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset)); |
| 4560 __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask)); |
| 4561 deferred->Branch(nz); |
| 4562 |
| 4563 // Check the object's elements are in fast case. |
| 4564 __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset)); |
| 4565 __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset)); |
| 4566 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| 4567 __ cmp(tmp2, ip); |
| 4568 deferred->Branch(ne); |
| 4569 |
| 4570 // Smi-tagging is equivalent to multiplying by 2. |
| 4571 STATIC_ASSERT(kSmiTag == 0); |
| 4572 STATIC_ASSERT(kSmiTagSize == 1); |
| 4573 |
| 4574 // Check that both indices are smis. |
| 4575 __ mov(tmp2, index1); |
| 4576 __ orr(tmp2, tmp2, index2); |
| 4577 __ tst(tmp2, Operand(kSmiTagMask)); |
| 4578 deferred->Branch(nz); |
| 4579 |
| 4580 // Bring the offsets into the fixed array in tmp1 into index1 and |
| 4581 // index2. |
| 4582 __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 4583 __ add(index1, tmp2, Operand(index1, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 4584 __ add(index2, tmp2, Operand(index2, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 4585 |
| 4586 // Swap elements. |
| 4587 Register tmp3 = object; |
| 4588 object = no_reg; |
| 4589 __ ldr(tmp3, MemOperand(tmp1, index1)); |
| 4590 __ ldr(tmp2, MemOperand(tmp1, index2)); |
| 4591 __ str(tmp3, MemOperand(tmp1, index2)); |
| 4592 __ str(tmp2, MemOperand(tmp1, index1)); |
| 4593 |
| 4594 Label done; |
| 4595 __ InNewSpace(tmp1, tmp2, eq, &done); |
| 4596 // Possible optimization: do a check that both values are Smis |
| 4597 // (or them and test against Smi mask.) |
| 4598 |
| 4599 __ mov(tmp2, tmp1); |
| 4600 RecordWriteStub recordWrite1(tmp1, index1, tmp3); |
| 4601 __ CallStub(&recordWrite1); |
| 4602 |
| 4603 RecordWriteStub recordWrite2(tmp2, index2, tmp3); |
| 4604 __ CallStub(&recordWrite2); |
| 4605 |
| 4606 __ bind(&done); |
| 4607 |
| 4608 deferred->BindExit(); |
| 4609 __ LoadRoot(tmp1, Heap::kUndefinedValueRootIndex); |
| 4610 frame_->EmitPush(tmp1); |
4521 } | 4611 } |
4522 | 4612 |
4523 | 4613 |
4524 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { | 4614 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { |
4525 Comment cmnt(masm_, "[ GenerateCallFunction"); | 4615 Comment cmnt(masm_, "[ GenerateCallFunction"); |
4526 | 4616 |
4527 ASSERT(args->length() >= 2); | 4617 ASSERT(args->length() >= 2); |
4528 | 4618 |
4529 int n_args = args->length() - 2; // for receiver and function. | 4619 int n_args = args->length() - 2; // for receiver and function. |
4530 Load(args->at(0)); // receiver | 4620 Load(args->at(0)); // receiver |
(...skipping 1965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6496 GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, r4, false, &runtime); | 6586 GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, r4, false, &runtime); |
6497 __ add(sp, sp, Operand(1 * kPointerSize)); | 6587 __ add(sp, sp, Operand(1 * kPointerSize)); |
6498 __ Ret(); | 6588 __ Ret(); |
6499 | 6589 |
6500 __ bind(&runtime); | 6590 __ bind(&runtime); |
6501 // Handle number to string in the runtime system if not found in the cache. | 6591 // Handle number to string in the runtime system if not found in the cache. |
6502 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); | 6592 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
6503 } | 6593 } |
6504 | 6594 |
6505 | 6595 |
| 6596 void RecordWriteStub::Generate(MacroAssembler* masm) { |
| 6597 __ RecordWriteHelper(object_, offset_, scratch_); |
| 6598 __ Ret(); |
| 6599 } |
| 6600 |
| 6601 |
6506 // On entry r0 (rhs) and r1 (lhs) are the values to be compared. | 6602 // On entry r0 (rhs) and r1 (lhs) are the values to be compared. |
6507 // On exit r0 is 0, positive or negative to indicate the result of | 6603 // On exit r0 is 0, positive or negative to indicate the result of |
6508 // the comparison. | 6604 // the comparison. |
6509 void CompareStub::Generate(MacroAssembler* masm) { | 6605 void CompareStub::Generate(MacroAssembler* masm) { |
6510 Label slow; // Call builtin. | 6606 Label slow; // Call builtin. |
6511 Label not_smis, both_loaded_as_doubles, lhs_not_nan; | 6607 Label not_smis, both_loaded_as_doubles, lhs_not_nan; |
6512 | 6608 |
6513 // NOTICE! This code is only reached after a smi-fast-case check, so | 6609 // NOTICE! This code is only reached after a smi-fast-case check, so |
6514 // it is certain that at least one operand isn't a smi. | 6610 // it is certain that at least one operand isn't a smi. |
6515 | 6611 |
(...skipping 3260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9776 | 9872 |
9777 // Just jump to runtime to add the two strings. | 9873 // Just jump to runtime to add the two strings. |
9778 __ bind(&string_add_runtime); | 9874 __ bind(&string_add_runtime); |
9779 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 9875 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
9780 } | 9876 } |
9781 | 9877 |
9782 | 9878 |
9783 #undef __ | 9879 #undef __ |
9784 | 9880 |
9785 } } // namespace v8::internal | 9881 } } // namespace v8::internal |
OLD | NEW |